Bug fix and authoring
[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
22 #include <json.h>
23
24 #include "verbose.h"
25 #include "utils-jbus.h"
26 #include "af-db.h"
27 #include "af-run.h"
28
29 static struct jbus *jbus;
30 static struct af_db *afdb;
31
32 const char error_nothing[] = "[]";
33 const char error_bad_request[] = "{\"status\":\"error: bad request\"}";
34 const char error_not_found[] = "{\"status\":\"error: not found\"}";
35 const char error_cant_start[] = "{\"status\":\"error: can't start\"}";
36
37 static const char *getappid(struct json_object *obj)
38 {
39         return json_type_string == json_object_get_type(obj) ? json_object_get_string(obj) : NULL;
40 }
41
42 static int getrunid(struct json_object *obj)
43 {
44         return json_type_int == json_object_get_type(obj) ? json_object_get_int(obj) : 0;
45 }
46
47 static void reply(struct jreq *jreq, struct json_object *resp, const char *errstr)
48 {
49         if (resp)
50                 jbus_reply(jreq, resp);
51         else
52                 jbus_replyj(jreq, errstr);
53 }
54
55 static void on_runnables(struct jreq *jreq, struct json_object *obj)
56 {
57         struct json_object *resp = af_db_application_list(afdb);
58         jbus_reply(jreq, resp);
59         json_object_put(obj);
60 }
61
62 static void on_detail(struct jreq *jreq, struct json_object *obj)
63 {
64         const char *appid = getappid(obj);
65         struct json_object *resp = af_db_get_application_public(afdb, appid);
66         reply(jreq, resp, error_not_found);
67         json_object_put(obj);
68 }
69
70 static void on_start(struct jreq *jreq, struct json_object *obj)
71 {
72         const char *appid;
73         struct json_object *appli;
74         int runid;
75         char runidstr[20];
76
77         appid = getappid(obj);
78         if (appid == NULL)
79                 jbus_replyj(jreq, error_bad_request);
80         else {
81                 appli = af_db_get_application(afdb, appid);
82                 if (appli == NULL)
83                         jbus_replyj(jreq, error_not_found);
84                 else {
85                         runid = af_run_start(appli);
86                         if (runid <= 0)
87                                 jbus_replyj(jreq, error_cant_start);
88                         else {
89                                 snprintf(runidstr, sizeof runidstr, "%d", runid);
90                                 runidstr[sizeof runidstr - 1] = 0;
91                                 jbus_replyj(jreq, runidstr);
92                         }
93                 }
94         }
95         json_object_put(obj);
96 }
97
98 static void on_stop(struct jreq *jreq, struct json_object *obj)
99 {
100         int runid = getrunid(obj);
101         int status = af_run_stop(runid);
102         jbus_replyj(jreq, status ? error_not_found : "true");
103         json_object_put(obj);
104 }
105
106 static void on_continue(struct jreq *jreq, struct json_object *obj)
107 {
108         int runid = getrunid(obj);
109         int status = af_run_continue(runid);
110         jbus_replyj(jreq, status ? error_not_found : "true");
111         json_object_put(obj);
112 }
113
114 static void on_terminate(struct jreq *jreq, struct json_object *obj)
115 {
116         int runid = getrunid(obj);
117         int status = af_run_terminate(runid);
118         jbus_replyj(jreq, status ? error_not_found : "true");
119         json_object_put(obj);
120 }
121
122 static void on_runners(struct jreq *jreq, struct json_object *obj)
123 {
124         struct json_object *resp = af_run_list();
125         jbus_reply(jreq, resp);
126         json_object_put(resp);
127         json_object_put(obj);
128 }
129
130 static void on_state(struct jreq *jreq, struct json_object *obj)
131 {
132         int runid = getrunid(obj);
133         struct json_object *resp = af_run_state(runid);
134         reply(jreq, resp, error_not_found);
135         json_object_put(resp);
136         json_object_put(obj);
137 }
138
139 static int daemonize()
140 {
141         int rc = fork();
142         if (rc < 0)
143                 return rc;
144         if (rc)
145                 _exit(0);
146         return 0;
147 }
148
149 int main(int ac, char **av)
150 {
151         LOGAUTH("afdb-usrd");
152
153         /* init random generator */
154         srandom((unsigned int)time(NULL));
155
156         /* init runners */
157         if (af_run_init()) {
158                 ERROR("af_run_init failed");
159                 return 1;
160         }
161
162         /* init framework */
163         afdb = af_db_create();
164         if (!afdb) {
165                 ERROR("af_create failed");
166                 return 1;
167         }
168         if (af_db_add_root(afdb, FWK_APP_DIR)) {
169                 ERROR("can't add root %s", FWK_APP_DIR);
170                 return 1;
171         }
172         if (af_db_update_applications(afdb)) {
173                 ERROR("af_update_applications failed");
174                 return 1;
175         }
176
177         /* init service */
178         jbus = create_jbus(1, "/org/AGL/framework");
179         if (!jbus) {
180                 ERROR("create_jbus failed");
181                 return 1;
182         }
183         if(jbus_add_service(jbus, "runnables", on_runnables)
184         || jbus_add_service(jbus, "detail", on_detail)
185         || jbus_add_service(jbus, "start", on_start)
186         || jbus_add_service(jbus, "terminate", on_terminate)
187         || jbus_add_service(jbus, "stop", on_stop)
188         || jbus_add_service(jbus, "continue", on_continue)
189         || jbus_add_service(jbus, "runners", on_runners)
190         || jbus_add_service(jbus, "state", on_state)) {
191                 ERROR("adding services failed");
192                 return 1;
193         }
194
195         /* start and run */
196         if (jbus_start_serving(jbus)) {
197                 ERROR("cant start server");
198                 return 1;
199         }
200         while (!jbus_read_write_dispatch(jbus, -1));
201         return 0;
202 }
203
204
205