📄 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"#ifdef WIN32 #include <string.h> #include <winsock2.h> #include <ws2tcpip.h> #include "unixutil.h"#endif#define MAX_TIME_TOREAD 45CLIENTONLY( SOCKET gSsdpReqSocket = 0; )void RequestHandler();Event ErrotEvt;enum Listener { Idle, Stopping, Running };unsigned short ssdpStopPort;struct SSDPSockArray { // socket for incoming advertisments and search requests int ssdpSock; // socket for sending search requests and receiving search replies CLIENTONLY( int ssdpReqSock; )};#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; const DOMString tmpStr; char SERVER[200]; const DOMString dbgStr; 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" ); } 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, 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 ) ) { 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 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -