2 * Copyright (C) 2015 "IoT.bzh"
3 * Author "Fulup Ar Foll"
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #define _GNU_SOURCE /* See feature_test_macros(7) */
24 #include "afb-plugin.h"
25 #include "afb-req-itf.h"
26 #include "afb-poll-itf.h"
28 #include "utils-sbus.h"
29 #include "utils-jbus.h"
31 static const char _auto_[] = "auto";
32 static const char _continue_[] = "continue";
33 static const char _detail_[] = "detail";
34 static const char _id_[] = "id";
35 static const char _install_[] = "install";
36 static const char _local_[] = "local";
37 static const char _mode_[] = "mode";
38 static const char _remote_[] = "remote";
39 static const char _runid_[] = "runid";
40 static const char _runnables_[] = "runnables";
41 static const char _runners_[] = "runners";
42 static const char _start_[] = "start";
43 static const char _state_[] = "state";
44 static const char _stop_[] = "stop";
45 static const char _terminate_[] = "terminate";
46 static const char _uninstall_[] = "uninstall";
47 static const char _uri_[] = "uri";
49 static const struct AFB_interface *interface;
51 static struct jbus *jbus;
53 static struct json_object *embed(const char *tag, struct json_object *obj)
55 struct json_object *result;
62 result = json_object_new_object();
68 /* TODO why is json-c not returning a status? */
69 json_object_object_add(result, tag, obj);
75 static void embed_call_void(struct afb_req request, const char *method)
77 struct json_object *obj = jbus_call_sj_sync(jbus, method, "true");
78 if (interface->verbosity)
79 fprintf(stderr, "(afm-main-plugin) %s(true) -> %s\n", method, obj ? json_object_to_json_string(obj) : "NULL");
81 afb_req_fail(request, "failed", "framework daemon failure");
84 obj = embed(method, obj);
86 afb_req_fail(request, "failed", "framework daemon failure");
89 afb_req_success(request, obj, NULL);
92 static void call_appid(struct afb_req request, const char *method)
94 struct json_object *obj;
96 const char *id = afb_req_value(request, _id_);
98 afb_req_fail(request, "bad-request", "missing 'id'");
101 if (asprintf(&sid, "\"%s\"", id) <= 0) {
102 afb_req_fail(request, "server-error", "out of memory");
105 obj = jbus_call_sj_sync(jbus, method, sid);
106 if (interface->verbosity)
107 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, sid, obj ? json_object_to_json_string(obj) : "NULL");
110 afb_req_fail(request, "failed", "framework daemon failure");
113 afb_req_success(request, obj, NULL);
116 static void call_runid(struct afb_req request, const char *method)
118 struct json_object *obj;
119 const char *id = afb_req_value(request, _runid_);
121 afb_req_fail(request, "bad-request", "missing 'runid'");
124 obj = jbus_call_sj_sync(jbus, method, id);
125 if (interface->verbosity)
126 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, id,
127 obj ? json_object_to_json_string(obj) : "NULL");
129 afb_req_fail(request, "failed", "framework daemon failure");
132 afb_req_success(request, obj, NULL);
136 /************************** entries ******************************/
138 static void runnables(struct afb_req request)
140 embed_call_void(request, _runnables_);
143 static void detail(struct afb_req request)
145 call_appid(request, _detail_);
148 static void start(struct afb_req request)
150 struct json_object *obj;
151 const char *id, *mode;
156 id = afb_req_value(request, _id_);
158 afb_req_fail(request, "bad-request", "missing 'id'");
162 mode = afb_req_value(request, _mode_);
163 if (mode == NULL || !strcmp(mode, _auto_)) {
164 mode = interface->mode == AFB_MODE_REMOTE ? _remote_ : _local_;
167 /* create the query */
168 rc = asprintf(&query, "{\"id\":\"%s\",\"mode\":\"%s\"}", id, mode);
170 afb_req_fail(request, "server-error", "out of memory");
174 /* calls the service */
175 obj = jbus_call_sj_sync(jbus, _start_, query);
176 if (interface->verbosity)
177 fprintf(stderr, "(afm-main-plugin) start(%s) -> %s\n", query, obj ? json_object_to_json_string(obj) : "NULL");
182 afb_req_fail(request, "failed", "framework daemon failure");
186 /* embed if needed */
187 if (json_object_get_type(obj) == json_type_int)
188 obj = embed(_runid_, obj);
189 afb_req_success(request, obj, NULL);
192 static void terminate(struct afb_req request)
194 call_runid(request, _terminate_);
197 static void stop(struct afb_req request)
199 call_runid(request, _stop_);
202 static void continue_(struct afb_req request)
204 call_runid(request, _continue_);
207 static void runners(struct afb_req request)
209 embed_call_void(request, _runners_);
212 static void state(struct afb_req request)
214 call_runid(request, _state_);
217 static void install(struct afb_req request)
219 struct json_object *obj;
221 const char *filename;
224 /* get the argument */
225 arg = afb_req_get(request, "widget");
227 if (filename == NULL) {
228 afb_req_fail(request, "bad-request", "missing 'widget' file");
232 /* makes the query */
233 if (0 >= asprintf(&query, "\"%s\"", filename)) {
234 afb_req_fail(request, "server-error", "out of memory");
238 obj = jbus_call_sj_sync(jbus, _install_, query);
239 if (interface->verbosity)
240 fprintf(stderr, "(afm-main-plugin) install(%s) -> %s\n", query, obj ? json_object_to_json_string(obj) : "NULL");
245 afb_req_fail(request, "failed", "framework daemon failure");
249 /* embed if needed */
250 obj = embed(_id_, obj);
251 afb_req_success(request, obj, NULL);
254 static void uninstall(struct afb_req request)
256 call_appid(request, _uninstall_);
259 static const struct AFB_restapi plug_apis[] =
261 {_runnables_, AFB_SESSION_CHECK, runnables, "Get list of runnable applications"},
262 {_detail_ , AFB_SESSION_CHECK, detail, "Get the details for one application"},
263 {_start_ , AFB_SESSION_CHECK, start, "Start an application"},
264 {_terminate_, AFB_SESSION_CHECK, terminate, "Terminate a running application"},
265 {_stop_ , AFB_SESSION_CHECK, stop, "Stop (pause) a running application"},
266 {_continue_ , AFB_SESSION_CHECK, continue_, "Continue (resume) a stopped application"},
267 {_runners_ , AFB_SESSION_CHECK, runners, "Get the list of running applications"},
268 {_state_ , AFB_SESSION_CHECK, state, "Get the state of a running application"},
269 {_install_ , AFB_SESSION_CHECK, install, "Install an application using a widget file"},
270 {_uninstall_, AFB_SESSION_CHECK, uninstall, "Uninstall an application"},
271 { NULL, 0, NULL, NULL }
274 static const struct AFB_plugin plug_desc = {
275 .type = AFB_PLUGIN_JSON,
276 .info = "Application Framework Master Service",
277 .prefix = "afm-main",
281 static struct sbus_itf sbusitf;
283 const struct AFB_plugin *pluginRegister(const struct AFB_interface *itf)
287 if (interface != NULL)
291 sbusitf.wait = itf->pollitf->wait;
292 sbusitf.open = itf->pollitf->open;
293 sbusitf.on_readable = itf->pollitf->on_readable;
294 sbusitf.on_writable = itf->pollitf->on_writable;
295 sbusitf.on_hangup = itf->pollitf->on_hangup;
296 sbusitf.close = itf->pollitf->close;
298 sbus = sbus_session(&sbusitf, itf->pollclosure);
300 fprintf(stderr, "ERROR: %s:%d: can't connect to DBUS session\n", __FILE__, __LINE__);
304 jbus = create_jbus(sbus, "/org/AGL/afm/user");