📄 ssdp_server.c
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000-2003 Intel Corporation // All rights reserved. //// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: //// * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission.// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE./////////////////////////////////////////////////////////////////////////////#include "config.h"#if EXCLUDE_SSDP == 0#include "membuffer.h"#include "ssdplib.h"#include <stdio.h>#include "ThreadPool.h"#include "miniserver.h"#include "upnpapi.h"#include "httpparser.h"#include "httpreadwrite.h"#define MAX_TIME_TOREAD 45CLIENTONLY( SOCKET gSsdpReqSocket = 0; ) void RequestHandler( ); Event ErrotEvt; enum Listener { Idle, Stopping, Running }; unsigned short ssdpStopPort; struct SSDPSockArray { int ssdpSock; //socket for incoming advertisments and search requests CLIENTONLY( int ssdpReqSock; ) //socket for sending search //requests and receiving // search replies };#ifdef INCLUDE_DEVICE_APIS#if EXCLUDE_SSDP == 0/************************************************************************* Function : AdvertiseAndReply * * Parameters: * IN int AdFlag: -1 = Send shutdown, 0 = send reply, * 1 = Send Advertisement* IN UpnpDevice_Handle Hnd: Device handle* IN enum SsdpSearchType SearchType:Search type for sending replies* IN struct sockaddr_in *DestAddr:Destination address* IN char *DeviceType:Device type* IN char *DeviceUDN:Device UDN* IN char *ServiceType:Service type* IN int Exp:Advertisement age** Description: * This function sends SSDP advertisements, replies and shutdown messages.** 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_in *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; DOMString tmpStr; char SERVER[200]; DBGONLY( const DOMString dbgStr; UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag ); ) HandleLock( ); if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { HandleUnlock( ); return UPNP_E_INVALID_HANDLE; } defaultExp = SInfo->MaxAge; //Modifed to prevent more than one thread from accessing the //UpnpDocument stored with the handle at the same time // HandleUnlock(); nodeList = NULL; //get server info get_sdk_info( SERVER ); // parse the device list and send advertisements/replies for( i = 0;; i++ ) { DBGONLY( 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 ) { DBGONLY( UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Exiting new device list with i = %d\n\n", i ); ) break; } DBGONLY( 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; } DBGONLY( dbgStr = ixmlNode_getNodeName( tmpNode ); UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, "Extracting UDN for %s\n", dbgStr ); ) DBGONLY( 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; } DBGONLY( 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; } DBGONLY( 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" );} 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 ) { DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, "UDN not found!!!\n" ); ) continue; } tmpNode2 = ixmlNodeList_item( nodeList, 0 ); if( tmpNode2 == NULL ) { DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, "UDN not found!!!\n" ); ) continue; } textNode = ixmlNode_getFirstChild( tmpNode2 ); if( textNode == NULL ) { DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, "UDN not found!!!\n" ); ) continue; } tmpStr = ixmlNode_getNodeValue( textNode ); if( tmpStr == NULL ) { DBGONLY( UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, "UDN not found!!!!\n" ); ) continue; } strcpy( UDNstr, tmpStr ); if( UDNstr == NULL ) { continue; } DBGONLY( 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 ); } else // AdFlag == -1 { DeviceShutdown( devType, i == 0, UDNstr, SERVER, SInfo->DescURL, Exp ); } } 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 ) ) { DBGONLY( UpnpPrintf ( UPNP_INFO, API, __FILE__, __LINE__, "DeviceUDN=%s and search " "UDN=%s did not match\n", UDNstr, DeviceUDN ); ) break; } else { DBGONLY( 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 ) ) ) { DBGONLY( 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 ); } DBGONLY( 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 DBGONLY( 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -