removed private api and fix some few warnings
[src/app-framework-binder.git] / plugins / media / media-api.c
1 /*
2  * Copyright (C) 2016 "IoT.bzh"
3  * Author "Manuel Bachmann"
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 #include "media-api.h"
20
21 /* ------ LOCAL HELPER FUNCTIONS --------- */
22
23 /* private client context creation ; default values */
24 STATIC mediaCtxHandleT* initMediaCtx () {
25
26     mediaCtxHandleT *ctx;
27
28     ctx = malloc (sizeof(mediaCtxHandleT));
29     ctx->media_server = NULL;
30     ctx->index = 0;
31
32     return ctx;
33 }
34
35 /* called when client session dies [e.g. client quits for more than 15mns] */
36 STATIC void freeMedia (void *context, void *handle) {
37
38     free (context);
39 }
40
41 /* ------ PUBLIC PLUGIN FUNCTIONS --------- */
42
43 STATIC json_object* init (AFB_request *request) {        /* AFB_SESSION_CHECK */
44
45     mediaCtxHandleT *ctx;
46     json_object *jresp;
47
48     /* create a private client context */
49     if (!request->context)
50         request->context = initMediaCtx();
51
52     ctx = (mediaCtxHandleT*)request->context;
53
54     /* initialize server connection */
55     if (!ctx->media_server)
56       _rygel_init (request->context);
57
58     jresp = json_object_new_object();
59     json_object_object_add(jresp, "info", json_object_new_string ("Media initialized"));
60     return jresp;
61 }
62
63 STATIC json_object* list (AFB_request *request) {        /* AFB_SESSION_CHECK */
64
65     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
66     json_object *jresp;
67
68     jresp = _rygel_list (ctx);
69
70     if (!jresp)
71       return jsonNewMessage(AFB_FAIL, "No content found in media server");
72
73     return jresp;
74 }
75
76 STATIC json_object* selecting (AFB_request *request) {   /* AFB_SESSION_CHECK */
77
78     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
79     const char *value = getQueryValue (request, "value");
80     json_object *jresp;
81     unsigned int index;
82     char index_str[5];
83
84     /* no "?value=" parameter : return current index */
85     if (!value) {
86         snprintf (index_str, sizeof(index_str), "%d", ctx->index);
87         jresp = json_object_new_object();
88         json_object_object_add (jresp, "index", json_object_new_string (index_str));
89     }
90
91     /* "?value=" parameter is negative */
92     else if (atoi(value) < 0)
93         return jsonNewMessage(AFB_FAIL, "Chosen index cannot be negative");
94
95     /* "?value=" parameter is positive */
96     else if (atoi(value) >= 0) {
97         index = (unsigned int) atoi(value);
98
99         if (!_rygel_select (ctx, index))
100           return jsonNewMessage(AFB_FAIL, "Chosen index superior to current media count");
101
102         ctx->index = index;
103         jresp = json_object_new_object();
104         json_object_object_add (jresp, "index", json_object_new_string (value));
105     }
106     else
107         jresp = NULL;
108
109     return jresp;
110 }
111
112 STATIC json_object* play (AFB_request *request) {        /* AFB_SESSION_CHECK */
113
114     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
115
116     if (!_rygel_do (ctx, PLAY, NULL))
117       return jsonNewMessage(AFB_FAIL, "Could not play chosen media");
118
119     return jsonNewMessage(AFB_SUCCESS, "PLaying media");
120 }
121
122 STATIC json_object* stop (AFB_request *request) {        /* AFB_SESSION_CHECK */
123
124     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
125
126     if (!_rygel_do (ctx, STOP, NULL))
127       return jsonNewMessage(AFB_FAIL, "Could not stop chosen media");
128
129     return jsonNewMessage(AFB_SUCCESS, "Stopped media");
130 }
131
132 STATIC json_object* pausing (AFB_request *request) {     /* AFB_SESSION_CHECK */
133
134     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
135
136     if (!_rygel_do (ctx, PAUSE, NULL))
137       return jsonNewMessage(AFB_FAIL, "Could not pause chosen media");
138
139     return jsonNewMessage(AFB_SUCCESS, "Paused media");
140 }
141
142 STATIC json_object* seek (AFB_request *request) {        /* AFB_SESSION_CHECK */
143
144     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
145     const char *value = getQueryValue (request, "value");
146
147     /* no "?value=" parameter : return error */
148     if (!value)
149       return jsonNewMessage(AFB_FAIL, "You must provide a time");
150
151     if (!_rygel_do (ctx, SEEK, value))
152       return jsonNewMessage(AFB_FAIL, "Could not seek chosen media");
153
154     return jsonNewMessage(AFB_SUCCESS, "Seeked media");
155 }
156
157 STATIC json_object* upload (AFB_request *request, AFB_PostItem *item) { /* AFB_SESSION_CHECK */
158
159     mediaCtxHandleT *ctx = (mediaCtxHandleT*)request->context;
160     AFB_PostCtx *postFileCtx;
161     json_object *jresp;
162     char *path;
163
164     /* item is !NULL until transfer is complete */
165     if (item != NULL)
166       return getPostFile (request, item, "media");
167
168     /* target intermediary file path */
169     path = getPostPath (request);
170
171     if (!path)
172         fprintf (stderr, "Error encoutered during intermediary file transfer\n");
173
174     else if (!_rygel_upload (ctx, path)) {
175         request->errcode = MHD_HTTP_EXPECTATION_FAILED;
176         request->jresp = jsonNewMessage (AFB_FAIL, "Error when uploading file to media server... could not complete");
177     }
178
179     else {
180         request->errcode = MHD_HTTP_OK;
181         request->jresp = jsonNewMessage (AFB_SUCCESS, "upload=%s done", path);
182     }
183
184     /* finalizes file transfer */
185     return getPostFile (request, item, NULL);
186 }
187
188 STATIC json_object* ping (AFB_request *request) {         /* AFB_SESSION_NONE */
189     return jsonNewMessage(AFB_SUCCESS, "Ping Binder Daemon - Media API");
190 }
191
192
193 STATIC AFB_restapi pluginApis[]= {
194   {"init"   , AFB_SESSION_CHECK,  (AFB_apiCB)init       , "Media API - init"   },
195   {"list"   , AFB_SESSION_CHECK,  (AFB_apiCB)list       , "Media API - list"   },
196   {"select" , AFB_SESSION_CHECK,  (AFB_apiCB)selecting  , "Media API - select" },
197   {"play"   , AFB_SESSION_CHECK,  (AFB_apiCB)play       , "Media API - play"   },
198   {"stop"   , AFB_SESSION_CHECK,  (AFB_apiCB)stop       , "Media API - stop"   },
199   {"pause"  , AFB_SESSION_CHECK,  (AFB_apiCB)pausing    , "Media API - pause"  },
200   {"seek"   , AFB_SESSION_CHECK,  (AFB_apiCB)seek       , "Media API - seek"   },
201   {"upload" , AFB_SESSION_CHECK,  (AFB_apiCB)upload     , "Media API - upload" },
202   {"ping"   , AFB_SESSION_NONE,   (AFB_apiCB)ping       , "Media API - ping"   },
203   {NULL}
204 };
205
206 PUBLIC AFB_plugin* pluginRegister () {
207     AFB_plugin *plugin = malloc (sizeof(AFB_plugin));
208     plugin->type  = AFB_PLUGIN_JSON;
209     plugin->info  = "Application Framework Binder - Media plugin";
210     plugin->prefix  = "media";
211     plugin->apis  = pluginApis;
212
213     /*plugin->handle = initRadioPlugin();*/
214     plugin->freeCtxCB = (AFB_freeCtxCB)freeMedia;
215
216     return (plugin);
217 };