Final modifications for Radio-Audio API communication
[src/app-framework-binder.git] / plugins / audio / audio-api.c
1 /*
2  * Copyright (C) 2015 "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 "audio-api.h"
20 #include "audio-alsa.h"
21
22
23 /* ------ LOCAL HELPER FUNCTIONS --------- */
24
25 /* private client context creation ; default values */
26 STATIC audioCtxHandleT* initAudioCtx () {
27
28     audioCtxHandleT *actx;
29
30     actx = malloc (sizeof(audioCtxHandleT));
31     actx->idx = -1;
32     actx->volume = 25;
33     actx->channels = 2;
34     actx->mute = 0;
35
36     return actx;
37 }
38
39 STATIC AFB_error releaseAudio (audioCtxHandleT *actx) {
40
41     /* power it off */
42     _alsa_free (actx->idx);
43
44     /* clean client context */
45     actx->idx = -1;
46
47     return AFB_SUCCESS;
48 }
49
50 /* called when client session dies [e.g. client quits for more than 15mns] */
51 STATIC json_object* freeAudio (AFB_clientCtx *client) {
52
53     releaseAudio (client->ctx);
54     free (client->ctx);
55     
56     return jsonNewMessage (AFB_SUCCESS, "Released radio and client context");
57 }
58
59
60 /* ------ PUBLIC PLUGIN FUNCTIONS --------- */
61
62 STATIC json_object* init (AFB_request *request) {       /* AFB_SESSION_CREATE */
63
64     audioCtxHandleT *actx;
65     json_object *jresp;
66     int idx;
67
68     /* create a private client context */
69     actx = initAudioCtx();
70     request->client->ctx = (audioCtxHandleT*)actx;
71     
72     _alsa_init("default", actx);
73     
74     jresp = json_object_new_object();
75     json_object_object_add (jresp, "token", json_object_new_string (request->client->token));
76     return jresp;
77 }
78
79 STATIC json_object* volume (AFB_request *request) {      /* AFB_SESSION_CHECK */
80
81     audioCtxHandleT *actx = (audioCtxHandleT*)request->client->ctx;
82     const char *value = getQueryValue (request, "value");
83     json_object *jresp;
84     int volume;
85     char volume_str[256];
86
87     /* no "?value=" parameter : return current state */
88     if (!value) {
89         actx->volume = _alsa_get_volume (actx->idx);
90         snprintf (volume_str, sizeof(volume_str), "%d", actx->volume);
91         jresp = json_object_new_object();
92         json_object_object_add (jresp, "volume", json_object_new_string(volume_str));
93     }
94
95     /* "?value=" parameter, set volume */
96     else {
97         volume = atoi (value);
98         if (100 < volume < 0) {
99             request->errcode = MHD_HTTP_SERVICE_UNAVAILABLE;
100             return (jsonNewMessage (AFB_FAIL, "Volume must be between 0 and 100"));
101         }
102         actx->volume = volume;
103         _alsa_set_volume (actx->idx, actx->volume);
104
105         snprintf (volume_str, sizeof(volume_str), "%d", actx->volume);
106         jresp = json_object_new_object();
107         json_object_object_add (jresp, "volume", json_object_new_string(volume_str));
108     }
109
110     return jresp;
111 }
112
113 STATIC json_object* channels (AFB_request *request) {    /* AFB_SESSION_CHECK */
114
115     audioCtxHandleT *actx = (audioCtxHandleT*)request->client->ctx;
116     const char *value = getQueryValue (request, "value");
117     json_object *jresp = json_object_new_object();
118     char channels_str[256];
119
120     /* no "?value=" parameter : return current state */
121     if (!value) {
122         snprintf (channels_str, sizeof(channels_str), "%d", actx->channels);
123         json_object_object_add (jresp, "channels", json_object_new_string (channels_str));
124     }
125
126     /* "?value=" parameter, set channels */
127     else {
128         actx->channels = atoi (value);
129         _alsa_set_channels (actx->idx, actx->channels);
130
131         snprintf (channels_str, sizeof(channels_str), "%d", actx->channels);
132         json_object_object_add (jresp, "channels", json_object_new_string (channels_str));
133     }
134
135     return jresp;
136 }
137
138 STATIC json_object* mute (AFB_request *request) {        /* AFB_SESSION_CHECK */
139
140     audioCtxHandleT *actx = (audioCtxHandleT*)request->client->ctx;
141     const char *value = getQueryValue (request, "value");
142     json_object *jresp = json_object_new_object();
143
144     /* no "?value=" parameter : return current state */
145     if (!value) {
146         actx->mute = _alsa_get_mute (actx->idx);
147         actx->mute ?
148             json_object_object_add (jresp, "mute", json_object_new_string ("on"))
149           : json_object_object_add (jresp, "mute", json_object_new_string ("off"));
150     }
151
152     /* "?value=" parameter is "1" or "on" */
153     else if ( atoi(value) == 1 || !strcasecmp(value, "on") ) {
154         actx->mute = 1;
155         _alsa_set_mute (actx->idx, actx->mute);
156
157         json_object_object_add (jresp, "mute", json_object_new_string ("on"));
158     }
159
160     /* "?value=" parameter is "0" or "off" */
161     else if ( atoi(value) == 0 || !strcasecmp(value, "off") ) {
162         actx->mute = 0;
163         _alsa_set_mute (actx->idx, actx->mute);
164
165         json_object_object_add (jresp, "mute", json_object_new_string ("off"));
166     }
167
168     return jresp;
169 }
170
171 STATIC json_object* status (AFB_request *request) {      /* AFB_SESSION_RENEW */
172     return NULL;
173 }
174
175
176 STATIC AFB_restapi pluginApis[]= {
177   {"init"    , AFB_SESSION_CREATE, (AFB_apiCB)init      , "Audio API - init"},
178   {"volume"  , AFB_SESSION_CHECK,  (AFB_apiCB)volume    , "Audio API - volume"},
179   {"channels", AFB_SESSION_CHECK,  (AFB_apiCB)channels  , "Audio API - channels"},
180   {"mute"    , AFB_SESSION_CHECK,  (AFB_apiCB)mute      , "Audio API - mute"},
181   {"status"  , AFB_SESSION_RENEW,  (AFB_apiCB)status    , "Audio API - status"},
182   {NULL}
183 };
184
185 PUBLIC AFB_plugin *audioRegister () {
186     AFB_plugin *plugin = malloc (sizeof(AFB_plugin));
187     plugin->type   = AFB_PLUGIN_JSON;
188     plugin->info   = "Application Framework Binder - Audio plugin";
189     plugin->prefix = "audio";        
190     plugin->apis   = pluginApis;
191
192     plugin->freeCtxCB = freeAudio;
193
194     return (plugin);
195 };