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