added libjson-c. added driver, webinterface and userspace daemon for the fonera mp3...
[librecmc/librecmc.git] / package / fonera-mp3 / src / cgi / main.c
1 /*
2 * FOXMP3 
3 * Copyright (c) 2007 acmesystems.it - john@acmesystems.it
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 2 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
18 *
19 * Feedback, Bugs...  info@acmesystems.it 
20 *
21 */ 
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <sys/un.h>
29 #include <unistd.h>
30 #include <netdb.h>
31
32 #include <json.h>
33
34 #define SOCKET_PATH "/tmp/foxmp3"
35
36 void print_http_header(){
37         printf("Content-type: text/html\n\n");
38 }
39
40 int read_parameter(char *name, char *value, int maxlen){
41         char *pos1, *pos2;
42         char *query_string = getenv("QUERY_STRING");
43         int success = 0;
44   
45         if(query_string){
46                 pos1 = strstr(query_string, name);
47                 if(pos1){
48                         pos1 += strlen(name) + 1;
49                         pos2 = strstr(pos1, "&");
50                         if(pos2){
51                                 *pos2 = '\0';
52                         }
53                         if(strlen(pos1) >= maxlen){
54                                 pos1[maxlen] = '\0';
55                         }
56                         strcpy(value, pos1);
57                         success = 1;
58                 }    
59         }
60         return success;
61 }
62
63
64 int issue_command(unsigned char *str){
65         int s, t, len;
66         struct sockaddr_un remote;
67
68         if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
69                 exit(1);
70         }
71         remote.sun_family = AF_UNIX;
72         strcpy(remote.sun_path, SOCKET_PATH);
73         len = strlen(remote.sun_path) + sizeof(remote.sun_family);
74         if (connect(s, (struct sockaddr *)&remote, len) == -1) {
75                 return 1;
76         }
77         if (send(s, str, strlen(str), 0) == -1) {
78                 return 1;
79         }
80         unsigned char loop = 1;
81         while(loop){
82                 if ((t=recv(s, str, 2048, 0)) > 0) {
83                         str[t] = '\0';
84                         if((strstr(str, "OK\n")) || (strstr(str, "ERROR\n"))){
85                                 loop = 0;
86                         }
87                 } else {
88                         return 1;
89                 }
90         }
91         close(s);
92         return 0;
93 }
94
95 void handle_cmd(){
96         unsigned char param[128];
97         unsigned char cmd[256];
98         int i;
99         *cmd = '\0';
100         if(read_parameter("vol", param, 128)){
101                 i = atoi(param);
102                 i = 120 - (i * 4);
103                 sprintf(cmd, "VOLUME %d", i);
104         }
105         if(read_parameter("bass", param, 128)){
106                 i = atoi(param);
107                 sprintf(cmd, "BASS %d", i);
108         }
109         if(read_parameter("start", param, 128)){
110                 sprintf(cmd, "START");
111         }
112         if(read_parameter("stop", param, 128)){
113                 sprintf(cmd, "STOP");
114         }
115         if(read_parameter("next", param, 128)){
116                 sprintf(cmd, "NEXT");
117         }
118         if(read_parameter("back", param, 128)){
119                 sprintf(cmd, "BACK");
120         }       
121         if(*cmd){
122                 issue_command(cmd);
123         }
124 }
125
126 void print_html_remote(){
127         char name[128];
128         gethostname(name, 128);
129         printf("<html><head><title>foxmp3 - %s - remote</title><link rel=\"stylesheet\" href=\"../local/stylesheet.css\" type=\"text/css\" /><script src=\"../local/json.js\" type=\"text/javascript\"></script></head><body onload=\"alpmp3_setup();\">");
130         printf("<center><p id=alpmp3_remote>");
131         printf("<table width=50%%>");
132         printf("<tr class=cellhead><th colspan=3 id=cell align=center>FOXMP3 - %s </td></tr>", name);
133         printf("<tr class=cellone><td>Action</td><td colspan=2 id=alpmp3_state>0</td></tr>");
134         printf("<tr class=celltwo><td>Filename</td><td colspan=2 id=alpmp3_filename>0</td></tr>");
135         printf("<tr class=cellone><td>Playtime</td><td colspan=2 id=alpmp3_playtime>0</td></tr>");
136         printf("<tr class=celltwo><td>Volume</td><td id=alpmp3_volume>0</td><td><a href=\"#\" onclick=\"javascript:alpmp3_remote('volup');\">Up</a>&nbsp;&nbsp;<a href=\"#\" onclick=\"javascript:alpmp3_remote('voldown')\">Down</a></td></tr>");
137         printf("<tr class=cellone><td width=20%%>Bass</td><td id=alpmp3_bass>0</td><td><a href=\"#\" onclick=\"javascript:alpmp3_remote('bassup');\" class=browse>Up</a>&nbsp;&nbsp;<a href=\"#\" onclick=\"javascript:alpmp3_remote('bassdown')\" class=browse>Down</a></td></tr>");
138         printf("<tr class=cellhead><th colspan=3 id=cell align=center><a href=\"#\" onclick=\"javascript:alpmp3_remote('start');\">Start</a>&nbsp;<a href=\"#\" onclick=\"javascript:alpmp3_remote('stop');\">Stop</a>&nbsp;<a href=\"#\" onclick=\"javascript:alpmp3_remote('back');\">Back</a>&nbsp;<a href=\"#\" onclick=\"javascript:alpmp3_remote('next');\">Next</a>&nbsp;</td></tr>");
139         printf("</table>");
140         printf("</p></center>");
141         printf("</body></html>");
142 }
143
144
145
146 void print_json_info(){
147         unsigned char str[2048];
148         sprintf(str, "STATE");
149         if(issue_command(str) == 0){
150                 int state = 0;
151                 int volume = 0;
152                 int bass = 0;
153                 int playtime = 0;
154                 unsigned char filename[1024];
155                 unsigned char *p1, *p2;
156                 
157                 memset(filename, 0, 1024);
158                 p1 = str;
159                 while(p1){
160                         p2 = strstr(p1, "\n");
161                         if(p2){
162                                 *p2 = '\0';
163                                 p2 ++;
164                                 // printf("parsing %s\n", p1);
165                                 if(strncmp(p1, "VOLUME", strlen("VOLUME")) == 0){
166                                         volume = atoi(&p1[strlen("VOLUME") + 1]);
167                                         if(volume > 120)
168                                                 volume = 120;
169                                         volume = 120 - volume;
170                                         volume /= 4;
171                                         //printf("vol = %d\n", volume);
172                                 } else if(strncmp(p1, "BASS", strlen("BASS")) == 0){
173                                         bass = atoi(&p1[strlen("BASS") + 1]);
174                                         //printf("bass = %d\n", bass);
175                                 } else if(strncmp(p1, "PLAYTIME", strlen("PLAYTIME")) == 0){
176                                         playtime = atoi(&p1[strlen("PLAYTIME") + 1]);
177                                         //printf("playtime = %d\n", playtime);
178                                 } else if(strncmp(p1, "STATE", strlen("STATE")) == 0){
179                                         if(strstr(p1, "MP3_STATE_IDLE")){
180                                                 state = 0;
181                                         } else if(strstr(p1, "MP3_STATE_FILE")){
182                                                 state = 1;
183                                         } else if(strstr(p1, "MP3_STATE_STREAM")){
184                                                 state = 2;
185                                         }
186                                         //printf("state = %d\n", state);
187                                 } else if(strncmp(p1, "STREAM", strlen("STREAM")) == 0){
188                                         strcpy(filename, &p1[strlen("STREAM") + 1]);
189                                         //printf("filename = %s\n", filename);
190                                 } else if(strncmp(p1, "FILE", strlen("FILE")) == 0){
191                                         strcpy(filename, &p1[strlen("FILE") + 1]);
192                                         //printf("filename = %s\n", filename);
193                                 }  
194                                 
195                                 p1 = p2;
196                         } else {
197                                 p1 = 0;
198                         }
199                 }
200
201                 struct json_object *alpmp3 = json_object_new_object();
202                 json_object_object_add(alpmp3, "state", json_object_new_int(state));
203                 switch(state){
204                 case 1:
205                         json_object_object_add(alpmp3, "type", json_object_new_string("file"));
206                         break;
207                 case 2:
208                         json_object_object_add(alpmp3, "type", json_object_new_string("stream"));
209                         break;
210                 default:
211                         json_object_object_add(alpmp3, "type", json_object_new_string("idle"));
212                         break;
213                 }
214                 json_object_object_add(alpmp3, "volume", json_object_new_int(volume));
215                 json_object_object_add(alpmp3, "bass", json_object_new_int(bass));
216                 json_object_object_add(alpmp3, "playtime", json_object_new_int(playtime));
217                 json_object_object_add(alpmp3, "filename", json_object_new_string(filename));   
218                 struct json_object *jo = json_object_new_object();
219                 json_object_object_add(jo, "alpmp3", alpmp3);
220                 printf("\n%s\n", json_object_to_json_string(jo));
221         }
222 }
223
224 int main(int argc, char **argv){
225         print_http_header();
226         
227         if(strstr(argv[0], "mp3_remote.cgi")){
228                 print_html_remote();
229         } else if(strstr(argv[0], "mp3_json.cgi")){
230                 print_json_info();
231         } else if(strstr(argv[0], "mp3_cmd.cgi")){
232                 handle_cmd();
233         } else {
234                 printf("Unknown command");
235         }
236         return 0;
237 }