added fonera-mp3 support to k7.09
[openwrt/svn-archive/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