Revision:
0:d9d38ebc0f69
Child:
1:1b5ed0fa82f0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Shoutcast.cpp	Mon Jan 24 13:32:52 2011 +0000
@@ -0,0 +1,469 @@
+#include "Shoutcast.h"
+#include "mbed.h"
+#include "HTTPClient.h"
+
+#include "FileDownloader.h"
+
+
+const char* FOLDER = "/sd/mydir/";
+const char* FILECHANNEL = "/sd/mydir/channel.xml";
+const char* FILECHANNELMOD = "/sd/mydir/cm.xml";
+const char* FILETOP500 = "/sd/mydir/top500.xml";
+const char* FILEPLS = "/sd/mydir/currChan.pls";
+const char* FILEPLSMOD = "/sd/mydir/ChanM";
+
+const char* 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"};
+
+unsigned int genreCounter = 0;
+unsigned int maxChannel = 0;
+unsigned int currentChannel = 0;
+unsigned int maxAddress = 0;
+unsigned int currentAddress = 0;
+FILE *fpin;
+FILE *fpout;
+
+int completed_dns;
+
+
+Shoutcast::Shoutcast(const char* devId, char * buffer,  int buffer_size) {
+    _devId = devId;
+    _buffer = buffer;
+    _buffer_size = buffer_size;
+    mkdir(FOLDER, 0777);
+
+}
+
+const char* Shoutcast::GetNextGenre() {
+    if (genreCounter < 24) {
+        genreCounter++;
+    } else {
+        genreCounter = 0;
+    }
+
+    return GENRE[genreCounter];
+
+}
+
+const char* Shoutcast::GetPrevGenre() {
+    if (genreCounter > 0) {
+        genreCounter--;
+    } else {
+        genreCounter = 24;
+    }
+    return GENRE[genreCounter];
+}
+const char* Shoutcast::GetCurrGenre() {
+    return GENRE[genreCounter];
+}
+
+int Shoutcast::GetChannel(char* name, int length) {
+    DEBUGOUT("Shoutcast:GetChannel started\r\n");
+    DEBUGOUT("Shoutcast: Download channellist:%s started\r\n",GENRE[genreCounter]);
+    strcpy (_buffer,"http://api.shoutcast.com/legacy/genresearch?k=");
+            
+    DEBUGOUT("strcpy ok\r\n");
+    strcat (_buffer,_devId);
+    DEBUGOUT("strcat1 ok\r\n");
+    strcat (_buffer,"&genre=");
+    DEBUGOUT("strcat1 ok\r\n");
+    strcat (_buffer,GENRE[genreCounter]);
+    DEBUGOUT("strcat1 ok\r\n");
+    strcat (_buffer,"&f=xml");
+    DEBUGOUT("strcat1 ok\r\n");
+    DEBUGOUT("%s\r\n",_buffer);
+
+    HTTPResult result = GetFile(_buffer,FILECHANNEL);
+    if(result != HTTP_OK)
+    {
+        DEBUGOUT("Shoutcast: Download channellist:%s ended with error %i.\r\n",GENRE[genreCounter],result);
+        return 1;
+    }
+    DEBUGOUT("Shoutcast: Download channellist:%s successfully completed.\r\n",GENRE[genreCounter]);
+    ParseChannelList(FILECHANNEL);
+
+    currentChannel = 0;
+    return GetChannel(name, length, 0);
+}
+
+int Shoutcast::GetTop500(char* name, int length) {
+
+    DEBUGOUT("Shoutcast: Download Top500 started\r\n");
+    strcpy (_buffer,"http://api.shoutcast.com/legacy/Top500?k=");
+    strcat (_buffer,_devId);
+    DEBUGOUT("%s\n",_buffer);
+     HTTPResult result = GetFile(_buffer,FILETOP500);
+    if(result != HTTP_OK)
+    {
+        DEBUGOUT("Shoutcast: Download Top500 ended with error %i.\r\n",result);
+        return 1;
+    }
+    DEBUGOUT("Shoutcast: Download Top500 successfully completed.\r\n");
+    ParseChannelList(FILETOP500);
+    currentChannel = 0;
+    return GetChannel(name, length, 0);
+}
+int Shoutcast::GetPrevChannel(char*name, int length) {
+    if(currentChannel > 0){
+        currentChannel--;
+    }
+    else {
+    currentChannel = maxChannel - 1;
+    }
+    return GetChannel(name, length, currentChannel);
+}
+int Shoutcast::GetNextChannel(char* name, int length) {
+    if(currentChannel < maxChannel - 1) {
+        currentChannel++;
+    }
+    else {
+    currentChannel++;
+    }
+    return GetChannel(name, length, currentChannel);
+}
+
+int Shoutcast::GetCurrChannel(char* name, int length) {
+    return GetChannel(name, length, currentChannel);
+}
+
+int Shoutcast::TuneIn(IpAddr* address, int* port) {
+    char buf[10];
+    sprintf(buf,"%d",GetChannelId(currentChannel));
+     
+    strcpy (_buffer,"http://yp.shoutcast.com/sbin/tunein-station.pls?&k=");
+    strcat (_buffer,_devId);
+    strcat (_buffer,"&id=");
+    strcat (_buffer,buf); //todo: int to string
+    strcat (_buffer,"&f=xml");
+    DEBUGOUT("%s\r\n",_buffer);
+    HTTPResult result = GetFile(_buffer,FILEPLS);
+    DEBUGOUT("result PLS: %d\n", result);
+    //TODO: PLS Parsen, IP und Port zur&#65533;ckgeben
+    if(ParsePls() != 0x00)
+    {   
+        return 1;
+    }
+    currentAddress = 0;
+    GetAddressData(address,port,0);
+    return 0;
+}
+
+
+
+int Shoutcast::ParseChannelList(const char* channelList) {
+    
+    DEBUGOUT("Shoutcast: Parsing started\r\n");
+    maxChannel = 0;
+    
+    fpin = fopen(channelList, "r");
+    if (fpin == NULL) {
+        error("Could not open file for write\n");
+    } 
+    
+    fpout = fopen(FILECHANNELMOD, "w");
+    if (fpout == NULL) {
+        error("Could not open file for write\n");
+    }
+    
+    char * cp;
+    char * cp2 = NULL;
+    char * station1; char * station2 = NULL;
+
+    int i=0;
+    bool finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+    _buffer[_buffer_size-1] = 0x00;
+    cp = _buffer;
+
+    while (!finished) {
+        if (cp==NULL) {
+            if (cp2 != NULL) {
+                int x = (_buffer + _buffer_size) - cp2 - 1;
+                int read_size = _buffer_size-(x-1);
+
+                finished = (fgets(_buffer+x-1, read_size,fpin) == NULL);
+                _buffer[_buffer_size-1] = 0x00;
+                cp=_buffer;
+
+            } else {
+                finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+                _buffer[_buffer_size-1] = 0x00;
+                cp = _buffer;
+            }
+        }
+
+        cp=strstr(cp,"<station ");
+
+        if (cp!=NULL) {
+            cp2=strstr(cp,"/>");
+            if (cp2 != NULL) {
+                i++;
+               
+                cp2[0] = 0x00;
+                
+                //name suchen
+                station1=strstr(cp,"name=\"");
+                if(station1 != NULL)
+                {
+                  station1 = station1 + strlen("name=\"");
+                  station2 = NULL;
+                  station2 = strstr(station1,"\"");
+                  if(station2 != NULL)
+                  {
+                    station2[0]=0x00;
+                    fprintf(fpout,"%s<>",station1);
+                    maxChannel++;
+                  }
+                }
+                //id suchen
+                station1=strstr(station2+1,"id=\"");
+                if(station1 != NULL)
+                {
+                  station1 = station1 + strlen("id=\"");
+                  station2 = NULL;
+                  station2 = strstr(station1,"\"");
+                  if(station2 != NULL)
+                  {
+                    station2[0]=0x00;
+                    fprintf(fpout,"%s\r\n",station1);
+                  }
+                }
+                
+                cp=cp2+1;
+            } else {
+                //Kopieren
+                strcpy(_buffer,cp);
+                int x = (_buffer + _buffer_size) - cp - 1;
+                int read_size = _buffer_size-(x-1);
+                finished = (fgets(_buffer+x-1, read_size,fpin) == NULL);
+                _buffer[_buffer_size-1] = 0x00;
+                cp = _buffer;
+            }
+        }
+
+    }
+    fclose(fpin);
+    fclose(fpout);
+    DEBUGOUT("Shoutcast: Parsing completed\r\n");
+    return true;
+}
+
+int Shoutcast::GetChannel(char* name, int length, int channelNumber)
+{   
+    DEBUGOUT("Shoutcast: GetChannel started\r\n");
+    fpin = fopen(FILECHANNELMOD, "r");
+    if (fpin == NULL) {
+        error("Could not open file for write\n");
+    }
+    bool finished = false;
+    int line = 0;
+    char * delimiter;
+    
+    while(!finished) {
+        finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+        DEBUGOUT("Shoutcast: GetChannel ReadLine %i\r\n",line);
+        if(channelNumber == line)
+        {
+            DEBUGOUT("Shoutcast: GetChannel Line found\r\n");
+            delimiter=strstr(_buffer,"<>");
+            if(delimiter != NULL)
+            {
+                int i = 0;
+                DEBUGOUT("Shoutcast: length %i\r\n",delimiter-_buffer);
+                for(i = 0; (i<delimiter-_buffer) && (i<length-1); i++)
+                {
+                   name[i] = _buffer[i];
+                }
+                DEBUGOUT("\r\n");
+                name[i]=0x00;
+                finished = true;
+            }
+            else
+            {
+                fclose(fpin);
+                return 1;
+            }
+        }
+         DEBUGOUT("Shoutcast: StringCopy ready\r\n");
+        line++;
+    }
+    DEBUGOUT("Shoutcast: GetChannel completed\r\n");
+    
+    fclose(fpin);
+    return 0;
+}
+
+
+int Shoutcast::GetChannelId(int channelNumber)
+{   
+    DEBUGOUT("Shoutcast: GetChannelId started\r\n");
+    fpin = fopen(FILECHANNELMOD, "r");
+    if (fpin == NULL) {
+        error("Could not open file for write\n");
+    }
+    bool finished = false;
+    int line = 0;
+    char * delimiter;
+    
+    while(!finished) {
+        finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+        if(channelNumber == line)
+        {
+            DEBUGOUT("Shoutcast: GetChannelId Line found\r\n");
+            delimiter=strstr(_buffer,"<>");
+            int id = -1;
+            if(delimiter != NULL)
+            {
+                 id = atoi(delimiter+strlen("<>"));
+                //id = 4;
+                fclose(fpin);
+                return id;  
+            }
+            else
+            {
+                fclose(fpin);
+                return -1;
+            }
+        }
+        line++;
+    }
+    fclose(fpin);
+    return -1;
+}
+
+int Shoutcast::ParsePls() {
+    DEBUGOUT("Shoutcast: start parsing pls\r\n");
+    
+fpin = fopen(FILEPLS, "r");
+ if (fpin == NULL) {
+        error("Could not open file for read\n");
+    }
+fpout = fopen(FILEPLSMOD, "w");
+ if (fpout == NULL) {
+        error("Could not open file for write\n");
+    }
+bool finished = false;
+  
+    char * cp;
+    char * cp2;
+    IpAddr addr;
+    while(!finished) {
+        finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+        
+        //suchen nach 
+        cp = strstr(_buffer,"=http://");
+        if(cp!= NULL)
+        {   
+            cp = cp +strlen("=http://");
+            cp2=strstr(cp,":");
+            if(cp2 != NULL)
+            {
+                cp2[0]=0x00;
+                int dnserr = ResolveDNSRequest(&addr, cp);
+                
+                if(dnserr != 0)
+                {   
+                    DEBUGOUT("Shoutcast: DNS Error - Parsing Pls\r\n");
+                    fclose(fpin);
+                    fclose(fpout);
+                    
+                    DEBUGOUT("Shoutcast: end parsing pls-ERROR");
+                    return -1;
+                }
+                int port = atoi(cp2+1);
+                fprintf(fpout, "%d %d %d %d %d\r\n",
+                       addr[0],addr[1],addr[2],addr[3],port);
+                maxAddress++;
+            }
+        }
+        _buffer[_buffer_size-1] = 0x00;
+        }
+    fclose(fpin);
+    fclose(fpout);
+    
+    DEBUGOUT("Shoutcast: end parsing pls\r\n");
+    return 0;
+}
+int Shoutcast::ResolveDNSRequest(IpAddr* addr, char * url){
+    DNSRequest * request = new DNSRequest();
+    request->setOnReply(this, &Shoutcast::onReply);
+
+     completed_dns=0;
+     
+
+     DNSRequestErr r = request->resolve(url);
+     if (0!=r) {
+         request->close();
+         return 1;
+        
+     }
+     while (0==completed_dns) {
+         Net::poll();
+     }
+
+    if(completed_dns == -1) {
+       return 1;
+    }
+     request->getResult(addr);
+     request->close();
+     return 0;
+}
+
+int Shoutcast::GetAddressData(IpAddr* address, int* port, int addressNumber) {
+
+    DEBUGOUT("Shoutcast: start get address data\r\n");
+    fpin = fopen(FILEPLSMOD, "r");
+    bool finished = false;
+    int line = 0;
+    
+    while(!finished) {
+        finished = (fgets(_buffer, _buffer_size-1, fpin) == NULL);
+        if(line == addressNumber){
+            int ip1 = 0;int ip2 = 0;int ip3 = 0;int ip4 = 0;int p = 0;
+            sscanf (_buffer,"%d %d %d %d %d",&ip1,&ip2,&ip3,&ip4,&p);
+            DEBUGOUT("IpGet:%d %d %d %d:%d\r\n",ip1,ip2,ip3,ip4,p);
+            IpAddr server = IpAddr(ip1,ip2,ip3,ip4);
+            DEBUGOUT("IpGet:%d.%d.%d.%d:%d\r\n",server[0],server[1],server[2],server[3],p);
+            *address = server;
+            *port = p;
+            finished = true;
+        }
+        line++;
+    }
+    DEBUGOUT("Shoutcast: end get address data\r\n");
+    return 0;
+}
+
+void Shoutcast::onReply(DNSReply reply) {
+         if (reply==DNS_FOUND)
+             completed_dns=1;
+         else
+             completed_dns=-1;
+     };
+
+int Shoutcast::GetNextAddress(IpAddr* address, int* port)
+{
+    if(currentAddress < maxAddress - 1 )
+    {
+        currentAddress++;
+    }
+    else
+    {
+        currentAddress = 0;
+    }
+    GetAddressData(address,port,currentAddress);
+}
+int Shoutcast::GetCurrAddress(IpAddr* address, int* port)
+{
+    GetAddressData(address,port,currentAddress);
+}
+int Shoutcast::GetPrevAddress(IpAddr* address, int* port)
+{
+    if(currentAddress > 0 )
+    {
+        currentAddress--;
+    }
+    else
+    {
+        currentAddress = maxAddress - 1;
+    }
+    GetAddressData(address,port,currentAddress);
+}
\ No newline at end of file