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

📄 upnpapi.c

📁 Upnp开发包文件
💻 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.///////////////////////////////////////////////////////////////////////////////File upnpapi.c#include <assert.h>#include <signal.h>#include <stdlib.h>#include <string.h>#include <sys/stat.h>#include "config.h"#include "upnpapi.h"#include "httpreadwrite.h"#include "ssdplib.h"#include "soaplib.h"#include "ThreadPool.h"#include "membuffer.h"#include <sys/ioctl.h>#include <linux/if.h>#include <sys/utsname.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <unistd.h>#include "httpreadwrite.h"//************************************//Needed for GENA#include "gena.h"#include "service_table.h"#include "miniserver.h"//*******************************************/* ********************* */#ifdef INTERNAL_WEB_SERVER#include "webserver.h"#include "urlconfig.h"#endif // INTERNAL_WEB_SERVER/* ****************** *///Mutex to synchronize the subscription handling at the client sideCLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex;     )    //Mutex to synchronize handles ( root device or control point handle)     ithread_mutex_t GlobalHndMutex;//Mutex to synchronize the uuid creation process     ithread_mutex_t gUUIDMutex;     TimerThread gTimerThread;     ThreadPool gRecvThreadPool;     ThreadPool gSendThreadPool;//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.     int g_maxContentLength = DEFAULT_SOAP_CONTENT_LENGTH;// 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;    if( UpnpSdkInit == 1 ) {        // already initialized        return UPNP_E_INIT;    }    membuffer_init( &gDocumentRootDir );    srand( time( NULL ) );      // needed by SSDP or other parts    DBGONLY( if( InitLog(  ) != UPNP_E_SUCCESS )             return UPNP_E_INIT_FAILED; );    DBGONLY( UpnpPrintf             ( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpInit \n" );         )        //initialize mutex        if( ithread_mutex_init( &GlobalHndMutex, NULL ) != 0 ) {        return UPNP_E_INIT_FAILED;    }    if( ithread_mutex_init( &gUUIDMutex, NULL ) != 0 ) {        return UPNP_E_INIT_FAILED;    }    //initialize subscribe mutex    CLIENTONLY( if                ( ithread_mutex_init( &GlobalClientSubscribeMutex, NULL )                  != 0 ) {                return UPNP_E_INIT_FAILED;}     )        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 );    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;    }    UpnpSdkInit = 1;#if EXCLUDE_SOAP == 0    DEVICEONLY( 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 ) {        DBGONLY( 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    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,                         "Host Ip: %s Host Port: %d\n", LOCAL_HOST,                         LOCAL_PORT ) );    DBGONLY( UpnpPrintf             ( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpInit \n" );         )        return UPNP_E_SUCCESS;} /***************** end of UpnpInit ******************//**************************************************************************** * 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(  ){    DEVICEONLY( UpnpDevice_Handle device_handle;         )        CLIENTONLY( UpnpClient_Handle client_handle;         )    struct Handle_Info *temp;    DBGONLY( ThreadPoolStats stats;         )        if( UpnpSdkInit != 1 )        return UPNP_E_FINISH;    DBGONLY( 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" );}             ThreadPoolGetStats( &gRecvThreadPool, &stats );             UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,                         "Recv Thread Pool \n High Jobs pending = %d"                         " \nMed Jobs Pending = %d\n Low Jobs Pending = %d \nWorker Threads"                         " = %d\nIdle Threads = %d\nPersistent Threads = %d\nAverage Time "                         "spent in High Q = %lf\nAverage Time spent in Med Q = %lf\nAverage"                         " Time spent in Low Q = %lf\nMax Threads Used: %d\nTotal Work Time"                         "= %lf\nTotal Idle Time = %lf\n",                         stats.currentJobsHQ, stats.currentJobsMQ,                         stats.currentJobsLQ, stats.persistentThreads,                         stats.avgWaitHQ, stats.avgWaitMQ, stats.avgWaitLQ,                         stats.maxThreads, stats.totalWorkTime,                         stats.totalIdleTime );             ThreadPoolGetStats( &gSendThreadPool, &stats );             UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,                         "Send Thread Pool \n High Jobs pending = %d"                         " \nMed Jobs Pending = %d\n Low Jobs Pending = %d \nWorker Threads"                         " = %d\nIdle Threads = %d\nPersistent Threads = %d\nAverage Time "                         "spent in High Q = %lf\nAverage Time spent in Med Q = %lf\nAverage"                         " Time spent in Low Q = %lf\nMax Threads Used: %d\nTotal Work Time"                         "= %lf\nTotal Idle Time = %lf\n",                         stats.currentJobsHQ, stats.currentJobsMQ,                         stats.currentJobsLQ, stats.persistentThreads,                         stats.avgWaitHQ, stats.avgWaitMQ, stats.avgWaitLQ,                         stats.maxThreads, stats.totalWorkTime,                         stats.totalIdleTime ); )#ifdef INCLUDE_DEVICE_APIS        if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE )            UpnpUnRegisterRootDevice( device_handle );#endif#ifdef INCLUDE_CLIENT_APIS    if( GetClientHandleInfo( &client_handle, &temp ) == HND_CLIENT )        UpnpUnRegisterClient( client_handle );#endif    TimerThreadShutdown( &gTimerThread );    StopMiniServer(  );#if EXCLUDE_WEB_SERVER == 0    web_server_destroy(  );#endif    ThreadPoolShutdown( &gSendThreadPool );    ThreadPoolShutdown( &gRecvThreadPool );    DBGONLY( UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Exiting UpnpFinish : UpnpSdkInit is :%d:\n", UpnpSdkInit ); ThreadPoolGetStats( &gRecvThreadPool, &stats ); UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Recv Thread Pool \n High Jobs pending = %d" " \nMed Jobs Pending = %d\n Low Jobs Pending = %d \nWorker Threads" " = %d\nIdle Threads = %d\nPersistent Threads = %d\nAverage Time " "spent in High Q = %lf\nAverage Time spent in Med Q = %lf\nAverage" " Time spent in Low Q = %lf\nMax Threads Used: %d\nTotal Work Time" "= %lf\nTotal Idle Time = %lf\n", stats.currentJobsHQ, stats.currentJobsMQ, stats.currentJobsLQ, stats.persistentThreads, stats.avgWaitHQ, stats.avgWaitMQ, stats.avgWaitLQ, stats.maxThreads, stats.totalWorkTime, stats.totalIdleTime ); ThreadPoolGetStats( &gSendThreadPool, &stats ); UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Send Thread Pool \n High Jobs pending = %d" " \nMed Jobs Pending = %d\n Low Jobs Pending = %d \nWorker Threads" " = %d\nIdle Threads = %d\nPersistent Threads = %d\nAverage Time " "spent in High Q = %lf\nAverage Time spent in Med Q = %lf\nAverage" " Time spent in Low Q = %lf\nMax Threads Used: %d\nTotal Work Time" "= %lf\nTotal Idle Time = %lf\n", stats.currentJobsHQ, stats.currentJobsMQ, stats.currentJobsLQ, stats.persistentThreads, stats.avgWaitHQ, stats.avgWaitMQ, stats.avgWaitLQ, stats.maxThreads, stats.totalWorkTime, stats.totalIdleTime ); )   // DBGONLY        DBGONLY( CloseLog(  );         );    CLIENTONLY( ithread_mutex_destroy( &GlobalClientSubscribeMutex );         )        ithread_mutex_destroy( &GlobalHndMutex );    ithread_mutex_destroy( &gUUIDMutex );    // remove all virtual dirs    UpnpRemoveAllVirtualDirs(  );    UpnpSdkInit = 0;    return UPNP_E_SUCCESS;}  /********************* End of  UpnpFinish  *************************//**************************************************************************** * Function: UpnpGetServerPort * *  Parameters:	NONE * *  Description: *      Gives back the miniserver port. * *  Return Values: *      local port on success, zero on failure. *****************************************************************************/unsigned shortUpnpGetServerPort( void ){    if( UpnpSdkInit != 1 )        return 0;    return LOCAL_PORT;}/*************************************************************************** * Function: UpnpGetServerIpAddress * *  Parameters:	NONE

⌨️ 快捷键说明

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