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.
This commit is contained in:
Fabrice Fontaine 2010-11-05 19:01:13 +01:00 committed by Marcelo Roberto Jimenez
parent 2d22e997e1
commit c65ec8a720
3 changed files with 242 additions and 247 deletions

View File

@ -2,6 +2,14 @@
Version 1.6.9 Version 1.6.9
******************************************************************************* *******************************************************************************
2010-11-08 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
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 <fabrice.fontaine(at)orange-ftgroup.com> 2010-11-05 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Removing unused NUM_COPY variable. Removing unused NUM_COPY variable.

View File

@ -535,18 +535,13 @@ DeviceAdvertisement( IN char *DevType,
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
// send packets // send packets
int NumCopy = 0; if( RootDev ) {
while( ret_code == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { // send 3 msg types
if( RootDev ) { ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
// send 3 msg types } else // sub-device
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] );
// send 2 msg types
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
}
NumCopy++;
imillisleep(SSDP_PAUSE);
} }
// free msgs // free msgs
@ -769,12 +764,7 @@ ServiceAdvertisement( IN char *Udn,
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
int NumCopy = 0; RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
while( RetVal == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) {
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
NumCopy++;
imillisleep(SSDP_PAUSE);
}
free( szReq[0] ); free( szReq[0] );
return RetVal; return RetVal;
@ -879,12 +869,7 @@ ServiceShutdown( IN char *Udn,
if( szReq[0] == NULL ) { if( szReq[0] == NULL ) {
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
int NumCopy = 0; RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
while( RetVal == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) {
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
NumCopy++;
imillisleep(SSDP_PAUSE);
}
free( szReq[0] ); free( szReq[0] );
return RetVal; return RetVal;
@ -971,18 +956,13 @@ DeviceShutdown( IN char *DevType,
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
// send packets // send packets
int NumCopy = 0; if( RootDev ) {
while( ret_code == UPNP_E_SUCCESS && NumCopy < NUM_SSDP_COPY ) { // send 3 msg types
if( RootDev ) { ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
// send 3 msg types } else // sub-device
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] );
// send 2 msg types
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
}
NumCopy++;
imillisleep(SSDP_PAUSE);
} }
// free msgs // free msgs

View File

@ -135,6 +135,7 @@ int AdvertiseAndReply(
const DOMString tmpStr; const DOMString tmpStr;
char SERVER[200]; char SERVER[200];
const DOMString dbgStr; const DOMString dbgStr;
int NumCopy = 0;
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag); "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag);
@ -152,245 +153,251 @@ int AdvertiseAndReply(
get_sdk_info(SERVER); get_sdk_info(SERVER);
/* parse the device list and send advertisements/replies */ /* parse the device list and send advertisements/replies */
for (i = 0;; i++) { while (NumCopy == 0 || (AdFlag && NumCopy < NUM_SSDP_COPY)) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, if (NumCopy != 0)
"Entering new device list with i = %d\n\n", i); imillisleep(SSDP_PAUSE);
tmpNode = ixmlNodeList_item(SInfo->DeviceList, i); NumCopy++;
if (!tmpNode) {
for (i = 0;; i++) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Exiting new device list with i = %d\n\n", i); "Entering new device list with i = %d\n\n", i);
break; tmpNode = ixmlNodeList_item(SInfo->DeviceList, i);
} if (!tmpNode) {
dbgStr = ixmlNode_getNodeName(tmpNode); UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Exiting new device list with i = %d\n\n", i);
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, break;
"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 );
} }
} else { dbgStr = ixmlNode_getNodeName(tmpNode);
switch (SearchType) {
case SSDP_ALL: UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
DeviceReply(DestAddr, devType, i == 0, "Extracting device type once for %s\n", dbgStr);
UDNstr, SInfo->DescURL, defaultExp); ixmlNodeList_free(nodeList);
break; nodeList = ixmlElement_getElementsByTagName(
case SSDP_ROOTDEVICE: (IXML_Element *)tmpNode, "deviceType");
if (i == 0) { if (!nodeList) continue;
SendReply(DestAddr, devType, 1,
UDNstr, SInfo->DescURL, defaultExp, 0); 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; } else {
case SSDP_DEVICEUDN: { switch (SearchType) {
if (DeviceUDN && strlen(DeviceUDN) != 0) { case SSDP_ALL:
if (strcasecmp(DeviceUDN, UDNstr)) { DeviceReply(DestAddr, devType, i == 0,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UDNstr, SInfo->DescURL, defaultExp);
"DeviceUDN=%s and search UDN=%s DID NOT match\n", break;
UDNstr, DeviceUDN); case SSDP_ROOTDEVICE:
break; if (i == 0) {
} else { SendReply(DestAddr, devType, 1,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UDNstr, SInfo->DescURL, defaultExp, 0);
"DeviceUDN=%s and search UDN=%s MATCH\n", }
UDNstr, DeviceUDN); break;
SendReply(DestAddr, devType, 0, case SSDP_DEVICEUDN: {
UDNstr, SInfo->DescURL, if (DeviceUDN && strlen(DeviceUDN) != 0) {
defaultExp, 0); if (strcasecmp(DeviceUDN, UDNstr)) {
break; 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: {
case SSDP_DEVICETYPE: { if (!strncasecmp(DeviceType, devType, strlen(DeviceType)-2)) {
if (!strncasecmp(DeviceType, devType, strlen(DeviceType)-2)) { if (atoi(&DeviceType[strlen(DeviceType)-1]) <= atoi(&devType[strlen(devType)-1])) {
if (atoi(&DeviceType[strlen(DeviceType)-1]) <= atoi(&devType[strlen(devType)-1])) { /* the requested version is lower than the device version
/* the requested version is lower than the device version * must reply with the lower version number */
* must reply with the lower version number */ UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "DeviceType=%s and search devType=%s MATCH\n",
"DeviceType=%s and search devType=%s MATCH\n", devType, DeviceType);
devType, DeviceType); SendReply(DestAddr, DeviceType, 0, UDNstr, SInfo->DescURL, defaultExp, 1);
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 { } else {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"DeviceType=%s and search devType=%s DID NOT MATCH\n", "DeviceType=%s and search devType=%s DID NOT MATCH\n",
devType, DeviceType); devType, DeviceType);
} }
} else { break;
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, }
"DeviceType=%s and search devType=%s DID NOT MATCH\n", default:
devType, DeviceType); break;
} }
break;
} }
default: /* send service advertisements for services corresponding
break; * 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 /* Correct service traversal such that each device's serviceList
* is directly traversed as a child of its parent device. This * is directly traversed as a child of its parent device. This
* ensures that the service's alive message uses the UDN of * ensures that the service's alive message uses the UDN of
* the parent device. */ * the parent device. */
tmpNode = ixmlNode_getFirstChild(tmpNode); tmpNode = ixmlNode_getFirstChild(tmpNode);
while (tmpNode) { while (tmpNode) {
dbgStr = ixmlNode_getNodeName(tmpNode); dbgStr = ixmlNode_getNodeName(tmpNode);
if (!strncmp(dbgStr, SERVICELIST_STR, sizeof SERVICELIST_STR)) { if (!strncmp(dbgStr, SERVICELIST_STR, sizeof SERVICELIST_STR)) {
break; break;
}
tmpNode = ixmlNode_getNextSibling(tmpNode);
} }
tmpNode = ixmlNode_getNextSibling(tmpNode); ixmlNodeList_free(nodeList);
}
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);
if (!tmpNode) { if (!tmpNode) {
break; nodeList = NULL;
}
ixmlNodeList_free(tmpNodeList);
tmpNodeList = ixmlElement_getElementsByTagName(
(IXML_Element *)tmpNode, "serviceType");
if (!tmpNodeList) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"ServiceType not found \n");
continue; continue;
} }
tmpNode2 = ixmlNodeList_item(tmpNodeList, 0); nodeList = ixmlElement_getElementsByTagName(
if (!tmpNode2) continue; (IXML_Element *)tmpNode, "service");
textNode = ixmlNode_getFirstChild(tmpNode2); if (!nodeList) {
if (!textNode) continue; UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
/* servType is of format Servicetype:ServiceVersion */ "Service not found 3\n" );
tmpStr = ixmlNode_getNodeValue(textNode); continue;
if (!tmpStr) continue; }
strcpy(servType, tmpStr); for (j = 0;; j++) {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, tmpNode = ixmlNodeList_item(nodeList, j);
"ServiceType = %s\n", servType); if (!tmpNode) {
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; break;
case SSDP_SERVICE: }
if (ServiceType) { ixmlNodeList_free(tmpNodeList);
if (!strncasecmp(ServiceType, servType, strlen(ServiceType) - 2)) { tmpNodeList = ixmlElement_getElementsByTagName(
if (atoi(&ServiceType[strlen(ServiceType)-1]) <= atoi(&servType[strlen(servType)-1])) { (IXML_Element *)tmpNode, "serviceType");
/* the requested version is lower than the service version if (!tmpNodeList) {
* must reply with the lower version number */ UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "ServiceType not found \n");
"ServiceType=%s and search servType=%s MATCH\n", continue;
ServiceType, servType); }
SendReply(DestAddr, ServiceType, 0, UDNstr, SInfo->DescURL, defaultExp, 1); 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 { } else {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"ServiceType=%s and search servType=%s DID NOT MATCH\n", "ServiceType=%s and search servType=%s DID NOT MATCH\n",
ServiceType, servType); 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: end_function: