960b44b5ba0fc383c2d745a9b6807f1ced48e3a5
[src/app-framework-main.git] / src / af-usrd.c
1 /*
2  Copyright 2015 IoT.bzh
3
4  author: José Bollo <jose.bollo@iot.bzh>
5
6  Licensed under the Apache License, Version 2.0 (the "License");
7  you may not use this file except in compliance with the License.
8  You may obtain a copy of the License at
9
10      http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  See the License for the specific language governing permissions and
16  limitations under the License.
17 */
18
19 #include <unistd.h>
20 #include <stdio.h>
21 #include <time.h>
22
23 #include <json.h>
24
25 #include "verbose.h"
26 #include "utils-jbus.h"
27 #include "af-db.h"
28 #include "af-run.h"
29
30 static struct jbus *jbus;
31 static struct af_db *afdb;
32
33 const char error_nothing[] = "[]";
34 const char error_bad_request[] = "{\"status\":\"error: bad request\"}";
35 const char error_not_found[] = "{\"status\":\"error: not found\"}";
36 const char error_cant_start[] = "{\"status\":\"error: can't start\"}";
37
38 static const char *getappid(struct json_object *obj)
39 {
40         return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
41 }
42
43 static int getrunid(struct json_object *obj)
44 {
45         return json_type_int == json_object_get_type(obj) ? json_object_get_int(obj) : 0;
46 }
47
48 static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
49 {
50         if (resp)
51                 jbus_reply(jreq, resp);
52         else
53                 jbus_replyj(jreq, errstr);
54 }
55
56 static void on_runnables(struct jreq *jreq, struct json_object *obj)
57 {
58         struct json_object *resp = af_db_application_list(afdb);
59         jbus_reply(jreq, resp);
60         json_object_put(obj);
61 }
62
63 static void on_detail(struct jreq *jreq, struct json_object *obj)
64 {
65         const char *appid = getappid(obj);
66         struct json_object *resp = af_db_get_application_public(afdb, appid);
67         reply(jreq, resp, error_not_found);
68         json_object_put(obj);
69 }
70
71 static void on_start(struct jreq *jreq, struct json_object *obj)
72 {
73         const char *appid;
74         struct json_object *appli;
75         int runid;
76         char runidstr[20];
77
78         appid = getappid(obj);
79         if (appid == NULL)
80                 jbus_replyj(jreq, error_bad_request);
81         else {
82                 appli = af_db_get_application(afdb, appid);
83                 if (appli == NULL)
84                         jbus_replyj(jreq, error_not_found);
85                 else {
86                         runid = af_run_start(appli);
87                         if (runid <= 0)
88                                 jbus_replyj(jreq, error_cant_start);
89                         else {
90                                 snprintf(runidstr, sizeof runidstr, "%d", runid);
91                                 runidstr[sizeof runidstr - 1] = 0;
92                                 jbus_replyj(jreq, runidstr);
93                         }
94                 }
95         }
96         json_object_put(obj);
97 }
98
99 static void on_stop(struct jreq *jreq, struct json_object *obj)
100 {
101         int runid = getrunid(obj);
102         int status = af_run_stop(runid);
103         jbus_replyj(jreq, status ? error_not_found : "true");
104         json_object_put(obj);
105 }
106
107 static void on_continue(struct jreq *jreq, struct json_object *obj)
108 {
109         int runid = getrunid(obj);
110         int status = af_run_continue(runid);
111         jbus_replyj(jreq, status ? error_not_found : "true");
112         json_object_put(obj);
113 }
114
115 static void on_terminate(struct jreq *jreq, struct json_object *obj)
116 {
117         int runid = getrunid(obj);
118         int status = af_run_terminate(runid);
119         jbus_replyj(jreq, status ? error_not_found : "true");
120         json_object_put(obj);
121 }
122
123 static void on_runners(struct jreq *jreq, struct json_object *obj)
124 {
125         struct json_object *resp = af_run_list();
126         jbus_reply(jreq, resp);
127         json_object_put(resp);
128         json_object_put(obj);
129 }
130
131 static void on_state(struct jreq *jreq, struct json_object *obj)
132 {
133         int runid = getrunid(obj);
134         struct json_object *resp = af_run_state(runid);
135         reply(jreq, resp, error_not_found);
136         json_object_put(resp);
137         json_object_put(obj);
138 }
139
140 static int daemonize()
141 {
142         int rc = fork();
143         if (rc < 0)
144                 return rc;
145         if (rc)
146                 _exit(0);
147         return 0;
148 }
149
150 int main(int ac, char **av)
151 {
152         LOGAUTH("afdb-usrd");
153
154         /* init random generator */
155         srandom((unsigned int)time(NULL));
156
157         /* init runners */
158         if (af_run_init()) {
159                 ERROR("af_run_init failed");
160                 return 1;
161         }
162
163         /* init framework */
164         afdb = af_db_create();
165         if (!afdb) {
166                 ERROR("af_create failed");
167                 return 1;
168         }
169         if (af_db_add_root(afdb, FWK_APP_DIR)) {
170                 ERROR("can't add root %s", FWK_APP_DIR);
171                 return 1;
172         }
173         if (af_db_update_applications(afdb)) {
174                 ERROR("af_update_applications failed");
175                 return 1;
176         }
177
178         /* init service */
179         jbus = create_jbus(1, "/org/AGL/framework");
180         if (!jbus) {
181                 ERROR("create_jbus failed");
182                 return 1;
183         }
184         if(jbus_add_service(jbus, "runnables", on_runnables)
185         || jbus_add_service(jbus, "detail", on_detail)
186         || jbus_add_service(jbus, "start", on_start)
187         || jbus_add_service(jbus, "terminate", on_terminate)
188         || jbus_add_service(jbus, "stop", on_stop)
189         || jbus_add_service(jbus, "continue", on_continue)
190         || jbus_add_service(jbus, "runners", on_runners)
191         || jbus_add_service(jbus, "state", on_state)) {
192                 ERROR("adding services failed");
193                 return 1;
194         }
195
196         /* start and run */
197         if (jbus_start_serving(jbus)) {
198                 ERROR("cant start server");
199                 return 1;
200         }
201         while (!jbus_read_write_dispatch(jbus, -1));
202         return 0;
203 }
204
205
206