diff --git a/ChangeLog b/ChangeLog index 3a3e31e..3beb111 100644 --- a/ChangeLog +++ b/ChangeLog @@ -221,6 +221,14 @@ Version 1.8.0 Version 1.6.9 ******************************************************************************* +2010-11-08 Fabrice Fontaine + + Make multiple SSDP advertisements faster. + + Put the loop to send multiple copies of each SSDP advertisements in + ssdp_server.c instead of ssdp_device.c so we have only one call to + imillisleep ( SSDP_PAUSE ) to speed up advertisements. + 2010-11-05 Fabrice Fontaine Removing unused NUM_COPY variable. diff --git a/upnp/src/ssdp/ssdp_device.c b/upnp/src/ssdp/ssdp_device.c index fd489a9..fdd8548 100644 --- a/upnp/src/ssdp/ssdp_device.c +++ b/upnp/src/ssdp/ssdp_device.c @@ -535,18 +535,13 @@ DeviceAdvertisement( IN char *DevType, return UPNP_E_OUTOF_MEMORY; } // send packets - int NumCopy = 0; - while( ret_code == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { - if( RootDev ) { - // send 3 msg types - ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] ); - } else // sub-device - { - // send 2 msg types - ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] ); - } - NumCopy++; - imillisleep(SSDP_PAUSE); + if( RootDev ) { + // send 3 msg types + ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] ); + } else // sub-device + { + // send 2 msg types + ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] ); } // free msgs @@ -769,12 +764,7 @@ ServiceAdvertisement( IN char *Udn, return UPNP_E_OUTOF_MEMORY; } - int NumCopy = 0; - while( RetVal == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { - RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq ); - NumCopy++; - imillisleep(SSDP_PAUSE); - } + RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq ); free( szReq[0] ); return RetVal; @@ -879,12 +869,7 @@ ServiceShutdown( IN char *Udn, if( szReq[0] == NULL ) { return UPNP_E_OUTOF_MEMORY; } - int NumCopy = 0; - while( RetVal == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { - RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq ); - NumCopy++; - imillisleep(SSDP_PAUSE); - } + RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq ); free( szReq[0] ); return RetVal; @@ -971,18 +956,13 @@ DeviceShutdown( IN char *DevType, return UPNP_E_OUTOF_MEMORY; } // send packets - int NumCopy = 0; - while( ret_code == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { - if( RootDev ) { - // send 3 msg types - ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] ); - } else // sub-device - { - // send 2 msg types - ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] ); - } - NumCopy++; - imillisleep(SSDP_PAUSE); + if( RootDev ) { + // send 3 msg types + ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] ); + } else // sub-device + { + // send 2 msg types + ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] ); } // free msgs diff --git a/upnp/src/ssdp/ssdp_server.c b/upnp/src/ssdp/ssdp_server.c index af85078..8a24e7e 100644 --- a/upnp/src/ssdp/ssdp_server.c +++ b/upnp/src/ssdp/ssdp_server.c @@ -135,6 +135,7 @@ int AdvertiseAndReply( const DOMString tmpStr; char SERVER[200]; const DOMString dbgStr; + int NumCopy = 0; UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag); @@ -152,245 +153,251 @@ int AdvertiseAndReply( 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) { + while (NumCopy == 0 || (AdFlag && NumCopy < NUM_SSDP_COPY)) { + if (NumCopy != 0) + imillisleep(SSDP_PAUSE); + NumCopy++; + + for (i = 0;; i++) { 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, - SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf ); + "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; } - } 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); + 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, + SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf ); } - 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; + } 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)-2)) { - if (atoi(&DeviceType[strlen(DeviceType)-1]) <= atoi(&devType[strlen(devType)-1])) { - /* the requested version is lower than the device version - * must reply with the lower version number */ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, - "DeviceType=%s and search devType=%s MATCH\n", - devType, DeviceType); - SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->DescURL, defaultExp, 1); + case SSDP_DEVICETYPE: { + if (!strncasecmp(DeviceType, devType, strlen(DeviceType)-2)) { + if (atoi(&DeviceType[strlen(DeviceType)-1]) <= atoi(&devType[strlen(devType)-1])) { + /* the requested version is lower than the device version + * must reply with the lower version number */ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "DeviceType=%s and search devType=%s MATCH\n", + devType, DeviceType); + SendReply(DestAddr, DeviceType, 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); + } } else { UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "DeviceType=%s and search devType=%s DID NOT MATCH\n", devType, DeviceType); } - } else { - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, - "DeviceType=%s and search devType=%s DID NOT MATCH\n", - devType, DeviceType); + break; + } + default: + break; } - break; } - default: - break; - } - } - /* send service advertisements for services corresponding - * to the same device */ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, - "Sending service Advertisement\n"); + /* send service advertisements for services corresponding + * to the same device */ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "Sending service Advertisement\n"); - /* Correct service traversal such that each device's serviceList - * is directly traversed as a child of its parent device. This - * ensures that the service's alive message uses the UDN of - * the parent device. */ - tmpNode = ixmlNode_getFirstChild(tmpNode); - while (tmpNode) { - dbgStr = ixmlNode_getNodeName(tmpNode); - if (!strncmp(dbgStr, SERVICELIST_STR, sizeof SERVICELIST_STR)) { - break; + /* Correct service traversal such that each device's serviceList + * is directly traversed as a child of its parent device. This + * ensures that the service's alive message uses the UDN of + * the parent device. */ + tmpNode = ixmlNode_getFirstChild(tmpNode); + while (tmpNode) { + dbgStr = ixmlNode_getNodeName(tmpNode); + if (!strncmp(dbgStr, SERVICELIST_STR, sizeof SERVICELIST_STR)) { + break; + } + tmpNode = ixmlNode_getNextSibling(tmpNode); } - tmpNode = ixmlNode_getNextSibling(tmpNode); - } - ixmlNodeList_free(nodeList); - if (!tmpNode) { - nodeList = NULL; - continue; - } - 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); + ixmlNodeList_free(nodeList); 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"); + nodeList = NULL; 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, - SInfo->DescURL, Exp, SInfo->DeviceAf ); - } - } else { - switch (SearchType) { - case SSDP_ALL: - ServiceReply(DestAddr, servType, - UDNstr, SInfo->DescURL, - defaultExp); + 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; - case SSDP_SERVICE: - if (ServiceType) { - if (!strncasecmp(ServiceType, servType, strlen(ServiceType) - 2)) { - if (atoi(&ServiceType[strlen(ServiceType)-1]) <= atoi(&servType[strlen(servType)-1])) { - /* the requested version is lower than the service version - * must reply with the lower version number */ - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, - "ServiceType=%s and search servType=%s MATCH\n", - ServiceType, servType); - SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->DescURL, defaultExp, 1); + } + 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, + SInfo->DescURL, Exp, SInfo->DeviceAf ); + } + } 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) - 2)) { + if (atoi(&ServiceType[strlen(ServiceType)-1]) <= atoi(&servType[strlen(servType)-1])) { + /* the requested version is lower than the service version + * must reply with the lower version number */ + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "ServiceType=%s and search servType=%s MATCH\n", + ServiceType, servType); + SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->DescURL, defaultExp, 1); + } else { + UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, + "ServiceType=%s and search servType=%s DID NOT MATCH\n", + ServiceType, servType); + } } else { UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "ServiceType=%s and search servType=%s DID NOT MATCH\n", ServiceType, servType); } - } else { - UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, - "ServiceType=%s and search servType=%s DID NOT MATCH\n", - ServiceType, servType); } + break; + default: + break; } - break; - default: - break; } } + ixmlNodeList_free(tmpNodeList); + tmpNodeList = NULL; + ixmlNodeList_free(nodeList); + nodeList = NULL; } - ixmlNodeList_free(tmpNodeList); - tmpNodeList = NULL; - ixmlNodeList_free(nodeList); - nodeList = NULL; } end_function: