Merge of current trunk to branch 1.6.x.

git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@251 119443c7-1b9e-41f8-b6fc-b9c35fce742c
This commit is contained in:
Marcelo Roberto Jimenez 2007-11-19 14:15:45 +00:00
parent 2a76749682
commit 0475a46680
31 changed files with 2506 additions and 2260 deletions

137
ChangeLog
View File

@ -1,3 +1,80 @@
*******************************************************************************
Version 1.6.2
*******************************************************************************
2007-11-09 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Added a isleep() call to the error handler of select() in
RunMiniServer(), so that it does not take 100% cpu in case select()
fails repeatedly.
2007-11-12 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* "make check" was failing because ixml/test/test_document.sh did not
have the executable flag set. Thanks to Steve Bresson.
*******************************************************************************
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
*******************************************************************************
@ -414,14 +491,14 @@ Version 1.4.0
FORK FROM DEAD libupnp
*******************************************************************************
2006-04-29 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-04-29 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* THANKS: new file with list of contributors
* upnp/src/gena/gena_device.c (respond_ok): add 'Content-Length: 0'
in subscription response. Patch by Chaos (Bug # 1455367).
2006-04-08 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-04-08 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/doc/UPnP_Programming_Guide.pdf: replace this document with
the one in libupnp-doc-1.2.1 because current CVS version
@ -432,20 +509,20 @@ FORK FROM DEAD libupnp
* changes applied to several files to work under Sparc Solaris, temporarily
requiring a define SPARC_SOLARIS
2006-04-03 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-04-03 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/Makefile.am: install upnp samples in $(docdir)/examples
2006-03-28 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-28 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* configure.ac: add --with-docdir option to choose where documentation
is installed (or -without-docdir to not install the documentation)
2006-03-27 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-27 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* ixml/test: add simple test suite for xml parser
2006-03-26 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-26 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* ixml/src/ixmlparser.c (Parser_processCDSect): fix bug which prevents
CDATA sections which contain a 0 (zero) to be parsed (instead the
@ -456,18 +533,18 @@ FORK FROM DEAD libupnp
option, and move samples compilation from check_PROGRAMS to
noinst_PROGRAMS
2006-03-25 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-25 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/genlib/miniserver/miniserver.c (get_miniserver_sockets):
fix bug if new socket created has fd 0 (can only occur when stdin
has been closed). Patch by Oskar Liljeblad 2004-07-02 :
http://sourceforge.net/mailarchive/message.php?msg_id=8870528
2006-03-21 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-21 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/test/test_init.c: add some version checks and exit if failure
2006-03-05 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-05 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* libupnp version 1.3.1
@ -482,11 +559,11 @@ FORK FROM DEAD libupnp
dependencies between upnp and ixml / threadutil, so that programs
linking against upnp only still work.
2006-03-04 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-04 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* libupnp version 1.3.0
2006-03-03 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-03-03 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/genlib/net/http/httpreadwrite.c (get_sdk_info): use
package version string from configure to set sdk info
@ -494,7 +571,7 @@ FORK FROM DEAD libupnp
* upnp/Makefile.am: add sample/tvdevice/web/ files in EXTRA_DIST
+ do not distribute generated upnpconfig.h file.
2006-02-28 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-02-28 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/inc/config.h, configure.ac: use only new defines
UPNP_HAVE_xx instead of INCLUDE_yyy_APIS and INTERNAL_WEB_SERVER
@ -503,7 +580,7 @@ FORK FROM DEAD libupnp
the librarie LDFLAGS in order to export only the symbols defined
in the API
2006-02-27 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-02-27 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* configure.ac: add libtool versions for the 3 libraries
@ -511,7 +588,7 @@ FORK FROM DEAD libupnp
* threadutil/src/ThreadPool.c (SetSeed): add missing 'static'
2006-02-26 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-02-26 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* threadutil/inc/iasnprintf.h: add gcc __printf__ format attribute
to "iasnprintf"
@ -532,11 +609,11 @@ FORK FROM DEAD libupnp
the configuration of the installed libraries (generates installed
file <upnp/upnpconfig.h>)
2006-02-22 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-02-22 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/ : add missing include of config.h in some .c files
2006-02-21 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-02-21 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/inc/upnp.h: move some definitions which should not be
exported into "upnp/src/inc/util.h"
@ -544,12 +621,12 @@ FORK FROM DEAD libupnp
* import all modifications below from libupnp in djmount 0.51
into official libupnp
2006-01-17 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-01-17 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* threadutil/Makefile.am (libthreadutil_la_SOURCES): remove extraneous
file
2006-01-15 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-01-15 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* configure.ac: add checks for large-file support
@ -569,53 +646,53 @@ FORK FROM DEAD libupnp
* ixml/src/node.c (ixmlNode_getNodeType): fix compilation warning
on const return type
2006-01-12 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-01-12 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/inc/readwrite.h : suppress unused C++ header file
2006-01-11 Rémi Turboult <r3mi(at)users.sourceforge.net>
2006-01-11 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/inc/config.h, upnp/src/inc/upnpapi.h,
upnp/src/inc/httpreadwrite.h: remove internal configuration variable
MINIMUM_DELAY (no clear purpose)
2005-12-05 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-12-05 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/inc/upnp.h: re-declare obsolete method UpnpSetContentLength,
for binary compatibility with previous libupnp version.
* upnp/src/api/upnpapi.c: correct type of g_maxContentLength to size_t
2005-11-01 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-11-01 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* autoconfiscate library : replace all makefiles by Makefile.am
for automake support, + preliminary autoconf support
(generated config.h not yet used in source files)
2005-10-18 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-10-18 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/makefile: fix location of DEBUG STATIC libupnp library
* upnp/sample/tvctrlpt/linux/Makefile,
upnp/sample/tvdevice/linux/Makefile: fix STATIC library support
2005-10-16 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-10-16 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* threadutil/src/Makefile (clean): remove built library
2005-08-28 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-08-28 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* ixml/src/ixml.h, ixml/src/ixml.c (ixmlRelaxParser) : new function
* ixml/src/ixmlparser.h, ixml/src/ixmlparser.c (Parser_setErrorChar) :
new function
2005-08-02 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-08-02 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* ixml/src/Makefile: correct bug for static library being incorrectly
stripped when building non-debug
2005-06-09 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-06-09 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* ixml/src/element.c (ixmlElement_removeAttributeNode):
remove some compilation warning
@ -626,7 +703,7 @@ FORK FROM DEAD libupnp
* upnp/inc/upnptools.h, upnp/src/api/upnptools.c :
add missing const's in public API
2005-05-28 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-05-28 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/inc/config.h: suppress HTTP_READ_BYTES (unused)
and replace by DEFAULT_SOAP_CONTENT_LENGTH (previously in upnpapi.h)
@ -647,7 +724,7 @@ FORK FROM DEAD libupnp
* upnp/src/genlib/net/http/httpreadwrite.c : corrected an incorrect
sprintf format
2005-05-27 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-05-27 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/makefile, upnp/src/makefile,
ixml/Makefile, ixml/src/Makefile,
@ -655,7 +732,7 @@ FORK FROM DEAD libupnp
implement STATIC library support (from patch at
http://sourceforge.net/tracker/?group_id=7189&atid=307189 )
2005-05-26 Rémi Turboult <r3mi(at)users.sourceforge.net>
2005-05-26 R<EFBFBD>mi Turboult <r3mi(at)users.sourceforge.net>
* upnp/src/api/upnpapi.c, upnp/src/soap/soap_device.c,
upnp/src/soap/makefile :

6
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
exempt of errors.
- Alex (afaucher)
- Arno Willig
- Bob Ciora
- Chaos
@ -20,10 +21,11 @@ exempt of errors.
- Jiri Zouhar
- John Dennis
- Jonathan (no_dice)
- Keith Brindley
- Leuk_He
- Loigu
- Luke Kim
- Marcelo Roberto Jimenez
- Marcelo Roberto Jimenez (mroberto)
- Markus Strobl
- Nektarios K. Papadopoulos
- Oskar Liljeblad
@ -31,6 +33,8 @@ exempt of errors.
- Paul Vixie
- Rene Hexel
- Siva Chandran
- Stéphane Corthésy
- Steve Bresson
- Timothy Redaelli
- Titus Winters

View File

@ -261,7 +261,7 @@
/** @name Other debugging features
The UPnP SDK contains other features to aid in debugging:
see <upnp/upnpdebug.h>
see <upnp/inc/upnpdebug.h>
*/
#define DEBUG_ALL 1

View File

@ -4,14 +4,15 @@
#
# 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_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
AC_INIT([libupnp], [1.6.2], [mroberto@users.sourceforge.net])
###############################################################################
# *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:
# - library code modified: revision++
# - 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
# *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_THREADUTIL], [2:2:0])
#AC_SUBST([LT_VERSION_UPNP], [2:2:0])
#
###############################################################################
# Release 1.4.6:
# "current:revision:age"
#
# - Code has changed in ixml
@ -37,11 +41,12 @@ AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
# - Code has changed in upnp
# revision: 2 -> 3
#
# For release 1.4.6, we had:
#AC_SUBST([LT_VERSION_IXML], [2:3:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [3:0:1])
#AC_SUBST([LT_VERSION_UPNP], [2:3:0])
#
###############################################################################
# Release 1.6.0:
# "current:revision:age"
#
# - Code has changed in ixml
@ -56,21 +61,58 @@ AC_INIT([libupnp], [1.6.0], [mroberto@users.sourceforge.net])
# - Interface removed in upnp
# age: 0 -> 0
#
# For release 1.6.0, we had:
#AC_SUBST([LT_VERSION_IXML], [2:4:0])
#AC_SUBST([LT_VERSION_THREADUTIL], [3:1:1])
#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])
#
###############################################################################
# Release 1.6.2:
# "current:revision:age"
#
#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_THREADUTIL], [3:1:1])
AC_SUBST([LT_VERSION_UPNP], [3:0:0])
AC_SUBST([LT_VERSION_THREADUTIL], [4:0:2])
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_MACRO_DIR(m4)
AC_CONFIG_SRCDIR(upnp/inc/upnp.h)
AM_INIT_AUTOMAKE([1.8 -Wall foreign subdir-objects dist-bzip2])
#
# Get canonical host names in host and host_os
#

0
ixml/test/test_document.sh Normal file → Executable file
View File

View File

@ -1,4 +1,4 @@
Version: 1.4.2
Version: 1.6.2
Summary: Universal Plug and Play (UPnP) SDK
Name: libupnp
Release: 1%{?dist}
@ -77,6 +77,12 @@ make install DESTDIR=$RPM_BUILD_ROOT
rm -rf %{buildroot}
%changelog
* Mon Nov 19 2007 Marcelo Jimenez <mroberto@users.sourceforge.net> - 1.6.2-1
- Update to version 1.6.2
* Mon Nov 19 2007 Marcelo Jimenez <mroberto@users.sourceforge.net> - 1.4.7-1
- Update to version 1.4.7
* Fri Feb 02 2007 Eric Tanguy <eric.tanguy@univ-nantes.fr> - 1.4.2-1
- Update to version 1.4.2

View File

@ -547,6 +547,10 @@ int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
EXPORT int ThreadPoolGetStats(ThreadPool *tp, 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
#ifdef __cplusplus

View File

@ -42,26 +42,31 @@ extern "C" {
#endif
#ifdef __FreeBSD__
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif
#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
*/
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK
#else
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_FAST_NP
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE_NP
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK_NP
#endif
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_NORMAL
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK
#else /* PTHREAD_MUTEX_RECURSIVE */
#define ITHREAD_MUTEX_FAST_NP PTHREAD_MUTEX_FAST_NP
#define ITHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE_NP
#define ITHREAD_MUTEX_ERRORCHECK_NP PTHREAD_MUTEX_ERRORCHECK_NP
#endif /* PTHREAD_MUTEX_RECURSIVE */
#define ITHREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
#define ITHREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
#define ITHREAD_CANCELED PTHREAD_CANCELED
/***************************************************************************
/***************************************************************************
* Name: ithread_t
*
* Description:
@ -69,9 +74,9 @@ extern "C" {
* typedef to pthread_t.
* Internal Use Only.
***************************************************************************/
typedef pthread_t ithread_t;
typedef pthread_t ithread_t;
/****************************************************************************
/****************************************************************************
* Name: ithread_attr_t
*
* Description:
@ -79,20 +84,20 @@ extern "C" {
* typedef to pthread_attr_t
* Internal Use Only
***************************************************************************/
typedef pthread_attr_t ithread_attr_t;
typedef pthread_attr_t ithread_attr_t;
/****************************************************************************
/****************************************************************************
* Name: start_routine
*
* Description:
* Thread start routine
* Internal Use Only.
***************************************************************************/
typedef void * (*start_routine) (void *arg);
typedef void * (*start_routine) (void *arg);
/****************************************************************************
/****************************************************************************
* Name: ithread_cond_t
*
* Description:
@ -100,10 +105,10 @@ extern "C" {
* typedef to pthread_cond_t
* Internal Use Only.
***************************************************************************/
typedef pthread_cond_t ithread_cond_t;
typedef pthread_cond_t ithread_cond_t;
/****************************************************************************
/****************************************************************************
* Name: ithread_mutexattr_t
*
* Description:
@ -111,10 +116,10 @@ extern "C" {
* typedef to pthread_mutexattr_t
* Internal Use Only
***************************************************************************/
typedef pthread_mutexattr_t ithread_mutexattr_t;
typedef pthread_mutexattr_t ithread_mutexattr_t;
/****************************************************************************
/****************************************************************************
* Name: ithread_mutex_t
*
* Description:
@ -122,10 +127,10 @@ extern "C" {
* typedef to pthread_mutex_t
* Internal Use Only.
***************************************************************************/
typedef pthread_mutex_t ithread_mutex_t;
typedef pthread_mutex_t ithread_mutex_t;
/****************************************************************************
/****************************************************************************
* Name: ithread_condattr_t
*
* Description:
@ -134,9 +139,31 @@ extern "C" {
* NOT USED
* Internal Use Only
***************************************************************************/
typedef pthread_condattr_t ithread_condattr_t;
typedef pthread_condattr_t ithread_condattr_t;
/****************************************************************************
/****************************************************************************
* Name: ithread_rwlockattr_t
*
* Description:
* Mutex attribute.
* typedef to pthread_rwlockattr_t
* Internal Use Only
***************************************************************************/
typedef pthread_rwlockattr_t ithread_rwlockattr_t;
/****************************************************************************
* 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:
@ -150,10 +177,10 @@ extern "C" {
* Always returns 0.
* See man page for pthread_mutexattr_init
***************************************************************************/
#define ithread_mutexattr_init pthread_mutexattr_init
/****************************************************************************
/****************************************************************************
* Function: ithread_mutexattr_destroy
*
* Description:
@ -180,7 +207,7 @@ extern "C" {
* ITHREAD_MUTEX_ERRORCHECK_NP
*
* 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)
* int kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
* or ITHREAD_MUTEX_ERRORCHECK_NP)
@ -190,9 +217,9 @@ extern "C" {
* See man page for pthread_mutexattr_setkind_np
*****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE
#define ithread_mutexattr_setkind_np pthread_mutexattr_settype
#define ithread_mutexattr_setkind_np pthread_mutexattr_settype
#else
#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
#endif
/****************************************************************************
@ -205,7 +232,7 @@ extern "C" {
* ITHREAD_MUTEX_ERRORCHECK_NP
*
* 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)
* int *kind (one of ITHREAD_MUTEX_FAST_NP or ITHREAD_MUTEX_RECURSIVE_NP
* or ITHREAD_MUTEX_ERRORCHECK_NP)
@ -215,9 +242,9 @@ extern "C" {
* See man page for pthread_mutexattr_getkind_np
*****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE
#define ithread_mutexattr_getkind_np pthread_mutexattr_gettype
#define ithread_mutexattr_getkind_np pthread_mutexattr_gettype
#else
#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
#endif
@ -238,6 +265,7 @@ extern "C" {
*****************************************************************************/
#define ithread_mutex_init pthread_mutex_init
/****************************************************************************
* Function: ithread_mutex_lock
*
@ -292,6 +320,169 @@ extern "C" {
#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
*

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
* Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -258,7 +258,7 @@ void UpnpPrintf(
__attribute__((format (__printf__, 5, 6)))
#endif
;
#else
#else /* DEBUG */
static UPNP_INLINE void UpnpPrintf(
Upnp_LogLevel DLevel,
Dbg_Module Module,
@ -266,7 +266,7 @@ static UPNP_INLINE void UpnpPrintf(
int DbgLineNo,
const char* FmtStr,
...) {}
#endif
#endif /* DEBUG */
/***************************************************************************

View File

@ -1362,7 +1362,7 @@ TvCtrlPointStart( print_string printFunctionPtr,
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 );
rc = UpnpInit( ip_address, port );
if( UPNP_E_SUCCESS != rc ) {

View File

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

View File

@ -36,7 +36,7 @@
#include "uri.h"
#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
struct ErrorString {
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"},
{UPNP_E_INVALID_HANDLE, "UPNP_E_INVALID_HANDLE"},
{UPNP_E_INVALID_PARAM, "UPNP_E_INVALID_PARAM"},
@ -581,4 +581,5 @@ UpnpCreatePropertySet( IN int NumArg,
return PropSet;
}
#endif
#endif // EXCLUDE_DOM == 0

View File

@ -93,7 +93,7 @@ GenaAutoRenewSubscription( IN void *input )
}
}
if( send_callback ) {
HandleLock();
HandleReadLock();
if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock();
free_upnp_timeout( event );
@ -543,10 +543,10 @@ genaSubscribe( IN UpnpClient_Handle client_handle,
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUBSCRIBE BEGIN" );
HandleLock();
memset( out_sid, 0, sizeof( Upnp_SID ) );
HandleReadLock();
// validate handle
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock();
@ -881,3 +881,4 @@ gena_process_notification_event( IN SOCKINFO * info,
#endif // INCLUDE_CLIENT_APIS
#endif // EXCLUDE_GENA

View File

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

View File

@ -42,12 +42,12 @@
#include <sys/wait.h>
#include <unistd.h>
#include <sys/time.h>
#else
#else /* WIN32 */
#include <winsock2.h>
typedef int socklen_t;
#define EAFNOSUPPORT 97
#endif
#endif /* WIN32 */
#include "unixutil.h"
#include "ithread.h"
@ -88,17 +88,16 @@ static MiniServerCallback gGenaCallback = NULL;
static MiniServerState gMServState = MSERV_IDLE;
/************************************************************************
* Function : SetHTTPGetCallback
*
* Parameters :
* MiniServerCallback callback ; - HTTP Callback to be invoked
*
* Description : Set HTTP Get Callback
*
* Return : void
*
* Note :
************************************************************************/
* Function: SetHTTPGetCallback
*
* Parameters :
* MiniServerCallback callback - HTTP Callback to be invoked
*
* Description:
* Set HTTP Get Callback
*
* Return: void
************************************************************************/
void
SetHTTPGetCallback( MiniServerCallback callback )
{
@ -106,17 +105,16 @@ SetHTTPGetCallback( MiniServerCallback callback )
}
/************************************************************************
* Function : SetSoapCallback
*
* Parameters :
* MiniServerCallback callback ; - SOAP Callback to be invoked
*
* Description : Set SOAP Callback
*
* Return : void
*
* Note :
************************************************************************/
* Function: SetSoapCallback
*
* Parameters:
* MiniServerCallback callback - SOAP Callback to be invoked
*
* Description:
* Set SOAP Callback
*
* Return: void
************************************************************************/
void
SetSoapCallback( MiniServerCallback callback )
{
@ -124,17 +122,16 @@ SetSoapCallback( MiniServerCallback callback )
}
/************************************************************************
* Function : SetGenaCallback
*
* Parameters :
* MiniServerCallback callback ; - GENA Callback to be invoked
*
* Description : Set GENA Callback
*
* Return : void
*
* Note :
************************************************************************/
* Function: SetGenaCallback
*
* Parameters:
* MiniServerCallback callback - GENA Callback to be invoked
*
* Description:
* Set GENA Callback
*
* Return: void
************************************************************************/
void
SetGenaCallback( MiniServerCallback callback )
{
@ -142,21 +139,19 @@ SetGenaCallback( MiniServerCallback callback )
}
/************************************************************************
* Function : dispatch_request
*
* Parameters :
* IN SOCKINFO *info ; Socket Information object.
* http_parser_t* hparser ; HTTP parser object.
*
* Description : Based on the type pf message, appropriate callback
* is issued
*
* Return : int ;
* 0 - On Success
* HTTP_INTERNAL_SERVER_ERROR - Callback is NULL
*
* Note :
************************************************************************/
* Function : dispatch_request
*
* Parameters :
* IN SOCKINFO *info - Socket Information object.
* http_parser_t* hparser - HTTP parser object.
*
* Description :
* Based on the type pf message, appropriate callback is issued
*
* Return: int
* 0 - On Success
* HTTP_INTERNAL_SERVER_ERROR - Callback is NULL
************************************************************************/
static int
dispatch_request( IN SOCKINFO * info,
http_parser_t * hparser )
@ -200,21 +195,19 @@ dispatch_request( IN SOCKINFO * info,
}
/************************************************************************
* Function : handle_error
*
* Parameters :
*
* IN SOCKINFO *info ; Socket Inforamtion Object
* int http_error_code ; HTTP Error Code
* int major ; Major Version Number
* int minor ; Minor Version Number
*
* Description : Send Error Message
*
* Return : void;
*
* Note :
************************************************************************/
* Function: handle_error
*
* Parameters:
* IN SOCKINFO *info - Socket Inforamtion Object
* int http_error_code - HTTP Error Code
* int major - Major Version Number
* int minor - Minor Version Number
*
* Description:
* Send Error Message
*
* Return: void
************************************************************************/
static UPNP_INLINE void
handle_error( IN SOCKINFO * info,
int http_error_code,
@ -225,18 +218,17 @@ handle_error( IN SOCKINFO * info,
}
/************************************************************************
* Function : free_handle_request_arg
*
* Parameters :
* void *args ; Request Message to be freed
*
* Description : Free memory assigned for handling request and unitial-
* -ize socket functionality
*
* Return : void
*
* Note :
************************************************************************/
* Function: free_handle_request_arg
*
* Parameters:
* void *args ; Request Message to be freed
*
* Description:
* Free memory assigned for handling request and unitialize socket
* functionality
*
* Return: void
************************************************************************/
static void
free_handle_request_arg( void *args )
{
@ -248,17 +240,16 @@ free_handle_request_arg( void *args )
}
/************************************************************************
* Function : handle_request
*
* Parameters :
* void *args ; Request Message to be handled
*
* Description : Receive the request and dispatch it for handling
*
* Return : void
*
* Note :
************************************************************************/
* Function: handle_request
*
* Parameters:
* void *args - Request Message to be handled
*
* Description:
* Receive the request and dispatch it for handling
*
* Return: void
************************************************************************/
static void
handle_request( void *args )
{
@ -319,20 +310,18 @@ handle_request( void *args )
}
/************************************************************************
* Function : schedule_request_job
*
* Parameters :
* IN int connfd ; Socket Descriptor on which connection is accepted
* IN struct sockaddr_in* clientAddr ; Clients Address information
*
* Description : Initilize the thread pool to handle a request.
* Sets priority for the job and adds the job to the thread pool
*
*
* Return : void
*
* Note :
************************************************************************/
* Function: schedule_request_job
*
* Parameters:
* IN int connfd - Socket Descriptor on which connection is accepted
* IN struct sockaddr_in* clientAddr - Clients Address information
*
* Description:
* Initilize the thread pool to handle a request.
* Sets priority for the job and adds the job to the thread pool
*
* Return: void
************************************************************************/
static UPNP_INLINE void
schedule_request_job( IN int connfd,
IN struct sockaddr_in *clientAddr )
@ -371,32 +360,31 @@ schedule_request_job( IN int connfd,
}
/************************************************************************
* Function : RunMiniServer
*
* Parameters :
* MiniServerSockArray *miniSock ; Socket Array
*
* Description : Function runs the miniserver. The MiniServer accepts a
* new request and schedules a thread to handle the new request.
* Checks for socket state and invokes appropriate read and shutdown
* actions for the Miniserver and SSDP sockets
*
* Return : void
*
* Note :
************************************************************************/
* Function: RunMiniServer
*
* Parameters:
* MiniServerSockArray *miniSock - Socket Array
*
* Description:
* Function runs the miniserver. The MiniServer accepts a
* new request and schedules a thread to handle the new request.
* Checks for socket state and invokes appropriate read and shutdown
* actions for the Miniserver and SSDP sockets
*
* Return: void
************************************************************************/
static void
RunMiniServer( MiniServerSockArray * miniSock )
{
struct sockaddr_in clientAddr;
socklen_t clientLen;
SOCKET miniServSock,
connectHnd;
SOCKET miniServStopSock;
SOCKET ssdpSock;
CLIENTONLY( SOCKET ssdpReqSock;
)
SOCKET connectHnd;
SOCKET miniServSock = miniSock->miniServerSock;
SOCKET miniServStopSock = miniSock->miniServerStopSock;
SOCKET ssdpSock = miniSock->ssdpSock;
#ifdef INCLUDE_CLIENT_APIS
SOCKET ssdpReqSock = miniSock->ssdpReqSock;
#endif
fd_set expSet;
fd_set rdSet;
@ -404,66 +392,55 @@ RunMiniServer( MiniServerSockArray * miniSock )
int byteReceived;
char requestBuf[256];
miniServSock = miniSock->miniServerSock;
miniServStopSock = miniSock->miniServerStopSock;
ssdpSock = miniSock->ssdpSock;
CLIENTONLY( ssdpReqSock = miniSock->ssdpReqSock;
);
gMServState = MSERV_RUNNING;
maxMiniSock = max( miniServSock, miniServStopSock );
maxMiniSock = max( maxMiniSock, ( SOCKET ) ( ssdpSock ) );
CLIENTONLY( maxMiniSock =
max( maxMiniSock, ( SOCKET ) ( ssdpReqSock ) ) );
maxMiniSock = max( miniServSock, miniServStopSock) ;
maxMiniSock = max( maxMiniSock, (SOCKET)(ssdpSock) );
#ifdef INCLUDE_CLIENT_APIS
maxMiniSock = max( maxMiniSock, (SOCKET)(ssdpReqSock) );
#endif
++maxMiniSock;
gMServState = MSERV_RUNNING;
while( TRUE ) {
FD_ZERO( &rdSet );
FD_ZERO( &expSet );
FD_SET( miniServStopSock, &expSet );
FD_SET( miniServSock, &rdSet );
FD_SET( miniServStopSock, &rdSet );
FD_SET( ssdpSock, &rdSet );
CLIENTONLY( FD_SET( ssdpReqSock, &rdSet ) );
#ifdef INCLUDE_CLIENT_APIS
FD_SET( ssdpReqSock, &rdSet );
#endif
if( select( maxMiniSock, &rdSet, NULL, &expSet, NULL ) ==
UPNP_SOCKETERROR ) {
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Error in select call !!!\n" );
"Error in select call!\n" );
/* Avoid 100% CPU in case of repeated error in select() */
isleep( 1 );
continue;
} else {
if( FD_ISSET( miniServSock, &rdSet ) ) {
clientLen = sizeof( struct sockaddr_in );
connectHnd = accept( miniServSock,
( struct sockaddr * )&clientAddr,
&clientLen );
( struct sockaddr * )&clientAddr, &clientLen );
if( connectHnd == UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
"miniserver: Error"
" in accepting connection\n" );
"miniserver: Error in accepting connection\n" );
continue;
}
schedule_request_job( connectHnd, &clientAddr );
}
//ssdp
CLIENTONLY( if( FD_ISSET( ssdpReqSock, &rdSet ) ) {
readFromSSDPSocket( ssdpReqSock );}
)
#ifdef INCLUDE_CLIENT_APIS
// ssdp
if( FD_ISSET( ssdpReqSock, &rdSet ) ) {
readFromSSDPSocket( ssdpReqSock );
}
#endif
if( FD_ISSET( ssdpSock, &rdSet ) ) {
readFromSSDPSocket( ssdpSock );
}
if( FD_ISSET( miniServStopSock, &rdSet ) ) {
clientLen = sizeof( struct sockaddr_in );
memset( ( char * )&clientAddr, 0,
sizeof( struct sockaddr_in ) );
@ -479,7 +456,6 @@ RunMiniServer( MiniServerSockArray * miniSock )
UpnpPrintf( UPNP_PACKET, MSERV, __FILE__, __LINE__,
"Received multicast packet: \n %s\n",
requestBuf );
if( NULL != strstr( requestBuf, "ShutDown" ) ) {
break;
}
@ -494,31 +470,30 @@ RunMiniServer( MiniServerSockArray * miniSock )
UpnpCloseSocket( miniServStopSock );
shutdown( ssdpSock, SD_BOTH );
UpnpCloseSocket( ssdpSock );
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ) );
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ) );
#ifdef INCLUDE_CLIENT_APIS
shutdown( ssdpReqSock, SD_BOTH );
UpnpCloseSocket( ssdpReqSock );
#endif
free( miniSock );
gMServState = MSERV_IDLE;
return;
}
/************************************************************************
* Function : get_port
*
* Parameters :
* int sockfd ; Socket Descriptor
*
* Description : Returns port to which socket, sockfd, is bound.
*
* Return : int,
* -1 on error; check errno
* > 0 means port number
*
* Note :
************************************************************************/
* Function: get_port
*
* Parameters:
* int sockfd - Socket Descriptor
*
* Description:
* Returns port to which socket, sockfd, is bound.
*
* Return: int
* -1 on error; check errno
* > 0 means port number
************************************************************************/
static int
get_port( int sockfd )
{
@ -541,28 +516,28 @@ get_port( int sockfd )
}
/************************************************************************
* Function : get_miniserver_sockets
*
* Parameters :
* MiniServerSockArray *out ; Socket Array
* unsigned short listen_port ; port on which the server is listening
* for incoming connections
*
* Description : Creates a STREAM socket, binds to INADDR_ANY and
* listens for incoming connecttions. Returns the actual port which
* the sockets sub-system returned.
* Also creates a DGRAM socket, binds to the loop back address and
* returns the port allocated by the socket sub-system.
*
* Return : int :
* UPNP_E_OUTOF_SOCKET - Failed to create a socket
* UPNP_E_SOCKET_BIND - Bind() failed
* UPNP_E_LISTEN - Listen() failed
* UPNP_E_INTERNAL_ERROR - Port returned by the socket layer is < 0
* UPNP_E_SUCCESS - Success
*
* Note :
************************************************************************/
* Function: get_miniserver_sockets
*
* Parameters:
* MiniServerSockArray *out - Socket Array
* unsigned short listen_port - port on which the server is
* listening for incoming connections
*
* Description:
* Creates a STREAM socket, binds to INADDR_ANY and listens for
* incoming connecttions. Returns the actual port which the sockets
* sub-system returned.
*
* Also creates a DGRAM socket, binds to the loop back address and
* returns the port allocated by the socket sub-system.
*
* Return: int
* UPNP_E_OUTOF_SOCKET - Failed to create a socket
* UPNP_E_SOCKET_BIND - Bind() failed
* UPNP_E_LISTEN - Listen() failed
* UPNP_E_INTERNAL_ERROR - Port returned by the socket layer is < 0
* UPNP_E_SUCCESS - Success
************************************************************************/
int
get_miniserver_sockets( MiniServerSockArray * out,
unsigned short listen_port )
@ -692,8 +667,8 @@ get_miniserver_sockets( MiniServerSockArray * out,
miniStopSockPort = get_port( miniServerStopSock );
if( miniStopSockPort <= 0 ) {
shutdown( miniServerStopSock, SD_BOTH );
shutdown( listenfd, SD_BOTH );
UpnpCloseSocket( miniServerStopSock );
shutdown( listenfd, SD_BOTH );
UpnpCloseSocket( listenfd );
return UPNP_E_INTERNAL_ERROR;
}
@ -708,31 +683,29 @@ get_miniserver_sockets( MiniServerSockArray * out,
}
/************************************************************************
* Function : StartMiniServer
*
* Parameters :
* unsigned short listen_port ; Port on which the server listens for
* incoming connections
*
* Description : Initialize the sockets functionality for the
* Miniserver. Initialize a thread pool job to run the MiniServer
* and the job to the thread pool. If listen port is 0, port is
* dynamically picked
*
* Use timer mechanism to start the MiniServer, failure to meet the
* allowed delay aborts the attempt to launch the MiniServer.
*
* Return : int ;
* Actual port socket is bound to - On Success:
* A negative number UPNP_E_XXX - On Error
* Note :
************************************************************************/
* Function: StartMiniServer
*
* Parameters :
* unsigned short listen_port - Port on which the server listens for
* incoming connections
*
* Description:
* Initialize the sockets functionality for the
* Miniserver. Initialize a thread pool job to run the MiniServer
* and the job to the thread pool. If listen port is 0, port is
* dynamically picked
*
* Use timer mechanism to start the MiniServer, failure to meet the
* allowed delay aborts the attempt to launch the MiniServer.
*
* Return: int
* Actual port socket is bound to - On Success
* A negative number UPNP_E_XXX - On Error
************************************************************************/
int
StartMiniServer( unsigned short listen_port )
{
int success;
int count;
int max_count = 10000;
@ -755,12 +728,10 @@ StartMiniServer( unsigned short listen_port )
}
if( ( success = get_ssdp_sockets( miniSocket ) ) != UPNP_E_SUCCESS ) {
shutdown( miniSocket->miniServerSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerSock );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
free( miniSocket );
return success;
@ -776,14 +747,15 @@ StartMiniServer( unsigned short listen_port )
if( success < 0 ) {
shutdown( miniSocket->miniServerSock, SD_BOTH );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
shutdown( miniSocket->ssdpSock, SD_BOTH );
CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );
UpnpCloseSocket( miniSocket->miniServerSock );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
shutdown( miniSocket->ssdpSock, SD_BOTH );
UpnpCloseSocket( miniSocket->ssdpSock );
CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );
#ifdef INCLUDE_CLIENT_APIS
shutdown( miniSocket->ssdpReqSock, SD_BOTH );
UpnpCloseSocket( miniSocket->ssdpReqSock );
#endif
return UPNP_E_OUTOF_MEMORY;
}
@ -796,16 +768,16 @@ StartMiniServer( unsigned short listen_port )
// taking too long to start that thread
if( count >= max_count ) {
shutdown( miniSocket->miniServerSock, SD_BOTH );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
shutdown( miniSocket->ssdpSock, SD_BOTH );
CLIENTONLY( shutdown( miniSocket->ssdpReqSock, SD_BOTH ) );
UpnpCloseSocket( miniSocket->miniServerSock );
shutdown( miniSocket->miniServerStopSock, SD_BOTH );
UpnpCloseSocket( miniSocket->miniServerStopSock );
shutdown( miniSocket->ssdpSock, SD_BOTH );
UpnpCloseSocket( miniSocket->ssdpSock );
CLIENTONLY( UpnpCloseSocket( miniSocket->ssdpReqSock ) );
#ifdef INCLUDE_CLIENT_APIS
shutdown( miniSocket->ssdpReqSock, SD_BOTH );
UpnpCloseSocket( miniSocket->ssdpReqSock );
#endif
return UPNP_E_INTERNAL_ERROR;
}
@ -814,33 +786,33 @@ StartMiniServer( unsigned short listen_port )
}
/************************************************************************
* Function : StopMiniServer
*
* Parameters :
* void ;
*
* Description : Stop and Shutdown the MiniServer and free socket
* resources.
*
* Return : int ;
* Always returns 0
*
* Note :
************************************************************************/
* Function: StopMiniServer
*
* Parameters:
* void
*
* Description:
* Stop and Shutdown the MiniServer and free socket
* resources.
*
* Return: int
* Always returns 0
************************************************************************/
int
StopMiniServer( void )
{
int socklen = sizeof( struct sockaddr_in ),
sock;
int socklen = sizeof( struct sockaddr_in );
int sock;
struct sockaddr_in ssdpAddr;
char buf[256] = "ShutDown";
int bufLen = strlen( buf );
if( gMServState == MSERV_RUNNING )
if( gMServState == MSERV_RUNNING ) {
gMServState = MSERV_STOPPING;
else
} else {
return 0;
}
sock = socket( AF_INET, SOCK_DGRAM, 0 );
if( sock == UPNP_INVALID_SOCKET ) {
@ -864,3 +836,4 @@ StopMiniServer( void )
UpnpCloseSocket( sock );
return 0;
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -555,7 +555,7 @@ parse_hostport( const char *in,
int begin_port;
int hostport_size = 0;
int host_size = 0;
#ifndef WIN32
#if !defined(WIN32) && !defined(__OSX__)
char temp_hostbyname_buff[BUFFER_SIZE];
struct hostent h_buf;
#endif
@ -626,27 +626,35 @@ parse_hostport( const char *in,
// TODO: Use autoconf to discover this rather than the
// platform-specific stuff below
#if defined(WIN32) || defined(__CYGWIN__)
h=gethostbyname(temp_host_name);
h = gethostbyname(temp_host_name);
#elif defined(SPARC_SOLARIS)
errCode = gethostbyname_r( temp_host_name,
errCode = gethostbyname_r(
temp_host_name,
&h,
temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
#elif defined(__FreeBSD__) && __FreeBSD_version < 601103
h = lwres_gethostbyname_r( temp_host_name,
h = lwres_gethostbyname_r(
temp_host_name,
&h_buf,
temp_hostbyname_buff,
BUFFER_SIZE, &errcode );
if ( h == NULL ) {
errCode = 1;
}
#elif defined(__OSX__)
h = gethostbyname(temp_host_name);
if ( h == NULL ) {
errCode = 1;
}
#elif defined(__linux__)
errCode = gethostbyname_r( temp_host_name,
errCode = gethostbyname_r(
temp_host_name,
&h_buf,
temp_hostbyname_buff,
BUFFER_SIZE, &h, &errcode );
#else
{
{
struct addrinfo hints, *res, *res0;
h = NULL;
@ -671,9 +679,8 @@ parse_hostport( const char *in,
}
freeaddrinfo(res0);
}
}
}
#endif
if( errCode == 0 ) {
if( h ) {
if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {

View File

@ -261,7 +261,7 @@
/** @name Other debugging features
The UPnP SDK contains other features to aid in debugging:
see <upnp/upnpdebug.h>
see <upnp/inc/upnpdebug.h>
*/
#define DEBUG_ALL 1

View File

@ -50,73 +50,78 @@ int
http_CancelHttpGet( IN void *Handle );
/************************************************************************
* Function: http_FixUrl
*
* Parameters:
* IN uri_type* url ; URL to be validated and fixed
* OUT uri_type* fixed_url ; URL after being fixed.
*
* Description: Validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
* Function: http_FixUrl
*
* Parameters:
* IN uri_type* url; URL to be validated and fixed
* OUT uri_type* fixed_url; URL after being fixed.
*
* Description:
* Validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
int http_FixUrl( IN uri_type* url, OUT uri_type* fixed_url );
/************************************************************************
* Function: http_FixStrUrl
*
* Parameters:
* IN char* urlstr ; Character string as a URL
* IN int urlstrlen ; Length of the character string
* OUT uri_type* fixed_url ; Fixed and corrected URL
*
* Description: Parses URL and then validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
* Function: http_FixStrUrl
*
* Parameters:
* IN char* urlstr ; Character string as a URL
* IN int urlstrlen ; Length of the character string
* OUT uri_type* fixed_url ; Fixed and corrected URL
*
* Description:
* Parses URL and then validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
int http_FixStrUrl( IN char* urlstr, IN int urlstrlen, OUT uri_type* fixed_url );
/************************************************************************
* Function: http_Connect
*
* Parameters:
* IN uri_type* destination_url ; URL containing destination information
* OUT uri_type *url ; Fixed and corrected URL
*
* Description: Gets destination address from URL and then connects to the
* remote end
*
* Returns:
* socket descriptor on sucess
* UPNP_E_OUTOF_SOCKET
* UPNP_E_SOCKET_CONNECT on error
************************************************************************/
* Function: http_Connect
*
* Parameters:
* IN uri_type* destination_url; URL containing destination information
* OUT uri_type *url; Fixed and corrected URL
*
* Description:
* Gets destination address from URL and then connects to the remote end
*
* Returns:
* socket descriptor on sucess
* UPNP_E_OUTOF_SOCKET
* UPNP_E_SOCKET_CONNECT on error
************************************************************************/
int http_Connect( IN uri_type* destination_url, OUT uri_type *url );
/************************************************************************
* Function: http_RecvMessage
*
* Parameters:
* IN SOCKINFO *info ; Socket information object
* OUT http_parser_t* parser, HTTP parser object
* IN http_method_t request_method ; HTTP request method
* IN OUT int* timeout_secs ; time out
* OUT int* http_error_code ; HTTP error code returned
*
* Description: Get the data on the socket and take actions based on the
* read data to modify the parser objects buffer. If an error is reported
* while parsing the data, the error code is passed in the http_errr_code
* parameter
*
* Returns:
* UPNP_E_BAD_HTTPMSG
* UPNP_E_SUCCESS
************************************************************************/
* Function: http_RecvMessage
*
* Parameters:
* IN SOCKINFO *info; Socket information object
* OUT http_parser_t* parser; HTTP parser object
* IN http_method_t request_method; HTTP request method
* IN OUT int* timeout_secs; time out
* OUT int* http_error_code; HTTP error code returned
*
* Description:
* Get the data on the socket and take actions based on the read data
* to modify the parser objects buffer. If an error is reported while
* parsing the data, the error code is passed in the http_errr_code
* parameter
*
* Returns:
* UPNP_E_BAD_HTTPMSG
* UPNP_E_SUCCESS
************************************************************************/
int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
IN http_method_t request_method,
IN OUT int* timeout_secs,
@ -124,302 +129,311 @@ int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
/************************************************************************
* Function: http_SendMessage
*
* Parameters:
* IN SOCKINFO *info ; Socket information object
* IN OUT int * TimeOut ; time out value
* IN const char* fmt, ... Pattern format to take actions upon
*
* Description: Sends a message to the destination based on the
* IN const char* fmt parameter
* fmt types:
* 'f': arg = const char * file name
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
* E.g.:
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* char *filename = "foo.dat";
* int status = http_SendMessage( tcpsock, "mf",
* buf, strlen(buf), // args for memory buffer
* filename ); // arg for file
*
* Returns:
* UPNP_E_OUTOF_MEMORY
* UPNP_E_FILE_READ_ERROR
* UPNP_E_SUCCESS
************************************************************************/
int http_SendMessage( IN SOCKINFO *info, IN OUT int* timeout_secs,
* Function: http_SendMessage
*
* Parameters:
* IN SOCKINFO *info ; Socket information object
* IN OUT int * TimeOut ; time out value
* IN const char* fmt, ... Pattern format to take actions upon
*
* Description:
* Sends a message to the destination based on the
* IN const char* fmt parameter
* fmt types:
* 'f': arg = const char * file name
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
* E.g.:
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* char *filename = "foo.dat";
* int status = http_SendMessage( tcpsock, "mf",
* buf, strlen(buf), // args for memory buffer
* filename ); // arg for file
*
* Returns:
* UPNP_E_OUTOF_MEMORY
* UPNP_E_FILE_READ_ERROR
* UPNP_E_SUCCESS
************************************************************************/
int http_SendMessage(
IN SOCKINFO *info,
IN OUT int* timeout_secs,
IN const char* fmt, ... );
/************************************************************************
* Function: http_RequestAndResponse
*
* Parameters:
* IN uri_type* destination ; Destination URI object which contains
* remote IP address among other elements
* IN const char* request ; Request to be sent
* IN size_t request_length ; Length of the request
* IN http_method_t req_method ; HTTP Request method
* IN int timeout_secs ; time out value
* OUT http_parser_t* response ; Parser object to receive the repsonse
*
* Description: Initiates socket, connects to the destination, sends a
* request and waits for the response from the remote end
*
* Returns:
* UPNP_E_SOCKET_ERROR
* UPNP_E_SOCKET_CONNECT
* Error Codes returned by http_SendMessage
* Error Codes returned by http_RecvMessage
************************************************************************/
int http_RequestAndResponse( IN uri_type* destination,
IN const char* request, IN size_t request_length,
* Function: http_RequestAndResponse
*
* Parameters:
* IN uri_type* destination; Destination URI object which contains
* remote IP address among other elements
* IN const char* request; Request to be sent
* IN size_t request_length; Length of the request
* IN http_method_t req_method; HTTP Request method
* IN int timeout_secs; time out value
* OUT http_parser_t* response; Parser object to receive the repsonse
*
* Description:
* Initiates socket, connects to the destination, sends a
* request and waits for the response from the remote end
*
* Returns:
* UPNP_E_SOCKET_ERROR
* UPNP_E_SOCKET_CONNECT
* Error Codes returned by http_SendMessage
* Error Codes returned by http_RecvMessage
************************************************************************/
int http_RequestAndResponse(
IN uri_type* destination,
IN const char* request,
IN size_t request_length,
IN http_method_t req_method,
IN int timeout_secs,
OUT http_parser_t* response );
/************************************************************************
* return codes:
* 0 -- success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_TIMEDOUT
* UPNP_E_BAD_REQUEST
* UPNP_E_BAD_RESPONSE
* UPNP_E_INVALID_URL
* UPNP_E_SOCKET_READ
* UPNP_E_SOCKET_WRITE
************************************************************************/
/************************************************************************
* Function : http_Download
*
* Parameters :
* IN const char* url_str : String as a URL
* IN int timeout_secs : time out value
* OUT char** document : buffer to store the document extracted
* from the donloaded message.
* OUT int* doc_length : length of the extracted document
* OUT char* content_type : Type of content
*
* Description : Download the document message and extract the document
* from the message.
*
* Return : int;
* UPNP_E_SUCCESS;
* UPNP_E_INVALID_URL;
*
*
* Note :
************************************************************************/
int http_Download( IN const char* url,
* return codes:
* 0 -- success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_TIMEDOUT
* UPNP_E_BAD_REQUEST
* UPNP_E_BAD_RESPONSE
* UPNP_E_INVALID_URL
* UPNP_E_SOCKET_READ
* UPNP_E_SOCKET_WRITE
************************************************************************/
/************************************************************************
* Function: http_Download
*
* Parameters:
* IN const char* url_str; String as a URL
* IN int timeout_secs; time out value
* OUT char** document; buffer to store the document extracted
* from the donloaded message.
* OUT int* doc_length; length of the extracted document
* OUT char* content_type; Type of content
*
* Description:
* Download the document message and extract the document
* from the message.
*
* Return: int
* UPNP_E_SUCCESS
* UPNP_E_INVALID_URL
************************************************************************/
int http_Download(
IN const char* url,
IN int timeout_secs,
OUT char** document, OUT int* doc_length,
OUT char** document,
OUT int* doc_length,
OUT char* content_type );
/************************************************************************
* Function : http_WriteHttpPost
*
* Parameters :
* IN void *Handle : Handle to the http post object
* IN char *buf : Buffer to send to peer, if format used
* is not UPNP_USING_CHUNKED,
* IN unsigned int *size : Size of the data to be sent.
* IN int timeout : time out value
*
* Description : Formats data if format used is UPNP_USING_CHUNKED.
* Writes data on the socket connected to the peer.
*
* Return : int ;
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Parameter
* -1 - On Socket Error.
*
* Note :
************************************************************************/
* Function: http_WriteHttpPost
*
* Parameters:
* IN void *Handle: Handle to the http post object
* IN char *buf: Buffer to send to peer, if format used
* is not UPNP_USING_CHUNKED,
* IN unsigned int *size: Size of the data to be sent.
* IN int timeout: time out value
*
* Description:
* Formats data if format used is UPNP_USING_CHUNKED.
* Writes data on the socket connected to the peer.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Parameter
* -1 - On Socket Error.
************************************************************************/
int http_WriteHttpPost(IN void *Handle,
IN char *buf,
IN unsigned int *size,
IN int timeout);
/************************************************************************
* Function : http_CloseHttpPost
*
* Parameters :
* IN void *Handle : Handle to the http post object
* IN OUT int *httpStatus : HTTP status returned on receiving a
* response message
* IN int timeout : time out value
*
* Description : Sends remaining data if using UPNP_USING_CHUNKED
* format. Receives any more messages. Destroys socket and any socket
* associated memory. Frees handle associated with the HTTP POST msg.
*
* Return : int ;
* UPNP_E_SUCCESS - On Sucess ;
* UPNP_E_INVALID_PARAM - Invalid Parameter;
*
* Note :
************************************************************************/
* Function: http_CloseHttpPost
*
* Parameters:
* IN void *Handle; Handle to the http post object
* IN OUT int *httpStatus; HTTP status returned on receiving a
* response message
* IN int timeout; time out value
*
* Description:
* Sends remaining data if using UPNP_USING_CHUNKED
* format. Receives any more messages. Destroys socket and any socket
* associated memory. Frees handle associated with the HTTP POST msg.
*
* Return: int
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_INVALID_PARAM - Invalid Parameter
************************************************************************/
int http_CloseHttpPost(IN void *Handle,
IN OUT int *httpStatus,
IN int timeout);
/************************************************************************
* Function : http_OpenHttpPost
*
* Parameters :
* IN const char *url_str : String as a URL
* IN OUT void **Handle : Pointer to buffer to store HTTP
* post handle
* IN const char *contentType : Type of content
* IN int contentLength : length of content
* IN int timeout : time out value
*
* Description : Makes the HTTP POST message, connects to the peer,
* sends the HTTP POST request. Adds the post handle to buffer of
* such handles
*
* Return : int;
* UPNP_E_SUCCESS - On Sucess ;
* UPNP_E_INVALID_PARAM - Invalid Paramter ;
* UPNP_E_OUTOF_MEMORY ;
* UPNP_E_SOCKET_ERROR ;
* UPNP_E_SOCKET_CONNECT ;
*
* Note :
************************************************************************/
* Function: http_OpenHttpPost
*
* Parameters:
* IN const char *url_str; String as a URL
* IN OUT void **Handle; Pointer to buffer to store HTTP
* post handle
* IN const char *contentType; Type of content
* IN int contentLength; length of content
* IN int timeout; time out value
*
* Description:
* Makes the HTTP POST message, connects to the peer,
* sends the HTTP POST request. Adds the post handle to buffer of
* such handles
*
* Return : int;
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_INVALID_PARAM - Invalid Parameter
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_SOCKET_CONNECT
************************************************************************/
int http_OpenHttpPost(IN const char *url_str,
IN OUT void **Handle,
IN const char *contentType,
IN int contentLength,
IN int timeout);
/************************************************************************
* Function : http_ReadHttpGet
*
* Parameters :
* IN void *Handle : Handle to the HTTP get object
* IN OUT char *buf : Buffer to get the read and parsed data
* IN OUT unsigned int *size : Size of tge buffer passed
* IN int timeout : time out value
*
* Description : Parses already existing data, then gets new data.
* Parses and extracts information from the new data.
*
* Return : int ;
* UPNP_E_SUCCESS - On Sucess ;
* UPNP_E_INVALID_PARAM - Invalid Parameter;
* UPNP_E_BAD_RESPONSE ;
* UPNP_E_BAD_HTTPMSG ;
*
* Note :
************************************************************************/
int http_ReadHttpGet(IN void *Handle,
* Function: http_ReadHttpGet
*
* Parameters:
* IN void *Handle; Handle to the HTTP get object
* IN OUT char *buf; Buffer to get the read and parsed data
* IN OUT unsigned int *size; Size of the buffer passed
* IN int timeout; time out value
*
* Description:
* Parses already existing data, then gets new data.
* Parses and extracts information from the new data.
*
* Return: int
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_INVALID_PARAM - Invalid Parameter
* UPNP_E_BAD_RESPONSE
* UPNP_E_BAD_HTTPMSG
* UPNP_E_CANCELED
************************************************************************/
int http_ReadHttpGet(
IN void *Handle,
IN OUT char *buf,
IN OUT unsigned int *size,
IN int timeout);
/************************************************************************
* Function : http_HttpGetProgress
*
* Parameters :
* IN void *Handle : Handle to the HTTP get object
* OUT unsigned int *length : Buffer to get the read and parsed data
* OUT unsigned int *total : Size of tge buffer passed
*
* Description : Extracts information from the Handle to the HTTP get
* object.
*
* Return : int ;
* UPNP_E_SUCCESS - On Sucess ;
* UPNP_E_INVALID_PARAM - Invalid Parameter;
*
* Note :
************************************************************************/
int http_HttpGetProgress(IN void *Handle,
* Function: http_HttpGetProgress
*
* Parameters:
* IN void *Handle; Handle to the HTTP get object
* OUT unsigned int *length; Buffer to get the read and parsed data
* OUT unsigned int *total; Size of tge buffer passed
*
* Description:
* Extracts information from the Handle to the HTTP get object.
*
* Return: int
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_INVALID_PARAM - Invalid Parameter
************************************************************************/
int http_HttpGetProgress(
IN void *Handle,
OUT unsigned int *length,
OUT unsigned int *total );
/************************************************************************
* Function : http_CloseHttpGet
*
* Parameters :
* IN void *Handle ; Handle to HTTP get object
*
* Description : Clears the handle allocated for the HTTP GET operation
* Clears socket states and memory allocated for socket operations.
*
* Return : int ;
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Parameter
*
* Note :
************************************************************************/
int http_CloseHttpGet(IN void *Handle);
/************************************************************************
* Function : http_OpenHttpGet
*
* Parameters :
* IN const char *url_str : String as a URL
* IN OUT void **Handle : Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType : Type of content
* OUT int *contentLength : length of content
* OUT int *httpStatus : HTTP status returned on receiving a
* response message
* IN int timeout : time out value
*
* Description : Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return : int;
* UPNP_E_SUCCESS - On Success ;
* UPNP_E_INVALID_PARAM - Invalid Paramters ;
* UPNP_E_OUTOF_MEMORY ;
* UPNP_E_SOCKET_ERROR ;
* UPNP_E_BAD_RESPONSE ;
*
* Note :
*
************************************************************************/
int http_OpenHttpGet(IN const char *url_str,
* Function: http_CloseHttpGet
*
* Parameters:
* IN void *Handle; Handle to HTTP get object
*
* Description:
* Clears the handle allocated for the HTTP GET operation
* Clears socket states and memory allocated for socket operations.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Parameter
************************************************************************/
int http_CloseHttpGet(IN void *Handle);
/************************************************************************
* Function: http_OpenHttpGet
*
* Parameters:
* IN const char *url_str: String as a URL
* IN OUT void **Handle: Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType: Type of content
* OUT int *contentLength: length of content
* OUT int *httpStatus: HTTP status returned on receiving a
* response message
* IN int timeout: time out value
*
* Description:
* Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Paramters
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE
************************************************************************/
int http_OpenHttpGet(
IN const char *url_str,
IN OUT void **Handle,
IN OUT char **contentType,
OUT int *contentLength,
OUT int *httpStatus,
IN int timeout);
/************************************************************************
* Function : http_OpenHttpGetProxy
*
* Parameters :
* IN const char *url_str : String as a URL
* IN const char *proxy_str : String as a URL to the proxy
* IN OUT void **Handle : Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType : Type of content
* OUT int *contentLength : length of content
* OUT int *httpStatus : HTTP status returned on receiving a
* response message
* IN int timeout : time out value
*
* Description : Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return : int;
* UPNP_E_SUCCESS - On Success ;
* UPNP_E_INVALID_PARAM - Invalid Paramters ;
* UPNP_E_OUTOF_MEMORY ;
* UPNP_E_SOCKET_ERROR ;
* UPNP_E_BAD_RESPONSE ;
*
* Note :
*
************************************************************************/
* Function: http_OpenHttpGetProxy
*
* Parameters:
* IN const char *url_str; String as a URL
* IN const char *proxy_str; String as a URL
* IN OUT void **Handle; Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType; Type of content
* OUT int *contentLength; length of content
* OUT int *httpStatus; HTTP status returned on receiving a
* response message
* IN int timeout: time out value
*
* Description:
* Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the response.
* If a proxy URL is defined then the connection is made there.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Paramters
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE
************************************************************************/
int http_OpenHttpGetProxy(IN const char *url_str,
IN const char *proxy_str,
IN OUT void **Handle,
@ -430,126 +444,134 @@ int http_OpenHttpGetProxy(IN const char *url_str,
/************************************************************************
* Function : http_SendStatusResponse
*
* Parameters :
* IN SOCKINFO *info : Socket information object
* IN int http_status_code : error code returned while making
* or sending the response message
* IN int request_major_version : request major version
* IN int request_minor_version : request minor version
*
* Description : Generate a response message for the status query and
* send the status response.
*
* Return : int;
* 0 -- success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_WRITE
* UPNP_E_TIMEDOUT
*
* Note :
************************************************************************/
int http_SendStatusResponse( IN SOCKINFO *info, IN int http_status_code,
* Function: http_SendStatusResponse
*
* Parameters:
* IN SOCKINFO *info; Socket information object
* IN int http_status_code; error code returned while making
* or sending the response message
* IN int request_major_version; request major version
* IN int request_minor_version; request minor version
*
* Description:
* Generate a response message for the status query and send the
* status response.
*
* Return: int
* 0 -- success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_WRITE
* UPNP_E_TIMEDOUT
************************************************************************/
int http_SendStatusResponse(
IN SOCKINFO *info,
IN int http_status_code,
IN int request_major_version,
IN int request_minor_version );
/************************************************************************
* Function : http_MakeMessage
*
* Parameters :
* INOUT membuffer* buf : buffer with the contents of the
* message
* IN int http_major_version : HTTP major version
* IN int http_minor_version : HTTP minor version
* IN const char* fmt : Pattern format
* ... :
*
* Description : Generate an HTTP message based on the format that is
* specified in the input parameters.
*
* fmt types:
* 's': arg = const char* C_string
* 'b': arg1 = const char* buf; arg2 = size_t buf_length
* memory ptr
* 'c': (no args) appends CRLF "\r\n"
* 'd': arg = int number // appends decimal number
* 'h': arg = off_t number // appends off_t number
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
* 'D': (no args) appends HTTP DATE: header
* 'S': (no args) appends HTTP SERVER: header
* 'U': (no args) appends HTTP USER-AGENT: header
* 'C': (no args) appends a HTTP CONNECTION: close header
* depending on major,minor version
* 'N': arg1 = int content_length // content-length header
* 'Q': arg1 = http_method_t; arg2 = char* url;
* arg3 = int url_length // start line of request
* 'R': arg = int status_code // adds a response start line
* 'B': arg = int status_code
* appends content-length, content-type and HTML body for given code
* 'T': arg = char * content_type; format e.g: "text/html";
* content-type header
*
* Return : int;
* 0 - On Success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_INVALID_URL;
*
* Note :
************************************************************************/
int http_MakeMessage( INOUT membuffer* buf,
* Function: http_MakeMessage
*
* Parameters:
* INOUT membuffer* buf; buffer with the contents of the
* message
* IN int http_major_version; HTTP major version
* IN int http_minor_version; HTTP minor version
* IN const char* fmt; Pattern format
* ...;
*
* Description:
* Generate an HTTP message based on the format that is specified
* in the input parameters.
*
* fmt types:
* 'B': arg = int status_code
* appends content-length, content-type and HTML body
* for given code
* 'b': arg1 = const char* buf;
* arg2 = size_t buf_length memory ptr
* 'C': (no args) appends a HTTP CONNECTION: close header
* depending on major,minor version
* 'c': (no args) appends CRLF "\r\n"
* 'D': (no args) appends HTTP DATE: header
* 'd': arg = int number // appends decimal number
* 'G': arg = range information // add range header
* 'h': arg = off_t number // appends off_t number
* 'K': (no args) // add chunky header
* 'N': arg1 = off_t content_length // content-length header
* 'q': arg1 = http_method_t // request start line and HOST header
* arg2 = (uri_type *)
* 'Q': arg1 = http_method_t; // start line of request
* arg2 = char* url;
* arg3 = size_t url_length
* 'R': arg = int status_code // adds a response start line
* 'S': (no args) appends HTTP SERVER: header
* 's': arg = const char* C_string
* 'T': arg = char * content_type; format
* e.g: "text/html"; content-type header
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
* 'U': (no args) appends HTTP USER-AGENT: header
* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent
*
* Return: int
* 0 - On Success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_INVALID_URL
************************************************************************/
int http_MakeMessage(
INOUT membuffer* buf,
IN int http_major_version,
IN int http_minor_version,
IN const char* fmt, ... );
/************************************************************************
* Function : http_CalcResponseVersion
*
* Parameters :
* IN int request_major_vers : Request major version
* IN int request_minor_vers : Request minor version
* OUT int* response_major_vers : Response mojor version
* OUT int* response_minor_vers : Response minor version
*
* Description : Calculate HTTP response versions based on the request
* versions.
*
* Return : void
*
* Note :
************************************************************************/
void http_CalcResponseVersion(
IN int request_major_vers, IN int request_minor_vers,
OUT int* response_major_vers, OUT int* response_minor_vers );
/************************************************************************
* Function : http_OpenHttpGetEx
*
* Parameters :
* IN const char *url_str : String as a URL
* IN OUT void **Handle : Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType : Type of content
* OUT int *contentLength : length of content
* OUT int *httpStatus : HTTP status returned on receiving a
* response message
* IN int timeout : time out value
*
* Description : Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return : int;
* UPNP_E_SUCCESS - On Success ;
* UPNP_E_INVALID_PARAM - Invalid Paramters ;
* UPNP_E_OUTOF_MEMORY ;
* UPNP_E_SOCKET_ERROR ;
* UPNP_E_BAD_RESPONSE ;
*
* Note :
*
************************************************************************/
* Function: http_CalcResponseVersion
*
* Parameters:
* IN int request_major_vers; Request major version
* IN int request_minor_vers; Request minor version
* OUT int* response_major_vers; Response mojor version
* OUT int* response_minor_vers; Response minor version
*
* Description:
* Calculate HTTP response versions based on the request versions.
*
* Return: void
************************************************************************/
void http_CalcResponseVersion(
IN int request_major_vers,
IN int request_minor_vers,
OUT int* response_major_vers,
OUT int* response_minor_vers );
/************************************************************************
* Function: http_OpenHttpGetEx
*
* Parameters:
* IN const char *url_str; String as a URL
* IN OUT void **Handle; Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType; Type of content
* OUT int *contentLength; length of content
* OUT int *httpStatus; HTTP status returned on receiving a
* response message
* IN int timeout; time out value
*
* Description:
* Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Paramters
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE
************************************************************************/
int http_OpenHttpGetEx(IN const char *url_str,
IN OUT void **Handle,
IN OUT char **contentType,
@ -559,19 +581,19 @@ int http_OpenHttpGetEx(IN const char *url_str,
IN int highRange,
IN int timeout);
/************************************************************************
* Function : get_sdk_info
*
* Parameters :
* OUT char *info ;
*
* Description : Returns the server information for the operating
* system
*
* Return : void ;
*
* Note :
************************************************************************/
* Function: get_sdk_info
*
* Parameters:
* OUT char *info; buffer to store the operating system information
*
* Description:
* Returns the server information for the operating system
*
* Return:
* UPNP_INLINE void
************************************************************************/
void get_sdk_info( OUT char *info );
#ifdef __cplusplus
@ -580,3 +602,4 @@ void get_sdk_info( OUT char *info );
#endif // GENLIB_NET_HTTP_HTTPREADWRITE_H

View File

@ -98,18 +98,25 @@ struct Handle_Info
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);
#define HandleLock() \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying Lock"); \
ithread_mutex_lock(&GlobalHndMutex); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "LOCK");
#define HandleLock() HandleWriteLock()
#define HandleWriteLock() \
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() \
UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \
ithread_mutex_unlock(&GlobalHndMutex); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlock");
ithread_rwlock_unlock(&GlobalHndRWLock); \
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlocked rwlock");
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
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
HandleLock();
HandleReadLock();
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
HandleUnlock();
@ -538,8 +538,7 @@ SearchByTarget( IN int Mx,
if( ReqBuf == NULL )
return UPNP_E_OUTOF_MEMORY;
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND >>>\n%s\n", ReqBuf );
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n");
timeTillRead = Mx;

View File

@ -242,7 +242,7 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
// "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
// 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
//
@ -530,7 +530,6 @@ SendReply( IN struct sockaddr_in *DestAddr,
* IN char * Udn: Device UDN
* IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device.
* Description:
* This function creates the reply packet based on the input parameter,
* and send it to the client address given in its input parameter DestAddr.
@ -607,11 +606,9 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
* IN char *ServType: Service Type.
* IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device.
* Description:
* This function creates the advertisement packet based
* on the input parameter, and send it to the multicast channel.
*
* Returns: int
* UPNP_E_SUCCESS if successful else appropriate error
@ -656,11 +653,9 @@ ServiceAdvertisement( IN char *Udn,
* IN char *ServType: Service Type.
* IN char * Location: Location of Device description document.
* IN int Duration :Life time of this device.
* Description:
* This function creates the advertisement packet based
* on the input parameter, and send it to the multicast channel.
*
* Returns: int
* UPNP_E_SUCCESS if successful else appropriate error
@ -700,7 +695,6 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
* IN char *ServType: Service Type.
* IN char * Location: Location of Device description document.
* IN int Duration :Service duration in sec.
* Description:
* This function creates a HTTP service shutdown request packet
* and sent it to the multicast channel through RequestHandler.
@ -821,3 +815,4 @@ DeviceShutdown( IN char *DevType,
#endif // EXCLUDE_SSDP
#endif // INCLUDE_DEVICE_APIS

View File

@ -75,7 +75,9 @@ CLIENTONLY( SOCKET gSsdpReqSocket = 0;
* Function : AdvertiseAndReply
*
* Parameters:
* IN int AdFlag: -1 = Send shutdown, 0 = send reply,
* IN int AdFlag:
* -1 = Send shutdown,
* 0 = send reply,
* 1 = Send Advertisement
* IN UpnpDevice_Handle Hnd: Device handle
* IN enum SsdpSearchType SearchType:Search type for sending replies
@ -120,16 +122,13 @@ int AdvertiseAndReply( IN int AdFlag,
"Inside AdvertiseAndReply with AdFlag = %d\n",
AdFlag );
HandleLock();
// Use a read lock
HandleReadLock();
if( GetHandleInfo( Hnd, &SInfo ) != HND_DEVICE ) {
HandleUnlock();
return UPNP_E_INVALID_HANDLE;
}
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;
//get server info
@ -151,14 +150,12 @@ int AdvertiseAndReply( IN int AdFlag,
dbgStr = ixmlNode_getNodeName( tmpNode );
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
"Extracting device type once for %s\n",
dbgStr );
"Extracting device type once for %s\n", dbgStr );
// extract device type
ixmlNodeList_free( nodeList );
nodeList = NULL;
nodeList =
ixmlElement_getElementsByTagName( ( IXML_Element * ) tmpNode,
"deviceType" );
nodeList = ixmlElement_getElementsByTagName(
( IXML_Element * ) tmpNode, "deviceType" );
if( nodeList == NULL ) {
continue;
}
@ -166,7 +163,6 @@ int AdvertiseAndReply( IN int AdFlag,
dbgStr = ixmlNode_getNodeName( tmpNode );
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Extracting UDN for %s\n", dbgStr );
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Extracting device type\n" );
@ -241,8 +237,7 @@ int AdvertiseAndReply( IN int AdFlag,
if( AdFlag == 1 ) {
DeviceAdvertisement( devType, i == 0,
UDNstr, SInfo->DescURL, Exp );
} else // AdFlag == -1
{
} else { // AdFlag == -1
DeviceShutdown( devType, i == 0, UDNstr,
SERVER, SInfo->DescURL, Exp );
}
@ -324,8 +319,9 @@ int AdvertiseAndReply( IN int AdFlag,
}
for( j = 0;; j++ ) {
tmpNode = ixmlNodeList_item( nodeList, j );
if( tmpNode == NULL )
if( tmpNode == NULL ) {
break;
}
ixmlNodeList_free( tmpNodeList );
tmpNodeList = NULL;
@ -367,26 +363,21 @@ int AdvertiseAndReply( IN int AdFlag,
} else {
switch ( SearchType ) {
case SSDP_ALL:
{
ServiceReply( DestAddr, servType,
UDNstr, SInfo->DescURL,
defaultExp );
break;
}
case SSDP_SERVICE:
{
if( ServiceType != NULL ) {
if( !strncasecmp( ServiceType,
servType,
strlen( ServiceType ) ) )
{
strlen( ServiceType ) ) ) {
ServiceReply( DestAddr, servType,
UDNstr, SInfo->DescURL,
defaultExp );
}
}
break;
}
default:
break;
} // switch(SearchType)
@ -401,7 +392,7 @@ int AdvertiseAndReply( IN int AdFlag,
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting AdvertiseAndReply : \n" );
HandleUnlock( );
HandleUnlock();
return UPNP_E_SUCCESS;
@ -819,18 +810,20 @@ readFromSSDPSocket( SOCKET socket )
( struct sockaddr * )&clientAddr, &socklen );
if( byteReceived > 0 ) {
requestBuf[byteReceived] = '\0';
UpnpPrintf( UPNP_INFO, SSDP,
__FILE__, __LINE__,
"Received response !!! "
"%s From host %s \n",
"Start of received response ----------------------------------------------------\n"
"%s\n"
"End of received response ------------------------------------------------------\n"
"From host %s\n",
requestBuf,
inet_ntoa( clientAddr.sin_addr ) );
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
"Received multicast packet:"
"\n %s\n", requestBuf );
"Start of received multicast packet --------------------------------------------\n"
"%s\n"
"End of received multicast packet ----------------------------------------------\n",
requestBuf );
//add thread pool job to handle request
if( data != NULL ) {
data->parser.msg.msg.length += byteReceived;
@ -869,8 +862,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
{
SOCKET ssdpSock;
CLIENTONLY( SOCKET ssdpReqSock;
)
CLIENTONLY( SOCKET ssdpReqSock; )
int onOff = 1;
u_char ttl = 4;
struct ip_mreq ssdpMcastAddr;
@ -878,20 +870,20 @@ get_ssdp_sockets( MiniServerSockArray * out )
int option = 1;
struct in_addr addr;
CLIENTONLY( if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
== UPNP_INVALID_SOCKET ) {
CLIENTONLY(
if( ( ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in socket operation !!!\n" );
return UPNP_E_OUTOF_SOCKET;}
setsockopt( ssdpReqSock,
IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
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
Make_Socket_NoBlocking( ssdpReqSock );
gSsdpReqSocket = ssdpReqSock; )
// END CLIENTONLY
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) )
== UPNP_INVALID_SOCKET ) {
if( ( ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 ) ) == UPNP_INVALID_SOCKET ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in socket operation !!!\n" );
@ -903,7 +895,6 @@ get_ssdp_sockets( MiniServerSockArray * out )
onOff = 1;
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
( char * )&onOff, sizeof( onOff ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in set reuse addr !!!\n" );
@ -917,7 +908,6 @@ get_ssdp_sockets( MiniServerSockArray * out )
#ifdef __FreeBSD__
if( setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
( char * )&onOff, sizeof( onOff ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in set reuse port !!!\n" );
@ -934,8 +924,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );
ssdpAddr.sin_port = htons( SSDP_PORT );
if( bind
( ssdpSock, ( struct sockaddr * )&ssdpAddr,
if( bind( ssdpSock, ( struct sockaddr * )&ssdpAddr,
sizeof( ssdpAddr ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
@ -951,8 +940,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
if( setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
( char * )&ssdpMcastAddr,
sizeof( struct ip_mreq ) ) != 0 ) {
( char * )&ssdpMcastAddr, sizeof( struct ip_mreq ) ) != 0 ) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in joining" " multicast group !!!\n" );
@ -966,7 +954,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
/* Set multicast interface. */
memset( ( void * )&addr, 0, sizeof( struct in_addr ));
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) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"Couldn't set multicast interface.\n" );
@ -977,7 +965,7 @@ get_ssdp_sockets( MiniServerSockArray * out )
setsockopt( ssdpSock, IPPROTO_IP,
IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
if( setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
( char * )&option, sizeof( option ) ) != 0 ) {
(char *)&option, sizeof(option) ) != 0) {
UpnpPrintf( UPNP_CRITICAL,
SSDP, __FILE__, __LINE__,
"Error in setting broadcast !!!\n" );
@ -988,10 +976,10 @@ get_ssdp_sockets( MiniServerSockArray * out )
return UPNP_E_NETWORK_ERROR;
}
CLIENTONLY( out->ssdpReqSock = ssdpReqSock;
);
CLIENTONLY( out->ssdpReqSock = ssdpReqSock; );
out->ssdpSock = ssdpSock;
return UPNP_E_SUCCESS;
}
#endif // EXCLUDE_SSDP

View File

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

View File

@ -33,17 +33,16 @@
This sample implementation generates a random node ID
*/
void
get_ieee_node_identifier( uuid_node_t * node )
get_ieee_node_identifier(uuid_node_t *node)
{
char seed[16];
static int inited = 0;
static uuid_node_t saved_node;
if( !inited ) {
get_random_info( seed );
if (!inited) {
get_random_info(seed);
seed[0] |= 0x80;
memcpy( &saved_node, seed, sizeof( uuid_node_t ) );
memcpy(&saved_node, seed, sizeof (uuid_node_t));
inited = 1;
};
@ -83,7 +82,7 @@ get_system_time( uuid_time_t * uuid_time )
/*-----------------------------------------------------------------------------*/
void
get_random_info( char seed[16] )
get_random_info(char seed[16])
{
MD5_CTX c;
typedef struct {
@ -97,38 +96,34 @@ get_random_info( char seed[16] )
} randomness;
randomness r;
MD5Init( &c );
/*
memory usage stats
*/
/* Initialize memory area so that valgrind does not complain */
memset(&r, 0, sizeof r);
/* memory usage stats */
GlobalMemoryStatus( &r.m );
/*
random system stats
*/
/* random system stats */
GetSystemInfo( &r.s );
/*
100ns resolution (nominally) time of day
*/
/* 100ns resolution (nominally) time of day */
GetSystemTimeAsFileTime( &r.t );
/*
high resolution performance counter
*/
/* high resolution performance counter */
QueryPerformanceCounter( &r.pc );
/*
milliseconds since last boot
*/
r.tc = GetTickCount( );
/* milliseconds since last boot */
r.tc = GetTickCount();
r.l = MAX_COMPUTERNAME_LENGTH + 1;
GetComputerName( r.hostname, &r.l );
MD5Update( &c, &r, sizeof( randomness ) );
MD5Final( seed, &c );
/* MD5 it */
MD5Init(&c);
MD5Update(&c, &r, sizeof r);
MD5Final(seed, &c);
};
#else
#else /* _WINDOWS_ */
/*-----------------------------------------------------------------------------*/
void
get_system_time( uuid_time_t * uuid_time )
get_system_time(uuid_time_t *uuid_time)
{
struct timeval tp;
@ -145,22 +140,28 @@ get_system_time( uuid_time_t * uuid_time )
/*-----------------------------------------------------------------------------*/
void
get_random_info( char seed[16] )
get_random_info(char seed[16])
{
MD5_CTX c;
typedef struct {
// struct sysinfo s;
//struct sysinfo s;
struct timeval t;
char hostname[257];
} randomness;
randomness r;
MD5Init( &c );
/* Initialize memory area so that valgrind does not complain */
memset(&r, 0, sizeof r);
gettimeofday( &r.t, ( struct timezone * )0 );
gethostname( r.hostname, 256 );
MD5Update( &c, &r, sizeof( randomness ) );
MD5Final( seed, &c );
/* Get some random stuff */
gettimeofday(&r.t, (struct timezone *)0);
gethostname(r.hostname, 256 );
/* 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
*/
int
uuid_create( uuid_upnp * uid )
uuid_create(uuid_upnp *uid)
{
uuid_time_t timestamp,
last_time;
uuid_time_t timestamp;
uuid_time_t last_time;
unsigned16 clockseq;
uuid_node_t node;
uuid_node_t last_node;
@ -65,61 +65,64 @@ uuid_create( uuid_upnp * uid )
/*
acquire system wide lock so we're alone
*/
UUIDLock( );
UUIDLock();
/*
get current time
*/
get_current_time( &timestamp );
get_current_time(&timestamp);
/*
get node ID
*/
get_ieee_node_identifier( &node );
get_ieee_node_identifier(&node);
/*
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
(e.g., net card swap) change clockseq
*/
if( !f || memcmp( &node, &last_node, sizeof( uuid_node_t ) ) )
clockseq = true_random( );
else if( timestamp < last_time )
if (!f || memcmp(&node, &last_node, sizeof(uuid_node_t))) {
clockseq = true_random();
} else if (timestamp < last_time) {
clockseq++;
}
/*
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
*/
write_state( clockseq, timestamp, node );
write_state(clockseq, timestamp, node);
UUIDUnlock( );
return ( 1 );
UUIDUnlock();
return 1;
};
/*-----------------------------------------------------------------------------*/
void
uuid_unpack( uuid_upnp * u,
char *out )
uuid_unpack(uuid_upnp *u, 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",
( unsigned int )u->time_low, u->time_mid,
u->time_hi_and_version, u->clock_seq_hi_and_reserved,
u->clock_seq_low, u->node[0], u->node[1], u->node[2],
u->node[3], u->node[4], u->node[5] );
*( out + 36 ) = '\0';
(unsigned int)u->time_low,
u->time_mid,
u->time_hi_and_version,
u->clock_seq_hi_and_reserved,
u->clock_seq_low,
u->node[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
* plus a few constants.
*/
uid->time_low = ( unsigned long )( timestamp & 0xFFFFFFFF );
uid->time_mid = ( unsigned short )( ( timestamp >> 32 ) & 0xFFFF );
uid->time_hi_and_version = ( unsigned short )( ( timestamp >> 48 ) &
0x0FFF );
uid->time_hi_and_version |= ( 1 << 12 );
uid->time_low = (unsigned long)(timestamp & 0xFFFFFFFF);
uid->time_mid = (unsigned short)((timestamp >> 32) & 0xFFFF);
uid->time_hi_and_version = (unsigned short)((timestamp >> 48) & 0x0FFF);
uid->time_hi_and_version |= (1 << 12);
uid->clock_seq_low = clock_seq & 0xFF;
uid->clock_seq_hi_and_reserved = ( clock_seq & 0x3F00 ) >> 8;
uid->clock_seq_hi_and_reserved |= 0x80;
@ -227,7 +229,6 @@ get_current_time( uuid_time_t * timestamp )
static int inited = 0;
if( !inited ) {
get_system_time( &time_now );
uuids_this_tick = UUIDS_PER_TICK;
inited = 1;
};

View File

@ -1,7 +1,7 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
// Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@ -105,7 +105,7 @@ main (int argc, char* argv[])
* Test library initialisation
*/
printf ("\n");
printf ("Intializing UPnP ... \n");
printf ("Initializing UPnP ... \n");
rc = UpnpInit (NULL, 0);
if ( UPNP_E_SUCCESS == rc ) {
const char* ip_address = UpnpGetServerIpAddress();