⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 upnpapi.c

📁 原来由英特尔制定的UPnP SDK的
💻 C
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////// 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"#include <sys/stat.h>#include <assert.h>#include <signal.h>#include <stdlib.h>#include <string.h>#ifndef WIN32	#include <arpa/inet.h>	#include <net/if.h>	#include <netinet/in.h>	#include <sys/ioctl.h>	#include <sys/param.h>	#include <sys/socket.h>	#include <sys/types.h>	#include <sys/utsname.h>	#include <unistd.h>	#if defined(_sun)		#include <sys/sockio.h>		#include <fcntl.h>	#elif defined(BSD) && BSD >= 199306		#include <ifaddrs.h>	#endif#endif /* WIN32 */#include "upnpapi.h"#include "httpreadwrite.h"#include "membuffer.h"#include "ssdplib.h"#include "soaplib.h"#include "ThreadPool.h"// Needed for GENA#include "gena.h"#include "miniserver.h"#include "service_table.h"#ifdef INTERNAL_WEB_SERVER	#include "webserver.h"	#include "urlconfig.h"#endif // INTERNAL_WEB_SERVER//virtualDirList *pVirtualDirList;// Mutex to synchronize the subscription handling at the client sideCLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex; )// rwlock to synchronize handles (root device or control point handle)    ithread_rwlock_t GlobalHndRWLock;// Mutex to synchronize the uuid creation process    ithread_mutex_t gUUIDMutex;    TimerThread gTimerThread;    ThreadPool gSendThreadPool;    ThreadPool gRecvThreadPool;    ThreadPool gMiniServerThreadPool;//Flag to indicate the state of web server     WebServerState bWebServerState = WEB_SERVER_DISABLED;// static buffer to store the local host ip address or host name     char LOCAL_HOST[LINE_SIZE];// local port for the mini-server     unsigned short LOCAL_PORT;// UPnP device and control point handle table      void *HandleTable[NUM_HANDLE];//This structure is for virtual directory callbacks     struct UpnpVirtualDirCallbacks virtualDirCallback;// a local dir which serves as webserver root     extern membuffer gDocumentRootDir;// Maximum content-length that the SDK will process on an incoming packet. // Content-Length exceeding this size will be not processed and error 413 // (HTTP Error Code) will be returned to the remote end point.size_t g_maxContentLength = DEFAULT_SOAP_CONTENT_LENGTH; // in bytes// Global variable to denote the state of Upnp SDK //    = 0 if uninitialized, = 1 if initialized.     int UpnpSdkInit = 0;// Global variable to denote the state of Upnp SDK device registration.// = 0 if unregistered, = 1 if registered.     int UpnpSdkDeviceRegistered = 0;// Global variable to denote the state of Upnp SDK client registration.// = 0 if unregistered, = 1 if registered.     int UpnpSdkClientRegistered = 0;/**************************************************************************** * Function: UpnpInit * * Parameters:		 *	IN const char * HostIP: Local IP Address *	IN short DestPort: Local Port to listen for incoming connections * Description: *	Initializes  *		- Mutex objects,  *		- Handle Table *		- Thread Pool and Thread Pool Attributes *		- MiniServer(starts listening for incoming requests)  *			and WebServer (Sends request to the  *		        Upper Layer after HTTP Parsing) *		- Checks for IP Address passed as an argument. IF NULL,  *                gets local host name *		- Sets GENA and SOAP Callbacks. *		- Starts the timer thread. * * Returns: *	UPNP_E_SUCCESS on success, nonzero on failure. *	UPNP_E_INIT_FAILED if Initialization fails. *	UPNP_E_INIT if UPnP is already initialized *****************************************************************************/int UpnpInit( IN const char *HostIP,              IN unsigned short DestPort ){    int retVal = 0;    ThreadPoolAttr attr;#ifdef WIN32	WORD wVersionRequested;	WSADATA wsaData;	int err;#endif    if( UpnpSdkInit == 1 ) {        // already initialized        return UPNP_E_INIT;    }#ifdef WIN32	wVersionRequested = MAKEWORD( 2, 2 );	err = WSAStartup( wVersionRequested, &wsaData );	if ( err != 0 ) {		/* Tell the user that we could not find a usable */		/* WinSock DLL.                                  */		return UPNP_E_INIT_FAILED;	}	/* Confirm that the WinSock DLL supports 2.2.*/	/* Note that if the DLL supports versions greater    */	/* than 2.2 in addition to 2.2, it will still return */	/* 2.2 in wVersion since that is the version we      */	/* requested.                                        */	 	if ( LOBYTE( wsaData.wVersion ) != 2 ||			HIBYTE( wsaData.wVersion ) != 2 ) {		/* Tell the user that we could not find a usable */		/* WinSock DLL.                                  */		WSACleanup( );		return UPNP_E_INIT_FAILED; 	}	/* The WinSock DLL is acceptable. Proceed. */#endif    membuffer_init( &gDocumentRootDir );    srand( time( NULL ) );      // needed by SSDP or other parts    if( UpnpInitLog() != UPNP_E_SUCCESS ) {             return UPNP_E_INIT_FAILED;    }    UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpInit\n" );    // initialize mutex#ifdef __CYGWIN__        /* On Cygwin, pthread_mutex_init() fails without this memset. */        /* TODO: Fix Cygwin so we don't need this memset(). */        memset(&GlobalHndRWLock, 0, sizeof(GlobalHndRWLock));#endif    if (ithread_rwlock_init(&GlobalHndRWLock, NULL) != 0) {        return UPNP_E_INIT_FAILED;    }    if (ithread_mutex_init(&gUUIDMutex, NULL) != 0) {        return UPNP_E_INIT_FAILED;    }    // initialize subscribe mutex#ifdef INCLUDE_CLIENT_APIS    if (ithread_mutex_init(&GlobalClientSubscribeMutex, NULL) != 0) {        return UPNP_E_INIT_FAILED;    }#endif    HandleLock();    if( HostIP != NULL ) {        strcpy( LOCAL_HOST, HostIP );    } else {        if( getlocalhostname( LOCAL_HOST ) != UPNP_E_SUCCESS ) {            HandleUnlock();            return UPNP_E_INIT_FAILED;        }    }    if( UpnpSdkInit != 0 ) {        HandleUnlock();        return UPNP_E_INIT;    }    InitHandleList();    HandleUnlock();    TPAttrInit( &attr );    TPAttrSetMaxThreads( &attr, MAX_THREADS );    TPAttrSetMinThreads( &attr, MIN_THREADS );    TPAttrSetJobsPerThread( &attr, JOBS_PER_THREAD );    TPAttrSetIdleTime( &attr, THREAD_IDLE_TIME );    TPAttrSetMaxJobsTotal( &attr, MAX_JOBS_TOTAL );    if( ThreadPoolInit( &gSendThreadPool, &attr ) != UPNP_E_SUCCESS ) {        UpnpSdkInit = 0;        UpnpFinish();        return UPNP_E_INIT_FAILED;    }    if( ThreadPoolInit( &gRecvThreadPool, &attr ) != UPNP_E_SUCCESS ) {        UpnpSdkInit = 0;        UpnpFinish();        return UPNP_E_INIT_FAILED;    }    if( ThreadPoolInit( &gMiniServerThreadPool, &attr ) != UPNP_E_SUCCESS ) {        UpnpSdkInit = 0;        UpnpFinish();        return UPNP_E_INIT_FAILED;    }    UpnpSdkInit = 1;#if EXCLUDE_SOAP == 0    SetSoapCallback( soap_device_callback );#endif#if EXCLUDE_GENA == 0    SetGenaCallback( genaCallback );#endif    if( ( retVal = TimerThreadInit( &gTimerThread,                                    &gSendThreadPool ) ) !=        UPNP_E_SUCCESS ) {        UpnpSdkInit = 0;        UpnpFinish();        return retVal;    }#if EXCLUDE_MINISERVER == 0    if( ( retVal = StartMiniServer( DestPort ) ) <= 0 ) {        UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,            "Miniserver failed to start" );        UpnpFinish();        UpnpSdkInit = 0;        if( retVal != -1 )            return retVal;        else                    // if miniserver is already running for unknown reasons!            return UPNP_E_INIT_FAILED;    }#endif    DestPort = retVal;    LOCAL_PORT = DestPort;#if EXCLUDE_WEB_SERVER == 0    if( ( retVal =          UpnpEnableWebserver( WEB_SERVER_ENABLED ) ) != UPNP_E_SUCCESS ) {        UpnpFinish();        UpnpSdkInit = 0;        return retVal;    }#endif    UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,        "Host Ip: %s Host Port: %d\n", LOCAL_HOST,        LOCAL_PORT );    UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpInit\n" );    return UPNP_E_SUCCESS;} /***************** end of UpnpInit ******************/#ifdef DEBUGstatic void PrintThreadPoolStats(	ThreadPool *tp, 	const char *DbgFileName,	int DbgLineNo,	const char *msg){	ThreadPoolStats stats;	ThreadPoolGetStats(tp, &stats);	UpnpPrintf(UPNP_INFO, API, DbgFileName, DbgLineNo, 		"%s\n"		"High Jobs pending: %d\n"		"Med Jobs Pending: %d\n"		"Low Jobs Pending: %d\n"		"Average wait in High Q in milliseconds: %lf\n"		"Average wait in Med Q in milliseconds: %lf\n"		"Average wait in Low Q in milliseconds: %lf\n"		"Max Threads Used: %d\n"		"Worker Threads: %d\n"		"Persistent Threads: %d\n"		"Idle Threads: %d\n"		"Total Threads: %d\n"		"Total Work Time: %lf\n"		"Total Idle Time: %lf\n",		msg,		stats.currentJobsHQ,		stats.currentJobsMQ,		stats.currentJobsLQ,		stats.avgWaitHQ,		stats.avgWaitMQ,		stats.avgWaitLQ,		stats.maxThreads,		stats.workerThreads,		stats.persistentThreads,		stats.idleThreads,		stats.totalThreads,		stats.totalWorkTime,		stats.totalIdleTime);}#else /* DEBUG */static UPNP_INLINE void PrintThreadPoolStats(	ThreadPool *tp, 	const char *DbgFileName,	int DbgLineNo,	const char *msg){}#endif /* DEBUG *//**************************************************************************** * Function: UpnpFinish * * Parameters:	NONE * * Description: *	Checks for pending jobs and threads  *		Unregisters either the client or device  *		Shuts down the Timer Thread *		Stops the Mini Server *		Uninitializes the Thread Pool *		For Win32 cleans up Winsock Interface  *		Cleans up mutex objects * * Return Values: *	UPNP_E_SUCCESS on success, nonzero on failure. *****************************************************************************/intUpnpFinish(){#ifdef INCLUDE_DEVICE_APIS    UpnpDevice_Handle device_handle;#endif#ifdef INCLUDE_CLIENT_APIS    UpnpClient_Handle client_handle;#endif    struct Handle_Info *temp;#ifdef WIN32//	WSACleanup();#endif    if( UpnpSdkInit != 1 ) {        return UPNP_E_FINISH;    }    UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,        "Inside UpnpFinish : UpnpSdkInit is :%d:\n", UpnpSdkInit );    if( UpnpSdkInit == 1 ) {        UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,            "UpnpFinish : UpnpSdkInit is ONE\n" );    }    PrintThreadPoolStats(&gSendThreadPool, __FILE__, __LINE__, "Send Thread Pool");    PrintThreadPoolStats(&gRecvThreadPool, __FILE__, __LINE__, "Recv Thread Pool");    PrintThreadPoolStats(&gMiniServerThreadPool, __FILE__, __LINE__, "MiniServer Thread Pool");#ifdef INCLUDE_DEVICE_APIS    if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE )        UpnpUnRegisterRootDevice( device_handle );#endif#ifdef INCLUDE_CLIENT_APIS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -