diff --git a/ChangeLog b/ChangeLog index c33ba48..375388c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -193,17 +193,48 @@ Version 1.8.0 Version 1.6.7 ******************************************************************************* +2010-03-21 Marcelo Jimenez + * SF Bug Tracker [ 2392304 ] Memory leak in SSDP AdvertiseAndReply + Submitted: Ulrik ( ulsv_enea ) - 2008-12-05 08:24 + + Valgrind reports a memory leak function in AdvertiseAndReply + (ssdp/ssdp_server.c) in libupnp 1.6.6 + + There are continue statements in many places in AdvertiseAndReply. In some + of those error handling cases the variable nodelist is not free'ed before + continuing to the next iteration. The next iteration will take care of + free'ing the nodelist from the previous iteration in most cases, but not + when breaking out of the for loop after the last element. + + I belive this memory leak can be solved by makeing sure that the rows + + ixmlNodeList_free( nodeList ); + nodeList = NULL; + + are always executed, also in the beginning of the last iteration when we + found out that there are not more elements. + + ==29110== at 0x4C21C16: malloc (vg_replace_malloc.c:149) + ==29110== by 0x5D8DE0E: ixmlNodeList_addToNodeList (nodeList.c:106) + ==29110== by 0x5D8B7E2: ixmlNode_getElementsByTagNameRecursive + (node.c:1438) + ==29110== by 0x5D8E587: ixmlElement_getElementsByTagName + (element.c:491) + ==29110== by 0x5B6C0F1: AdvertiseAndReply (ssdp_server.c:201) + ==29110== by 0x5B7AB74: UpnpSendAdvertisement (upnpapi.c:1495) + 2010-03-21 Marcelo Jimenez * libupnp and multi-flows scenario patch Submited by Carlo Parata from STMicroelectronics. -Hi Roberto and Nektarios, -after an analysis of the problem of libupnp with a multi-flows scenario, I -noticed that the only cause of the freezed system is the ThreadPool -management. There are not mutex problems. In practise, if all threads in the -thread pool are busy executing jobs, a new worker thread should be created if -a job is scheduled (I inspired to tombupnp library). So I solved the problem -with a little patch in threadutil library that you can find attached in this -e-mail. I hope to have helped you. + + Hi Roberto and Nektarios, + after an analysis of the problem of libupnp with a multi-flows scenario, I + noticed that the only cause of the freezed system is the ThreadPool + management. There are not mutex problems. In practise, if all threads in the + thread pool are busy executing jobs, a new worker thread should be created if + a job is scheduled (I inspired to tombupnp library). So I solved the problem + with a little patch in threadutil library that you can find attached in this + e-mail. I hope to have helped you. 2010-03-21 Marcelo Jimenez * SF Patch Tracker [ 2964973 ] install: will not overwrite just-created @@ -686,7 +717,7 @@ Version 1.6.1 handle accordingly. 2007-08-05 Marcelo Jimenez - * Merge of Mac OS X patch from Stéphane Corthésy (davelopper), + * Merge of Mac OS X patch from Stéphane Corthésy (davelopper), SF Bug Tracker [ 1686420 ] Modifications for MacOSX. Some of the proposed changes were already done by Rene Hexel's patch. @@ -1110,14 +1141,14 @@ Version 1.4.0 FORK FROM DEAD libupnp ******************************************************************************* -2006-04-29 Rémi Turboult +2006-04-29 Rémi Turboult * THANKS: new file with list of contributors * upnp/src/gena/gena_device.c (respond_ok): add 'Content-Length: 0' in subscription response. Patch by Chaos (Bug # 1455367). -2006-04-08 Rémi Turboult +2006-04-08 Rémi Turboult * upnp/doc/UPnP_Programming_Guide.pdf: replace this document with the one in libupnp-doc-1.2.1 because current CVS version @@ -1128,20 +1159,20 @@ FORK FROM DEAD libupnp * changes applied to several files to work under Sparc Solaris, temporarily requiring a define SPARC_SOLARIS -2006-04-03 Rémi Turboult +2006-04-03 Rémi Turboult * upnp/Makefile.am: install upnp samples in $(docdir)/examples -2006-03-28 Rémi Turboult +2006-03-28 Rémi Turboult * configure.ac: add --with-docdir option to choose where documentation is installed (or -without-docdir to not install the documentation) -2006-03-27 Rémi Turboult +2006-03-27 Rémi Turboult * ixml/test: add simple test suite for xml parser -2006-03-26 Rémi Turboult +2006-03-26 Rémi Turboult * ixml/src/ixmlparser.c (Parser_processCDSect): fix bug which prevents CDATA sections which contain a 0 (zero) to be parsed (instead the @@ -1152,18 +1183,18 @@ FORK FROM DEAD libupnp option, and move samples compilation from check_PROGRAMS to noinst_PROGRAMS -2006-03-25 Rémi Turboult +2006-03-25 Rémi Turboult * upnp/src/genlib/miniserver/miniserver.c (get_miniserver_sockets): fix bug if new socket created has fd 0 (can only occur when stdin has been closed). Patch by Oskar Liljeblad 2004-07-02 : http://sourceforge.net/mailarchive/message.php?msg_id=8870528 -2006-03-21 Rémi Turboult +2006-03-21 Rémi Turboult * upnp/test/test_init.c: add some version checks and exit if failure -2006-03-05 Rémi Turboult +2006-03-05 Rémi Turboult * libupnp version 1.3.1 @@ -1178,11 +1209,11 @@ FORK FROM DEAD libupnp dependencies between upnp and ixml / threadutil, so that programs linking against upnp only still work. -2006-03-04 Rémi Turboult +2006-03-04 Rémi Turboult * libupnp version 1.3.0 -2006-03-03 Rémi Turboult +2006-03-03 Rémi Turboult * upnp/src/genlib/net/http/httpreadwrite.c (get_sdk_info): use package version string from configure to set sdk info @@ -1190,7 +1221,7 @@ FORK FROM DEAD libupnp * upnp/Makefile.am: add sample/tvdevice/web/ files in EXTRA_DIST + do not distribute generated upnpconfig.h file. -2006-02-28 Rémi Turboult +2006-02-28 Rémi Turboult * upnp/src/inc/config.h, configure.ac: use only new defines UPNP_HAVE_xx instead of INCLUDE_yyy_APIS and INTERNAL_WEB_SERVER @@ -1199,7 +1230,7 @@ FORK FROM DEAD libupnp the librarie LDFLAGS in order to export only the symbols defined in the API -2006-02-27 Rémi Turboult +2006-02-27 Rémi Turboult * configure.ac: add libtool versions for the 3 libraries @@ -1207,7 +1238,7 @@ FORK FROM DEAD libupnp * threadutil/src/ThreadPool.c (SetSeed): add missing 'static' -2006-02-26 Rémi Turboult +2006-02-26 Rémi Turboult * threadutil/inc/iasnprintf.h: add gcc __printf__ format attribute to "iasnprintf" @@ -1228,11 +1259,11 @@ FORK FROM DEAD libupnp the configuration of the installed libraries (generates installed file ) -2006-02-22 Rémi Turboult +2006-02-22 Rémi Turboult * upnp/ : add missing include of config.h in some .c files -2006-02-21 Rémi Turboult +2006-02-21 Rémi Turboult * upnp/inc/upnp.h: move some definitions which should not be exported into "upnp/src/inc/util.h" @@ -1240,12 +1271,12 @@ FORK FROM DEAD libupnp * import all modifications below from libupnp in djmount 0.51 into official libupnp -2006-01-17 Rémi Turboult +2006-01-17 Rémi Turboult * threadutil/Makefile.am (libthreadutil_la_SOURCES): remove extraneous file -2006-01-15 Rémi Turboult +2006-01-15 Rémi Turboult * configure.ac: add checks for large-file support @@ -1265,53 +1296,53 @@ FORK FROM DEAD libupnp * ixml/src/node.c (ixmlNode_getNodeType): fix compilation warning on const return type -2006-01-12 Rémi Turboult +2006-01-12 Rémi Turboult * upnp/src/inc/readwrite.h : suppress unused C++ header file -2006-01-11 Rémi Turboult +2006-01-11 Rémi Turboult * upnp/inc/config.h, upnp/src/inc/upnpapi.h, upnp/src/inc/httpreadwrite.h: remove internal configuration variable MINIMUM_DELAY (no clear purpose) -2005-12-05 Rémi Turboult +2005-12-05 Rémi Turboult * upnp/inc/upnp.h: re-declare obsolete method UpnpSetContentLength, for binary compatibility with previous libupnp version. * upnp/src/api/upnpapi.c: correct type of g_maxContentLength to size_t -2005-11-01 Rémi Turboult +2005-11-01 Rémi Turboult * autoconfiscate library : replace all makefiles by Makefile.am for automake support, + preliminary autoconf support (generated config.h not yet used in source files) -2005-10-18 Rémi Turboult +2005-10-18 Rémi Turboult * upnp/src/makefile: fix location of DEBUG STATIC libupnp library * upnp/sample/tvctrlpt/linux/Makefile, upnp/sample/tvdevice/linux/Makefile: fix STATIC library support -2005-10-16 Rémi Turboult +2005-10-16 Rémi Turboult * threadutil/src/Makefile (clean): remove built library -2005-08-28 Rémi Turboult +2005-08-28 Rémi Turboult * ixml/src/ixml.h, ixml/src/ixml.c (ixmlRelaxParser) : new function * ixml/src/ixmlparser.h, ixml/src/ixmlparser.c (Parser_setErrorChar) : new function -2005-08-02 Rémi Turboult +2005-08-02 Rémi Turboult * ixml/src/Makefile: correct bug for static library being incorrectly stripped when building non-debug -2005-06-09 Rémi Turboult +2005-06-09 Rémi Turboult * ixml/src/element.c (ixmlElement_removeAttributeNode): remove some compilation warning @@ -1322,7 +1353,7 @@ FORK FROM DEAD libupnp * upnp/inc/upnptools.h, upnp/src/api/upnptools.c : add missing const's in public API -2005-05-28 Rémi Turboult +2005-05-28 Rémi Turboult * upnp/inc/config.h: suppress HTTP_READ_BYTES (unused) and replace by DEFAULT_SOAP_CONTENT_LENGTH (previously in upnpapi.h) @@ -1343,7 +1374,7 @@ FORK FROM DEAD libupnp * upnp/src/genlib/net/http/httpreadwrite.c : corrected an incorrect sprintf format -2005-05-27 Rémi Turboult +2005-05-27 Rémi Turboult * upnp/makefile, upnp/src/makefile, ixml/Makefile, ixml/src/Makefile, @@ -1351,7 +1382,7 @@ FORK FROM DEAD libupnp implement STATIC library support (from patch at http://sourceforge.net/tracker/?group_id=7189&atid=307189 ) -2005-05-26 Rémi Turboult +2005-05-26 Rémi Turboult * upnp/src/api/upnpapi.c, upnp/src/soap/soap_device.c, upnp/src/soap/makefile : diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index e513dad..b7e302a 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -96,309 +96,269 @@ struct SSDPSockArray { * Returns: int * UPNP_E_SUCCESS if successful else appropriate error ***************************************************************************/ -int AdvertiseAndReply( IN int AdFlag, - IN UpnpDevice_Handle Hnd, - IN enum SsdpSearchType SearchType, - IN struct sockaddr *DestAddr, - IN char *DeviceType, - IN char *DeviceUDN, - IN char *ServiceType, - int Exp ) +int AdvertiseAndReply( + IN int AdFlag, + IN UpnpDevice_Handle Hnd, + IN enum SsdpSearchType SearchType, + IN struct sockaddr *DestAddr, + IN char *DeviceType, + IN char *DeviceUDN, + IN char *ServiceType, + int Exp) { - int i, - j; - int defaultExp = DEFAULT_MAXAGE; - struct Handle_Info *SInfo = NULL; - char UDNstr[100], - devType[100], - servType[100]; - IXML_NodeList *nodeList = NULL; - IXML_NodeList *tmpNodeList = NULL; - IXML_Node *tmpNode = NULL; - IXML_Node *tmpNode2 = NULL; - IXML_Node *textNode = NULL; - const DOMString tmpStr; - char SERVER[200]; + int retVal = UPNP_E_SUCCESS; + int i; + int j; + int defaultExp = DEFAULT_MAXAGE; + struct Handle_Info *SInfo = NULL; + char UDNstr[100]; + char devType[100]; + char servType[100]; + IXML_NodeList *nodeList = NULL; + IXML_NodeList *tmpNodeList = NULL; + IXML_Node *tmpNode = NULL; + IXML_Node *tmpNode2 = NULL; + IXML_Node *textNode = NULL; + const DOMString tmpStr; + char SERVER[200]; + const DOMString dbgStr; - const DOMString dbgStr; - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Inside AdvertiseAndReply with AdFlag = %d\n", - AdFlag ); + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag); - // Use a read lock - HandleReadLock(); - if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { - HandleUnlock(); - return UPNP_E_INVALID_HANDLE; - } - defaultExp = SInfo->MaxAge; - - //get server info - - get_sdk_info( SERVER ); - - // parse the device list and send advertisements/replies - for( i = 0;; i++ ) { - - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Entering new device list with i = %d\n\n", i ); - - tmpNode = ixmlNodeList_item( SInfo->DeviceList, i ); - if( tmpNode == NULL ) { - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Exiting new device list with i = %d\n\n", i ); - break; - } - - dbgStr = ixmlNode_getNodeName( tmpNode ); - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "Extracting device type once for %s\n", dbgStr ); - // extract device type - ixmlNodeList_free( nodeList ); - nodeList = NULL; - nodeList = ixmlElement_getElementsByTagName( - ( IXML_Element * ) tmpNode, "deviceType" ); - if( nodeList == NULL ) { - continue; - } - - dbgStr = ixmlNode_getNodeName( tmpNode ); - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Extracting UDN for %s\n", dbgStr ); - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Extracting device type\n" ); - - tmpNode2 = ixmlNodeList_item( nodeList, 0 ); - if( tmpNode2 == NULL ) { - continue; - } - textNode = ixmlNode_getFirstChild( tmpNode2 ); - if( textNode == NULL ) { - continue; - } - - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Extracting device type \n" ); - - tmpStr = ixmlNode_getNodeValue( textNode ); - if( tmpStr == NULL ) { - continue; - } - - strcpy( devType, tmpStr ); - if( devType == NULL ) { - continue; - } - - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Extracting device type = %s\n", devType ); - if( tmpNode == NULL ) { - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "TempNode is NULL\n" ); + /* Use a read lock */ + HandleReadLock(); + if (GetHandleInfo(Hnd, &SInfo) != HND_DEVICE) { + retVal = UPNP_E_INVALID_HANDLE; + goto end_function; } - dbgStr = ixmlNode_getNodeName( tmpNode ); - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Extracting UDN for %s\n", dbgStr ); - // extract UDN - ixmlNodeList_free( nodeList ); - nodeList = NULL; - nodeList = ixmlElement_getElementsByTagName( ( IXML_Element * ) - tmpNode, "UDN" ); - if( nodeList == NULL ) { - UpnpPrintf( UPNP_CRITICAL, API, __FILE__, - __LINE__, "UDN not found!!!\n" ); - continue; - } - tmpNode2 = ixmlNodeList_item( nodeList, 0 ); - if( tmpNode2 == NULL ) { - UpnpPrintf( UPNP_CRITICAL, API, __FILE__, - __LINE__, "UDN not found!!!\n" ); - continue; - } - textNode = ixmlNode_getFirstChild( tmpNode2 ); - if( textNode == NULL ) { - UpnpPrintf( UPNP_CRITICAL, API, __FILE__, - __LINE__, "UDN not found!!!\n" ); - continue; - } - tmpStr = ixmlNode_getNodeValue( textNode ); - if( tmpStr == NULL ) { - UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, - "UDN not found!!!!\n" ); - continue; - } - strcpy( UDNstr, tmpStr ); - if( UDNstr == NULL ) { - continue; - } - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "Sending UDNStr = %s \n", UDNstr ); - if( AdFlag ) { - // send the device advertisement - if( AdFlag == 1 ) { - DeviceAdvertisement( devType, i == 0, + defaultExp = SInfo->MaxAge; + + /* get server info */ + get_sdk_info(SERVER); + + /* parse the device list and send advertisements/replies */ + for (i = 0;; i++) { + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Entering new device list with i = %d\n\n", i); + tmpNode = ixmlNodeList_item(SInfo->DeviceList, i); + if (!tmpNode) { + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Exiting new device list with i = %d\n\n", i); + break; + } + dbgStr = ixmlNode_getNodeName(tmpNode); + + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "Extracting device type once for %s\n", dbgStr); + ixmlNodeList_free(nodeList); + nodeList = ixmlElement_getElementsByTagName( + (IXML_Element *)tmpNode, "deviceType"); + if (!nodeList) continue; + + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Extracting UDN for %s\n", dbgStr); + dbgStr = ixmlNode_getNodeName(tmpNode); + + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Extracting device type\n"); + tmpNode2 = ixmlNodeList_item(nodeList, 0); + if (!tmpNode2) continue; + + textNode = ixmlNode_getFirstChild(tmpNode2); + if (!textNode) continue; + + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Extracting device type \n"); + tmpStr = ixmlNode_getNodeValue(textNode); + if (!tmpStr) continue; + + strcpy(devType, tmpStr); + UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, + "Extracting device type = %s\n", devType); + if (!tmpNode) { + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "TempNode is NULL\n"); + } + dbgStr = ixmlNode_getNodeName(tmpNode); + + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Extracting UDN for %s\n", dbgStr); + ixmlNodeList_free(nodeList); + nodeList = ixmlElement_getElementsByTagName( + (IXML_Element *)tmpNode, "UDN"); + if (!nodeList) { + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, + __LINE__, "UDN not found!\n"); + continue; + } + tmpNode2 = ixmlNodeList_item(nodeList, 0); + if (!tmpNode2) { + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, + __LINE__, "UDN not found!\n"); + continue; + } + textNode = ixmlNode_getFirstChild(tmpNode2); + if (!textNode) { + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, + __LINE__, "UDN not found!\n"); + continue; + } + tmpStr = ixmlNode_getNodeValue(textNode); + if (!tmpStr) { + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, + "UDN not found!\n"); + continue; + } + strcpy(UDNstr, tmpStr); + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "Sending UDNStr = %s \n", UDNstr); + if (AdFlag) { + /* send the device advertisement */ + if (AdFlag == 1) { + DeviceAdvertisement(devType, i == 0, UDNstr, SInfo->DescURL, Exp, SInfo->DeviceAf ); - } else { // AdFlag == -1 - DeviceShutdown( devType, i == 0, UDNstr, + } else { + /* AdFlag == -1 */ + DeviceShutdown(devType, i == 0, UDNstr, SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf ); - } - } else { - switch ( SearchType ) { - - case SSDP_ALL: - DeviceReply( DestAddr, - devType, i == 0, - UDNstr, SInfo->DescURL, defaultExp ); - break; - - case SSDP_ROOTDEVICE: - if( i == 0 ) { - SendReply( DestAddr, devType, 1, - UDNstr, SInfo->DescURL, defaultExp, 0 ); - } - break; - case SSDP_DEVICEUDN: - { - if( DeviceUDN != NULL && strlen( DeviceUDN ) != 0 ) { - if( strcasecmp( DeviceUDN, UDNstr ) ) { - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "DeviceUDN=%s and search " - "UDN=%s did not match\n", - UDNstr, DeviceUDN ); - break; - } else { - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "DeviceUDN=%s and search " - "UDN=%s MATCH\n", UDNstr, - DeviceUDN ); - SendReply( DestAddr, devType, 0, - UDNstr, SInfo->DescURL, - defaultExp, 0 ); - break; - } - } - } - case SSDP_DEVICETYPE: - { - if( !strncasecmp - ( DeviceType, devType, - strlen( DeviceType ) ) ) { - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "DeviceType=%s and search devType=%s MATCH\n", - devType, DeviceType ); - SendReply( DestAddr, devType, 0, UDNstr, - SInfo->DescURL, defaultExp, 1 ); - } else { - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "DeviceType=%s and search devType=%s" - " DID NOT MATCH\n", - devType, DeviceType ); } - break; - } - default: - break; - } - } - // send service advertisements for services corresponding - // to the same device - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "Sending service Advertisement\n" ); + } else { + switch (SearchType) { + case SSDP_ALL: + DeviceReply(DestAddr, devType, i == 0, + UDNstr, SInfo->DescURL, defaultExp); + break; + case SSDP_ROOTDEVICE: + if (i == 0) { + SendReply(DestAddr, devType, 1, + UDNstr, SInfo->DescURL, defaultExp, 0); + } + break; + case SSDP_DEVICEUDN: { + if (DeviceUDN && strlen(DeviceUDN) != 0) { + if (strcasecmp(DeviceUDN, UDNstr)) { + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "DeviceUDN=%s and search " + "UDN=%s did not match\n", + UDNstr, DeviceUDN); + break; + } else { + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "DeviceUDN=%s and search " + "UDN=%s MATCH\n", UDNstr, + DeviceUDN); + SendReply(DestAddr, devType, 0, + UDNstr, SInfo->DescURL, + defaultExp, 0); + break; + } + } + } + case SSDP_DEVICETYPE: { + if (!strncasecmp(DeviceType, devType, strlen(DeviceType))) { + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "DeviceType=%s and search devType=%s MATCH\n", + devType, DeviceType); + SendReply(DestAddr, devType, 0, UDNstr, + SInfo->DescURL, defaultExp, 1); + } else { + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "DeviceType=%s and search devType=%s" + " DID NOT MATCH\n", + devType, DeviceType); + } + break; + } + default: + break; + } + } + /* send service advertisements for services corresponding + * to the same device */ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "Sending service Advertisement\n"); - tmpNode = ixmlNodeList_item( SInfo->ServiceList, i ); - if( tmpNode == NULL ) { - continue; - } - ixmlNodeList_free( nodeList ); - nodeList = NULL; - nodeList = ixmlElement_getElementsByTagName( ( IXML_Element * ) - tmpNode, "service" ); - if( nodeList == NULL ) { - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "Service not found 3\n" ); - continue; - } - for( j = 0;; j++ ) { - tmpNode = ixmlNodeList_item( nodeList, j ); - if( tmpNode == NULL ) { - break; - } - - ixmlNodeList_free( tmpNodeList ); - tmpNodeList = NULL; - tmpNodeList = ixmlElement_getElementsByTagName( - ( IXML_Element *)tmpNode, "serviceType" ); - if( tmpNodeList == NULL ) { - UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, - "ServiceType not found \n" ); - continue; - } - tmpNode2 = ixmlNodeList_item( tmpNodeList, 0 ); - if( tmpNode2 == NULL ) { - continue; - } - textNode = ixmlNode_getFirstChild( tmpNode2 ); - if( textNode == NULL ) { - continue; - } - // servType is of format Servicetype:ServiceVersion - tmpStr = ixmlNode_getNodeValue( textNode ); - if( tmpStr == NULL ) { - continue; - } - strcpy( servType, tmpStr ); - if( servType == NULL ) { - continue; - } - - UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, - "ServiceType = %s\n", servType ); - if( AdFlag ) { - if( AdFlag == 1 ) { - ServiceAdvertisement( UDNstr, servType, + tmpNode = ixmlNodeList_item(SInfo->ServiceList, i); + if (!tmpNode) continue; + ixmlNodeList_free(nodeList); + nodeList = ixmlElement_getElementsByTagName( + (IXML_Element *)tmpNode, "service"); + if (!nodeList) { + UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, + "Service not found 3\n" ); + continue; + } + for (j = 0;; j++) { + tmpNode = ixmlNodeList_item(nodeList, j); + if (!tmpNode) { + break; + } + ixmlNodeList_free(tmpNodeList); + tmpNodeList = ixmlElement_getElementsByTagName( + (IXML_Element *)tmpNode, "serviceType"); + if (!tmpNodeList) { + UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, + "ServiceType not found \n"); + continue; + } + tmpNode2 = ixmlNodeList_item(tmpNodeList, 0); + if (!tmpNode2) continue; + textNode = ixmlNode_getFirstChild(tmpNode2); + if (!textNode) continue; + /* servType is of format Servicetype:ServiceVersion */ + tmpStr = ixmlNode_getNodeValue(textNode); + if (!tmpStr) continue; + strcpy(servType, tmpStr); + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "ServiceType = %s\n", servType); + if (AdFlag) { + if (AdFlag == 1) { + ServiceAdvertisement(UDNstr, servType, SInfo->DescURL, Exp, SInfo->DeviceAf ); - } else { // AdFlag == -1 - ServiceShutdown( UDNstr, servType, + } else { + /* AdFlag == -1 */ + ServiceShutdown(UDNstr, servType, SInfo->DescURL, Exp, SInfo->DeviceAf ); - } - } else { - switch ( SearchType ) { - case SSDP_ALL: - ServiceReply( DestAddr, servType, - UDNstr, SInfo->DescURL, - defaultExp ); - break; - case SSDP_SERVICE: - if( ServiceType != NULL ) { - if( !strncasecmp( ServiceType, - servType, - strlen( ServiceType ) ) ) { - ServiceReply( DestAddr, servType, - UDNstr, SInfo->DescURL, - defaultExp ); - } - } - break; - default: - break; - } // switch(SearchType) + } + } else { + switch (SearchType) { + case SSDP_ALL: + ServiceReply(DestAddr, servType, + UDNstr, SInfo->DescURL, + defaultExp); + break; + case SSDP_SERVICE: + if (ServiceType) { + if (!strncasecmp(ServiceType, servType, strlen(ServiceType))) { + ServiceReply(DestAddr, servType, + UDNstr, SInfo->DescURL, defaultExp); + } + } + break; + default: + break; + } + } + } + ixmlNodeList_free(tmpNodeList); + tmpNodeList = NULL; + ixmlNodeList_free(nodeList); + nodeList = NULL; + } - } - } - ixmlNodeList_free( tmpNodeList ); - tmpNodeList = NULL; - ixmlNodeList_free( nodeList ); - nodeList = NULL; - } - UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, - "Exiting AdvertiseAndReply : \n" ); +end_function: + ixmlNodeList_free(tmpNodeList); + ixmlNodeList_free(nodeList); - HandleUnlock(); + UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, + "Exiting AdvertiseAndReply.\n"); - return UPNP_E_SUCCESS; + HandleUnlock(); -} /****************** End of AdvertiseAndReply *********************/ + return retVal; +} #endif /* EXCLUDE_SSDP == 0 */ #endif /* INCLUDE_DEVICE_APIS */