afm-main-plugin: Adds verbose prompts
[src/app-framework-binder.git] / plugins / afm-main-plugin / afm-main-plugin.c
1 /*
2  * Copyright (C) 2015 "IoT.bzh"
3  * Author "Fulup Ar Foll"
4  *
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.
9  *
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.
14  *
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/>.
17  */
18
19
20 #include "local-def.h"
21
22 #include "utils-jbus.h"
23
24 static const char _id_[]    = "id";
25 static const char _runid_[] = "runid";
26 static char _runnables_[]   = "runnables";
27 static char _detail_[]      = "detail";
28 static char _start_[]       = "start";
29 static char _terminate_[]   = "terminate";
30 static char _stop_[]        = "stop";
31 static char _continue_[]    = "continue";
32 static char _runners_[]     = "runners";
33 static char _state_[]       = "state";
34 static char _install_[]     = "install";
35 static char _uninstall_[]   = "uninstall";
36
37 static struct jbus *jbus;
38
39 static struct json_object *embed(AFB_request *request, const char *tag, struct json_object *obj)
40 {
41         struct json_object *result;
42
43         if (obj == NULL)
44                 result = NULL;
45         else if (!tag) {
46                 request->errcode = MHD_HTTP_OK;
47                 result = obj;
48         }
49         else {
50                 result = json_object_new_object();
51                 if (result == NULL) {
52                         /* can't embed */
53                         result = obj;
54                         request->errcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
55                 }
56                 else {
57                         /* TODO why is json-c not returning a status? */
58                         json_object_object_add(result, tag, obj);
59                         request->errcode = MHD_HTTP_OK;
60                 }
61         }
62         return result;
63 }
64
65 static struct json_object *call(AFB_request *request, AFB_PostItem *item, const char *tag, struct json_object *(*fun)(AFB_request*,AFB_PostItem*))
66 {
67         return embed(request, tag, fun(request, item));
68 }
69
70 static struct json_object *call_void(AFB_request *request, AFB_PostItem *item)
71 {
72         struct json_object *obj = jbus_call_sj_sync(jbus, request->api, "true");
73         if (verbose)
74                 fprintf(stderr, "(afm-main-plugin) call_void: true -> %s\n", obj ? json_object_to_json_string(obj) : "NULL");
75         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
76         return obj;
77 }
78
79 static struct json_object *call_appid(AFB_request *request, AFB_PostItem *item)
80 {
81         struct json_object *obj;
82         char *sid;
83         const char *id = getQueryValue(request, _id_);
84         if (id == NULL) {
85                 request->errcode = MHD_HTTP_BAD_REQUEST;
86                 return NULL;
87         }
88         if (0 >= asprintf(&sid, "\"%s\"", id)) {
89                 request->errcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
90                 return NULL;
91         }
92         obj = jbus_call_sj_sync(jbus, request->api, sid);
93         if (verbose)
94                 fprintf(stderr, "(afm-main-plugin) call_appid: %s -> %s\n", sid, obj ? json_object_to_json_string(obj) : "NULL");
95         free(sid);
96         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
97         return obj;
98 }
99
100 static struct json_object *call_runid(AFB_request *request, AFB_PostItem *item)
101 {
102         struct json_object *obj;
103         const char *id = getQueryValue(request, _runid_);
104         if (id == NULL) {
105                 request->errcode = MHD_HTTP_BAD_REQUEST;
106                 return NULL;
107         }
108         obj = jbus_call_sj_sync(jbus, request->api, id);
109         if (verbose)
110                 fprintf(stderr, "(afm-main-plugin) call_runid: %s -> %s\n", id, obj ? json_object_to_json_string(obj) : "NULL");
111         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
112         return obj;
113 }
114
115 static struct json_object *call_void__runnables(AFB_request *request, AFB_PostItem *item)
116 {
117         return embed(request, _runnables_, call_void(request, item));
118 }
119
120 static struct json_object *call_appid__runid(AFB_request *request, AFB_PostItem *item)
121 {
122         return embed(request, _runid_, call_appid(request, item));
123 }
124
125 static struct json_object *call_void__runners(AFB_request *request, AFB_PostItem *item)
126 {
127         return embed(request, _runners_, call_void(request, item));
128 }
129
130 static struct json_object *call_file__appid(AFB_request *request, AFB_PostItem *item)
131 {
132         if (item == NULL) {
133                 const char *filename = getPostPath(request);
134                 if (filename != NULL) {
135                         struct json_object *obj;
136                         char *query;
137                         request->jresp = NULL;
138                         if (0 >= asprintf(&query, "\"%s\"", filename))
139                                 request->errcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
140                         else {
141                                 obj = jbus_call_sj_sync(jbus, request->api, query);
142                                 if (verbose)
143                                         fprintf(stderr, "(afm-main-plugin) call_file_appid: %s -> %s\n", query, obj ? json_object_to_json_string(obj) : "NULL");
144                                 free(query);
145                                 if (obj)
146                                         request->jresp = embed(request, _id_, obj);
147                                 else
148                                         request->errcode = MHD_HTTP_FAILED_DEPENDENCY;
149                         }
150                         unlink(filename);
151                 }
152         }
153         return getPostFile (request, item, "/tmp/upload");
154 }
155
156 static AFB_restapi plug_apis[] =
157 {
158         {_runnables_, AFB_SESSION_CHECK, (AFB_apiCB)call_void__runnables,  "Get list of runnable applications"},
159         {_detail_   , AFB_SESSION_CHECK, (AFB_apiCB)call_appid, "Get the details for one application"},
160         {_start_    , AFB_SESSION_CHECK, (AFB_apiCB)call_appid__runid, "Start an application"},
161         {_terminate_, AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Terminate a running application"},
162         {_stop_     , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Stop (pause) a running application"},
163         {_continue_ , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Continue (resume) a stopped application"},
164         {_runners_  , AFB_SESSION_CHECK, (AFB_apiCB)call_void__runners,  "Get the list of running applications"},
165         {_state_    , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Get the state of a running application"},
166         {_install_  , AFB_SESSION_CHECK, (AFB_apiCB)call_file__appid,  "Install an application using a widget file"},
167         {_uninstall_, AFB_SESSION_CHECK, (AFB_apiCB)call_appid, "Uninstall an application"},
168         {NULL}
169 };
170
171 static AFB_plugin plug_desc = {
172         .type = AFB_PLUGIN_JSON,
173         .info = "Application Framework Master Service",
174         .prefix = "afm-main",
175         .apis = plug_apis
176 };
177
178 AFB_plugin *pluginRegister()
179 {
180         jbus = create_jbus(1, "/org/AGL/afm/user");
181         if (jbus)
182                 return &plug_desc;
183         fprintf(stderr, "ERROR: %s:%d: can't connect to DBUS session\n", __FILE__, __LINE__);
184         return NULL;
185 }
186