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