afm-main: adds install/uninstall
[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         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
74         return obj;
75 }
76
77 static struct json_object *call_appid(AFB_request *request, AFB_PostItem *item)
78 {
79         struct json_object *obj;
80         char *sid;
81         const char *id = getQueryValue(request, _id_);
82         if (id == NULL) {
83                 request->errcode = MHD_HTTP_BAD_REQUEST;
84                 return NULL;
85         }
86         if (0 >= asprintf(&sid, "\"%s\"", id)) {
87                 request->errcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
88                 return NULL;
89         }
90         obj = jbus_call_sj_sync(jbus, request->api, sid);
91         free(sid);
92         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
93         return obj;
94 }
95
96 static struct json_object *call_runid(AFB_request *request, AFB_PostItem *item)
97 {
98         struct json_object *obj;
99         const char *id = getQueryValue(request, _runid_);
100         if (id == NULL) {
101                 request->errcode = MHD_HTTP_BAD_REQUEST;
102                 return NULL;
103         }
104         obj = jbus_call_sj_sync(jbus, request->api, id);
105         request->errcode = obj ? MHD_HTTP_OK : MHD_HTTP_FAILED_DEPENDENCY;
106         return obj;
107 }
108
109 static struct json_object *call_void__runnables(AFB_request *request, AFB_PostItem *item)
110 {
111         return embed(request, _runnables_, call_void(request, item));
112 }
113
114 static struct json_object *call_appid__runid(AFB_request *request, AFB_PostItem *item)
115 {
116         return embed(request, _runid_, call_appid(request, item));
117 }
118
119 static struct json_object *call_void__runners(AFB_request *request, AFB_PostItem *item)
120 {
121         return embed(request, _runners_, call_void(request, item));
122 }
123
124 static struct json_object *call_file__appid(AFB_request *request, AFB_PostItem *item)
125 {
126         if (item == NULL) {
127                 struct json_object *obj;
128                 char *query;
129                 const char *filename = getPostPath(request);
130                 request->jresp = NULL;
131                 if (0 >= asprintf(&query, "\"%s\"", filename))
132                         request->errcode = MHD_HTTP_INTERNAL_SERVER_ERROR;
133                 else {
134                         obj = jbus_call_sj_sync(jbus, request->api, query);
135                         free(query);
136                         if (obj)
137                                 request->jresp = embed(request, _id_, obj);
138                         else
139                                 request->errcode = MHD_HTTP_FAILED_DEPENDENCY;
140                 }
141                 unlink(filename);
142         }
143         return getPostFile (request, item, "/tmp");
144 }
145
146 static AFB_restapi plug_apis[] =
147 {
148         {_runnables_, AFB_SESSION_CHECK, (AFB_apiCB)call_void__runnables,  "Get list of runnable applications"},
149         {_detail_   , AFB_SESSION_CHECK, (AFB_apiCB)call_appid, "Get the details for one application"},
150         {_start_    , AFB_SESSION_CHECK, (AFB_apiCB)call_appid__runid, "Start an application"},
151         {_terminate_, AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Terminate a running application"},
152         {_stop_     , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Stop (pause) a running application"},
153         {_continue_ , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Continue (resume) a stopped application"},
154         {_runners_  , AFB_SESSION_CHECK, (AFB_apiCB)call_void__runners,  "Get the list of running applications"},
155         {_state_    , AFB_SESSION_CHECK, (AFB_apiCB)call_runid, "Get the state of a running application"},
156         {_install_  , AFB_SESSION_CHECK, (AFB_apiCB)call_file__appid,  "Install an application using a widget file"},
157         {_uninstall_, AFB_SESSION_CHECK, (AFB_apiCB)call_appid, "Uninstall an application"},
158         {NULL}
159 };
160
161 static AFB_plugin plug_desc = {
162         .type = AFB_PLUGIN_JSON,
163         .info = "Application Framework Master Service",
164         .prefix = "afm-main",
165         .apis = plug_apis
166 };
167
168 AFB_plugin *pluginRegister()
169 {
170         jbus = create_jbus(1, "/org/AGL/afm/user");
171         return jbus ? &plug_desc : NULL;
172 }
173