2 * Copyright (C) 2015 "IoT.bzh"
3 * Author "Fulup Ar Foll"
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #define _GNU_SOURCE /* See feature_test_macros(7) */
24 #include "afb-plugin.h"
26 #include "utils-sbus.h"
27 #include "utils-jbus.h"
29 static const char _added_[] = "added";
30 static const char _auto_[] = "auto";
31 static const char _continue_[] = "continue";
32 static const char _changed_[] = "changed";
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;
50 static struct afb_evmgr evmgr;
52 static struct jbus *jbus;
54 static void application_list_changed(const char *data, void *closure)
56 afb_evmgr_push(evmgr, "application-list-changed", NULL);
59 static struct json_object *embed(const char *tag, struct json_object *obj)
61 struct json_object *result;
68 result = json_object_new_object();
74 /* TODO why is json-c not returning a status? */
75 json_object_object_add(result, tag, obj);
81 static void embed_call_void(struct afb_req request, const char *method)
83 struct json_object *obj = jbus_call_sj_sync(jbus, method, "true");
84 if (interface->verbosity)
85 fprintf(stderr, "(afm-main-plugin) %s(true) -> %s\n", method,
86 obj ? json_object_to_json_string(obj) : "NULL");
88 afb_req_fail(request, "failed", "framework daemon failure");
91 obj = json_object_get(obj);
92 obj = embed(method, obj);
94 afb_req_fail(request, "failed", "framework daemon failure");
97 afb_req_success(request, obj, NULL);
100 static void call_appid(struct afb_req request, const char *method)
102 struct json_object *obj;
104 const char *id = afb_req_value(request, _id_);
106 afb_req_fail(request, "bad-request", "missing 'id'");
109 if (asprintf(&sid, "\"%s\"", id) <= 0) {
110 afb_req_fail(request, "server-error", "out of memory");
113 obj = jbus_call_sj_sync(jbus, method, sid);
114 if (interface->verbosity)
115 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, sid,
116 obj ? json_object_to_json_string(obj) : "NULL");
119 afb_req_fail(request, "failed", "framework daemon failure");
122 obj = json_object_get(obj);
123 afb_req_success(request, obj, NULL);
126 static void call_runid(struct afb_req request, const char *method)
128 struct json_object *obj;
129 const char *id = afb_req_value(request, _runid_);
131 afb_req_fail(request, "bad-request", "missing 'runid'");
134 obj = jbus_call_sj_sync(jbus, method, id);
135 if (interface->verbosity)
136 fprintf(stderr, "(afm-main-plugin) %s(%s) -> %s\n", method, id,
137 obj ? json_object_to_json_string(obj) : "NULL");
139 afb_req_fail(request, "failed", "framework daemon failure");
142 obj = json_object_get(obj);
143 afb_req_success(request, obj, NULL);
147 /************************** entries ******************************/
149 static void runnables(struct afb_req request)
151 embed_call_void(request, _runnables_);
154 static void detail(struct afb_req request)
156 call_appid(request, _detail_);
159 static void start(struct afb_req request)
161 struct json_object *obj;
162 const char *id, *mode;
167 id = afb_req_value(request, _id_);
169 afb_req_fail(request, "bad-request", "missing 'id'");
173 mode = afb_req_value(request, _mode_);
174 if (mode == NULL || !strcmp(mode, _auto_)) {
175 mode = interface->mode == AFB_MODE_REMOTE ? _remote_ : _local_;
178 /* create the query */
179 rc = asprintf(&query, "{\"id\":\"%s\",\"mode\":\"%s\"}", id, mode);
181 afb_req_fail(request, "server-error", "out of memory");
185 /* calls the service */
186 obj = jbus_call_sj_sync(jbus, _start_, query);
187 if (interface->verbosity)
188 fprintf(stderr, "(afm-main-plugin) start(%s) -> %s\n", query,
189 obj ? json_object_to_json_string(obj) : "NULL");
193 obj = json_object_get(obj);
195 afb_req_fail(request, "failed", "framework daemon failure");
199 /* embed if needed */
200 if (json_object_get_type(obj) == json_type_int)
201 obj = embed(_runid_, obj);
202 afb_req_success(request, obj, NULL);
205 static void terminate(struct afb_req request)
207 call_runid(request, _terminate_);
210 static void stop(struct afb_req request)
212 call_runid(request, _stop_);
215 static void continue_(struct afb_req request)
217 call_runid(request, _continue_);
220 static void runners(struct afb_req request)
222 embed_call_void(request, _runners_);
225 static void state(struct afb_req request)
227 call_runid(request, _state_);
230 static void install(struct afb_req request)
232 struct json_object *obj, *added;
234 const char *filename;
237 /* get the argument */
238 arg = afb_req_get(request, "widget");
240 if (filename == NULL) {
241 afb_req_fail(request, "bad-request", "missing 'widget' file");
245 /* makes the query */
246 if (0 >= asprintf(&query, "\"%s\"", filename)) {
247 afb_req_fail(request, "server-error", "out of memory");
251 obj = jbus_call_sj_sync(jbus, _install_, query);
252 if (interface->verbosity)
254 fprintf(stderr, "(afm-main-plugin) install(%s) -> %s\n", query,
255 obj ? json_object_to_json_string(obj) : "NULL");
260 afb_req_fail(request, "failed", "framework daemon failure");
264 /* embed if needed */
265 if (json_object_object_get_ex(obj, _added_, &added))
267 obj = json_object_get(obj);
268 obj = embed(_id_, obj);
269 afb_req_success(request, obj, NULL);
272 static void uninstall(struct afb_req request)
274 call_appid(request, _uninstall_);
277 static const struct AFB_restapi plug_apis[] =
279 {_runnables_, AFB_SESSION_CHECK, runnables, "Get list of runnable applications"},
280 {_detail_ , AFB_SESSION_CHECK, detail, "Get the details for one application"},
281 {_start_ , AFB_SESSION_CHECK, start, "Start an application"},
282 {_terminate_, AFB_SESSION_CHECK, terminate, "Terminate a running application"},
283 {_stop_ , AFB_SESSION_CHECK, stop, "Stop (pause) a running application"},
284 {_continue_ , AFB_SESSION_CHECK, continue_, "Continue (resume) a stopped application"},
285 {_runners_ , AFB_SESSION_CHECK, runners, "Get the list of running applications"},
286 {_state_ , AFB_SESSION_CHECK, state, "Get the state of a running application"},
287 {_install_ , AFB_SESSION_CHECK, install, "Install an application using a widget file"},
288 {_uninstall_, AFB_SESSION_CHECK, uninstall, "Uninstall an application"},
289 { NULL, 0, NULL, NULL }
292 static const struct AFB_plugin plug_desc = {
293 .type = AFB_PLUGIN_JSON,
294 .info = "Application Framework Master Service",
295 .prefix = "afm-main",
299 static struct sbus_itf sbusitf;
301 const struct AFB_plugin *pluginRegister(const struct AFB_interface *itf)
304 struct afb_pollmgr pollmgr;
307 /* records the interface */
308 assert (interface == NULL);
310 evmgr = afb_daemon_get_evmgr(itf->daemon);
312 /* creates the sbus for session */
313 pollmgr = afb_daemon_get_pollmgr(itf->daemon);
314 sbusitf.wait = pollmgr.itf->wait;
315 sbusitf.open = pollmgr.itf->open;
316 sbusitf.on_readable = pollmgr.itf->on_readable;
317 sbusitf.on_writable = pollmgr.itf->on_writable;
318 sbusitf.on_hangup = pollmgr.itf->on_hangup;
319 sbusitf.close = pollmgr.itf->close;
320 sbus = sbus_session(&sbusitf, pollmgr.closure);
322 fprintf(stderr, "ERROR: %s:%d: can't connect to DBUS session\n", __FILE__, __LINE__);
326 /* creates the jbus for accessing afm-user-daemon */
327 jbus = create_jbus(sbus, "/org/AGL/afm/user");
333 /* records the signal handler */
334 rc = jbus_on_signal_s(jbus, _changed_, application_list_changed, NULL);