added libjson-c. added driver, webinterface and userspace daemon for the fonera mp3...
[oweals/openwrt.git] / package / fonera-mp3 / src / lib / mp3_tcp_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 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <string.h>
27 #include <sys/types.h>
28 #include <sys/socket.h>
29 #include <netinet/in.h>
30 #include <arpa/inet.h>
31 #include <sys/wait.h>
32 #include <signal.h>
33 #include <sys/poll.h>
34
35 #include "mp3.h"
36
37 #define SOCKET_PORT     369
38 #define BACKLOG         10
39
40 typedef struct _MP3_TCP_SOCKET {
41         fd_set master;
42         fd_set clients;
43         int max;
44         int listener;
45 } MP3_TCP_SOCKET;
46
47 static MP3_TCP_SOCKET mp3_tcp_socket;
48
49 int mp3_tcp_socket_setup(void){
50         struct sockaddr_in myaddr;
51         int yes=1;      
52         FD_ZERO(&mp3_tcp_socket.master); 
53         FD_ZERO(&mp3_tcp_socket.clients);
54         
55         if ((mp3_tcp_socket.listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
56                 perror("socket");
57                 return MP3_ERROR;
58         }
59         if (setsockopt(mp3_tcp_socket.listener, SOL_SOCKET, 
60                                 SO_REUSEADDR, &yes, sizeof(int)) == -1) {
61                 perror("setsockopt");
62                 return MP3_ERROR;
63         }
64         myaddr.sin_family = AF_INET;
65         myaddr.sin_port = htons(SOCKET_PORT);
66         myaddr.sin_addr.s_addr = INADDR_ANY; 
67         memset(&(myaddr.sin_zero), '\0', 8);
68         if (bind(mp3_tcp_socket.listener, (struct sockaddr *)&myaddr, sizeof(struct sockaddr)) == -1) {
69                 perror("bind");
70                 return MP3_ERROR;
71         }
72         if (listen(mp3_tcp_socket.listener, 3) == -1) {
73                 perror("listen");
74                 return MP3_ERROR;
75         }
76         FD_SET(mp3_tcp_socket.listener, &mp3_tcp_socket.master);
77         mp3_tcp_socket.max = mp3_tcp_socket.listener;
78         printf("Started tcp socket on port %d\n", SOCKET_PORT);
79         return MP3_OK;
80 };
81
82 int mp3_tcp_socket_handle(void){
83         struct sockaddr_in remoteaddr; 
84         socklen_t addrlen;
85         int i;
86         int newfd; 
87         char buf[1024]; 
88         int nbytes;     
89         char buf_out[1024];
90         struct timeval tv;
91         
92         tv.tv_sec = 0;
93         tv.tv_usec = 0;
94         mp3_tcp_socket.clients = mp3_tcp_socket.master;
95         
96         if (select(mp3_tcp_socket.max + 1, &mp3_tcp_socket.clients,
97                                 NULL, NULL, &tv) == -1) {
98                 return MP3_ERROR;
99         }
100         for(i = 0; i <= mp3_tcp_socket.max; i++) {
101                 if (FD_ISSET(i, &mp3_tcp_socket.clients)) { 
102                         if (i == mp3_tcp_socket.listener) {
103                                 addrlen = sizeof(remoteaddr);
104                                 if ((newfd = accept(mp3_tcp_socket.listener, 
105                                                         (struct sockaddr *)&remoteaddr, 
106                                                         &addrlen)) == -1) {
107                                         perror("error whilst accepting socket");
108                                         return MP3_ERROR;
109                                 } else {
110                                         printf("New TCP connection from %s\n", 
111                                                         inet_ntoa(remoteaddr.sin_addr));
112                                         FD_SET(newfd, &mp3_tcp_socket.master); 
113                                         if (newfd > mp3_tcp_socket.max) { 
114                                                 mp3_tcp_socket.max = newfd;
115                                         }
116                                 }
117                         } else {
118                                 if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
119                                         if (nbytes == 0) {
120                                                 perror("selectserver: socket hung up\n");
121                                         } else {
122                                                 perror("error whilst receiving socket");
123                                         }
124                                         close(i); 
125                                         FD_CLR(i, &mp3_tcp_socket.master);
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                                         close(i); 
134                                         FD_CLR(i, &mp3_tcp_socket.master);
135                                 }
136                         }
137                 }       
138         }
139         return MP3_OK;
140 };
141
142 int mp3_tcp_socket_cleanup(void){
143         return MP3_OK;
144 };
145