Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Shoutcast.cpp
00001 #include "Shoutcast.h" 00002 #include "mbed.h" 00003 #include "HTTPClient.h" 00004 00005 #include "FileDownloader.h" 00006 00007 00008 #define FOLDER "/sd/mydir/" 00009 #define FILECHANNEL "/sd/mydir/channel.xml" 00010 #define FILECHANNELMOD "/sd/mydir/cm.xml" 00011 #define FILETOP500 "/sd/mydir/top500.xml" 00012 #define FILEPLS "/sd/mydir/currChan.pls" 00013 #define FILEPLSMOD "/sd/mydir/ChanM" 00014 00015 const char* const GENRE[25] = {"Alternative","Blues","Classical","Country","Decades","Easy Listening","Electronic","Folk","Inspirational","International","Jazz","Latin","Metal","Misc","New Age","Pop","Public Radio","R&B/Urban","Rap","Reggae","Rock","Seasonal/Holiday","Soundtracks","Talk","Themes" }; 00016 00017 int completed_dns; 00018 00019 00020 Shoutcast::Shoutcast(const char* devId, char * big_buffer, int big_buffer_size, char * small_buffer, int small_buffer_size) { 00021 _devId = devId; 00022 _big_buffer = big_buffer; 00023 _big_buffer_size = big_buffer_size; 00024 _small_buffer = small_buffer; 00025 _small_buffer_size = small_buffer_size; 00026 _genreCounter = 0; 00027 _maxChannel = 0; 00028 _currentChannel = 0; 00029 _maxAddress = 0; 00030 _currentAddress = 0; 00031 00032 mkdir(FOLDER, 0777); 00033 00034 } 00035 00036 const char* Shoutcast::GetNextGenre() { 00037 if (_genreCounter < 24) { 00038 _genreCounter++; 00039 } else { 00040 _genreCounter = 0; 00041 } 00042 00043 _maxChannel = 0; 00044 _currentChannel = 0; 00045 _maxAddress = 0; 00046 _currentAddress = 0; 00047 00048 return GENRE[_genreCounter]; 00049 00050 } 00051 00052 const char* Shoutcast::GetPrevGenre() { 00053 if (_genreCounter > 0) { 00054 _genreCounter--; 00055 } else { 00056 _genreCounter = 24; 00057 } 00058 00059 _maxChannel = 0; 00060 _currentChannel = 0; 00061 _maxAddress = 0; 00062 _currentAddress = 0; 00063 00064 return GENRE[_genreCounter]; 00065 } 00066 const char* Shoutcast::GetCurrGenre() { 00067 return GENRE[_genreCounter]; 00068 } 00069 00070 int Shoutcast::GetChannel(char* name, int length) { 00071 DEBUGOUT("Shoutcast:GetChannel started\r\n"); 00072 DEBUGOUT("Shoutcast: Download channellist:%s started\r\n",GENRE[_genreCounter]); 00073 00074 strcpy (_big_buffer,"http://api.shoutcast.com/legacy/genresearch?k="); 00075 strcat (_big_buffer,_devId); 00076 strcat (_big_buffer,"&genre="); 00077 strcat (_big_buffer,GENRE[_genreCounter]); 00078 strcat (_big_buffer,"&f=xml"); 00079 DEBUGOUT("Shoutcast: %s\r\n",_big_buffer); 00080 00081 HTTPResult result = GetFile(_big_buffer,FILECHANNEL,_fpout,_small_buffer,_small_buffer_size); 00082 if(result != HTTP_OK) 00083 { 00084 DEBUGOUT("Shoutcast: Download channellist:%s ended with error %i.\r\n",GENRE[_genreCounter],result); 00085 return 1; 00086 } 00087 DEBUGOUT("Shoutcast: Download channellist:%s successfully completed.\r\n",GENRE[_genreCounter]); 00088 ParseChannelList(FILECHANNEL); 00089 00090 _currentChannel = 0; 00091 return GetChannel(name, length, 0); 00092 } 00093 00094 int Shoutcast::GetTop500(char* name, int length) { 00095 00096 DEBUGOUT("Shoutcast: Download Top500 started\r\n"); 00097 strcpy (_big_buffer,"http://api.shoutcast.com/legacy/Top500?k="); 00098 strcat (_big_buffer,_devId); 00099 DEBUGOUT("%s\n",_big_buffer); 00100 HTTPResult result = GetFile(_big_buffer,FILETOP500,_fpout,_small_buffer,_small_buffer_size); 00101 if(result != HTTP_OK) 00102 { 00103 DEBUGOUT("Shoutcast: Download Top500 ended with error %i.\r\n",result); 00104 return 1; 00105 } 00106 DEBUGOUT("Shoutcast: Download Top500 successfully completed.\r\n"); 00107 ParseChannelList(FILETOP500); 00108 _currentChannel = 0; 00109 return GetChannel(name, length, 0); 00110 } 00111 int Shoutcast::GetPrevChannel(char* name, int length) { 00112 00113 if(_maxChannel == 0){ 00114 return -2; 00115 } 00116 00117 if(_currentChannel > 0){ 00118 _currentChannel--; 00119 } 00120 else { 00121 _currentChannel = _maxChannel - 1; 00122 } 00123 00124 if((length == 0) || (name == NULL)) { 00125 return 0; 00126 } 00127 00128 _maxAddress = 0; 00129 _currentAddress = 0; 00130 00131 return GetChannel(name, length, _currentChannel); 00132 } 00133 int Shoutcast::GetNextChannel(char* name, int length) { 00134 00135 if(_maxChannel == 0){ 00136 return -2; 00137 } 00138 00139 00140 if(_currentChannel < _maxChannel - 1) { 00141 _currentChannel++; 00142 } 00143 else { 00144 _currentChannel=0; 00145 } 00146 00147 if((length == 0) || (name == NULL)) { 00148 return 0; 00149 } 00150 00151 _maxAddress = 0; 00152 _currentAddress = 0; 00153 00154 return GetChannel(name, length, _currentChannel); 00155 } 00156 00157 int Shoutcast::GetCurrChannel(char* name, int length) { 00158 return GetChannel(name, length, _currentChannel); 00159 } 00160 00161 int Shoutcast::TuneIn(IpAddr* address, int* port, char * path, const int length) { 00162 char buf[10]; 00163 sprintf(buf,"%d",GetChannelId(_currentChannel)); 00164 00165 strcpy (_big_buffer,"http://yp.shoutcast.com/sbin/tunein-station.pls?&k="); 00166 strcat (_big_buffer,_devId); 00167 strcat (_big_buffer,"&id="); 00168 strcat (_big_buffer,buf); //todo: int to string 00169 strcat (_big_buffer,"&f=xml"); 00170 DEBUGOUT("Shoutcast: %s\r\n",_big_buffer); 00171 HTTPResult result = GetFile(_big_buffer,FILEPLS,_fpout,_small_buffer,_small_buffer_size); 00172 DEBUGOUT("Shoutcast: result PLS: %d\n", result); 00173 00174 if(ParsePls() != 0x00) 00175 { 00176 return 1; 00177 } 00178 _currentAddress = 0; 00179 return GetAddressData(address,port,path,length,0); 00180 } 00181 00182 00183 00184 int Shoutcast::ParseChannelList(const char* channelList) { 00185 00186 DEBUGOUT("Shoutcast: Parsing started\r\n"); 00187 _maxChannel = 0; 00188 00189 _fpin = fopen(channelList, "r"); 00190 if (_fpin == NULL) { 00191 error("Could not open file for write\n"); 00192 } 00193 00194 _fpout = fopen(FILECHANNELMOD, "w"); 00195 if (_fpout == NULL) { 00196 error("Could not open file for write\n"); 00197 } 00198 00199 char * cp; 00200 char * cp2 = NULL; 00201 char * station1; char * station2 = NULL; 00202 00203 int i=0; 00204 bool finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00205 _big_buffer[_big_buffer_size-1] = 0x00; 00206 cp = _big_buffer; 00207 00208 while (!finished) { 00209 if (cp==NULL) { 00210 if (cp2 != NULL) { 00211 int x = (_big_buffer + _big_buffer_size) - cp2 - 1; 00212 int read_size = _big_buffer_size-(x-1); 00213 00214 finished = (fgets(_big_buffer+x-1, read_size,_fpin) == NULL); 00215 _big_buffer[_big_buffer_size-1] = 0x00; 00216 cp=_big_buffer; 00217 00218 } else { 00219 finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00220 _big_buffer[_big_buffer_size-1] = 0x00; 00221 cp = _big_buffer; 00222 } 00223 } 00224 00225 cp=strstr(cp,"<station "); 00226 00227 if (cp!=NULL) { 00228 cp2=strstr(cp,"/>"); 00229 if (cp2 != NULL) { 00230 i++; 00231 00232 cp2[0] = 0x00; 00233 00234 //name suchen 00235 station1=strstr(cp,"name=\""); 00236 if(station1 != NULL) 00237 { 00238 station1 = station1 + strlen("name=\""); 00239 station2 = NULL; 00240 station2 = strstr(station1,"\""); 00241 if(station2 != NULL) 00242 { 00243 station2[0]=0x00; 00244 fprintf(_fpout,"%s<>",station1); 00245 _maxChannel++; 00246 } 00247 } 00248 //id suchen 00249 station1=strstr(station2+1,"id=\""); 00250 if(station1 != NULL) 00251 { 00252 station1 = station1 + strlen("id=\""); 00253 station2 = NULL; 00254 station2 = strstr(station1,"\""); 00255 if(station2 != NULL) 00256 { 00257 station2[0]=0x00; 00258 fprintf(_fpout,"%s\r\n",station1); 00259 } 00260 } 00261 00262 cp=cp2+1; 00263 } else { 00264 //Kopieren 00265 strcpy(_big_buffer,cp); 00266 int x = (_big_buffer + _big_buffer_size) - cp - 1; 00267 int read_size = _big_buffer_size-(x-1); 00268 finished = (fgets(_big_buffer+x-1, read_size,_fpin) == NULL); 00269 _big_buffer[_big_buffer_size-1] = 0x00; 00270 cp = _big_buffer; 00271 } 00272 } 00273 00274 } 00275 fclose(_fpin); 00276 fclose(_fpout); 00277 DEBUGOUT("Shoutcast: Parsing completed\r\n"); 00278 return true; 00279 } 00280 00281 int Shoutcast::GetChannel(char* name, int length, int channelNumber) 00282 { 00283 if(_maxChannel == 0) return -1; 00284 if(channelNumber > _maxChannel) return -1; 00285 00286 _fpin = fopen(FILECHANNELMOD, "r"); 00287 if (_fpin == NULL) { 00288 error("Could not open file for write\n"); 00289 } 00290 bool finished = false; 00291 int line = 0; 00292 char * delimiter; 00293 00294 while(!finished) { 00295 finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00296 if(channelNumber == line) 00297 { 00298 delimiter=strstr(_big_buffer,"<>"); 00299 if(delimiter != NULL) 00300 { 00301 int i = 0; 00302 for(i = 0; (i<delimiter-_big_buffer) && (i<length-1); i++) 00303 { 00304 name[i] = _big_buffer[i]; 00305 } 00306 name[i]=0x00; 00307 finished = true; 00308 } 00309 else 00310 { 00311 fclose(_fpin); 00312 return 1; 00313 } 00314 } 00315 line++; 00316 } 00317 00318 fclose(_fpin); 00319 return 0; 00320 } 00321 00322 00323 int Shoutcast::GetChannelId(int channelNumber) 00324 { 00325 DEBUGOUT("Shoutcast: GetChannelId started\r\n"); 00326 _fpin = fopen(FILECHANNELMOD, "r"); 00327 if (_fpin == NULL) { 00328 error("Could not open file for write\n"); 00329 } 00330 bool finished = false; 00331 int line = 0; 00332 char * delimiter; 00333 00334 while(!finished) { 00335 finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00336 if(channelNumber == line) 00337 { 00338 DEBUGOUT("Shoutcast: GetChannelId Line found\r\n"); 00339 delimiter=strstr(_big_buffer,"<>"); 00340 int id = -1; 00341 if(delimiter != NULL) 00342 { 00343 id = atoi(delimiter+strlen("<>")); 00344 //id = 4; 00345 fclose(_fpin); 00346 return id; 00347 } 00348 else 00349 { 00350 fclose(_fpin); 00351 return -1; 00352 } 00353 } 00354 line++; 00355 } 00356 fclose(_fpin); 00357 return -1; 00358 } 00359 00360 int Shoutcast::ParsePls() { 00361 DEBUGOUT("Shoutcast: start parsing pls\r\n"); 00362 00363 _fpin = fopen(FILEPLS, "r"); 00364 if (_fpin == NULL) { 00365 error("Could not open file for read\n"); 00366 } 00367 _fpout = fopen(FILEPLSMOD, "w"); 00368 if (_fpout == NULL) { 00369 error("Could not open file for write\n"); 00370 } 00371 bool finished = false; 00372 00373 char * cp; 00374 char * cp2; 00375 IpAddr addr; 00376 int k=0; 00377 while(!finished) { 00378 finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00379 //suchen nach 00380 cp = strstr(_big_buffer,"=http://"); 00381 if(cp!= NULL) 00382 { 00383 cp = cp +strlen("=http://"); 00384 cp2=strstr(cp,":"); 00385 if(cp2 != NULL) 00386 { 00387 cp2[0]=0x00; 00388 int dnserr = ResolveDNSRequest(&addr, cp); 00389 00390 if(dnserr != 0) 00391 { 00392 DEBUGOUT("Shoutcast: DNS Error - Parsing Pls\r\n"); 00393 fclose(_fpin); 00394 fclose(_fpout); 00395 00396 return -1; 00397 } 00398 else 00399 { 00400 cp = NULL; 00401 } 00402 int port = atoi(cp2+1); 00403 cp = strstr(cp2+1,"/"); 00404 if(cp == NULL) 00405 { 00406 _small_buffer[0] = '/'; 00407 _small_buffer[1] = 0x00; 00408 } 00409 else 00410 { 00411 int j=0; 00412 while(cp[j]!=0x0a) 00413 j++; 00414 00415 cp[j] = 0x00; 00416 strcpy (_small_buffer,cp); 00417 } 00418 fprintf(_fpout, "%d %d %d %d %d %s\r\n", 00419 addr[0],addr[1],addr[2],addr[3],port,_small_buffer); 00420 _maxAddress++; 00421 } 00422 } 00423 _big_buffer[_big_buffer_size-1] = 0x00; 00424 } 00425 fclose(_fpin); 00426 fclose(_fpout); 00427 00428 DEBUGOUT("Shoutcast: end parsing pls\r\n"); 00429 return 0; 00430 } 00431 int Shoutcast::ResolveDNSRequest(IpAddr* addr, char * url){ 00432 //TODO: instanzvaraible, setOnReplay im Konstruktor 00433 DNSRequest * request = new DNSRequest(); 00434 request->setOnReply(this, &Shoutcast::onReply); 00435 00436 completed_dns=0; 00437 00438 00439 DNSRequestErr r = request->resolve(url); 00440 if (0!=r) { 00441 request->close(); 00442 return 1; 00443 00444 } 00445 while (0==completed_dns) { 00446 Net::poll(); 00447 } 00448 00449 if(completed_dns == -1) { 00450 return 1; 00451 } 00452 request->getResult(addr); 00453 request->close(); 00454 return 0; 00455 } 00456 00457 int Shoutcast::GetAddressData(IpAddr* address, int* port, char * path, const int length, int addressNumber) { 00458 00459 if(_maxAddress == 0) return -1; 00460 if(addressNumber > _maxAddress) return -1; 00461 00462 DEBUGOUT("Shoutcast: start get address data\r\n"); 00463 _fpin = fopen(FILEPLSMOD, "r"); 00464 bool finished = false; 00465 int line = 0; 00466 00467 while(!finished) { 00468 finished = (fgets(_big_buffer, _big_buffer_size-1, _fpin) == NULL); 00469 if(line == addressNumber){ 00470 int ip1 = 0;int ip2 = 0;int ip3 = 0;int ip4 = 0; 00471 sscanf (_big_buffer,"%d %d %d %d %d %s",&ip1,&ip2,&ip3,&ip4,port,path); 00472 IpAddr server = IpAddr(ip1,ip2,ip3,ip4); 00473 *address = server; 00474 //*path = _small_buffer[0]; //TODO: Length 00475 finished = true; 00476 } 00477 line++; 00478 } 00479 DEBUGOUT("Shoutcast: end get address data\r\n"); 00480 return 0; 00481 } 00482 00483 void Shoutcast::onReply(DNSReply reply) { 00484 if (reply==DNS_FOUND) 00485 completed_dns=1; 00486 else 00487 completed_dns=-1; 00488 }; 00489 00490 int Shoutcast::GetNextAddress(IpAddr* address, int* port, char * path, const int length) 00491 { 00492 if(_currentAddress < _maxAddress - 1 ) 00493 { 00494 _currentAddress++; 00495 } 00496 else 00497 { 00498 _currentAddress = 0; 00499 } 00500 return GetAddressData(address,port,path,length,_currentAddress); 00501 00502 } 00503 int Shoutcast::GetCurrAddress(IpAddr* address, int* port, char * path, const int length) 00504 { 00505 return GetAddressData(address,port,path,length,_currentAddress); 00506 } 00507 int Shoutcast::GetPrevAddress(IpAddr* address, int* port, char * path, const int length) 00508 { 00509 if(_currentAddress > 0 ) 00510 { 00511 _currentAddress--; 00512 } 00513 else 00514 { 00515 _currentAddress = _maxAddress - 1; 00516 } 00517 return GetAddressData(address,port,path,length,_currentAddress); 00518 }
Generated on Tue Jul 12 2022 16:21:00 by
1.7.2