Compare commits

..

26 Commits

Author SHA1 Message Date
Marcelo Roberto Jimenez
46cc47b167 Created tag for the new release.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/tags/release-1.6.1@238 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-08 02:22:05 +00:00
Marcelo Roberto Jimenez
13a1fff7a1 SF Bug Tracker [ 1825278 ] AdvertiseAndReply sleeps with handle lock out
Applied patch from Alex (afaucher) to change some write locks to read
locks.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@237 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-08 01:54:50 +00:00
Marcelo Roberto Jimenez
c9463545a8 Small fix for changelog.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@235 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-06 02:43:44 +00:00
Marcelo Roberto Jimenez
de1d7e81a3 Adjusting libtool library numbers to reflect the last changes.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@234 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-06 02:41:34 +00:00
Marcelo Roberto Jimenez
f87dbf8115 GlobalHndMutex, which was a mutex is now GlobalHndRWLock, which is a
rwlock. HandleLock() is mapped to HandleWriteLock() while all other
instances have not been checked. One instance in AdvertiseAndReply()
has been changed to HandleReadLock(). Thanks to Alex (afaucher) for the 
bug report and suggestions.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@233 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-06 02:29:03 +00:00
Marcelo Roberto Jimenez
83ee32afb7 Added support for rwlocks.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@232 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-06 02:04:38 +00:00
Marcelo Roberto Jimenez
4f960c4e34 Small printf changes. Also reworked PrintThreadPoolStats() so that we can
remove a few #ifdef DEBUG from the main code.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@231 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 13:39:58 +00:00
Marcelo Roberto Jimenez
c85537df11 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@230 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 13:12:35 +00:00
Marcelo Roberto Jimenez
20905cb7a7 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@229 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 13:09:33 +00:00
Marcelo Roberto Jimenez
5b744169d5 SF Bug Tracker [ 1825929 ] woker thread still alive after UpnpFinish()
Submitted By: Luke Kim - nereusuj
	Worker thread still alive after calling UpnpFinish() because
	ThreadPoolShutdown() is in the #ifdef DEBUG block.
	421
	422 #ifdef DEBUG
	423 ThreadPoolShutdown( &gSendThreadPool );
	424 ThreadPoolShutdown( &gRecvThreadPool );



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@228 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 13:07:54 +00:00
Marcelo Roberto Jimenez
c69e16b347 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@227 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 12:25:18 +00:00
Marcelo Roberto Jimenez
cb7e6b7472 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@226 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-05 12:06:52 +00:00
Marcelo Roberto Jimenez
fd80e5a8ff Slightly better debug messages and lots of white spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@225 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-10-26 13:21:59 +00:00
Marcelo Roberto Jimenez
b29de32110 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@224 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-09-01 17:05:07 +00:00
Marcelo Roberto Jimenez
6455ac6eea Changed the calls to virtualDirCallback.open(filename, UPNP_WRITE)
to (virtualDirCallback.open)(filename, UPNP_WRITE) (notice the
parenthesis) due to a change in glibc that produces compilation
errors.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@223 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-09-01 16:58:58 +00:00
Marcelo Roberto Jimenez
f7bb1f9582 Fixed the path in the documentation for upnpdebug.h.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@222 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-31 13:12:40 +00:00
Marcelo Roberto Jimenez
0728ab3b25 Initialization of the "randomness" struct so that valgrind does not complain.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@221 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-28 14:37:41 +00:00
Marcelo Roberto Jimenez
cb9ee8254c White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@220 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-28 14:08:53 +00:00
Marcelo Roberto Jimenez
f08fdac9b6 ReqBuf was not initialized, so it should not be used.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@219 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-25 02:28:44 +00:00
Marcelo Roberto Jimenez
0db035cc7b Two unnecessary lines.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@218 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-25 01:22:27 +00:00
Marcelo Roberto Jimenez
da11e52924 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@217 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-25 01:20:21 +00:00
Marcelo Roberto Jimenez
bc7b0c9d4d Libtool stuff update.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@216 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-06 05:18:25 +00:00
Marcelo Roberto Jimenez
b2757d9d55 Changelog fix.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@215 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-06 05:12:17 +00:00
Marcelo Roberto Jimenez
7967a0cd45 Merge of patch submitted By Keith Brindley - brindlk
SF Bug Tracker [ 1762758 ] Seek not working for large files.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@214 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-06 05:11:07 +00:00
Marcelo Roberto Jimenez
67b51187b9 Merge of Mac OS X patch from Stéphane Corthésy (davelopper),
SF Bug Tracker [ 1686420 ] Modifications for MacOSX.
Some of the proposed changes were already done by Rene Hexel's patch.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@213 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-08-06 02:07:41 +00:00
Marcelo Roberto Jimenez
491f5ffef6 Bumping library version.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/trunk@212 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-06-23 14:38:32 +00:00
27 changed files with 1168 additions and 927 deletions

View File

@@ -1,3 +1,67 @@
*******************************************************************************
Version 1.6.1
*******************************************************************************
2007-11-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1825278 ] AdvertiseAndReply sleeps with handle lock out
Applied patch from Alex (afaucher) to change some write locks to read
locks.
2007-11-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Adjusting libtool library numbers to reflect the last changes.
2007-11-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1825278 ] AdvertiseAndReply sleeps with handle lock out
GlobalHndMutex, which was a mutex is now GlobalHndRWLock, which is a
rwlock. HandleLock() is mapped to HandleWriteLock() while all other
instances have not been checked. One instance in AdvertiseAndReply()
has been changed to HandleReadLock(). Thanks to Alex (afaucher) for the
bug report and suggestions.
2007-11-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Added support for rwlocks.
2007-11-05 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1825929 ] woker thread still alive after UpnpFinish()
Submitted By: Luke Kim - nereusuj
Worker thread still alive after calling UpnpFinish() because
ThreadPoolShutdown() is in the #ifdef DEBUG block.
421
422 #ifdef DEBUG
423 ThreadPoolShutdown( &gSendThreadPool );
424 ThreadPoolShutdown( &gRecvThreadPool );
2007-08-28 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Changed the calls to virtualDirCallback.open(filename, UPNP_WRITE)
to (virtualDirCallback.open)(filename, UPNP_WRITE) (notice the
parenthesis) due to a change in glibc that produces compilation
errors.
2007-08-28 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Initialization of the "randomness" struct so that valgrind does not
complain.
2007-08-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Merge of patch submitted By Keith Brindley - brindlk
SF Bug Tracker [ 1762758 ] Seek not working for large files
Problem:
Requests from the uPnP client to seek to a position beyond 2GB in a large
file are handled as a request to see from the 2GB point.
Impact:
Varies depending on client. The Xbox 360 kills the connection when it
realises.
Solution:
GetNextRange function (webserver.c) is updated to handle large file sizes.
Fix should also recognise when built on a 32bit platform rather than 64 and
handle accordingly.
2007-08-05 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Merge of Mac OS X patch from St<53>phane Corth<74>sy (davelopper),
SF Bug Tracker [ 1686420 ] Modifications for MacOSX.
Some of the proposed changes were already done by Rene Hexel's patch.
******************************************************************************* *******************************************************************************
Version 1.6.0 Version 1.6.0
******************************************************************************* *******************************************************************************

5
THANKS
View File

@@ -6,6 +6,7 @@ suggesting various improvements or submitting actual code.
Here is a list of these people. Help us keep it complete and Here is a list of these people. Help us keep it complete and
exempt of errors. exempt of errors.
- Alex (afaucher)
- Arno Willig - Arno Willig
- Bob Ciora - Bob Ciora
- Chaos - Chaos
@@ -20,10 +21,11 @@ exempt of errors.
- Jiri Zouhar - Jiri Zouhar
- John Dennis - John Dennis
- Jonathan (no_dice) - Jonathan (no_dice)
- Keith Brindley
- Leuk_He - Leuk_He
- Loigu - Loigu
- Luke Kim - Luke Kim
- Marcelo Roberto Jimenez - Marcelo Roberto Jimenez (mroberto)
- Markus Strobl - Markus Strobl
- Nektarios K. Papadopoulos - Nektarios K. Papadopoulos
- Oskar Liljeblad - Oskar Liljeblad
@@ -31,6 +33,7 @@ exempt of errors.
- Paul Vixie - Paul Vixie
- Rene Hexel - Rene Hexel
- Siva Chandran - Siva Chandran
- Stéphane Corthésy
- Timothy Redaelli - Timothy Redaelli
- Titus Winters - Titus Winters

View File

@@ -261,18 +261,18 @@
/** @name Other debugging features /** @name Other debugging features
The UPnP SDK contains other features to aid in debugging: The UPnP SDK contains other features to aid in debugging:
see <upnp/upnpdebug.h> see <upnp/inc/upnpdebug.h>
*/ */
#define DEBUG_ALL 1 #define DEBUG_ALL 1
#define DEBUG_SSDP 0 #define DEBUG_SSDP 0
#define DEBUG_SOAP 0 #define DEBUG_SOAP 0
#define DEBUG_GENA 0 #define DEBUG_GENA 0
#define DEBUG_TPOOL 0 #define DEBUG_TPOOL 0
#define DEBUG_MSERV 0 #define DEBUG_MSERV 0
#define DEBUG_DOM 0 #define DEBUG_DOM 0
#define DEBUG_HTTP 0 #define DEBUG_HTTP 0
#define DEBUG_API 0 #define DEBUG_API 0
//@} // Compile time configuration options //@} // Compile time configuration options

View File

@@ -4,14 +4,15 @@
# #
# Process this file with autoconf to produce a configure script. # Process this file with autoconf to produce a configure script.
# #
# (C) Copyright 2005-2006 R<>mi Turboult <r3mi@users.sourceforge.net> # (C) Copyright 2005-2007 R<>mi Turboult <r3mi@users.sourceforge.net>
# #
AC_PREREQ(2.60) AC_PREREQ(2.60)
AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net]) AC_INIT([libupnp], [1.6.1], [mroberto@users.sourceforge.net])
###############################################################################
# *Independently* of the above libupnp package version, the libtool version # *Independently* of the above libupnp package version, the libtool version
# of the 3 libraries need to be updated whenever there is a change released : # of the 3 libraries need to be updated whenever there is a change released:
# "current:revision:age" (this is NOT the same as the package version), where: # "current:revision:age" (this is NOT the same as the package version), where:
# - library code modified: revision++ # - library code modified: revision++
# - interfaces changed/added/removed: current++ and revision=0 # - interfaces changed/added/removed: current++ and revision=0
@@ -19,11 +20,14 @@ AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
# - interfaces removed: age=0 # - interfaces removed: age=0
# *please update only once, before a formal release, not for each change* # *please update only once, before a formal release, not for each change*
# #
# For release 1.4.1, we had: ###############################################################################
# Release 1.4.1:
#AC_SUBST([LT_VERSION_IXML], [2:2:0]) #AC_SUBST([LT_VERSION_IXML], [2:2:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0]) #AC_SUBST([LT_VERSION_THREADUTIL], [2:2:0])
#AC_SUBST([LT_VERSION_UPNP], [2:2:0]) #AC_SUBST([LT_VERSION_UPNP], [2:2:0])
# #
###############################################################################
# Release 1.4.6:
# "current:revision:age" # "current:revision:age"
# #
# - Code has changed in ixml # - Code has changed in ixml
@@ -37,11 +41,12 @@ AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
# - Code has changed in upnp # - Code has changed in upnp
# revision: 2 -> 3 # revision: 2 -> 3
# #
# For release 1.4.6, we had:
#AC_SUBST([LT_VERSION_IXML], [2:3:0]) #AC_SUBST([LT_VERSION_IXML], [2:3:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1]) #AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1])
#AC_SUBST([LT_VERSION_UPNP], [2:3:0]) #AC_SUBST([LT_VERSION_UPNP], [2:3:0])
# #
###############################################################################
# Release 1.6.0:
# "current:revision:age" # "current:revision:age"
# #
# - Code has changed in ixml # - Code has changed in ixml
@@ -56,21 +61,50 @@ AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
# - Interface removed in upnp # - Interface removed in upnp
# age: 0 -> 0 # age: 0 -> 0
# #
# For release 1.6.0, we had:
#AC_SUBST([LT_VERSION_IXML], [2:4:0]) #AC_SUBST([LT_VERSION_IXML], [2:4:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1]) #AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1])
#AC_SUBST([LT_VERSION_UPNP], [3:0:0]) #AC_SUBST([LT_VERSION_UPNP], [3:0:0])
#
###############################################################################
# Release 1.6.1:
# "current:revision:age"
#
# - Code has changed in threadutil
# revision: 1 -> 2
# - Interface added in threadutil
# current: 3 -> 4
# revision: 2 -> 0
# - Interface added in threadutil
# age: 1 -> 2
# - Code has changed in upnp
# revision: 0 -> 1
#
#AC_SUBST([LT_VERSION_IXML], [2:4:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2])
#AC_SUBST([LT_VERSION_UPNP], [3:1:0])
#
###############################################################################
AC_SUBST([LT_VERSION_IXML], [2:4:0]) AC_SUBST([LT_VERSION_IXML], [2:4:0])
AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1]) AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2])
AC_SUBST([LT_VERSION_UPNP], [3:0:0]) AC_SUBST([LT_VERSION_UPNP], [3:1:0])
###############################################################################
# Repeating the algorithm so that it is closer to the modificatin place:
# - library code modified: revision++
# - interfaces changed/added/removed: current++ and revision=0
# - interfaces added: age++
# - interfaces removed: age=0
# *please update only once, before a formal release, not for each change*
###############################################################################
AC_CONFIG_AUX_DIR(config.aux) AC_CONFIG_AUX_DIR(config.aux)
AC_CONFIG_MACRO_DIR(m4) AC_CONFIG_MACRO_DIR(m4)
AC_CONFIG_SRCDIR(upnp/inc/upnp.h) AC_CONFIG_SRCDIR(upnp/inc/upnp.h)
AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects dist-bzip2]) AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects dist-bzip2])
# #
# Get canonical host names in host and host_os # Get canonical host names in host and host_os
# #

View File

@@ -547,6 +547,10 @@ int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
EXPORT int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats); EXPORT int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats);
EXPORT void ThreadPoolPrintStats(ThreadPoolStats *stats); EXPORT void ThreadPoolPrintStats(ThreadPoolStats *stats);
#else
static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {}
static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {}
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -42,131 +42,158 @@ extern "C" {
#endif #endif
#ifdef __FreeBSD__ #ifdef __FreeBSD__
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif #endif
#ifdef PTHREAD_MUTEX_RECURSIVE #ifdef PTHREAD_MUTEX_RECURSIVE
/* This system has SuS2-compliant mutex attributes. /* This system has SuS2-compliant mutex attributes.
* E.g. on Cygwin, where we don't have the old nonportable (NP) symbols * E.g. on Cygwin, where we don't have the old nonportable (NP) symbols
*/ */
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL #define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK #define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK
#else #else /* PTHREAD_MUTEX_RECURSIVE */
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_FAST_NP #define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_FAST_NP
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE_NP #define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE_NP
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK_NP #define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK_NP
#endif #endif /* PTHREAD_MUTEX_RECURSIVE */
#define ITHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
#define ITHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
#define ITHREAD_CANCELED PTHREAD_CANCELED #define ITHREAD_CANCELED PTHREAD_CANCELED
/*************************************************************************** /***************************************************************************
* Name: ithread_t * Name: ithread_t
* *
* Description: * Description:
* Thread handle. * Thread handle.
* typedef to pthread_t. * typedef to pthread_t.
* Internal Use Only. * Internal Use Only.
***************************************************************************/ ***************************************************************************/
typedef pthread_t ithread_t; typedef pthread_t ithread_t;
/**************************************************************************** /****************************************************************************
* Name: ithread_attr_t * Name: ithread_attr_t
* *
* Description: * Description:
* Thread attribute. * Thread attribute.
* typedef to pthread_attr_t * typedef to pthread_attr_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
typedef pthread_attr_t ithread_attr_t; typedef pthread_attr_t ithread_attr_t;
/**************************************************************************** /****************************************************************************
* Name: start_routine * Name: start_routine
* *
* Description: * Description:
* Thread start routine * Thread start routine
* Internal Use Only. * Internal Use Only.
***************************************************************************/ ***************************************************************************/
typedef void * (*start_routine) (void *arg); typedef void * (*start_routine) (void *arg);
/**************************************************************************** /****************************************************************************
* Name: ithread_cond_t * Name: ithread_cond_t
* *
* Description: * Description:
* condition variable. * condition variable.
* typedef to pthread_cond_t * typedef to pthread_cond_t
* Internal Use Only. * Internal Use Only.
***************************************************************************/ ***************************************************************************/
typedef pthread_cond_t ithread_cond_t; typedef pthread_cond_t ithread_cond_t;
/**************************************************************************** /****************************************************************************
* Name: ithread_mutexattr_t * Name: ithread_mutexattr_t
* *
* Description: * Description:
* Mutex attribute. * Mutex attribute.
* typedef to pthread_mutexattr_t * typedef to pthread_mutexattr_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
typedef pthread_mutexattr_t ithread_mutexattr_t; typedef pthread_mutexattr_t ithread_mutexattr_t;
/**************************************************************************** /****************************************************************************
* Name: ithread_mutex_t * Name: ithread_mutex_t
* *
* Description: * Description:
* Mutex. * Mutex.
* typedef to pthread_mutex_t * typedef to pthread_mutex_t
* Internal Use Only. * Internal Use Only.
***************************************************************************/ ***************************************************************************/
typedef pthread_mutex_t ithread_mutex_t; typedef pthread_mutex_t ithread_mutex_t;
/**************************************************************************** /****************************************************************************
* Name: ithread_condattr_t * Name: ithread_condattr_t
* *
* Description: * Description:
* Condition attribute. * Condition attribute.
* typedef to pthread_condattr_t * typedef to pthread_condattr_t
* NOT USED * NOT USED
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
typedef pthread_condattr_t ithread_condattr_t; typedef pthread_condattr_t ithread_condattr_t;
/****************************************************************************
* Function: ithread_mutexattr_init /****************************************************************************
* * Name: ithread_rwlockattr_t
* Description: *
* Initializes a mutex attribute variable. * Description:
* Used to set the type of the mutex. * Mutex attribute.
* Parameters: * typedef to pthread_rwlockattr_t
* ithread_mutexattr_init * attr (must be valid non NULL pointer to * Internal Use Only
* pthread_mutexattr_t) ***************************************************************************/
* Returns: typedef pthread_rwlockattr_t ithread_rwlockattr_t;
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_mutexattr_init /****************************************************************************
***************************************************************************/ * Name: ithread_rwlock_t
*
* Description:
* Condition attribute.
* typedef to pthread_rwlock_t
* Internal Use Only
***************************************************************************/
typedef pthread_rwlock_t ithread_rwlock_t;
/****************************************************************************
* Function: ithread_mutexattr_init
*
* Description:
* Initializes a mutex attribute variable.
* Used to set the type of the mutex.
* Parameters:
* ithread_mutexattr_init * attr (must be valid non NULL pointer to
* pthread_mutexattr_t)
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_mutexattr_init
***************************************************************************/
#define ithread_mutexattr_init pthread_mutexattr_init #define ithread_mutexattr_init pthread_mutexattr_init
/****************************************************************************
* Function: ithread_mutexattr_destroy /****************************************************************************
* * Function: ithread_mutexattr_destroy
* Description: *
* Releases any resources held by the mutex attribute. * Description:
* Currently there are no resources associated with the attribute * Releases any resources held by the mutex attribute.
* Parameters: * Currently there are no resources associated with the attribute
* ithread_mutexattr_t * attr (must be valid non NULL pointer to * Parameters:
* pthread_mutexattr_t) * ithread_mutexattr_t * attr (must be valid non NULL pointer to
* Returns: * pthread_mutexattr_t)
* 0 on success, Nonzero on failure. * Returns:
* Always returns 0. * 0 on success, Nonzero on failure.
* See man page for pthread_mutexattr_destroy * Always returns 0.
***************************************************************************/ * See man page for pthread_mutexattr_destroy
***************************************************************************/
#define ithread_mutexattr_destroy pthread_mutexattr_destroy #define ithread_mutexattr_destroy pthread_mutexattr_destroy
@@ -180,7 +207,7 @@ extern "C" {
* ITHREAD_MUTEX_ERRORCHECK_NP * ITHREAD_MUTEX_ERRORCHECK_NP
* *
* Parameters: * Parameters:
* ithread_mutexattr_t * mutex (must be valid non NULL pointer to * ithread_mutexattr_t * attr (must be valid non NULL pointer to
* ithread_mutexattr_t) * ithread_mutexattr_t)
* int kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP * int kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
* or ITHREAD_MUTEX_ERRORCHECK_NP) * or ITHREAD_MUTEX_ERRORCHECK_NP)
@@ -190,9 +217,9 @@ extern "C" {
* See man page for pthread_mutexattr_setkind_np * See man page for pthread_mutexattr_setkind_np
*****************************************************************************/ *****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE #ifdef PTHREAD_MUTEX_RECURSIVE
#define ithread_mutexattr_setkind_np pthread_mutexattr_settype #define ithread_mutexattr_setkind_np pthread_mutexattr_settype
#else #else
#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np #define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
#endif #endif
/**************************************************************************** /****************************************************************************
@@ -205,7 +232,7 @@ extern "C" {
* ITHREAD_MUTEX_ERRORCHECK_NP * ITHREAD_MUTEX_ERRORCHECK_NP
* *
* Parameters: * Parameters:
* ithread_mutexattr_t * mutex (must be valid non NULL pointer to * ithread_mutexattr_t * attr (must be valid non NULL pointer to
* pthread_mutexattr_t) * pthread_mutexattr_t)
* int *kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP * int *kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
* or ITHREAD_MUTEX_ERRORCHECK_NP) * or ITHREAD_MUTEX_ERRORCHECK_NP)
@@ -215,9 +242,9 @@ extern "C" {
* See man page for pthread_mutexattr_getkind_np * See man page for pthread_mutexattr_getkind_np
*****************************************************************************/ *****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE #ifdef PTHREAD_MUTEX_RECURSIVE
#define ithread_mutexattr_getkind_np pthread_mutexattr_gettype #define ithread_mutexattr_getkind_np pthread_mutexattr_gettype
#else #else
#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np #define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
#endif #endif
@@ -237,7 +264,8 @@ extern "C" {
* See man page for pthread_mutex_init * See man page for pthread_mutex_init
*****************************************************************************/ *****************************************************************************/
#define ithread_mutex_init pthread_mutex_init #define ithread_mutex_init pthread_mutex_init
/**************************************************************************** /****************************************************************************
* Function: ithread_mutex_lock * Function: ithread_mutex_lock
* *
@@ -291,7 +319,170 @@ extern "C" {
*****************************************************************************/ *****************************************************************************/
#define ithread_mutex_destroy pthread_mutex_destroy #define ithread_mutex_destroy pthread_mutex_destroy
/****************************************************************************
* Function: ithread_rwlockattr_init
*
* Description:
* Initializes a rwlock attribute variable to default values.
* Parameters:
* const ithread_rwlockattr_init *attr (must be valid non NULL pointer to
* pthread_rwlockattr_t)
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlockattr_init
***************************************************************************/
#define ithread_rwlockattr_init pthread_rwlockattr_init
/****************************************************************************
* Function: ithread_rwlockattr_destroy
*
* Description:
* Releases any resources held by the rwlock attribute.
* Parameters:
* ithread_rwlockattr_t *attr (must be valid non NULL pointer to
* pthread_rwlockattr_t)
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlockattr_destroy
***************************************************************************/
#define ithread_rwlockattr_destroy pthread_rwlockattr_destroy
/****************************************************************************
* Function: ithread_rwlockatttr_setpshared
*
* Description:
* Sets the rwlock type in the attribute.
* Valid types are: ITHREAD_PROCESS_PRIVATE
* ITHREAD_PROCESS_SHARED
*
* Parameters:
* ithread_rwlockattr_t * attr (must be valid non NULL pointer to
* ithread_rwlockattr_t)
* int kind (one of ITHREAD_PROCESS_PRIVATE or ITHREAD_PROCESS_SHARED)
*
* Returns:
* 0 on success. Nonzero on failure.
* Returns EINVAL if the kind is not supported.
* See man page for pthread_rwlockattr_setkind_np
*****************************************************************************/
#define ithread_rwlockatttr_setpshared pthread_rwlockatttr_setpshared
/****************************************************************************
* Function: ithread_rwlockatttr_getpshared
*
* Description:
* Gets the rwlock type in the attribute.
* Valid types are: ITHREAD_PROCESS_PRIVATE
* ITHREAD_PROCESS_SHARED
*
* Parameters:
* ithread_rwlockattr_t * attr (must be valid non NULL pointer to
* pthread_rwlockattr_t)
* int *kind (one of ITHREAD_PROCESS_PRIVATE or ITHREAD_PROCESS_SHARED)
*
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlockatttr_getpshared
*****************************************************************************/
#define ithread_rwlockatttr_getpshared pthread_rwlockatttr_getpshared
/****************************************************************************
* Function: ithread_rwlock_init
*
* Description:
* Initializes rwlock.
* Must be called before use.
*
* Parameters:
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
* const ithread_rwlockattr_t * rwlock_attr
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlock_init
*****************************************************************************/
#define ithread_rwlock_init pthread_rwlock_init
/****************************************************************************
* Function: ithread_rwlock_rdlock
*
* Description:
* Locks rwlock for reading.
* Parameters:
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
* rwlock must be initialized.
*
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlock_rdlock
*****************************************************************************/
#define ithread_rwlock_rdlock pthread_rwlock_rdlock
/****************************************************************************
* Function: ithread_rwlock_wrlock
*
* Description:
* Locks rwlock for writting.
* Parameters:
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
* rwlock must be initialized.
*
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlock_wrlock
*****************************************************************************/
#define ithread_rwlock_wrlock pthread_rwlock_wrlock
/****************************************************************************
* Function: ithread_rwlock_unlock
*
* Description:
* Unlocks rwlock.
*
* Parameters:
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
* rwlock must be initialized.
*
* Returns:
* 0 on success, Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlock_unlock
*****************************************************************************/
#define ithread_rwlock_unlock pthread_rwlock_unlock
/****************************************************************************
* Function: ithread_rwlock_destroy
*
* Description:
* Releases any resources held by the rwlock.
* rwlock can no longer be used after this call.
* rwlock is only destroyed when there are no longer any threads waiting on it.
* rwlock cannot be destroyed if it is locked.
* Parameters:
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
* rwlock must be initialized.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
* See man page for pthread_rwlock_destroy
*****************************************************************************/
#define ithread_rwlock_destroy pthread_rwlock_destroy
/**************************************************************************** /****************************************************************************
* Function: ithread_cond_init * Function: ithread_cond_init
* *

View File

@@ -31,7 +31,7 @@
#include "LinkedList.h" #include "LinkedList.h"
#include <sys/param.h> #include <sys/param.h>
#if (defined(BSD) && BSD >= 199306) #if (defined(BSD) && BSD >= 199306) || defined(__OSX__)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <malloc.h>

View File

@@ -90,22 +90,23 @@ FreeThreadPoolJob( ThreadPool * tp,
static int static int
SetPolicyType( PolicyType in ) SetPolicyType( PolicyType in )
{ {
#ifdef __CYGWIN__ #ifdef __CYGWIN__
/* TODO not currently working... */ /* TODO not currently working... */
return 0; return 0;
#else #elif defined(__OSX__)
#ifdef WIN32 setpriority(PRIO_PROCESS, 0, 0);
return 0;
#elif defined(WIN32)
return sched_setscheduler( 0, in); return sched_setscheduler( 0, in);
#elif defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0 #elif defined(_POSIX_PRIORITY_SCHEDULING) && _POSIX_PRIORITY_SCHEDULING > 0
struct sched_param current; struct sched_param current;
sched_getparam( 0, &current ); sched_getparam( 0, &current );
current.sched_priority = DEFAULT_SCHED_PARAM; current.sched_priority = DEFAULT_SCHED_PARAM;
return sched_setscheduler( 0, in, &current ); return sched_setscheduler( 0, in, &current );
#else #else
return 0; return 0;
#endif #endif
#endif
} }
/**************************************************************************** /****************************************************************************
@@ -364,7 +365,7 @@ static void SetSeed() {
ftime( &t ); ftime( &t );
#if defined(WIN32) #if defined(WIN32)
srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id().p ); srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id().p );
#elif defined(__FreeBSD__) #elif defined(__FreeBSD__) || defined(__OSX__)
srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id() ); srand( ( unsigned int )t.millitm + (unsigned int)ithread_get_current_thread_id() );
#elif defined(__linux__) #elif defined(__linux__)
srand( ( unsigned int )t.millitm + ithread_get_current_thread_id() ); srand( ( unsigned int )t.millitm + ithread_get_current_thread_id() );
@@ -1510,36 +1511,33 @@ static void SetSeed() {
} }
#ifdef STATS #ifdef STATS
void ThreadPoolPrintStats( ThreadPoolStats * stats ) { void ThreadPoolPrintStats(ThreadPoolStats * stats)
assert( stats != NULL ); if( stats == NULL ) { {
return;} assert( stats != NULL );
if (stats == NULL) {
return;
}
#ifdef __FreeBSD__ #ifdef __FreeBSD__
printf( "ThreadPoolStats at Time: %d\n", time( NULL ) ); printf("ThreadPoolStats at Time: %d\n", time(NULL));
#else #else /* __FreeBSD__ */
printf( "ThreadPoolStats at Time: %ld\n", time( NULL ) ); printf("ThreadPoolStats at Time: %ld\n", time(NULL));
#endif #endif /* __FreeBSD__ */
printf printf("High Jobs pending: %d\n", stats->currentJobsHQ);
( "Average Wait in High Priority Q in milliseconds: %f\n", printf("Med Jobs Pending: %d\n", stats->currentJobsMQ);
stats->avgWaitHQ ); printf("Low Jobs Pending: %d\n", stats->currentJobsLQ);
printf printf("Average Wait in High Priority Q in milliseconds: %f\n", stats->avgWaitHQ);
( "Average Wait in Med Priority Q in milliseconds: %f\n", printf("Average Wait in Med Priority Q in milliseconds: %f\n", stats->avgWaitMQ);
stats->avgWaitMQ ); printf("Averate Wait in Low Priority Q in milliseconds: %f\n", stats->avgWaitLQ);
printf printf("Max Threads Active: %d\n", stats->maxThreads);
( "Averate Wait in Low Priority Q in milliseconds: %f\n", printf("Current Worker Threads: %d\n", stats->workerThreads);
stats->avgWaitLQ ); printf("Current Persistent Threads: %d\n", stats->persistentThreads);
printf( "Max Threads Active: %d\n", stats->maxThreads ); printf("Current Idle Threads: %d\n", stats->idleThreads);
printf( "Current Worker Threads: %d\n", printf("Total Threads : %d\n", stats->totalThreads);
stats->workerThreads ); printf("Total Time spent Working in seconds: %f\n", stats->totalWorkTime);
printf( "Current Persistent Threads: %d\n", printf("Total Time spent Idle in seconds : %f\n", stats->totalIdleTime);
stats->persistentThreads ); }
printf( "Current Idle Threads: %d\n", stats->idleThreads ); #endif /* STATS */
printf( "Total Threads : %d\n", stats->totalThreads );
printf( "Total Time spent Working in seconds: %f\n",
stats->totalWorkTime );
printf( "Total Time spent Idle in seconds : %f\n",
stats->totalIdleTime );}
#endif
/**************************************************************************** /****************************************************************************
* Function: TPAttrSetMaxJobsTotal * Function: TPAttrSetMaxJobsTotal
@@ -1552,17 +1550,19 @@ static void SetSeed() {
* Returns: * Returns:
* Always returns 0. * Always returns 0.
*****************************************************************************/ *****************************************************************************/
int TPAttrSetMaxJobsTotal( ThreadPoolAttr * attr, int TPAttrSetMaxJobsTotal(
int maxJobsTotal ) { ThreadPoolAttr * attr,
assert( attr != NULL ); int maxJobsTotal )
{
assert( attr != NULL );
if( attr == NULL ) { if( attr == NULL ) {
return EINVAL; return EINVAL;
} }
attr->maxJobsTotal = maxJobsTotal; attr->maxJobsTotal = maxJobsTotal;
return 0; return 0;
} }
/**************************************************************************** /****************************************************************************
* Function: ThreadPoolGetStats * Function: ThreadPoolGetStats
@@ -1579,40 +1579,54 @@ static void SetSeed() {
*****************************************************************************/ *****************************************************************************/
#ifdef STATS #ifdef STATS
int int
ThreadPoolGetStats( ThreadPool * tp, ThreadPoolGetStats(
ThreadPoolStats * stats ) { ThreadPool *tp,
ThreadPoolStats *stats)
{
assert(tp != NULL);
assert(stats != NULL);
assert( tp != NULL ); if (tp == NULL || stats == NULL) {
assert( stats != NULL ); return EINVAL;
if( ( tp == NULL ) || ( stats == NULL ) ) { }
return EINVAL;}
//if not shutdown then acquire mutex //if not shutdown then acquire mutex
if( !tp->shutdown ) { if (!tp->shutdown) {
ithread_mutex_lock( &tp->mutex );} ithread_mutex_lock(&tp->mutex);
}
( *stats ) = tp->stats; if( stats->totalJobsHQ > 0 ) *stats = tp->stats;
stats->avgWaitHQ = if (stats->totalJobsHQ > 0) {
stats->totalTimeHQ / stats->totalJobsHQ; stats->avgWaitHQ = stats->totalTimeHQ / stats->totalJobsHQ;
else } else {
stats->avgWaitHQ = 0; if( stats->totalJobsMQ > 0 ) stats->avgWaitHQ = 0;
stats->avgWaitMQ = }
stats->totalTimeMQ / stats->totalJobsMQ;
else if( stats->totalJobsMQ > 0 ) {
stats->avgWaitMQ = 0; if( stats->totalJobsLQ > 0 ) stats->avgWaitMQ = stats->totalTimeMQ / stats->totalJobsMQ;
stats->avgWaitLQ = } else {
stats->totalTimeLQ / stats->totalJobsLQ; stats->avgWaitMQ = 0;
else }
stats->avgWaitLQ = 0;
stats->totalThreads = tp->totalThreads; if( stats->totalJobsLQ > 0 ) {
stats->persistentThreads = tp->persistentThreads; stats->avgWaitLQ = stats->totalTimeLQ / stats->totalJobsLQ;
stats->currentJobsHQ = ListSize( &tp->highJobQ ); } else {
stats->currentJobsLQ = ListSize( &tp->lowJobQ ); stats->avgWaitLQ = 0;
stats->currentJobsMQ = ListSize( &tp->medJobQ ); }
//if not shutdown then release mutex
if( !tp->shutdown ) {
ithread_mutex_unlock( &tp->mutex );}
return 0;} stats->totalThreads = tp->totalThreads;
stats->persistentThreads = tp->persistentThreads;
stats->currentJobsHQ = ListSize( &tp->highJobQ );
stats->currentJobsLQ = ListSize( &tp->lowJobQ );
stats->currentJobsMQ = ListSize( &tp->medJobQ );
//if not shutdown then release mutex
if( !tp->shutdown ) {
ithread_mutex_unlock( &tp->mutex );
}
return 0;
}
#endif /* STATS */
#endif

View File

@@ -32,7 +32,7 @@
#include <stdarg.h> #include <stdarg.h>
#include <assert.h> #include <assert.h>
#include <sys/param.h> #include <sys/param.h>
#if (defined(BSD) && BSD >= 199306) #if (defined(BSD) && BSD >= 199306) || defined(__OSX__)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <malloc.h>

View File

@@ -258,7 +258,7 @@ void UpnpPrintf(
__attribute__((format (__printf__, 5, 6))) __attribute__((format (__printf__, 5, 6)))
#endif #endif
; ;
#else #else /* DEBUG */
static UPNP_INLINE void UpnpPrintf( static UPNP_INLINE void UpnpPrintf(
Upnp_LogLevel DLevel, Upnp_LogLevel DLevel,
Dbg_Module Module, Dbg_Module Module,
@@ -266,7 +266,7 @@ static UPNP_INLINE void UpnpPrintf(
int DbgLineNo, int DbgLineNo,
const char* FmtStr, const char* FmtStr,
...) {} ...) {}
#endif #endif /* DEBUG */
/*************************************************************************** /***************************************************************************

View File

@@ -1362,7 +1362,7 @@ TvCtrlPointStart( print_string printFunctionPtr,
ithread_mutex_init( &DeviceListMutex, 0 ); ithread_mutex_init( &DeviceListMutex, 0 );
SampleUtil_Print( "Intializing UPnP with ipaddress=%s port=%d", SampleUtil_Print( "Initializing UPnP with ipaddress=%s port=%d",
ip_address, port ); ip_address, port );
rc = UpnpInit( ip_address, port ); rc = UpnpInit( ip_address, port );
if( UPNP_E_SUCCESS != rc ) { if( UPNP_E_SUCCESS != rc ) {

View File

@@ -84,8 +84,8 @@ virtualDirList *pVirtualDirList;
// Mutex to synchronize the subscription handling at the client side // Mutex to synchronize the subscription handling at the client side
CLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex; ) CLIENTONLY( ithread_mutex_t GlobalClientSubscribeMutex; )
//Mutex to synchronize handles ( root device or control point handle) // rwlock to synchronize handles (root device or control point handle)
ithread_mutex_t GlobalHndMutex; ithread_rwlock_t GlobalHndRWLock;
// Mutex to synchronize the uuid creation process // Mutex to synchronize the uuid creation process
ithread_mutex_t gUUIDMutex; ithread_mutex_t gUUIDMutex;
@@ -213,26 +213,26 @@ int UpnpInit( IN const char *HostIP,
#ifdef __CYGWIN__ #ifdef __CYGWIN__
/* On Cygwin, pthread_mutex_init() fails without this memset. */ /* On Cygwin, pthread_mutex_init() fails without this memset. */
/* TODO: Fix Cygwin so we don't need this memset(). */ /* TODO: Fix Cygwin so we don't need this memset(). */
memset(&GlobalHndMutex, 0, sizeof(GlobalHndMutex)); memset(&GlobalHndRWLock, 0, sizeof(GlobalHndRWLock));
#endif #endif
if( ithread_mutex_init( &GlobalHndMutex, NULL ) != 0 ) { if (ithread_rwlock_init(&GlobalHndRWLock, NULL) != 0) {
return UPNP_E_INIT_FAILED; return UPNP_E_INIT_FAILED;
} }
if( ithread_mutex_init( &gUUIDMutex, NULL ) != 0 ) { if (ithread_mutex_init(&gUUIDMutex, NULL) != 0) {
return UPNP_E_INIT_FAILED; return UPNP_E_INIT_FAILED;
} }
// initialize subscribe mutex // initialize subscribe mutex
#ifdef INCLUDE_CLIENT_APIS #ifdef INCLUDE_CLIENT_APIS
if ( ithread_mutex_init( &GlobalClientSubscribeMutex, NULL ) != 0 ) { if (ithread_mutex_init(&GlobalClientSubscribeMutex, NULL) != 0) {
return UPNP_E_INIT_FAILED; return UPNP_E_INIT_FAILED;
} }
#endif #endif
HandleLock(); HandleLock();
if( HostIP != NULL ) if( HostIP != NULL ) {
strcpy( LOCAL_HOST, HostIP ); strcpy( LOCAL_HOST, HostIP );
else { } else {
if( getlocalhostname( LOCAL_HOST ) != UPNP_E_SUCCESS ) { if( getlocalhostname( LOCAL_HOST ) != UPNP_E_SUCCESS ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INIT_FAILED; return UPNP_E_INIT_FAILED;
@@ -323,29 +323,56 @@ int UpnpInit( IN const char *HostIP,
#ifdef DEBUG #ifdef DEBUG
static void static void
PrintThreadPoolStats (const char* DbgFileName, int DbgLineNo, PrintThreadPoolStats(
const char* msg, const ThreadPoolStats* const stats) ThreadPool *tp,
const char *DbgFileName,
int DbgLineNo,
const char *msg)
{ {
UpnpPrintf (UPNP_INFO, API, DbgFileName, DbgLineNo, ThreadPoolStats stats;
"%s \n High Jobs pending = %d \nMed Jobs Pending = %d\n" ThreadPoolGetStats(tp, &stats);
" Low Jobs Pending = %d \nWorker Threads = %d\n" UpnpPrintf(UPNP_INFO, API, DbgFileName, DbgLineNo,
"Idle Threads = %d\nPersistent Threads = %d\n" "%s \n"
"Average Time spent in High Q = %lf\n" "High Jobs pending: %d\n"
"Average Time spent in Med Q = %lf\n" "Med Jobs Pending: %d\n"
"Average Time spent in Low Q = %lf\n" "Low Jobs Pending: %d\n"
"Max Threads Used: %d\nTotal Work Time= %lf\n" "Average wait in High Q in milliseconds: %lf\n"
"Total Idle Time = %lf\n", "Average wait in Med Q in milliseconds: %lf\n"
msg, "Average wait in Low Q in milliseconds: %lf\n"
stats->currentJobsHQ, stats->currentJobsMQ, "Max Threads Used: %d\n"
stats->currentJobsLQ, stats->workerThreads, "Worker Threads: %d\n"
stats->idleThreads, stats->persistentThreads, "Persistent Threads: %d\n"
stats->avgWaitHQ, stats->avgWaitMQ, stats->avgWaitLQ, "Idle Threads: %d\n"
stats->maxThreads, stats->totalWorkTime, "Total Threads: %d\n"
stats->totalIdleTime ); "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);
} }
#endif #else /* DEBUG */
static UPNP_INLINE void
PrintThreadPoolStats(
ThreadPool *tp,
const char *DbgFileName,
int DbgLineNo,
const char *msg)
{
}
#endif /* DEBUG */
/**************************************************************************** /****************************************************************************
* Function: UpnpFinish * Function: UpnpFinish
* *
@@ -374,10 +401,6 @@ UpnpFinish()
#endif #endif
struct Handle_Info *temp; struct Handle_Info *temp;
#ifdef DEBUG
ThreadPoolStats stats;
#endif
#ifdef WIN32 #ifdef WIN32
// WSACleanup( ); // WSACleanup( );
#endif #endif
@@ -389,18 +412,12 @@ UpnpFinish()
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Inside UpnpFinish : UpnpSdkInit is :%d:\n", "Inside UpnpFinish : UpnpSdkInit is :%d:\n",
UpnpSdkInit ); UpnpSdkInit );
#ifdef DEBUG
if( UpnpSdkInit == 1 ) { if( UpnpSdkInit == 1 ) {
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"UpnpFinish : UpnpSdkInit is ONE\n" ); "UpnpFinish : UpnpSdkInit is ONE\n" );
} }
ThreadPoolGetStats( &gRecvThreadPool, &stats ); PrintThreadPoolStats(&gRecvThreadPool, __FILE__, __LINE__, "Recv Thread Pool");
PrintThreadPoolStats (__FILE__, __LINE__, PrintThreadPoolStats(&gSendThreadPool, __FILE__, __LINE__, "Send Thread Pool");
"Recv Thread Pool", &stats);
ThreadPoolGetStats( &gSendThreadPool, &stats );
PrintThreadPoolStats (__FILE__, __LINE__,
"Send Thread Pool", &stats);
#endif
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE ) if( GetDeviceHandleInfo( &device_handle, &temp ) == HND_DEVICE )
UpnpUnRegisterRootDevice( device_handle ); UpnpUnRegisterRootDevice( device_handle );
@@ -419,44 +436,38 @@ UpnpFinish()
web_server_destroy(); web_server_destroy();
#endif #endif
#ifdef DEBUG ThreadPoolShutdown(&gSendThreadPool);
ThreadPoolShutdown( &gSendThreadPool ); ThreadPoolShutdown(&gRecvThreadPool);
ThreadPoolShutdown( &gRecvThreadPool );
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Exiting UpnpFinish : UpnpSdkInit is :%d:\n", "Exiting UpnpFinish : UpnpSdkInit is :%d:\n", UpnpSdkInit);
UpnpSdkInit ); PrintThreadPoolStats(&gRecvThreadPool, __FILE__, __LINE__, "Recv Thread Pool");
ThreadPoolGetStats( &gRecvThreadPool, &stats ); PrintThreadPoolStats(&gSendThreadPool, __FILE__, __LINE__, "Send Thread Pool");
PrintThreadPoolStats( __FILE__, __LINE__,
"Recv Thread Pool", &stats);
ThreadPoolGetStats( &gSendThreadPool, &stats );
PrintThreadPoolStats(__FILE__, __LINE__,
"Send Thread Pool", &stats);
UpnpCloseLog(); UpnpCloseLog();
#endif
#ifdef INCLUDE_CLIENT_APIS #ifdef INCLUDE_CLIENT_APIS
ithread_mutex_destroy( &GlobalClientSubscribeMutex ); ithread_mutex_destroy(&GlobalClientSubscribeMutex);
#endif #endif
ithread_mutex_destroy( &GlobalHndMutex ); ithread_rwlock_destroy(&GlobalHndRWLock);
ithread_mutex_destroy( &gUUIDMutex ); ithread_mutex_destroy(&gUUIDMutex);
// remove all virtual dirs // remove all virtual dirs
UpnpRemoveAllVirtualDirs(); UpnpRemoveAllVirtualDirs();
// leuk_he allow static linking:
// allow static linking
#ifdef WIN32 #ifdef WIN32
#ifdef PTW32_STATIC_LIB #ifdef PTW32_STATIC_LIB
pthread_win32_thread_detach_np (); pthread_win32_thread_detach_np ();
#endif #endif
#endif #endif
UpnpSdkInit = 0; UpnpSdkInit = 0;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} /********************* End of UpnpFinish *************************/ }
/*************************** End of UpnpFinish *****************************/
/**************************************************************************** /******************************************************************************
* Function: UpnpGetServerPort * Function: UpnpGetServerPort
* *
* Parameters: NONE * Parameters: NONE
@@ -953,7 +964,7 @@ GetDescDocumentAndURL( IN Upnp_DescType descriptionType,
char *temp_str = NULL; char *temp_str = NULL;
FILE *fp = NULL; FILE *fp = NULL;
off_t fileLen; off_t fileLen;
unsigned num_read; size_t num_read;
time_t last_modified; time_t last_modified;
struct stat file_info; struct stat file_info;
struct sockaddr_in serverAddr; struct sockaddr_in serverAddr;
@@ -1559,7 +1570,7 @@ UpnpSearchAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSearchAsync \n" ); "Inside UpnpSearchAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -1735,7 +1746,7 @@ UpnpSubscribeAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSubscribeAsync \n" ); "Inside UpnpSubscribeAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -1752,15 +1763,13 @@ UpnpSubscribeAsync( IN UpnpClient_Handle Hnd,
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
} }
HandleUnlock();
Param = Param = (struct UpnpNonblockParam *)
( struct UpnpNonblockParam * ) malloc(sizeof (struct UpnpNonblockParam));
malloc( sizeof( struct UpnpNonblockParam ) );
if( Param == NULL ) { if( Param == NULL ) {
HandleUnlock();
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
HandleUnlock();
Param->FunName = SUBSCRIBE; Param->FunName = SUBSCRIBE;
Param->Handle = Hnd; Param->Handle = Hnd;
@@ -1820,7 +1829,7 @@ UpnpSubscribe( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSubscribe \n" ); "Inside UpnpSubscribe \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -1880,7 +1889,7 @@ UpnpUnSubscribe( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpUnSubscribe \n" ); "Inside UpnpUnSubscribe \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -1939,7 +1948,7 @@ UpnpUnSubscribeAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpUnSubscribeAsync \n" ); "Inside UpnpUnSubscribeAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2013,7 +2022,7 @@ UpnpRenewSubscription( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRenewSubscription \n" ); "Inside UpnpRenewSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2078,7 +2087,7 @@ UpnpRenewSubscriptionAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRenewSubscriptionAsync \n" ); "Inside UpnpRenewSubscriptionAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2173,7 +2182,7 @@ UpnpNotify( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpNotify \n" ); "Inside UpnpNotify \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2244,7 +2253,7 @@ UpnpNotifyExt( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpNotify \n" ); "Inside UpnpNotify \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2321,7 +2330,7 @@ UpnpAcceptSubscription( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpAcceptSubscription \n" ); "Inside UpnpAcceptSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2397,7 +2406,7 @@ UpnpAcceptSubscriptionExt( IN UpnpDevice_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpAcceptSubscription \n" ); "Inside UpnpAcceptSubscription \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2493,7 +2502,7 @@ UpnpSendAction( IN UpnpClient_Handle Hnd,
} }
DevUDN_const = NULL; DevUDN_const = NULL;
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2577,7 +2586,7 @@ UpnpSendActionEx( IN UpnpClient_Handle Hnd,
return retVal; return retVal;
} }
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2653,7 +2662,7 @@ UpnpSendActionAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpSendActionAsync \n" ); "Inside UpnpSendActionAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2773,7 +2782,7 @@ UpnpSendActionExAsync( IN UpnpClient_Handle Hnd,
return retVal; return retVal;
} }
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2887,7 +2896,7 @@ UpnpGetServiceVarStatusAsync( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpGetServiceVarStatusAsync \n" ); "Inside UpnpGetServiceVarStatusAsync \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -2967,7 +2976,7 @@ UpnpGetServiceVarStatus( IN UpnpClient_Handle Hnd,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpGetServiceVarStatus \n" ); "Inside UpnpGetServiceVarStatus \n" );
HandleLock(); HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
@@ -3300,9 +3309,9 @@ UpnpDownloadXmlDoc( const char *url,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"****************** END OF Parsed XML Doc *****************\n" ); "****************** END OF Parsed XML Doc *****************\n" );
ixmlFreeDOMString( xml_buf ); ixmlFreeDOMString( xml_buf );
#endif
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting UpnpDownloadXmlDoc\n" ); "Exiting UpnpDownloadXmlDoc\n" );
#endif
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
} }
@@ -3635,7 +3644,6 @@ int PrintHandleInfo( IN UpnpClient_Handle Hnd )
struct Handle_Info * HndInfo; struct Handle_Info * HndInfo;
if (HandleTable[Hnd] != NULL) { if (HandleTable[Hnd] != NULL) {
HndInfo = HandleTable[Hnd]; HndInfo = HandleTable[Hnd];
#ifdef DEBUG
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Printing information for Handle_%d\n", Hnd); "Printing information for Handle_%d\n", Hnd);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
@@ -3644,7 +3652,6 @@ int PrintHandleInfo( IN UpnpClient_Handle Hnd )
if(HndInfo->HType != HND_CLIENT) if(HndInfo->HType != HND_CLIENT)
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"DescURL_%s\n", HndInfo->DescURL ); "DescURL_%s\n", HndInfo->DescURL );
#endif
#endif #endif
} else { } else {
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;

View File

@@ -36,7 +36,7 @@
#include "uri.h" #include "uri.h"
#define HEADER_LENGTH 2000 #define HEADER_LENGTH 2000
//Structure to maintain a error code and string associated with the // Structure to maintain a error code and string associated with the
// error code // error code
struct ErrorString { struct ErrorString {
int rc; /* error code */ int rc; /* error code */
@@ -44,7 +44,7 @@ struct ErrorString {
}; };
//Intializing the array of error structures. // Initializing the array of error structures.
struct ErrorString ErrorMessages[] = { {UPNP_E_SUCCESS, "UPNP_E_SUCCESS"}, struct ErrorString ErrorMessages[] = { {UPNP_E_SUCCESS, "UPNP_E_SUCCESS"},
{UPNP_E_INVALID_HANDLE, "UPNP_E_INVALID_HANDLE"}, {UPNP_E_INVALID_HANDLE, "UPNP_E_INVALID_HANDLE"},
{UPNP_E_INVALID_PARAM, "UPNP_E_INVALID_PARAM"}, {UPNP_E_INVALID_PARAM, "UPNP_E_INVALID_PARAM"},
@@ -81,13 +81,13 @@ struct ErrorString ErrorMessages[] = { {UPNP_E_SUCCESS, "UPNP_E_SUCCESS"},
}; };
/************************************************************************ /************************************************************************
* Function : UpnpGetErrorMessage * Function : UpnpGetErrorMessage
* *
* Parameters: * Parameters:
* IN int rc: error code * IN int rc: error code
* *
* Description: * Description:
* This functions returns the error string mapped to the error code * This functions returns the error string mapped to the error code
* Returns: const char * * Returns: const char *
* return either the right string or "Unknown Error" * return either the right string or "Unknown Error"
***************************************************************************/ ***************************************************************************/
@@ -108,14 +108,14 @@ UpnpGetErrorMessage( IN int rc )
} }
/************************************************************************ /************************************************************************
* Function : UpnpResolveURL * Function : UpnpResolveURL
* *
* Parameters: * Parameters:
* IN char * BaseURL: Base URL string * IN char * BaseURL: Base URL string
* IN char * RelURL: relative URL string * IN char * RelURL: relative URL string
* OUT char * AbsURL: Absolute URL string * OUT char * AbsURL: Absolute URL string
* Description: * Description:
* This functions concatinates the base URL and relative URL to generate * This functions concatinates the base URL and relative URL to generate
* the absolute URL * the absolute URL
* Returns: int * Returns: int
* return either UPNP_E_SUCCESS or appropriate error * return either UPNP_E_SUCCESS or appropriate error
@@ -151,19 +151,19 @@ UpnpResolveURL( IN const char *BaseURL,
} }
/************************************************************************ /************************************************************************
* Function : addToAction * Function : addToAction
* *
* Parameters: * Parameters:
* IN int response: flag to tell if the ActionDoc is for response * IN int response: flag to tell if the ActionDoc is for response
* or request * or request
* INOUT IXML_Document **ActionDoc: request or response document * INOUT IXML_Document **ActionDoc: request or response document
* IN char *ActionName: Name of the action request or response * IN char *ActionName: Name of the action request or response
* IN char *ServType: Service type * IN char *ServType: Service type
* IN char * ArgName: Name of the argument * IN char * ArgName: Name of the argument
* IN char * ArgValue: Value of the argument * IN char * ArgValue: Value of the argument
* *
* Description: * Description:
* This function adds the argument in the action request or response. * This function adds the argument in the action request or response.
* This function creates the action request or response if it is a first * This function creates the action request or response if it is a first
* argument else it will add the argument in the document * argument else it will add the argument in the document
* *
@@ -230,22 +230,22 @@ addToAction( IN int response,
} }
/************************************************************************ /************************************************************************
* Function : makeAction * Function : makeAction
* *
* Parameters: * Parameters:
* IN int response: flag to tell if the ActionDoc is for response * IN int response: flag to tell if the ActionDoc is for response
* or request * or request
* IN char * ActionName: Name of the action request or response * IN char * ActionName: Name of the action request or response
* IN char * ServType: Service type * IN char * ServType: Service type
* IN int NumArg :Number of arguments in the action request or response * IN int NumArg :Number of arguments in the action request or response
* IN char * Arg : pointer to the first argument * IN char * Arg : pointer to the first argument
* IN va_list ArgList: Argument list * IN va_list ArgList: Argument list
* *
* Description: * Description:
* This function creates the action request or response from the argument * This function creates the action request or response from the argument
* list. * list.
* Returns: IXML_Document * * Returns: IXML_Document *
* returns action request or response document if successful * returns action request or response document if successful
* else returns NULL * else returns NULL
***************************************************************************/ ***************************************************************************/
static IXML_Document * static IXML_Document *
@@ -326,9 +326,9 @@ makeAction( IN int response,
} }
/************************************************************************ /************************************************************************
* Function : UpnpMakeAction * Function : UpnpMakeAction
* *
* Parameters: * Parameters:
* IN char * ActionName: Name of the action request or response * IN char * ActionName: Name of the action request or response
* IN char * ServType: Service type * IN char * ServType: Service type
* IN int NumArg :Number of arguments in the action request or response * IN int NumArg :Number of arguments in the action request or response
@@ -336,7 +336,7 @@ makeAction( IN int response,
* IN ... : variable argument list * IN ... : variable argument list
* IN va_list ArgList: Argument list * IN va_list ArgList: Argument list
* *
* Description: * Description:
* This function creates the action request from the argument * This function creates the action request from the argument
* list. Its a wrapper function that calls makeAction function to create * list. Its a wrapper function that calls makeAction function to create
* the action request. * the action request.
@@ -363,9 +363,9 @@ UpnpMakeAction( const char *ActionName,
} }
/************************************************************************ /************************************************************************
* Function : UpnpMakeActionResponse * Function : UpnpMakeActionResponse
* *
* Parameters: * Parameters:
* IN char * ActionName: Name of the action request or response * IN char * ActionName: Name of the action request or response
* IN char * ServType: Service type * IN char * ServType: Service type
* IN int NumArg :Number of arguments in the action request or response * IN int NumArg :Number of arguments in the action request or response
@@ -373,13 +373,13 @@ UpnpMakeAction( const char *ActionName,
* IN ... : variable argument list * IN ... : variable argument list
* IN va_list ArgList: Argument list * IN va_list ArgList: Argument list
* *
* Description: * Description:
* This function creates the action response from the argument * This function creates the action response from the argument
* list. Its a wrapper function that calls makeAction function to create * list. Its a wrapper function that calls makeAction function to create
* the action response. * the action response.
* *
* Returns: IXML_Document * * Returns: IXML_Document *
* returns action response document if successful * returns action response document if successful
* else returns NULL * else returns NULL
***************************************************************************/ ***************************************************************************/
IXML_Document * IXML_Document *
@@ -400,22 +400,22 @@ UpnpMakeActionResponse( const char *ActionName,
} }
/************************************************************************ /************************************************************************
* Function : UpnpAddToActionResponse * Function : UpnpAddToActionResponse
* *
* Parameters: * Parameters:
* INOUT IXML_Document **ActionResponse: action response document * INOUT IXML_Document **ActionResponse: action response document
* IN char * ActionName: Name of the action request or response * IN char * ActionName: Name of the action request or response
* IN char * ServType: Service type * IN char * ServType: Service type
* IN int ArgName :Name of argument to be added in the action response * IN int ArgName :Name of argument to be added in the action response
* IN char * ArgValue : value of the argument * IN char * ArgValue : value of the argument
* *
* Description: * Description:
* This function adds the argument in the action response. Its a wrapper * This function adds the argument in the action response. Its a wrapper
* function that calls addToAction function to add the argument in the * function that calls addToAction function to add the argument in the
* action response. * action response.
* *
* Returns: int * Returns: int
* returns UPNP_E_SUCCESS if successful * returns UPNP_E_SUCCESS if successful
* else returns appropriate error * else returns appropriate error
***************************************************************************/ ***************************************************************************/
int int
@@ -430,22 +430,22 @@ UpnpAddToActionResponse( INOUT IXML_Document ** ActionResponse,
} }
/************************************************************************ /************************************************************************
* Function : UpnpAddToAction * Function : UpnpAddToAction
* *
* Parameters: * Parameters:
* INOUT IXML_Document **ActionDoc: action request document * INOUT IXML_Document **ActionDoc: action request document
* IN char * ActionName: Name of the action request or response * IN char * ActionName: Name of the action request or response
* IN char * ServType: Service type * IN char * ServType: Service type
* IN int ArgName :Name of argument to be added in the action response * IN int ArgName :Name of argument to be added in the action response
* IN char * ArgValue : value of the argument * IN char * ArgValue : value of the argument
* *
* Description: * Description:
* This function adds the argument in the action request. Its a wrapper * This function adds the argument in the action request. Its a wrapper
* function that calls addToAction function to add the argument in the * function that calls addToAction function to add the argument in the
* action request. * action request.
* *
* Returns: int * Returns: int
* returns UPNP_E_SUCCESS if successful * returns UPNP_E_SUCCESS if successful
* else returns appropriate error * else returns appropriate error
***************************************************************************/ ***************************************************************************/
int int
@@ -461,15 +461,15 @@ UpnpAddToAction( IXML_Document ** ActionDoc,
} }
/************************************************************************ /************************************************************************
* Function : UpnpAddToPropertySet * Function : UpnpAddToPropertySet
* *
* Parameters: * Parameters:
* INOUT IXML_Document **PropSet: propertyset document * INOUT IXML_Document **PropSet: propertyset document
* IN char *ArgName: Name of the argument * IN char *ArgName: Name of the argument
* IN char *ArgValue: value of the argument * IN char *ArgValue: value of the argument
* *
* Description: * Description:
* This function adds the argument in the propertyset node * This function adds the argument in the propertyset node
* *
* Returns: int * Returns: int
* returns UPNP_E_SUCCESS if successful else returns appropriate error * returns UPNP_E_SUCCESS if successful else returns appropriate error
@@ -516,14 +516,14 @@ UpnpAddToPropertySet( INOUT IXML_Document ** PropSet,
} }
/************************************************************************ /************************************************************************
* Function : UpnpCreatePropertySet * Function : UpnpCreatePropertySet
* *
* Parameters: * Parameters:
* IN int NumArg: Number of argument that will go in the propertyset node * IN int NumArg: Number of argument that will go in the propertyset node
* IN char * Args: argument strings * IN char * Args: argument strings
* *
* Description: * Description:
* This function creates a propertyset node and put all the input * This function creates a propertyset node and put all the input
* parameters in the node as elements * parameters in the node as elements
* *
* Returns: IXML_Document * * Returns: IXML_Document *
@@ -581,4 +581,5 @@ UpnpCreatePropertySet( IN int NumArg,
return PropSet; return PropSet;
} }
#endif #endif // EXCLUDE_DOM == 0

View File

@@ -45,12 +45,12 @@
extern ithread_mutex_t GlobalClientSubscribeMutex; extern ithread_mutex_t GlobalClientSubscribeMutex;
/************************************************************************ /************************************************************************
* Function : GenaAutoRenewSubscription * Function : GenaAutoRenewSubscription
* *
* Parameters: * Parameters:
* IN void *input: Thread data(upnp_timeout *) needed to send the renewal * IN void *input: Thread data(upnp_timeout *) needed to send the renewal
* *
* Description: * Description:
* This is a thread function to send the renewal just before the * This is a thread function to send the renewal just before the
* subscription times out. * subscription times out.
* *
@@ -93,7 +93,7 @@ GenaAutoRenewSubscription( IN void *input )
} }
} }
if( send_callback ) { if( send_callback ) {
HandleLock(); HandleReadLock();
if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) { if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
free_upnp_timeout( event ); free_upnp_timeout( event );
@@ -113,14 +113,14 @@ GenaAutoRenewSubscription( IN void *input )
} }
/************************************************************************ /************************************************************************
* Function : ScheduleGenaAutoRenew * Function : ScheduleGenaAutoRenew
* *
* Parameters: * Parameters:
* IN int client_handle: Handle that also contains the subscription list * IN int client_handle: Handle that also contains the subscription list
* IN int TimeOut: The time out value of the subscription * IN int TimeOut: The time out value of the subscription
* IN client_subscription * sub: Subscription being renewed * IN client_subscription * sub: Subscription being renewed
* *
* Description: * Description:
* This function schedules a job to renew the subscription just before * This function schedules a job to renew the subscription just before
* time out. * time out.
* *
@@ -188,14 +188,14 @@ ScheduleGenaAutoRenew( IN int client_handle,
} }
/************************************************************************ /************************************************************************
* Function : gena_unsubscribe * Function : gena_unsubscribe
* *
* Parameters: * Parameters:
* IN char *url: Event URL of the service * IN char *url: Event URL of the service
* IN char *sid: The subcription ID. * IN char *sid: The subcription ID.
* OUT http_parser_t* response: The UNSUBCRIBE response from the device * OUT http_parser_t* response: The UNSUBCRIBE response from the device
* *
* Description: * Description:
* This function sends the UNSUBCRIBE gena request and recieves the * This function sends the UNSUBCRIBE gena request and recieves the
* response from the device and returns it as a parameter * response from the device and returns it as a parameter
* *
@@ -251,9 +251,9 @@ gena_unsubscribe( IN char *url,
} }
/************************************************************************ /************************************************************************
* Function : gena_subscribe * Function : gena_subscribe
* *
* Parameters: * Parameters:
* IN char *url: url of service to subscribe * IN char *url: url of service to subscribe
* INOUT int* timeout:subscription time desired (in secs) * INOUT int* timeout:subscription time desired (in secs)
* IN char* renewal_sid:for renewal, this contains a currently h * IN char* renewal_sid:for renewal, this contains a currently h
@@ -261,7 +261,7 @@ gena_unsubscribe( IN char *url,
* subscription, this must be NULL * subscription, this must be NULL
* OUT char** sid: SID returned by the subscription or renew msg * OUT char** sid: SID returned by the subscription or renew msg
* *
* Description: * Description:
* This function subscribes or renew subscription * This function subscribes or renew subscription
* *
* Returns: int * Returns: int
@@ -374,13 +374,13 @@ gena_subscribe( IN char *url,
} }
/************************************************************************ /************************************************************************
* Function : genaUnregisterClient * Function : genaUnregisterClient
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: Handle containing all the control * IN UpnpClient_Handle client_handle: Handle containing all the control
* point related information * point related information
* *
* Description: * Description:
* This function unsubcribes all the outstanding subscriptions and cleans * This function unsubcribes all the outstanding subscriptions and cleans
* the subscription list. This function is called when control point * the subscription list. This function is called when control point
* unregisters. * unregisters.
@@ -435,12 +435,12 @@ genaUnregisterClient( IN UpnpClient_Handle client_handle )
/************************************************************************ /************************************************************************
* Function : genaUnSubscribe * Function : genaUnSubscribe
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: UPnP client handle * IN UpnpClient_Handle client_handle: UPnP client handle
* IN SID in_sid: The subscription ID * IN SID in_sid: The subscription ID
* *
* Description: * Description:
* This function unsubscribes a SID. It first validates the SID and * This function unsubscribes a SID. It first validates the SID and
* client_handle,copies the subscription, sends UNSUBSCRIBE http request * client_handle,copies the subscription, sends UNSUBSCRIBE http request
* to service processes request and finally removes the subscription * to service processes request and finally removes the subscription
@@ -506,8 +506,8 @@ genaUnSubscribe( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : genaSubscribe * Function : genaSubscribe
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: * IN UpnpClient_Handle client_handle:
* IN char * PublisherURL: NULL Terminated, of the form : * IN char * PublisherURL: NULL Terminated, of the form :
* "http://134.134.156.80:4000/RedBulb/Event" * "http://134.134.156.80:4000/RedBulb/Event"
@@ -516,7 +516,7 @@ genaUnSubscribe( IN UpnpClient_Handle client_handle,
* by Service, -1 for infinite * by Service, -1 for infinite
* OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller * OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller
* *
* Description: * Description:
* This function subscribes to a PublisherURL ( also mentioned as EventURL * This function subscribes to a PublisherURL ( also mentioned as EventURL
* some places). It sends SUBSCRIBE http request to service processes * some places). It sends SUBSCRIBE http request to service processes
* request. Finally adds a Subscription to * request. Finally adds a Subscription to
@@ -543,10 +543,10 @@ genaSubscribe( IN UpnpClient_Handle client_handle,
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUBSCRIBE BEGIN" ); "GENA SUBSCRIBE BEGIN" );
HandleLock();
memset( out_sid, 0, sizeof( Upnp_SID ) ); memset( out_sid, 0, sizeof( Upnp_SID ) );
HandleReadLock();
// validate handle // validate handle
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) { if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
@@ -616,15 +616,15 @@ genaSubscribe( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : genaRenewSubscription * Function : genaRenewSubscription
* *
* Parameters: * Parameters:
* IN UpnpClient_Handle client_handle: Client handle * IN UpnpClient_Handle client_handle: Client handle
* IN const Upnp_SID in_sid: subscription ID * IN const Upnp_SID in_sid: subscription ID
* INOUT int * TimeOut: requested Duration, if -1, then "infinite". * INOUT int * TimeOut: requested Duration, if -1, then "infinite".
* in the OUT case: actual Duration granted * in the OUT case: actual Duration granted
* by Service, -1 for infinite * by Service, -1 for infinite
* *
* Description: * Description:
* This function renews a SID. It first validates the SID and * This function renews a SID. It first validates the SID and
* client_handle and copies the subscription. It sends RENEW * client_handle and copies the subscription. It sends RENEW
* (modified SUBSCRIBE) http request to service and processes * (modified SUBSCRIBE) http request to service and processes
@@ -724,14 +724,14 @@ genaRenewSubscription( IN UpnpClient_Handle client_handle,
/************************************************************************ /************************************************************************
* Function : gena_process_notification_event * Function : gena_process_notification_event
* *
* Parameters: * Parameters:
* IN SOCKINFO *info: Socket structure containing the device socket * IN SOCKINFO *info: Socket structure containing the device socket
* information * information
* IN http_message_t* event: The http message contains the GENA * IN http_message_t* event: The http message contains the GENA
* notification * notification
* *
* Description: * Description:
* This function processes NOTIFY events that are sent by devices. * This function processes NOTIFY events that are sent by devices.
* called by genacallback() * called by genacallback()
* *
@@ -881,3 +881,4 @@ gena_process_notification_event( IN SOCKINFO * info,
#endif // INCLUDE_CLIENT_APIS #endif // INCLUDE_CLIENT_APIS
#endif // EXCLUDE_GENA #endif // EXCLUDE_GENA

View File

@@ -365,7 +365,7 @@ genaNotifyThread( IN void *input )
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
ThreadPoolJob job; ThreadPoolJob job;
HandleLock(); HandleReadLock();
//validate context //validate context
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) { if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {

View File

@@ -349,7 +349,7 @@ http_SendMessage( IN SOCKINFO * info,
filename = ( char * )va_arg( argp, char * ); filename = ( char * )va_arg( argp, char * );
if( Instr && Instr->IsVirtualFile ) if( Instr && Instr->IsVirtualFile )
Fp = virtualDirCallback.open( filename, UPNP_READ ); Fp = (virtualDirCallback.open)( filename, UPNP_READ );
else else
Fp = fopen( filename, "rb" ); Fp = fopen( filename, "rb" );
@@ -475,11 +475,13 @@ http_SendMessage( IN SOCKINFO * info,
buf_length = ( size_t ) va_arg( argp, size_t ); buf_length = ( size_t ) va_arg( argp, size_t );
if( buf_length > 0 ) { if( buf_length > 0 ) {
num_written = sock_write( info, buf, buf_length, TimeOut ); num_written = sock_write( info, buf, buf_length, TimeOut );
UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
">>> (SENT) >>>\n"
"%.*s\nbuf_length=%d, num_written=%d\n"
"------------\n",
(int)buf_length, buf, (int)buf_length, num_written );
if( ( size_t ) num_written != buf_length ) if( ( size_t ) num_written != buf_length )
goto end; goto end;
UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
">>> (SENT) >>>\n%.*s\n------------\n",
( int )buf_length, buf );
} }
} }
} }

View File

@@ -880,22 +880,24 @@ GetNextRange( char **SrcRangeStr,
off_t *FirstByte, off_t *FirstByte,
off_t *LastByte ) off_t *LastByte )
{ {
char *Ptr, char *Ptr;
*Tok; char *Tok;
int i, int i;
F = -1, int64_t F = -1;
L = -1; int64_t L = -1;
int Is_Suffix_byte_Range = 1; int Is_Suffix_byte_Range = 1;
if( *SrcRangeStr == NULL ) if( *SrcRangeStr == NULL ) {
return -1; return -1;
}
Tok = StrTok( SrcRangeStr, "," ); Tok = StrTok( SrcRangeStr, "," );
if( ( Ptr = strstr( Tok, "-" ) ) == NULL ) if( ( Ptr = strstr( Tok, "-" ) ) == NULL ) {
return -1; return -1;
}
*Ptr = ' '; *Ptr = ' ';
sscanf( Tok, "%d%d", &F, &L ); sscanf( Tok, "%"SCNd64"%"SCNd64, &F, &L );
if( F == -1 || L == -1 ) { if( F == -1 || L == -1 ) {
*Ptr = '-'; *Ptr = '-';
@@ -910,16 +912,15 @@ GetNextRange( char **SrcRangeStr,
} }
if( Is_Suffix_byte_Range ) { if( Is_Suffix_byte_Range ) {
*FirstByte = L; *FirstByte = (off_t)L;
*LastByte = F; *LastByte = (off_t)F;
return 1; return 1;
} }
} }
*FirstByte = (off_t)F;
*LastByte = (off_t)L;
*FirstByte = F;
*LastByte = L;
return 1; return 1;
} }
/************************************************************************ /************************************************************************
@@ -1531,7 +1532,7 @@ http_RecvPostMessage( http_parser_t * parser,
if( Instr && Instr->IsVirtualFile ) { if( Instr && Instr->IsVirtualFile ) {
Fp = virtualDirCallback.open( filename, UPNP_WRITE ); Fp = (virtualDirCallback.open)( filename, UPNP_WRITE );
if( Fp == NULL ) { if( Fp == NULL ) {
return HTTP_INTERNAL_SERVER_ERROR; return HTTP_INTERNAL_SERVER_ERROR;
} }

View File

@@ -555,7 +555,7 @@ parse_hostport( const char *in,
int begin_port; int begin_port;
int hostport_size = 0; int hostport_size = 0;
int host_size = 0; int host_size = 0;
#ifndef WIN32 #if !defined(WIN32) && !defined(__OSX__)
char temp_hostbyname_buff[BUFFER_SIZE]; char temp_hostbyname_buff[BUFFER_SIZE];
struct hostent h_buf; struct hostent h_buf;
#endif #endif
@@ -626,54 +626,61 @@ parse_hostport( const char *in,
// TODO: Use autoconf to discover this rather than the // TODO: Use autoconf to discover this rather than the
// platform-specific stuff below // platform-specific stuff below
#if defined(WIN32) || defined(__CYGWIN__) #if defined(WIN32) || defined(__CYGWIN__)
h=gethostbyname(temp_host_name); h = gethostbyname(temp_host_name);
#elif defined(SPARC_SOLARIS) #elif defined(SPARC_SOLARIS)
errCode = gethostbyname_r( temp_host_name, errCode = gethostbyname_r(
&h, temp_host_name,
temp_hostbyname_buff, &h,
BUFFER_SIZE, &errcode ); temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
#elif defined(__FreeBSD__) && __FreeBSD_version < 601103 #elif defined(__FreeBSD__) && __FreeBSD_version < 601103
h = lwres_gethostbyname_r( temp_host_name, h = lwres_gethostbyname_r(
&h_buf, temp_host_name,
temp_hostbyname_buff, &h_buf,
BUFFER_SIZE, &errcode ); temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
if ( h == NULL ) { if ( h == NULL ) {
errCode = 1; errCode = 1;
}
#elif defined(__OSX__)
h = gethostbyname(temp_host_name);
if ( h == NULL ) {
errCode = 1;
} }
#elif defined(__linux__) #elif defined(__linux__)
errCode = gethostbyname_r( temp_host_name, errCode = gethostbyname_r(
&h_buf, temp_host_name,
temp_hostbyname_buff, &h_buf,
BUFFER_SIZE, &h, &errcode ); temp_hostbyname_buff,
BUFFER_SIZE, &h, &errcode );
#else #else
{ {
struct addrinfo hints, *res, *res0; struct addrinfo hints, *res, *res0;
h = NULL; h = NULL;
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_INET; hints.ai_family = PF_INET;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
errCode = getaddrinfo(temp_host_name, "http", &hints, &res0); errCode = getaddrinfo(temp_host_name, "http", &hints, &res0);
if (!errCode) { if (!errCode) {
for (res = res0; res; res = res->ai_next) { for (res = res0; res; res = res->ai_next) {
if (res->ai_family == PF_INET && if (res->ai_family == PF_INET &&
res->ai_addr->sa_family == AF_INET) res->ai_addr->sa_family == AF_INET)
{ {
h = &h_buf; h = &h_buf;
h->h_addrtype = res->ai_addr->sa_family; h->h_addrtype = res->ai_addr->sa_family;
h->h_length = 4; h->h_length = 4;
h->h_addr = (void *) temp_hostbyname_buff; h->h_addr = (void *) temp_hostbyname_buff;
*(struct in_addr *)h->h_addr = *(struct in_addr *)h->h_addr =
((struct sockaddr_in *)res->ai_addr)->sin_addr; ((struct sockaddr_in *)res->ai_addr)->sin_addr;
break; break;
} }
} }
freeaddrinfo(res0); freeaddrinfo(res0);
} }
} }
#endif #endif
if( errCode == 0 ) { if( errCode == 0 ) {
if( h ) { if( h ) {
if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) { if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {

View File

@@ -261,18 +261,18 @@
/** @name Other debugging features /** @name Other debugging features
The UPnP SDK contains other features to aid in debugging: The UPnP SDK contains other features to aid in debugging:
see <upnp/upnpdebug.h> see <upnp/inc/upnpdebug.h>
*/ */
#define DEBUG_ALL 1 #define DEBUG_ALL 1
#define DEBUG_SSDP 0 #define DEBUG_SSDP 0
#define DEBUG_SOAP 0 #define DEBUG_SOAP 0
#define DEBUG_GENA 0 #define DEBUG_GENA 0
#define DEBUG_TPOOL 0 #define DEBUG_TPOOL 0
#define DEBUG_MSERV 0 #define DEBUG_MSERV 0
#define DEBUG_DOM 0 #define DEBUG_DOM 0
#define DEBUG_HTTP 0 #define DEBUG_HTTP 0
#define DEBUG_API 0 #define DEBUG_API 0
//@} // Compile time configuration options //@} // Compile time configuration options

View File

@@ -98,18 +98,25 @@ struct Handle_Info
int aliasInstalled; // 0 = not installed; otherwise installed int aliasInstalled; // 0 = not installed; otherwise installed
}; };
extern ithread_mutex_t GlobalHndMutex; extern ithread_rwlock_t GlobalHndRWLock;
Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo); Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo);
#define HandleLock() \ #define HandleLock() HandleWriteLock()
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying Lock"); \
ithread_mutex_lock(&GlobalHndMutex); \ #define HandleWriteLock() \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "LOCK"); UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a write lock"); \
ithread_rwlock_wrlock(&GlobalHndRWLock); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Write lock acquired");
#define HandleReadLock() \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a read lock"); \
ithread_rwlock_rdlock(&GlobalHndRWLock); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Read lock acquired");
#define HandleUnlock() \ #define HandleUnlock() \
UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \ UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \
ithread_mutex_unlock(&GlobalHndMutex); \ ithread_rwlock_unlock(&GlobalHndRWLock); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlock"); UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlocked rwlock");
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out, Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
struct Handle_Info **HndInfo); struct Handle_Info **HndInfo);

View File

@@ -125,7 +125,7 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
// we are assuming that there can be only one client supported at a time // we are assuming that there can be only one client supported at a time
HandleLock(); HandleReadLock();
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
@@ -538,8 +538,7 @@ SearchByTarget( IN int Mx,
if( ReqBuf == NULL ) if( ReqBuf == NULL )
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n");
">>> SSDP SEND >>>\n%s\n", ReqBuf );
timeTillRead = Mx; timeTillRead = Mx;

View File

@@ -1,30 +1,30 @@
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2000-2003 Intel Corporation // Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: // modification, are permitted provided that the following conditions are met:
// //
// * Redistributions of source code must retain the above copyright notice, // * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. // this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, // * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation // this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. // and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors // * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software // may be used to endorse or promote products derived from this software
// without specific prior written permission. // without specific prior written permission.
// //
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@@ -83,11 +83,11 @@ advertiseAndReplyThread( IN void *data )
/************************************************************************ /************************************************************************
* Function : ssdp_handle_device_request * Function : ssdp_handle_device_request
* *
* Parameters: * Parameters:
* IN http_message_t* hmsg: SSDP search request from the control point * IN http_message_t* hmsg: SSDP search request from the control point
* IN struct sockaddr_in* dest_addr: The address info of control point * IN struct sockaddr_in* dest_addr: The address info of control point
* *
* Description: * Description:
* This function handles the search request. It do the sanity checks of * This function handles the search request. It do the sanity checks of
* the request and then schedules a thread to send a random time reply ( * the request and then schedules a thread to send a random time reply (
* random within maximum time given by the control point to reply). * random within maximum time given by the control point to reply).
@@ -194,15 +194,15 @@ ssdp_handle_device_request( IN http_message_t * hmsg,
#endif #endif
/************************************************************************ /************************************************************************
* Function : NewRequestHandler * Function : NewRequestHandler
* *
* Parameters: * Parameters:
* IN struct sockaddr_in * DestAddr: Ip address, to send the reply. * IN struct sockaddr_in * DestAddr: Ip address, to send the reply.
* IN int NumPacket: Number of packet to be sent. * IN int NumPacket: Number of packet to be sent.
* IN char **RqPacket:Number of packet to be sent. * IN char **RqPacket:Number of packet to be sent.
* *
* Description: * Description:
* This function works as a request handler which passes the HTTP * This function works as a request handler which passes the HTTP
* request string to multicast channel then * request string to multicast channel then
* *
* Returns: void * * Returns: void *
@@ -242,7 +242,7 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
// "If a multicast resource would send a response(s) to any copy of the // "If a multicast resource would send a response(s) to any copy of the
// request, it SHOULD send its response(s) to each copy of the request // request, it SHOULD send its response(s) to each copy of the request
// it receives. It MUST NOT repeat its response(s) per copy of the // it receives. It MUST NOT repeat its response(s) per copy of the
// reuqest." // request."
// //
// http://www.upnp.org/download/draft-goland-http-udp-04.txt // http://www.upnp.org/download/draft-goland-http-udp-04.txt
// //
@@ -266,24 +266,24 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
} }
/************************************************************************ /************************************************************************
* Function : CreateServiceRequestPacket * Function : CreateServiceRequestPacket
* *
* Parameters: * Parameters:
* IN int msg_type : type of the message ( Search Reply, Advertisement * IN int msg_type : type of the message ( Search Reply, Advertisement
* or Shutdown ) * or Shutdown )
* IN char * nt : ssdp type * IN char * nt : ssdp type
* IN char * usn : unique service name ( go in the HTTP Header) * IN char * usn : unique service name ( go in the HTTP Header)
* IN char * location :Location URL. * IN char * location :Location URL.
* IN int duration :Service duration in sec. * IN int duration :Service duration in sec.
* OUT char** packet :Output buffer filled with HTTP statement. * OUT char** packet :Output buffer filled with HTTP statement.
* *
* Description: * Description:
* This function creates a HTTP request packet. Depending * This function creates a HTTP request packet. Depending
* on the input parameter it either creates a service advertisement * on the input parameter it either creates a service advertisement
* request or service shutdown request etc. * request or service shutdown request etc.
* *
* Returns: void * Returns: void
* *
***************************************************************************/ ***************************************************************************/
void void
CreateServicePacket( IN int msg_type, CreateServicePacket( IN int msg_type,
@@ -358,9 +358,9 @@ CreateServicePacket( IN int msg_type,
} }
/************************************************************************ /************************************************************************
* Function : DeviceAdvertisement * Function : DeviceAdvertisement
* *
* Parameters: * Parameters:
* IN char * DevType : type of the device * IN char * DevType : type of the device
* IN int RootDev: flag to indicate if the device is root device * IN int RootDev: flag to indicate if the device is root device
* IN char * nt : ssdp type * IN char * nt : ssdp type
@@ -368,7 +368,7 @@ CreateServicePacket( IN int msg_type,
* IN char * location :Location URL. * IN char * location :Location URL.
* IN int duration :Service duration in sec. * IN int duration :Service duration in sec.
* *
* Description: * Description:
* This function creates the device advertisement request based on * This function creates the device advertisement request based on
* the input parameter, and send it to the multicast channel. * the input parameter, and send it to the multicast channel.
* *
@@ -444,9 +444,9 @@ DeviceAdvertisement( IN char *DevType,
} }
/************************************************************************ /************************************************************************
* Function : SendReply * Function : SendReply
* *
* Parameters: * Parameters:
* IN struct sockaddr_in * DestAddr:destination IP address. * IN struct sockaddr_in * DestAddr:destination IP address.
* IN char *DevType: Device type * IN char *DevType: Device type
* IN int RootDev: 1 means root device 0 means embedded device. * IN int RootDev: 1 means root device 0 means embedded device.
@@ -455,7 +455,7 @@ DeviceAdvertisement( IN char *DevType,
* IN int Duration :Life time of this device. * IN int Duration :Life time of this device.
* IN int ByType: * IN int ByType:
* *
* Description: * Description:
* This function creates the reply packet based on the input parameter, * This function creates the reply packet based on the input parameter,
* and send it to the client addesss given in its input parameter DestAddr. * and send it to the client addesss given in its input parameter DestAddr.
* *
@@ -521,17 +521,16 @@ SendReply( IN struct sockaddr_in *DestAddr,
} }
/************************************************************************ /************************************************************************
* Function : DeviceReply * Function : DeviceReply
* *
* Parameters: * Parameters:
* IN struct sockaddr_in * DestAddr:destination IP address. * IN struct sockaddr_in * DestAddr:destination IP address.
* IN char *DevType: Device type * IN char *DevType: Device type
* IN int RootDev: 1 means root device 0 means embedded device. * IN int RootDev: 1 means root device 0 means embedded device.
* IN char * Udn: Device UDN * IN char * Udn: Device UDN
* IN char * Location: Location of Device description document. * IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device. * IN int Duration :Life time of this device.
* Description:
* Description:
* This function creates the reply packet based on the input parameter, * This function creates the reply packet based on the input parameter,
* and send it to the client address given in its input parameter DestAddr. * and send it to the client address given in its input parameter DestAddr.
* *
@@ -600,18 +599,16 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
} }
/************************************************************************ /************************************************************************
* Function : ServiceAdvertisement * Function : ServiceAdvertisement
* *
* Parameters: * Parameters:
* IN char * Udn: Device UDN * IN char * Udn: Device UDN
* IN char *ServType: Service Type. * IN char *ServType: Service Type.
* IN char * Location: Location of Device description document. * IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device. * IN int Duration :Life time of this device.
* Description:
* Description: * This function creates the advertisement packet based
* This function creates the advertisement packet based
* on the input parameter, and send it to the multicast channel. * on the input parameter, and send it to the multicast channel.
* *
* Returns: int * Returns: int
* UPNP_E_SUCCESS if successful else appropriate error * UPNP_E_SUCCESS if successful else appropriate error
@@ -648,19 +645,17 @@ ServiceAdvertisement( IN char *Udn,
} }
/************************************************************************ /************************************************************************
* Function : ServiceReply * Function : ServiceReply
* *
* Parameters: * Parameters:
* IN struct sockaddr_in *DestAddr: * IN struct sockaddr_in *DestAddr:
* IN char * Udn: Device UDN * IN char * Udn: Device UDN
* IN char *ServType: Service Type. * IN char *ServType: Service Type.
* IN char * Location: Location of Device description document. * IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device. * IN int Duration :Life time of this device.
* Description:
* Description:
* This function creates the advertisement packet based * This function creates the advertisement packet based
* on the input parameter, and send it to the multicast channel. * on the input parameter, and send it to the multicast channel.
* *
* Returns: int * Returns: int
* UPNP_E_SUCCESS if successful else appropriate error * UPNP_E_SUCCESS if successful else appropriate error
@@ -693,15 +688,14 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
} }
/************************************************************************ /************************************************************************
* Function : ServiceShutdown * Function : ServiceShutdown
* *
* Parameters: * Parameters:
* IN char * Udn: Device UDN * IN char * Udn: Device UDN
* IN char *ServType: Service Type. * IN char *ServType: Service Type.
* IN char * Location: Location of Device description document. * IN char * Location: Location of Device description document.
* IN int Duration :Service duration in sec. * IN int Duration :Service duration in sec.
* Description:
* Description:
* This function creates a HTTP service shutdown request packet * This function creates a HTTP service shutdown request packet
* and sent it to the multicast channel through RequestHandler. * and sent it to the multicast channel through RequestHandler.
* *
@@ -739,16 +733,16 @@ ServiceShutdown( IN char *Udn,
} }
/************************************************************************ /************************************************************************
* Function : DeviceShutdown * Function : DeviceShutdown
* *
* Parameters: * Parameters:
* IN char *DevType: Device Type. * IN char *DevType: Device Type.
* IN int RootDev:1 means root device. * IN int RootDev:1 means root device.
* IN char * Udn: Device UDN * IN char * Udn: Device UDN
* IN char * Location: Location URL * IN char * Location: Location URL
* IN int Duration :Device duration in sec. * IN int Duration :Device duration in sec.
* *
* Description: * Description:
* This function creates a HTTP device shutdown request packet * This function creates a HTTP device shutdown request packet
* and sent it to the multicast channel through RequestHandler. * and sent it to the multicast channel through RequestHandler.
* *
@@ -821,3 +815,4 @@ DeviceShutdown( IN char *DevType,
#endif // EXCLUDE_SSDP #endif // EXCLUDE_SSDP
#endif // INCLUDE_DEVICE_APIS #endif // INCLUDE_DEVICE_APIS

View File

@@ -72,11 +72,13 @@ CLIENTONLY( SOCKET gSsdpReqSocket = 0;
#if EXCLUDE_SSDP == 0 #if EXCLUDE_SSDP == 0
/************************************************************************ /************************************************************************
* Function : AdvertiseAndReply * Function : AdvertiseAndReply
* *
* Parameters: * Parameters:
* IN int AdFlag: -1 = Send shutdown, 0 = send reply, * IN int AdFlag:
* 1 = Send Advertisement * -1 = Send shutdown,
* 0 = send reply,
* 1 = Send Advertisement
* IN UpnpDevice_Handle Hnd: Device handle * IN UpnpDevice_Handle Hnd: Device handle
* IN enum SsdpSearchType SearchType:Search type for sending replies * IN enum SsdpSearchType SearchType:Search type for sending replies
* IN struct sockaddr_in *DestAddr:Destination address * IN struct sockaddr_in *DestAddr:Destination address
@@ -85,7 +87,7 @@ CLIENTONLY( SOCKET gSsdpReqSocket = 0;
* IN char *ServiceType:Service type * IN char *ServiceType:Service type
* IN int Exp:Advertisement age * IN int Exp:Advertisement age
* *
* Description: * Description:
* This function sends SSDP advertisements, replies and shutdown messages. * This function sends SSDP advertisements, replies and shutdown messages.
* *
* Returns: int * Returns: int
@@ -120,16 +122,13 @@ int AdvertiseAndReply( IN int AdFlag,
"Inside AdvertiseAndReply with AdFlag = %d\n", "Inside AdvertiseAndReply with AdFlag = %d\n",
AdFlag ); AdFlag );
HandleLock(); // Use a read lock
HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) { if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock(); HandleUnlock();
return UPNP_E_INVALID_HANDLE; return UPNP_E_INVALID_HANDLE;
} }
defaultExp = SInfo->MaxAge; 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; nodeList = NULL;
//get server info //get server info
@@ -150,15 +149,13 @@ int AdvertiseAndReply( IN int AdFlag,
} }
dbgStr = ixmlNode_getNodeName( tmpNode ); dbgStr = ixmlNode_getNodeName( tmpNode );
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Extracting device type once for %s\n", "Extracting device type once for %s\n", dbgStr );
dbgStr ); // extract device type
// extract device type ixmlNodeList_free( nodeList );
ixmlNodeList_free( nodeList );
nodeList = NULL; nodeList = NULL;
nodeList = nodeList = ixmlElement_getElementsByTagName(
ixmlElement_getElementsByTagName( ( IXML_Element * ) tmpNode, ( IXML_Element * ) tmpNode, "deviceType" );
"deviceType" );
if( nodeList == NULL ) { if( nodeList == NULL ) {
continue; continue;
} }
@@ -166,7 +163,6 @@ int AdvertiseAndReply( IN int AdFlag,
dbgStr = ixmlNode_getNodeName( tmpNode ); dbgStr = ixmlNode_getNodeName( tmpNode );
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Extracting UDN for %s\n", dbgStr ); "Extracting UDN for %s\n", dbgStr );
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Extracting device type\n" ); "Extracting device type\n" );
@@ -236,13 +232,12 @@ int AdvertiseAndReply( IN int AdFlag,
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Sending UDNStr = %s \n", UDNstr ); "Sending UDNStr = %s \n", UDNstr );
if( AdFlag ) { if( AdFlag ) {
// send the device advertisement // send the device advertisement
if( AdFlag == 1 ) { if( AdFlag == 1 ) {
DeviceAdvertisement( devType, i == 0, DeviceAdvertisement( devType, i == 0,
UDNstr, SInfo->DescURL, Exp ); UDNstr, SInfo->DescURL, Exp );
} else // AdFlag == -1 } else { // AdFlag == -1
{
DeviceShutdown( devType, i == 0, UDNstr, DeviceShutdown( devType, i == 0, UDNstr,
SERVER, SInfo->DescURL, Exp ); SERVER, SInfo->DescURL, Exp );
} }
@@ -324,8 +319,9 @@ int AdvertiseAndReply( IN int AdFlag,
} }
for( j = 0;; j++ ) { for( j = 0;; j++ ) {
tmpNode = ixmlNodeList_item( nodeList, j ); tmpNode = ixmlNodeList_item( nodeList, j );
if( tmpNode == NULL ) if( tmpNode == NULL ) {
break; break;
}
ixmlNodeList_free( tmpNodeList ); ixmlNodeList_free( tmpNodeList );
tmpNodeList = NULL; tmpNodeList = NULL;
@@ -334,7 +330,7 @@ int AdvertiseAndReply( IN int AdFlag,
if( tmpNodeList == NULL ) { if( tmpNodeList == NULL ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"ServiceType not found \n" ); "ServiceType not found \n" );
continue; continue;
} }
tmpNode2 = ixmlNodeList_item( tmpNodeList, 0 ); tmpNode2 = ixmlNodeList_item( tmpNodeList, 0 );
if( tmpNode2 == NULL ) { if( tmpNode2 == NULL ) {
@@ -367,26 +363,21 @@ int AdvertiseAndReply( IN int AdFlag,
} else { } else {
switch ( SearchType ) { switch ( SearchType ) {
case SSDP_ALL: case SSDP_ALL:
{ ServiceReply( DestAddr, servType,
ServiceReply( DestAddr, servType, UDNstr, SInfo->DescURL,
UDNstr, SInfo->DescURL, defaultExp );
defaultExp ); break;
break;
}
case SSDP_SERVICE: case SSDP_SERVICE:
{ if( ServiceType != NULL ) {
if( ServiceType != NULL ) { if( !strncasecmp( ServiceType,
if( !strncasecmp( ServiceType, servType,
servType, strlen( ServiceType ) ) ) {
strlen( ServiceType ) ) ) ServiceReply( DestAddr, servType,
{ UDNstr, SInfo->DescURL,
ServiceReply( DestAddr, servType, defaultExp );
UDNstr, SInfo->DescURL,
defaultExp );
}
} }
break;
} }
break;
default: default:
break; break;
} // switch(SearchType) } // switch(SearchType)
@@ -401,7 +392,7 @@ int AdvertiseAndReply( IN int AdFlag,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__, UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting AdvertiseAndReply : \n" ); "Exiting AdvertiseAndReply : \n" );
HandleUnlock( ); HandleUnlock();
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
@@ -411,12 +402,12 @@ int AdvertiseAndReply( IN int AdFlag,
#endif #endif
/************************************************************************ /************************************************************************
* Function : Make_Socket_NoBlocking * Function : Make_Socket_NoBlocking
*
* Parameters:
* IN int sock: socket
* *
* Description: * Parameters:
* IN int sock: socket
*
* Description:
* This function makes socket non-blocking. * This function makes socket non-blocking.
* *
* Returns: int * Returns: int
@@ -440,19 +431,19 @@ Make_Socket_NoBlocking( int sock )
} }
/************************************************************************ /************************************************************************
* Function : unique_service_name * Function : unique_service_name
*
* Parameters:
* IN char *cmd: Service Name string
* OUT SsdpEvent *Evt: The SSDP event structure partially filled
* by all the function.
* *
* Description: * Parameters:
* IN char *cmd: Service Name string
* OUT SsdpEvent *Evt: The SSDP event structure partially filled
* by all the function.
*
* Description:
* This function fills the fields of the event structure like DeviceType, * This function fills the fields of the event structure like DeviceType,
* Device UDN and Service Type * Device UDN and Service Type
* *
* Returns: int * Returns: int
* 0 if successful else -1 * 0 if successful else -1
***************************************************************************/ ***************************************************************************/
int int
unique_service_name( IN char *cmd, unique_service_name( IN char *cmd,
@@ -535,13 +526,13 @@ unique_service_name( IN char *cmd,
} }
/************************************************************************ /************************************************************************
* Function : ssdp_request_type1 * Function : ssdp_request_type1
* *
* Parameters: * Parameters:
* IN char *cmd: command came in the ssdp request * IN char *cmd: command came in the ssdp request
* *
* Description: * Description:
* This function figures out the type of the SSDP search in the * This function figures out the type of the SSDP search in the
* in the request. * in the request.
* *
* Returns: enum SsdpSearchType * Returns: enum SsdpSearchType
@@ -571,16 +562,16 @@ ssdp_request_type1( IN char *cmd )
} }
/************************************************************************ /************************************************************************
* Function : ssdp_request_type * Function : ssdp_request_type
* *
* Parameters: * Parameters:
* IN char *cmd: command came in the ssdp request * IN char *cmd: command came in the ssdp request
* OUT SsdpEvent *Evt: The event structure partially filled by * OUT SsdpEvent *Evt: The event structure partially filled by
* this function. * this function.
* *
* Description: * Description:
* This function starts filling the SSDP event structure based upon the * This function starts filling the SSDP event structure based upon the
* request received. * request received.
* *
* Returns: int * Returns: int
* 0 on success; -1 on error * 0 on success; -1 on error
@@ -602,17 +593,17 @@ ssdp_request_type( IN char *cmd,
} }
/************************************************************************ /************************************************************************
* Function : free_ssdp_event_handler_data * Function : free_ssdp_event_handler_data
* *
* Parameters: * Parameters:
* IN void *the_data: ssdp_thread_data structure. This structure contains * IN void *the_data: ssdp_thread_data structure. This structure contains
* SSDP request message. * SSDP request message.
* *
* Description: * Description:
* This function frees the ssdp request * This function frees the ssdp request
* *
* Returns: VOID * Returns: VOID
* *
***************************************************************************/ ***************************************************************************/
static void static void
free_ssdp_event_handler_data( void *the_data ) free_ssdp_event_handler_data( void *the_data )
@@ -629,13 +620,13 @@ free_ssdp_event_handler_data( void *the_data )
} }
/************************************************************************ /************************************************************************
* Function : valid_ssdp_msg * Function : valid_ssdp_msg
* *
* Parameters: * Parameters:
* IN void *the_data: ssdp_thread_data structure. This structure contains * IN void *the_data: ssdp_thread_data structure. This structure contains
* SSDP request message. * SSDP request message.
* *
* Description: * Description:
* This function do some quick checking of the ssdp msg * This function do some quick checking of the ssdp msg
* *
* Returns: xboolean * Returns: xboolean
@@ -670,14 +661,14 @@ valid_ssdp_msg( IN http_message_t * hmsg )
} }
/************************************************************************ /************************************************************************
* Function : start_event_handler * Function : start_event_handler
* *
* Parameters: * Parameters:
* IN void *the_data: ssdp_thread_data structure. This structure contains * IN void *the_data: ssdp_thread_data structure. This structure contains
* SSDP request message. * SSDP request message.
* *
* Description: * Description:
* This function parses the message and dispatches it to a handler * This function parses the message and dispatches it to a handler
* which handles the ssdp request msg * which handles the ssdp request msg
* *
* Returns: int * Returns: int
@@ -722,17 +713,17 @@ start_event_handler( void *Data )
} }
/************************************************************************ /************************************************************************
* Function : ssdp_event_handler_thread * Function : ssdp_event_handler_thread
* *
* Parameters: * Parameters:
* IN void *the_data: ssdp_thread_data structure. This structure contains * IN void *the_data: ssdp_thread_data structure. This structure contains
* SSDP request message. * SSDP request message.
* *
* Description: * Description:
* This function is a thread that handles SSDP requests. * This function is a thread that handles SSDP requests.
* *
* Returns: void * Returns: void
* *
***************************************************************************/ ***************************************************************************/
static void static void
ssdp_event_handler_thread( void *the_data ) ssdp_event_handler_thread( void *the_data )
@@ -757,16 +748,16 @@ ssdp_event_handler_thread( void *the_data )
} }
/************************************************************************ /************************************************************************
* Function : readFromSSDPSocket * Function : readFromSSDPSocket
* *
* Parameters: * Parameters:
* IN SOCKET socket: SSDP socket * IN SOCKET socket: SSDP socket
* *
* Description: * Description:
* This function reads the data from the ssdp socket. * This function reads the data from the ssdp socket.
* *
* Returns: void * Returns: void
* *
***************************************************************************/ ***************************************************************************/
void void
readFromSSDPSocket( SOCKET socket ) readFromSSDPSocket( SOCKET socket )
@@ -819,18 +810,20 @@ readFromSSDPSocket( SOCKET socket )
( struct sockaddr * )&clientAddr, &socklen ); ( struct sockaddr * )&clientAddr, &socklen );
if( byteReceived > 0 ) { if( byteReceived > 0 ) {
requestBuf[byteReceived] = '\0'; requestBuf[byteReceived] = '\0';
UpnpPrintf( UPNP_INFO, SSDP, UpnpPrintf( UPNP_INFO, SSDP,
__FILE__, __LINE__, __FILE__, __LINE__,
"Received response !!! " "Start of received response ----------------------------------------------------\n"
"%s From host %s \n", "%s\n"
requestBuf, "End of received response ------------------------------------------------------\n"
inet_ntoa( clientAddr.sin_addr ) ); "From host %s\n",
requestBuf,
inet_ntoa( clientAddr.sin_addr ) );
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__, UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
"Received multicast packet:" "Start of received multicast packet --------------------------------------------\n"
"\n %s\n", requestBuf ); "%s\n"
"End of received multicast packet ----------------------------------------------\n",
requestBuf );
//add thread pool job to handle request //add thread pool job to handle request
if( data != NULL ) { if( data != NULL ) {
data->parser.msg.msg.length += byteReceived; data->parser.msg.msg.length += byteReceived;
@@ -853,12 +846,12 @@ readFromSSDPSocket( SOCKET socket )
/************************************************************************ /************************************************************************
* Function : get_ssdp_sockets * Function : get_ssdp_sockets
* *
* Parameters: * Parameters:
* OUT MiniServerSockArray *out: Arrays of SSDP sockets * OUT MiniServerSockArray *out: Arrays of SSDP sockets
* *
* Description: * Description:
* This function creates the ssdp sockets. It set their option to listen * This function creates the ssdp sockets. It set their option to listen
* for multicast traffic. * for multicast traffic.
* *
* Returns: int * Returns: int
@@ -869,8 +862,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
{ {
SOCKET ssdpSock; SOCKET ssdpSock;
CLIENTONLY( SOCKET ssdpReqSock; CLIENTONLY( SOCKET ssdpReqSock; )
)
int onOff = 1; int onOff = 1;
u_char ttl = 4; u_char ttl = 4;
struct ip_mreq ssdpMcastAddr; struct ip_mreq ssdpMcastAddr;
@@ -878,32 +870,31 @@ get_ssdp_sockets( MiniServerSockArray * out )
int option = 1; int option = 1;
struct in_addr addr; struct in_addr addr;
CLIENTONLY( if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) CLIENTONLY(
== UPNP_INVALID_SOCKET ) { if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in socket operation !!!\n" ); "Error in socket operation !!!\n" );
return UPNP_E_OUTOF_SOCKET;}
setsockopt( ssdpReqSock,
IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
// just do it, regardless if fails or not.
Make_Socket_NoBlocking( ssdpReqSock ); gSsdpReqSocket = ssdpReqSock; ) //CLIENTONLY
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
== UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in socket operation !!!\n" );
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
return UPNP_E_OUTOF_SOCKET; return UPNP_E_OUTOF_SOCKET;
} }
setsockopt( ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
// just do it, regardless if fails or not.
Make_Socket_NoBlocking( ssdpReqSock );
gSsdpReqSocket = ssdpReqSock; )
// END CLIENTONLY
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in socket operation !!!\n" );
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
return UPNP_E_OUTOF_SOCKET;
}
onOff = 1; onOff = 1;
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR, if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
( char * )&onOff, sizeof( onOff ) ) != 0 ) { ( char * )&onOff, sizeof( onOff ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in set reuse addr !!!\n" ); "Error in set reuse addr !!!\n" );
@@ -916,8 +907,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
#ifdef __FreeBSD__ #ifdef __FreeBSD__
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT, if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
( char * )&onOff, sizeof( onOff ) ) != 0 ) { ( char * )&onOff, sizeof( onOff ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in set reuse port !!!\n" ); "Error in set reuse port !!!\n" );
@@ -934,9 +924,8 @@ get_ssdp_sockets( MiniServerSockArray * out )
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST); // ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY ); ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );
ssdpAddr.sin_port = htons( SSDP_PORT ); ssdpAddr.sin_port = htons( SSDP_PORT );
if( bind if( bind( ssdpSock, ( struct sockaddr * )&ssdpAddr,
( ssdpSock, ( struct sockaddr * )&ssdpAddr, sizeof( ssdpAddr ) ) != 0 ) {
sizeof( ssdpAddr ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in binding !!!\n" ); "Error in binding !!!\n" );
@@ -951,8 +940,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST ); ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP ); ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP, if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
( char * )&ssdpMcastAddr, ( char * )&ssdpMcastAddr, sizeof( struct ip_mreq ) ) != 0 ) {
sizeof( struct ip_mreq ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in joining" " multicast group !!!\n" ); "Error in joining" " multicast group !!!\n" );
@@ -966,8 +954,8 @@ get_ssdp_sockets( MiniServerSockArray * out )
/* Set multicast interface. */ /* Set multicast interface. */
memset( ( void * )&addr, 0, sizeof( struct in_addr )); memset( ( void * )&addr, 0, sizeof( struct in_addr ));
addr.s_addr = inet_addr(LOCAL_HOST); addr.s_addr = inet_addr(LOCAL_HOST);
if (setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF, if ( setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&addr, sizeof addr) != 0) { (char *)&addr, sizeof addr) != 0) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"Couldn't set multicast interface.\n" ); "Couldn't set multicast interface.\n" );
/* This is probably not a critical error, so let's continue. */ /* This is probably not a critical error, so let's continue. */
@@ -977,7 +965,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
setsockopt( ssdpSock, IPPROTO_IP, setsockopt( ssdpSock, IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) ); IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST, if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
( char * )&option, sizeof( option ) ) != 0 ) { (char *)&option, sizeof(option) ) != 0) {
UpnpPrintf( UPNP_CRITICAL, UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__, SSDP, __FILE__, __LINE__,
"Error in setting broadcast !!!\n" ); "Error in setting broadcast !!!\n" );
@@ -988,10 +976,10 @@ get_ssdp_sockets( MiniServerSockArray * out )
return UPNP_E_NETWORK_ERROR; return UPNP_E_NETWORK_ERROR;
} }
CLIENTONLY( out->ssdpReqSock = ssdpReqSock; CLIENTONLY( out->ssdpReqSock = ssdpReqSock; );
);
out->ssdpSock = ssdpSock; out->ssdpSock = ssdpSock;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
#endif // EXCLUDE_SSDP #endif // EXCLUDE_SSDP

View File

@@ -50,22 +50,11 @@
#define S43 15 #define S43 15
#define S44 21 #define S44 21
static void MD5Transform PROTO_LIST( ( UINT4[4], static void MD5Transform PROTO_LIST((UINT4[4], unsigned char[64]));
unsigned char[64] ) ); static void Encode PROTO_LIST((unsigned char *, UINT4 *, unsigned int));
static void Encode PROTO_LIST( ( unsigned char *, static void Decode PROTO_LIST((UINT4 *, unsigned char *, unsigned int));
UINT4 *, static void MD5_memcpy PROTO_LIST((POINTER, POINTER, unsigned int));
unsigned int ) ); static void MD5_memset PROTO_LIST((POINTER, int, unsigned int));
static void Decode PROTO_LIST( ( UINT4 *,
unsigned char *,
unsigned int ) );
static void MD5_memcpy PROTO_LIST( ( POINTER,
POINTER,
unsigned int ) );
static void MD5_memset PROTO_LIST( ( POINTER,
int,
unsigned int ) );
static unsigned char PADDING[64] = { static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@@ -118,14 +107,10 @@ static unsigned char PADDING[64] = {
MD5 initialization. Begins an MD5 operation, writing a new context. MD5 initialization. Begins an MD5 operation, writing a new context.
*/ */
void void
MD5Init( context ) MD5Init(MD5_CTX * context)
MD5_CTX *context; /* context */
{ {
context->count[0] = context->count[1] = 0; context->count[0] = context->count[1] = 0;
/* Load magic initialization constants. */
/*
Load magic initialization constants.
*/
context->state[0] = 0x67452301; context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89; context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe; context->state[2] = 0x98badcfe;
@@ -139,114 +124,72 @@ MD5Init( context )
*/ */
void void
MD5Update( context, MD5Update(MD5_CTX *context, unsigned char *input, unsigned int inputLen)
input,
inputLen )
MD5_CTX *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{ {
unsigned int i, unsigned int i;
index, unsigned int index;
partLen; unsigned int partLen;
/* /* Compute number of bytes mod 64 */
Compute number of bytes mod 64 index = (unsigned int)((context->count[0] >> 3) & 0x3F);
*/
index = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3F );
/* /* Update number of bits */
Update number of bits if ((context->count[0] += ((UINT4)inputLen << 3)) < ((UINT4)inputLen << 3)) {
*/ context->count[1]++;
if( ( context->count[0] += }
( ( UINT4 ) inputLen << 3 ) ) < ( ( UINT4 ) inputLen << 3 ) ) context->count[1] += ((UINT4)inputLen >> 29);
context->count[1]++; partLen = 64 - index;
context->count[1] += ( ( UINT4 ) inputLen >> 29 ); /* Transform as many times as possible. */
if (inputLen >= partLen) {
partLen = 64 - index; MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform(context->state, context->buffer);
/* for (i = partLen; i + 63 < inputLen; i += 64) {
Transform as many times as possible. MD5Transform(context->state, &input[i]);
*/ }
if( inputLen >= partLen ) { index = 0;
} else {
MD5_memcpy i = 0;
( ( POINTER ) & context->buffer[index], ( POINTER ) input, }
partLen );
MD5Transform( context->state, context->buffer );
for( i = partLen; i + 63 < inputLen; i += 64 )
MD5Transform( context->state, &input[i] );
index = 0;
} else
i = 0;
/*
Buffer remaining input
*/
MD5_memcpy
( ( POINTER ) & context->buffer[index], ( POINTER ) & input[i],
inputLen - i );
/* Buffer remaining input */
MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen - i);
} }
/* /*
MD5 finalization. Ends an MD5 message-digest operation, writing the MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context. the message digest and zeroizing the context.
*/ */
void void
MD5Final( digest, MD5Final(unsigned char digest[16], MD5_CTX *context)
context )
unsigned char digest[16]; /* message digest */
MD5_CTX *context; /* context */
{ {
unsigned char bits[8]; unsigned char bits[8];
unsigned int index, unsigned int index;
padLen; unsigned int padLen;
/* /* Save number of bits */
Save number of bits Encode(bits, context->count, 8);
*/
Encode( bits, context->count, 8 );
/* /* Pad out to 56 mod 64. */
Pad out to 56 mod 64. index = (unsigned int)((context->count[0] >> 3) & 0x3f);
*/ padLen = (index < 56) ? (56 - index) : (120 - index);
index = ( unsigned int )( ( context->count[0] >> 3 ) & 0x3f ); MD5Update(context, PADDING, padLen);
padLen = ( index < 56 ) ? ( 56 - index ) : ( 120 - index ); /* Append length (before padding) */
MD5Update(context, bits, 8);
MD5Update( context, PADDING, padLen ); /* Store state in digest */
Encode(digest, context->state, 16);
/*
Append length (before padding)
*/
MD5Update( context, bits, 8 );
/*
Store state in digest
*/
Encode( digest, context->state, 16 );
/*
Zeroize sensitive information.
*/
MD5_memset( ( POINTER ) context, 0, sizeof( *context ) );
/* Zeroize sensitive information. */
MD5_memset((POINTER)context, 0, sizeof(*context));
} }
/* /*
MD5 basic transformation. Transforms state based on block. MD5 basic transformation. Transforms state based on block.
*/ */
static void static void
MD5Transform( state, MD5Transform(UINT4 state[4], unsigned char block[64])
block )
UINT4 state[4];
unsigned char block[64];
{ {
UINT4 a = state[0], UINT4 a = state[0],
b = state[1], b = state[1],
@@ -353,23 +296,16 @@ MD5Transform( state,
a multiple of 4. a multiple of 4.
*/ */
static void static void
Encode( output, Encode(unsigned char *output, UINT4 *input, unsigned int len)
input,
len )
unsigned char *output;
UINT4 *input;
unsigned int len;
{ {
unsigned int i, unsigned int i;
j; unsigned int j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
for( i = 0, j = 0; j < len; i++, j += 4 ) { output[j+0] = (unsigned char)((input[i] >> 0) & 0xff);
output[j] = ( unsigned char )( input[i] & 0xff ); output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j + 1] = ( unsigned char )( ( input[i] >> 8 ) & 0xff ); output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j + 2] = ( unsigned char )( ( input[i] >> 16 ) & 0xff ); output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
output[j + 3] = ( unsigned char )( ( input[i] >> 24 ) & 0xff ); }
}
} }
/* /*
@@ -378,55 +314,40 @@ Encode( output,
*/ */
static void static void
Decode( output, Decode(UINT4 *output, unsigned char *input, unsigned int len)
input,
len )
UINT4 *output;
unsigned char *input;
unsigned int len;
{ {
unsigned int i, unsigned int i;
j; unsigned int j;
for (i = 0, j = 0; j < len; ++i, j += 4) {
for( i = 0, j = 0; j < len; i++, j += 4 ) output[i] =
output[i] = (((UINT4)input[j+0]) << 0) |
( ( UINT4 ) input[j] ) | ( ( ( UINT4 ) input[j + 1] ) << 8 ) | (((UINT4)input[j+1]) << 8) |
( ( ( UINT4 ) input[j + 2] ) << 16 ) | (((UINT4)input[j+2]) << 16) |
( ( ( UINT4 ) input[j + 3] ) << 24 ); (((UINT4)input[j+3]) << 24);
}
} }
/* /*
Note: Replace &quot;for loop&quot; with standard memcpy if possible. Note: Replace for loop with standard memcpy if possible.
*/ */
static void static void
MD5_memcpy( output, MD5_memcpy(POINTER output, POINTER input, unsigned int len)
input,
len )
POINTER output;
POINTER input;
unsigned int len;
{ {
unsigned int i; unsigned int i;
for (i = 0; i < len; ++i) {
for( i = 0; i < len; i++ ) output[i] = input[i];
output[i] = input[i]; }
} }
/* /*
Note: Replace &quot;for loop&quot; with standard memset if possible. Note: Replace for loop with standard memset if possible.
*/ */
static void static void
MD5_memset( output, MD5_memset(POINTER output, int value, unsigned int len)
value,
len )
POINTER output;
int value;
unsigned int len;
{ {
unsigned int i; unsigned int i;
for (i = 0; i < len; ++i) {
for( i = 0; i < len; i++ ) ((char *)output)[i] = (char)value;
( ( char * )output )[i] = ( char )value; }
} }

View File

@@ -33,17 +33,16 @@
This sample implementation generates a random node ID This sample implementation generates a random node ID
*/ */
void void
get_ieee_node_identifier( uuid_node_t * node ) get_ieee_node_identifier(uuid_node_t *node)
{ {
char seed[16]; char seed[16];
static int inited = 0; static int inited = 0;
static uuid_node_t saved_node; static uuid_node_t saved_node;
if( !inited ) { if (!inited) {
get_random_info( seed ); get_random_info(seed);
seed[0] |= 0x80; seed[0] |= 0x80;
memcpy( &saved_node, seed, sizeof( uuid_node_t ) ); memcpy(&saved_node, seed, sizeof (uuid_node_t));
inited = 1; inited = 1;
}; };
@@ -83,52 +82,48 @@ get_system_time( uuid_time_t * uuid_time )
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void void
get_random_info( char seed[16] ) get_random_info(char seed[16])
{ {
MD5_CTX c; MD5_CTX c;
typedef struct { typedef struct {
MEMORYSTATUS m; MEMORYSTATUS m;
SYSTEM_INFO s; SYSTEM_INFO s;
FILETIME t; FILETIME t;
LARGE_INTEGER pc; LARGE_INTEGER pc;
DWORD tc; DWORD tc;
DWORD l; DWORD l;
char hostname[MAX_COMPUTERNAME_LENGTH + 1]; char hostname[MAX_COMPUTERNAME_LENGTH + 1];
} randomness; } randomness;
randomness r; randomness r;
MD5Init( &c ); /* Initialize memory area so that valgrind does not complain */
/* memset(&r, 0, sizeof r);
memory usage stats
*/
GlobalMemoryStatus( &r.m );
/*
random system stats
*/
GetSystemInfo( &r.s );
/*
100ns resolution (nominally) time of day
*/
GetSystemTimeAsFileTime( &r.t );
/*
high resolution performance counter
*/
QueryPerformanceCounter( &r.pc );
/*
milliseconds since last boot
*/
r.tc = GetTickCount( );
r.l = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName( r.hostname, &r.l ); /* memory usage stats */
MD5Update( &c, &r, sizeof( randomness ) ); GlobalMemoryStatus( &r.m );
MD5Final( seed, &c ); /* random system stats */
GetSystemInfo( &r.s );
/* 100ns resolution (nominally) time of day */
GetSystemTimeAsFileTime( &r.t );
/* high resolution performance counter */
QueryPerformanceCounter( &r.pc );
/* milliseconds since last boot */
r.tc = GetTickCount();
r.l = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName( r.hostname, &r.l );
/* MD5 it */
MD5Init(&c);
MD5Update(&c, &r, sizeof r);
MD5Final(seed, &c);
}; };
#else
#else /* _WINDOWS_ */
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void void
get_system_time( uuid_time_t * uuid_time ) get_system_time(uuid_time_t *uuid_time)
{ {
struct timeval tp; struct timeval tp;
@@ -145,22 +140,28 @@ get_system_time( uuid_time_t * uuid_time )
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void void
get_random_info( char seed[16] ) get_random_info(char seed[16])
{ {
MD5_CTX c; MD5_CTX c;
typedef struct { typedef struct {
// struct sysinfo s; //struct sysinfo s;
struct timeval t; struct timeval t;
char hostname[257]; char hostname[257];
} randomness; } randomness;
randomness r; randomness r;
MD5Init( &c ); /* Initialize memory area so that valgrind does not complain */
memset(&r, 0, sizeof r);
gettimeofday( &r.t, ( struct timezone * )0 ); /* Get some random stuff */
gethostname( r.hostname, 256 ); gettimeofday(&r.t, (struct timezone *)0);
MD5Update( &c, &r, sizeof( randomness ) ); gethostname(r.hostname, 256 );
MD5Final( seed, &c );
/* MD5 it */
MD5Init(&c);
MD5Update(&c, &r, sizeof r);
MD5Final(seed, &c);
}; };
#endif #endif /* _WINDOWS_ */

View File

@@ -53,10 +53,10 @@ static unsigned16 true_random( void );
uuid_create -- generator a UUID uuid_create -- generator a UUID
*/ */
int int
uuid_create( uuid_upnp * uid ) uuid_create(uuid_upnp *uid)
{ {
uuid_time_t timestamp, uuid_time_t timestamp;
last_time; uuid_time_t last_time;
unsigned16 clockseq; unsigned16 clockseq;
uuid_node_t node; uuid_node_t node;
uuid_node_t last_node; uuid_node_t last_node;
@@ -65,61 +65,64 @@ uuid_create( uuid_upnp * uid )
/* /*
acquire system wide lock so we're alone acquire system wide lock so we're alone
*/ */
UUIDLock( ); UUIDLock();
/* /*
get current time get current time
*/ */
get_current_time( &timestamp ); get_current_time(&timestamp);
/* /*
get node ID get node ID
*/ */
get_ieee_node_identifier( &node ); get_ieee_node_identifier(&node);
/* /*
get saved state from NV storage get saved state from NV storage
*/ */
f = read_state( &clockseq, &last_time, &last_node ); f = read_state(&clockseq, &last_time, &last_node);
/* /*
if no NV state, or if clock went backwards, or node ID changed if no NV state, or if clock went backwards, or node ID changed
(e.g., net card swap) change clockseq (e.g., net card swap) change clockseq
*/ */
if( !f || memcmp( &node, &last_node, sizeof( uuid_node_t ) ) ) if (!f || memcmp(&node, &last_node, sizeof(uuid_node_t))) {
clockseq = true_random( ); clockseq = true_random();
else if( timestamp < last_time ) } else if (timestamp < last_time) {
clockseq++; clockseq++;
}
/* /*
stuff fields into the UUID stuff fields into the UUID
*/ */
format_uuid_v1( uid, clockseq, timestamp, node ); format_uuid_v1(uid, clockseq, timestamp, node);
/* /*
save the state for next time save the state for next time
*/ */
write_state( clockseq, timestamp, node ); write_state(clockseq, timestamp, node);
UUIDUnlock( ); UUIDUnlock();
return ( 1 ); return 1;
}; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
void void
uuid_unpack( uuid_upnp * u, uuid_unpack(uuid_upnp *u, char *out)
char *out )
{ {
sprintf(out,
sprintf( out, "%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",
"%8.8x-%4.4x-%4.4x-%2.2x%2.2x-%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x", (unsigned int)u->time_low,
( unsigned int )u->time_low, u->time_mid, u->time_mid,
u->time_hi_and_version, u->clock_seq_hi_and_reserved, u->time_hi_and_version,
u->clock_seq_low, u->node[0], u->node[1], u->node[2], u->clock_seq_hi_and_reserved,
u->node[3], u->node[4], u->node[5] ); u->clock_seq_low,
u->node[0],
*( out + 36 ) = '\0'; u->node[1],
u->node[2],
u->node[3],
u->node[4],
u->node[5]);
}; };
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/
@@ -137,11 +140,10 @@ format_uuid_v1( uuid_upnp * uid,
Construct a version 1 uuid with the information we've gathered Construct a version 1 uuid with the information we've gathered
* plus a few constants. * plus a few constants.
*/ */
uid->time_low = ( unsigned long )( timestamp & 0xFFFFFFFF ); uid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);
uid->time_mid = ( unsigned short )( ( timestamp >> 32 ) & 0xFFFF ); uid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);
uid->time_hi_and_version = ( unsigned short )( ( timestamp >> 48 ) & uid->time_hi_and_version = (unsigned short)((timestamp >> 48) & 0x0FFF);
0x0FFF ); uid->time_hi_and_version |= (1 << 12);
uid->time_hi_and_version |= ( 1 << 12 );
uid->clock_seq_low = clock_seq & 0xFF; uid->clock_seq_low = clock_seq & 0xFF;
uid->clock_seq_hi_and_reserved = ( clock_seq & 0x3F00 ) >> 8; uid->clock_seq_hi_and_reserved = ( clock_seq & 0x3F00 ) >> 8;
uid->clock_seq_hi_and_reserved |= 0x80; uid->clock_seq_hi_and_reserved |= 0x80;
@@ -227,7 +229,6 @@ get_current_time( uuid_time_t * timestamp )
static int inited = 0; static int inited = 0;
if( !inited ) { if( !inited ) {
get_system_time( &time_now );
uuids_this_tick = UUIDS_PER_TICK; uuids_this_tick = UUIDS_PER_TICK;
inited = 1; inited = 1;
}; };

View File

@@ -105,7 +105,7 @@ main (int argc, char* argv[])
* Test library initialisation * Test library initialisation
*/ */
printf ("\n"); printf ("\n");
printf ("Intializing UPnP ... \n"); printf ("Initializing UPnP ... \n");
rc = UpnpInit (NULL, 0); rc = UpnpInit (NULL, 0);
if ( UPNP_E_SUCCESS == rc ) { if ( UPNP_E_SUCCESS == rc ) {
const char* ip_address = UpnpGetServerIpAddress(); const char* ip_address = UpnpGetServerIpAddress();