White spaces and code reorganization.

git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@528 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez 2010-03-31 17:47:55 +00:00
parent 3fb182aa95
commit 59ec1fd641
6 changed files with 456 additions and 486 deletions

View File

@ -2,47 +2,6 @@
Version 1.8.0 Version 1.8.0
******************************************************************************* *******************************************************************************
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Added API to ithread, created the following functions:
- int ithread_initialize_library(void);
- int ithread_cleanup_library(void);
- int ithread_initialize_thread(void);
- int ithread_cleanup_thread(void);
* SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008
Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05
Hi,
I am one of the devs of the MorphXT project and I use this lib in some
other of my projects, too. When I tried to upgrade the lib earlier for one
of my projects I had to realise that something did not work at first and
while most of the things were reasonably ease to be fixed. Now, the last
thing I encountered was not so easy to fix and I am uncertain if my fix is
any good so I'll just post it here and wait for some comments.
The problem was that I got an Access Violation when calling "UpnpInit". It
would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually
led to calling "pthread_cond_init" and I got the error notice at
"EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that
"ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly
moving the whole block after at least one of the "ThreadPoolInit" calls
will fix the issue. Secondly, you could add:
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
// to get the following working we need this... is it a good patch or
not... I do not know!
pthread_win32_process_attach_np();
#endif
#endif
right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)".
Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both
are linked static into the binaries. I am currently using Visual Studio
2008 for development with Windows being the target OS. Any comment at your
end?
Regards, Stulle
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Forward port of svn revision 505: * Forward port of svn revision 505:
SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage. SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
@ -234,6 +193,47 @@ Version 1.8.0
Version 1.6.7 Version 1.6.7
******************************************************************************* *******************************************************************************
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Added API to ithread, created the following functions:
- int ithread_initialize_library(void);
- int ithread_cleanup_library(void);
- int ithread_initialize_thread(void);
- int ithread_cleanup_thread(void);
* SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008
Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05
Hi,
I am one of the devs of the MorphXT project and I use this lib in some
other of my projects, too. When I tried to upgrade the lib earlier for one
of my projects I had to realise that something did not work at first and
while most of the things were reasonably ease to be fixed. Now, the last
thing I encountered was not so easy to fix and I am uncertain if my fix is
any good so I'll just post it here and wait for some comments.
The problem was that I got an Access Violation when calling "UpnpInit". It
would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually
led to calling "pthread_cond_init" and I got the error notice at
"EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that
"ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly
moving the whole block after at least one of the "ThreadPoolInit" calls
will fix the issue. Secondly, you could add:
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
// to get the following working we need this... is it a good patch or
not... I do not know!
pthread_win32_process_attach_np();
#endif
#endif
right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)".
Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both
are linked static into the binaries. I am currently using Visual Studio
2008 for development with Windows being the target OS. Any comment at your
end?
Regards, Stulle
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage. * SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
Submitted By: zephyrus ( zephyrus00jp ) Submitted By: zephyrus ( zephyrus00jp )

View File

@ -285,13 +285,13 @@ static UPNP_INLINE void UpnpDisplayBanner(
*/ */
#ifdef DEBUG #ifdef DEBUG
void PrintThreadPoolStats( void PrintThreadPoolStats(
/* [in] The thread pool. */ /*! [in] The thread pool. */
ThreadPool *tp, ThreadPool *tp,
/* [in] The file name that called this function, use the macro __FILE__. */ /*! [in] The file name that called this function, use the macro __FILE__. */
const char *DbgFileName, const char *DbgFileName,
/* [in] The line number that the function was called, use the macro __LINE__. */ /*! [in] The line number that the function was called, use the macro __LINE__. */
int DbgLineNo, int DbgLineNo,
/* [in] The message. */ /*! [in] The message. */
const char *msg); const char *msg);
#else #else
static UPNP_INLINE void PrintThreadPoolStats( static UPNP_INLINE void PrintThreadPoolStats(
@ -304,6 +304,24 @@ static UPNP_INLINE void PrintThreadPoolStats(
#endif #endif
/*!
* \brief Print the node names and values of a XML tree.
*/
#ifdef DEBUG
void printNodes(
/*! [in] The root of the tree to print. */
IXML_Node *tmpRoot,
/*! [in] The depth to print. */
int depth);
#else
static UPNP_INLINE void printNodes(
IXML_Node *tmpRoot,
int depth)
{
}
#endif
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -83,7 +83,7 @@
#include "uuid.h" #include "uuid.h"
// Needed for GENA /* Needed for GENA */
#include "gena.h" #include "gena.h"
#include "miniserver.h" #include "miniserver.h"
#include "service_table.h" #include "service_table.h"
@ -93,7 +93,7 @@
#include "urlconfig.h" #include "urlconfig.h"
#include "VirtualDir.h" #include "VirtualDir.h"
#include "webserver.h" #include "webserver.h"
#endif // INTERNAL_WEB_SERVER #endif /* INTERNAL_WEB_SERVER */
/*! This structure is for virtual directory callbacks */ /*! This structure is for virtual directory callbacks */
@ -181,23 +181,240 @@ Upnp_SID gUpnpSdkNLSuuid;
/*! /*!
* \brief Fills the sockadr_in with miniserver information. * \brief (Windows Only) Initializes the Windows Winsock library.
*
* \return UPNP_E_SUCCESS on success, UPNP_E_INIT_FAILED on failure.
*/ */
static int GetDescDocumentAndURL( static int WinsockInit(void)
/* [in] pointer to server address structure. */ {
Upnp_DescType descriptionType, int retVal = UPNP_E_SUCCESS;
/* [in] . */ #ifdef WIN32
char *description, WORD wVersionRequested;
/* [in] . */ WSADATA wsaData;
unsigned int bufferLen, int err;
/* [in] . */
int config_baseURL, wVersionRequested = MAKEWORD(2, 2);
/* [in] . */ err = WSAStartup(wVersionRequested, &wsaData);
int AddressFamily, if (err != 0) {
/* [out] . */ /* Tell the user that we could not find a usable */
IXML_Document **xmlDoc, /* WinSock DLL. */
/* [out] . */ retVal = UPNP_E_INIT_FAILED;
char *descURL); goto exit_function;
}
/* 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();
retVal = UPNP_E_INIT_FAILED;
goto exit_function;
}
/* The WinSock DLL is acceptable. Proceed. */
exit_function:
#else
#endif
return retVal;
}
/*!
* \brief Initializes the global mutexes used by the UPnP SDK.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
static int UpnpInitMutexes(void)
{
#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
return UPNP_E_SUCCESS;
}
/*!
* \brief Initializes the global threadm pools used by the UPnP SDK.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
static int UpnpInitThreadPools(void)
{
int ret = UPNP_E_SUCCESS;
ThreadPoolAttr attr;
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) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
if (ThreadPoolInit(&gRecvThreadPool, &attr) != UPNP_E_SUCCESS) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
if (ThreadPoolInit(&gMiniServerThreadPool, &attr) != UPNP_E_SUCCESS) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
exit_function:
if (ret != UPNP_E_SUCCESS) {
UpnpSdkInit = 0;
UpnpFinish();
}
return ret;
}
/*!
* \brief Performs the initial steps in initializing the UPnP SDK.
*
* \li Winsock library is initialized for the process (Windows specific).
* \li The logging (for debug messages) is initialized.
* \li Mutexes, Handle table and thread pools are allocated and initialized.
* \li Callback functions for SOAP and GENA are set, if they're enabled.
* \li The SDK timer thread is initialized.
*
* \return UPNP_E_SUCCESS on success.
*/
static int UpnpInitPreamble(void)
{
int retVal = UPNP_E_SUCCESS;
int i;
uuid_upnp nls_uuid;
retVal = WinsockInit();
if (retVal != UPNP_E_SUCCESS) {
return retVal;
}
/* needed by SSDP or other parts. */
srand((unsigned int)time(NULL));
/* Initialize debug output. */
retVal = UpnpInitLog();
if (retVal != UPNP_E_SUCCESS) {
/* UpnpInitLog does not return a valid UPNP_E_*. */
return UPNP_E_INIT_FAILED;
}
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpInitPreamble\n" );
/* Initialize SDK global mutexes. */
retVal = UpnpInitMutexes();
if (retVal != UPNP_E_SUCCESS) {
return retVal;
}
/* Create the NLS uuid. */
uuid_create(&nls_uuid);
uuid_unpack(&nls_uuid, gUpnpSdkNLSuuid);
/* Initializes the handle list. */
HandleLock();
for (i = 0; i < NUM_HANDLE; ++i) {
HandleTable[i] = NULL;
}
HandleUnlock();
/* Initialize SDK global thread pools. */
retVal = UpnpInitThreadPools();
if (retVal != UPNP_E_SUCCESS) {
return retVal;
}
#if EXCLUDE_SOAP == 0
SetSoapCallback(soap_device_callback);
#endif
#if EXCLUDE_GENA == 0
SetGenaCallback(genaCallback);
#endif
/* Initialize the SDK timer thread. */
retVal = TimerThreadInit( &gTimerThread, &gSendThreadPool );
if (retVal != UPNP_E_SUCCESS) {
UpnpFinish();
return retVal;
}
return UPNP_E_SUCCESS;
}
/*!
* \brief Finishes initializing the UPnP SDK.
* \li The MiniServer is started, if enabled.
* \li The WebServer is started, if enabled.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
static int UpnpInitStartServers(
/*! [in] Local Port to listen for incoming connections. */
unsigned short DestPort)
{
int retVal = 0;
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Entering UpnpInitStartServers\n" );
#if EXCLUDE_MINISERVER == 0
LOCAL_PORT_V4 = DestPort;
LOCAL_PORT_V6 = DestPort;
retVal = StartMiniServer(&LOCAL_PORT_V4, &LOCAL_PORT_V6);
if (retVal != UPNP_E_SUCCESS) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Miniserver failed to start");
UpnpFinish();
return retVal;
}
#endif
#if EXCLUDE_WEB_SERVER == 0
membuffer_init(&gDocumentRootDir);
retVal = UpnpEnableWebserver(WEB_SERVER_ENABLED);
if (retVal != UPNP_E_SUCCESS) {
UpnpFinish();
return retVal;
}
#endif
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Exiting UpnpInitStartServers\n");
return UPNP_E_SUCCESS;
}
int UpnpInit(const char *HostIP, unsigned short DestPort) int UpnpInit(const char *HostIP, unsigned short DestPort)
@ -532,7 +749,7 @@ int UpnpRegisterRootDevice(
printServiceTable( &HInfo->ServiceTable, UPNP_ALL, API ); printServiceTable( &HInfo->ServiceTable, UPNP_ALL, API );
} else { } else {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"\nUpnpRegisterRootDevice2: Empty service table\n"); "\nUpnpRegisterRootDevice: Empty service table\n");
} }
UpnpSdkDeviceRegisteredV4 = 1; UpnpSdkDeviceRegisteredV4 = 1;
@ -549,6 +766,26 @@ exit_function:
#endif /* INCLUDE_DEVICE_APIS */ #endif /* INCLUDE_DEVICE_APIS */
/*!
* \brief Fills the sockadr_in with miniserver information.
*/
static int GetDescDocumentAndURL(
/* [in] pointer to server address structure. */
Upnp_DescType descriptionType,
/* [in] . */
char *description,
/* [in] . */
unsigned int bufferLen,
/* [in] . */
int config_baseURL,
/* [in] . */
int AddressFamily,
/* [out] . */
IXML_Document **xmlDoc,
/* [out] . */
char *descURL);
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
int UpnpRegisterRootDevice2( int UpnpRegisterRootDevice2(
Upnp_DescType descriptionType, Upnp_DescType descriptionType,
@ -694,7 +931,7 @@ int UpnpRegisterRootDevice3(
HandleLock(); HandleLock();
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRegisterRootDevice\n"); "Inside UpnpRegisterRootDevice3\n");
if (UpnpSdkInit != 1) { if (UpnpSdkInit != 1) {
retVal = UPNP_E_FINISH; retVal = UPNP_E_FINISH;
@ -753,8 +990,8 @@ int UpnpRegisterRootDevice3(
goto exit_function; goto exit_function;
} }
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice: Valid Description\n" "UpnpRegisterRootDevice3: Valid Description\n"
"UpnpRegisterRootDevice: DescURL : %s\n", "UpnpRegisterRootDevice3: DescURL : %s\n",
HInfo->DescURL); HInfo->DescURL);
HInfo->DeviceList = ixmlDocument_getElementsByTagName( HInfo->DeviceList = ixmlDocument_getElementsByTagName(
@ -764,7 +1001,7 @@ int UpnpRegisterRootDevice3(
ixmlDocument_free(HInfo->DescDocument); ixmlDocument_free(HInfo->DescDocument);
FreeHandle(*Hnd); FreeHandle(*Hnd);
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice: No devices found for RootDevice\n"); "UpnpRegisterRootDevice3: No devices found for RootDevice\n");
retVal = UPNP_E_INVALID_DESC; retVal = UPNP_E_INVALID_DESC;
goto exit_function; goto exit_function;
} }
@ -773,7 +1010,7 @@ int UpnpRegisterRootDevice3(
HInfo->DescDocument, "serviceList" ); HInfo->DescDocument, "serviceList" );
if (!HInfo->ServiceList) { if (!HInfo->ServiceList) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice: No services found for RootDevice\n"); "UpnpRegisterRootDevice3: No services found for RootDevice\n");
} }
/* /*
@ -787,7 +1024,7 @@ int UpnpRegisterRootDevice3(
HInfo->DescURL); HInfo->DescURL);
if (hasServiceTable) { if (hasServiceTable) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice: GENA Service Table \n" "UpnpRegisterRootDevice3: GENA Service Table \n"
"Here are the known services: \n" ); "Here are the known services: \n" );
printServiceTable(&HInfo->ServiceTable, UPNP_ALL, API); printServiceTable(&HInfo->ServiceTable, UPNP_ALL, API);
} else { } else {
@ -839,8 +1076,7 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
#if EXCLUDE_SSDP == 0 #if EXCLUDE_SSDP == 0
retVal = AdvertiseAndReply(-1, Hnd, 0, (struct sockaddr *)NULL, retVal = AdvertiseAndReply(-1, Hnd, 0, (struct sockaddr *)NULL,
(char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, (char *)NULL, HInfo->MaxAge);
(char *)NULL, HInfo->MaxAge);
#endif #endif
HandleLock(); HandleLock();
@ -874,7 +1110,6 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
"Exiting UpnpUnRegisterRootDevice\n" ); "Exiting UpnpUnRegisterRootDevice\n" );
return retVal; return retVal;
} }
#endif /* INCLUDE_DEVICE_APIS */ #endif /* INCLUDE_DEVICE_APIS */
@ -1210,11 +1445,11 @@ static int GetDescDocumentAndURL(
#endif /* INCLUDE_DEVICE_APIS */ #endif /* INCLUDE_DEVICE_APIS */
//----------------------------------------------------------------------------- /*******************************************************************************
// *
// SSDP interface * SSDP interface
// *
//----------------------------------------------------------------------------- ******************************************************************************/
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
@ -1357,18 +1592,16 @@ int UpnpSearchAsync(
#endif #endif
//----------------------------------------------------------------------------- /*******************************************************************************
// *
// GENA interface * GENA interface
// *
//----------------------------------------------------------------------------- ******************************************************************************/
#if EXCLUDE_GENA == 0 #if EXCLUDE_GENA == 0
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
int UpnpSetMaxSubscriptions( int UpnpSetMaxSubscriptions(UpnpDevice_Handle Hnd, int MaxSubscriptions)
UpnpDevice_Handle Hnd,
int MaxSubscriptions )
{ {
struct Handle_Info *SInfo = NULL; struct Handle_Info *SInfo = NULL;
@ -1399,9 +1632,7 @@ int UpnpSetMaxSubscriptions(
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
int UpnpSetMaxSubscriptionTimeOut( int UpnpSetMaxSubscriptionTimeOut(UpnpDevice_Handle Hnd, int MaxSubscriptionTimeOut)
UpnpDevice_Handle Hnd,
int MaxSubscriptionTimeOut)
{ {
struct Handle_Info *SInfo = NULL; struct Handle_Info *SInfo = NULL;
@ -1836,7 +2067,6 @@ int UpnpNotify(
"Exiting UpnpNotify\n"); "Exiting UpnpNotify\n");
return retVal; return retVal;
} }
@ -1879,7 +2109,6 @@ int UpnpNotifyExt(
"Exiting UpnpNotify \n" ); "Exiting UpnpNotify \n" );
return retVal; return retVal;
} }
#endif /* INCLUDE_DEVICE_APIS */ #endif /* INCLUDE_DEVICE_APIS */
@ -2034,11 +2263,11 @@ exit_function:
#endif /* EXCLUDE_GENA == 0 */ #endif /* EXCLUDE_GENA == 0 */
//--------------------------------------------------------------------------- /*******************************************************************************
// *
// SOAP interface * SOAP interface
// *
//--------------------------------------------------------------------------- ******************************************************************************/
#if EXCLUDE_SOAP == 0 #if EXCLUDE_SOAP == 0
@ -2055,8 +2284,8 @@ int UpnpSendAction(
int retVal = 0; int retVal = 0;
char *ActionURL = (char *)ActionURL_const; char *ActionURL = (char *)ActionURL_const;
char *ServiceType = (char *)ServiceType_const; char *ServiceType = (char *)ServiceType_const;
/* udn not used? */
//char *DevUDN = (char *)DevUDN_const; // udn not used? /*char *DevUDN = (char *)DevUDN_const;*/
if( UpnpSdkInit != 1 ) { if( UpnpSdkInit != 1 ) {
return UPNP_E_FINISH; return UPNP_E_FINISH;
@ -2093,7 +2322,6 @@ int UpnpSendAction(
"Exiting UpnpSendAction\n"); "Exiting UpnpSendAction\n");
return retVal; return retVal;
} }
@ -2110,8 +2338,8 @@ int UpnpSendActionEx(
int retVal = 0; int retVal = 0;
char *ActionURL = (char *)ActionURL_const; char *ActionURL = (char *)ActionURL_const;
char *ServiceType = (char *)ServiceType_const; char *ServiceType = (char *)ServiceType_const;
/* udn not used? */
//char *DevUDN = (char *)DevUDN_const; // udn not used? /*char *DevUDN = (char *)DevUDN_const;*/
if( UpnpSdkInit != 1 ) { if( UpnpSdkInit != 1 ) {
return UPNP_E_FINISH; return UPNP_E_FINISH;
@ -2147,7 +2375,6 @@ int UpnpSendActionEx(
"Exiting UpnpSendAction \n"); "Exiting UpnpSendAction \n");
return retVal; return retVal;
} }
@ -2160,15 +2387,15 @@ int UpnpSendActionAsync(
Upnp_FunPtr Fun, Upnp_FunPtr Fun,
const void *Cookie_const) const void *Cookie_const)
{ {
int rc;
ThreadPoolJob job; ThreadPoolJob job;
struct Handle_Info *SInfo = NULL; struct Handle_Info *SInfo = NULL;
struct UpnpNonblockParam *Param; struct UpnpNonblockParam *Param;
DOMString tmpStr; DOMString tmpStr;
char *ActionURL = (char *)ActionURL_const; char *ActionURL = (char *)ActionURL_const;
char *ServiceType = (char *)ServiceType_const; char *ServiceType = (char *)ServiceType_const;
/* udn not used? */
//char *DevUDN = (char *)DevUDN_const; /*char *DevUDN = (char *)DevUDN_const;*/
int rc;
if(UpnpSdkInit != 1) { if(UpnpSdkInit != 1) {
return UPNP_E_FINISH; return UPNP_E_FINISH;
@ -2233,7 +2460,6 @@ int UpnpSendActionAsync(
"Exiting UpnpSendActionAsync \n"); "Exiting UpnpSendActionAsync \n");
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
@ -2342,7 +2568,6 @@ int UpnpSendActionExAsync(
"Exiting UpnpSendActionAsync\n"); "Exiting UpnpSendActionAsync\n");
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
@ -2453,11 +2678,11 @@ int UpnpGetServiceVarStatus(
#endif /* EXCLUDE_SOAP */ #endif /* EXCLUDE_SOAP */
/****************************************************************************** /*******************************************************************************
* *
* Client API's * Client API
* *
*****************************************************************************/ ******************************************************************************/
int UpnpOpenHttpPost( int UpnpOpenHttpPost(
@ -2571,7 +2796,7 @@ int UpnpDownloadUrlItem(const char *url, char **outBuf, char *contentType)
ret_code = http_Download( url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy, ret_code = http_Download( url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy,
contentType ); contentType );
if( ret_code > 0 ) { if( ret_code > 0 ) {
// error reply was received /* error reply was received */
ret_code = UPNP_E_INVALID_URL; ret_code = UPNP_E_INVALID_URL;
} }
@ -2598,11 +2823,11 @@ int UpnpDownloadXmlDoc(const char *url, IXML_Document **xmlDoc)
if (strncasecmp(content_type, "text/xml", strlen("text/xml"))) { if (strncasecmp(content_type, "text/xml", strlen("text/xml"))) {
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Not text/xml\n"); UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Not text/xml\n");
// Linksys WRT54G router returns /* Linksys WRT54G router returns
// "CONTENT-TYPE: application/octet-stream". * "CONTENT-TYPE: application/octet-stream".
// Let's be nice to Linksys and try to parse document anyway. * Let's be nice to Linksys and try to parse document anyway.
// If the data sended is not a xml file, ixmlParseBufferEx * If the data sended is not a xml file, ixmlParseBufferEx
// will fail and the function will return UPNP_E_INVALID_DESC too. * will fail and the function will return UPNP_E_INVALID_DESC too. */
#if 0 #if 0
free(xml_buf); free(xml_buf);
return UPNP_E_INVALID_DESC; return UPNP_E_INVALID_DESC;
@ -2640,208 +2865,6 @@ int UpnpDownloadXmlDoc(const char *url, IXML_Document **xmlDoc)
} }
/*----------------------------------------------------------------------------
*
* UPNP-API Internal function implementation
*
*----------------------------------------------------------------------------
*/
#ifdef WIN32
int WinsockInit()
{
WORD wVersionRequested;
WSADATA wsaData;
int err;
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;
}
return UPNP_E_SUCCESS;
}
#endif
int UpnpInitPreamble()
{
uuid_upnp nls_uuid;
int retVal = 0;
#ifdef WIN32
retVal = WinsockInit();
if( retVal != UPNP_E_SUCCESS ){
return retVal;
}
/* The WinSock DLL is acceptable. Proceed. */
#endif
srand( (unsigned int)time( NULL ) ); // needed by SSDP or other parts
// Initialize debug output.
retVal = UpnpInitLog();
if( retVal != UPNP_E_SUCCESS ) {
// UpnpInitLog does not return a valid UPNP_E_*
return UPNP_E_INIT_FAILED;
}
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Inside UpnpInitPreamble\n" );
// Initialize SDK global mutexes.
retVal = UpnpInitMutexes();
if( retVal != UPNP_E_SUCCESS ) {
return retVal;
}
// Create the NLS uuid.
uuid_create(&nls_uuid);
uuid_unpack(&nls_uuid, gUpnpSdkNLSuuid);
// Init the handle list.
HandleLock();
InitHandleList();
HandleUnlock();
// Initialize SDK global thread pools.
retVal = UpnpInitThreadPools();
if( retVal != UPNP_E_SUCCESS ) {
return retVal;
}
#if EXCLUDE_SOAP == 0
SetSoapCallback( soap_device_callback );
#endif
#if EXCLUDE_GENA == 0
SetGenaCallback( genaCallback );
#endif
// Initialize the SDK timer thread.
retVal = TimerThreadInit( &gTimerThread, &gSendThreadPool );
if( retVal != UPNP_E_SUCCESS ) {
UpnpFinish();
return retVal;
}
return UPNP_E_SUCCESS;
}
int UpnpInitMutexes()
{
#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
return UPNP_E_SUCCESS;
}
int UpnpInitThreadPools()
{
int ret = UPNP_E_SUCCESS;
ThreadPoolAttr attr;
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) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
if (ThreadPoolInit(&gRecvThreadPool, &attr) != UPNP_E_SUCCESS) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
if (ThreadPoolInit(&gMiniServerThreadPool, &attr) != UPNP_E_SUCCESS) {
ret = UPNP_E_INIT_FAILED;
goto exit_function;
}
exit_function:
if (ret != UPNP_E_SUCCESS) {
UpnpSdkInit = 0;
UpnpFinish();
}
return ret;
}
int UpnpInitStartServers(unsigned short DestPort)
{
int retVal = 0;
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Entering UpnpInitStartServers\n" );
#if EXCLUDE_MINISERVER == 0
LOCAL_PORT_V4 = DestPort;
LOCAL_PORT_V6 = DestPort;
retVal = StartMiniServer(&LOCAL_PORT_V4, &LOCAL_PORT_V6);
if (retVal != UPNP_E_SUCCESS) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Miniserver failed to start");
UpnpFinish();
return retVal;
}
#endif
#if EXCLUDE_WEB_SERVER == 0
membuffer_init(&gDocumentRootDir);
retVal = UpnpEnableWebserver(WEB_SERVER_ENABLED);
if (retVal != UPNP_E_SUCCESS) {
UpnpFinish();
return retVal;
}
#endif
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Exiting UpnpInitStartServers\n");
return UPNP_E_SUCCESS;
}
int UpnpGetIfInfo(const char *IfName) int UpnpGetIfInfo(const char *IfName)
{ {
#ifdef WIN32 #ifdef WIN32
@ -3187,11 +3210,12 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
UpnpEventSubscribe *evt = UpnpEventSubscribe_new(); UpnpEventSubscribe *evt = UpnpEventSubscribe_new();
// cast away constness // cast away constness
UpnpString *sid = (UpnpString *)UpnpEventSubscribe_get_SID(evt); UpnpString *sid = (UpnpString *)UpnpEventSubscribe_get_SID(evt);
UpnpEventSubscribe_strcpy_PublisherUrl(evt, Param->Url); UpnpEventSubscribe_strcpy_PublisherUrl(evt, Param->Url);
errCode = genaSubscribe( errCode = genaSubscribe(
Param->Handle, Param->Handle,
UpnpEventSubscribe_get_PublisherUrl(evt), UpnpEventSubscribe_get_PublisherUrl(evt),
(int *)&(Param->TimeOut), (int *)&Param->TimeOut,
sid); sid);
UpnpEventSubscribe_set_ErrCode(evt, errCode); UpnpEventSubscribe_set_ErrCode(evt, errCode);
UpnpEventSubscribe_set_TimeOut(evt, Param->TimeOut); UpnpEventSubscribe_set_TimeOut(evt, Param->TimeOut);
@ -3220,7 +3244,7 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
errCode = genaRenewSubscription( errCode = genaRenewSubscription(
Param->Handle, Param->Handle,
UpnpEventSubscribe_get_SID(evt), UpnpEventSubscribe_get_SID(evt),
&(Param->TimeOut)); &Param->TimeOut);
UpnpEventSubscribe_set_ErrCode(evt, errCode); UpnpEventSubscribe_set_ErrCode(evt, errCode);
UpnpEventSubscribe_set_TimeOut(evt, Param->TimeOut); UpnpEventSubscribe_set_TimeOut(evt, Param->TimeOut);
Param->Fun(UPNP_EVENT_RENEWAL_COMPLETE, evt, Param->Cookie); Param->Fun(UPNP_EVENT_RENEWAL_COMPLETE, evt, Param->Cookie);
@ -3228,13 +3252,16 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
free(Param); free(Param);
break; break;
} }
#endif // EXCLUDE_GENA == 0 #endif /* EXCLUDE_GENA == 0 */
#if EXCLUDE_SOAP == 0 #if EXCLUDE_SOAP == 0
case ACTION: { case ACTION: {
UpnpActionComplete *Evt = UpnpActionComplete_new(); UpnpActionComplete *Evt = UpnpActionComplete_new();
IXML_Document *actionResult = NULL; IXML_Document *actionResult = NULL;
int errCode = SoapSendAction( int errCode = SoapSendAction(
Param->Url, Param->ServiceType, Param->Act, &actionResult ); Param->Url,
Param->ServiceType,
Param->Act,
&actionResult);
UpnpActionComplete_set_ErrCode(Evt, errCode); UpnpActionComplete_set_ErrCode(Evt, errCode);
UpnpActionComplete_set_ActionRequest(Evt, Param->Act); UpnpActionComplete_set_ActionRequest(Evt, Param->Act);
UpnpActionComplete_set_ActionResult(Evt, actionResult); UpnpActionComplete_set_ActionResult(Evt, actionResult);
@ -3248,7 +3275,9 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
UpnpStateVarComplete *Evt = UpnpStateVarComplete_new(); UpnpStateVarComplete *Evt = UpnpStateVarComplete_new();
DOMString currentVal = NULL; DOMString currentVal = NULL;
int errCode = SoapGetServiceVarStatus( int errCode = SoapGetServiceVarStatus(
Param->Url, Param->VarName, &currentVal ); Param->Url,
Param->VarName,
&currentVal);
UpnpStateVarComplete_set_ErrCode(Evt, errCode); UpnpStateVarComplete_set_ErrCode(Evt, errCode);
UpnpStateVarComplete_strcpy_CtrlUrl(Evt, Param->Url); UpnpStateVarComplete_strcpy_CtrlUrl(Evt, Param->Url);
UpnpStateVarComplete_strcpy_StateVarName(Evt, Param->VarName); UpnpStateVarComplete_strcpy_StateVarName(Evt, Param->VarName);
@ -3261,11 +3290,10 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
#endif /* EXCLUDE_SOAP == 0 */ #endif /* EXCLUDE_SOAP == 0 */
default: default:
break; break;
} /* end of switch(Param->FunName) */ }
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Exiting UpnpThreadDistribution\n"); "Exiting UpnpThreadDistribution\n");
} }
#endif /* INCLUDE_CLIENT_APIS */ #endif /* INCLUDE_CLIENT_APIS */
@ -3281,16 +3309,6 @@ Upnp_FunPtr GetCallBackFn(UpnpClient_Handle Hnd)
} }
void InitHandleList()
{
int i;
for (i = 0; i < NUM_HANDLE; ++i) {
HandleTable[i] = NULL;
}
}
int GetFreeHandle() int GetFreeHandle()
{ {
/* Handle 0 is not used as NULL translates to 0 when passed as a handle */ /* Handle 0 is not used as NULL translates to 0 when passed as a handle */
@ -3433,36 +3451,6 @@ int PrintHandleInfo(UpnpClient_Handle Hnd)
} }
/*!
* \brief Print the node names and values of a XML tree.
*/
static void printNodes(IXML_Node *tmpRoot, int depth)
{
int i;
IXML_NodeList *NodeList1;
IXML_Node *ChildNode1;
unsigned short NodeType;
const DOMString NodeValue;
const DOMString NodeName;
NodeList1 = ixmlNode_getChildNodes(tmpRoot);
for (i = 0; i < 100; ++i) {
ChildNode1 = ixmlNodeList_item(NodeList1, i);
if (ChildNode1 == NULL) {
break;
}
printNodes(ChildNode1, depth+1);
NodeType = ixmlNode_getNodeType(ChildNode1);
NodeValue = ixmlNode_getNodeValue(ChildNode1);
NodeName = ixmlNode_getNodeName(ChildNode1);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"DEPTH-%2d-IXML_Node Type %d, "
"IXML_Node Name: %s, IXML_Node Value: %s\n",
depth, NodeType, NodeName, NodeValue);
}
}
int getlocalhostname(char *out, const int out_len) int getlocalhostname(char *out, const int out_len)
{ {
int ret = UPNP_E_SUCCESS; int ret = UPNP_E_SUCCESS;
@ -3703,7 +3691,6 @@ int UpnpAddVirtualDir(const char *newDirName)
int UpnpRemoveVirtualDir(const char *dirName) int UpnpRemoveVirtualDir(const char *dirName)
{ {
virtualDirList *pPrev; virtualDirList *pPrev;
virtualDirList *pCur; virtualDirList *pCur;
int found = 0; int found = 0;
@ -3750,7 +3737,6 @@ int UpnpRemoveVirtualDir(const char *dirName)
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
else else
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
} }
@ -3773,7 +3759,6 @@ void UpnpRemoveAllVirtualDirs(void)
} }
pVirtualDirList = NULL; pVirtualDirList = NULL;
} }

View File

@ -33,6 +33,7 @@
#include "ithread.h" #include "ithread.h"
#include "ixml.h"
#include "upnp.h" #include "upnp.h"
#include "upnpdebug.h" #include "upnpdebug.h"
@ -64,6 +65,8 @@ static const char *infoFileName = "IUpnpInfoFile.txt";
#ifdef DEBUG #ifdef DEBUG
int UpnpInitLog(void) int UpnpInitLog(void)
{ {
ithread_mutex_init(&GlobalDebugMutex, NULL); ithread_mutex_init(&GlobalDebugMutex, NULL);
@ -108,10 +111,8 @@ void UpnpSetLogFileNames(
infoFileName = InfoFileName; infoFileName = InfoFileName;
} }
} }
#endif /* DEBUG */
#ifdef DEBUG
int DebugAtThisLevel( int DebugAtThisLevel(
Upnp_LogLevel DLevel, Upnp_LogLevel DLevel,
Dbg_Module Module) Dbg_Module Module)
@ -129,10 +130,8 @@ int DebugAtThisLevel(
return ret; return ret;
} }
#endif
#ifdef DEBUG
void UpnpPrintf( void UpnpPrintf(
Upnp_LogLevel DLevel, Upnp_LogLevel DLevel,
Dbg_Module Module, Dbg_Module Module,
@ -171,10 +170,8 @@ void UpnpPrintf(
va_end(ArgList); va_end(ArgList);
ithread_mutex_unlock(&GlobalDebugMutex); ithread_mutex_unlock(&GlobalDebugMutex);
} }
#endif
#ifdef DEBUG
FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module) FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module)
{ {
FILE *ret; FILE *ret;
@ -193,10 +190,8 @@ FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module)
return ret; return ret;
} }
#endif
#ifdef DEBUG
void UpnpDisplayFileAndLine( void UpnpDisplayFileAndLine(
FILE *fd, FILE *fd,
const char *DbgFileName, const char *DbgFileName,
@ -233,10 +228,8 @@ void UpnpDisplayFileAndLine(
UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS); UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS);
fflush(fd); fflush(fd);
} }
#endif
#ifdef DEBUG
void UpnpDisplayBanner( void UpnpDisplayBanner(
FILE * fd, FILE * fd,
const char **lines, const char **lines,
@ -289,10 +282,8 @@ void UpnpDisplayBanner(
free(rightMargin); free(rightMargin);
free(leftMargin); free(leftMargin);
} }
#endif
#ifdef DEBUG
void PrintThreadPoolStats( void PrintThreadPoolStats(
ThreadPool *tp, ThreadPool *tp,
const char *DbgFileName, const char *DbgFileName,
@ -331,5 +322,34 @@ void PrintThreadPoolStats(
stats.totalWorkTime, stats.totalWorkTime,
stats.totalIdleTime); stats.totalIdleTime);
} }
#endif
void printNodes(IXML_Node *tmpRoot, int depth)
{
int i;
IXML_NodeList *NodeList1;
IXML_Node *ChildNode1;
unsigned short NodeType;
const DOMString NodeValue;
const DOMString NodeName;
NodeList1 = ixmlNode_getChildNodes(tmpRoot);
for (i = 0; i < 100; ++i) {
ChildNode1 = ixmlNodeList_item(NodeList1, i);
if (ChildNode1 == NULL) {
break;
}
printNodes(ChildNode1, depth+1);
NodeType = ixmlNode_getNodeType(ChildNode1);
NodeValue = ixmlNode_getNodeValue(ChildNode1);
NodeName = ixmlNode_getNodeName(ChildNode1);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"DEPTH-%2d-IXML_Node Type %d, "
"IXML_Node Name: %s, IXML_Node Value: %s\n",
depth, NodeType, NodeName, NodeValue);
}
}
#endif /* DEBUG */

View File

@ -69,7 +69,8 @@ typedef enum SsdpSearchType{
/* Enumeration to define all different type of ssdp messages */ /* Enumeration to define all different type of ssdp messages */
typedef enum SsdpCmdType{SSDP_ERROR=-1, typedef enum SsdpCmdType{
SSDP_ERROR=-1,
SSDP_OK, SSDP_OK,
SSDP_ALIVE, SSDP_ALIVE,
SSDP_BYEBYE, SSDP_BYEBYE,

View File

@ -245,60 +245,6 @@ typedef enum {
#define E_HTTP_SYNTAX -6 #define E_HTTP_SYNTAX -6
/*!
* \brief (Windows Only) Initializes the Windows Winsock library.
*
* \return UPNP_E_SUCCESS on success, UPNP_E_INIT_FAILED on failure.
*/
#ifdef WIN32
int WinsockInit();
#endif
/*!
* \brief Performs the initial steps in initializing the UPnP SDK.
*
* \li Winsock library is initialized for the process (Windows specific).
* \li The logging (for debug messages) is initialized.
* \li Mutexes, Handle table and thread pools are allocated and initialized.
* \li Callback functions for SOAP and GENA are set, if they're enabled.
* \li The SDK timer thread is initialized.
*
* \return UPNP_E_SUCCESS on success.
*/
int UpnpInitPreamble();
/*!
* \brief Initializes the global mutexes used by the UPnP SDK.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
int UpnpInitMutexes();
/*!
* \brief Initializes the global threadm pools used by the UPnP SDK.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
int UpnpInitThreadPools();
/*!
* \brief Finishes initializing the UPnP SDK.
* \li The MiniServer is started, if enabled.
* \li The WebServer is started, if enabled.
*
* \return UPNP_E_SUCCESS on success or UPNP_E_INIT_FAILED if a mutex could not
* be initialized.
*/
int UpnpInitStartServers(
/*! [in] Local Port to listen for incoming connections. */
unsigned short DestPort);
/*! /*!
* \brief Retrieve interface information and keep it in global variables. * \brief Retrieve interface information and keep it in global variables.
* If NULL, we'll find the first suitable interface for operation. * If NULL, we'll find the first suitable interface for operation.