00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00051 #include <dev/board.h>
00052
00053 #include <sys/heap.h>
00054 #include <sys/thread.h>
00055 #include <sys/timer.h>
00056
00057 #include <netinet/tcp.h>
00058 #include <arpa/inet.h>
00059
00060 #include <stdlib.h>
00061 #include <stdio.h>
00062 #include <string.h>
00063
00064
00065 #include "scanner.h"
00066
00067 #ifdef DEV_ETHER
00068
00069
00070
00071
00072 static int GetLine(TCPSOCKET * sock, char * line, u_short size)
00073 {
00074 int rc = 0;
00075 u_char to_cnt = 0;
00076 int got;
00077 char *cp = line;
00078
00079 if (size > 0) {
00080 for (;;) {
00081 if ((got = NutTcpReceive(sock, cp, 1)) <= 0) {
00082 if (got == 0 && to_cnt++ < 10)
00083 continue;
00084 rc = got;
00085 printf("[GL-TO]");
00086 break;
00087 }
00088 if (*cp == '\n') {
00089 *cp = 0;
00090 break;
00091 }
00092 if (*cp != '\r' && rc < (int) size) {
00093 rc++;
00094 cp++;
00095 }
00096 }
00097 }
00098 return rc;
00099 }
00100
00101 static int PutString(TCPSOCKET * sock, char * str)
00102 {
00103 u_short len = strlen(str);
00104 u_short n;
00105 int c;
00106
00107 for (n = 0; n < len; n += c)
00108 if ((c = NutTcpSend(sock, str + n, len - n)) < 0)
00109 return -1;
00110 return len;
00111 }
00112
00113
00117 int ScanStreamHeader(TCPSOCKET * sock, RADIOSTATION * rsp)
00118 {
00119 int rc = -1;
00120 char *line = malloc(256);
00121 char *cp;
00122
00123
00124
00125
00126 strcpy(line, "GET /");
00127 if (rsp->rs_url)
00128 strcat(line, rsp->rs_url);
00129 strcat(line, " HTTP/1.0\r\n");
00130 PutString(sock, line);
00131
00132 sprintf(line, "Host: %s\r\n", inet_ntoa(rsp->rs_ip));
00133 PutString(sock, line);
00134
00135 PutString(sock, "User-Agent: WinampMPEG/2.7\r\n" "Accept: */*\r\n" "Icy-MetaData: 1\r\n" "Connection: close\r\n\r\n");
00136
00137 if (rsp->rs_name) {
00138 free(rsp->rs_name);
00139 rsp->rs_name = 0;
00140 }
00141 if (rsp->rs_genre) {
00142 free(rsp->rs_genre);
00143 rsp->rs_genre = 0;
00144 }
00145 rsp->rs_metaint = 0;
00146
00147
00148
00149
00150 if (GetLine(sock, line, 256) > 5) {
00151 printf("%s\n", line);
00152 if (strncmp(line, "ICY", 3) == 0) {
00153 if (atoi(line + 4) == 200) {
00154 for (;;) {
00155 if ((rc = GetLine(sock, line, 256)) <= 0) {
00156 break;
00157 }
00158 if (strncmp(line, "icy-name:", 9) == 0) {
00159 cp = line + 9;
00160 while (*cp && *cp == ' ')
00161 cp++;
00162 if (*cp && rsp->rs_name == 0) {
00163 rsp->rs_name = malloc(strlen(cp) + 1);
00164 strcpy(rsp->rs_name, cp);
00165 printf("%s\n", cp);
00166 }
00167 } else if (strncmp(line, "icy-genre:", 10) == 0) {
00168 cp = line + 10;
00169 while (*cp && *cp == ' ')
00170 cp++;
00171 if (*cp && rsp->rs_genre == 0) {
00172 rsp->rs_genre = malloc(strlen(cp) + 1);
00173 strcpy(rsp->rs_genre, cp);
00174 }
00175 } else if (strncmp(line, "icy-metaint:", 12) == 0)
00176 rsp->rs_metaint = atol(line + 12);
00177 else if (strncmp(line, "icy-br:", 7) == 0)
00178 rsp->rs_bitrate = atol(line + 7);
00179 }
00180 } else
00181 puts(line);
00182 }
00183 }
00184
00185 free(line);
00186
00187 printf("\n%s %ukbps %s ", inet_ntoa(rsp->rs_ip), rsp->rs_bitrate, rsp->rs_name);
00188
00189 return rc;
00190 }
00191
00192
00193
00194
00195 static char *ReadMetaTitle(TCPSOCKET * sock, u_long iv)
00196 {
00197 u_char blks = 0;
00198 u_short cnt;
00199 int got;
00200 int rc = 0;
00201 char *title = 0;
00202 char *buf;
00203 char *mn1;
00204 char *mn2;
00205 char *md1;
00206 char *md2;
00207
00208
00209 if ((buf = malloc(512 + 1)) == 0) {
00210 return 0;
00211 }
00212 for (cnt = 512; iv; iv -= got) {
00213 if (iv < 512)
00214 cnt = iv;
00215 if ((got = NutTcpReceive(sock, buf, cnt)) <= 0)
00216 break;
00217 }
00218
00219 if (iv == 0) {
00220
00221 if ((got = NutTcpReceive(sock, &blks, 1)) == 1) {
00222 if (blks && blks <= 32) {
00223
00224
00225 for (cnt = blks * 16; cnt; cnt -= got) {
00226 if ((got = NutTcpReceive(sock, buf + rc, cnt)) < 0)
00227 break;
00228 rc += got;
00229 buf[rc] = 0;
00230 }
00231 if (cnt == 0) {
00232 mn1 = buf;
00233 while (mn1) {
00234 if ((mn2 = strchr(mn1, ';')) != 0)
00235 *mn2++ = 0;
00236 if ((md1 = strchr(mn1, '=')) != 0) {
00237 *md1++ = 0;
00238 while (*md1 == ' ' || *md1 == '\'')
00239 md1++;
00240 if ((md2 = strrchr(md1, '\'')) != 0)
00241 *md2 = 0;
00242 if (strcasecmp(mn1, "StreamTitle") == 0) {
00243 title = malloc(strlen(md1) + 1);
00244 strcpy(title, md1);
00245 break;
00246 }
00247 }
00248 mn1 = mn2;
00249 }
00250 }
00251 } else
00252 printf("[ML=%u]", blks);
00253 }
00254 } else
00255 puts("[SMFAIL]");
00256 free(buf);
00257 return title;
00258 }
00259
00260
00261
00262
00263
00264
00265 THREAD(Scanner, arg)
00266 {
00267 TCPSOCKET *sock;
00268 RADIOSTATION *rsp;
00269 u_char rs;
00270 u_long rx_to = 10000UL;
00271
00272 NutThreadSetPriority(128);
00273 NutSleep(10000);
00274 for (;;) {
00275 for (rs = 0; rs < MAXNUM_STATIONS; rs++) {
00276 NutSleep(2000);
00277 if (rs == radio.rc_rstation || rs == radio.rc_cstation)
00278 continue;
00279 rsp = &station[rs];
00280 if (rsp->rs_ip == 0 || rsp->rs_port == 0 || radio.rc_off) {
00281 continue;
00282 }
00283
00284
00285 if (rsp->rs_name) {
00286 printf("%lu bytes free\n", NutHeapAvailable());
00287 NutSleep(30000);
00288 }
00289
00290
00291 if ((sock = NutTcpCreateSocket()) == 0) {
00292 break;
00293 }
00294 NutTcpSetSockOpt(sock, SO_RCVTIMEO, &rx_to, sizeof(rx_to));
00295
00296
00297 printf("[Scan %s:%u]\n", inet_ntoa(rsp->rs_ip), rsp->rs_port);
00298 if (NutTcpConnect(sock, rsp->rs_ip, rsp->rs_port) == 0) {
00299
00300 if (ScanStreamHeader(sock, rsp) == 0) {
00301 if (rsp->rs_scantitle) {
00302 free(rsp->rs_scantitle);
00303 rsp->rs_scantitle = 0;
00304 }
00305 if (rsp->rs_metaint) {
00306 if ((rsp->rs_scantitle = ReadMetaTitle(sock, rsp->rs_metaint)) != 0) {
00307 printf("%03u: %s\n", rs, rsp->rs_scantitle);
00308 rsp->rs_scandead = 0;
00309 } else
00310 rsp->rs_scandead = 1;
00311 } else
00312 rsp->rs_scandead = 0;
00313 } else
00314 rsp->rs_scandead = 1;
00315 } else {
00316 rsp->rs_scandead = 1;
00317 printf("[SERR=%d]\n", NutTcpError(sock));
00318 }
00319 NutTcpCloseSocket(sock);
00320 }
00321 }
00322 NutSleep(30000);
00323 }
00324
00331 int ScannerInit(void)
00332 {
00333
00334 if (NutThreadCreate("scanner", Scanner, 0, 512) == 0)
00335 return -1;
00336
00337 return 0;
00338 }
00339
00340 #endif