46a662d0ec1d228179cd81748fbfacd29efdbc36
[src/app-framework-main.git] / src / afm-user-daemon.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[] = "bad request";
35 const char error_not_found[] = "not found";
36 const char error_cant_start[] = "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_j(jreq, resp);
52         else
53                 jbus_reply_error_s(jreq, errstr);
54 }
55
56 static void reply_status(struct jreq *jreq, int status)
57 {
58         if (status)
59                 jbus_reply_error_s(jreq, error_not_found);
60         else
61                 jbus_reply_s(jreq, "true");
62 }
63
64 static void on_runnables(struct jreq *jreq, struct json_object *obj)
65 {
66         struct json_object *resp = af_db_application_list(afdb);
67         jbus_reply_j(jreq, resp);
68         json_object_put(obj);
69 }
70
71 static void on_detail(struct jreq *jreq, struct json_object *obj)
72 {
73         const char *appid = getappid(obj);
74         struct json_object *resp = af_db_get_application_public(afdb, appid);
75         reply(jreq, resp, error_not_found);
76         json_object_put(obj);
77 }
78
79 static void on_start(struct jreq *jreq, struct json_object *obj)
80 {
81         const char *appid;
82         struct json_object *appli;
83         int runid;
84         char runidstr[20];
85
86         appid = getappid(obj);
87         if (appid == NULL)
88                 jbus_reply_error_s(jreq, error_bad_request);
89         else {
90                 appli = af_db_get_application(afdb, appid);
91                 if (appli == NULL)
92                         jbus_reply_error_s(jreq, error_not_found);
93                 else {
94                         runid = af_run_start(appli);
95                         if (runid <= 0)
96                                 jbus_reply_error_s(jreq, error_cant_start);
97                         else {
98                                 snprintf(runidstr, sizeof runidstr, "%d", runid);
99                                 runidstr[sizeof runidstr - 1] = 0;
100                                 jbus_reply_s(jreq, runidstr);
101                         }
102                 }
103         }
104         json_object_put(obj);
105 }
106
107 static void on_stop(struct jreq *jreq, struct json_object *obj)
108 {
109         int runid = getrunid(obj);
110         int status = af_run_stop(runid);
111         reply_status(jreq, status);
112         json_object_put(obj);
113 }
114
115 static void on_continue(struct jreq *jreq, struct json_object *obj)
116 {
117         int runid = getrunid(obj);
118         int status = af_run_continue(runid);
119         reply_status(jreq, status);
120         json_object_put(obj);
121 }
122
123 static void on_terminate(struct jreq *jreq, struct json_object *obj)
124 {
125         int runid = getrunid(obj);
126         int status = af_run_terminate(runid);
127         reply_status(jreq, status);
128         json_object_put(obj);
129 }
130
131 static void on_runners(struct jreq *jreq, struct json_object *obj)
132 {
133         struct json_object *resp = af_run_list();
134         jbus_reply_j(jreq, resp);
135         json_object_put(resp);
136         json_object_put(obj);
137 }
138
139 static void on_state(struct jreq *jreq, struct json_object *obj)
140 {
141         int runid = getrunid(obj);
142         struct json_object *resp = af_run_state(runid);
143         reply(jreq, resp, error_not_found);
144         json_object_put(resp);
145         json_object_put(obj);
146 }
147
148 static int daemonize()
149 {
150         int rc = fork();
151         if (rc < 0)
152                 return rc;
153         if (rc)
154                 _exit(0);
155         return 0;
156 }
157
158 int main(int ac, char **av)
159 {
160         LOGAUTH("afm-main-daemon");
161
162         /* init random generator */
163         srandom((unsigned int)time(NULL));
164
165         /* init runners */
166         if (af_run_init()) {
167                 ERROR("af_run_init failed");
168                 return 1;
169         }
170
171         /* init framework */
172         afdb = af_db_create();
173         if (!afdb) {
174                 ERROR("af_create failed");
175                 return 1;
176         }
177         if (af_db_add_root(afdb, FWK_APP_DIR)) {
178                 ERROR("can't add root %s", FWK_APP_DIR);
179                 return 1;
180         }
181         if (af_db_update_applications(afdb)) {
182                 ERROR("af_update_applications failed");
183                 return 1;
184         }
185
186         /* init service */
187         jbus = create_jbus(1, "/org/AGL/afmMain");
188         if (!jbus) {
189                 ERROR("create_jbus failed");
190                 return 1;
191         }
192         if(jbus_add_service_j(jbus, "runnables", on_runnables)
193         || jbus_add_service_j(jbus, "detail", on_detail)
194         || jbus_add_service_j(jbus, "start", on_start)
195         || jbus_add_service_j(jbus, "terminate", on_terminate)
196         || jbus_add_service_j(jbus, "stop", on_stop)
197         || jbus_add_service_j(jbus, "continue", on_continue)
198         || jbus_add_service_j(jbus, "runners", on_runners)
199         || jbus_add_service_j(jbus, "state", on_state)) {
200                 ERROR("adding services failed");
201                 return 1;
202         }
203
204         /* start and run */
205         if (jbus_start_serving(jbus)) {
206                 ERROR("cant start server");
207                 return 1;
208         }
209         while (!jbus_read_write_dispatch(jbus, -1));
210         return 0;
211 }
212
213
214