2 * Copyright (C) 2016 "IoT.bzh"
3 * Author "Manuel Bachmann"
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.
19 #include <json-c/json.h>
21 #include "media-api.h"
22 #include "media-rygel.h"
24 #include "afb-plugin.h"
25 #include "afb-req-itf.h"
27 json_object* _rygel_list (mediaCtxHandleT *);
29 /* ------ LOCAL HELPER FUNCTIONS --------- */
31 /* private client context creation ; default values */
32 static mediaCtxHandleT* initMediaCtx () {
36 ctx = malloc (sizeof(mediaCtxHandleT));
37 ctx->media_server = NULL;
43 /* ------ PUBLIC PLUGIN FUNCTIONS --------- */
45 static void init (struct afb_req request) { /* AFB_SESSION_CHECK */
47 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
50 /* create a private client context */
53 afb_req_context_set (request, ctx, free);
56 /* initialize server connection */
57 if (!ctx->media_server)
60 jresp = json_object_new_object ();
61 json_object_object_add (jresp, "init", json_object_new_string ("success"));
62 afb_req_success (request, jresp, "Media - Initialized");
65 static void list (struct afb_req request) { /* AFB_SESSION_CHECK */
67 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
70 jresp = _rygel_list (ctx);
73 afb_req_fail (request, "failed", "no content found in media server");
77 afb_req_success (request, jresp, "Media - Listed");
80 static void selecting (struct afb_req request) { /* AFB_SESSION_CHECK */
82 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
83 const char *value = afb_req_value (request, "value");
88 /* no "?value=" parameter : return current index */
90 snprintf (index_str, sizeof(index_str), "%d", ctx->index);
91 jresp = json_object_new_object();
92 json_object_object_add (jresp, "index", json_object_new_string (index_str));
95 /* "?value=" parameter is negative */
96 else if (atoi(value) < 0) {
97 afb_req_fail (request, "failed", "chosen index cannot be negatuve");
101 /* "?value=" parameter is positive */
102 else if (atoi(value) >= 0) {
103 index = (unsigned int) atoi(value);
105 if (!_rygel_select (ctx, index)) {
106 afb_req_fail (request, "failed", "chosen index superior to current media count");
111 jresp = json_object_new_object();
112 json_object_object_add (jresp, "index", json_object_new_string (value));
117 afb_req_success (request, jresp, "Media - Listed");
120 static void play (struct afb_req request) { /* AFB_SESSION_CHECK */
122 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
125 if (!_rygel_do (ctx, PLAY, NULL)) {
126 afb_req_fail (request, "failed", "could not play chosen media");
130 jresp = json_object_new_object ();
131 json_object_object_add (jresp, "play", json_object_new_string ("success"));
132 afb_req_success (request, jresp, "Media - Listed");
135 static void stop (struct afb_req request) { /* AFB_SESSION_CHECK */
137 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
140 if (!_rygel_do (ctx, STOP, NULL)) {
141 afb_req_fail (request, "failed", "could not stop chosen media");
145 jresp = json_object_new_object ();
146 json_object_object_add (jresp, "stop", json_object_new_string ("success"));
147 afb_req_success (request, jresp, "Media - Stopped");
150 static void pausing (struct afb_req request) { /* AFB_SESSION_CHECK */
152 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
155 if (!_rygel_do (ctx, PAUSE, NULL)) {
156 afb_req_fail (request, "failed", "could not pause chosen media");
160 jresp = json_object_new_object();
161 json_object_object_add (jresp, "pause", json_object_new_string ("success"));
162 afb_req_success (request, jresp, "Media - Paused");
165 static void seek (struct afb_req request) { /* AFB_SESSION_CHECK */
167 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
168 const char *value = afb_req_value (request, "value");
171 /* no "?value=" parameter : return error */
173 afb_req_fail (request, "failed", "you must provide a time");
177 if (!_rygel_do (ctx, SEEK, (char *)value)) {
178 afb_req_fail (request, "failed", "could not seek chosen media");
182 jresp = json_object_new_object();
183 json_object_object_add (jresp, "seek", json_object_new_string ("success"));
184 afb_req_success (request, jresp, "Media - Sought");
188 static void upload (AFB_request *request, AFB_PostItem *item) { /* AFB_SESSION_CHECK */
190 mediaCtxHandleT *ctx = (mediaCtxHandleT*) afb_req_context_get(request);
191 AFB_PostCtx *postFileCtx;
195 /* item is !NULL until transfer is complete */
197 return getPostFile (request, item, "media");
199 /* target intermediary file path */
200 path = getPostPath (request);
203 fprintf (stderr, "Error encoutered during intermediary file transfer\n");
205 else if (!_rygel_upload (ctx, path)) {
206 request->errcode = MHD_HTTP_EXPECTATION_FAILED;
207 request->jresp = jsonNewMessage (AFB_FAIL, "Error when uploading file to media server... could not complete");
211 request->errcode = MHD_HTTP_OK;
212 request->jresp = jsonNewMessage (AFB_SUCCESS, "upload=%s done", path);
215 /* finalizes file transfer */
216 return getPostFile (request, item, NULL);
220 static void ping (struct afb_req request) { /* AFB_SESSION_NONE */
221 afb_req_success (request, NULL, "Media - Ping succeeded");
225 static const struct AFB_restapi pluginApis[]= {
226 {"init" , AFB_SESSION_CHECK, init , "Media API - init" },
227 {"list" , AFB_SESSION_CHECK, list , "Media API - list" },
228 {"select" , AFB_SESSION_CHECK, selecting , "Media API - select" },
229 {"play" , AFB_SESSION_CHECK, play , "Media API - play" },
230 {"stop" , AFB_SESSION_CHECK, stop , "Media API - stop" },
231 {"pause" , AFB_SESSION_CHECK, pausing , "Media API - pause" },
232 {"seek" , AFB_SESSION_CHECK, seek , "Media API - seek" },
233 // {"upload" , AFB_SESSION_CHECK, (AFB_apiCB)upload , "Media API - upload" },
234 {"ping" , AFB_SESSION_NONE, ping , "Media API - ping" },
238 static const struct AFB_plugin pluginDesc = {
239 .type = AFB_PLUGIN_JSON,
240 .info = "Application Framework Binder - Media plugin",
245 const struct AFB_plugin *pluginRegister (const struct AFB_interface *itf)