diff -ruP src/ao.h libshairport.new/src/ao.h --- src/ao.h 2012-05-07 22:26:53.000000000 +0200 +++ src/ao.h 2012-05-08 18:46:42.000000000 +0200 @@ -152,5 +152,7 @@ /* -- Device Setup/Playback/Teardown -- */ int (*ao_append_option)(ao_option **, const char *, const char *); void (*ao_free_options)(ao_option *); - char* (*ao_get_option)(ao_option *, const char* ); + char* (*ao_get_option)(ao_option *, const char* ); + void (*ao_set_metadata)(const char *buffer, unsigned int size); + void (*ao_set_metadata_coverart)(const char *buffer, unsigned int size); }; diff -ruP src/hairtunes.c src/hairtunes.c --- src/hairtunes.c 2012-05-07 22:26:53.000000000 +0200 +++ src/hairtunes.c 2012-05-08 18:45:51.000000000 +0200 @@ -267,6 +267,16 @@ fix_volume = 65536.0 * volume; } +void hairtunes_set_metadata(const char *buffer, unsigned int size) +{ + g_ao.ao_set_metadata(buffer, size); +} + +void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size) +{ + g_ao.ao_set_metadata_coverart(buffer, size); +} + void hairtunes_flush(void) { pthread_mutex_lock(&ab_mutex); diff -ruP src/hairtunes.h src/hairtunes.h --- src/hairtunes.h 2011-08-21 00:06:21.000000000 +0200 +++ src/hairtunes.h 2012-05-08 18:46:00.000000000 +0200 @@ -4,6 +4,8 @@ int hairtunes_init(char *pAeskey, char *pAesiv, char *pFmtpstr, int pCtrlPort, int pTimingPort, int pDataPort, char *pRtpHost, char*pPipeName, char *pLibaoDriver, char *pLibaoDeviceName, char *pLibaoDeviceId); void hairtunes_setvolume(float vol); +void hairtunes_set_metadata(const char *buffer, unsigned int size); +void hairtunes_set_metadata_coverart(const char *buffer, unsigned int size); void hairtunes_flush(void); void hairtunes_cleanup(void); diff -ruP src/shairport.c src/shairport.c --- src/shairport.c 2012-05-07 22:26:53.000000000 +0200 +++ src/shairport.c 2012-05-08 18:45:30.000000000 +0200 @@ -513,7 +513,8 @@ while(1 == tMoreDataNeeded) { tError = readDataFromClient(pSock, &(tConn.recv)); - if(!tError && strlen(tConn.recv.data) > 0) + //if(!tError && strlen(tConn.recv.data) > 0) + if(!tError && tConn.recv.current > 0) { xprintf("Finished Reading some data from client\n"); // parse client request @@ -632,7 +633,7 @@ } tSize = (int) (tShortest - tFound); - xprintf("Found %.*s length: %d\n", tSize, tFound, tSize); + xprintf("Found %s length: %d\n",tFound, tSize); if(pReturnSize != NULL) { *pReturnSize = tSize; @@ -744,7 +745,7 @@ if(tContent != NULL) { int tContentSize = atoi(tContent); - if(pConn->recv.marker == 0 || strlen(pConn->recv.data+pConn->recv.marker) != tContentSize) + if(pConn->recv.marker == 0 || pConn->recv.current-pConn->recv.marker != tContentSize) { if(isLogEnabledFor(HEADER_LOG_LEVEL)) { @@ -752,7 +753,7 @@ if(pConn->recv.marker != 0) { xprintf("ContentPtr has %d, but needs %d\n", - strlen(pConn->recv.data+pConn->recv.marker), tContentSize); + (pConn->recv.current-pConn->recv.marker), tContentSize); } } // check if value in tContent > 2nd read from client. @@ -989,15 +990,67 @@ { propogateCSeq(pConn); int tSize = 0; + char *buffer = NULL; + char *contentType = getFromHeader(pConn->recv.data, "Content-Type", &tSize); + char *tContent = getFromHeader(pConn->recv.data, "Content-Length", NULL); + int iContentSize = 0; + int isJpg = 0; + + if(tContent != NULL) + { + iContentSize = atoi(tContent); + } + + if( tSize > 1 && + (strncmp(contentType, "application/x-dmap-tagged", tSize) == 0) || + (strncmp(contentType, "image/jpeg", tSize) == 0) ) + { + if( (pConn->recv.current - pConn->recv.marker) == iContentSize && pConn->recv.marker != 0) + { + if(strncmp(contentType, "image/jpeg", tSize) == 0) + { + isJpg = 1; + } + buffer = (char *)malloc(iContentSize * sizeof(char)); + memcpy(buffer, pConn->recv.data + pConn->recv.marker, iContentSize); + } + else + { + iContentSize = 0; + } + } + else + { + iContentSize = 0; + } char *tVol = getFromHeader(pConn->recv.data, "volume", &tSize); - xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol); + if( tVol) + { + xprintf("About to write [vol: %.*s] data to hairtunes\n", tSize, tVol); + } // TBD VOLUME #ifndef XBMC write(pConn->hairtunes->in[1], "vol: ", 5); write(pConn->hairtunes->in[1], tVol, tSize); write(pConn->hairtunes->in[1], "\n", 1); #else - hairtunes_setvolume(atof(tVol)); + if(tVol) + { + hairtunes_setvolume(atof(tVol)); + } + + if(iContentSize) + { + if(isJpg) + { + hairtunes_set_metadata_coverart(buffer, iContentSize); + } + else + { + hairtunes_set_metadata(buffer, iContentSize); + } + free(buffer); + } #endif xprintf("Finished writing data write data to hairtunes\n"); }