added libjson-c. added driver, webinterface and userspace daemon for the fonera mp3...
[oweals/openwrt.git] / package / fonera-mp3 / src / lib / mp3_nix_socket.c
1 /*
2 * FOXMP3 
3 * Copyright (c) 2006 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 <sys/socket.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <string.h>
28 #include <sys/socket.h>
29 #include <sys/un.h>
30 #include <sys/poll.h>
31 #include <stdarg.h>
32 #include <fcntl.h>
33 #include "mp3.h"
34
35 #define SOCKET_PATH "/tmp/foxmp3"
36
37 typedef struct _MP3_NIX_SOCKET {
38         fd_set master;
39         fd_set clients;
40         int max;
41         int listener;
42 } MP3_NIX_SOCKET;
43
44 static MP3_NIX_SOCKET mp3_nix_socket;
45
46 int mp3_nix_socket_setup(void){
47         struct sockaddr_un myaddr;
48         int yes=1;      
49         int len;
50         FD_ZERO(&mp3_nix_socket.master); 
51         FD_ZERO(&mp3_nix_socket.clients);
52         
53         if ((mp3_nix_socket.listener = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
54                 perror("socket");
55                 return MP3_ERROR;
56         }
57         if (setsockopt(mp3_nix_socket.listener, SOL_SOCKET, 
58                                 SO_REUSEADDR, &yes, sizeof(int)) == -1) {
59                 perror("setsockopt");
60                 return MP3_ERROR;
61         }
62         myaddr.sun_family = AF_UNIX;
63         strcpy(myaddr.sun_path, SOCKET_PATH);
64         unlink(myaddr.sun_path);
65         len = strlen(myaddr.sun_path) + sizeof(myaddr.sun_family);
66         if (bind(mp3_nix_socket.listener, (struct sockaddr *)&myaddr, len) == -1) {
67                 perror("bind");
68                 return MP3_ERROR;
69         }
70         if (listen(mp3_nix_socket.listener, 3) == -1) {
71                 perror("listen");
72                 return MP3_ERROR;
73         }
74         FD_SET(mp3_nix_socket.listener, &mp3_nix_socket.master);
75         mp3_nix_socket.max = mp3_nix_socket.listener;
76
77         return MP3_OK;
78 };
79
80 int mp3_nix_socket_handle(void){
81         struct sockaddr_un remoteaddr; 
82         socklen_t addrlen;
83         int i;
84         int newfd; 
85         char buf[1024]; 
86         int nbytes;     
87         char buf_out[1024];
88         struct timeval tv;
89         
90         tv.tv_sec = 0;
91         tv.tv_usec = 0;
92         mp3_nix_socket.clients = mp3_nix_socket.master;
93         
94         if (select(mp3_nix_socket.max + 1, &mp3_nix_socket.clients,
95                                 NULL, NULL, &tv) == -1) {
96                 // sometimes the select is interrupted, because of the alarm signal used by the playtime counter
97                 //perror("error whilst selecting socket");
98                 return MP3_ERROR;
99         }
100         for(i = 0; i <= mp3_nix_socket.max; i++) {
101                 if (FD_ISSET(i, &mp3_nix_socket.clients)) { 
102                         if (i == mp3_nix_socket.listener) {
103                                 addrlen = sizeof(remoteaddr);
104                                 if ((newfd = accept(mp3_nix_socket.listener, 
105                                                         (struct sockaddr *)&remoteaddr, 
106                                                         &addrlen)) == -1) {
107                                         perror("error whilst accepting socket");
108                                         return MP3_ERROR;
109                                 } else {
110                                         FD_SET(newfd, &mp3_nix_socket.master); 
111                                         if (newfd > mp3_nix_socket.max) { 
112                                                 mp3_nix_socket.max = newfd;
113                                         }
114                                         fcntl(newfd, F_SETFL, O_NONBLOCK);
115                                         printf("New socket client on %d\n", newfd);
116                                 }
117                         } else {
118                                 if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
119                                         if (nbytes == 0) {
120                                                 printf("selectserver: socket hung up %d\n", i);
121                                                 close(i); 
122                                                 FD_CLR(i, &mp3_nix_socket.master);
123                                         } else {
124                                                 printf("error whilst receiving socket %d\n", i);
125                                         }
126                                 } else {
127                                         buf[nbytes] = '\0';
128                                         printf("Got data : %s\n", buf);
129                                         mp3_parser_incoming(buf,buf_out);
130                                         if(*buf_out != '\0'){
131                                                 send(i, buf_out, strlen(buf_out), 0);
132                                         }
133                                 }
134                         }
135                 }       
136         }
137         return MP3_OK;
138 }
139
140 void mp3_nix_socket_write(unsigned char *data, ...){
141         unsigned int i;
142         unsigned char t[2048];  
143         va_list ap;
144         
145         // clear possible dead sockets
146         mp3_nix_socket_handle();
147         memset(t, 0, 2048);     
148         va_start(ap, data);
149         vsprintf(t, data, ap);
150         va_end(ap);
151         printf("Sending data --> %s\n", t);     
152         for(i = 0; i <= mp3_nix_socket.max; i++) {
153                 if (FD_ISSET(i, &mp3_nix_socket.master)) { 
154                         if (i != mp3_nix_socket.listener) {
155                                 printf("Sending on socket %d\n", i);
156                                 send(i, t, strlen(t), 0);
157                         }
158                 }       
159         }
160         printf("Finished sending\n");
161 }
162
163 int mp3_nix_socket_cleanup(void){
164         return MP3_OK;
165 };
166