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"
27 #include "utils-jbus.h"
29 static const char _auto_[] = "auto";
30 static const char _continue_[] = "continue";
31 static const char _detail_[] = "detail";
32 static const char _id_[] = "id";
33 static const char _install_[] = "install";
34 static const char _local_[] = "local";
35 static const char _mode_[] = "mode";
36 static const char _remote_[] = "remote";
37 static const char _runid_[] = "runid";
38 static const char _runnables_[] = "runnables";
39 static const char _runners_[] = "runners";
40 static const char _start_[] = "start";
41 static const char _state_[] = "state";
42 static const char _stop_[] = "stop";
43 static const char _terminate_[] = "terminate";
44 static const char _uninstall_[] = "uninstall";
45 static const char _uri_[] = "uri";
47 static const struct AFB_interface *interface;
49 static struct jbus *jbus;
51 static struct json_object *embed(const char *tag, struct json_object *obj)
53 struct json_object *result;
60 result = json_object_new_object();
66 /* TODO why is json-c not returning a status? */
67 json_object_object_add(result, tag, obj);
73 static void embed_call_void(struct afb_req request, const char *method)
75 struct json_object *obj = jbus_call_sj_sync(jbus, method, "true");
76 if (interface->verbose)
77 fprintf(stderr, "(afm-main-plugin) %s(true) -> %s\n", method, obj ? json_object_to_json_string(obj) : "NULL");
79 afb_req_fail(request, "failed", "framework daemon failure");
82 obj = embed(method, obj);
84 afb_req_fail(request, "failed", "framework daemon failure");
87 afb_req_success(request, obj, NULL);
90 static void call_appid(struct afb_req request, const char *method)
92 struct json_object *obj;
94 const char *id = afb_req_argument(request, _id_);
96 afb_req_fail(request, "bad-request", "missing 'id'");
99 if (asprintf(&sid, "\"%s\"", id) <= 0) {
100 afb_req_fail(request, "server-error", "out of memory");
103 obj = jbus_call_sj_sync(jbus, method, sid);
104 if (interface->verbose)
105 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, sid, obj ? json_object_to_json_string(obj) : "NULL");
108 afb_req_fail(request, "failed", "framework daemon failure");
111 afb_req_success(request, obj, NULL);
114 static void call_runid(struct afb_req request, const char *method)
116 struct json_object *obj;
117 const char *id = afb_req_argument(request, _runid_);
119 afb_req_fail(request, "bad-request", "missing 'runid'");
122 obj = jbus_call_sj_sync(jbus, method, id);
123 if (interface->verbose)
124 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, id,
125 obj ? json_object_to_json_string(obj) : "NULL");
127 afb_req_fail(request, "failed", "framework daemon failure");
130 afb_req_success(request, obj, NULL);
134 /************************** entries ******************************/
136 static void runnables(struct afb_req request)
138 embed_call_void(request, _runnables_);
141 static void detail(struct afb_req request)
143 call_appid(request, _detail_);
146 static void start(struct afb_req request)
148 struct json_object *obj;
149 const char *id, *mode;
154 id = afb_req_argument(request, _id_);
156 afb_req_fail(request, "bad-request", "missing 'id'");
160 mode = afb_req_argument(request, _mode_);
161 if (mode == NULL || !strcmp(mode, _auto_)) {
162 mode = interface->mode == AFB_MODE_REMOTE ? _remote_ : _local_;
165 /* create the query */
166 rc = asprintf(&query, "{\"id\":\"%s\",\"mode\":\"%s\"}", id, mode);
168 afb_req_fail(request, "server-error", "out of memory");
172 /* calls the service */
173 obj = jbus_call_sj_sync(jbus, _start_, query);
174 if (interface->verbose)
175 fprintf(stderr, "(afm-main-plugin) start(%s) -> %s\n", query, obj ? json_object_to_json_string(obj) : "NULL");
180 afb_req_fail(request, "failed", "framework daemon failure");
184 /* embed if needed */
185 if (json_object_get_type(obj) == json_type_int)
186 obj = embed(_runid_, obj);
187 afb_req_success(request, obj, NULL);
190 static void terminate(struct afb_req request)
192 call_runid(request, _terminate_);
195 static void stop(struct afb_req request)
197 call_runid(request, _stop_);
200 static void continue_(struct afb_req request)
202 call_runid(request, _continue_);
205 static void runners(struct afb_req request)
207 embed_call_void(request, _runners_);
210 static void state(struct afb_req request)
212 call_runid(request, _state_);
215 static void install(struct afb_req request)
217 struct json_object *obj;
219 const char *filename;
222 /* get the argument */
223 arg = afb_req_get(request, "widget");
224 filename = arg.value;
225 if (filename == NULL || !arg.is_file) {
226 afb_req_fail(request, "bad-request", "missing 'widget' file");
230 /* makes the query */
231 if (0 >= asprintf(&query, "\"%s\"", filename)) {
232 afb_req_fail(request, "server-error", "out of memory");
236 obj = jbus_call_sj_sync(jbus, _install_, query);
237 if (interface->verbose)
238 fprintf(stderr, "(afm-main-plugin) install(%s) -> %s\n", query, obj ? json_object_to_json_string(obj) : "NULL");
243 afb_req_fail(request, "failed", "framework daemon failure");
247 /* embed if needed */
248 obj = embed(_id_, obj);
249 afb_req_success(request, obj, NULL);
252 static void uninstall(struct afb_req request)
254 call_appid(request, _uninstall_);
257 static const struct AFB_restapi plug_apis[] =
259 {_runnables_, AFB_SESSION_CHECK, runnables, "Get list of runnable applications"},
260 {_detail_ , AFB_SESSION_CHECK, detail, "Get the details for one application"},
261 {_start_ , AFB_SESSION_CHECK, start, "Start an application"},
262 {_terminate_, AFB_SESSION_CHECK, terminate, "Terminate a running application"},
263 {_stop_ , AFB_SESSION_CHECK, stop, "Stop (pause) a running application"},
264 {_continue_ , AFB_SESSION_CHECK, continue_, "Continue (resume) a stopped application"},
265 {_runners_ , AFB_SESSION_CHECK, runners, "Get the list of running applications"},
266 {_state_ , AFB_SESSION_CHECK, state, "Get the state of a running application"},
267 {_install_ , AFB_SESSION_CHECK, install, "Install an application using a widget file"},
268 {_uninstall_, AFB_SESSION_CHECK, uninstall, "Uninstall an application"},
269 { NULL, 0, NULL, NULL }
272 static const struct AFB_plugin plug_desc = {
273 .type = AFB_PLUGIN_JSON,
274 .info = "Application Framework Master Service",
275 .prefix = "afm-main",
279 const struct AFB_plugin *pluginRegister(const struct AFB_interface *itf)
283 jbus = create_jbus_session("/org/AGL/afm/user");
286 fprintf(stderr, "ERROR: %s:%d: can't connect to DBUS session\n", __FILE__, __LINE__);