Compare commits

...

38 Commits

Author SHA1 Message Date
Marcelo Roberto Jimenez
95f7a7eeef Whitespace fix on soaplib.h. 2010-10-02 18:57:35 -03:00
Marcelo Roberto Jimenez
ca50c2153e Remove extra soaplib.h. 2010-10-02 18:57:13 -03:00
Fabrice Fontaine
c73d870f46 Adding --disable-notification-reordering option
Adding a configure flag to disable GENA notification reordering as even
with an imillisleep(1), this mechanism consumes too much CPU on embedded
devices when there is a burst of notifications.
2010-10-02 13:44:52 -03:00
Fabrice Fontaine
ab54cb3dc5 Bug fix when there is no service in embedded devices
When a device with embedded devices (like IGD) when created and one of
the embedded devices did not have any service, there was a Segmentation
Fault (see SF Tracker [ 2688125 ]).
2010-09-30 11:51:06 -03:00
Fabrice Fontaine
c33b11d09f Bug fix on burst of GENA notification
When a lot of notifications were generated by a device in a short
period of time then 100% of the CPU was used to reorder those
notifications by pushing back the thread in the job queue. This
mechanism has been modified so now thread sleep 1 ms before being
pushed back into the job queue.

Removing DEFAULT_SCHED_PARAM parameter and use
sched_get_priority_min(DEFAULT_POLICY) instead.
2010-09-28 20:41:28 -03:00
Fabrice Fontaine
4966423d96 Bug fix on M-SEARCH response
Devices must respond to M-SEARCH requests for any supported version and the
response should specify the same version as was contained in the search target.
Previously, the device did not answer if the M-SEARCH request did not
contain the same version number than the version number of the device.
2010-09-22 15:34:45 -03:00
Marcelo Roberto Jimenez
2fb55d3874 White space fix. 2010-09-21 16:49:20 -03:00
Fabrice Fontaine
d2238615e3 Add Content-Language iff Accept-Language
Add Content-Language header in the response if and only if there is an Accept-Language header in the request.
2010-09-21 13:50:29 -03:00
Fabrice Fontaine
2fcbe6df52 Addition of WEB_SERVER_CONTENT_LANGUAGE parameter
This patch adds the WEB_SERVER_CONTENT_LANGUAGE parameter so the user can specify
the language used by the device during Description and Presentation steps of UPnP
through the HTTP CONTENT-LANGUAGE header.
By default, the WEB_SERVER_CONTENT_LANGUAGE is an empty string so no
CONTENT-LANGUAGE is added.
2010-09-21 08:48:40 -03:00
Fabrice Fontaine
467f9987a1 Customize the stack size of the threads used by pupnp through the new THREAD_STACK_SIZE variable
This patch allows a user to customize the stack size of the threads used by
pupnp through the new THREAD_STACK_SIZE variable. This is especially useful
on embedded systems with limited memory where the user can set THREAD_STACK_SIZE
to ITHREAD_STACK_MIN.

However, as this modification can have side effects, I set 0 as the default
value, so threads will continue to use the default stack size of the system
(which varies greatly as stated in
https://computing.llnl.gov/tutorials/pthreads/).
2010-09-18 06:45:56 -03:00
Marcelo Roberto Jimenez
8fbecaee5e Another fix for Changelog. 2010-09-16 08:42:14 -03:00
Fabrice Fontaine
55d581481f Broken IPv6.
IPv6 is currently broken in latest release of branch-1.6.x, so find
a patch attached that correct the issue (small fixes on define,
undef and retVal).
2010-09-16 08:21:41 -03:00
Marcelo Roberto Jimenez
a0b405f902 White spaces. 2010-09-15 06:07:42 -03:00
Marcelo Roberto Jimenez
b37f9ac64a Get rid of evil CLIENTONLY macro. 2010-09-15 05:46:07 -03:00
Marcelo Roberto Jimenez
2dad42679d White spaces. 2010-09-15 05:44:36 -03:00
Chandra Penke
ea00f0f222 Fix win32 compilation errors in visual studio 2010-09-15 05:23:53 -03:00
Marcelo Roberto Jimenez
f3ae1b4116 Added UpnpString_cmp() and UpnpString_casecmp() methods to UpnpString.
UpnpString_set_String() and UpnpString_set_StringN now return error values.
String lenghts are size_t.
(cherry picked from commit 81b28fbb90)
2010-09-12 00:35:31 -03:00
David Hoeung
67009170d1 Timeout for TCP connect
Hi,

I've made some modification to the libupnp v1.6.5
I've add a timeout for each TCP connect.

It is very useful when an UPnP device stop working and do not accept
connection for an UPnP action.

Modifications are only located in
upnp/src/genlib/net/http/httpreadwrite.c

For every TCP connection, I set the socket to non-blocking, perform
connect,
check result and wait during a timeout if necessary, then reset the
socket to blocking.

Please see this patch in attached file.

I hope it helps.

Regards,

David Hoeung
Consultant Extia
Orange Labs R&D

----
2010-09-11 00:17:55 -03:00
Warwick Harvey
2b399b1791 Take notice of UPNP_USE_RWLOCK flag.
Updated threadutil to use mutexes instead of read-write locks if
UPNP_USE_RWLOCK is false (0).
2010-09-10 22:43:30 -03:00
Marcelo Roberto Jimenez
0bec9ec1ae Remove some unused code plus some coding style in httpparser.c 2010-09-10 19:46:18 -03:00
Marcelo Roberto Jimenez
25a4bd6d25 2010-09-10 Jean Sigwald <jean.sigwald(at)orange-ftgroup.com>
I discovered a reliable denial-of-service issue on the last stable
release of libupnp (1.6.6) remotely triggerable by any
unauthenticated user. The issue is related with a bad parsing of
malformed XML.
2010-09-10 19:26:10 -03:00
Marcelo Roberto Jimenez
5755ac022f SF Patch Tracker [ 2854711 ] Patch for Solaris10 compilation and usage
Submitted By: zephyrus ( zephyrus00jp )

Patch for Solaris10 compilation and usage.
2010-09-10 19:02:31 -03:00
Marcelo Roberto Jimenez
0158f52ee2 One setp further to stop the CLIENTONLY() mess. 2010-09-10 18:56:36 -03:00
Marcelo Roberto Jimenez
0db4a6beac Fix an UTF-8 issue in README. 2010-09-10 00:47:53 -03:00
Chandra Penke
575e5fc196 SUMMARY: Minor change in comment for SetMaxContentLenght in upnp.h
This is a follow up from issue 6 in tracker id 3056713: calling UpnpSetMaxContentLength() by passing '0' disables the content length checking. This is useful for developing some prototype applications that deal with a lot of XML/SOAP data, and for debugging.

The corresponding c file change is already in the pupnp tree. Copy/pasting the relevant block of code here for clarity:

In upnp/src/genlib/net/http/httpreadwrite.c:

if (g_maxContentLength > 0 && parser->content_length > (unsigned int)g_maxContentLength) {
	*http_error_code = HTTP_REQ_ENTITY_TOO_LARGE;
	line = __LINE__;
	ret = UPNP_E_OUTOF_BOUNDS;
	goto ExitFunction;
}

This block of code checks only does the bounds check if g_maxContentLength > 0, and it's only place g_maxContentLength is checked.

Attached is a patch against the latest sources.
(cherry picked from commit 7f1e164a5a)
2010-09-10 00:42:27 -03:00
Marcelo Roberto Jimenez
0e45dd9b8f Fix for coding style and compiler warning message:
src/genlib/miniserver/miniserver.c: In function ‘get_miniserver_sockets’:
src/genlib/miniserver/miniserver.c:592: warning: unused variable ‘actual_port6’
src/genlib/miniserver/miniserver.c:582: warning: unused variable ‘__ss_v6’
2010-09-10 00:32:49 -03:00
Chandra Penke
ae516b6bd3 Add support for conditionally enabling ipv6
(cherry picked from commit 6b0d84fc95)
2010-09-10 00:32:49 -03:00
Chandra Penke
7137f6e261 Fix for compilation in debug builds.
Ensure internal methods are declared as static since debug builds don't inline.
2010-09-10 00:02:04 -03:00
Marcelo Roberto Jimenez
92b241b560 Fix for UpnpPrintf() in Chandra Penke's last commit.
src/ssdp/ssdp_ctrlpt.c: In function ‘SearchByTarget’:
src/ssdp/ssdp_ctrlpt.c:634: warning: format ‘%s’ expects type ‘char *’, but argument 6 has type ‘int’
2010-09-09 22:52:27 -03:00
Chandra Penke
2b3ab1799b Fix for regression in SSDP code to send/receive messages over UDP
Sending messages over UDP is broken in some Apple OSes
such as OS X and iOS. This might be broken in other OSes to but didn't
verify.

The fix is to modify the socket lenght argument of sendto to use the correct
sockaddr lenght dependng on whether the socket is IPV4 or IPV6.

Also added some error checks and debugging related to the issue
2010-09-09 22:52:26 -03:00
Marcelo Roberto Jimenez
4657e57766 Using UpnpReadHttpGet to download large files causes the application to
crash. This happens when the file being downloaded exceeds the device
memory - entirely possible when transferring video files.
The programmatic cause is that the logic implemented in the function
http_ReadHttpGet (which UpnpReadHttpGet calls) reads the entire file
into memory. The fix modifies the existing logic to discard data after
it's been read; there's no reason to keep it around since the caller
of UpnpReadHttpGet already has a copy of it.

This issue exists in 1.6.6 as well as the latest sources.

Patch submitted by Chandra (inactiveneurons).
2010-09-07 22:15:21 -03:00
Marcelo Roberto Jimenez
21660334e4 In the latest sources, http_RequestAndResponse and other methods that
use connect() are broken. More specifically, connect() in these methods
is returning with an EINVAL. The programatic cause is that the address_len
argument passed to connect() is different in IPV4 vs IPV6 (as described in:
http://www.opengroup.org/onlinepubs/009695399/functions/connect.html).
The current code always uses the IPV6 size. The fix modifies each use of
connect() to use the correct size based on the address family being used.

Patch submitted by Chandra (inactiveneurons).
2010-09-07 21:56:53 -03:00
Marcelo Roberto Jimenez
97af8b6fdb Fix compilation error in upnp/src/gena/gena_ctrlpt.c (this is most
likely an error on all platforms).

Patch submitted by Chandra (inactiveneurons).
2010-09-07 14:57:56 -03:00
Marcelo Roberto Jimenez
934bd2682f Fix compilation error in upnp/src/inc/ssdplib.h when compiling in OS X
(the netinet/* headers are not available).

Patch submitted by Chandra (inactiveneurons).
2010-09-07 14:51:38 -03:00
Marcelo Roberto Jimenez
b8e9628140 Fix compilation error in ixml/inc/ixml.h when compiling with an
Objective-C compiler (when cross-compiling for iPhone devices).

Patch submitted by Chandra (inactiveneurons).
2010-09-07 14:47:12 -03:00
Marcelo Roberto Jimenez
b3b7a91a64 White spaces. 2010-09-03 21:51:31 -03:00
Marcelo Roberto Jimenez
ebc941f265 Issue regarding the GENA notifications. A string termination indicator was added
at the end of the notification ("\r\n") in notify_send_and_recv() in
upnp/src/gena/gena_device.c.

Patch by Fabrice Fontaine.
2010-09-03 21:49:49 -03:00
Marcelo Roberto Jimenez
842a6ce5c8 Adding .gitignore. 2010-09-03 21:49:20 -03:00
38 changed files with 2191 additions and 1579 deletions

104
.gitignore vendored Normal file
View File

@@ -0,0 +1,104 @@
#
# NOTE! Don't add files that are generated in specific
# subdirectories here. Add them in the ".gitignore" file
# in that subdirectory instead.
#
# NOTE! Please use 'git ls-files -i --exclude-standard'
# command after changing this file, to see if there are
# any tracked files which get ignored after the change.
#
# Normal rules
#
.*
*.o
*.o.*
*.a
*.s
*.ko
*.so
*.so.dbg
*.mod.c
*.i
*.lst
*.symtypes
*.order
modules.builtin
*.elf
*.bin
*.gz
*.bz2
*.lzma
*.patch
*.gcno
#
# Top-level generic files
#
/tags
/TAGS
/linux
/vmlinux
/vmlinuz
/System.map
/Module.markers
/Module.symvers
#
# git files that we don't want to ignore even it they are dot-files
#
!.gitignore
!.mailmap
#
# Generated include files
#
include/config
include/linux/version.h
include/generated
# stgit generated dirs
patches-*
# quilt's files
patches
series
# cscope files
cscope.*
ncscope.*
# gnu global files
GPATH
GRTAGS
GSYMS
GTAGS
*.orig
*~
\#*#
*.lo
*.la
Makefile
Makefile.in
aclocal.m4
autoconfig.h
autoconfig.h.in
autom4te.cache/
build-aux/
config.log
config.status
configure
libtool
libupnp.pc
m4/libtool.m4
m4/ltoptions.m4
m4/ltsugar.m4
m4/ltversion.m4
m4/lt~obsolete.m4
stamp-h1
upnp/inc/stamp-h2
upnp/inc/upnpconfig.h
upnp/sample/upnp_tv_combo
upnp/sample/upnp_tv_ctrlpt
upnp/sample/upnp_tv_device

188
ChangeLog
View File

@@ -2,6 +2,194 @@
Version 1.6.7
*******************************************************************************
2010-10-01 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Adding --disable-notification-reordering option
Adding a configure flag to disable GENA notification reordering as even
with an imillisleep(1), this mechanism consumes too much CPU on embedded
devices when there is a burst of notifications.
2010-09-30 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Bug fix when there is no service in embedded devices
When a device with embedded devices (like IGD) when created and one of
the embedded devices did not have any service, there was a Segmentation
Fault (see SF Tracker [ 2688125 ]).
Original SF Tracker issue follows:
SF Tracker [ 2688125 ] v1.6.6 crashes on subdevices without services
Submitted by: Arno Willig ( akw ) - 2009-03-15 22:45:23 BRT
I discovered a bug, which will make libupnp (1.6.6) segfault, when you
create a upnp description document with multiple devices which have
subdevices, but no own services.
The crash occurs in genlib/service_table.c in line 977:
end->next =
getServiceList( currentDevice, &next_end, URLBase );
In this case "end" seems not to be defined, so end->next crashes.
Can anyone confirm this, please?
2010-09-28 Marc Essayan <marc.essayan(at)orange-ftgroup.com>
Bug fix on burst of GENA notification
When a lot of notifications were generated by a device in a short
period of time then 100% of the CPU was used to reorder those
notifications by pushing back the thread in the job queue. This
mechanism has been modified so now thread sleep 1 ms before being
pushed back into the job queue.
Removing DEFAULT_SCHED_PARAM parameter and use
sched_get_priority_min(DEFAULT_POLICY) instead.
2010-09-22 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Bug fix on M-SEARCH response
Devices must respond to M-SEARCH requests for any supported version and the
response should specify the same version as was contained in the search target.
Previously, the device did not answer if the M-SEARCH request did not
contain the same version number than the version number of the device.
2010-09-21 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Add Content-Language iff Accept-Language
Add Content-Language header in the response if and only if there is an
Accept-Language header in the request.
2010-09-21 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Addition of WEB_SERVER_CONTENT_LANGUAGE parameter
This patch adds the WEB_SERVER_CONTENT_LANGUAGE parameter so the user can specify
the language used by the device during Description and Presentation steps of UPnP
through the HTTP CONTENT-LANGUAGE header.
By default, the WEB_SERVER_CONTENT_LANGUAGE is an empty string so no
CONTENT-LANGUAGE is added.
2010-09-18 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Customize the stack size of the threads used by pupnp through the new
THREAD_STACK_SIZE variable.
This patch allows a user to customize the stack size of the threads used by
pupnp through the new THREAD_STACK_SIZE variable. This is especially useful
on embedded systems with limited memory where the user can set THREAD_STACK_SIZE
to ITHREAD_STACK_MIN.
However, as this modification can have side effects, I set 0 as the default
value, so threads will continue to use the default stack size of the system
(which varies greatly as stated in
https://computing.llnl.gov/tutorials/pthreads/).
2010-09-16 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Broken IPv6.
IPv6 is currently broken in latest release of branch-1.6.x, so find a
patch attached that correct the issue (small fixes on define, undef and
retVal).
2010-09-10 Warwick Harvey <warwick.harvey(at)tieto.com>
Patch to take notice of UPNP_USE_RWLOCK flag
The configure.ac file included with UPnP checks for the presence of the
pthread_rwlock_t type, and then sets the value of the UPNP_USE_RWLOCK
flag appropriately. However, this flag is not referenced at all in the
source code, and thus the code does not compile on systems that don't
have the pthread_rwlock_t type (such as Android).
Please find attached a patch (against the current 1.6.x head) that checks
the value of this flag and falls back on using mutexes if read-write
locks are not available.
2010-09-10 Jean Sigwald <jean.sigwald(at)orange-ftgroup.com>
I discovered a reliable denial-of-service issue on the last stable
release of libupnp (1.6.6) remotely triggerable by any
unauthenticated user. The issue is related with a bad parsing of
malformed XML.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
* SF Patch Tracker [ 2854711 ] Patch for Solaris10 compilation and usage
Submitted By: zephyrus ( zephyrus00jp )
Patch for Solaris10 compilation and usage.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
Add support for conditionally enabling ipv6.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for compilation in debug builds.
Ensure internal methods are declared as static since debug builds don't inline.
2010-09-09 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for regression in SSDP code to send/receive messages over UDP
Sending messages over UDP is broken in some Apple OSes
such as OS X and iOS. This might be broken in other OSes to but didn't
verify.
The fix is to modify the socket lenght argument of sendto to use the correct
sockaddr lenght dependng on whether the socket is IPV4 or IPV6.
Also added some error checks and debugging related to the issue
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Using UpnpReadHttpGet to download large files causes the application to
crash. This happens when the file being downloaded exceeds the device
memory - entirely possible when transferring video files.
The programmatic cause is that the logic implemented in the function
http_ReadHttpGet (which UpnpReadHttpGet calls) reads the entire file
into memory. The fix modifies the existing logic to discard data after
it's been read; there's no reason to keep it around since the caller
of UpnpReadHttpGet already has a copy of it.
This issue exists in 1.6.6 as well as the latest sources.
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
In the latest sources, http_RequestAndResponse and other methods that
use connect() are broken. More specifically, connect() in these methods
is returning with an EINVAL. The programatic cause is that the address_len
argument passed to connect() is different in IPV4 vs IPV6 (as described in:
http://www.opengroup.org/onlinepubs/009695399/functions/connect.html).
The current code always uses the IPV6 size. The fix modifies each use of
connect() to use the correct size based on the address family being used.
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in upnp/src/gena/gena_ctrlpt.c (this is most
likely an error on all platforms).
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in upnp/src/inc/ssdplib.h when compiling in OS X
(the netinet/* headers are not available).
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in ixml/inc/ixml.h when compiling with an
Objective-C compiler (when cross-compiling for iPhone devices).
Patch submitted by Chandra (inactiveneurons).
2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Issue regarding the GENA notifications. A string termination indicator
was added at the end of the notification ("\r\n") in
notify_send_and_recv() in upnp/src/gena/gena_device.c.
Patch by Fabrice Fontaine.
2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* The last part of Ronan Menard's patch.

2
README
View File

@@ -1,7 +1,7 @@
Portable SDK for UPnP* Devices (libupnp)
Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved.
Copyright (c) 2005-2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net>
Copyright (c) 2005-2006 Rémi Turboult <r3mi@users.sourceforge.net>
Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds@gmx.de>
See LICENSE for details.

1
THANKS
View File

@@ -13,6 +13,7 @@ exempt of errors.
- Arno Willig
- Bob Ciora
- Carlo Parata
- Chandra (inactiveneurons)
- Chaos
- Charles Nepveu (cnepveu)
- Chris Pickel

View File

@@ -1,148 +1,214 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
#ifndef INTERNAL_CONFIG_H
#define INTERNAL_CONFIG_H
#include "autoconfig.h"
/** @name Compile time configuration options
/*!
* \name Compile time configuration options
*
* The Linux SDK for UPnP Devices contains some compile-time parameters
* that effect the behavior of the SDK. All configuration options are
* located in {\tt src/inc/config.h}.
*
* @{
*/
//@{
/** @name THREAD_IDLE_TIME
/*!
* \name THREAD_IDLE_TIME
*
* The {\tt THREAD_IDLE_TIME} constant determines when a thread will be
* removed from the thread pool and returned to the operating system. When
* a thread in the thread pool has been idle for this number of milliseconds
* the thread will be released from the thread pool. The default value is
* 5000 milliseconds (5 seconds).
*
* @{
*/
//@{
#define THREAD_IDLE_TIME 5000
//@}
/* @} */
/** @name JOBS_PER_THREAD
* The {\tt JOBS_PER_THREAD} constant determines when a new thread will be
* allocated to the thread pool inside the SDK. The thread pool will
* try and maintain this jobs/thread ratio. When the jobs/thread ratio
* becomes greater than this, then a new thread (up to the max) will be
* allocated to the thread pool. The default ratio is 10 jobs/thread.
/*!
* \name JOBS_PER_THREAD
*
* The {\tt JOBS_PER_THREAD} constant determines when a new thread will be
* allocated to the thread pool inside the SDK. The thread pool will
* try and maintain this jobs/thread ratio. When the jobs/thread ratio
* becomes greater than this, then a new thread (up to the max) will be
* allocated to the thread pool. The default ratio is 10 jobs/thread.
*
* @{
*/
//@{
#define JOBS_PER_THREAD 10
//@}
/* @} */
/** @name MIN_THREADS
* The {\tt MIN_THREADS} constant defines the minimum number of threads the
* thread pool inside the SDK will create. The thread pool will
* always have this number of threads. These threads are used
* for both callbacks into applications built on top of the SDK and also
* for making connections to other control points and devices. This number
* includes persistent threads. The default value is two threads.
/*!
* \name MIN_THREADS
*
* The {\tt MIN_THREADS} constant defines the minimum number of threads the
* thread pool inside the SDK will create. The thread pool will
* always have this number of threads. These threads are used
* for both callbacks into applications built on top of the SDK and also
* for making connections to other control points and devices. This number
* includes persistent threads. The default value is two threads.
*
* @{
*/
//@{
#define MIN_THREADS 2
//@}
/* @} */
/** @name MAX_THREADS
* The {\tt MAX_THREADS} constant defines the maximum number of threads the
* thread pool inside the SDK will create. These threads are used
* for both callbacks into applications built on top of the library and also
* for making connections to other control points and devices. It is not
* recommended that this value be below 10, since the threads are
* necessary for correct operation. This value can be increased for greater
* performance in operation at the expense of greater memory overhead. The
* default value is 12.
/*!
* \name MAX_THREADS
*
* The {\tt MAX_THREADS} constant defines the maximum number of threads the
* thread pool inside the SDK will create. These threads are used
* for both callbacks into applications built on top of the library and also
* for making connections to other control points and devices. It is not
* recommended that this value be below 10, since the threads are
* necessary for correct operation. This value can be increased for greater
* performance in operation at the expense of greater memory overhead. The
* default value is 12.
*
* @{
*/
//@{
#define MAX_THREADS 12
//@}
/* @} */
/** @name MAX_JOBS_TOTAL
/*!
* \name THREAD_STACK_SIZE
*
* The {\tt THREAD_STACK_SIZE} constant defines the minimum stack size (in
* bytes) allocated for the stack of each thread the thread pool inside the
* SDK will create. These threads are used for both callbacks into
* applications built on top of the library and also for making connections
* to other control points and devices. This value will not be used if it
* is lower than ITHREAD_STACK_MIN or greater than a system-imposed limit.
* This value can be used to lower memory overhead in embedded systems.
* The default value is 0 (so it is not used by default).
*
* @{
*/
#define THREAD_STACK_SIZE 0
/* @} */
/*! \name MAX_JOBS_TOTAL
*
* The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs
* that can be queued. If this limit is reached further jobs will be thrown
* to avoid memory exhaustion. The default value 100.
* (Added by Axis.)
*
* @{
*/
//@{
#define MAX_JOBS_TOTAL 100
//@}
/* @} */
/** @name DEFAULT_SOAP_CONTENT_LENGTH
/*!
* \name DEFAULT_SOAP_CONTENT_LENGTH
*
* SOAP messages will read at most {\tt DEFAULT_SOAP_CONTENT_LENGTH} bytes.
* This prevents devices that have a misbehaving web server to send
* a large amount of data to the control point causing it to crash.
* This can be adjusted dynamically with {\tt UpnpSetMaxContentLength}.
*
* @{
*/
//@{
#define DEFAULT_SOAP_CONTENT_LENGTH 16000
//@}
/* @} */
/** @name NUM_SSDP_COPY
/*!
* \name NUM_SSDP_COPY
*
* This configuration parameter determines how many copies of each SSDP
* advertisement and search packets will be sent. By default it will send two
* copies of every packet.
*
* @{
*/
//@{
#define NUM_SSDP_COPY 2
//@}
/* @} */
/** @name SSDP_PAUSE
/*!
* \name SSDP_PAUSE
*
* This configuration parameter determines the pause between identical SSDP
* advertisement and search packets. The pause is measured in milliseconds
* and defaults to 100.
*
* @{
*/
//@{
#define SSDP_PAUSE 100
//@}
/* @} */
/** @name WEB_SERVER_BUF_SIZE
/*!
* \name WEB_SERVER_BUF_SIZE
*
* This configuration parameter sets the maximum buffer size for the
* webserver. The default value is 1MB.
* webserver. The default value is 1MB.
*
* @{
*/
//@{
#define WEB_SERVER_BUF_SIZE (1024*1024)
//@}
/* @} */
/** @name AUTO_RENEW_TIME
/*!
* \name WEB_SERVER_CONTENT_LANGUAGE
*
* This configuration parameter sets the value of the Content-Language
* header for the webserver. Thanks to this parameter, the use can advertize
* the language used by the device in the description (friendlyName) and
* presentation steps of UPnP. The default value is empty string so no
* Content-Language header is added.
*
* @{
*/
#define WEB_SERVER_CONTENT_LANGUAGE ""
/* @} */
/*!
* \name AUTO_RENEW_TIME
*
* The {\tt AUTO_RENEW_TIME} is the time, in seconds, before a subscription
* expires that the SDK automatically resubscribes. The default
* value is 10 seconds. Setting this value too low can result in the
@@ -150,89 +216,104 @@
* subscription to timeout. In order to avoid continually resubscribing
* the minimum subscription time is five seconds more than the auto renew
* time.
*
* @{
*/
//@{
#define AUTO_RENEW_TIME 10
//@}
/* @} */
/** @name CP_MINIMUM_SUBSCRIPTION_TIME
/*!
* \name CP_MINIMUM_SUBSCRIPTION_TIME
*
* The {\tt CP_MINIMUM_SUBSCRIPTION_TIME} is the minimum subscription time
* allowed for a control point using the SDK. Subscribing for less than
* this time automatically results in a subscription for this amount. The
* default value is 5 seconds more than the {\tt AUTO_RENEW_TIME}, or 15
* seconds.
*
* @{
*/
//@{
#define CP_MINIMUM_SUBSCRIPTION_TIME (AUTO_RENEW_TIME + 5)
//@}
/* @} */
/** @name MAX_SEARCH_TIME
/*!
* \name MAX_SEARCH_TIME
*
* The {\tt MAX_SEARCH_TIME} is the maximum time
* allowed for an SSDP search by a control point. Searching for greater than
* this time automatically results in a search for this amount. The default
* value is 80 seconds.
*
* @{
*/
//@{
#define MAX_SEARCH_TIME 80
//@}
/* @} */
/** @name MIN_SEARCH_TIME
/*!
* \name MIN_SEARCH_TIME
*
* The {\tt MIN_SEARCH_TIME} is the minimumm time
* allowed for an SSDP search by a control point. Searching for less than
* this time automatically results in a search for this amount. The default
* value is 2 seconds.
*/
//@{
#define MIN_SEARCH_TIME 2
//@}
/** @name AUTO_ADVERTISEMENT_TIME
* The {\tt AUTO_ADVERTISEMENT_TIME} is the time, in seconds, before an
* device advertisements expires before a renewed advertisement is sent.
* The default time is 30 seconds.
*/
//@{
#define AUTO_ADVERTISEMENT_TIME 30
//@}
/** @name SSDP_PACKET_DISTRIBUTE
* The {\tt SSDP_PACKET_DISTRIBUTE} enables the SSDP packets to be sent
* at an interval equal to half of the expiration time of SSDP packets
* minus the AUTO_ADVERTISEMENT_TIME. This is used to increase
* the probability of SSDP packets reaching to control points.
* It is recommended that this flag be turned on for embedded wireless
* devices.
*/
//@{
#define SSDP_PACKET_DISTRIBUTE 1
//@}
/** @name Module Exclusion
* Depending on the requirements, the user can selectively discard any of
* the major modules like SOAP, GENA, SSDP or the Internal web server. By
* default everything is included inside the SDK. By setting any of
* the values below to 0, that component will not be included in the final
* SDK.
* \begin{itemize}
* \item {\tt EXCLUDE_SOAP[0,1]}
* \item {\tt EXCLUDE_GENA[0,1]}
* \item {\tt EXCLUDE_SSDP[0,1]}
* \item {\tt EXCLUDE_DOM [0,1]}
* \item {\tt EXCLUDE_MINISERVER[0,1]}
* \item {\tt EXCLUDE_WEB_SERVER[0,1]}
* \item {\tt EXCLUDE_JNI[0,1]}
* \end{itemize}
*
* @{
*/
#define MIN_SEARCH_TIME 2
/* @} */
//@{
/*!
* \name AUTO_ADVERTISEMENT_TIME
*
* The {\tt AUTO_ADVERTISEMENT_TIME} is the time, in seconds, before an
* device advertisements expires before a renewed advertisement is sent.
* The default time is 30 seconds.
*
* @{
*/
#define AUTO_ADVERTISEMENT_TIME 30
/* @} */
/*!
* \name SSDP_PACKET_DISTRIBUTE
*
* The {\tt SSDP_PACKET_DISTRIBUTE} enables the SSDP packets to be sent
* at an interval equal to half of the expiration time of SSDP packets
* minus the AUTO_ADVERTISEMENT_TIME. This is used to increase
* the probability of SSDP packets reaching to control points.
* It is recommended that this flag be turned on for embedded wireless
* devices.
*
* @{
*/
#define SSDP_PACKET_DISTRIBUTE 1
/* @} */
/*!
* \name Module Exclusion
*
* Depending on the requirements, the user can selectively discard any of
* the major modules like SOAP, GENA, SSDP or the Internal web server. By
* default everything is included inside the SDK. By setting any of
* the values below to 0, that component will not be included in the final
* SDK.
* \begin{itemize}
* \item {\tt EXCLUDE_SOAP[0,1]}
* \item {\tt EXCLUDE_GENA[0,1]}
* \item {\tt EXCLUDE_SSDP[0,1]}
* \item {\tt EXCLUDE_DOM [0,1]}
* \item {\tt EXCLUDE_MINISERVER[0,1]}
* \item {\tt EXCLUDE_WEB_SERVER[0,1]}
* \item {\tt EXCLUDE_JNI[0,1]}
* \end{itemize}
*
* @{
*/
#define EXCLUDE_SSDP 0
#define EXCLUDE_SOAP 0
#define EXCLUDE_GENA 0
@@ -244,24 +325,28 @@
#else
# define EXCLUDE_JNI 1
#endif
//@}
/* @} */
/** @name DEBUG_TARGET
* The user has the option to redirect the library output debug messages
* to either the screen or to a log file. All the output messages with
* debug level 0 will go to {\tt upnp.err} and messages with debug level
* greater than zero will be redirected to {\tt upnp.out}.
/*!
* \name DEBUG_TARGET
*
* The user has the option to redirect the library output debug messages
* to either the screen or to a log file. All the output messages with
* debug level 0 will go to {\tt upnp.err} and messages with debug level
* greater than zero will be redirected to {\tt upnp.out}.
*
* @{
*/
//@{
#define DEBUG_TARGET 1
//@}
/* @} */
/** @name Other debugging features
The UPnP SDK contains other features to aid in debugging:
see <upnp/inc/upnpdebug.h>
/*!
* \name Other debugging features
*
* The UPnP SDK contains other features to aid in debugging:
* see <upnp/inc/upnpdebug.h>
*/
#define DEBUG_ALL 1
@@ -274,38 +359,46 @@
#define DEBUG_HTTP 0
#define DEBUG_API 0
//@} // Compile time configuration options
/*
* @} Compile time configuration options
*/
/***************************************************************************
* Do not change, Internal purpose only!!!
* Do not change, Internal purpose only!!!
***************************************************************************/
//@{
/*!
* @{
*/
/*
* Set additional defines based on requested configuration
*/
// configure --enable-client
/* configure --enable-client */
#if UPNP_HAVE_CLIENT
# define INCLUDE_CLIENT_APIS 1
#endif
// configure --enable-device
/* configure --enable-device */
#if UPNP_HAVE_DEVICE
# define INCLUDE_DEVICE_APIS 1
#endif
// configure --enable-webserver --enable-device
/* configure --enable-webserver --enable-device */
#if UPNP_HAVE_WEBSERVER
# define INTERNAL_WEB_SERVER 1
#endif
#undef EXCLUDE_WEB_SERVER
#undef EXCLUDE_MINISERVER
#undef EXCLUDE_WEB_SERVER
#undef EXCLUDE_MINISERVER
#ifdef INTERNAL_WEB_SERVER
# define EXCLUDE_WEB_SERVER 0
# define EXCLUDE_MINISERVER 0
@@ -314,16 +407,18 @@
# define EXCLUDE_MINISERVER 1
#endif
#if EXCLUDE_GENA == 1 && EXCLUDE_SOAP == 1 && EXCLUDE_WEB_SERVER == 1
# undef EXCLUDE_MINISERVER
# undef EXCLUDE_MINISERVER
# define EXCLUDE_MINISERVER 1
# if INTERNAL_WEB_SERVER
# error "conflicting settings: use configure --disable-webserver"
# endif
#endif
#if EXCLUDE_GENA == 0 || EXCLUDE_SOAP == 0 || EXCLUDE_WEB_SERVER == 0
# undef EXCLUDE_MINISERVER
# undef EXCLUDE_MINISERVER
# define EXCLUDE_MINISERVER 0
# if EXCLUDE_WEB_SERVER == 0 && !defined INTERNAL_WEB_SERVER
# error "conflicting settings : use configure --enable-webserver"
@@ -331,13 +426,9 @@
#endif
/*
* @}
*/
#ifdef INCLUDE_CLIENT_APIS
# define CLIENTONLY(x) x
#else
# define CLIENTONLY(x)
#endif
//@}
#endif
#endif /* INTERNAL_CONFIG_H */

View File

@@ -256,6 +256,16 @@ if test "x$enable_tools" = xyes ; then
AC_DEFINE(UPNP_HAVE_TOOLS, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([ipv6], [no], [ipv6 support])
if test "x$enable_ipv6" = xyes ; then
AC_DEFINE(UPNP_ENABLE_IPV6, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([notification_reordering], [yes], [GENA notification reordering in gena_device.c])
if test "x$enable_notification_reordering" = xyes ; then
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code])

View File

@@ -45,9 +45,13 @@
#include "UpnpGlobal.h" /* For EXPORT_SPEC */
typedef int BOOL;
/* Define BOOL. */
#ifndef __OBJC__
typedef int BOOL;
#else
/* For Objective C compilers, include objc.h which defines BOOL. */
#include <objc/objc.h>
#endif
/*!
* \brief The type of DOM strings.

View File

@@ -583,11 +583,14 @@ static int Parser_isValidEndElement(
IXML_Node *newNode)
{
assert(xmlParser);
assert(xmlParser->pCurElement);
assert(xmlParser->pCurElement->element);
assert(newNode);
assert(newNode->nodeName);
if (xmlParser->pCurElement == NULL) {
return 0;
}
return strcmp(xmlParser->pCurElement->element, newNode->nodeName) == 0;
}

View File

@@ -115,6 +115,10 @@ typedef enum priority {
#define DEFAULT_MAX_THREADS 10
/*! default stack size used by TPAttrInit */
#define DEFAULT_STACK_SIZE 0
/*! default jobs per thread used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10
@@ -154,10 +158,6 @@ typedef int PolicyType;
#define DEFAULT_POLICY SCHED_OTHER
/*! Default priority */
#define DEFAULT_SCHED_PARAM 0
/****************************************************************************
* Name: free_routine
*
@@ -182,6 +182,10 @@ typedef struct THREADPOOLATTR
/* maxThreads, ThreadPool will never have more than this number of threads */
int maxThreads;
/* stackSize (in bytes), this is the minimum stack size allocated for each
* thread */
size_t stackSize;
/* maxIdleTime (in milliseconds) this is the maximum time a thread will
* remain idle before dying */
int maxIdleTime;
@@ -522,6 +526,20 @@ int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
/****************************************************************************
* Function: TPAttrSetStackSize
*
* Description:
* Sets the stack size for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* stackSize - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetStackSize(ThreadPoolAttr *attr, size_t stackSize);
/****************************************************************************
* Function: TPAttrSetIdleTime
*

View File

@@ -85,7 +85,10 @@ extern "C" {
#define ITHREAD_CANCELED PTHREAD_CANCELED
#define ITHREAD_STACK_MIN PTHREAD_STACK_MIN
/***************************************************************************
* Name: ithread_t
*
@@ -171,7 +174,9 @@ typedef pthread_condattr_t ithread_condattr_t;
* typedef to pthread_rwlockattr_t
* Internal Use Only
***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlockattr_t ithread_rwlockattr_t;
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -182,7 +187,9 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t;
* typedef to pthread_rwlock_t
* Internal Use Only
***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlock_t ithread_rwlock_t;
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -443,7 +450,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlockattr_init
***************************************************************************/
#define ithread_rwlockattr_init pthread_rwlockattr_init
#if UPNP_USE_RWLOCK
#define ithread_rwlockattr_init pthread_rwlockattr_init
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -459,7 +468,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlockattr_destroy
***************************************************************************/
#define ithread_rwlockattr_destroy pthread_rwlockattr_destroy
#if UPNP_USE_RWLOCK
#define ithread_rwlockattr_destroy pthread_rwlockattr_destroy
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -480,7 +491,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Returns EINVAL if the kind is not supported.
* See man page for pthread_rwlockattr_setkind_np
*****************************************************************************/
#define ithread_rwlockatttr_setpshared pthread_rwlockatttr_setpshared
#if UPNP_USE_RWLOCK
#define ithread_rwlockatttr_setpshared pthread_rwlockatttr_setpshared
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -501,7 +514,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlockatttr_getpshared
*****************************************************************************/
#define ithread_rwlockatttr_getpshared pthread_rwlockatttr_getpshared
#if UPNP_USE_RWLOCK
#define ithread_rwlockatttr_getpshared pthread_rwlockatttr_getpshared
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -519,7 +534,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlock_init
*****************************************************************************/
#define ithread_rwlock_init pthread_rwlock_init
#if UPNP_USE_RWLOCK
#define ithread_rwlock_init pthread_rwlock_init
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -536,7 +553,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlock_rdlock
*****************************************************************************/
#define ithread_rwlock_rdlock pthread_rwlock_rdlock
#if UPNP_USE_RWLOCK
#define ithread_rwlock_rdlock pthread_rwlock_rdlock
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -553,7 +572,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlock_wrlock
*****************************************************************************/
#define ithread_rwlock_wrlock pthread_rwlock_wrlock
#if UPNP_USE_RWLOCK
#define ithread_rwlock_wrlock pthread_rwlock_wrlock
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -571,7 +592,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlock_unlock
*****************************************************************************/
#define ithread_rwlock_unlock pthread_rwlock_unlock
#if UPNP_USE_RWLOCK
#define ithread_rwlock_unlock pthread_rwlock_unlock
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -590,7 +613,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_rwlock_destroy
*****************************************************************************/
#define ithread_rwlock_destroy pthread_rwlock_destroy
#if UPNP_USE_RWLOCK
#define ithread_rwlock_destroy pthread_rwlock_destroy
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -704,6 +729,49 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
***************************************************************************/
#define ithread_cond_destroy pthread_cond_destroy
/****************************************************************************
* Function: ithread_attr_init
*
* Description:
* Initialises thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_init
***************************************************************************/
#define ithread_attr_init pthread_attr_init
/****************************************************************************
* Function: ithread_attr_destroy
*
* Description:
* Destroys thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_destroy
***************************************************************************/
#define ithread_attr_destroy pthread_attr_destroy
/****************************************************************************
* Function: ithread_attr_setstacksize
*
* Description:
* Sets stack size of a thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* size_t stacksize (value of stacksize must be greater than
* ITHREAD_STACK_MIN and lower than system-imposed limits
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_setstacksize
***************************************************************************/
#define ithread_attr_setstacksize pthread_attr_setstacksize
/****************************************************************************
* Function: ithread_create
@@ -713,7 +781,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* and argument.
* Parameters:
* ithread_t * thread (must be valid non NULL pointer to pthread_t)
* ithread_attr_t *attr, IGNORED
* ithread_attr_t *attr
* void * (start_routine) (void *arg) (start routine)
* void * arg - argument.
* Returns:

View File

@@ -246,7 +246,7 @@ static int SetPolicyType(PolicyType in)
memset(&current, 0, sizeof(current));
sched_getparam(0, &current);
current.sched_priority = DEFAULT_SCHED_PARAM;
current.sched_priority = sched_get_priority_min(DEFAULT_POLICY);
sched_result = sched_setscheduler(0, in, &current);
retVal = (sched_result != -1 || errno == EPERM) ? 0 : errno;
#else
@@ -609,12 +609,16 @@ static int CreateWorker(ThreadPool *tp)
ithread_t temp;
int rc = 0;
int currentThreads = tp->totalThreads + 1;
ithread_attr_t attr;
if (tp->attr.maxThreads != INFINITE_THREADS &&
currentThreads > tp->attr.maxThreads) {
return EMAXTHREADS;
}
rc = ithread_create(&temp, NULL, WorkerThread, tp);
ithread_attr_init(&attr);
ithread_attr_setstacksize(&attr, tp->attr.stackSize);
rc = ithread_create(&temp, &attr, WorkerThread, tp);
ithread_attr_destroy(&attr);
if (rc == 0) {
rc = ithread_detach(temp);
while (tp->totalThreads < currentThreads) {
@@ -1174,6 +1178,7 @@ int TPAttrInit(ThreadPoolAttr *attr)
attr->maxIdleTime = DEFAULT_IDLE_TIME;
attr->maxThreads = DEFAULT_MAX_THREADS;
attr->minThreads = DEFAULT_MIN_THREADS;
attr->stackSize = DEFAULT_STACK_SIZE;
attr->schedPolicy = DEFAULT_POLICY;
attr->starvationTime = DEFAULT_STARVATION_TIME;
attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL;
@@ -1298,6 +1303,28 @@ int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads)
return 0;
}
/****************************************************************************
* Function: TPAttrSetStackSize
*
* Description:
* Sets the stack size for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* stackSize - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetStackSize(ThreadPoolAttr *attr, size_t stackSize)
{
if (!attr) {
return EINVAL;
}
attr->stackSize = stackSize;
return 0;
}
/****************************************************************************
* Function: TPAttrSetIdleTime
*

View File

@@ -24,6 +24,9 @@
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include <stdlib.h> /* for size_t */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
@@ -76,11 +79,22 @@ EXPORT_SPEC void UpnpString_assign(
*
* \return The length of the string.
* */
EXPORT_SPEC int UpnpString_get_Length(
EXPORT_SPEC size_t UpnpString_get_Length(
/*! [in] The \em \b this pointer. */
const UpnpString *p);
/*!
* \brief Truncates the string to the specified lenght, or does nothing
* if the current lenght is less than or equal to the requested length.
* */
EXPORT_SPEC void UpnpString_set_Length(
/*! [in] The \em \b this pointer. */
UpnpString *p,
/*! [in] The requested length. */
size_t n);
/*!
* \brief Returns the pointer to char.
*
@@ -94,7 +108,7 @@ EXPORT_SPEC const char *UpnpString_get_String(
/*!
* \brief Sets the string from a pointer to char.
*/
EXPORT_SPEC void UpnpString_set_String(
EXPORT_SPEC int UpnpString_set_String(
/*! [in] The \em \b this pointer. */
UpnpString *p,
/*! [in] (char *) to copy from. */
@@ -104,13 +118,13 @@ EXPORT_SPEC void UpnpString_set_String(
/*!
* \brief Sets the string from a pointer to char using a maximum of N chars.
*/
EXPORT_SPEC void UpnpString_set_StringN(
EXPORT_SPEC int UpnpString_set_StringN(
/*! [in] The \em \b this pointer. */
UpnpString *p,
/*! [in] (char *) to copy from. */
const char *s,
/*! Maximum number of chars to copy.*/
int n);
size_t n);
/*!
@@ -121,6 +135,30 @@ EXPORT_SPEC void UpnpString_clear(
UpnpString *p);
/*!
* \brief Compares two strings for equality. Case matters.
*
* \return The result of strcmp().
*/
EXPORT_SPEC int UpnpString_cmp(
/*! [in] The \em \b the first string. */
UpnpString *p,
/*! [in] The \em \b the second string. */
UpnpString *q);
/*!
* \brief Compares two strings for equality. Case does not matter.
*
* \return The result of strcasecmp().
*/
EXPORT_SPEC int UpnpString_casecmp(
/*! [in] The \em \b the first string. */
UpnpString *p,
/*! [in] The \em \b the second string. */
UpnpString *q);
#ifdef __cplusplus
}
#endif /* __cplusplus */

View File

@@ -987,6 +987,7 @@ EXPORT_SPEC int UpnpInit(
* \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not
* have a valid IPv4 or IPv6 addresss configured.
*/
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC int UpnpInit2(
/*! The interface name to use by the UPnP SDK operations.
* Examples: "eth0", "xl0", "Local Area Connection", \c NULL to
@@ -995,6 +996,7 @@ EXPORT_SPEC int UpnpInit2(
/*! Local Port to listen for incoming connections.
* \c NULL will pick an arbitrary free port. */
unsigned short DestPort);
#endif
/*!
@@ -1044,8 +1046,9 @@ EXPORT_SPEC unsigned short UpnpGetServerPort(void);
* related requests.
* \li On error: 0 is returned if \b UpnpInit has not succeeded.
*/
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
#endif
/*!
* \brief Returns the local IPv4 listening ip address.
*
@@ -1071,10 +1074,11 @@ EXPORT_SPEC char *UpnpGetServerIpAddress(void);
* listening for UPnP related requests.
* \li On error: \c NULL is returned if \b UpnpInit has not succeeded.
*/
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC char *UpnpGetServerIp6Address(void);
EXPORT_SPEC char *UpnpGetServerUlaGuaIp6Address(void);
#endif
/*!
* \brief Registers a device application with the UPnP Library.
*
@@ -1351,6 +1355,8 @@ EXPORT_SPEC int UpnpSetContentLength(
* behaviour if the size of the incoming SOAP message exceeds the memory that
* device can allocate.
*
* If set to 0 then checking will be disabled.
*
* The default maximum content-length is \c DEFAULT_SOAP_CONTENT_LENGTH
* = 16K bytes.
*

View File

@@ -90,6 +90,9 @@
* (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
#undef UPNP_HAVE_TOOLS
/** Defined to 1 if the library has been compiled with ipv6 support
* (i.e. configure --enable-ipv6) */
#undef UPNP_ENABLE_IPV6
#endif /* UPNP_CONFIG_H */

View File

@@ -43,7 +43,8 @@
#endif
int initialize = 1;
static int initialize_init = 1;
static int initialize_register = 1;
/*! Function pointers to use for displaying formatted strings.
* Set on Initialization of device. */
@@ -67,7 +68,7 @@ ithread_mutex_t display_mutex;
******************************************************************************/
int SampleUtil_Initialize(print_string print_function)
{
if (initialize) {
if (initialize_init) {
ithread_mutexattr_t attr;
ithread_mutexattr_init(&attr);
@@ -80,7 +81,7 @@ int SampleUtil_Initialize(print_string print_function)
gPrintFun = print_function;
ithread_mutex_unlock(&display_mutex);
initialize = 0;
initialize_init = 0;
} else {
SampleUtil_Print("***** SampleUtil_Initialize was called multiple times!\n");
abort();
@@ -99,12 +100,9 @@ int SampleUtil_Initialize(print_string print_function)
******************************************************************************/
int SampleUtil_RegisterUpdateFunction(state_update update_function)
{
/* Intialize only once. */
static int initialize = 1;
if (initialize) {
if (initialize_register) {
gStateUpdateFun = update_function;
initialize = 0;
initialize_register = 0;
}
return UPNP_E_SUCCESS;
@@ -123,7 +121,9 @@ int SampleUtil_Finish()
{
ithread_mutex_destroy(&display_mutex);
gPrintFun = NULL;
initialize = 1;
gStateUpdateFun = NULL;
initialize_init = 1;
initialize_register = 1;
return UPNP_E_SUCCESS;
}

View File

@@ -1310,7 +1310,8 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print(
"Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n",
ip_address, port);
ip_address ? ip_address : "{NULL}",
port);
rc = UpnpInit(ip_address, port);
if (rc != UPNP_E_SUCCESS) {

View File

@@ -1872,7 +1872,8 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print(
"Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n",
ip_address, port );
ip_address ? ip_address : "{NULL}",
port);
ret = UpnpInit( ip_address, port );
if( ret != UPNP_E_SUCCESS ) {
@@ -1886,8 +1887,9 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print(
"UPnP Initialized\n"
"\tipaddress= %s port = %u\n",
ip_address, port );
"\tipaddress = %s port = %u\n",
ip_address ? ip_address : "{NULL}",
port);
if( desc_doc_name == NULL ) {
desc_doc_name = "tvcombodesc.xml";

View File

@@ -1331,7 +1331,8 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print(
"Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n",
ip_address, port);
ip_address ? ip_address : "{NULL}",
port);
rc = UpnpInit(ip_address, port);
if (rc != UPNP_E_SUCCESS) {
@@ -1348,8 +1349,9 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print(
"UPnP Initialized\n"
"\tipaddress= %s port = %u\n",
ip_address, port);
"\tipaddress = %s port = %u\n",
ip_address ? ip_address : "{NULL}",
port);
SampleUtil_Print("Registering Control Point");
rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler,

View File

@@ -28,6 +28,19 @@
#include <string.h> /* for strlen(), strdup() */
#ifdef WIN32
#define strcasecmp stricmp
#else
/* Other systems have strncasecmp */
#endif
/* strndup() is a GNU extension. Other systems must fix it with elif's. */
#ifdef __GNUC__
extern char *strndup(__const char *__string, size_t __n);
#endif
/*!
* \brief Internal implementation of the class UpnpString.
*
@@ -115,42 +128,78 @@ void UpnpString_assign(UpnpString *p, const UpnpString *q)
}
int UpnpString_get_Length(const UpnpString *p)
size_t UpnpString_get_Length(const UpnpString *p)
{
return ((struct SUpnpString *)p)->m_length;
}
void UpnpString_set_Length(UpnpString *p, size_t n)
{
if (((struct SUpnpString *)p)->m_length > n) {
((struct SUpnpString *)p)->m_length = n;
/* No need to realloc now, will do later when needed. */
((struct SUpnpString *)p)->m_string[n] = 0;
}
}
const char *UpnpString_get_String(const UpnpString *p)
{
return ((struct SUpnpString *)p)->m_string;
}
void UpnpString_set_String(UpnpString *p, const char *s)
int UpnpString_set_String(UpnpString *p, const char *s)
{
char *q = strdup(s);
if (!q) goto error_handler1;
free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = strlen(s);
((struct SUpnpString *)p)->m_string = strdup(s);
((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = q;
error_handler1:
return q != NULL;
}
void UpnpString_set_StringN(UpnpString *p, const char *s, int n)
int UpnpString_set_StringN(UpnpString *p, const char *s, size_t n)
{
char *q = strndup(s, n);
if (!q) goto error_handler1;
free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = n;
((struct SUpnpString *)p)->m_string = (char *)malloc(n+1);
strncpy(((struct SUpnpString *)p)->m_string, s, n);
((struct SUpnpString *)p)->m_string[n] = 0;
((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = q;
error_handler1:
return q != NULL;
}
void UpnpString_clear(UpnpString *p)
{
((struct SUpnpString *)p)->m_length = 0;
// No need to realloc now, will do later when needed
/* No need to realloc now, will do later when needed. */
((struct SUpnpString *)p)->m_string[0] = 0;
}
int UpnpString_cmp(UpnpString *p, UpnpString *q)
{
const char *cp = UpnpString_get_String(p);
const char *cq = UpnpString_get_String(q);
return strcmp(cp, cq);
}
int UpnpString_casecmp(UpnpString *p, UpnpString *q)
{
const char *cp = UpnpString_get_String(p);
const char *cq = UpnpString_get_String(q);
return strcasecmp(cp, cq);
}
/* @} UpnpString */

View File

@@ -282,6 +282,7 @@ static int UpnpInitThreadPools(void)
TPAttrInit(&attr);
TPAttrSetMaxThreads(&attr, MAX_THREADS);
TPAttrSetMinThreads(&attr, MIN_THREADS);
TPAttrSetStackSize(&attr, THREAD_STACK_SIZE);
TPAttrSetJobsPerThread(&attr, JOBS_PER_THREAD);
TPAttrSetIdleTime(&attr, THREAD_IDLE_TIME);
TPAttrSetMaxJobsTotal(&attr, MAX_JOBS_TOTAL);
@@ -488,7 +489,7 @@ exit_function:
return retVal;
}
#ifdef UPNP_ENABLE_IPV6
int UpnpInit2(const char *IfName, unsigned short DestPort)
{
int retVal;
@@ -533,8 +534,9 @@ int UpnpInit2(const char *IfName, unsigned short DestPort)
exit_function:
ithread_mutex_unlock(&gSDKInitMutex);
return UPNP_E_SUCCESS;
return retVal;
}
#endif
int UpnpFinish(void)
@@ -620,7 +622,7 @@ unsigned short UpnpGetServerPort(void)
return LOCAL_PORT_V4;
}
#ifdef UPNP_ENABLE_IPV6
unsigned short UpnpGetServerPort6(void)
{
if (UpnpSdkInit != 1) {
@@ -629,6 +631,7 @@ unsigned short UpnpGetServerPort6(void)
return LOCAL_PORT_V6;
}
#endif
char *UpnpGetServerIpAddress(void)
@@ -777,8 +780,10 @@ int UpnpRegisterRootDevice(
HInfo->DeviceList = NULL;
HInfo->ServiceList = NULL;
HInfo->DescDocument = NULL;
CLIENTONLY( ListInit(&HInfo->SsdpSearchList, NULL, NULL); )
CLIENTONLY( HInfo->ClientSubList = NULL; )
#ifdef INCLUDE_CLIENT_APIS
ListInit(&HInfo->SsdpSearchList, NULL, NULL);
HInfo->ClientSubList = NULL;
#endif /* INCLUDE_CLIENT_APIS */
HInfo->MaxSubscriptions = UPNP_INFINITE;
HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
HInfo->DeviceAf = AF_INET;
@@ -788,7 +793,9 @@ int UpnpRegisterRootDevice(
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"UpnpRegisterRootDevice: error downloading Document: %d\n",
retVal);
CLIENTONLY( ListDestroy(&HInfo->SsdpSearchList, 0); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy(&HInfo->SsdpSearchList, 0);
#endif /* INCLUDE_CLIENT_APIS */
FreeHandle(*Hnd);
goto exit_function;
}
@@ -800,7 +807,9 @@ int UpnpRegisterRootDevice(
HInfo->DeviceList =
ixmlDocument_getElementsByTagName(HInfo->DescDocument, "device");
if (!HInfo->DeviceList) {
CLIENTONLY( ListDestroy(&HInfo->SsdpSearchList, 0); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy(&HInfo->SsdpSearchList, 0);
#endif /* INCLUDE_CLIENT_APIS */
ixmlDocument_free(HInfo->DescDocument);
FreeHandle(*Hnd);
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
@@ -936,8 +945,10 @@ int UpnpRegisterRootDevice2(
HInfo->MaxAge = DEFAULT_MAXAGE;
HInfo->DeviceList = NULL;
HInfo->ServiceList = NULL;
CLIENTONLY( ListInit(&HInfo->SsdpSearchList, NULL, NULL); )
CLIENTONLY( HInfo->ClientSubList = NULL; )
#ifdef INCLUDE_CLIENT_APIS
ListInit(&HInfo->SsdpSearchList, NULL, NULL);
HInfo->ClientSubList = NULL;
#endif /* INCLUDE_CLIENT_APIS */
HInfo->MaxSubscriptions = UPNP_INFINITE;
HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
HInfo->DeviceAf = AF_INET;
@@ -950,7 +961,9 @@ int UpnpRegisterRootDevice2(
HInfo->DeviceList =
ixmlDocument_getElementsByTagName( HInfo->DescDocument, "device" );
if (!HInfo->DeviceList) {
CLIENTONLY( ListDestroy(&HInfo->SsdpSearchList, 0); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy(&HInfo->SsdpSearchList, 0);
#endif /* INCLUDE_CLIENT_APIS */
ixmlDocument_free(HInfo->DescDocument);
FreeHandle(*Hnd);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
@@ -1010,17 +1023,16 @@ int UpnpRegisterRootDevice3(
struct Handle_Info *HInfo;
int retVal = 0;
int hasServiceTable = 0;
int handler_index = 0;
HandleLock();
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Inside UpnpRegisterRootDevice3\n");
if (UpnpSdkInit != 1) {
retVal = UPNP_E_FINISH;
goto exit_function;
}
if (Hnd == NULL ||
Fun == NULL ||
DescUrl == NULL ||
@@ -1029,17 +1041,14 @@ int UpnpRegisterRootDevice3(
retVal = UPNP_E_INVALID_PARAM;
goto exit_function;
}
/* Test for already regsitered IPV4. */
if (AddressFamily == AF_INET && UpnpSdkDeviceRegisteredV4 == 1) {
retVal = UPNP_E_ALREADY_REGISTERED;
goto exit_function;
}
/* Test for already registered IPV6. IPV6 devices might register on multiple
* IPv6 addresses (link local and GUA or ULA), so we must to check the
* description URL in the HandleTable. */
int handler_index = 0;
while (handler_index < NUM_HANDLE && HandleTable[handler_index] != NULL) {
if (strcmp(((struct Handle_Info *)HandleTable[handler_index])->DescURL, DescUrl)) {
retVal = UPNP_E_ALREADY_REGISTERED;
@@ -1047,13 +1056,11 @@ int UpnpRegisterRootDevice3(
}
handler_index++;
}
*Hnd = GetFreeHandle();
if (*Hnd == UPNP_E_OUTOF_HANDLE) {
retVal = UPNP_E_OUTOF_MEMORY;
goto exit_function;
}
HInfo = (struct Handle_Info *)malloc(sizeof (struct Handle_Info));
if (HInfo == NULL) {
retVal = UPNP_E_OUTOF_MEMORY;
@@ -1062,7 +1069,6 @@ int UpnpRegisterRootDevice3(
HandleTable[*Hnd] = HInfo;
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Root device URL is %s\n", DescUrl);
HInfo->aliasInstalled = 0;
HInfo->HType = HND_DEVICE;
strcpy(HInfo->DescURL, DescUrl);
@@ -1072,15 +1078,18 @@ int UpnpRegisterRootDevice3(
HInfo->DeviceList = NULL;
HInfo->ServiceList = NULL;
HInfo->DescDocument = NULL;
CLIENTONLY( ListInit(&HInfo->SsdpSearchList, NULL, NULL); )
CLIENTONLY( HInfo->ClientSubList = NULL; )
#ifdef INCLUDE_CLIENT_APIS
ListInit(&HInfo->SsdpSearchList, NULL, NULL);
HInfo->ClientSubList = NULL;
#endif /* INCLUDE_CLIENT_APIS */
HInfo->MaxSubscriptions = UPNP_INFINITE;
HInfo->MaxSubscriptionTimeOut = UPNP_INFINITE;
HInfo->DeviceAf = AddressFamily;
retVal = UpnpDownloadXmlDoc(HInfo->DescURL, &(HInfo->DescDocument));
if (retVal != UPNP_E_SUCCESS) {
CLIENTONLY( ListDestroy(&HInfo->SsdpSearchList, 0); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy(&HInfo->SsdpSearchList, 0);
#endif /* INCLUDE_CLIENT_APIS */
FreeHandle(*Hnd);
goto exit_function;
}
@@ -1092,7 +1101,9 @@ int UpnpRegisterRootDevice3(
HInfo->DeviceList = ixmlDocument_getElementsByTagName(
HInfo->DescDocument, "device");
if (!HInfo->DeviceList) {
CLIENTONLY( ListDestroy(&HInfo->SsdpSearchList, 0); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy(&HInfo->SsdpSearchList, 0);
#endif /* INCLUDE_CLIENT_APIS */
ixmlDocument_free(HInfo->DescDocument);
FreeHandle(*Hnd);
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
@@ -1184,7 +1195,9 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
ixmlNodeList_free( HInfo->ServiceList );
ixmlDocument_free( HInfo->DescDocument );
CLIENTONLY( ListDestroy( &HInfo->SsdpSearchList, 0 ); )
#ifdef INCLUDE_CLIENT_APIS
ListDestroy( &HInfo->SsdpSearchList, 0 );
#endif /* INCLUDE_CLIENT_APIS */
#ifdef INTERNAL_WEB_SERVER
if( HInfo->aliasInstalled ) {

View File

@@ -320,18 +320,18 @@ static int gena_subscribe(
"TIMEOUT: Second-", timeout_str );
} else {
// subscribe
if( dest_url.hostport.IPaddress.ss_family == AF_INET6 ) {
if (dest_url.hostport.IPaddress.ss_family == AF_INET6) {
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&dest_url.hostport.IPaddress;
return_code = http_MakeMessage(
&request, 1, 1,
"q" "sssdsc" "sc" "sscc",
HTTPMETHOD_SUBSCRIBE, &dest_url,
"CALLBACK: <http://[",
((IN6_IS_ADDR_LINKLOCAL(DestAddr6))||(strlen(gIF_IPV6_ULA_GUA) == 0 ))?
gIF_IPV6 : gIF_IPV6_ULA_GUA,
(IN6_IS_ADDR_LINKLOCAL(&DestAddr6->sin6_addr) || strlen(gIF_IPV6_ULA_GUA) == 0) ?
gIF_IPV6 : gIF_IPV6_ULA_GUA,
"]:", LOCAL_PORT_V6, "/>",
"NT: upnp:event",
"TIMEOUT: Second-", timeout_str );
"TIMEOUT: Second-", timeout_str);
} else {
return_code = http_MakeMessage(
&request, 1, 1,

View File

@@ -178,70 +178,76 @@ static UPNP_INLINE int notify_send_and_recv(
/*! [out] The response from the control point. */
http_parser_t *response)
{
uri_type url;
int conn_fd;
membuffer start_msg;
int ret_code;
int err_code;
int timeout;
SOCKINFO info;
uri_type url;
int conn_fd;
membuffer start_msg;
int ret_code;
int err_code;
int timeout;
SOCKINFO info;
// connect
UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__,
"gena notify to: %.*s\n",
(int)destination_url->hostport.text.size,
destination_url->hostport.text.buff );
/* connect */
UpnpPrintf(UPNP_ALL, GENA, __FILE__, __LINE__,
"gena notify to: %.*s\n",
(int)destination_url->hostport.text.size,
destination_url->hostport.text.buff);
conn_fd = http_Connect( destination_url, &url );
if( conn_fd < 0 ) {
return conn_fd; // return UPNP error
}
conn_fd = http_Connect(destination_url, &url);
if (conn_fd < 0) {
/* return UPNP error */
if( ( ret_code = sock_init( &info, conn_fd ) ) != 0 ) {
sock_destroy( &info, SD_BOTH );
return ret_code;
}
// make start line and HOST header
membuffer_init( &start_msg );
if (http_MakeMessage(
&start_msg, 1, 1,
"q" "s",
HTTPMETHOD_NOTIFY, &url,
mid_msg->buf ) != 0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
return UPNP_E_OUTOF_MEMORY;
}
return conn_fd;
}
timeout = HTTP_DEFAULT_TIMEOUT;
ret_code = sock_init(&info, conn_fd);
if (ret_code) {
sock_destroy(&info, SD_BOTH);
// send msg (note +1 for propertyset; null-terminator is also sent)
if( ( ret_code = http_SendMessage( &info, &timeout,
"bb",
start_msg.buf, start_msg.length,
propertySet,
strlen( propertySet ) + 1 ) ) !=
0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
return ret_code;
}
return ret_code;
}
/* make start line and HOST header */
membuffer_init(&start_msg);
if (http_MakeMessage(
&start_msg, 1, 1,
"q" "s",
HTTPMETHOD_NOTIFY, &url,
mid_msg->buf) != 0) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
if( ( ret_code = http_RecvMessage( &info, response,
HTTPMETHOD_NOTIFY, &timeout,
&err_code ) ) != 0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
httpmsg_destroy( &response->msg );
return ret_code;
}
return UPNP_E_OUTOF_MEMORY;
}
sock_destroy( &info, SD_BOTH ); //should shutdown completely
//when closing socket
// sock_destroy( &info,SD_RECEIVE);
membuffer_destroy( &start_msg );
timeout = HTTP_DEFAULT_TIMEOUT;
return UPNP_E_SUCCESS;
/* send msg (note: end of notification will contain "\r\n" twice) */
ret_code = http_SendMessage(&info, &timeout,
"bbb",
start_msg.buf, start_msg.length,
propertySet, strlen(propertySet),
"\r\n", 2);
if (ret_code) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
return ret_code;
}
ret_code = http_RecvMessage(&info, response,
HTTPMETHOD_NOTIFY, &timeout, &err_code);
if (ret_code) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
httpmsg_destroy(&response->msg);
return ret_code;
}
/* should shutdown completely when closing socket */
sock_destroy(&info, SD_BOTH);
membuffer_destroy(&start_msg);
return UPNP_E_SUCCESS;
}
@@ -336,7 +342,12 @@ static void genaNotifyThread(
struct Handle_Info *handle_info;
ThreadPoolJob job;
HandleReadLock();
/* This should be a HandleLock and not a HandleReadLock otherwise if there
* is a lot of notifications, then multiple threads will acquire a read
* lock and the thread which sends the notification will be blocked forever
* on the HandleLock at the end of this function. */
//HandleReadLock();
HandleLock();
//validate context
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
@@ -354,18 +365,27 @@ static void genaNotifyThread(
HandleUnlock();
return;
}
#ifdef UPNP_ENABLE_NOTIFICATION_REORDERING
//If the event is out of order push it back to the job queue
if( in->eventKey != sub->ToSendEventKey ) {
TPJobInit( &job, ( start_routine ) genaNotifyThread, input );
TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
/* Sleep a little before creating another thread otherwise if there is
* a lot of notifications to send, the device will take 100% of the CPU
* to create threads and push them back to the job queue. */
imillisleep( 1 );
ThreadPoolAdd( &gSendThreadPool, &job, NULL );
freeSubscription( &sub_copy );
HandleUnlock();
return;
}
#endif
HandleUnlock();

View File

@@ -579,41 +579,59 @@ static int get_miniserver_sockets(
{
char errorBuffer[ERROR_BUFFER_LEN];
struct sockaddr_storage __ss_v4;
struct sockaddr_storage __ss_v6;
struct sockaddr_in* serverAddr4 = (struct sockaddr_in*)&__ss_v4;
SOCKET listenfd4 = INVALID_SOCKET;
unsigned short actual_port4;
#ifdef UPNP_ENABLE_IPV6
struct sockaddr_storage __ss_v6;
struct sockaddr_in6* serverAddr6 = (struct sockaddr_in6*)&__ss_v6;
SOCKET listenfd4, listenfd6;
SOCKET listenfd6 = INVALID_SOCKET;
unsigned short actual_port6;
#endif
int ret_code;
unsigned short actual_port4, actual_port6;
int reuseaddr_on = 0;
int sockError = UPNP_E_SUCCESS;
int errCode = 0;
//
// Initialize all the sockets to be invalid
//
out->miniServerSock4 = INVALID_SOCKET;
out->miniServerSock6 = INVALID_SOCKET;
// Create listen socket for IPv4/IPv6. An error here may indicate
// that we don't have an IPv4/IPv6 stack.
listenfd4 = socket(AF_INET, SOCK_STREAM, 0);
listenfd6 = socket(AF_INET6, SOCK_STREAM, 0);
if (listenfd4 == INVALID_SOCKET && listenfd6 == INVALID_SOCKET) {
if (listenfd4 == INVALID_SOCKET) {
return UPNP_E_OUTOF_SOCKET;
}
#ifdef UPNP_ENABLE_IPV6
listenfd6 = socket(AF_INET6, SOCK_STREAM, 0);
if (listenfd6 == INVALID_SOCKET) {
return UPNP_E_OUTOF_SOCKET;
}
#endif
// As per the IANA specifications for the use of ports by applications
// override the listen port passed in with the first available
if (listen_port4 < APPLICATION_LISTENING_PORT) {
listen_port4 = APPLICATION_LISTENING_PORT;
}
#ifdef UPNP_ENABLE_IPV6
if (listen_port6 < APPLICATION_LISTENING_PORT) {
listen_port6 = APPLICATION_LISTENING_PORT;
}
#endif
memset(&__ss_v4, 0, sizeof (__ss_v4));
serverAddr4->sin_family = AF_INET;
serverAddr4->sin_addr.s_addr = htonl(INADDR_ANY);
#ifdef UPNP_ENABLE_IPV6
memset(&__ss_v6, 0, sizeof (__ss_v6));
serverAddr6->sin6_family = AF_INET6;
serverAddr6->sin6_addr = in6addr_any;
#endif
// Getting away with implementation of re-using address:port and instead
// choosing to increment port numbers.
// Keeping the re-use address code as an optional behaviour that can be
@@ -633,8 +651,10 @@ static int get_miniserver_sockets(
if (sockError == -1) {
shutdown(listenfd4, SD_BOTH);
UpnpCloseSocket(listenfd4);
#ifdef UPNP_ENABLE_IPV6
shutdown(listenfd6, SD_BOTH);
UpnpCloseSocket(listenfd6);
#endif
return UPNP_E_SOCKET_BIND;
}
@@ -647,14 +667,17 @@ static int get_miniserver_sockets(
errorBuffer);
shutdown(listenfd4, SD_BOTH);
UpnpCloseSocket(listenfd4);
#ifdef UPNP_ENABLE_IPV6
shutdown(listenfd6, SD_BOTH);
UpnpCloseSocket(listenfd6);
#endif
/* Bind failed */
return UPNP_E_SOCKET_BIND;
}
}
if(listenfd6 != INVALID_SOCKET) {
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != INVALID_SOCKET) {
sockError = setsockopt(listenfd6, SOL_SOCKET, SO_REUSEADDR,
(const char *)&reuseaddr_on, sizeof (int));
if (sockError == -1) {
@@ -680,6 +703,7 @@ static int get_miniserver_sockets(
return UPNP_E_SOCKET_BIND;
}
}
#endif //IPv6
} else {
if (listenfd4 != INVALID_SOCKET) {
unsigned short orig_listen_port4 = listen_port4;
@@ -707,12 +731,15 @@ static int get_miniserver_sockets(
errorBuffer);
shutdown(listenfd4, SD_BOTH);
UpnpCloseSocket(listenfd4);
#ifdef UPNP_ENABLE_IPV6
shutdown(listenfd6, SD_BOTH);
UpnpCloseSocket(listenfd6);
#endif
return UPNP_E_SOCKET_BIND; // bind failed
}
}
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != INVALID_SOCKET) {
unsigned short orig_listen_port6 = listen_port6;
do {
@@ -745,6 +772,7 @@ static int get_miniserver_sockets(
return UPNP_E_SOCKET_BIND;
}
}
#endif
}
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
@@ -759,8 +787,10 @@ static int get_miniserver_sockets(
errorBuffer);
shutdown(listenfd4, SD_BOTH);
UpnpCloseSocket(listenfd4);
#ifdef UPNP_ENABLE_IPV6
shutdown(listenfd6, SD_BOTH);
UpnpCloseSocket(listenfd6);
#endif
return UPNP_E_LISTEN;
}
@@ -768,14 +798,17 @@ static int get_miniserver_sockets(
if (actual_port4 <= 0) {
shutdown(listenfd4, SD_BOTH);
UpnpCloseSocket(listenfd4);
#ifdef UPNP_ENABLE_IPV6
shutdown(listenfd6, SD_BOTH);
UpnpCloseSocket(listenfd6);
#endif
return UPNP_E_INTERNAL_ERROR;
}
out->miniServerPort4 = actual_port4;
}
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != INVALID_SOCKET) {
ret_code = listen(listenfd6, SOMAXCONN);
if (ret_code == -1) {
@@ -801,10 +834,11 @@ static int get_miniserver_sockets(
out->miniServerPort6 = actual_port6;
}
#endif
out->miniServerSock4 = listenfd4;
#ifdef UPNP_ENABLE_IPV6
out->miniServerSock6 = listenfd6;
#endif
return UPNP_E_SUCCESS;
}
#endif /* INTERNAL_WEB_SERVER */

View File

@@ -72,7 +72,6 @@ static str_int_entry Http_Method_Table[NUM_HTTP_METHODS] = {
{"SUBSCRIBE", HTTPMETHOD_SUBSCRIBE},
{"UNSUBSCRIBE", HTTPMETHOD_UNSUBSCRIBE},
{"POST", SOAPMETHOD_POST},
};
#define NUM_HTTP_HEADER_NAMES 33
@@ -113,9 +112,7 @@ str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES] = {
};
/***********************************************************************/
/************* scanner *************/
/***********************************************************************/
#define TOKCHAR_CR 0xD
@@ -134,13 +131,11 @@ str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES] = {
*
* Note :
************************************************************************/
static UPNP_INLINE void
scanner_init( OUT scanner_t *scanner,
IN membuffer *bufptr )
static UPNP_INLINE void scanner_init(OUT scanner_t *scanner, IN membuffer *bufptr)
{
scanner->cursor = 0;
scanner->msg = bufptr;
scanner->entire_msg_loaded = FALSE;
scanner->cursor = 0;
scanner->msg = bufptr;
scanner->entire_msg_loaded = FALSE;
}
/************************************************************************
@@ -155,10 +150,9 @@ scanner_init( OUT scanner_t *scanner,
*
* Note :
************************************************************************/
static UPNP_INLINE xboolean
is_separator_char( IN char c )
static UPNP_INLINE xboolean is_separator_char(IN char c)
{
return strchr( " \t()<>@,;:\\\"/[]?={}", c ) != NULL;
return strchr(" \t()<>@,;:\\\"/[]?={}", c) != NULL;
}
/************************************************************************
@@ -173,10 +167,9 @@ is_separator_char( IN char c )
*
* Note :
************************************************************************/
static UPNP_INLINE xboolean
is_identifier_char( IN char c )
static UPNP_INLINE xboolean is_identifier_char(IN char c)
{
return ( c >= 32 && c <= 126 ) && !is_separator_char( c );
return c >= 32 && c <= 126 && !is_separator_char(c);
}
/************************************************************************
@@ -191,10 +184,9 @@ is_identifier_char( IN char c )
*
* Note :
************************************************************************/
static UPNP_INLINE xboolean
is_control_char( IN char c )
static UPNP_INLINE xboolean is_control_char(IN char c)
{
return ( ( c >= 0 && c <= 31 ) || ( c == 127 ) );
return (c >= 0 && c <= 31) || c == 127;
}
/************************************************************************
@@ -209,8 +201,7 @@ is_control_char( IN char c )
*
* Note :
************************************************************************/
static UPNP_INLINE xboolean
is_qdtext_char( IN char cc )
static UPNP_INLINE xboolean is_qdtext_char(IN char cc)
{
unsigned char c = ( unsigned char )cc;
@@ -244,10 +235,10 @@ is_qdtext_char( IN char cc )
*
* Note :
************************************************************************/
static parse_status_t
scanner_get_token( INOUT scanner_t * scanner,
OUT memptr * token,
OUT token_type_t * tok_type )
static parse_status_t scanner_get_token(
INOUT scanner_t *scanner,
OUT memptr *token,
OUT token_type_t *tok_type)
{
char *cursor;
char *null_terminator; // point to null-terminator in buffer
@@ -388,57 +379,11 @@ scanner_get_token( INOUT scanner_t * scanner,
*
* Note :
************************************************************************/
static UPNP_INLINE char *
scanner_get_str( IN scanner_t * scanner )
static UPNP_INLINE char *scanner_get_str(IN scanner_t * scanner)
{
return scanner->msg->buf + scanner->cursor;
return scanner->msg->buf + scanner->cursor;
}
/************************************************************************
* Function : scanner_pushback
*
* Parameters :
* INOUT scanner_t* scanner ; Scanner Object
* IN size_t pushback_bytes ; Bytes to be moved back
*
* Description : Move back by a certain number of bytes.
* This is used to put back one or more tokens back into the input
*
* Return : void ;
*
* Note :
************************************************************************/
#ifdef WIN32
#pragma message ("The only use of the function 'scanner_pushback()' in the code is commented out.")
#pragma message ("'scanner_pushback()' is a candidate for removal.")
#else
#warning The only use of the function 'scanner_pushback()' in the code is commented out.
#warning 'scanner_pushback()' is a candidate for removal.
#endif
static UPNP_INLINE void
scanner_pushback( INOUT scanner_t * scanner,
IN size_t pushback_bytes )
{
scanner->cursor -= pushback_bytes;
}
/***********************************************************************/
/************* end of scanner **************/
/***********************************************************************/
/***********************************************************************/
/************* parser **************/
/***********************************************************************/
/***********************************************************************/
/************* http_message_t **************/
/***********************************************************************/
/************************************************************************
* Function : httpmsg_compare
@@ -453,15 +398,14 @@ scanner_pushback( INOUT scanner_t * scanner,
*
* Note :
************************************************************************/
static int
httpmsg_compare( void *param1,
void *param2 )
static int httpmsg_compare(void *param1, void *param2)
{
assert( param1 != NULL );
assert( param2 != NULL );
return ( ( http_header_t * ) param1 )->name_id ==
( ( http_header_t * ) param2 )->name_id;
return
((http_header_t *)param1)->name_id ==
((http_header_t *)param2)->name_id;
}
/************************************************************************
@@ -476,8 +420,7 @@ httpmsg_compare( void *param1,
*
* Note :
************************************************************************/
static void
httpheader_free( void *msg )
static void httpheader_free(void *msg)
{
http_header_t *hdr = ( http_header_t * ) msg;
@@ -498,8 +441,7 @@ httpheader_free( void *msg )
*
* Note :
************************************************************************/
void
httpmsg_init( INOUT http_message_t * msg )
void httpmsg_init(INOUT http_message_t *msg)
{
msg->initialized = 1;
msg->entity.buf = NULL;
@@ -521,8 +463,7 @@ httpmsg_init( INOUT http_message_t * msg )
*
* Note :
************************************************************************/
void
httpmsg_destroy( INOUT http_message_t * msg )
void httpmsg_destroy( INOUT http_message_t * msg )
{
assert( msg != NULL );
@@ -550,9 +491,9 @@ httpmsg_destroy( INOUT http_message_t * msg )
*
* Note :
************************************************************************/
http_header_t *
httpmsg_find_hdr_str( IN http_message_t * msg,
IN const char *header_name )
http_header_t *httpmsg_find_hdr_str(
IN http_message_t *msg,
IN const char *header_name)
{
http_header_t *header;
@@ -587,27 +528,21 @@ httpmsg_find_hdr_str( IN http_message_t * msg,
*
* Note :
************************************************************************/
http_header_t *
httpmsg_find_hdr( IN http_message_t * msg,
IN int header_name_id,
OUT memptr * value )
http_header_t *httpmsg_find_hdr(
IN http_message_t *msg,
IN int header_name_id,
OUT memptr *value)
{
http_header_t header; // temp header for searching
ListNode *node;
http_header_t *data;
header.name_id = header_name_id;
node = ListFind( &msg->headers, NULL, &header );
if( node == NULL ) {
return NULL;
}
data = ( http_header_t * ) node->item;
if( value != NULL ) {
value->buf = data->value.buf;
value->length = data->value.length;
@@ -616,12 +551,6 @@ httpmsg_find_hdr( IN http_message_t * msg,
return data;
}
/***********************************************************************/
/************* http_parser_t **************/
/***********************************************************************/
/************************************************************************
* Function : skip_blank_lines
*
@@ -634,26 +563,23 @@ httpmsg_find_hdr( IN http_message_t * msg,
*
* Note :
************************************************************************/
static UPNP_INLINE int
skip_blank_lines( INOUT scanner_t * scanner )
static UPNP_INLINE int skip_blank_lines(INOUT scanner_t *scanner)
{
memptr token;
token_type_t tok_type;
parse_status_t status;
memptr token;
token_type_t tok_type;
parse_status_t status;
// skip ws, crlf
do {
status = scanner_get_token( scanner, &token, &tok_type );
} while( status == PARSE_OK &&
( tok_type == TT_WHITESPACE || tok_type == TT_CRLF ) );
/* skip ws, crlf */
do {
status = scanner_get_token(scanner, &token, &tok_type);
} while (status == PARSE_OK &&
(tok_type == TT_WHITESPACE || tok_type == TT_CRLF));
if (status == PARSE_OK) {
/* pushback a non-whitespace token */
scanner->cursor -= token.length;
}
if( status == PARSE_OK ) {
// pushback a non-whitespace token
scanner->cursor -= token.length;
//scanner_pushback( scanner, token.length );
}
return status;
return status;
}
/************************************************************************
@@ -671,8 +597,7 @@ skip_blank_lines( INOUT scanner_t * scanner )
*
* Note :
************************************************************************/
static UPNP_INLINE int
skip_lws( INOUT scanner_t * scanner )
static UPNP_INLINE int skip_lws(INOUT scanner_t *scanner)
{
memptr token;
token_type_t tok_type;
@@ -726,9 +651,9 @@ skip_lws( INOUT scanner_t * scanner )
*
* Note :
************************************************************************/
static UPNP_INLINE parse_status_t
match_non_ws_string( INOUT scanner_t * scanner,
OUT memptr * str )
static UPNP_INLINE parse_status_t match_non_ws_string(
INOUT scanner_t *scanner,
OUT memptr *str)
{
memptr token;
token_type_t tok_type;
@@ -792,9 +717,9 @@ match_non_ws_string( INOUT scanner_t * scanner,
*
* Note :
************************************************************************/
static UPNP_INLINE parse_status_t
match_raw_value( INOUT scanner_t * scanner,
OUT memptr * raw_value )
static UPNP_INLINE parse_status_t match_raw_value(
INOUT scanner_t * scanner,
OUT memptr *raw_value)
{
memptr token;
token_type_t tok_type;
@@ -883,10 +808,10 @@ match_raw_value( INOUT scanner_t * scanner,
* PARSE_FAILURE -- bad input
* PARSE_INCOMPLETE
************************************************************************/
static UPNP_INLINE int
match_int( INOUT scanner_t * scanner,
IN int base,
OUT int *value )
static UPNP_INLINE int match_int(
INOUT scanner_t *scanner,
IN int base,
OUT int *value)
{
memptr token;
token_type_t tok_type;
@@ -970,36 +895,6 @@ read_until_crlf( INOUT scanner_t * scanner,
return status;
}
/************************************************************************
* Function: skip_to_end_of_header
*
* Parameters:
* INOUT scanner_t* scanner ; Scanner Object
*
* Description: Skip to end of header
*
* Returns:
* PARSE_OK
* PARSE_FAILURE
* PARSE_INCOMPLETE
************************************************************************/
#ifdef WIN32
#pragma message("There are currently no uses of the function 'skip_to_end_of_header()' in the code.")
#pragma message("'skip_to_end_of_header()' is a candidate for removal.")
#else
#warning There are currently no uses of the function 'skip_to_end_of_header()' in the code.
#warning 'skip_to_end_of_header()' is a candidate for removal.
#endif
static UPNP_INLINE int
skip_to_end_of_header( INOUT scanner_t * scanner )
{
memptr dummy_raw_value;
parse_status_t status;
status = match_raw_value( scanner, &dummy_raw_value );
return status;
}
/************************************************************************
* Function: match_char
*
@@ -1754,140 +1649,6 @@ parser_parse_headers( INOUT http_parser_t * parser )
}
////////////////////////////////////////////////////////////////////////
#ifdef HIGHLY_UNLIKELY
// **************
static parse_status_t
parser_parse_headers_old( INOUT http_parser_t * parser )
{
parse_status_t status;
memptr token;
memptr hdr_value;
token_type_t tok_type;
scanner_t *scanner = &parser->scanner;
size_t save_pos;
http_header_t *header;
int header_id;
int ret = 0;
int index;
http_header_t *orig_header;
char save_char;
int ret2,
ret3;
assert( parser->position == POS_HEADERS ||
parser->ent_position == ENTREAD_CHUNKY_HEADERS );
while( TRUE ) {
save_pos = scanner->cursor;
//
// check end of headers
//
status = scanner_get_token( scanner, &token, &tok_type );
if( status != PARSE_OK ) {
return status;
}
if( tok_type == TT_CRLF ) {
// end of headers
parser->position = POS_ENTITY; // read entity next
return PARSE_OK;
}
//
// not end; read header
//
if( tok_type != TT_IDENTIFIER ) {
return PARSE_FAILURE; // didn't see header name
}
status = match( scanner, " : %R%c", &hdr_value );
if( status != PARSE_OK ) {
// pushback tokens; useful only on INCOMPLETE error
scanner->cursor = save_pos;
return status;
}
//
// add header
//
// find header
index = map_str_to_int( token.buf, token.length, Http_Header_Names,
NUM_HTTP_HEADER_NAMES, FALSE );
if( index != -1 ) {
header_id = Http_Header_Names[index].id;
orig_header =
httpmsg_find_hdr( &parser->msg, header_id, NULL );
} else {
header_id = HDR_UNKNOWN;
save_char = token.buf[token.length];
token.buf[token.length] = '\0';
orig_header = httpmsg_find_hdr_str( &parser->msg, token.buf );
token.buf[token.length] = save_char; // restore
}
if( orig_header == NULL ) {
//
// add new header
//
header = ( http_header_t * ) malloc( sizeof( http_header_t ) );
if( header == NULL ) {
parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
return PARSE_FAILURE;
}
membuffer_init( &header->multi_hdr_buf );
header->name = token;
header->value = hdr_value;
header->name_id = header_id;
ret = dlist_append( &parser->msg.headers, header );
if( ret == UPNP_E_OUTOF_MEMORY ) {
parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
return PARSE_FAILURE;
}
} else if( hdr_value.length > 0 ) {
//
// append value to existing header
//
if( orig_header->multi_hdr_buf.buf == NULL ) {
// store in buffer
ret = membuffer_append( &orig_header->multi_hdr_buf,
orig_header->value.buf,
orig_header->value.length );
}
// append space
ret2 =
membuffer_append( &orig_header->multi_hdr_buf, ", ", 2 );
// append continuation of header value
ret3 = membuffer_append( &orig_header->multi_hdr_buf,
hdr_value.buf, hdr_value.length );
if( ret == UPNP_E_OUTOF_MEMORY ||
ret2 == UPNP_E_OUTOF_MEMORY ||
ret3 == UPNP_E_OUTOF_MEMORY ) {
// not enuf mem
parser->http_error_code = HTTP_INTERNAL_SERVER_ERROR;
return PARSE_FAILURE;
}
// header value points to allocated buf
orig_header->value.buf = orig_header->multi_hdr_buf.buf;
orig_header->value.length = orig_header->multi_hdr_buf.length;
}
} // end while
}
#endif
// ******************************
/************************************************************************
* Function: parser_parse_entity_using_clen
*
@@ -1909,9 +1670,9 @@ parser_parse_entity_using_clen( INOUT http_parser_t * parser )
assert( parser->ent_position == ENTREAD_USING_CLEN );
// determine entity (i.e. body) length so far
//entity_length = parser->msg.msg.length - parser->entity_start_position;
parser->msg.entity.length =
parser->msg.msg.length - parser->entity_start_position;
parser->msg.msg.length - parser->entity_start_position +
parser->msg.entity_offset;
if( parser->msg.entity.length < parser->content_length ) {
// more data to be read
@@ -1919,7 +1680,8 @@ parser_parse_entity_using_clen( INOUT http_parser_t * parser )
} else {
if( parser->msg.entity.length > parser->content_length ) {
// silently discard extra data
parser->msg.msg.buf[parser->entity_start_position +
parser->msg.msg.buf[parser->entity_start_position -
parser->msg.entity_offset +
parser->content_length] = '\0';
}
// save entity length
@@ -2304,6 +2066,7 @@ parser_response_init( OUT http_parser_t * parser,
parser_init( parser );
parser->msg.is_request = FALSE;
parser->msg.request_method = request_method;
parser->msg.entity_offset = 0;
parser->position = POS_RESPONSE_LINE;
}
@@ -2399,10 +2162,6 @@ parser_append( INOUT http_parser_t * parser,
return parser_parse( parser );
}
/************************************************************************
********** end of parser ***********
************************************************************************/
/************************************************************************
* Function: raw_to_int
*
@@ -2415,9 +2174,7 @@ parser_append( INOUT http_parser_t * parser,
* Returns:
* int
************************************************************************/
int
raw_to_int( IN memptr * raw_value,
IN int base )
int raw_to_int(IN memptr *raw_value, IN int base)
{
long num;
char *end_ptr;
@@ -2454,9 +2211,7 @@ raw_to_int( IN memptr * raw_value,
* Returns:
* int - index at which the substring is found.
************************************************************************/
int
raw_find_str( IN memptr *raw_value,
IN const char *str )
int raw_find_str(IN memptr *raw_value, IN const char *str)
{
char c;
char *ptr;
@@ -2499,8 +2254,7 @@ raw_find_str( IN memptr *raw_value,
* Returns:
* const char* ptr - Ptr to the HTTP Method
************************************************************************/
const char *
method_to_str( IN http_method_t method )
const char *method_to_str(IN http_method_t method)
{
int index;
@@ -2544,5 +2298,5 @@ void print_http_headers(http_message_t *hmsg)
/* NNS: node = dlist_next( &hmsg->headers, node ); */
}
}
#endif
#endif /* DEBUG */

File diff suppressed because it is too large Load Diff

View File

@@ -307,9 +307,10 @@ search_extension( IN const char *extension,
* 0 - On Sucess
* UPNP_E_OUTOF_MEMORY - on memory allocation failures
************************************************************************/
UPNP_INLINE int
get_content_type( IN const char *filename,
OUT DOMString * content_type )
static UPNP_INLINE int
get_content_type(
IN const char *filename,
OUT DOMString *content_type)
{
const char *extension;
const char *type;
@@ -1123,6 +1124,12 @@ CheckOtherHTTPHeaders( IN http_message_t * Req,
return RetCode;
}
break;
case HDR_ACCEPT_LANGUAGE:
{
memcpy( RespInstr->AcceptLanguageHeader, TmpBuf,
sizeof( RespInstr->AcceptLanguageHeader ) - 1 );
break;
}
default:
/*
TODO
@@ -1137,7 +1144,6 @@ CheckOtherHTTPHeaders( IN http_message_t * Req,
case HDR_CONTENT_LOCATION://return 1;
case HDR_ACCEPT: //return 1;
case HDR_ACCEPT_CHARSET://return 1;
case HDR_ACCEPT_LANGUAGE://return 1;
case HDR_USER_AGENT: break;//return 1;
*/
@@ -1397,10 +1403,11 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "T" "GKD" "s" "tcS" "Xc" "sCc",
"R" "T" "GKLD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
finfo.content_type, // content type
RespInstr, // range info
RespInstr, // language info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1412,11 +1419,12 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "N" "T" "GD" "s" "tcS" "Xc" "sCc",
"R" "N" "T" "GLD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
RespInstr, // range info
RespInstr, // language info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1429,9 +1437,10 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"RK" "TD" "s" "tcS" "Xc" "sCc",
"RK" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
RespInstr, // language info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1445,10 +1454,11 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "N" "TD" "s" "tcS" "Xc" "sCc",
"R" "N" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
RespInstr, // language info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1460,9 +1470,10 @@ process_request( IN http_message_t * req,
// Transfer-Encoding: chunked
if (http_MakeMessage(
headers, resp_major, resp_minor,
"R" "TD" "s" "tcS" "b" "Xc" "sCc",
"R" "TLD" "s" "tcS" "b" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
RespInstr, // language info
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1696,6 +1707,8 @@ web_server_callback( IN http_parser_t * parser,
RespInstr.IsChunkActive = 0;
RespInstr.IsRangeActive = 0;
RespInstr.IsTrailers = 0;
memset( RespInstr.AcceptLanguageHeader, 0,
sizeof( RespInstr.AcceptLanguageHeader ) );
// init
membuffer_init( &headers );
membuffer_init( &filename );
@@ -1750,7 +1763,7 @@ web_server_callback( IN http_parser_t * parser,
http_MakeMessage(
&headers, 1, 1,
"RTDSXcCc",
"RTLSXcCc",
ret,
"text/html",
X_USER_AGENT );

View File

@@ -913,8 +913,10 @@ getServiceList( IXML_Node * node,
( *end ) = current;
return head;
} else
} else {
( *end ) = NULL;
return NULL;
}
}
@@ -960,7 +962,8 @@ getAllServiceList( IXML_Node * node,
if( head ) {
end->next =
getServiceList( currentDevice, &next_end, URLBase );
end = next_end;
if ( next_end )
end = next_end;
} else
head = getServiceList( currentDevice, &end, URLBase );

View File

@@ -1,33 +1,33 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
#ifndef INTERNAL_CONFIG_H
#define INTERNAL_CONFIG_H
@@ -36,114 +36,179 @@
#include "autoconfig.h"
/** @name Compile time configuration options
/*!
* \name Compile time configuration options
*
* The Linux SDK for UPnP Devices contains some compile-time parameters
* that effect the behavior of the SDK. All configuration options are
* located in {\tt src/inc/config.h}.
*
* @{
*/
//@{
/** @name THREAD_IDLE_TIME
/*!
* \name THREAD_IDLE_TIME
*
* The {\tt THREAD_IDLE_TIME} constant determines when a thread will be
* removed from the thread pool and returned to the operating system. When
* a thread in the thread pool has been idle for this number of milliseconds
* the thread will be released from the thread pool. The default value is
* 5000 milliseconds (5 seconds).
*
* @{
*/
//@{
#define THREAD_IDLE_TIME 5000
//@}
/* @} */
/** @name JOBS_PER_THREAD
* The {\tt JOBS_PER_THREAD} constant determines when a new thread will be
* allocated to the thread pool inside the SDK. The thread pool will
* try and maintain this jobs/thread ratio. When the jobs/thread ratio
* becomes greater than this, then a new thread (up to the max) will be
* allocated to the thread pool. The default ratio is 10 jobs/thread.
/*!
* \name JOBS_PER_THREAD
*
* The {\tt JOBS_PER_THREAD} constant determines when a new thread will be
* allocated to the thread pool inside the SDK. The thread pool will
* try and maintain this jobs/thread ratio. When the jobs/thread ratio
* becomes greater than this, then a new thread (up to the max) will be
* allocated to the thread pool. The default ratio is 10 jobs/thread.
*
* @{
*/
//@{
#define JOBS_PER_THREAD 10
//@}
/* @} */
/** @name MIN_THREADS
* The {\tt MIN_THREADS} constant defines the minimum number of threads the
* thread pool inside the SDK will create. The thread pool will
* always have this number of threads. These threads are used
* for both callbacks into applications built on top of the SDK and also
* for making connections to other control points and devices. This number
* includes persistent threads. The default value is two threads.
/*!
* \name MIN_THREADS
*
* The {\tt MIN_THREADS} constant defines the minimum number of threads the
* thread pool inside the SDK will create. The thread pool will
* always have this number of threads. These threads are used
* for both callbacks into applications built on top of the SDK and also
* for making connections to other control points and devices. This number
* includes persistent threads. The default value is two threads.
*
* @{
*/
//@{
#define MIN_THREADS 2
//@}
/* @} */
/** @name MAX_THREADS
* The {\tt MAX_THREADS} constant defines the maximum number of threads the
* thread pool inside the SDK will create. These threads are used
* for both callbacks into applications built on top of the library and also
* for making connections to other control points and devices. It is not
* recommended that this value be below 10, since the threads are
* necessary for correct operation. This value can be increased for greater
* performance in operation at the expense of greater memory overhead. The
* default value is 12.
/*!
* \name MAX_THREADS
*
* The {\tt MAX_THREADS} constant defines the maximum number of threads the
* thread pool inside the SDK will create. These threads are used
* for both callbacks into applications built on top of the library and also
* for making connections to other control points and devices. It is not
* recommended that this value be below 10, since the threads are
* necessary for correct operation. This value can be increased for greater
* performance in operation at the expense of greater memory overhead. The
* default value is 12.
*
* @{
*/
//@{
#define MAX_THREADS 12
//@}
/* @} */
/** @name MAX_JOBS_TOTAL
/*!
* \name THREAD_STACK_SIZE
*
* The {\tt THREAD_STACK_SIZE} constant defines the minimum stack size (in
* bytes) allocated for the stack of each thread the thread pool inside the
* SDK will create. These threads are used for both callbacks into
* applications built on top of the library and also for making connections
* to other control points and devices. This value will not be used if it
* is lower than ITHREAD_STACK_MIN or greater than a system-imposed limit.
* This value can be used to lower memory overhead in embedded systems.
* The default value is 0 (so it is not used by default).
*
* @{
*/
#define THREAD_STACK_SIZE 0
/* @} */
/*! \name MAX_JOBS_TOTAL
*
* The {\tt MAX_JOBS_TOTAL} constant determines the maximum number of jobs
* that can be queued. If this limit is reached further jobs will be thrown
* to avoid memory exhaustion. The default value 100.
* (Added by Axis.)
*
* @{
*/
//@{
#define MAX_JOBS_TOTAL 100
//@}
/* @} */
/** @name DEFAULT_SOAP_CONTENT_LENGTH
/*!
* \name DEFAULT_SOAP_CONTENT_LENGTH
*
* SOAP messages will read at most {\tt DEFAULT_SOAP_CONTENT_LENGTH} bytes.
* This prevents devices that have a misbehaving web server to send
* a large amount of data to the control point causing it to crash.
* This can be adjusted dynamically with {\tt UpnpSetMaxContentLength}.
*
* @{
*/
//@{
#define DEFAULT_SOAP_CONTENT_LENGTH 16000
//@}
/* @} */
/** @name NUM_SSDP_COPY
/*!
* \name NUM_SSDP_COPY
*
* This configuration parameter determines how many copies of each SSDP
* advertisement and search packets will be sent. By default it will send two
* copies of every packet.
*
* @{
*/
//@{
#define NUM_SSDP_COPY 2
//@}
/* @} */
/** @name SSDP_PAUSE
/*!
* \name SSDP_PAUSE
*
* This configuration parameter determines the pause between identical SSDP
* advertisement and search packets. The pause is measured in milliseconds
* and defaults to 100.
*
* @{
*/
//@{
#define SSDP_PAUSE 100
//@}
/* @} */
/** @name WEB_SERVER_BUF_SIZE
/*!
* \name WEB_SERVER_BUF_SIZE
*
* This configuration parameter sets the maximum buffer size for the
* webserver. The default value is 1MB.
* webserver. The default value is 1MB.
*
* @{
*/
//@{
#define WEB_SERVER_BUF_SIZE (1024*1024)
//@}
/* @} */
/** @name AUTO_RENEW_TIME
/*!
* \name WEB_SERVER_CONTENT_LANGUAGE
*
* This configuration parameter sets the value of the Content-Language
* header for the webserver. Thanks to this parameter, the use can advertize
* the language used by the device in the description (friendlyName) and
* presentation steps of UPnP. The default value is empty string so no
* Content-Language header is added.
*
* @{
*/
#define WEB_SERVER_CONTENT_LANGUAGE ""
/* @} */
/*!
* \name AUTO_RENEW_TIME
*
* The {\tt AUTO_RENEW_TIME} is the time, in seconds, before a subscription
* expires that the SDK automatically resubscribes. The default
* value is 10 seconds. Setting this value too low can result in the
@@ -151,89 +216,104 @@
* subscription to timeout. In order to avoid continually resubscribing
* the minimum subscription time is five seconds more than the auto renew
* time.
*
* @{
*/
//@{
#define AUTO_RENEW_TIME 10
//@}
/* @} */
/** @name CP_MINIMUM_SUBSCRIPTION_TIME
/*!
* \name CP_MINIMUM_SUBSCRIPTION_TIME
*
* The {\tt CP_MINIMUM_SUBSCRIPTION_TIME} is the minimum subscription time
* allowed for a control point using the SDK. Subscribing for less than
* this time automatically results in a subscription for this amount. The
* default value is 5 seconds more than the {\tt AUTO_RENEW_TIME}, or 15
* seconds.
*
* @{
*/
//@{
#define CP_MINIMUM_SUBSCRIPTION_TIME (AUTO_RENEW_TIME + 5)
//@}
/* @} */
/** @name MAX_SEARCH_TIME
/*!
* \name MAX_SEARCH_TIME
*
* The {\tt MAX_SEARCH_TIME} is the maximum time
* allowed for an SSDP search by a control point. Searching for greater than
* this time automatically results in a search for this amount. The default
* value is 80 seconds.
*
* @{
*/
//@{
#define MAX_SEARCH_TIME 80
//@}
/* @} */
/** @name MIN_SEARCH_TIME
/*!
* \name MIN_SEARCH_TIME
*
* The {\tt MIN_SEARCH_TIME} is the minimumm time
* allowed for an SSDP search by a control point. Searching for less than
* this time automatically results in a search for this amount. The default
* value is 2 seconds.
*/
//@{
#define MIN_SEARCH_TIME 2
//@}
/** @name AUTO_ADVERTISEMENT_TIME
* The {\tt AUTO_ADVERTISEMENT_TIME} is the time, in seconds, before an
* device advertisements expires before a renewed advertisement is sent.
* The default time is 30 seconds.
*/
//@{
#define AUTO_ADVERTISEMENT_TIME 30
//@}
/** @name SSDP_PACKET_DISTRIBUTE
* The {\tt SSDP_PACKET_DISTRIBUTE} enables the SSDP packets to be sent
* at an interval equal to half of the expiration time of SSDP packets
* minus the AUTO_ADVERTISEMENT_TIME. This is used to increase
* the probability of SSDP packets reaching to control points.
* It is recommended that this flag be turned on for embedded wireless
* devices.
*/
//@{
#define SSDP_PACKET_DISTRIBUTE 1
//@}
/** @name Module Exclusion
* Depending on the requirements, the user can selectively discard any of
* the major modules like SOAP, GENA, SSDP or the Internal web server. By
* default everything is included inside the SDK. By setting any of
* the values below to 0, that component will not be included in the final
* SDK.
* \begin{itemize}
* \item {\tt EXCLUDE_SOAP[0,1]}
* \item {\tt EXCLUDE_GENA[0,1]}
* \item {\tt EXCLUDE_SSDP[0,1]}
* \item {\tt EXCLUDE_DOM [0,1]}
* \item {\tt EXCLUDE_MINISERVER[0,1]}
* \item {\tt EXCLUDE_WEB_SERVER[0,1]}
* \item {\tt EXCLUDE_JNI[0,1]}
* \end{itemize}
*
* @{
*/
#define MIN_SEARCH_TIME 2
/* @} */
//@{
/*!
* \name AUTO_ADVERTISEMENT_TIME
*
* The {\tt AUTO_ADVERTISEMENT_TIME} is the time, in seconds, before an
* device advertisements expires before a renewed advertisement is sent.
* The default time is 30 seconds.
*
* @{
*/
#define AUTO_ADVERTISEMENT_TIME 30
/* @} */
/*!
* \name SSDP_PACKET_DISTRIBUTE
*
* The {\tt SSDP_PACKET_DISTRIBUTE} enables the SSDP packets to be sent
* at an interval equal to half of the expiration time of SSDP packets
* minus the AUTO_ADVERTISEMENT_TIME. This is used to increase
* the probability of SSDP packets reaching to control points.
* It is recommended that this flag be turned on for embedded wireless
* devices.
*
* @{
*/
#define SSDP_PACKET_DISTRIBUTE 1
/* @} */
/*!
* \name Module Exclusion
*
* Depending on the requirements, the user can selectively discard any of
* the major modules like SOAP, GENA, SSDP or the Internal web server. By
* default everything is included inside the SDK. By setting any of
* the values below to 0, that component will not be included in the final
* SDK.
* \begin{itemize}
* \item {\tt EXCLUDE_SOAP[0,1]}
* \item {\tt EXCLUDE_GENA[0,1]}
* \item {\tt EXCLUDE_SSDP[0,1]}
* \item {\tt EXCLUDE_DOM [0,1]}
* \item {\tt EXCLUDE_MINISERVER[0,1]}
* \item {\tt EXCLUDE_WEB_SERVER[0,1]}
* \item {\tt EXCLUDE_JNI[0,1]}
* \end{itemize}
*
* @{
*/
#define EXCLUDE_SSDP 0
#define EXCLUDE_SOAP 0
#define EXCLUDE_GENA 0
@@ -245,24 +325,28 @@
#else
# define EXCLUDE_JNI 1
#endif
//@}
/* @} */
/** @name DEBUG_TARGET
* The user has the option to redirect the library output debug messages
* to either the screen or to a log file. All the output messages with
* debug level 0 will go to {\tt upnp.err} and messages with debug level
* greater than zero will be redirected to {\tt upnp.out}.
/*!
* \name DEBUG_TARGET
*
* The user has the option to redirect the library output debug messages
* to either the screen or to a log file. All the output messages with
* debug level 0 will go to {\tt upnp.err} and messages with debug level
* greater than zero will be redirected to {\tt upnp.out}.
*
* @{
*/
//@{
#define DEBUG_TARGET 1
//@}
/* @} */
/** @name Other debugging features
The UPnP SDK contains other features to aid in debugging:
see <upnp/inc/upnpdebug.h>
/*!
* \name Other debugging features
*
* The UPnP SDK contains other features to aid in debugging:
* see <upnp/inc/upnpdebug.h>
*/
#define DEBUG_ALL 1
@@ -275,38 +359,46 @@
#define DEBUG_HTTP 0
#define DEBUG_API 0
//@} // Compile time configuration options
/*
* @} Compile time configuration options
*/
/***************************************************************************
* Do not change, Internal purpose only!!!
* Do not change, Internal purpose only!!!
***************************************************************************/
//@{
/*!
* @{
*/
/*
* Set additional defines based on requested configuration
*/
// configure --enable-client
/* configure --enable-client */
#if UPNP_HAVE_CLIENT
# define INCLUDE_CLIENT_APIS 1
#endif
// configure --enable-device
/* configure --enable-device */
#if UPNP_HAVE_DEVICE
# define INCLUDE_DEVICE_APIS 1
#endif
// configure --enable-webserver --enable-device
/* configure --enable-webserver --enable-device */
#if UPNP_HAVE_WEBSERVER
# define INTERNAL_WEB_SERVER 1
#endif
#undef EXCLUDE_WEB_SERVER
#undef EXCLUDE_MINISERVER
#undef EXCLUDE_WEB_SERVER
#undef EXCLUDE_MINISERVER
#ifdef INTERNAL_WEB_SERVER
# define EXCLUDE_WEB_SERVER 0
# define EXCLUDE_MINISERVER 0
@@ -315,16 +407,18 @@
# define EXCLUDE_MINISERVER 1
#endif
#if EXCLUDE_GENA == 1 && EXCLUDE_SOAP == 1 && EXCLUDE_WEB_SERVER == 1
# undef EXCLUDE_MINISERVER
# undef EXCLUDE_MINISERVER
# define EXCLUDE_MINISERVER 1
# if INTERNAL_WEB_SERVER
# error "conflicting settings: use configure --disable-webserver"
# endif
#endif
#if EXCLUDE_GENA == 0 || EXCLUDE_SOAP == 0 || EXCLUDE_WEB_SERVER == 0
# undef EXCLUDE_MINISERVER
# undef EXCLUDE_MINISERVER
# define EXCLUDE_MINISERVER 0
# if EXCLUDE_WEB_SERVER == 0 && !defined INTERNAL_WEB_SERVER
# error "conflicting settings : use configure --enable-webserver"
@@ -332,13 +426,9 @@
#endif
/*
* @}
*/
#ifdef INCLUDE_CLIENT_APIS
# define CLIENTONLY(x) x
#else
# define CLIENTONLY(x)
#endif
//@}
#endif
#endif /* INTERNAL_CONFIG_H */

View File

@@ -193,7 +193,8 @@ typedef struct // http_message_t
// private fields
membuffer msg; // entire raw message
char *urlbuf; // storage for url string
char *urlbuf; // storage for url string
size_t entity_offset;
} http_message_t;
typedef struct // http_parser_t

View File

@@ -6,6 +6,9 @@
#ifdef WIN32
#ifdef IPV6_
#define INET_IPV6
#endif
#include "unixutil.h"

View File

@@ -55,9 +55,11 @@ typedef struct MServerSockArray {
SOCKET miniServerPort4;
SOCKET miniServerPort6;
#ifdef INCLUDE_CLIENT_APIS
/* socket for sending search requests and receiving search replies */
CLIENTONLY(SOCKET ssdpReqSock4;)
CLIENTONLY(SOCKET ssdpReqSock6;)
SOCKET ssdpReqSock4;
SOCKET ssdpReqSock6;
#endif /* INCLUDE_CLIENT_APIS */
} MiniServerSockArray;

View File

@@ -1,133 +1,135 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
#ifndef SOAPLIB_H
#define SOAPLIB_H
// SOAP module API to be called in Upnp-Dk API
/* SOAP module API to be called in Upnp-Dk API */
/****************************************************************************
* Function : soap_device_callback
*
* Parameters :
* IN http_parser_t *parser : Parsed request received by the device
* IN http_message_t* request : HTTP request
* INOUT SOCKINFO *info : socket info
*
* Description : This is a callback called by minisever after receiving
* the request from the control point. This function will start
* processing the request. It calls handle_invoke_action to handle the
* SOAP action
*
* Return : void
*
* Note :
****************************************************************************/
* Function: soap_device_callback
*
* Parameters:
* IN http_parser_t *parser: Parsed request received by the device
* IN http_message_t* request: HTTP request
* INOUT SOCKINFO *info: socket info
*
* Description: This is a callback called by minisever after receiving
* the request from the control point. This function will start
* processing the request. It calls handle_invoke_action to handle the
* SOAP action
*
* Return: void
*
* Note:
****************************************************************************/
void soap_device_callback(
IN http_parser_t *parser,
IN http_message_t* request,
INOUT SOCKINFO *info );
IN http_parser_t *parser,
IN http_message_t* request,
INOUT SOCKINFO *info);
/****************************************************************************
* Function : SoapSendAction
*
* Parameters :
* IN char* action_url : device contrl URL
* IN char *service_type : device service type
* IN IXML_Document *action_node : SOAP action node
* OUT IXML_Document **response_node : SOAP response node
*
* Description : This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer
*
* Return : int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
int SoapSendAction(
IN char* action_url,
IN char *service_type,
IN IXML_Document *action_node,
OUT IXML_Document **response_node );
* Function: SoapSendAction
*
* Parameters:
* IN char* action_url: device contrl URL
* IN char *service_type: device service type
* IN IXML_Document *action_node: SOAP action node
* OUT IXML_Document **response_node: SOAP response node
*
* Description: This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer
*
* Return: int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note:
****************************************************************************/
int SoapSendAction(
IN char* action_url,
IN char *service_type,
IN IXML_Document *action_node,
OUT IXML_Document **response_node);
/****************************************************************************
* Function : SoapSendActionEx
*
* Parameters :
* IN char* action_url : device contrl URL
* IN char *service_type : device service type
IN IXML_Document *Header: Soap header
* IN IXML_Document *action_node : SOAP action node ( SOAP body)
* OUT IXML_Document **response_node : SOAP response node
*
* Description : This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer. This action is similar to the
* the SoapSendAction with only difference that it allows users to
* pass the SOAP header along the SOAP body ( soap action request)
*
* Return : int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
* Function: SoapSendActionEx
*
* Parameters:
* IN char* action_url: device contrl URL
* IN char *service_type: device service type
* IN IXML_Document *Header: Soap header
* IN IXML_Document *action_node: SOAP action node (SOAP body)
* OUT IXML_Document **response_node: SOAP response node
*
* Description: This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer. This action is similar to the
* the SoapSendAction with only difference that it allows users to
* pass the SOAP header along the SOAP body ( soap action request)
*
* Return: int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note:
****************************************************************************/
int SoapSendActionEx(
IN char * ActionURL,
IN char *ServiceType,
IN IXML_Document *Header,
IN IXML_Document *ActNode ,
OUT IXML_Document **RespNode) ;
IN char * ActionURL,
IN char *ServiceType,
IN IXML_Document *Header,
IN IXML_Document *ActNode,
OUT IXML_Document **RespNode);
/****************************************************************************
* Function : SoapGetServiceVarStatus
*
* Parameters :
* IN char * action_url : Address to send this variable
* query message.
* IN char *var_name : Name of the variable.
* OUT char **var_value : Output value.
*
* Description : This function creates a status variable query message
* send it to the specified URL. It also collect the response.
*
* Return : int
*
* Note :
****************************************************************************/
* Function: SoapGetServiceVarStatus
*
* Parameters:
* IN char * action_url: Address to send this variable query message.
* IN char *var_name: Name of the variable.
* OUT char **var_value: Output value.
*
* Description: This function creates a status variable query message
* send it to the specified URL. It also collect the response.
*
* Return: int
*
* Note:
****************************************************************************/
int SoapGetServiceVarStatus(
IN char * ActionURL,
IN DOMString VarName,
OUT DOMString *StVar) ;
IN char * ActionURL,
IN DOMString VarName,
OUT DOMString *StVar);
extern const char* ContentTypeHeader;
#endif //SOAPLIB_H
#endif /* SOAPLIB_H */

View File

@@ -47,15 +47,17 @@
#ifdef WIN32
#else
#else /* WIN32 */
#include <syslog.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#ifndef __APPLE__
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#endif /* __APPLE__ */
#include <sys/time.h>
#include <arpa/inet.h>
#endif
#endif /* WIN32 */
/* Enumeration to define all different types of ssdp searches */
@@ -183,9 +185,12 @@ typedef struct
/* globals */
CLIENTONLY(extern SOCKET gSsdpReqSocket4;);
CLIENTONLY(extern SOCKET gSsdpReqSocket6;);
#ifdef INCLUDE_CLIENT_APIS
extern SOCKET gSsdpReqSocket4;
#ifdef UPNP_ENABLE_IPV6
extern SOCKET gSsdpReqSocket6;
#endif /* UPNP_ENABLE_IPV6 */
#endif /* INCLUDE_CLIENT_APIS */
typedef int (*ParserFun)(char *, Event *);

View File

@@ -43,16 +43,17 @@ extern "C" {
struct SendInstruction
{
int IsVirtualFile;
int IsChunkActive;
int IsRangeActive;
int IsTrailers;
char RangeHeader[200];
off_t RangeOffset;
off_t ReadSendSize; // Read from local source and send on the network.
long RecvWriteSize; // Recv from the network and write into local file.
int IsVirtualFile;
int IsChunkActive;
int IsRangeActive;
int IsTrailers;
char RangeHeader[200];
char AcceptLanguageHeader[200];
off_t RangeOffset;
off_t ReadSendSize; // Read from local source and send on the network.
long RecvWriteSize; // Recv from the network and write into local file.
//Later few more member could be added depending on the requirement.
//Later few more member could be added depending on the requirement.
};
/************************************************************************

View File

@@ -1,135 +0,0 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef SOAPLIB_H
#define SOAPLIB_H
//SOAP module API to be called in Upnp-Dk API
/****************************************************************************
* Function : soap_device_callback
*
* Parameters :
* IN http_parser_t *parser : Parsed request received by the device
* IN http_message_t* request : HTTP request
* INOUT SOCKINFO *info : socket info
*
* Description : This is a callback called by minisever after receiving
* the request from the control point. This function will start
* processing the request. It calls handle_invoke_action to handle the
* SOAP action
*
* Return : void
*
* Note :
****************************************************************************/
void soap_device_callback(
IN http_parser_t *parser,
IN http_message_t* request,
INOUT SOCKINFO *info );
/****************************************************************************
* Function : SoapSendAction
*
* Parameters :
* IN char* action_url : device contrl URL
* IN char *service_type : device service type
* IN IXML_Document *action_node : SOAP action node
* OUT IXML_Document **response_node : SOAP response node
*
* Description : This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer
*
* Return : int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
int SoapSendAction(
IN char* action_url,
IN char *service_type,
IN IXML_Document *action_node,
OUT IXML_Document **response_node );
/****************************************************************************
* Function : SoapSendActionEx
*
* Parameters :
* IN char* action_url : device contrl URL
* IN char *service_type : device service type
IN IXML_Document *Header: Soap header
* IN IXML_Document *action_node : SOAP action node ( SOAP body)
* OUT IXML_Document **response_node : SOAP response node
*
* Description : This function is called by UPnP API to send the SOAP
* action request and waits till it gets the response from the device
* pass the response to the API layer. This action is similar to the
* the SoapSendAction with only difference that it allows users to
* pass the SOAP header along the SOAP body ( soap action request)
*
* Return : int
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
int SoapSendActionEx(
IN char * ActionURL,
IN char *ServiceType,
IN IXML_Document *Header,
IN IXML_Document *ActNode ,
OUT IXML_Document **RespNode) ;
/****************************************************************************
* Function : SoapGetServiceVarStatus
*
* Parameters :
* IN char * action_url : Address to send this variable
* query message.
* IN char *var_name : Name of the variable.
* OUT char **var_value : Output value.
*
* Description : This function creates a status variable query message
* send it to the specified URL. It also collect the response.
*
* Return : int
*
* Note :
****************************************************************************/
int SoapGetServiceVarStatus(
IN char * ActionURL,
IN DOMString VarName,
OUT DOMString *StVar) ;
// extern form the HTTP parser.
extern const char* ContentTypeHeader;
#endif //SOAPLIB_H

View File

@@ -510,7 +510,6 @@ int SearchByTarget(
IN void *Cookie)
{
char errorBuffer[ERROR_BUFFER_LEN];
int socklen = sizeof( struct sockaddr_storage );
int *id = NULL;
int ret = 0;
char ReqBufv4[BUFSIZE];
@@ -595,12 +594,14 @@ int SearchByTarget(
FD_SET(gSsdpReqSocket4, &wrSet);
max_fd = max(max_fd, gSsdpReqSocket4);
}
#ifdef UPNP_ENABLE_IPV6
if (gSsdpReqSocket6 != INVALID_SOCKET) {
setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char *)&gIF_INDEX, sizeof (gIF_INDEX));
FD_SET(gSsdpReqSocket6, &wrSet);
max_fd = max(max_fd, gSsdpReqSocket6);
}
#endif
ret = select(max_fd + 1, NULL, &wrSet, NULL, NULL);
if (ret == -1) {
@@ -610,11 +611,13 @@ int SearchByTarget(
errorBuffer);
shutdown(gSsdpReqSocket4, SD_BOTH);
UpnpCloseSocket(gSsdpReqSocket4);
#ifdef UPNP_ENABLE_IPV6
shutdown(gSsdpReqSocket6, SD_BOTH);
UpnpCloseSocket(gSsdpReqSocket6);
#endif
return UPNP_E_INTERNAL_ERROR;
}
#ifdef UPNP_ENABLE_IPV6
if (gSsdpReqSocket6 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket6, &wrSet)) {
int NumCopy = 0;
@@ -622,28 +625,38 @@ int SearchByTarget(
while (NumCopy < NUM_SSDP_COPY) {
sendto(gSsdpReqSocket6,
ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
(struct sockaddr *)&__ss_v6, socklen);
(struct sockaddr *)&__ss_v6,
sizeof(struct sockaddr_in));
NumCopy++;
imillisleep(SSDP_PAUSE);
}
NumCopy = 0;
inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
while (NumCopy < NUM_SSDP_COPY) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND M-SEARCH >>>\n%s\n",
ReqBufv6);
sendto(gSsdpReqSocket6,
ReqBufv6, strlen(ReqBufv6), 0,
(struct sockaddr *)&__ss_v6, socklen);
ReqBufv6, strlen(ReqBufv6), 0,
(struct sockaddr *)&__ss_v6,
sizeof(struct sockaddr_in6));
NumCopy++;
imillisleep(SSDP_PAUSE);
}
}
#endif //IPv6
if (gSsdpReqSocket4 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket4, &wrSet)) {
int NumCopy = 0;
while (NumCopy < NUM_SSDP_COPY) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND M-SEARCH >>>\n%s\n",
ReqBufv4);
sendto(gSsdpReqSocket4,
ReqBufv4, strlen(ReqBufv4), 0,
(struct sockaddr *)&__ss_v4, socklen);
(struct sockaddr *)&__ss_v4,
sizeof(struct sockaddr_in));
NumCopy++;
imillisleep(SSDP_PAUSE);
}

View File

@@ -1,30 +1,30 @@
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
@@ -229,6 +229,7 @@ NewRequestHandler( IN struct sockaddr *DestAddr,
int ttl = 4; // a/c to UPNP Spec
int hops = 1;
char buf_ntop[64];
int ret = UPNP_E_SUCCESS;
ReplySock = socket( DestAddr->sa_family, SOCK_DGRAM, 0 );
if ( ReplySock == -1 ) {
@@ -247,6 +248,7 @@ NewRequestHandler( IN struct sockaddr *DestAddr,
(char *)&replyAddr, sizeof (replyAddr) );
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&ttl, sizeof (int) );
socklen = sizeof(struct sockaddr_in);
} else if( DestAddr->sa_family == AF_INET6 ) {
inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr,
buf_ntop, sizeof(buf_ntop));
@@ -257,6 +259,8 @@ NewRequestHandler( IN struct sockaddr *DestAddr,
} else {
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Invalid destination address specified." );
ret = UPNP_E_NETWORK_ERROR;
goto end_NewRequestHandler;
}
for( Index = 0; Index < NumPacket; Index++ ) {
@@ -280,15 +284,27 @@ NewRequestHandler( IN struct sockaddr *DestAddr,
rc = sendto( ReplySock, *( RqPacket + Index ),
strlen( *( RqPacket + Index ) ),
0, DestAddr, socklen );
if (rc == -1) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP_LIB: New Request Handler:"
"Error in socket(): %s\n", errorBuffer );
ret = UPNP_E_SOCKET_WRITE;
goto end_NewRequestHandler;
}
imillisleep( SSDP_PAUSE );
++NumCopy;
}
}
end_NewRequestHandler:
shutdown( ReplySock, SD_BOTH );
UpnpCloseSocket( ReplySock );
return UPNP_E_SUCCESS;
return ret;
}
/**
@@ -405,6 +421,7 @@ void CreateServicePacket(
}
} else if (msg_type == MSGTYPE_ADVERTISEMENT ||
msg_type == MSGTYPE_SHUTDOWN) {
char *host = NULL;
if (msg_type == MSGTYPE_ADVERTISEMENT) {
nts = "ssdp:alive";
} else {
@@ -413,7 +430,6 @@ void CreateServicePacket(
}
/* NOTE: The CACHE-CONTROL and LOCATION headers are not present in
* a shutdown msg, but are present here for MS WinMe interop. */
char *host = NULL;
if (AddressFamily == AF_INET) {
host = SSDP_IP;
} else {

View File

@@ -50,26 +50,36 @@
#define MAX_TIME_TOREAD 45
CLIENTONLY( SOCKET gSsdpReqSocket4 = INVALID_SOCKET; )
CLIENTONLY( SOCKET gSsdpReqSocket6 = INVALID_SOCKET; )
#ifdef INCLUDE_CLIENT_APIS
SOCKET gSsdpReqSocket4 = INVALID_SOCKET;
#ifdef UPNP_ENABLE_IPV6
SOCKET gSsdpReqSocket6 = INVALID_SOCKET;
#endif /* UPNP_ENABLE_IPV6 */
#endif /* INCLUDE_CLIENT_APIS */
void RequestHandler();
int create_ssdp_sock_v4( SOCKET* ssdpSock );
#ifdef UPNP_ENABLE_IPV6
int create_ssdp_sock_v6( SOCKET* ssdpSock );
int create_ssdp_sock_v6_ula_gua( SOCKET* ssdpSock );
#endif
#if INCLUDE_CLIENT_APIS
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock );
#ifdef UPNP_ENABLE_IPV6
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock );
#endif
#endif
Event ErrotEvt;
enum Listener { Idle, Stopping, Running };
struct SSDPSockArray {
// socket for incoming advertisments and search requests
/* socket for incoming advertisments and search requests */
SOCKET ssdpSock;
// socket for sending search requests and receiving search replies
CLIENTONLY( int ssdpReqSock; )
#ifdef INCLUDE_CLIENT_APIS
/* socket for sending search requests and receiving search replies */
int ssdpReqSock;
#endif /* INCLUDE_CLIENT_APIS */
};
#ifdef INCLUDE_DEVICE_APIS
@@ -258,7 +268,7 @@ int AdvertiseAndReply(
}
}
case SSDP_DEVICETYPE: {
if (!strncasecmp(DeviceType, devType, strlen(DeviceType))) {
if (!strncasecmp(DeviceType, devType, strlen(DeviceType)-2)) {
if (atoi(&DeviceType[strlen(DeviceType)-1]) <= atoi(&devType[strlen(devType)-1])) {
/* the requested version is lower than the device version
* must reply with the lower version number */
@@ -301,6 +311,7 @@ int AdvertiseAndReply(
}
ixmlNodeList_free(nodeList);
if (!tmpNode) {
nodeList = NULL;
continue;
}
nodeList = ixmlElement_getElementsByTagName(
@@ -732,26 +743,26 @@ start_event_handler( void *Data )
* Returns: void
*
***************************************************************************/
static void
ssdp_event_handler_thread( void *the_data )
static void ssdp_event_handler_thread(void * the_data)
{
ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;
http_message_t *hmsg = &data->parser.msg;
ssdp_thread_data *data = (ssdp_thread_data *)the_data;
http_message_t *hmsg = &data->parser.msg;
if( start_event_handler( the_data ) != 0 ) {
return;
}
// send msg to device or ctrlpt
if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg,
(struct sockaddr*)&data->dest_addr, FALSE, NULL );)
} else {
ssdp_handle_device_request( hmsg, (struct sockaddr*)&data->dest_addr );
}
if (start_event_handler(the_data) != 0) {
return;
}
/* send msg to device or ctrlpt */
if (hmsg->method == HTTPMETHOD_NOTIFY ||
hmsg->request_method == HTTPMETHOD_MSEARCH) {
#ifdef INCLUDE_CLIENT_APIS
ssdp_handle_ctrlpt_msg(hmsg, (struct sockaddr*)&data->dest_addr, FALSE, NULL);
#endif /* INCLUDE_CLIENT_APIS */
} else {
ssdp_handle_device_request(hmsg, (struct sockaddr*)&data->dest_addr);
}
// free data
free_ssdp_event_handler_data( data );
/* free data */
free_ssdp_event_handler_data(data);
}
/************************************************************************
@@ -791,11 +802,20 @@ readFromSSDPSocket( SOCKET socket )
//initialize parser
#ifdef INCLUDE_CLIENT_APIS
#ifdef UPNP_ENABLE_IPV6
if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) {
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
} else {
parser_request_init( &data->parser );
}
#else
if( socket == gSsdpReqSocket4 ) {
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
} else {
parser_request_init( &data->parser );
}
#endif
#else
parser_request_init( &data->parser );
#endif
@@ -820,8 +840,10 @@ readFromSSDPSocket( SOCKET socket )
if( __ss.ss_family == AF_INET )
inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) );
#ifdef UPNP_ENABLE_IPV6
else if( __ss.ss_family == AF_INET6 )
inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) );
#endif
else
strncpy( ntop_buf, "<Invalid address family>", sizeof(ntop_buf) );
@@ -876,6 +898,9 @@ int get_ssdp_sockets(MiniServerSockArray *out)
{
int retVal;
out->ssdpReqSock4 = INVALID_SOCKET;
out->ssdpReqSock6 = INVALID_SOCKET;
#if INCLUDE_CLIENT_APIS
/* Create the IPv4 socket for SSDP REQUESTS */
if(strlen(gIF_IPV4) > 0) {
@@ -890,6 +915,7 @@ int get_ssdp_sockets(MiniServerSockArray *out)
}
/* Create the IPv6 socket for SSDP REQUESTS */
#ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) {
retVal = create_ssdp_sock_reqv6(&out->ssdpReqSock6);
if (retVal != UPNP_E_SUCCESS) {
@@ -902,6 +928,9 @@ int get_ssdp_sockets(MiniServerSockArray *out)
} else {
out->ssdpReqSock6 = INVALID_SOCKET;
}
#endif //IPv6
#endif /* INCLUDE_CLIENT_APIS */
/* Create the IPv4 socket for SSDP */
@@ -921,6 +950,7 @@ int get_ssdp_sockets(MiniServerSockArray *out)
}
/* Create the IPv6 socket for SSDP */
#ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) {
retVal = create_ssdp_sock_v6(&out->ssdpSock6);
if (retVal != UPNP_E_SUCCESS) {
@@ -956,6 +986,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
} else {
out->ssdpSock6UlaGua = INVALID_SOCKET;
}
#endif //IPv6
return UPNP_E_SUCCESS;
}
@@ -1011,6 +1043,7 @@ int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock )
* Returns: void
*
***************************************************************************/
#ifdef UPNP_ENABLE_IPV6
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock )
{
char errorBuffer[ERROR_BUFFER_LEN];
@@ -1035,6 +1068,8 @@ int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock )
return UPNP_E_SUCCESS;
}
#endif // IPv6
#endif /* INCLUDE_CLIENT_APIS */
@@ -1178,6 +1213,7 @@ int create_ssdp_sock_v4( SOCKET* ssdpSock )
* Returns: void
*
***************************************************************************/
#ifdef UPNP_ENABLE_IPV6
int create_ssdp_sock_v6( SOCKET* ssdpSock )
{
char errorBuffer[ERROR_BUFFER_LEN];
@@ -1274,7 +1310,7 @@ int create_ssdp_sock_v6( SOCKET* ssdpSock )
return UPNP_E_SUCCESS;
}
#endif // IPv6
/************************************************************************
* Function : create_ssdp_sock_v6_ula_gua
@@ -1288,6 +1324,7 @@ int create_ssdp_sock_v6( SOCKET* ssdpSock )
* Returns: void
*
***************************************************************************/
#ifdef UPNP_ENABLE_IPV6
int create_ssdp_sock_v6_ula_gua(SOCKET *ssdpSock)
{
char errorBuffer[ERROR_BUFFER_LEN];
@@ -1385,7 +1422,7 @@ int create_ssdp_sock_v6_ula_gua(SOCKET *ssdpSock)
return UPNP_E_SUCCESS;
}
#endif //IPv6
#endif /* EXCLUDE_SSDP */