Compare commits

..

69 Commits

Author SHA1 Message Date
Marcelo Roberto Jimenez
593b8d0a2b Fixes in configure.ac for release. 2010-10-20 11:11:45 -02:00
Marcelo Roberto Jimenez
890c1b6ef8 Disable debug for release. 2010-10-20 10:36:11 -02:00
Marcelo Roberto Jimenez
c127a3a87e Add docs/doxygen to .gitignore. 2010-10-20 10:35:15 -02:00
Marcelo Roberto Jimenez
bd5758186c White spaces. 2010-10-20 10:29:45 -02:00
Marcelo Roberto Jimenez
cc472bc2cd Doxygen and indentation for sock. 2010-10-20 09:05:42 -02:00
Marcelo Roberto Jimenez
6128296e5f Doxygen and indentation for miniserver. 2010-10-20 08:56:06 -02:00
Marcelo Roberto Jimenez
d84c6a7e9f Indent plus Doxygen in webserver. 2010-10-20 01:28:37 -02:00
Marcelo Roberto Jimenez
113ebd1f91 Slightly better implementation for ToUpperCase(). 2010-10-20 00:36:47 -02:00
Marcelo Roberto Jimenez
bf1450bf81 Fix a long date memory leak in webserver.c:StrStr(). 2010-10-20 00:29:08 -02:00
Marcelo Roberto Jimenez
56b9c75056 Changelog fix. 2010-10-19 16:11:39 -02:00
Marcelo Roberto Jimenez
2bdc9e075e Bug fix in select of miniserver.c
Fix a bug in miniserver.c, in which maxMiniSock was wrongly declared as
unsigned int and as a result it was beeng set to ((unsigned int)(-1)).
As a result, after beeing incremented, it became zero, and this value
was beeing used in the select() call.

Thanks to Fabrice Fontaine for helping and testing with this issue.
2010-10-19 15:49:36 -02:00
Marcelo Roberto Jimenez
923eee2393 Don't ask, UTF-8 mess? 2010-10-15 12:54:00 -03:00
Marcelo Roberto Jimenez
f74746ff3f Fix for 100% CPU issue in select() in miniserv.c. I have also removed
the sleep() call, it was just a workaround.

SF Bug Tracker [ 3086852 ] 99% CPU loop in miniserver.c on a non ipv6
system.

Submitted by: Jin ( jin_eld ) - 2010-10-13 19:29:13 UTC

I cross compiled libupnp 1.6.7 for ARM9 using the --disable-ipv6
option, my system is an ipv4 only setup.

I do not know why this problem only appears when running the app in the
background (for instance using nohup &), but then it starts using 99%
CPU.

I traced the problem down to the select() call in miniserver.c in the
RunMiniServer() function. Select returns code 1, but errno is set to
"Socket operation on non-socket", I also see this when running my app
under strace.

I set all ...Sock6 variables to INVALID_SOCKET to make sure that they
do not get added to the FD_SET and the problem is gone.
2010-10-15 12:41:36 -03:00
Marcelo Roberto Jimenez
8401a59ed5 New function, sock_close(). 2010-10-15 12:25:35 -03:00
Marcelo Roberto Jimenez
5b40cfa272 Misplaced declaration of UpnpCloseSocket. 2010-10-15 12:17:15 -03:00
Marcelo Roberto Jimenez
fcda28ba75 Remove of unused file. 2010-10-15 11:53:25 -03:00
Marcelo Roberto Jimenez
7cd434225f White spaces and comments. 2010-10-04 17:05:43 -03:00
Marcelo Roberto Jimenez
78e5ba89fa Merge of similar files. 2010-10-04 15:48:45 -03:00
Marcelo Roberto Jimenez
ebb8f209b0 Merge of similar files. 2010-10-04 15:36:11 -03:00
Marcelo Roberto Jimenez
73afd667e1 Fix for bug introduced in the last commit. 2010-10-04 13:24:38 -03:00
Marcelo Roberto Jimenez
cc294a6cf1 Merge similar code. 2010-10-04 13:03:20 -03:00
Marcelo Roberto Jimenez
458a9416c6 Merge of work from 1.8.x. 2010-10-04 12:04:38 -03:00
Marcelo Roberto Jimenez
b9eeb89250 Bumped Doxyfile version. 2010-10-04 11:44:06 -03:00
Marcelo Roberto Jimenez
a6e68b481d Updated THANKS. 2010-10-04 11:33:37 -03:00
Marcelo Roberto Jimenez
a19a896e88 Updated TODO list. 2010-10-04 11:28:37 -03:00
Marcelo Roberto Jimenez
cdee5b7cde UTF-8. 2010-10-04 11:11:33 -03:00
Marcelo Roberto Jimenez
dec78c8ef1 Echo the copy on configure output. 2010-10-04 11:01:28 -03:00
Marcelo Roberto Jimenez
fb62a5d42a Update files for windows compilation. 2010-10-04 10:51:30 -03:00
Marcelo Roberto Jimenez
a9b5081a08 Update build/inc/autoconfig.h and build/inc/upnpconfig.h at configure
time.
2010-10-04 10:47:39 -03:00
Marcelo Roberto Jimenez
3886a697b5 Remove build/inc/config.h. The right file is upnp/src/inc/config.h. 2010-10-04 10:42:32 -03:00
Marcelo Roberto Jimenez
3dab2bd00a Homekeeping for the next release. 2010-10-04 09:58:15 -03:00
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
75 changed files with 5488 additions and 5895 deletions

105
.gitignore vendored Normal file
View File

@@ -0,0 +1,105 @@
#
# 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
docs/doxygen

232
ChangeLog
View File

@@ -1,7 +1,239 @@
*******************************************************************************
Version 1.6.8
*******************************************************************************
2010-10-20 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Fix a long date memory leak in webserver.c:StrStr().
2010-10-19 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Bug fix in select of miniserver.c
Fix a bug in miniserver.c, in which maxMiniSock was wrongly declared as
unsigned int and as a result it was beeng set to ((unsigned int)(-1)).
As a result, after beeing incremented, it became zero, and this value
was beeing used in the select() call.
Thanks to Fabrice Fontaine for helping and testing with this issue.
2010-10-15 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Fix for 100% CPU issue in select() in miniserv.c. I have also removed
the sleep() call, it was just a workaround.
SF Bug Tracker [ 3086852 ] 99% CPU loop in miniserver.c on a non ipv6
system.
Submitted by: Jin ( jin_eld ) - 2010-10-13 19:29:13 UTC
I cross compiled libupnp 1.6.7 for ARM9 using the --disable-ipv6
option, my system is an ipv4 only setup.
I do not know why this problem only appears when running the app in the
background (for instance using nohup &), but then it starts using 99%
CPU.
I traced the problem down to the select() call in miniserver.c in the
RunMiniServer() function. Select returns code 1, but errno is set to
"Socket operation on non-socket", I also see this when running my app
under strace.
I set all ...Sock6 variables to INVALID_SOCKET to make sure that they
do not get added to the FD_SET and the problem is gone.
******************************************************************************* *******************************************************************************
Version 1.6.7 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> 2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* The last part of Ronan Menard's patch. * The last part of Ronan Menard's patch.

View File

@@ -31,7 +31,7 @@ PROJECT_NAME = libUPnP
# This could be handy for archiving the generated documentation or # This could be handy for archiving the generated documentation or
# if some version control system is used. # if some version control system is used.
PROJECT_NUMBER = 1.6.7 PROJECT_NUMBER = 1.6.8
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put. # base path where the generated documentation will be put.

View File

@@ -26,7 +26,6 @@ EXTRA_DIST = \
build/libupnp.dsp \ build/libupnp.dsp \
build/libupnp.dsw \ build/libupnp.dsw \
build/inc/autoconfig.h \ build/inc/autoconfig.h \
build/inc/config.h \
build/inc/upnpconfig.h \ build/inc/upnpconfig.h \
build/msvc/inttypes.h \ build/msvc/inttypes.h \
build/msvc/stdint.h \ build/msvc/stdint.h \

2
README
View File

@@ -1,7 +1,7 @@
Portable SDK for UPnP* Devices (libupnp) Portable SDK for UPnP* Devices (libupnp)
Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved. 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> Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds@gmx.de>
See LICENSE for details. See LICENSE for details.

2
THANKS
View File

@@ -13,11 +13,13 @@ exempt of errors.
- Arno Willig - Arno Willig
- Bob Ciora - Bob Ciora
- Carlo Parata - Carlo Parata
- Chandra (inactiveneurons)
- Chaos - Chaos
- Charles Nepveu (cnepveu) - Charles Nepveu (cnepveu)
- Chris Pickel - Chris Pickel
- Chuck Thomason (cyt4) - Chuck Thomason (cyt4)
- Craig Nelson - Craig Nelson
- David Blanchet
- David Maass - David Maass
- Emil Ljungdahl - Emil Ljungdahl
- Erik Johansson - Erik Johansson

23
TODO
View File

@@ -2,28 +2,5 @@
To Be Done To Be Done
========== ==========
- add FreeBSD patches
( http://sf.net/tracker/index.php?func=detail&aid=1332618&group_id=7189&atid=307189 ?)
- non-regression testing - non-regression testing
- replace doc++ by Doxygen for documentation generation
- incorporate public patches and fix reported bugs :
http://sourceforge.net/tracker/?group_id=7189&atid=107189 and
http://sourceforge.net/tracker/?group_id=7189&atid=307189
- RPM packaging (a preliminary one here :
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=176617 )
- make API clean for large files and 64 bits
To Be Decided
=============
- IPV6 support ?

View File

@@ -67,9 +67,6 @@
/* Define to 1 if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/timeb.h> header file. */
#define HAVE_SYS_TIMEB_H 1
/* Define to 1 if you have the <sys/time.h> header file. */ /* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIME_H 1
@@ -82,6 +79,13 @@
/* Define to 1 if you have the `vprintf' function. */ /* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1 #define HAVE_VPRINTF 1
/* Define to 1 if you have the <ws2tcpip.h> header file. */
/* #undef HAVE_WS2TCPIP_H */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 to prevent compilation of assert() */ /* Define to 1 to prevent compilation of assert() */
#define NDEBUG 1 #define NDEBUG 1
@@ -101,13 +105,13 @@
#define PACKAGE_NAME "libupnp" #define PACKAGE_NAME "libupnp"
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#define PACKAGE_STRING "libupnp 1.4.7" #define PACKAGE_STRING "libupnp 1.6.8"
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libupnp" #define PACKAGE_TARNAME "libupnp"
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "1.4.7" #define PACKAGE_VERSION "1.6.8"
/* Define to necessary symbol if this constant uses a non-standard name on /* Define to necessary symbol if this constant uses a non-standard name on
your system. */ your system. */
@@ -116,6 +120,12 @@
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* see upnpconfig.h */
/* #undef UPNP_ENABLE_IPV6 */
/* see upnpconfig.h */
#define UPNP_ENABLE_NOTIFICATION_REORDERING 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_HAVE_CLIENT 1 #define UPNP_HAVE_CLIENT 1
@@ -131,20 +141,23 @@
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_HAVE_WEBSERVER 1 #define UPNP_HAVE_WEBSERVER 1
/* Do not use pthread_rwlock_t */
#define UPNP_USE_RWLOCK 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_MAJOR 1 #define UPNP_VERSION_MAJOR 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_MINOR 4 #define UPNP_VERSION_MINOR 6
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_PATCH 7 #define UPNP_VERSION_PATCH 8
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_STRING "1.4.7" #define UPNP_VERSION_STRING "1.6.8"
/* Version number of package */ /* Version number of package */
#define VERSION "1.4.7" #define VERSION "1.6.8"
/* File Offset size */ /* File Offset size */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
@@ -153,7 +166,7 @@
/* #undef _LARGEFILE_SOURCE */ /* #undef _LARGEFILE_SOURCE */
/* Large files support */ /* Large files support */
#define _LARGE_FILE_SOURCE #define _LARGE_FILE_SOURCE /**/
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */ /* #undef const */
@@ -164,5 +177,5 @@
/* Define to `unsigned int' if <sys/types.h> does not define. */ /* Define to `unsigned int' if <sys/types.h> does not define. */
/* #undef size_t */ /* #undef size_t */
/* Substitute for socklen_t */ /* Type for storing the length of struct sockaddr */
/* #undef socklen_t */ /* #undef socklen_t */

View File

@@ -1,343 +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 INTERNAL_CONFIG_H
#define INTERNAL_CONFIG_H
#include "autoconfig.h"
/** @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
* 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.
*/
//@{
#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.
*/
//@{
#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.
*/
//@{
#define MAX_THREADS 12
//@}
/** @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
* 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
* 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
* 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
* This configuration parameter sets the maximum buffer size for the
* webserver. The default value is 1MB.
*/
//@{
#define WEB_SERVER_BUF_SIZE (1024*1024)
//@}
/** @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
* subscription renewal not making it to the device in time, causing the
* 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
* 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
* 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
* 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 EXCLUDE_SSDP 0
#define EXCLUDE_SOAP 0
#define EXCLUDE_GENA 0
#define EXCLUDE_DOM 0
#define EXCLUDE_MINISERVER 0
#define EXCLUDE_WEB_SERVER 0
#ifdef USE_JNI
# define EXCLUDE_JNI 0
#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}.
*/
//@{
#define DEBUG_TARGET 1
//@}
/** @name Other debugging features
The UPnP SDK contains other features to aid in debugging:
see <upnp/inc/upnpdebug.h>
*/
#define DEBUG_ALL 1
#define DEBUG_SSDP 0
#define DEBUG_SOAP 0
#define DEBUG_GENA 0
#define DEBUG_TPOOL 0
#define DEBUG_MSERV 0
#define DEBUG_DOM 0
#define DEBUG_HTTP 0
#define DEBUG_API 0
//@} // Compile time configuration options
/***************************************************************************
* Do not change, Internal purpose only!!!
***************************************************************************/
//@{
/*
* Set additional defines based on requested configuration
*/
// configure --enable-client
#if UPNP_HAVE_CLIENT
# define INCLUDE_CLIENT_APIS 1
#endif
// configure --enable-device
#if UPNP_HAVE_DEVICE
# define INCLUDE_DEVICE_APIS 1
#endif
// configure --enable-webserver --enable-device
#if UPNP_HAVE_WEBSERVER
# define INTERNAL_WEB_SERVER 1
#endif
#undef EXCLUDE_WEB_SERVER
#undef EXCLUDE_MINISERVER
#ifdef INTERNAL_WEB_SERVER
# define EXCLUDE_WEB_SERVER 0
# define EXCLUDE_MINISERVER 0
#else
# define EXCLUDE_WEB_SERVER 1
# define EXCLUDE_MINISERVER 1
#endif
#if EXCLUDE_GENA == 1 && EXCLUDE_SOAP == 1 && EXCLUDE_WEB_SERVER == 1
# 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
# define EXCLUDE_MINISERVER 0
# if EXCLUDE_WEB_SERVER == 0 && !defined INTERNAL_WEB_SERVER
# error "conflicting settings : use configure --enable-webserver"
# endif
#endif
#ifdef INCLUDE_CLIENT_APIS
# define CLIENTONLY(x) x
#else
# define CLIENTONLY(x)
#endif
//@}
#endif

View File

@@ -1,35 +1,35 @@
/* upnp/inc/upnpconfig.h. Generated from upnpconfig.h.in by configure. */ /* upnp/inc/upnpconfig.h. Generated from upnpconfig.h.in by configure. */
// -*- C -*- /* -*- C -*- */
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> * Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef UPNP_CONFIG_H #ifndef UPNP_CONFIG_H
#define UPNP_CONFIG_H #define UPNP_CONFIG_H
@@ -40,20 +40,20 @@
***************************************************************************/ ***************************************************************************/
/** The library version (string) e.g. "1.3.0" */ /** The library version (string) e.g. "1.3.0" */
#define UPNP_VERSION_STRING "1.4.7" #define UPNP_VERSION_STRING "1.6.8"
/** Major version of the library */ /** Major version of the library */
#define UPNP_VERSION_MAJOR 1 #define UPNP_VERSION_MAJOR 1
/** Minor version of the library */ /** Minor version of the library */
#define UPNP_VERSION_MINOR 4 #define UPNP_VERSION_MINOR 6
/** Patch version of the library */ /** Patch version of the library */
#define UPNP_VERSION_PATCH 7 #define UPNP_VERSION_PATCH 8
/** The library version (numeric) e.g. 10300 means version 1.3.0 */ /** The library version (numeric) e.g. 10300 means version 1.3.0 */
#define UPNP_VERSION \ #define UPNP_VERSION \
((UPNP_VERSION_MAJOR*100 + UPNP_VERSION_MINOR)*100 + UPNP_VERSION_PATCH) ((UPNP_VERSION_MAJOR * 100 + UPNP_VERSION_MINOR) * 100 + UPNP_VERSION_PATCH)
@@ -91,7 +91,9 @@
* (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */ * (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
#define UPNP_HAVE_TOOLS 1 #define UPNP_HAVE_TOOLS 1
/** 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 #endif /* UPNP_CONFIG_H */

View File

@@ -5,17 +5,17 @@
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 # TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=libupnp - Win32 Debug CFG=libupnp - Win32 Debug
!MESSAGE Dies ist kein g<EFBFBD>ltiges Makefile. Zum Erstellen dieses Projekts mit NMAKE !MESSAGE Dies ist kein gültiges Makefile. Zum Erstellen dieses Projekts mit NMAKE
!MESSAGE verwenden Sie den Befehl "Makefile exportieren" und f<EFBFBD>hren Sie den Befehl !MESSAGE verwenden Sie den Befehl "Makefile exportieren" und führen Sie den Befehl
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "libupnp.mak". !MESSAGE NMAKE /f "libupnp.mak".
!MESSAGE !MESSAGE
!MESSAGE Sie k<EFBFBD>nnen beim Ausf<EFBFBD>hren von NMAKE eine Konfiguration angeben !MESSAGE Sie können beim Ausf?hren von NMAKE eine Konfiguration angeben
!MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel: !MESSAGE durch Definieren des Makros CFG in der Befehlszeile. Zum Beispiel:
!MESSAGE !MESSAGE
!MESSAGE NMAKE /f "libupnp.mak" CFG="libupnp - Win32 Debug" !MESSAGE NMAKE /f "libupnp.mak" CFG="libupnp - Win32 Debug"
!MESSAGE !MESSAGE
!MESSAGE F<EFBFBD>r die Konfiguration stehen zur Auswahl: !MESSAGE Für die Konfiguration stehen zur Auswahl:
!MESSAGE !MESSAGE
!MESSAGE "libupnp - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library") !MESSAGE "libupnp - Win32 Release" (basierend auf "Win32 (x86) Dynamic-Link Library")
!MESSAGE "libupnp - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library") !MESSAGE "libupnp - Win32 Debug" (basierend auf "Win32 (x86) Dynamic-Link Library")
@@ -389,10 +389,6 @@ SOURCE=..\upnp\src\inc\upnpapi.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\upnp\src\inc\upnpclosesocket.h
# End Source File
# Begin Source File
SOURCE=..\upnp\src\inc\uri.h SOURCE=..\upnp\src\inc\uri.h
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -603,10 +603,6 @@
RelativePath="..\..\upnp\src\inc\upnpapi.h" RelativePath="..\..\upnp\src\inc\upnpapi.h"
> >
</File> </File>
<File
RelativePath="..\..\upnp\src\inc\upnpclosesocket.h"
>
</File>
<File <File
RelativePath="..\..\upnp\inc\upnpdebug.h" RelativePath="..\..\upnp\inc\upnpdebug.h"
> >

View File

@@ -599,10 +599,6 @@
RelativePath="..\..\upnp\src\inc\upnpapi.h" RelativePath="..\..\upnp\src\inc\upnpapi.h"
> >
</File> </File>
<File
RelativePath="..\..\upnp\src\inc\upnpclosesocket.h"
>
</File>
<File <File
RelativePath="..\..\upnp\inc\upnpdebug.h" RelativePath="..\..\upnp\inc\upnpdebug.h"
> >

View File

@@ -9,7 +9,7 @@
AC_PREREQ(2.60) AC_PREREQ(2.60)
AC_INIT([libupnp], [1.6.7], [mroberto@users.sourceforge.net]) AC_INIT([libupnp], [1.6.8], [mroberto@users.sourceforge.net])
dnl ############################################################################ dnl ############################################################################
dnl # *Independently* of the above libupnp package version, the libtool version dnl # *Independently* of the above libupnp package version, the libtool version
dnl # of the 3 libraries need to be updated whenever there is a change released: dnl # of the 3 libraries need to be updated whenever there is a change released:
@@ -147,22 +147,42 @@ dnl ############################################################################
dnl # Release 1.6.7: dnl # Release 1.6.7:
dnl # "current:revision:age" dnl # "current:revision:age"
dnl # dnl #
dnl # - Code has changed in upnp
dnl # revision: 5 -> 6
dnl # - Code has changed in threadutil dnl # - Code has changed in threadutil
dnl # revision: 3 -> 4 dnl # revision: 3 -> 4
dnl # - Code has changed in upnp
dnl # revision: 5 -> 6
dnl # - Interfaces have been changed, added and removed in upnp dnl # - Interfaces have been changed, added and removed in upnp
dnl # current: 4 -> 5 dnl # current: 3 -> 4
dnl # revision: 4 -> 0 dnl # revision: 6 -> 0
dnl # - Interfaces removed in upnp:
dnl # age: -> 0
dnl # dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0]) dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0])
dnl # dnl #
dnl # Obs.: 1.6.7 was released with a version error, the correct nubers should
dnl # have been:
dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0])
dnl #
dnl ############################################################################ dnl ############################################################################
AC_SUBST([LT_VERSION_IXML], [2:4:0]) dnl # Release 1.6.8:
AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) dnl # "current:revision:age"
AC_SUBST([LT_VERSION_UPNP], [3:5:0]) dnl #
dnl # - Code has changed in ixml
dnl # revision: 4 -> 5
dnl # - Code has changed in threadutil
dnl # revision: 0 -> 1
dnl # - Code has changed in upnp
dnl # revision: 0 -> 1
dnl #AC_SUBST([LT_VERSION_IXML], [2:5:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:1:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [4:1:0])
dnl #
dnl ############################################################################
AC_SUBST([LT_VERSION_IXML], [2:5:0])
AC_SUBST([LT_VERSION_THREADUTIL], [5:1:2])
AC_SUBST([LT_VERSION_UPNP], [4:1:0])
dnl ############################################################################ dnl ############################################################################
dnl # Repeating the algorithm to place it closer to the modificatin place: dnl # Repeating the algorithm to place it closer to the modificatin place:
dnl # - library code modified: revision++ dnl # - library code modified: revision++
@@ -256,6 +276,16 @@ if test "x$enable_tools" = xyes ; then
AC_DEFINE(UPNP_HAVE_TOOLS, 1, [see upnpconfig.h]) AC_DEFINE(UPNP_HAVE_TOOLS, 1, [see upnpconfig.h])
fi 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]) RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code])
@@ -482,3 +512,11 @@ AC_CONFIG_FILES([
AC_OUTPUT AC_OUTPUT
#
# Files copied for windows compilation.
#
echo "configure: copying \"autoconfig.h\" to \"build/inc/autoconfig.h\""
cp autoconfig.h build/inc/autoconfig.h
echo "configure: copying \"upnp/inc/upnpconfig.h\" to \"build/inc/upnpconfig.h\""
cp upnp/inc/upnpconfig.h build/inc/upnpconfig.h

View File

@@ -2,7 +2,7 @@
# #
# "Makefile.am" for "libupnp/ixml" # "Makefile.am" for "libupnp/ixml"
# #
# (C) Copyright 2005 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> # (C) Copyright 2005 Rémi Turboult <r3mi@users.sourceforge.net>
# #
SUBDIRS = doc SUBDIRS = doc

View File

@@ -45,9 +45,13 @@
#include "UpnpGlobal.h" /* For EXPORT_SPEC */ #include "UpnpGlobal.h" /* For EXPORT_SPEC */
/* Define BOOL. */
typedef int 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. * \brief The type of DOM strings.

View File

@@ -5,6 +5,7 @@
#include "UpnpGlobal.h" #include "UpnpGlobal.h"
#include "ixml.h"
/*! /*!
@@ -20,6 +21,13 @@
*/ */
#ifdef DEBUG #ifdef DEBUG
void IxmlPrintf( void IxmlPrintf(
/*! [in] The file name, usually __FILE__. */
const char *DbgFileName,
/*! [in] The line number, usually __LINE__ or a variable that got the
* __LINE__ at the appropriate place. */
int DbgLineNo,
/*! [in] The function name. */
const char *FunctionName,
/*! [in] Printf like format specification. */ /*! [in] Printf like format specification. */
const char* FmtStr, const char* FmtStr,
/*! [in] Printf like Variable number of arguments that will go in the debug /*! [in] Printf like Variable number of arguments that will go in the debug
@@ -27,7 +35,7 @@ void IxmlPrintf(
...) ...)
#if (__GNUC__ >= 3) #if (__GNUC__ >= 3)
/* This enables printf like format checking by the compiler */ /* This enables printf like format checking by the compiler */
__attribute__((format (__printf__, 1, 2))) __attribute__((format (__printf__, 4, 5)))
#endif #endif
; ;
#else /* DEBUG */ #else /* DEBUG */
@@ -37,5 +45,23 @@ static UPNP_INLINE void IxmlPrintf(
#endif /* DEBUG */ #endif /* DEBUG */
/*!
* \brief Print the node names and values of a XML tree.
*/
#ifdef DEBUG
void printNodes(
/*! [in] The root of the tree to print. */
IXML_Node *tmpRoot,
/*! [in] The depth to print. */
int depth);
#else
static UPNP_INLINE void printNodes(
IXML_Node *tmpRoot,
int depth)
{
}
#endif
#endif /* IXMLDEBUG_H */ #endif /* IXMLDEBUG_H */

View File

@@ -444,17 +444,17 @@ int ixmlDocument_createElementNSEx(
IXML_Element **rtElement) IXML_Element **rtElement)
{ {
IXML_Element *newElement = NULL; IXML_Element *newElement = NULL;
int errCode = IXML_SUCCESS; int ret = IXML_SUCCESS;
int line = 0; int line = 0;
if (doc == NULL || namespaceURI == NULL || qualifiedName == NULL) { if (doc == NULL || namespaceURI == NULL || qualifiedName == NULL) {
line = __LINE__; line = __LINE__;
errCode = IXML_INVALID_PARAMETER; ret = IXML_INVALID_PARAMETER;
goto ErrorHandler; goto ErrorHandler;
} }
errCode = ixmlDocument_createElementEx(doc, qualifiedName, &newElement); ret = ixmlDocument_createElementEx(doc, qualifiedName, &newElement);
if (errCode != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
line = __LINE__; line = __LINE__;
goto ErrorHandler; goto ErrorHandler;
} }
@@ -464,16 +464,16 @@ int ixmlDocument_createElementNSEx(
line = __LINE__; line = __LINE__;
ixmlElement_free(newElement); ixmlElement_free(newElement);
newElement = NULL; newElement = NULL;
errCode = IXML_INSUFFICIENT_MEMORY; ret = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler; goto ErrorHandler;
} }
// set the localName and prefix // set the localName and prefix
errCode = ixmlNode_setNodeName((IXML_Node *)newElement, qualifiedName); ret = ixmlNode_setNodeName((IXML_Node *)newElement, qualifiedName);
if (errCode != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
line = __LINE__; line = __LINE__;
ixmlElement_free(newElement); ixmlElement_free(newElement);
newElement = NULL; newElement = NULL;
errCode = IXML_INSUFFICIENT_MEMORY; ret = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler; goto ErrorHandler;
} }
@@ -481,12 +481,11 @@ int ixmlDocument_createElementNSEx(
ErrorHandler: ErrorHandler:
*rtElement = newElement; *rtElement = newElement;
if (errCode != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
IxmlPrintf("(%s::ixmlDocument_createElementNSEx): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "ixmlDocument_createElementNSEx", "Error %d\n", ret);
__FILE__, errCode, line);
} }
return errCode; return ret;
} }

View File

@@ -181,9 +181,9 @@ static void ixmlPrintDomTreeRecursive(
break; break;
default: default:
IxmlPrintf("(%s::ixmlPrintDomTreeRecursive) line %d: " IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTreeRecursive",
"Warning, unknown node type %d\n", "Warning, unknown node type %d\n",
__FILE__, __LINE__, ixmlNode_getNodeType(nodeptr)); ixmlNode_getNodeType(nodeptr));
break; break;
} }
} }
@@ -253,9 +253,9 @@ static void ixmlPrintDomTree(
break; break;
default: default:
IxmlPrintf("(%s::ixmlPrintDomTree) line %d: " IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTree",
"Warning, unknown node type %d\n", "Warning, unknown node type %d\n",
__FILE__, __LINE__, ixmlNode_getNodeType(nodeptr)); ixmlNode_getNodeType(nodeptr));
break; break;
} }
} }
@@ -324,9 +324,9 @@ static void ixmlDomTreetoString(
break; break;
default: default:
IxmlPrintf("(%s::ixmlDomTreetoString) line %d: " IxmlPrintf(__FILE__, __LINE__, "ixmlPrintDomTreeRecursive",
"Warning, unknown node type %d\n", "Warning, unknown node type %d\n",
__FILE__, __LINE__, ixmlNode_getNodeType(nodeptr)); ixmlNode_getNodeType(nodeptr));
break; break;
} }
} }

View File

@@ -17,15 +17,54 @@
#ifdef DEBUG #ifdef DEBUG
void IxmlPrintf( void IxmlPrintf(
const char *DbgFileName,
int DbgLineNo,
const char *FunctionName,
const char *FmtStr, const char *FmtStr,
...) ...)
{ {
va_list ArgList; va_list ArgList;
va_start(ArgList, FmtStr); FILE *fp = stdout;
vfprintf(stdout, FmtStr, ArgList); fprintf(fp, "(%s::%s), line %d", DbgFileName, FunctionName, DbgLineNo);
fflush(stdout); if (FmtStr) {
va_end(ArgList); fprintf(fp, ": ");
va_start(ArgList, FmtStr);
vfprintf(fp, FmtStr, ArgList);
fflush(fp);
va_end(ArgList);
} else {
fprintf(fp, "\n");
}
} }
void printNodes(IXML_Node *tmpRoot, int depth)
{
int i;
IXML_NodeList *NodeList1;
IXML_Node *ChildNode1;
unsigned short NodeType;
const DOMString NodeValue;
const DOMString NodeName;
NodeList1 = ixmlNode_getChildNodes(tmpRoot);
for (i = 0; i < 100; ++i) {
ChildNode1 = ixmlNodeList_item(NodeList1, i);
if (ChildNode1 == NULL) {
break;
}
printNodes(ChildNode1, depth+1);
NodeType = ixmlNode_getNodeType(ChildNode1);
NodeValue = ixmlNode_getNodeValue(ChildNode1);
NodeName = ixmlNode_getNodeName(ChildNode1);
IxmlPrintf(__FILE__, __LINE__, "printNodes",
"DEPTH-%2d-IXML_Node Type %d, "
"IXML_Node Name: %s, IXML_Node Value: %s\n",
depth, NodeType, NodeName, NodeValue);
}
}
#endif #endif

View File

@@ -542,8 +542,7 @@ static int Parser_UTF8ToInt(
*len = 0; *len = 0;
ret = -1; ret = -1;
} }
IxmlPrintf("(%s::Parser_UTF8ToInt): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_UTF8ToInt", "Error %d\n", ret);
__FILE__, ret, line);
return ret; return ret;
} }
} }
@@ -583,11 +582,14 @@ static int Parser_isValidEndElement(
IXML_Node *newNode) IXML_Node *newNode)
{ {
assert(xmlParser); assert(xmlParser);
assert(xmlParser->pCurElement);
assert(xmlParser->pCurElement->element); assert(xmlParser->pCurElement->element);
assert(newNode); assert(newNode);
assert(newNode->nodeName); assert(newNode->nodeName);
if (xmlParser->pCurElement == NULL) {
return 0;
}
return strcmp(xmlParser->pCurElement->element, newNode->nodeName) == 0; return strcmp(xmlParser->pCurElement->element, newNode->nodeName) == 0;
} }
@@ -1302,8 +1304,7 @@ fail_entity:
ExitFunction: ExitFunction:
if (ret == -1 || (g_error_char && ret == g_error_char)) { if (ret == -1 || (g_error_char && ret == g_error_char)) {
IxmlPrintf("(%s::Parser_getChar): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_getChar", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -1370,8 +1371,7 @@ static int Parser_copyToken(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
IxmlPrintf("(%s::Parser_copyToken): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_copyToken", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -1918,8 +1918,7 @@ static int Parser_xmlNamespace(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) { if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) {
IxmlPrintf("(%s::Parser_xmlNamespace): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_xmlNamespace", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -2248,8 +2247,7 @@ static int Parser_processContent(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
IxmlPrintf("(%s::Parser_processContent): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_processContent", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -2321,8 +2319,7 @@ static int Parser_processETag(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS) { if (ret != IXML_SUCCESS) {
IxmlPrintf("(%s::Parser_processETag): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_processETag", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -2577,8 +2574,7 @@ static int Parser_processAttribute(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) { if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) {
IxmlPrintf("(%s::Parser_processAttribute): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_processAttribute", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;
@@ -2681,8 +2677,7 @@ static int Parser_getNextNode(
ExitFunction: ExitFunction:
if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) { if (ret != IXML_SUCCESS && ret != IXML_FILE_DONE) {
IxmlPrintf("(%s::Parser_getNextNode): Error %d, line %d\n", IxmlPrintf(__FILE__, line, "Parser_getNextNode", "Error %d\n", ret);
__FILE__, ret, line);
} }
return ret; return ret;

View File

@@ -1,4 +1,4 @@
Version: 1.6.7 Version: 1.6.8
Summary: Universal Plug and Play (UPnP) SDK Summary: Universal Plug and Play (UPnP) SDK
Name: libupnp Name: libupnp
Release: 1%{?dist} Release: 1%{?dist}

View File

@@ -29,14 +29,24 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef FREE_LIST_H #ifndef FREE_LIST_H
#define FREE_LIST_H #define FREE_LIST_H
/*!
* \file
*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "ithread.h" #include "ithread.h"
#include <errno.h> #include <errno.h>
/**************************************************************************** /****************************************************************************

View File

@@ -29,21 +29,32 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef LINKED_LIST_H #ifndef LINKED_LIST_H
#define LINKED_LIST_H #define LINKED_LIST_H
/*!
* \file
*/
#include "FreeList.h" #include "FreeList.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define EOUTOFMEM (-7 & 1<<29) #define EOUTOFMEM (-7 & 1<<29)
#define FREELISTSIZE 100 #define FREELISTSIZE 100
#define LIST_SUCCESS 1 #define LIST_SUCCESS 1
#define LIST_FAIL 0 #define LIST_FAIL 0
/**************************************************************************** /****************************************************************************
* Name: free_routine * Name: free_routine
* *
@@ -52,6 +63,7 @@ extern "C" {
*****************************************************************************/ *****************************************************************************/
typedef void (*free_function)(void *arg); typedef void (*free_function)(void *arg);
/**************************************************************************** /****************************************************************************
* Name: cmp_routine * Name: cmp_routine
* *
@@ -61,6 +73,7 @@ typedef void (*free_function)(void *arg);
*****************************************************************************/ *****************************************************************************/
typedef int (*cmp_routine)(void *itemA,void *itemB); typedef int (*cmp_routine)(void *itemA,void *itemB);
/**************************************************************************** /****************************************************************************
* Name: ListNode * Name: ListNode
* *
@@ -75,6 +88,7 @@ typedef struct LISTNODE
void *item; void *item;
} ListNode; } ListNode;
/**************************************************************************** /****************************************************************************
* Name: LinkedList * Name: LinkedList
* *
@@ -104,6 +118,7 @@ typedef struct LINKEDLIST
cmp_routine cmp_func; /* compare function to use */ cmp_routine cmp_func; /* compare function to use */
} LinkedList; } LinkedList;
/**************************************************************************** /****************************************************************************
* Function: ListInit * Function: ListInit
* *
@@ -119,6 +134,7 @@ typedef struct LINKEDLIST
*****************************************************************************/ *****************************************************************************/
int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func); int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func);
/**************************************************************************** /****************************************************************************
* Function: ListAddHead * Function: ListAddHead
* *
@@ -135,6 +151,7 @@ int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func);
*****************************************************************************/ *****************************************************************************/
ListNode *ListAddHead(LinkedList *list, void *item); ListNode *ListAddHead(LinkedList *list, void *item);
/**************************************************************************** /****************************************************************************
* Function: ListAddTail * Function: ListAddTail
* *
@@ -151,6 +168,7 @@ ListNode *ListAddHead(LinkedList *list, void *item);
*****************************************************************************/ *****************************************************************************/
ListNode *ListAddTail(LinkedList *list, void *item); ListNode *ListAddTail(LinkedList *list, void *item);
/**************************************************************************** /****************************************************************************
* Function: ListAddAfter * Function: ListAddAfter
* *
@@ -205,6 +223,7 @@ ListNode *ListAddBefore(LinkedList *list,void *item, ListNode *anode);
*****************************************************************************/ *****************************************************************************/
void *ListDelNode(LinkedList *list,ListNode *dnode, int freeItem); void *ListDelNode(LinkedList *list,ListNode *dnode, int freeItem);
/**************************************************************************** /****************************************************************************
* Function: ListDestroy * Function: ListDestroy
* *
@@ -240,6 +259,7 @@ int ListDestroy(LinkedList *list, int freeItem);
*****************************************************************************/ *****************************************************************************/
ListNode* ListHead(LinkedList *list); ListNode* ListHead(LinkedList *list);
/**************************************************************************** /****************************************************************************
* Function: ListTail * Function: ListTail
* *
@@ -256,6 +276,7 @@ ListNode* ListHead(LinkedList *list);
*****************************************************************************/ *****************************************************************************/
ListNode* ListTail(LinkedList *list); ListNode* ListTail(LinkedList *list);
/**************************************************************************** /****************************************************************************
* Function: ListNext * Function: ListNext
* *
@@ -272,6 +293,7 @@ ListNode* ListTail(LinkedList *list);
*****************************************************************************/ *****************************************************************************/
ListNode* ListNext(LinkedList *list, ListNode * node); ListNode* ListNext(LinkedList *list, ListNode * node);
/**************************************************************************** /****************************************************************************
* Function: ListPrev * Function: ListPrev
* *
@@ -288,6 +310,7 @@ ListNode* ListNext(LinkedList *list, ListNode * node);
*****************************************************************************/ *****************************************************************************/
ListNode* ListPrev(LinkedList *list, ListNode * node); ListNode* ListPrev(LinkedList *list, ListNode * node);
/**************************************************************************** /****************************************************************************
* Function: ListFind * Function: ListFind
* *
@@ -307,6 +330,7 @@ ListNode* ListPrev(LinkedList *list, ListNode * node);
*****************************************************************************/ *****************************************************************************/
ListNode* ListFind(LinkedList *list, ListNode *start, void * item); ListNode* ListFind(LinkedList *list, ListNode *start, void * item);
/**************************************************************************** /****************************************************************************
* Function: ListSize * Function: ListSize
* *

View File

@@ -115,6 +115,10 @@ typedef enum priority {
#define DEFAULT_MAX_THREADS 10 #define DEFAULT_MAX_THREADS 10
/*! default stack size used by TPAttrInit */
#define DEFAULT_STACK_SIZE 0
/*! default jobs per thread used by TPAttrInit */ /*! default jobs per thread used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10 #define DEFAULT_JOBS_PER_THREAD 10
@@ -154,10 +158,6 @@ typedef int PolicyType;
#define DEFAULT_POLICY SCHED_OTHER #define DEFAULT_POLICY SCHED_OTHER
/*! Default priority */
#define DEFAULT_SCHED_PARAM 0
/**************************************************************************** /****************************************************************************
* Name: free_routine * Name: free_routine
* *
@@ -182,6 +182,10 @@ typedef struct THREADPOOLATTR
/* maxThreads, ThreadPool will never have more than this number of threads */ /* maxThreads, ThreadPool will never have more than this number of threads */
int maxThreads; 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 /* maxIdleTime (in milliseconds) this is the maximum time a thread will
* remain idle before dying */ * remain idle before dying */
int maxIdleTime; int maxIdleTime;
@@ -522,6 +526,20 @@ int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads); 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 * Function: TPAttrSetIdleTime
* *

View File

@@ -29,160 +29,139 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef TIMERTHREAD_H #ifndef TIMERTHREAD_H
#define TIMERTHREAD_H #define TIMERTHREAD_H
/*!
* \file
*/
#include "FreeList.h"
#include "ithread.h" #include "ithread.h"
#include "LinkedList.h" #include "LinkedList.h"
#include "FreeList.h"
#include "ThreadPool.h" #include "ThreadPool.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#define INVALID_EVENT_ID (-10 & 1<<29) #define INVALID_EVENT_ID (-10 & 1<<29)
/* Timeout Types */ /* Timeout Types */
/* absolute means in seconds from Jan 1, 1970 */ /* absolute means in seconds from Jan 1, 1970 */
/* relative means in seconds from current time */ /* relative means in seconds from current time */
typedef enum timeoutType {ABS_SEC,REL_SEC} TimeoutType; typedef enum timeoutType {ABS_SEC,REL_SEC} TimeoutType;
/**************************************************************************** /*!
* Name: TimerThread * A timer thread similar to the one in the Upnp SDK that allows
* * the scheduling of a job to run at a specified time in the future.
* Description: *
* A timer thread similar to the one in the Upnp SDK that allows * Because the timer thread uses the thread pool there is no
* the scheduling of a job to run at a specified time in the future * gurantee of timing, only approximate timing.
* Because the timer thread uses the thread pool there is no *
* gurantee of timing, only approximate timing. * Uses ThreadPool, Mutex, Condition, Thread.
* Uses ThreadPool, Mutex, Condition, Thread */
*
*
*****************************************************************************/
typedef struct TIMERTHREAD typedef struct TIMERTHREAD
{ {
ithread_mutex_t mutex; ithread_mutex_t mutex;
ithread_cond_t condition; ithread_cond_t condition;
int lastEventId; int lastEventId;
LinkedList eventQ; LinkedList eventQ;
int shutdown; int shutdown;
FreeList freeEvents; FreeList freeEvents;
ThreadPool *tp; ThreadPool *tp;
} TimerThread; } TimerThread;
/**************************************************************************** /*!
* Name: TimerEvent * Struct to contain information for a timer event.
* *
* Description: * Internal to the TimerThread.
* */
* Struct to contain information for a timer event.
* Internal to the TimerThread
*
*****************************************************************************/
typedef struct TIMEREVENT typedef struct TIMEREVENT
{ {
ThreadPoolJob job; ThreadPoolJob job;
time_t eventTime; /* absolute time for event in seconds since Jan 1, 1970 */ /*! [in] Absolute time for event in seconds since Jan 1, 1970. */
Duration persistent; /* long term or short term job */ time_t eventTime;
int id; /*! [in] Long term or short term job. */
Duration persistent;
int id;
} TimerEvent; } TimerEvent;
/*!
* \brief Initializes and starts timer thread.
/************************************************************************
* Function: TimerThreadInit
*
* Description:
* Initializes and starts timer thread.
* *
* Parameters: * \return 0 on success, nonzero on failure. Returns error from
* timer - valid timer thread pointer. * ThreadPoolAddPersistent on failure.
* tp - valid thread pool to use. Must be */
* started. Must be valid for lifetime int TimerThreadInit(
* of timer. Timer must be shutdown /*! [in] Valid timer thread pointer. */
* BEFORE thread pool. TimerThread *timer,
* Return: /*! [in] Valid thread pool to use. Must be started. Must be valid for
* 0 on success, nonzero on failure * lifetime of timer. Timer must be shutdown BEFORE thread pool. */
* Returns error from ThreadPoolAddPersistent on failure. ThreadPool *tp);
*
************************************************************************/
int TimerThreadInit(TimerThread *timer,
ThreadPool *tp);
/************************************************************************ /*!
* Function: TimerThreadSchedule * \brief Schedules an event to run at a specified time.
*
* Description:
* Schedules an event to run at a specified time.
* *
* Parameters: * \return 0 on success, nonzero on failure, EOUTOFMEM if not enough memory
* timer - valid timer thread pointer. * to schedule job.
* time_t - time of event. */
* either in absolute seconds, int TimerThreadSchedule(
* or relative seconds in the future. /*! [in] Valid timer thread pointer. */
* timeoutType - either ABS_SEC, or REL_SEC. TimerThread* timer,
* if REL_SEC, then the event /*! [in] time of event. Either in absolute seconds, or relative
* will be scheduled at the * seconds in the future. */
* current time + REL_SEC. time_t time,
* job-> valid Thread pool job with following fields /*! [in] either ABS_SEC, or REL_SEC. If REL_SEC, then the event
* func - function to schedule * will be scheduled at the current time + REL_SEC. */
* arg - argument to function TimeoutType type,
* priority - priority of job. /*! [in] Valid Thread pool job with following fields. */
* ThreadPoolJob *job,
* id - id of timer event. (out, can be null) /*! [in] . */
* Return: Duration duration,
* 0 on success, nonzero on failure /*! [in] Id of timer event. (out, can be null). */
* EOUTOFMEM if not enough memory to schedule job. int *id);
*
************************************************************************/
int TimerThreadSchedule(TimerThread* timer,
time_t time,
TimeoutType type,
ThreadPoolJob *job,
Duration duration,
int *id);
/************************************************************************
* Function: TimerThreadRemove
*
* Description:
* Removes an event from the timer Q.
* Events can only be removed
* before they have been placed in the
* thread pool.
*
* Parameters:
* timer - valid timer thread pointer.
* id - id of event to remove.
* ThreadPoolJob *out - space for thread pool job.
* Return:
* 0 on success,
* INVALID_EVENT_ID on failure
*
************************************************************************/
int TimerThreadRemove(TimerThread *timer,
int id,
ThreadPoolJob *out);
/************************************************************************ /*!
* Function: TimerThreadShutdown * \brief Removes an event from the timer Q.
* *
* Description: * Events can only be removed before they have been placed in the thread pool.
* Shutdown the timer thread *
* Events scheduled in the future will NOT be run. * \return 0 on success, INVALID_EVENT_ID on failure.
* Timer thread should be shutdown BEFORE it's associated */
* thread pool. int TimerThreadRemove(
* Returns: /*! [in] Valid timer thread pointer. */
* returns 0 if succesfull, TimerThread *timer,
* nonzero otherwise. /*! [in] Id of event to remove. */
* Always returns 0. int id,
***********************************************************************/ /*! [in] Space for thread pool job. */
int TimerThreadShutdown(TimerThread *timer); ThreadPoolJob *out);
/*!
* \brief Shutdown the timer thread.
*
* Events scheduled in the future will NOT be run.
*
* Timer thread should be shutdown BEFORE it's associated thread pool.
*
* \return 0 if succesfull, nonzero otherwise. Always returns 0.
*/
int TimerThreadShutdown(
/*! [in] Valid timer thread pointer. */
TimerThread *timer);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -85,7 +85,10 @@ extern "C" {
#define ITHREAD_CANCELED PTHREAD_CANCELED #define ITHREAD_CANCELED PTHREAD_CANCELED
#define ITHREAD_STACK_MIN PTHREAD_STACK_MIN
/*************************************************************************** /***************************************************************************
* Name: ithread_t * Name: ithread_t
* *
@@ -171,7 +174,9 @@ typedef pthread_condattr_t ithread_condattr_t;
* typedef to pthread_rwlockattr_t * typedef to pthread_rwlockattr_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlockattr_t ithread_rwlockattr_t; 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 * typedef to pthread_rwlock_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlock_t ithread_rwlock_t; 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. * Always returns 0.
* See man page for pthread_rwlockattr_init * 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. * Always returns 0.
* See man page for pthread_rwlockattr_destroy * 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. * Returns EINVAL if the kind is not supported.
* See man page for pthread_rwlockattr_setkind_np * 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. * Always returns 0.
* See man page for pthread_rwlockatttr_getpshared * 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. * Always returns 0.
* See man page for pthread_rwlock_init * 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. * Always returns 0.
* See man page for pthread_rwlock_rdlock * 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. * Always returns 0.
* See man page for pthread_rwlock_wrlock * 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. * Always returns 0.
* See man page for pthread_rwlock_unlock * 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. * Always returns 0.
* See man page for pthread_rwlock_destroy * 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 #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 * Function: ithread_create
@@ -713,7 +781,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* and argument. * and argument.
* Parameters: * Parameters:
* ithread_t * thread (must be valid non NULL pointer to pthread_t) * 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 * (start_routine) (void *arg) (start routine)
* void * arg - argument. * void * arg - argument.
* Returns: * Returns:

View File

@@ -1,45 +1,55 @@
/////////////////////////////////////////////////////////////////////////// /**************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// **************************************************************************/
#include "LinkedList.h" #include "LinkedList.h"
#ifndef WIN32
#ifdef WIN32
/* Do not #include <sys/param.h> */
#else
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__) #if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <malloc.h>
#endif #endif
#include <assert.h> #include <assert.h>
static int static int
freeListNode( ListNode * node, freeListNode( ListNode * node,
LinkedList * list ) LinkedList * list )

View File

@@ -246,7 +246,7 @@ static int SetPolicyType(PolicyType in)
memset(&current, 0, sizeof(current)); memset(&current, 0, sizeof(current));
sched_getparam(0, &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); sched_result = sched_setscheduler(0, in, &current);
retVal = (sched_result != -1 || errno == EPERM) ? 0 : errno; retVal = (sched_result != -1 || errno == EPERM) ? 0 : errno;
#else #else
@@ -609,12 +609,16 @@ static int CreateWorker(ThreadPool *tp)
ithread_t temp; ithread_t temp;
int rc = 0; int rc = 0;
int currentThreads = tp->totalThreads + 1; int currentThreads = tp->totalThreads + 1;
ithread_attr_t attr;
if (tp->attr.maxThreads != INFINITE_THREADS && if (tp->attr.maxThreads != INFINITE_THREADS &&
currentThreads > tp->attr.maxThreads) { currentThreads > tp->attr.maxThreads) {
return EMAXTHREADS; 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) { if (rc == 0) {
rc = ithread_detach(temp); rc = ithread_detach(temp);
while (tp->totalThreads < currentThreads) { while (tp->totalThreads < currentThreads) {
@@ -1174,6 +1178,7 @@ int TPAttrInit(ThreadPoolAttr *attr)
attr->maxIdleTime = DEFAULT_IDLE_TIME; attr->maxIdleTime = DEFAULT_IDLE_TIME;
attr->maxThreads = DEFAULT_MAX_THREADS; attr->maxThreads = DEFAULT_MAX_THREADS;
attr->minThreads = DEFAULT_MIN_THREADS; attr->minThreads = DEFAULT_MIN_THREADS;
attr->stackSize = DEFAULT_STACK_SIZE;
attr->schedPolicy = DEFAULT_POLICY; attr->schedPolicy = DEFAULT_POLICY;
attr->starvationTime = DEFAULT_STARVATION_TIME; attr->starvationTime = DEFAULT_STARVATION_TIME;
attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL; attr->maxJobsTotal = DEFAULT_MAX_JOBS_TOTAL;
@@ -1298,6 +1303,28 @@ int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads)
return 0; 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 * Function: TPAttrSetIdleTime
* *

View File

@@ -1,68 +1,69 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
/*!
* \file
*/
#include "TimerThread.h" #include "TimerThread.h"
#include <assert.h> #include <assert.h>
/****************************************************************************
* Function: FreeTimerEvent /*!
* * \brief Deallocates a dynamically allocated TimerEvent.
* Description: */
* Deallocates a dynamically allocated TimerEvent. static void FreeTimerEvent(
* Parameters: /*! [in] Valid timer thread pointer. */
* TimerEvent *event - must be allocated with CreateTimerEvent TimerThread *timer,
*****************************************************************************/ /*! [in] Must be allocated with CreateTimerEvent*/
static void TimerEvent *event)
FreeTimerEvent( TimerThread * timer,
TimerEvent * event )
{ {
assert(timer != NULL);
assert( timer != NULL ); FreeListFree(&timer->freeEvents, event);
FreeListFree( &timer->freeEvents, event );
} }
/****************************************************************************
* Function: TimerThreadWorker /*!
* \brief Implements timer thread.
* *
* Description: * Waits for next event to occur and schedules associated job into threadpool.
* Implements timer thread. */
* Waits for next event to occur and schedules static void *TimerThreadWorker(
* associated job into threadpool. /*! [in] arg is cast to (TimerThread *). */
* Internal Only. void *arg)
* Parameters:
* void * arg -> is cast to TimerThread *
*****************************************************************************/
static void *
TimerThreadWorker( void *arg )
{ {
TimerThread *timer = ( TimerThread * ) arg; TimerThread *timer = ( TimerThread * ) arg;
ListNode *head = NULL; ListNode *head = NULL;
@@ -81,19 +82,14 @@ TimerThreadWorker( void *arg )
while( 1 ) while( 1 )
{ {
//mutex should always be locked at top of loop //mutex should always be locked at top of loop
//Check for shutdown //Check for shutdown
if( timer->shutdown ) if( timer->shutdown )
{ {
timer->shutdown = 0; timer->shutdown = 0;
ithread_cond_signal( &timer->condition ); ithread_cond_signal( &timer->condition );
ithread_mutex_unlock( &timer->mutex ); ithread_mutex_unlock( &timer->mutex );
return NULL; return NULL;
} }
nextEvent = NULL; nextEvent = NULL;
@@ -102,7 +98,6 @@ TimerThreadWorker( void *arg )
if( timer->eventQ.size > 0 ) if( timer->eventQ.size > 0 )
{ {
head = ListHead( &timer->eventQ ); head = ListHead( &timer->eventQ );
nextEvent = ( TimerEvent * ) head->item; nextEvent = ( TimerEvent * ) head->item;
nextEventTime = nextEvent->eventTime; nextEventTime = nextEvent->eventTime;
} }
@@ -110,54 +105,42 @@ TimerThreadWorker( void *arg )
currentTime = time( NULL ); currentTime = time( NULL );
//If time has elapsed, schedule job //If time has elapsed, schedule job
if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) ) if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
{ {
if( nextEvent->persistent ) { if( nextEvent->persistent ) {
ThreadPoolAddPersistent( timer->tp, &nextEvent->job, ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
&tempId ); &tempId );
} else { } else {
ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId ); ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId );
} }
ListDelNode( &timer->eventQ, head, 0 ); ListDelNode( &timer->eventQ, head, 0 );
FreeTimerEvent( timer, nextEvent ); FreeTimerEvent( timer, nextEvent );
continue; continue;
} }
if( nextEvent != NULL ) { if( nextEvent != NULL ) {
timeToWait.tv_nsec = 0; timeToWait.tv_nsec = 0;
timeToWait.tv_sec = nextEvent->eventTime; timeToWait.tv_sec = nextEvent->eventTime;
ithread_cond_timedwait( &timer->condition, &timer->mutex, ithread_cond_timedwait( &timer->condition, &timer->mutex,
&timeToWait ); &timeToWait );
} else { } else {
ithread_cond_wait( &timer->condition, &timer->mutex ); ithread_cond_wait( &timer->condition, &timer->mutex );
} }
} }
} }
/****************************************************************************
* Function: CalculateEventTime /*!
* \brief Calculates the appropriate timeout in absolute seconds
* since Jan 1, 1970.
* *
* Description: * \return
* Calculates the appropriate timeout in absolute seconds since */
* Jan 1, 1970 static int CalculateEventTime(
* Internal Only. /*! [in] Timeout. */
* Parameters: time_t *timeout,
* time_t *timeout - timeout /*! [in] Timeout type. */
* TimeoutType type)
*****************************************************************************/
static int
CalculateEventTime( time_t * timeout,
TimeoutType type )
{ {
time_t now; time_t now;
@@ -175,29 +158,22 @@ CalculateEventTime( time_t * timeout,
} }
/**************************************************************************** /*!
* Function: CreateTimerEvent * \brief Creates a Timer Event. (Dynamically allocated).
* *
* Description: * \return (TimerEvent *) on success, NULL on failure.
* Creates a Timer Event. (Dynamically allocated) */
* Internal to timer thread. static TimerEvent *CreateTimerEvent(
* Parameters: /*! [in] Valid timer thread pointer. */
* func - thread function to run. TimerThread *timer,
* arg - argument to function. /*! [in] . */
* priority - priority of job. ThreadPoolJob *job,
* eventTime - the absoule time of the event /*! [in] . */
* in seconds from Jan, 1970 Duration persistent,
* id - id of job /*! [in] The absoule time of the event in seconds from Jan, 1970. */
* time_t eventTime,
* Returns: /*! [in] Id of job. */
* TimerEvent * on success, NULL on failure. int id)
****************************************************************************/
static TimerEvent *
CreateTimerEvent( TimerThread * timer,
ThreadPoolJob * job,
Duration persistent,
time_t eventTime,
int id )
{ {
TimerEvent *temp = NULL; TimerEvent *temp = NULL;
@@ -215,25 +191,8 @@ CreateTimerEvent( TimerThread * timer,
return temp; return temp;
} }
/************************************************************************
* Function: TimerThreadInit int TimerThreadInit(TimerThread *timer, ThreadPool *tp)
*
* Description:
* Initializes and starts timer thread.
*
* Parameters:
* timer - valid timer thread pointer.
* tp - valid thread pool to use. Must be
* started. Must be valid for lifetime
* of timer. Timer must be shutdown
* BEFORE thread pool.
* Return:
* 0 on success, nonzero on failure
* Returns error from ThreadPoolAddPersistent if failure.
************************************************************************/
int
TimerThreadInit( TimerThread * timer,
ThreadPool * tp )
{ {
int rc = 0; int rc = 0;
@@ -290,37 +249,14 @@ TimerThreadInit( TimerThread * timer,
} }
/************************************************************************
* Function: TimerThreadSchedule int TimerThreadSchedule(
* TimerThread *timer,
* Description: time_t timeout,
* Schedules an event to run at a specified time. TimeoutType type,
* ThreadPoolJob *job,
* Parameters: Duration duration,
* timer - valid timer thread pointer. int *id)
* time_t - time of event.
* either in absolute seconds,
* or relative seconds in the future.
* timeoutType - either ABS_SEC, or REL_SEC.
* if REL_SEC, then the event
* will be scheduled at the
* current time + REL_SEC.
*
* func - function to schedule
* arg - argument to function
* priority - priority of job.
* id - id of timer event. (out)
* Return:
* 0 on success, nonzero on failure
* EOUTOFMEM if not enough memory to schedule job
************************************************************************/
int
TimerThreadSchedule( TimerThread * timer,
time_t timeout,
TimeoutType type,
ThreadPoolJob * job,
Duration duration,
int *id )
{ {
int rc = EOUTOFMEM; int rc = EOUTOFMEM;
@@ -394,28 +330,11 @@ TimerThreadSchedule( TimerThread * timer,
return rc; return rc;
} }
/************************************************************************
* Function: TimerThreadRemove int TimerThreadRemove(
* TimerThread *timer,
* Description: int id,
* Removes an event from the timer Q. ThreadPoolJob *out)
* Events can only be removed
* before they have been placed in the
* thread pool.
*
* Parameters:
* timer - valid timer thread pointer.
* id - id of event to remove.
* out - space for returned job (Can be NULL)
* Return:
* 0 on success.
* INVALID_EVENT_ID on error.
*
************************************************************************/
int
TimerThreadRemove( TimerThread * timer,
int id,
ThreadPoolJob * out )
{ {
int rc = INVALID_EVENT_ID; int rc = INVALID_EVENT_ID;
ListNode *tempNode = NULL; ListNode *tempNode = NULL;
@@ -450,21 +369,8 @@ TimerThreadRemove( TimerThread * timer,
return rc; return rc;
} }
/************************************************************************
* Function: TimerThreadShutdown int TimerThreadShutdown(TimerThread *timer)
*
* Description:
* Shutdown the timer thread
* Events scheduled in the future will NOT be run.
* Timer thread should be shutdown BEFORE it's associated
* thread pool.
* Returns:
* returns 0 if succesfull,
* nonzero otherwise.
* Always returns 0.
***********************************************************************/
int
TimerThreadShutdown( TimerThread * timer )
{ {
ListNode *tempNode2 = NULL; ListNode *tempNode2 = NULL;
ListNode *tempNode = NULL; ListNode *tempNode = NULL;
@@ -517,3 +423,4 @@ TimerThreadShutdown( TimerThread * timer )
return 0; return 0;
} }

View File

@@ -67,7 +67,6 @@ libupnp_la_SOURCES = \
src/inc/sysdep.h \ src/inc/sysdep.h \
src/inc/unixutil.h \ src/inc/unixutil.h \
src/inc/upnpapi.h \ src/inc/upnpapi.h \
src/inc/upnpclosesocket.h \
src/inc/upnp_timeout.h \ src/inc/upnp_timeout.h \
src/inc/uri.h \ src/inc/uri.h \
src/inc/urlconfig.h \ src/inc/urlconfig.h \

View File

@@ -12,8 +12,11 @@
#ifdef WIN32 #ifdef WIN32
#include <iphlpapi.h>
#include <winsock2.h> #include <winsock2.h>
#include <Ws2tcpip.h> #include <Ws2tcpip.h>
#define UpnpCloseSocket closesocket
#else #else
#include <sys/param.h> #include <sys/param.h>
#if (defined(BSD) && BSD >= 199306) || defined (__FreeBSD_kernel__) #if (defined(BSD) && BSD >= 199306) || defined (__FreeBSD_kernel__)
@@ -23,6 +26,11 @@
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <netinet/in.h> #include <netinet/in.h>
#include <unistd.h> /* for close(). Do not include in WIN32. */
#define SOCKET int
#define INVALID_SOCKET ((SOCKET)(-1))
#define UpnpCloseSocket close
#endif #endif

View File

@@ -24,6 +24,9 @@
#include "UpnpGlobal.h" /* for EXPORT_SPEC */ #include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include <stdlib.h> /* for size_t */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
@@ -76,11 +79,22 @@ EXPORT_SPEC void UpnpString_assign(
* *
* \return The length of the string. * \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. */ /*! [in] The \em \b this pointer. */
const UpnpString *p); 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. * \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. * \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. */ /*! [in] The \em \b this pointer. */
UpnpString *p, UpnpString *p,
/*! [in] (char *) to copy from. */ /*! [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. * \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. */ /*! [in] The \em \b this pointer. */
UpnpString *p, UpnpString *p,
/*! [in] (char *) to copy from. */ /*! [in] (char *) to copy from. */
const char *s, const char *s,
/*! Maximum number of chars to copy.*/ /*! Maximum number of chars to copy.*/
int n); size_t n);
/*! /*!
@@ -121,6 +135,30 @@ EXPORT_SPEC void UpnpString_clear(
UpnpString *p); 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 #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */

View File

@@ -69,22 +69,6 @@
#endif #endif
#ifdef WIN32
#include <iphlpapi.h>
#else
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
#endif
#ifdef WIN32
#define UpnpCloseSocket closesocket
#define fseeko fseek
#else
#define UpnpCloseSocket close
#endif
#define LINE_SIZE 180 #define LINE_SIZE 180
#define NAME_SIZE 256 #define NAME_SIZE 256
#define MNFT_NAME_SIZE 64 #define MNFT_NAME_SIZE 64
@@ -987,6 +971,7 @@ EXPORT_SPEC int UpnpInit(
* \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not * \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not
* have a valid IPv4 or IPv6 addresss configured. * have a valid IPv4 or IPv6 addresss configured.
*/ */
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC int UpnpInit2( EXPORT_SPEC int UpnpInit2(
/*! The interface name to use by the UPnP SDK operations. /*! The interface name to use by the UPnP SDK operations.
* Examples: "eth0", "xl0", "Local Area Connection", \c NULL to * Examples: "eth0", "xl0", "Local Area Connection", \c NULL to
@@ -995,6 +980,7 @@ EXPORT_SPEC int UpnpInit2(
/*! Local Port to listen for incoming connections. /*! Local Port to listen for incoming connections.
* \c NULL will pick an arbitrary free port. */ * \c NULL will pick an arbitrary free port. */
unsigned short DestPort); unsigned short DestPort);
#endif
/*! /*!
@@ -1044,8 +1030,9 @@ EXPORT_SPEC unsigned short UpnpGetServerPort(void);
* related requests. * related requests.
* \li On error: 0 is returned if \b UpnpInit has not succeeded. * \li On error: 0 is returned if \b UpnpInit has not succeeded.
*/ */
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC unsigned short UpnpGetServerPort6(void); EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
#endif
/*! /*!
* \brief Returns the local IPv4 listening ip address. * \brief Returns the local IPv4 listening ip address.
* *
@@ -1071,10 +1058,11 @@ EXPORT_SPEC char *UpnpGetServerIpAddress(void);
* listening for UPnP related requests. * listening for UPnP related requests.
* \li On error: \c NULL is returned if \b UpnpInit has not succeeded. * \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 *UpnpGetServerIp6Address(void);
EXPORT_SPEC char *UpnpGetServerUlaGuaIp6Address(void); EXPORT_SPEC char *UpnpGetServerUlaGuaIp6Address(void);
#endif
/*! /*!
* \brief Registers a device application with the UPnP Library. * \brief Registers a device application with the UPnP Library.
* *
@@ -1351,6 +1339,8 @@ EXPORT_SPEC int UpnpSetContentLength(
* behaviour if the size of the incoming SOAP message exceeds the memory that * behaviour if the size of the incoming SOAP message exceeds the memory that
* device can allocate. * device can allocate.
* *
* If set to 0 then checking will be disabled.
*
* The default maximum content-length is \c DEFAULT_SOAP_CONTENT_LENGTH * The default maximum content-length is \c DEFAULT_SOAP_CONTENT_LENGTH
* = 16K bytes. * = 16K bytes.
* *

View File

@@ -1,7 +1,7 @@
/* -*- C -*- */ /* -*- C -*- */
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> * Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -52,7 +52,7 @@
/** The library version (numeric) e.g. 10300 means version 1.3.0 */ /** The library version (numeric) e.g. 10300 means version 1.3.0 */
#define UPNP_VERSION \ #define UPNP_VERSION \
((UPNP_VERSION_MAJOR*100 + UPNP_VERSION_MINOR)*100 + UPNP_VERSION_PATCH) ((UPNP_VERSION_MAJOR * 100 + UPNP_VERSION_MINOR) * 100 + UPNP_VERSION_PATCH)
@@ -90,6 +90,9 @@
* (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */ * (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
#undef UPNP_HAVE_TOOLS #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 */ #endif /* UPNP_CONFIG_H */

View File

@@ -304,24 +304,6 @@ static UPNP_INLINE void PrintThreadPoolStats(
#endif #endif
/*!
* \brief Print the node names and values of a XML tree.
*/
#ifdef DEBUG
void printNodes(
/*! [in] The root of the tree to print. */
IXML_Node *tmpRoot,
/*! [in] The depth to print. */
int depth);
#else
static UPNP_INLINE void printNodes(
IXML_Node *tmpRoot,
int depth)
{
}
#endif
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -29,201 +29,237 @@
* *
******************************************************************************/ ******************************************************************************/
/** @name Optional Tool APIs
* The Linux SDK for UPnP Devices contains some additional, optional
* utility APIs that can be helpful in writing applications using the
* SDK. These additional APIs can be compiled out in order to save code
* size in the SDK. Refer to the README for details.
*/
/*! @{ */
#ifndef UPNP_TOOLS_H #ifndef UPNP_TOOLS_H
#define UPNP_TOOLS_H #define UPNP_TOOLS_H
#include "upnp.h"
/*!
* \file
*
* \defgroup UPnPTools Optional Tool API
*
* \brief Additional, optional utility API that can be helpful in writing
* applications.
*
* This additional API can be compiled out in order to save code size in the
* library. Refer to the file README for details.
*
* @{
*/
#include "ixml.h" /* for IXML_Document */
/* Function declarations only if tools compiled into the library */ /* Function declarations only if tools compiled into the library */
#if UPNP_HAVE_TOOLS #if UPNP_HAVE_TOOLS
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** {\bf UpnpResolveURL} combines a base URL and a relative URL into
* a single absolute URL. The memory for {\bf AbsURL} needs to be /*!
* allocated by the caller and must be large enough to hold the * \brief Converts an SDK error code into a string error message suitable for
* {\bf BaseURL} and {\bf RelURL} combined. * display. The memory returned from this function should NOT be freed.
* *
* @return [int] An integer representing one of the following: * \return An ASCII text string representation of the error message associated
* \begin{itemize} * with the error code or the string "Unknown error code"
* \item {\tt UPNP_E_SUCCESS}: The operation completed successfully. */
* \item {\tt UPNP_E_INVALID_PARAM}: {\bf RelURL} is {\tt NULL}. EXPORT_SPEC const char *UpnpGetErrorMessage(
* \item {\tt UPNP_E_INVALID_URL}: The {\bf BaseURL} / {\bf RelURL} /*! [in] The SDK error code to convert. */
int errorcode);
/*!
* \brief Combines a base URL and a relative URL into a single absolute URL.
*
* The memory for \b AbsURL needs to be allocated by the caller and must
* be large enough to hold the \b BaseURL and \b RelURL combined.
*
* \return An integer representing one of the following:
* \li <tt>UPNP_E_SUCCESS</tt>: The operation completed successfully.
* \li <tt>UPNP_E_INVALID_PARAM</tt>: \b RelURL is <tt>NULL</tt>.
* \li <tt>UPNP_E_INVALID_URL</tt>: The \b BaseURL / \b RelURL
* combination does not form a valid URL. * combination does not form a valid URL.
* \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to * \li <tt>UPNP_E_OUTOF_MEMORY</tt>: Insufficient resources exist to
* complete this operation. * complete this operation.
* \end{itemize}
*/ */
EXPORT_SPEC int UpnpResolveURL( EXPORT_SPEC int UpnpResolveURL(
IN const char * BaseURL, /** The base URL to combine. */ /*! [in] The base URL to combine. */
IN const char * RelURL, /** The relative URL to {\bf BaseURL}. */ const char *BaseURL,
OUT char * AbsURL /** A pointer to a buffer to store the /*! [in] The relative URL to \b BaseURL. */
absolute URL. */ const char *RelURL,
); /*! [out] A pointer to a buffer to store the absolute URL. */
char *AbsURL);
/** {\bf UpnpMakeAction} creates an action request packet based on its input
* parameters (status variable name and value pair). Any number of input
* parameters can be passed to this function but every input variable name
* should have a matching value argument.
*
* @return [IXML_Document*] The action node of {\bf Upnp_Document} type or
* {\tt NULL} if the operation failed.
*/
EXPORT_SPEC IXML_Document* UpnpMakeAction( /*!
IN const char * ActionName, /** The action name. */ * \brief Creates an action request packet based on its input parameters
IN const char * ServType, /** The service type. */ * (status variable name and value pair).
IN int NumArg, /** Number of argument pairs to be passed. */
IN const char * Arg, /** Status variable name and value pair. */
IN ... /* Other status variable name and value pairs. */
);
/** {\bf UpnpAddToAction} creates an action request packet based on its input
* parameters (status variable name and value pair). This API is specially
* suitable inside a loop to add any number input parameters into an existing
* action. If no action document exists in the beginning then a
* {\bf Upnp_Document} variable initialized with {\tt NULL} should be passed
* as a parameter.
* *
* @return [int] An integer representing one of the following: * Any number of input parameters can be passed to this function but every
* \begin{itemize} * input variable name should have a matching value argument.
* \item {\tt UPNP_E_SUCCESS}: The operation completed successfully. *
* \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters * It is a wrapper function that calls makeAction() function to create the
* are invalid. * action request.
* \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to *
* complete this operation. * \return The action node of \b Upnp_Document type or <tt>NULL</tt> if the
* \end{itemize} * operation failed.
*/ */
EXPORT_SPEC IXML_Document *UpnpMakeAction(
/*! [in] Name of the action request or response. */
const char *ActionName,
/*! [in] The service type. */
const char *ServType,
/*! [in] Number of argument pairs to be passed. */
int NumArg,
/*! [in] pointer to the first argument. */
const char *Arg,
/*! [in] Argument list. */
...);
/*!
* \brief Ceates an action response packet based on its output parameters
* (status variable name and value pair).
*
* Any number of input parameters can be passed to this function but every
* output variable name should have a matching value argument.
*
* It is a wrapper function that calls makeAction() function to create the
* action request.
*
* \return The action node of \b Upnp_Document type or <tt>NULL</tt> if the
* operation failed.
*/
EXPORT_SPEC IXML_Document *UpnpMakeActionResponse(
/*! [in] The action name. */
const char *ActionName,
/*! [in] The service type.. */
const char *ServType,
/*! [in] The number of argument pairs passed. */
int NumArg,
/*! [in] The status variable name and value pair. */
const char *Arg,
/*! [in] Other status variable name and value pairs. */
...);
/*!
* \brief Adds the argument in the action request.
*
* This API is specially suitable inside a loop to add any number input
* parameters into an existing action. If no action document exists in the
* beginning then a <b>Upnp_Document variable initialized with <tt>NULL</tt></b>
* should be passed as a parameter.
*
* It is a wrapper function that calls addToAction() function to add the
* argument in the action request.
*
* \return An integer representing one of the following:
* \li <tt>UPNP_E_SUCCESS</tt>: The operation completed successfully.
* \li <tt>UPNP_E_INVALID_PARAM</tt>: One or more of the parameters are invalid.
* \li <tt>UPNP_E_OUTOF_MEMORY</tt>: Insufficient resources exist to
* complete this operation.
*/
EXPORT_SPEC int UpnpAddToAction( EXPORT_SPEC int UpnpAddToAction(
IN OUT IXML_Document ** ActionDoc, /*! [in,out] A pointer to store the action document node. */
/** A pointer to store the action IXML_Document **ActionDoc,
document node. */ /*! [in] The action name. */
IN const char * ActionName, /** The action name. */ const char *ActionName,
IN const char * ServType, /** The service type. */ /*! [in] The service type. */
IN const char * ArgName, /** The status variable name. */ const char *ServType,
IN const char * ArgVal /** The status variable value. */ /*! [in] The status variable name. */
); const char *ArgName,
/*! [in] The status variable value. */
const char *ArgVal);
/** {\bf UpnpMakeActionResponse} creates an action response packet based
* on its output parameters (status variable name and value pair). Any
* number of input parameters can be passed to this function but every output
* variable name should have a matching value argument.
*
* @return [IXML_Document*] The action node of {\bf Upnp_Document} type or
* {\tt NULL} if the operation failed.
*/
EXPORT_SPEC IXML_Document* UpnpMakeActionResponse( /*!
IN const char * ActionName, /** The action name. */ * \brief Creates an action response packet based on its output parameters
IN const char * ServType, /** The service type. */ * (status variable name and value pair).
IN int NumArg, /** The number of argument pairs passed. */
IN const char * Arg, /** The status variable name and value pair. */
IN ... /* Other status variable name and value pairs. */
);
/** {\bf UpnpAddToActionResponse} creates an action response
* packet based on its output parameters (status variable name
* and value pair). This API is especially suitable inside
* a loop to add any number of input parameters into an existing action
* response. If no action document exists in the beginning, a
* {\bf Upnp_Document} variable initialized with {\tt NULL} should be passed
* as a parameter.
* *
* @return [int] An integer representing one of the following: * This API is especially suitable inside a loop to add any number of input
* \begin{itemize} * parameters into an existing action response. If no action document exists
* \item {\tt UPNP_E_SUCCESS}: The operation completed successfully. * in the beginning, a \b Upnp_Document variable initialized with <tt>NULL</tt>
* \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters * should be passed as a parameter.
* are invalid. *
* \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to * It is a wrapper function that calls addToAction() function to add the
* complete this operation. * argument in the action request.
* \end{itemize} *
* \return An integer representing one of the following:
* \li <tt>UPNP_E_SUCCESS</tt>: The operation completed successfully.
* \li <tt>UPNP_E_INVALID_PARAM</tt>: One or more of the parameters are invalid.
* \li <tt>UPNP_E_OUTOF_MEMORY</tt>: Insufficient resources exist to
* complete this operation.
*/ */
EXPORT_SPEC int UpnpAddToActionResponse( EXPORT_SPEC int UpnpAddToActionResponse(
IN OUT IXML_Document ** ActionResponse, /*! [in,out] Pointer to a document to store the action document node. */
/** Pointer to a document to IXML_Document **ActionResponse,
store the action document /*! [in] The action name. */
node. */ const char *ActionName,
IN const char * ActionName, /** The action name. */ /*! [in] The service type. */
IN const char * ServType, /** The service type. */ const char *ServType,
IN const char * ArgName, /** The status variable name. */ /*! [in] The status variable name. */
IN const char * ArgVal /** The status variable value. */ const char *ArgName,
); /*! [in] The status variable value. */
const char *ArgVal);
/** {\bf UpnpAddToPropertySet} can be used when an application needs to
* transfer the status of many variables at once. It can be used /*!
* (inside a loop) to add some extra status variables into an existing * \brief Creates a property set message packet.
* property set. If the application does not already have a property
* set document, the application should create a variable initialized
* with {\tt NULL} and pass that as the first parameter.
*
* @return [int] An integer representing one of the following:
* \begin{itemize}
* \item {\tt UPNP_E_SUCCESS}: The operation completed successfully.
* \item {\tt UPNP_E_INVALID_PARAM}: One or more of the parameters
* are invalid.
* \item {\tt UPNP_E_OUTOF_MEMORY}: Insufficient resources exist to
* complete this operation.
* \end{itemize}
* *
* Any number of input parameters can be passed to this function but every
* input variable name should have a matching value input argument.
*
* \return <tt>NULL</tt> on failure, or the property-set document node.
*/ */
EXPORT_SPEC IXML_Document *UpnpCreatePropertySet(
/*! [in] The number of argument pairs passed. */
int NumArg,
/*! [in] The status variable name and value pair. */
const char *Arg,
/*! [in] Variable sized list with the rest of the parameters. */
...);
/*!
* \brief Can be used when an application needs to transfer the status of many
* variables at once.
*
* It can be used (inside a loop) to add some extra status variables into an
* existing property set. If the application does not already have a property
* set document, the application should create a variable initialized with
* <tt>NULL</tt> and pass that as the first parameter.
*
* \return An integer representing one of the following:
* \li <tt>UPNP_E_SUCCESS</tt>: The operation completed successfully.
* \li <tt>UPNP_E_INVALID_PARAM</tt>: One or more of the parameters are invalid.
* \li <tt>UPNP_E_OUTOF_MEMORY</tt>: Insufficient resources exist to
* complete this operation.
*/
EXPORT_SPEC int UpnpAddToPropertySet( EXPORT_SPEC int UpnpAddToPropertySet(
IN OUT IXML_Document **PropSet, /*! [in,out] A pointer to the document containing the property set document node. */
/** A pointer to the document containing IXML_Document **PropSet,
the property set document node. */ /*! [in] The status variable name. */
IN const char * ArgName, /** The status variable name. */ const char *ArgName,
IN const char * ArgVal /** The status variable value. */ /*! [in] The status variable value. */
); const char *ArgVal);
/** {\bf UpnpCreatePropertySet} creates a property set
* message packet. Any number of input parameters can be passed
* to this function but every input variable name should have
* a matching value input argument.
*
* @return [IXML_Document*] {\tt NULL} on failure, or the property-set
* document node.
*
*/
EXPORT_SPEC IXML_Document* UpnpCreatePropertySet(
IN int NumArg, /** The number of argument pairs passed. */
IN const char* Arg, /** The status variable name and value pair. */
IN ...
);
/** {\bf UpnpGetErrorMessage} converts an SDK error code into a
* string error message suitable for display. The memory returned
* from this function should NOT be freed.
*
* @return [char*] An ASCII text string representation of the error message
* associated with the error code.
*/
EXPORT_SPEC const char * UpnpGetErrorMessage(
int errorcode /** The SDK error code to convert. */
);
/*! @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/*! @} */
#endif /* UPNP_HAVE_TOOLS */ #endif /* UPNP_HAVE_TOOLS */
#endif /* UPNP_TOOLS_H */ #endif /* UPNP_TOOLS_H */

View File

@@ -43,7 +43,8 @@
#endif #endif
int initialize = 1; static int initialize_init = 1;
static int initialize_register = 1;
/*! Function pointers to use for displaying formatted strings. /*! Function pointers to use for displaying formatted strings.
* Set on Initialization of device. */ * Set on Initialization of device. */
@@ -67,7 +68,7 @@ ithread_mutex_t display_mutex;
******************************************************************************/ ******************************************************************************/
int SampleUtil_Initialize(print_string print_function) int SampleUtil_Initialize(print_string print_function)
{ {
if (initialize) { if (initialize_init) {
ithread_mutexattr_t attr; ithread_mutexattr_t attr;
ithread_mutexattr_init(&attr); ithread_mutexattr_init(&attr);
@@ -80,7 +81,7 @@ int SampleUtil_Initialize(print_string print_function)
gPrintFun = print_function; gPrintFun = print_function;
ithread_mutex_unlock(&display_mutex); ithread_mutex_unlock(&display_mutex);
initialize = 0; initialize_init = 0;
} else { } else {
SampleUtil_Print("***** SampleUtil_Initialize was called multiple times!\n"); SampleUtil_Print("***** SampleUtil_Initialize was called multiple times!\n");
abort(); abort();
@@ -99,12 +100,9 @@ int SampleUtil_Initialize(print_string print_function)
******************************************************************************/ ******************************************************************************/
int SampleUtil_RegisterUpdateFunction(state_update update_function) int SampleUtil_RegisterUpdateFunction(state_update update_function)
{ {
/* Intialize only once. */ if (initialize_register) {
static int initialize = 1;
if (initialize) {
gStateUpdateFun = update_function; gStateUpdateFun = update_function;
initialize = 0; initialize_register = 0;
} }
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
@@ -123,7 +121,9 @@ int SampleUtil_Finish()
{ {
ithread_mutex_destroy(&display_mutex); ithread_mutex_destroy(&display_mutex);
gPrintFun = NULL; gPrintFun = NULL;
initialize = 1; gStateUpdateFun = NULL;
initialize_init = 1;
initialize_register = 1;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
@@ -428,8 +428,9 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
{ {
ithread_mutex_lock(&display_mutex); ithread_mutex_lock(&display_mutex);
SampleUtil_Print("======================================================================\n"); SampleUtil_Print(
SampleUtil_Print("----------------------------------------------------------------------\n"); "======================================================================\n"
"----------------------------------------------------------------------\n");
SampleUtil_PrintEventType(EventType); SampleUtil_PrintEventType(EventType);
switch (EventType) { switch (EventType) {
/* SSDP */ /* SSDP */
@@ -467,7 +468,7 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
SampleUtil_Print("ServiceID = %s\n", a_event->ServiceID); SampleUtil_Print("ServiceID = %s\n", a_event->ServiceID);
if (a_event->ActionRequest) { if (a_event->ActionRequest) {
xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest); xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest);
if ( xmlbuff ) { if (xmlbuff) {
SampleUtil_Print("ActRequest = %s\n", xmlbuff); SampleUtil_Print("ActRequest = %s\n", xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
} }
@@ -541,6 +542,7 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
SampleUtil_Print("CurrentVal = %s\n", sv_event->CurrentVal); SampleUtil_Print("CurrentVal = %s\n", sv_event->CurrentVal);
break; break;
} }
/* GENA */ /* GENA */
case UPNP_EVENT_SUBSCRIPTION_REQUEST: { case UPNP_EVENT_SUBSCRIPTION_REQUEST: {
struct Upnp_Subscription_Request *sr_event = struct Upnp_Subscription_Request *sr_event =
@@ -585,7 +587,6 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
SampleUtil_Print("TimeOut = %d\n", es_event->TimeOut); SampleUtil_Print("TimeOut = %d\n", es_event->TimeOut);
break; break;
} }
case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_AUTORENEWAL_FAILED:
case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { case UPNP_EVENT_SUBSCRIPTION_EXPIRED: {
struct Upnp_Event_Subscribe *es_event = struct Upnp_Event_Subscribe *es_event =
@@ -599,8 +600,10 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
break; break;
} }
} }
SampleUtil_Print("----------------------------------------------------------------------\n"); SampleUtil_Print(
SampleUtil_Print("======================================================================\n"); "----------------------------------------------------------------------\n"
"======================================================================\n"
"\n\n\n");
ithread_mutex_unlock(&display_mutex); ithread_mutex_unlock(&display_mutex);

View File

@@ -1,51 +1,55 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef SAMPLE_UTIL_H #ifndef SAMPLE_UTIL_H
#define SAMPLE_UTIL_H #define SAMPLE_UTIL_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
#include <stdlib.h>
#include <string.h>
#include "ithread.h" #include "ithread.h"
#include "ixml.h" #include "ixml.h" /* for IXML_Document, IXML_Element */
#include "upnp.h" /* for Upnp_EventType */
#include "upnptools.h" #include "upnptools.h"
// mutex to control displaying of events #include <stdlib.h>
#include <string.h>
/* mutex to control displaying of events */
extern ithread_mutex_t display_mutex; extern ithread_mutex_t display_mutex;
@@ -166,7 +170,7 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType,
********************************************************************************/ ********************************************************************************/
int SampleUtil_FindAndParseService ( int SampleUtil_FindAndParseService (
IN IXML_Document *DescDoc, IN IXML_Document *DescDoc,
IN const char *location, IN const char* location,
IN char *serviceType, IN char *serviceType,
OUT char **serviceId, OUT char **serviceId,
OUT char **eventURL, OUT char **eventURL,

View File

@@ -29,9 +29,14 @@
* *
******************************************************************************/ ******************************************************************************/
#include "upnp_tv_ctrlpt.h" #include "upnp_tv_ctrlpt.h"
/*
#include "upnp.h"
/*!
Mutex for protecting the global device list Mutex for protecting the global device list
in a multi-threaded, asynchronous environment. in a multi-threaded, asynchronous environment.
All functions should lock this mutex before reading All functions should lock this mutex before reading
@@ -48,7 +53,7 @@ char *TvServiceType[] = {
}; };
char *TvServiceName[] = { "Control", "Picture" }; char *TvServiceName[] = { "Control", "Picture" };
/* /*!
Global arrays for storing variable names and counts for Global arrays for storing variable names and counts for
TvControl and TvPicture services TvControl and TvPicture services
*/ */
@@ -59,12 +64,12 @@ char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS] = {
char TvVarCount[TV_SERVICE_SERVCOUNT] = char TvVarCount[TV_SERVICE_SERVCOUNT] =
{ TV_CONTROL_VARCOUNT, TV_PICTURE_VARCOUNT }; { TV_CONTROL_VARCOUNT, TV_PICTURE_VARCOUNT };
/* /*!
Timeout to request during subscriptions Timeout to request during subscriptions
*/ */
int default_timeout = 1801; int default_timeout = 1801;
/* /*!
The first node in the global device list, or NULL if empty The first node in the global device list, or NULL if empty
*/ */
struct TvDeviceNode *GlobalDeviceList = NULL; struct TvDeviceNode *GlobalDeviceList = NULL;
@@ -937,7 +942,7 @@ TvStateUpdate( char *UDN,
* *
********************************************************************************/ ********************************************************************************/
void TvCtrlPointHandleEvent( void TvCtrlPointHandleEvent(
const Upnp_SID sid, const char *sid,
int evntkey, int evntkey,
IXML_Document *changes) IXML_Document *changes)
{ {
@@ -949,11 +954,11 @@ void TvCtrlPointHandleEvent(
tmpdevnode = GlobalDeviceList; tmpdevnode = GlobalDeviceList;
while (tmpdevnode) { while (tmpdevnode) {
for (service = 0; service < TV_SERVICE_SERVCOUNT; ++service) { for (service = 0; service < TV_SERVICE_SERVCOUNT; ++service) {
if(strcmp(tmpdevnode->device.TvService[service].SID, sid) == 0) { if (strcmp(tmpdevnode->device.TvService[service].SID, sid) == 0) {
SampleUtil_Print("Received Tv %s Event: %d for SID %s", SampleUtil_Print("Received Tv %s Event: %d for SID %s",
TvServiceName[service], TvServiceName[service],
evntkey, evntkey,
sid ); sid);
TvStateUpdate( TvStateUpdate(
tmpdevnode->device.UDN, tmpdevnode->device.UDN,
service, service,
@@ -1310,7 +1315,8 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print( SampleUtil_Print(
"Initializing UPnP Sdk with\n" "Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port); ip_address ? ip_address : "{NULL}",
port);
rc = UpnpInit(ip_address, port); rc = UpnpInit(ip_address, port);
if (rc != UPNP_E_SUCCESS) { if (rc != UPNP_E_SUCCESS) {
@@ -1329,8 +1335,9 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print( SampleUtil_Print(
"UPnP Initialized\n" "UPnP Initialized\n"
"\tipaddress= %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port); ip_address ? ip_address : "{NULL}",
port);
SampleUtil_Print("Registering Control Point"); SampleUtil_Print("Registering Control Point");
rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler, rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler,

View File

@@ -1,4 +1,4 @@
/******************************************************************************* /**************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
@@ -27,29 +27,40 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
******************************************************************************/ **************************************************************************/
#ifndef UPNP_TV_CTRLPT_H #ifndef UPNP_TV_CTRLPT_H
#define UPNP_TV_CTRLPT_H #define UPNP_TV_CTRLPT_H
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdio.h>
#include "sample_util.h"
#include "ithread.h" #include "ithread.h"
#ifndef WIN32 #include "upnp.h"
#include <unistd.h> #include "UpnpString.h"
#endif #include "upnptools.h"
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include "upnp.h"
#include "upnptools.h" #ifdef WIN32
#include "sample_util.h" /* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
#define TV_SERVICE_SERVCOUNT 2 #define TV_SERVICE_SERVCOUNT 2
#define TV_SERVICE_CONTROL 0 #define TV_SERVICE_CONTROL 0
@@ -68,12 +79,12 @@ extern "C" {
#define TV_MAX_VAL_LEN 5 #define TV_MAX_VAL_LEN 5
#define TV_SUCCESS 0 #define TV_SUCCESS 0
#define TV_ERROR (-1) #define TV_ERROR (-1)
#define TV_WARNING 1 #define TV_WARNING 1
/* This should be the maximum VARCOUNT from above */ /* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT #define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[]; extern char TvDeviceType[];
extern char *TvServiceType[]; extern char *TvServiceType[];
@@ -110,11 +121,11 @@ extern ithread_mutex_t DeviceListMutex;
extern UpnpClient_Handle ctrlpt_handle; extern UpnpClient_Handle ctrlpt_handle;
void TvCtrlPointPrintHelp( void ); void TvCtrlPointPrintHelp(void);
int TvCtrlPointDeleteNode(struct TvDeviceNode *); int TvCtrlPointDeleteNode(struct TvDeviceNode *);
int TvCtrlPointRemoveDevice(const char *); int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll( void ); int TvCtrlPointRemoveAll(void);
int TvCtrlPointRefresh( void ); int TvCtrlPointRefresh(void);
int TvCtrlPointSendAction(int, int, char *, char **, char **, int); int TvCtrlPointSendAction(int, int, char *, char **, char **, int);
@@ -138,20 +149,20 @@ int TvCtrlPointGetContrast(int);
int TvCtrlPointGetBrightness(int); int TvCtrlPointGetBrightness(int);
int TvCtrlPointGetDevice(int, struct TvDeviceNode **); int TvCtrlPointGetDevice(int, struct TvDeviceNode **);
int TvCtrlPointPrintList( void ); int TvCtrlPointPrintList(void);
int TvCtrlPointPrintDevice(int); int TvCtrlPointPrintDevice(int);
void TvCtrlPointAddDevice(IXML_Document *, const char *, int); void TvCtrlPointAddDevice(IXML_Document *, const char *, int);
void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString); void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString);
void TvStateUpdate(char*,int, IXML_Document * , char **); void TvStateUpdate(char*,int, IXML_Document * , char **);
void TvCtrlPointHandleEvent(const Upnp_SID, int, IXML_Document *); void TvCtrlPointHandleEvent(const char *, int, IXML_Document *);
void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int); void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int);
int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *); int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *);
void TvCtrlPointVerifyTimeouts(int); void TvCtrlPointVerifyTimeouts(int);
void TvCtrlPointPrintCommands( void ); void TvCtrlPointPrintCommands(void);
void* TvCtrlPointCommandLoop( void* ); void* TvCtrlPointCommandLoop(void *);
int TvCtrlPointStart( print_string printFunctionPtr, state_update updateFunctionPtr ); int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr);
int TvCtrlPointStop( void ); int TvCtrlPointStop(void);
int TvCtrlPointProcessCommand( char *cmdline ); int TvCtrlPointProcessCommand(char *cmdline);
#ifdef __cplusplus #ifdef __cplusplus
}; };

View File

@@ -371,23 +371,26 @@ TvDeviceStateTableInit( IN char *DescDocURL )
* sr_event -- The subscription request event structure * sr_event -- The subscription request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleSubscriptionRequest(IN struct Upnp_Subscription_Request *sr_event)
TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
*sr_event )
{ {
unsigned int i = 0; //,j=0; unsigned int i = 0;
int cmp1 = 0;
// IXML_Document *PropSet = NULL; int cmp2 = 0;
const char *l_serviceId = NULL;
const char *l_udn = NULL;
const char *l_sid = NULL;
// lock state mutex // lock state mutex
ithread_mutex_lock( &TVDevMutex ); ithread_mutex_lock(&TVDevMutex);
for( i = 0; i < TV_SERVICE_SERVCOUNT; i++ ) { l_serviceId = sr_event->ServiceId;
if( ( strcmp( sr_event->UDN, tv_service_table[i].UDN ) == 0 ) && l_udn = sr_event->UDN;
( strcmp( sr_event->ServiceId, tv_service_table[i].ServiceId ) l_sid = sr_event->Sid;
== 0 ) ) { for (i = 0; i < TV_SERVICE_SERVCOUNT; ++i) {
cmp1 = strcmp(l_udn, tv_service_table[i].UDN);
/* cmp2 = strcmp(l_serviceId, tv_service_table[i].ServiceId);
if (cmp1 == 0 && cmp2 == 0) {
#if 0
PropSet = NULL; PropSet = NULL;
for (j = 0; j< tv_service_table[i].VariableCount; ++j) { for (j = 0; j< tv_service_table[i].VariableCount; ++j) {
@@ -402,29 +405,27 @@ TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
// dump initial state // dump initial state
UpnpAcceptSubscriptionExt( UpnpAcceptSubscriptionExt(
device_handle, device_handle,
sr_event->UDN, l_udn,
sr_event->ServiceId, l_serviceId,
PropSet, PropSet,
sr_event->Sid); l_sid);
// free document // free document
Document_free(PropSet); Document_free(PropSet);
#endif
*/ UpnpAcceptSubscription(
device_handle,
UpnpAcceptSubscription( device_handle, l_udn,
sr_event->UDN, l_serviceId,
sr_event->ServiceId,
(const char **)tv_service_table[i]. (const char **)tv_service_table[i].
VariableName, VariableName,
(const char **)tv_service_table[i]. (const char **)tv_service_table[i].
VariableStrVal, VariableStrVal,
tv_service_table[i].VariableCount, tv_service_table[i].VariableCount,
sr_event->Sid); l_sid);
} }
} }
ithread_mutex_unlock( &TVDevMutex ); ithread_mutex_unlock(&TVDevMutex);
return 1; return 1;
} }
@@ -442,52 +443,52 @@ TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
* cgv_event -- The control get variable request event structure * cgv_event -- The control get variable request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleGetVarRequest(INOUT struct Upnp_State_Var_Request *cgv_event)
TvDeviceHandleGetVarRequest( INOUT struct Upnp_State_Var_Request
*cgv_event )
{ {
unsigned int i = 0; unsigned int i = 0;
unsigned int j = 0; unsigned int j = 0;
int getvar_succeeded = 0; int getvar_succeeded = 0;
cgv_event->CurrentVal = NULL; cgv_event->CurrentVal = NULL;
ithread_mutex_lock( &TVDevMutex ); ithread_mutex_lock(&TVDevMutex);
for( i = 0; i < TV_SERVICE_SERVCOUNT; i++ ) { for (i = 0; i < TV_SERVICE_SERVCOUNT; i++) {
// check udn and service id // check udn and service id
if( ( strcmp( cgv_event->DevUDN, tv_service_table[i].UDN ) == 0 ) const char *devUDN =
&& cgv_event->DevUDN;
( strcmp( cgv_event->ServiceID, tv_service_table[i].ServiceId ) const char *serviceID =
== 0 ) ) { cgv_event->ServiceID;
// check variable name if (strcmp(devUDN, tv_service_table[i].UDN) == 0 &&
for( j = 0; j < tv_service_table[i].VariableCount; j++ ) { strcmp(serviceID, tv_service_table[i].ServiceId) == 0) {
if( strcmp( cgv_event->StateVarName, // check variable name
tv_service_table[i].VariableName[j] ) == 0 ) { for (j = 0; j < tv_service_table[i].VariableCount; j++) {
getvar_succeeded = 1; const char *stateVarName =
cgv_event->CurrentVal = cgv_event->StateVarName;
ixmlCloneDOMString( tv_service_table[i]. if (strcmp(stateVarName,
VariableStrVal[j] ); tv_service_table[i].VariableName[j]) == 0) {
break; getvar_succeeded = 1;
} cgv_event->CurrentVal = ixmlCloneDOMString(
} tv_service_table[i].VariableStrVal[j]);
} break;
} }
}
}
}
if (getvar_succeeded) {
cgv_event->ErrCode = UPNP_E_SUCCESS;
} else {
SampleUtil_Print(
"Error in UPNP_CONTROL_GET_VAR_REQUEST callback:\n"
" Unknown variable name = %s\n",
cgv_event->StateVarName);
cgv_event->ErrCode = 404;
strcpy(cgv_event->ErrStr, "Invalid Variable");
}
if( getvar_succeeded ) { ithread_mutex_unlock(&TVDevMutex);
cgv_event->ErrCode = UPNP_E_SUCCESS;
} else {
SampleUtil_Print
( "Error in UPNP_CONTROL_GET_VAR_REQUEST callback:\n" );
SampleUtil_Print( " Unknown variable name = %s\n",
cgv_event->StateVarName );
cgv_event->ErrCode = 404;
strcpy( cgv_event->ErrStr, "Invalid Variable" );
}
ithread_mutex_unlock( &TVDevMutex ); return cgv_event->ErrCode == UPNP_E_SUCCESS;
return ( cgv_event->ErrCode == UPNP_E_SUCCESS );
} }
/****************************************************************************** /******************************************************************************
@@ -502,99 +503,79 @@ TvDeviceHandleGetVarRequest( INOUT struct Upnp_State_Var_Request
* ca_event -- The control action request event structure * ca_event -- The control action request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleActionRequest(INOUT struct Upnp_Action_Request *ca_event)
TvDeviceHandleActionRequest( INOUT struct Upnp_Action_Request *ca_event )
{ {
/* /* Defaults if action not found. */
Defaults if action not found int action_found = 0;
*/ int i = 0;
int action_found = 0; int service = -1;
int i = 0; int retCode = 0;
int service = -1; char *errorString = NULL;
int retCode = 0; const char *devUDN = NULL;
char *errorString = NULL; const char *serviceID = NULL;
const char *actionName = NULL;
ca_event->ErrCode = 0; ca_event->ErrCode = 0;
ca_event->ActionResult = NULL; ca_event->ActionResult = NULL;
if( ( strcmp( ca_event->DevUDN, devUDN = ca_event->DevUDN;
tv_service_table[TV_SERVICE_CONTROL].UDN ) == 0 ) && serviceID = ca_event->ServiceID;
( strcmp actionName = ca_event->ActionName;
( ca_event->ServiceID, if (strcmp(devUDN, tv_service_table[TV_SERVICE_CONTROL].UDN) == 0 &&
tv_service_table[TV_SERVICE_CONTROL].ServiceId ) == 0 ) ) { strcmp(serviceID, tv_service_table[TV_SERVICE_CONTROL].ServiceId) == 0) {
/* /* Request for action in the TvDevice Control Service. */
Request for action in the TvDevice Control Service service = TV_SERVICE_CONTROL;
*/ } else if (strcmp(devUDN, tv_service_table[TV_SERVICE_PICTURE].UDN) == 0 &&
service = TV_SERVICE_CONTROL; strcmp(serviceID, tv_service_table[TV_SERVICE_PICTURE].ServiceId) == 0) {
} else if( ( strcmp( ca_event->DevUDN, /* Request for action in the TvDevice Picture Service. */
tv_service_table[TV_SERVICE_PICTURE].UDN ) == 0 ) service = TV_SERVICE_PICTURE;
&& }
( strcmp /* Find and call appropriate procedure based on action name.
( ca_event->ServiceID, * Each action name has an associated procedure stored in the
tv_service_table[TV_SERVICE_PICTURE].ServiceId ) == * service table. These are set at initialization. */
0 ) ) { for (i = 0;
/* i < TV_MAXACTIONS && tv_service_table[service].ActionNames[i] != NULL;
Request for action in the TvDevice Picture Service i++) {
*/ if (!strcmp(actionName, tv_service_table[service].ActionNames[i])) {
service = TV_SERVICE_PICTURE; if (!strcmp(tv_service_table[TV_SERVICE_CONTROL].
} VariableStrVal[TV_CONTROL_POWER], "1") ||
//Find and call appropriate procedure based on action name !strcmp(actionName, "PowerOn")) {
//Each action name has an associated procedure stored in the retCode = tv_service_table[service].actions[i](
//service table. These are set at initialization. ca_event->ActionRequest,
&ca_event->ActionResult,
&errorString);
} else {
errorString = "Power is Off";
retCode = UPNP_E_INTERNAL_ERROR;
}
action_found = 1;
break;
}
}
for( i = 0; ( ( i < TV_MAXACTIONS ) && if (!action_found) {
( tv_service_table[service].ActionNames[i] != NULL ) ); ca_event->ActionResult = NULL;
i++ ) { strcpy(ca_event->ErrStr, "Invalid Action");
ca_event->ErrCode = 401;
} else {
if (retCode == UPNP_E_SUCCESS) {
ca_event->ErrCode = UPNP_E_SUCCESS;
} else {
// copy the error string
strcpy(ca_event->ErrStr, errorString);
switch (retCode) {
case UPNP_E_INVALID_PARAM:
ca_event->ErrCode = 402;
break;
case UPNP_E_INTERNAL_ERROR:
default:
ca_event->ErrCode = 501;
break;
}
}
}
if( !strcmp( ca_event->ActionName, return ca_event->ErrCode;
tv_service_table[service].ActionNames[i] ) ) {
if( ( !strcmp( tv_service_table[TV_SERVICE_CONTROL].
VariableStrVal[TV_CONTROL_POWER], "1" ) )
|| ( !strcmp( ca_event->ActionName, "PowerOn" ) ) ) {
retCode =
tv_service_table[service].actions[i] ( ca_event->
ActionRequest,
&ca_event->
ActionResult,
&errorString );
} else {
errorString = "Power is Off";
retCode = UPNP_E_INTERNAL_ERROR;
}
action_found = 1;
break;
}
}
if( !action_found ) {
ca_event->ActionResult = NULL;
strcpy( ca_event->ErrStr, "Invalid Action" );
ca_event->ErrCode = 401;
} else {
if( retCode == UPNP_E_SUCCESS ) {
ca_event->ErrCode = UPNP_E_SUCCESS;
} else {
// copy the error string
strcpy( ca_event->ErrStr, errorString );
switch ( retCode ) {
case UPNP_E_INVALID_PARAM:
{
ca_event->ErrCode = 402;
break;
}
case UPNP_E_INTERNAL_ERROR:
default:
{
ca_event->ErrCode = 501;
break;
}
}
}
}
return ( ca_event->ErrCode );
} }
/****************************************************************************** /******************************************************************************
@@ -1770,48 +1751,43 @@ TvDeviceDecreaseBrightness( IN IXML_Document *in, OUT IXML_Document **out, OUT c
*****************************************************************************/ *****************************************************************************/
int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie) int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie)
{ {
switch ( EventType ) { switch (EventType) {
case UPNP_EVENT_SUBSCRIPTION_REQUEST: case UPNP_EVENT_SUBSCRIPTION_REQUEST:
TvDeviceHandleSubscriptionRequest((struct Upnp_Subscription_Request *)Event);
break;
TvDeviceHandleSubscriptionRequest( ( struct case UPNP_CONTROL_GET_VAR_REQUEST:
Upnp_Subscription_Request TvDeviceHandleGetVarRequest((struct Upnp_State_Var_Request *)Event);
* )Event ); break;
break;
case UPNP_CONTROL_GET_VAR_REQUEST: case UPNP_CONTROL_ACTION_REQUEST:
TvDeviceHandleGetVarRequest( ( struct Upnp_State_Var_Request TvDeviceHandleActionRequest((struct Upnp_Action_Request *)Event);
* )Event ); break;
break;
case UPNP_CONTROL_ACTION_REQUEST: /*
TvDeviceHandleActionRequest( ( struct Upnp_Action_Request * ) ignore these cases, since this is not a control point
Event ); */
break; case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
case UPNP_DISCOVERY_SEARCH_RESULT:
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
case UPNP_CONTROL_ACTION_COMPLETE:
case UPNP_CONTROL_GET_VAR_COMPLETE:
case UPNP_EVENT_RECEIVED:
case UPNP_EVENT_RENEWAL_COMPLETE:
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
break;
/* default:
ignore these cases, since this is not a control point SampleUtil_Print("Error in TvDeviceCallbackEventHandler: unknown event type %d\n",
*/ EventType);
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: }
case UPNP_DISCOVERY_SEARCH_RESULT:
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
case UPNP_CONTROL_ACTION_COMPLETE:
case UPNP_CONTROL_GET_VAR_COMPLETE:
case UPNP_EVENT_RECEIVED:
case UPNP_EVENT_RENEWAL_COMPLETE:
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
break;
default: /* Print a summary of the event received */
SampleUtil_Print( "Error in TvDeviceCallbackEventHandler: unknown event type %d\n", SampleUtil_PrintEvent(EventType, Event);
EventType );
}
/* Print a summary of the event received */ return 0;
SampleUtil_PrintEvent( EventType, Event );
return 0;
} }
/****************************************************************************** /******************************************************************************
@@ -1823,8 +1799,7 @@ int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Co
* Parameters: * Parameters:
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceStop(void)
TvDeviceStop()
{ {
UpnpUnRegisterRootDevice( device_handle ); UpnpUnRegisterRootDevice( device_handle );
UpnpFinish(); UpnpFinish();
@@ -1872,7 +1847,8 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print( SampleUtil_Print(
"Initializing UPnP Sdk with\n" "Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port ); ip_address ? ip_address : "{NULL}",
port);
ret = UpnpInit( ip_address, port ); ret = UpnpInit( ip_address, port );
if( ret != UPNP_E_SUCCESS ) { if( ret != UPNP_E_SUCCESS ) {
@@ -1886,8 +1862,9 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print( SampleUtil_Print(
"UPnP Initialized\n" "UPnP Initialized\n"
"\tipaddress= %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port ); ip_address ? ip_address : "{NULL}",
port);
if( desc_doc_name == NULL ) { if( desc_doc_name == NULL ) {
desc_doc_name = "tvcombodesc.xml"; desc_doc_name = "tvcombodesc.xml";

View File

@@ -1,53 +1,66 @@
/////////////////////////////////////////////////////////////////////////// /**************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// **************************************************************************/
#ifndef UPNP_TV_DEVICE_H #ifndef UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H #define UPNP_TV_DEVICE_H
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "ithread.h"
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <string.h>
#include "upnp.h"
#include "sample_util.h" #include "sample_util.h"
#include "ithread.h"
#include "upnp.h"
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
//Color constants //Color constants
#define MAX_COLOR 10 #define MAX_COLOR 10
#define MIN_COLOR 1 #define MIN_COLOR 1
@@ -148,8 +161,7 @@ extern char *TvServiceType[];
* *
*****************************************************************************/ *****************************************************************************/
typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, char **errorString);
char **errorString);
/* Structure for storing Tv Service /* Structure for storing Tv Service
identifiers and state table */ identifiers and state table */
@@ -193,7 +205,7 @@ extern ithread_mutex_t TVDevMutex;
* struct TvService *out - service containing action table to set. * struct TvService *out - service containing action table to set.
* *
*****************************************************************************/ *****************************************************************************/
int SetActionTable(int serviceType, struct TvService * out); int SetActionTable(int serviceType, struct TvService *out);
/****************************************************************************** /******************************************************************************
* TvDeviceStateTableInit * TvDeviceStateTableInit
@@ -313,8 +325,7 @@ int TvDeviceSetServiceTableVar(unsigned int, unsigned int, char*);
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDevicePowerOff * TvDevicePowerOff
@@ -329,8 +340,7 @@ int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetChannel * TvDeviceSetChannel
@@ -347,8 +357,7 @@ int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseChannel * TvDeviceIncreaseChannel
@@ -363,8 +372,7 @@ int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseChannel * TvDeviceDecreaseChannel
* *
@@ -378,8 +386,7 @@ int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetVolume * TvDeviceSetVolume
* *
@@ -395,8 +402,7 @@ int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseVolume * TvDeviceIncreaseVolume
@@ -411,8 +417,7 @@ int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document**out, int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
@@ -428,8 +433,7 @@ int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document**out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document**out, int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
//Picture Service Actions //Picture Service Actions
@@ -449,8 +453,7 @@ int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document**out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
@@ -465,8 +468,7 @@ int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseColor * TvDeviceDecreaseColor
@@ -480,8 +482,7 @@ int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetTint * TvDeviceSetTint
@@ -498,8 +499,7 @@ int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseTint * TvDeviceIncreaseTint
@@ -514,8 +514,7 @@ int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseTint * TvDeviceDecreaseTint
@@ -530,8 +529,7 @@ int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/***************************************************************************** /*****************************************************************************
* TvDeviceSetContrast * TvDeviceSetContrast
@@ -548,8 +546,7 @@ int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
****************************************************************************/ ****************************************************************************/
int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseContrast * TvDeviceIncreaseContrast
@@ -565,8 +562,7 @@ int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseContrast * TvDeviceDecreaseContrast
* *
@@ -580,8 +576,7 @@ int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetBrightness * TvDeviceSetBrightness
@@ -595,8 +590,7 @@ int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out,
* brightness -- The brightness value to change to. * brightness -- The brightness value to change to.
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseBrightness * TvDeviceIncreaseBrightness
@@ -611,8 +605,7 @@ int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseBrightness * TvDeviceDecreaseBrightness
@@ -626,12 +619,11 @@ int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name, int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name,
char *web_dir_path, print_string pfun); char *web_dir_path, print_string pfun);
int TvDeviceStop(); int TvDeviceStop(void);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -143,8 +143,7 @@ TvCtrlPointDeleteNode( struct TvDeviceNode *node )
* UDN -- The Unique Device Name for the device to remove * UDN -- The Unique Device Name for the device to remove
* *
********************************************************************************/ ********************************************************************************/
int int TvCtrlPointRemoveDevice(const char *UDN)
TvCtrlPointRemoveDevice(const char *UDN)
{ {
struct TvDeviceNode *curdevnode; struct TvDeviceNode *curdevnode;
struct TvDeviceNode *prevdevnode; struct TvDeviceNode *prevdevnode;
@@ -943,7 +942,7 @@ TvStateUpdate( char *UDN,
* *
********************************************************************************/ ********************************************************************************/
void TvCtrlPointHandleEvent( void TvCtrlPointHandleEvent(
const Upnp_SID sid, const char *sid,
int evntkey, int evntkey,
IXML_Document *changes) IXML_Document *changes)
{ {
@@ -955,7 +954,7 @@ void TvCtrlPointHandleEvent(
tmpdevnode = GlobalDeviceList; tmpdevnode = GlobalDeviceList;
while (tmpdevnode) { while (tmpdevnode) {
for (service = 0; service < TV_SERVICE_SERVCOUNT; ++service) { for (service = 0; service < TV_SERVICE_SERVCOUNT; ++service) {
if (strcmp(tmpdevnode->device.TvService[service].SID, sid) == 0) { if (strcmp(tmpdevnode->device.TvService[service].SID, sid) == 0) {
SampleUtil_Print("Received Tv %s Event: %d for SID %s", SampleUtil_Print("Received Tv %s Event: %d for SID %s",
TvServiceName[service], TvServiceName[service],
evntkey, evntkey,
@@ -1019,10 +1018,10 @@ void TvCtrlPointHandleSubscribeUpdate(
ithread_mutex_unlock( &DeviceListMutex ); ithread_mutex_unlock( &DeviceListMutex );
} }
void void TvCtrlPointHandleGetVar(
TvCtrlPointHandleGetVar( const char *controlURL, const char *controlURL,
const char *varName, const char *varName,
const DOMString varValue ) const DOMString varValue)
{ {
struct TvDeviceNode *tmpdevnode; struct TvDeviceNode *tmpdevnode;
@@ -1033,9 +1032,9 @@ TvCtrlPointHandleGetVar( const char *controlURL,
tmpdevnode = GlobalDeviceList; tmpdevnode = GlobalDeviceList;
while (tmpdevnode) { while (tmpdevnode) {
for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) { for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) {
if (strcmp(tmpdevnode->device.TvService[service].ControlURL, controlURL ) == 0 ) { if (strcmp(tmpdevnode->device.TvService[service].ControlURL, controlURL) == 0) {
SampleUtil_StateUpdate( SampleUtil_StateUpdate(
varName, varValue, tmpdevnode->device.UDN, GET_VAR_COMPLETE ); varName, varValue, tmpdevnode->device.UDN, GET_VAR_COMPLETE);
break; break;
} }
} }
@@ -1076,29 +1075,24 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
SampleUtil_Print( SampleUtil_Print(
"Error in Discovery Callback -- %d", d_event->ErrCode); "Error in Discovery Callback -- %d", d_event->ErrCode);
} }
ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc); ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc);
if (ret != UPNP_E_SUCCESS) { if (ret != UPNP_E_SUCCESS) {
SampleUtil_Print( SampleUtil_Print(
"Error obtaining device description from %s -- error = %d", "Error obtaining device description from %s -- error = %d",
d_event->Location, ret ); d_event->Location, ret);
} else { } else {
TvCtrlPointAddDevice( TvCtrlPointAddDevice(
DescDoc, d_event->Location, d_event->Expires); DescDoc, d_event->Location, d_event->Expires);
} }
if (DescDoc) {
if( DescDoc ) {
ixmlDocument_free(DescDoc); ixmlDocument_free(DescDoc);
} }
TvCtrlPointPrintList(); TvCtrlPointPrintList();
break; break;
} }
case UPNP_DISCOVERY_SEARCH_TIMEOUT: case UPNP_DISCOVERY_SEARCH_TIMEOUT:
/* Nothing to do here... */ /* Nothing to do here... */
break; break;
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: { case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: {
struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event; struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event;
@@ -1106,13 +1100,10 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
SampleUtil_Print( SampleUtil_Print(
"Error in Discovery ByeBye Callback -- %d", d_event->ErrCode); "Error in Discovery ByeBye Callback -- %d", d_event->ErrCode);
} }
SampleUtil_Print("Received ByeBye for Device: %s", d_event->DeviceId); SampleUtil_Print("Received ByeBye for Device: %s", d_event->DeviceId);
TvCtrlPointRemoveDevice(d_event->DeviceId); TvCtrlPointRemoveDevice(d_event->DeviceId);
SampleUtil_Print("After byebye:"); SampleUtil_Print("After byebye:");
TvCtrlPointPrintList(); TvCtrlPointPrintList();
break; break;
} }
/* SOAP Stuff */ /* SOAP Stuff */
@@ -1121,13 +1112,10 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
if (a_event->ErrCode != UPNP_E_SUCCESS) { if (a_event->ErrCode != UPNP_E_SUCCESS) {
SampleUtil_Print( SampleUtil_Print(
"Error in Action Complete Callback -- %d", "Error in Action Complete Callback -- %d", a_event->ErrCode);
a_event->ErrCode);
} }
/* No need for any processing here, just print out results. /* No need for any processing here, just print out results.
* Service state table updates are handled by events. */ * Service state table updates are handled by events. */
break; break;
} }
case UPNP_CONTROL_GET_VAR_COMPLETE: { case UPNP_CONTROL_GET_VAR_COMPLETE: {
@@ -1135,8 +1123,7 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
if (sv_event->ErrCode != UPNP_E_SUCCESS) { if (sv_event->ErrCode != UPNP_E_SUCCESS) {
SampleUtil_Print( SampleUtil_Print(
"Error in Get Var Complete Callback -- %d", "Error in Get Var Complete Callback -- %d", sv_event->ErrCode);
sv_event->ErrCode);
} else { } else {
TvCtrlPointHandleGetVar( TvCtrlPointHandleGetVar(
sv_event->CtrlUrl, sv_event->CtrlUrl,
@@ -1162,15 +1149,13 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
if (es_event->ErrCode != UPNP_E_SUCCESS) { if (es_event->ErrCode != UPNP_E_SUCCESS) {
SampleUtil_Print( SampleUtil_Print(
"Error in Event Subscribe Callback -- %d", "Error in Event Subscribe Callback -- %d", es_event->ErrCode);
es_event->ErrCode);
} else { } else {
TvCtrlPointHandleSubscribeUpdate( TvCtrlPointHandleSubscribeUpdate(
es_event->PublisherUrl, es_event->PublisherUrl,
es_event->Sid, es_event->Sid,
es_event->TimeOut); es_event->TimeOut);
} }
break; break;
} }
case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_AUTORENEWAL_FAILED:
@@ -1185,7 +1170,6 @@ int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void
es_event->PublisherUrl, es_event->PublisherUrl,
&TimeOut, &TimeOut,
newSID); newSID);
if (ret == UPNP_E_SUCCESS) { if (ret == UPNP_E_SUCCESS) {
SampleUtil_Print("Subscribed to EventURL with SID=%s", newSID); SampleUtil_Print("Subscribed to EventURL with SID=%s", newSID);
TvCtrlPointHandleSubscribeUpdate( TvCtrlPointHandleSubscribeUpdate(
@@ -1331,7 +1315,8 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print( SampleUtil_Print(
"Initializing UPnP Sdk with\n" "Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port); ip_address ? ip_address : "{NULL}",
port);
rc = UpnpInit(ip_address, port); rc = UpnpInit(ip_address, port);
if (rc != UPNP_E_SUCCESS) { if (rc != UPNP_E_SUCCESS) {
@@ -1348,8 +1333,9 @@ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionP
SampleUtil_Print( SampleUtil_Print(
"UPnP Initialized\n" "UPnP Initialized\n"
"\tipaddress= %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port); ip_address ? ip_address : "{NULL}",
port);
SampleUtil_Print("Registering Control Point"); SampleUtil_Print("Registering Control Point");
rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler, rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler,

View File

@@ -44,6 +44,7 @@ extern "C" {
#include "ithread.h" #include "ithread.h"
#include "upnp.h" #include "upnp.h"
#include "UpnpString.h"
#include "upnptools.h" #include "upnptools.h"
@@ -120,8 +121,8 @@ extern ithread_mutex_t DeviceListMutex;
extern UpnpClient_Handle ctrlpt_handle; extern UpnpClient_Handle ctrlpt_handle;
void TvCtrlPointPrintHelp(void); void TvCtrlPointPrintHelp(void);
int TvCtrlPointDeleteNode(struct TvDeviceNode*); int TvCtrlPointDeleteNode(struct TvDeviceNode *);
int TvCtrlPointRemoveDevice(const char *); int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll(void); int TvCtrlPointRemoveAll(void);
int TvCtrlPointRefresh(void); int TvCtrlPointRefresh(void);
@@ -148,20 +149,20 @@ int TvCtrlPointGetContrast(int);
int TvCtrlPointGetBrightness(int); int TvCtrlPointGetBrightness(int);
int TvCtrlPointGetDevice(int, struct TvDeviceNode **); int TvCtrlPointGetDevice(int, struct TvDeviceNode **);
int TvCtrlPointPrintList( void ); int TvCtrlPointPrintList(void);
int TvCtrlPointPrintDevice(int); int TvCtrlPointPrintDevice(int);
void TvCtrlPointAddDevice(IXML_Document *, const char *, int); void TvCtrlPointAddDevice(IXML_Document *, const char *, int);
void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString); void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString);
void TvStateUpdate(char*,int, IXML_Document * , char **); void TvStateUpdate(char*,int, IXML_Document * , char **);
void TvCtrlPointHandleEvent(const Upnp_SID, int, IXML_Document *); void TvCtrlPointHandleEvent(const char *, int, IXML_Document *);
void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int); void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int);
int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *); int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *);
void TvCtrlPointVerifyTimeouts(int); void TvCtrlPointVerifyTimeouts(int);
void TvCtrlPointPrintCommands( void ); void TvCtrlPointPrintCommands(void);
void* TvCtrlPointCommandLoop( void* ); void* TvCtrlPointCommandLoop(void *);
int TvCtrlPointStart( print_string printFunctionPtr, state_update updateFunctionPtr ); int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr);
int TvCtrlPointStop( void ); int TvCtrlPointStop(void);
int TvCtrlPointProcessCommand( char *cmdline ); int TvCtrlPointProcessCommand(char *cmdline);
#ifdef __cplusplus #ifdef __cplusplus
}; };

View File

@@ -373,23 +373,26 @@ TvDeviceStateTableInit( IN char *DescDocURL )
* sr_event -- The subscription request event structure * sr_event -- The subscription request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleSubscriptionRequest(IN struct Upnp_Subscription_Request *sr_event)
TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
*sr_event )
{ {
unsigned int i = 0; //,j=0; unsigned int i = 0;
int cmp1 = 0;
// IXML_Document *PropSet = NULL; int cmp2 = 0;
const char *l_serviceId = NULL;
const char *l_udn = NULL;
const char *l_sid = NULL;
// lock state mutex // lock state mutex
ithread_mutex_lock( &TVDevMutex ); ithread_mutex_lock(&TVDevMutex);
for( i = 0; i < TV_SERVICE_SERVCOUNT; i++ ) { l_serviceId = sr_event->ServiceId;
if( ( strcmp( sr_event->UDN, tv_service_table[i].UDN ) == 0 ) && l_udn = sr_event->UDN;
( strcmp( sr_event->ServiceId, tv_service_table[i].ServiceId ) l_sid = sr_event->Sid;
== 0 ) ) { for (i = 0; i < TV_SERVICE_SERVCOUNT; ++i) {
cmp1 = strcmp(l_udn, tv_service_table[i].UDN);
/* cmp2 = strcmp(l_serviceId, tv_service_table[i].ServiceId);
if (cmp1 == 0 && cmp2 == 0) {
#if 0
PropSet = NULL; PropSet = NULL;
for (j = 0; j< tv_service_table[i].VariableCount; ++j) { for (j = 0; j< tv_service_table[i].VariableCount; ++j) {
@@ -404,29 +407,27 @@ TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
// dump initial state // dump initial state
UpnpAcceptSubscriptionExt( UpnpAcceptSubscriptionExt(
device_handle, device_handle,
sr_event->UDN, l_udn,
sr_event->ServiceId, l_serviceId,
PropSet, PropSet,
sr_event->Sid); l_sid);
// free document // free document
Document_free(PropSet); Document_free(PropSet);
#endif
*/ UpnpAcceptSubscription(
device_handle,
UpnpAcceptSubscription( device_handle, l_udn,
sr_event->UDN, l_serviceId,
sr_event->ServiceId,
(const char **)tv_service_table[i]. (const char **)tv_service_table[i].
VariableName, VariableName,
(const char **)tv_service_table[i]. (const char **)tv_service_table[i].
VariableStrVal, VariableStrVal,
tv_service_table[i].VariableCount, tv_service_table[i].VariableCount,
sr_event->Sid); l_sid);
} }
} }
ithread_mutex_unlock( &TVDevMutex ); ithread_mutex_unlock(&TVDevMutex);
return 1; return 1;
} }
@@ -444,52 +445,52 @@ TvDeviceHandleSubscriptionRequest( IN struct Upnp_Subscription_Request
* cgv_event -- The control get variable request event structure * cgv_event -- The control get variable request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleGetVarRequest(INOUT struct Upnp_State_Var_Request *cgv_event)
TvDeviceHandleGetVarRequest( INOUT struct Upnp_State_Var_Request
*cgv_event )
{ {
unsigned int i = 0; unsigned int i = 0;
unsigned int j = 0; unsigned int j = 0;
int getvar_succeeded = 0; int getvar_succeeded = 0;
cgv_event->CurrentVal = NULL; cgv_event->CurrentVal = NULL;
ithread_mutex_lock( &TVDevMutex ); ithread_mutex_lock(&TVDevMutex);
for( i = 0; i < TV_SERVICE_SERVCOUNT; i++ ) { for (i = 0; i < TV_SERVICE_SERVCOUNT; i++) {
// check udn and service id // check udn and service id
if( ( strcmp( cgv_event->DevUDN, tv_service_table[i].UDN ) == 0 ) const char *devUDN =
&& cgv_event->DevUDN;
( strcmp( cgv_event->ServiceID, tv_service_table[i].ServiceId ) const char *serviceID =
== 0 ) ) { cgv_event->ServiceID;
// check variable name if (strcmp(devUDN, tv_service_table[i].UDN) == 0 &&
for( j = 0; j < tv_service_table[i].VariableCount; j++ ) { strcmp(serviceID, tv_service_table[i].ServiceId) == 0) {
if( strcmp( cgv_event->StateVarName, // check variable name
tv_service_table[i].VariableName[j] ) == 0 ) { for (j = 0; j < tv_service_table[i].VariableCount; j++) {
getvar_succeeded = 1; const char *stateVarName =
cgv_event->CurrentVal = cgv_event->StateVarName;
ixmlCloneDOMString( tv_service_table[i]. if (strcmp(stateVarName,
VariableStrVal[j] ); tv_service_table[i].VariableName[j]) == 0) {
break; getvar_succeeded = 1;
} cgv_event->CurrentVal = ixmlCloneDOMString(
} tv_service_table[i].VariableStrVal[j]);
} break;
} }
}
}
}
if (getvar_succeeded) {
cgv_event->ErrCode = UPNP_E_SUCCESS;
} else {
SampleUtil_Print(
"Error in UPNP_CONTROL_GET_VAR_REQUEST callback:\n"
" Unknown variable name = %s\n",
cgv_event->StateVarName);
cgv_event->ErrCode = 404;
strcpy(cgv_event->ErrStr, "Invalid Variable");
}
if( getvar_succeeded ) { ithread_mutex_unlock(&TVDevMutex);
cgv_event->ErrCode = UPNP_E_SUCCESS;
} else {
SampleUtil_Print
( "Error in UPNP_CONTROL_GET_VAR_REQUEST callback:\n" );
SampleUtil_Print( " Unknown variable name = %s\n",
cgv_event->StateVarName );
cgv_event->ErrCode = 404;
strcpy( cgv_event->ErrStr, "Invalid Variable" );
}
ithread_mutex_unlock( &TVDevMutex ); return cgv_event->ErrCode == UPNP_E_SUCCESS;
return ( cgv_event->ErrCode == UPNP_E_SUCCESS );
} }
/****************************************************************************** /******************************************************************************
@@ -504,99 +505,79 @@ TvDeviceHandleGetVarRequest( INOUT struct Upnp_State_Var_Request
* ca_event -- The control action request event structure * ca_event -- The control action request event structure
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceHandleActionRequest(INOUT struct Upnp_Action_Request *ca_event)
TvDeviceHandleActionRequest( INOUT struct Upnp_Action_Request *ca_event )
{ {
/* /* Defaults if action not found. */
Defaults if action not found int action_found = 0;
*/ int i = 0;
int action_found = 0; int service = -1;
int i = 0; int retCode = 0;
int service = -1; char *errorString = NULL;
int retCode = 0; const char *devUDN = NULL;
char *errorString = NULL; const char *serviceID = NULL;
const char *actionName = NULL;
ca_event->ErrCode = 0; ca_event->ErrCode = 0;
ca_event->ActionResult = NULL; ca_event->ActionResult = NULL;
if( ( strcmp( ca_event->DevUDN, devUDN = ca_event->DevUDN;
tv_service_table[TV_SERVICE_CONTROL].UDN ) == 0 ) && serviceID = ca_event->ServiceID;
( strcmp actionName = ca_event->ActionName;
( ca_event->ServiceID, if (strcmp(devUDN, tv_service_table[TV_SERVICE_CONTROL].UDN) == 0 &&
tv_service_table[TV_SERVICE_CONTROL].ServiceId ) == 0 ) ) { strcmp(serviceID, tv_service_table[TV_SERVICE_CONTROL].ServiceId) == 0) {
/* /* Request for action in the TvDevice Control Service. */
Request for action in the TvDevice Control Service service = TV_SERVICE_CONTROL;
*/ } else if (strcmp(devUDN, tv_service_table[TV_SERVICE_PICTURE].UDN) == 0 &&
service = TV_SERVICE_CONTROL; strcmp(serviceID, tv_service_table[TV_SERVICE_PICTURE].ServiceId) == 0) {
} else if( ( strcmp( ca_event->DevUDN, /* Request for action in the TvDevice Picture Service. */
tv_service_table[TV_SERVICE_PICTURE].UDN ) == 0 ) service = TV_SERVICE_PICTURE;
&& }
( strcmp /* Find and call appropriate procedure based on action name.
( ca_event->ServiceID, * Each action name has an associated procedure stored in the
tv_service_table[TV_SERVICE_PICTURE].ServiceId ) == * service table. These are set at initialization. */
0 ) ) { for (i = 0;
/* i < TV_MAXACTIONS && tv_service_table[service].ActionNames[i] != NULL;
Request for action in the TvDevice Picture Service i++) {
*/ if (!strcmp(actionName, tv_service_table[service].ActionNames[i])) {
service = TV_SERVICE_PICTURE; if (!strcmp(tv_service_table[TV_SERVICE_CONTROL].
} VariableStrVal[TV_CONTROL_POWER], "1") ||
//Find and call appropriate procedure based on action name !strcmp(actionName, "PowerOn")) {
//Each action name has an associated procedure stored in the retCode = tv_service_table[service].actions[i](
//service table. These are set at initialization. ca_event->ActionRequest,
&ca_event->ActionResult,
&errorString);
} else {
errorString = "Power is Off";
retCode = UPNP_E_INTERNAL_ERROR;
}
action_found = 1;
break;
}
}
for( i = 0; ( ( i < TV_MAXACTIONS ) && if (!action_found) {
( tv_service_table[service].ActionNames[i] != NULL ) ); ca_event->ActionResult = NULL;
i++ ) { strcpy(ca_event->ErrStr, "Invalid Action");
ca_event->ErrCode = 401;
} else {
if (retCode == UPNP_E_SUCCESS) {
ca_event->ErrCode = UPNP_E_SUCCESS;
} else {
// copy the error string
strcpy(ca_event->ErrStr, errorString);
switch (retCode) {
case UPNP_E_INVALID_PARAM:
ca_event->ErrCode = 402;
break;
case UPNP_E_INTERNAL_ERROR:
default:
ca_event->ErrCode = 501;
break;
}
}
}
if( !strcmp( ca_event->ActionName, return ca_event->ErrCode;
tv_service_table[service].ActionNames[i] ) ) {
if( ( !strcmp( tv_service_table[TV_SERVICE_CONTROL].
VariableStrVal[TV_CONTROL_POWER], "1" ) )
|| ( !strcmp( ca_event->ActionName, "PowerOn" ) ) ) {
retCode =
tv_service_table[service].actions[i] ( ca_event->
ActionRequest,
&ca_event->
ActionResult,
&errorString );
} else {
errorString = "Power is Off";
retCode = UPNP_E_INTERNAL_ERROR;
}
action_found = 1;
break;
}
}
if( !action_found ) {
ca_event->ActionResult = NULL;
strcpy( ca_event->ErrStr, "Invalid Action" );
ca_event->ErrCode = 401;
} else {
if( retCode == UPNP_E_SUCCESS ) {
ca_event->ErrCode = UPNP_E_SUCCESS;
} else {
// copy the error string
strcpy( ca_event->ErrStr, errorString );
switch ( retCode ) {
case UPNP_E_INVALID_PARAM:
{
ca_event->ErrCode = 402;
break;
}
case UPNP_E_INTERNAL_ERROR:
default:
{
ca_event->ErrCode = 501;
break;
}
}
}
}
return ( ca_event->ErrCode );
} }
/****************************************************************************** /******************************************************************************
@@ -1772,48 +1753,43 @@ TvDeviceDecreaseBrightness( IN IXML_Document *in, OUT IXML_Document **out, OUT c
*****************************************************************************/ *****************************************************************************/
int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie) int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie)
{ {
switch ( EventType ) { switch (EventType) {
case UPNP_EVENT_SUBSCRIPTION_REQUEST: case UPNP_EVENT_SUBSCRIPTION_REQUEST:
TvDeviceHandleSubscriptionRequest((struct Upnp_Subscription_Request *)Event);
break;
TvDeviceHandleSubscriptionRequest( ( struct case UPNP_CONTROL_GET_VAR_REQUEST:
Upnp_Subscription_Request TvDeviceHandleGetVarRequest((struct Upnp_State_Var_Request *)Event);
* )Event ); break;
break;
case UPNP_CONTROL_GET_VAR_REQUEST: case UPNP_CONTROL_ACTION_REQUEST:
TvDeviceHandleGetVarRequest( ( struct Upnp_State_Var_Request TvDeviceHandleActionRequest((struct Upnp_Action_Request *)Event);
* )Event ); break;
break;
case UPNP_CONTROL_ACTION_REQUEST: /*
TvDeviceHandleActionRequest( ( struct Upnp_Action_Request * ) ignore these cases, since this is not a control point
Event ); */
break; case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
case UPNP_DISCOVERY_SEARCH_RESULT:
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
case UPNP_CONTROL_ACTION_COMPLETE:
case UPNP_CONTROL_GET_VAR_COMPLETE:
case UPNP_EVENT_RECEIVED:
case UPNP_EVENT_RENEWAL_COMPLETE:
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
break;
/* default:
ignore these cases, since this is not a control point SampleUtil_Print("Error in TvDeviceCallbackEventHandler: unknown event type %d\n",
*/ EventType);
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: }
case UPNP_DISCOVERY_SEARCH_RESULT:
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
case UPNP_CONTROL_ACTION_COMPLETE:
case UPNP_CONTROL_GET_VAR_COMPLETE:
case UPNP_EVENT_RECEIVED:
case UPNP_EVENT_RENEWAL_COMPLETE:
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
break;
default: /* Print a summary of the event received */
SampleUtil_Print( "Error in TvDeviceCallbackEventHandler: unknown event type %d\n", SampleUtil_PrintEvent(EventType, Event);
EventType );
}
/* Print a summary of the event received */ return 0;
SampleUtil_PrintEvent( EventType, Event );
return 0;
} }
/****************************************************************************** /******************************************************************************
@@ -1825,8 +1801,7 @@ int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Co
* Parameters: * Parameters:
* *
*****************************************************************************/ *****************************************************************************/
int int TvDeviceStop(void)
TvDeviceStop(void)
{ {
UpnpUnRegisterRootDevice( device_handle ); UpnpUnRegisterRootDevice( device_handle );
UpnpFinish(); UpnpFinish();
@@ -1874,7 +1849,8 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print( SampleUtil_Print(
"Initializing UPnP Sdk with\n" "Initializing UPnP Sdk with\n"
"\tipaddress = %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port ); ip_address ? ip_address : "{NULL}",
port);
ret = UpnpInit( ip_address, port ); ret = UpnpInit( ip_address, port );
if( ret != UPNP_E_SUCCESS ) { if( ret != UPNP_E_SUCCESS ) {
@@ -1888,8 +1864,9 @@ TvDeviceStart( char *ip_address,
SampleUtil_Print( SampleUtil_Print(
"UPnP Initialized\n" "UPnP Initialized\n"
"\tipaddress= %s port = %u\n", "\tipaddress = %s port = %u\n",
ip_address, port ); ip_address ? ip_address : "{NULL}",
port);
if( desc_doc_name == NULL ) { if( desc_doc_name == NULL ) {
desc_doc_name = "tvdevicedesc.xml"; desc_doc_name = "tvdevicedesc.xml";

View File

@@ -1,4 +1,4 @@
/******************************************************************************* /**************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
* All rights reserved. * All rights reserved.
@@ -27,28 +27,40 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
******************************************************************************/ **************************************************************************/
#ifndef UPNP_TV_DEVICE_H #ifndef UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H #define UPNP_TV_DEVICE_H
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "ithread.h"
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#endif
#include <string.h>
#include "upnp.h"
#include "sample_util.h" #include "sample_util.h"
#include "ithread.h"
#include "upnp.h"
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
//Color constants //Color constants
#define MAX_COLOR 10 #define MAX_COLOR 10
#define MIN_COLOR 1 #define MIN_COLOR 1
@@ -149,8 +161,7 @@ extern char *TvServiceType[];
* *
*****************************************************************************/ *****************************************************************************/
typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, char **errorString);
char **errorString);
/* Structure for storing Tv Service /* Structure for storing Tv Service
identifiers and state table */ identifiers and state table */
@@ -194,7 +205,7 @@ extern ithread_mutex_t TVDevMutex;
* struct TvService *out - service containing action table to set. * struct TvService *out - service containing action table to set.
* *
*****************************************************************************/ *****************************************************************************/
int SetActionTable(int serviceType, struct TvService * out); int SetActionTable(int serviceType, struct TvService *out);
/****************************************************************************** /******************************************************************************
* TvDeviceStateTableInit * TvDeviceStateTableInit
@@ -314,8 +325,7 @@ int TvDeviceSetServiceTableVar(unsigned int, unsigned int, char*);
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDevicePowerOff * TvDevicePowerOff
@@ -330,8 +340,7 @@ int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetChannel * TvDeviceSetChannel
@@ -348,8 +357,7 @@ int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseChannel * TvDeviceIncreaseChannel
@@ -364,8 +372,7 @@ int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseChannel * TvDeviceDecreaseChannel
* *
@@ -379,8 +386,7 @@ int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetVolume * TvDeviceSetVolume
* *
@@ -396,8 +402,7 @@ int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseVolume * TvDeviceIncreaseVolume
@@ -412,8 +417,7 @@ int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document**out, int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
@@ -429,8 +433,7 @@ int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document**out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document**out, int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
//Picture Service Actions //Picture Service Actions
@@ -450,8 +453,7 @@ int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document**out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
@@ -466,8 +468,7 @@ int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseColor * TvDeviceDecreaseColor
@@ -481,8 +482,7 @@ int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out,
* IXML_Document **out - action result document * IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetTint * TvDeviceSetTint
@@ -499,8 +499,7 @@ int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseTint * TvDeviceIncreaseTint
@@ -515,8 +514,7 @@ int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseTint * TvDeviceDecreaseTint
@@ -531,8 +529,7 @@ int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/***************************************************************************** /*****************************************************************************
* TvDeviceSetContrast * TvDeviceSetContrast
@@ -549,8 +546,7 @@ int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
****************************************************************************/ ****************************************************************************/
int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseContrast * TvDeviceIncreaseContrast
@@ -566,8 +562,7 @@ int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseContrast * TvDeviceDecreaseContrast
* *
@@ -581,8 +576,7 @@ int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceSetBrightness * TvDeviceSetBrightness
@@ -596,8 +590,7 @@ int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out,
* brightness -- The brightness value to change to. * brightness -- The brightness value to change to.
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceIncreaseBrightness * TvDeviceIncreaseBrightness
@@ -612,8 +605,7 @@ int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
/****************************************************************************** /******************************************************************************
* TvDeviceDecreaseBrightness * TvDeviceDecreaseBrightness
@@ -627,8 +619,7 @@ int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out,
* char **errorString - errorString (in case action was unsuccessful) * char **errorString - errorString (in case action was unsuccessful)
* *
*****************************************************************************/ *****************************************************************************/
int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
OUT char **errorString);
int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name, int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name,
char *web_dir_path, print_string pfun); char *web_dir_path, print_string pfun);

View File

@@ -28,6 +28,19 @@
#include <string.h> /* for strlen(), strdup() */ #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. * \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; 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) const char *UpnpString_get_String(const UpnpString *p)
{ {
return ((struct SUpnpString *)p)->m_string; 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); free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = strlen(s); ((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = strdup(s); ((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); free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = n; ((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = (char *)malloc(n+1); ((struct SUpnpString *)p)->m_string = q;
strncpy(((struct SUpnpString *)p)->m_string, s, n);
((struct SUpnpString *)p)->m_string[n] = 0; error_handler1:
return q != NULL;
} }
void UpnpString_clear(UpnpString *p) void UpnpString_clear(UpnpString *p)
{ {
((struct SUpnpString *)p)->m_length = 0; ((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; ((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 */ /* @} UpnpString */

View File

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

View File

@@ -149,7 +149,7 @@ void UpnpPrintf(
ithread_mutex_lock(&GlobalDebugMutex); ithread_mutex_lock(&GlobalDebugMutex);
va_start(ArgList, FmtStr); va_start(ArgList, FmtStr);
if (!DEBUG_TARGET) { if (!DEBUG_TARGET) {
if( DbgFileName ) { if (DbgFileName) {
UpnpDisplayFileAndLine(stdout, DbgFileName, DbgLineNo); UpnpDisplayFileAndLine(stdout, DbgFileName, DbgLineNo);
} }
vfprintf(stdout, FmtStr, ArgList); vfprintf(stdout, FmtStr, ArgList);
@@ -324,32 +324,5 @@ void PrintThreadPoolStats(
} }
void printNodes(IXML_Node *tmpRoot, int depth)
{
int i;
IXML_NodeList *NodeList1;
IXML_Node *ChildNode1;
unsigned short NodeType;
const DOMString NodeValue;
const DOMString NodeName;
NodeList1 = ixmlNode_getChildNodes(tmpRoot);
for (i = 0; i < 100; ++i) {
ChildNode1 = ixmlNodeList_item(NodeList1, i);
if (ChildNode1 == NULL) {
break;
}
printNodes(ChildNode1, depth+1);
NodeType = ixmlNode_getNodeType(ChildNode1);
NodeValue = ixmlNode_getNodeValue(ChildNode1);
NodeName = ixmlNode_getNodeName(ChildNode1);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"DEPTH-%2d-IXML_Node Type %d, "
"IXML_Node Name: %s, IXML_Node Value: %s\n",
depth, NodeType, NodeName, NodeValue);
}
}
#endif /* DEBUG */ #endif /* DEBUG */

View File

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

View File

@@ -178,70 +178,76 @@ static UPNP_INLINE int notify_send_and_recv(
/*! [out] The response from the control point. */ /*! [out] The response from the control point. */
http_parser_t *response) http_parser_t *response)
{ {
uri_type url; uri_type url;
int conn_fd; int conn_fd;
membuffer start_msg; membuffer start_msg;
int ret_code; int ret_code;
int err_code; int err_code;
int timeout; int timeout;
SOCKINFO info; SOCKINFO info;
// connect /* connect */
UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, GENA, __FILE__, __LINE__,
"gena notify to: %.*s\n", "gena notify to: %.*s\n",
(int)destination_url->hostport.text.size, (int)destination_url->hostport.text.size,
destination_url->hostport.text.buff ); destination_url->hostport.text.buff);
conn_fd = http_Connect( destination_url, &url ); conn_fd = http_Connect(destination_url, &url);
if( conn_fd < 0 ) { if (conn_fd < 0) {
return conn_fd; // return UPNP error /* return UPNP error */
}
if( ( ret_code = sock_init( &info, conn_fd ) ) != 0 ) { return conn_fd;
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;
}
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) return ret_code;
if( ( ret_code = http_SendMessage( &info, &timeout, }
"bb", /* make start line and HOST header */
start_msg.buf, start_msg.length, membuffer_init(&start_msg);
propertySet, if (http_MakeMessage(
strlen( propertySet ) + 1 ) ) != &start_msg, 1, 1,
0 ) { "q" "s",
membuffer_destroy( &start_msg ); HTTPMETHOD_NOTIFY, &url,
sock_destroy( &info, SD_BOTH ); mid_msg->buf) != 0) {
return ret_code; membuffer_destroy(&start_msg);
} sock_destroy(&info, SD_BOTH);
if( ( ret_code = http_RecvMessage( &info, response, return UPNP_E_OUTOF_MEMORY;
HTTPMETHOD_NOTIFY, &timeout, }
&err_code ) ) != 0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
httpmsg_destroy( &response->msg );
return ret_code;
}
sock_destroy( &info, SD_BOTH ); //should shutdown completely timeout = HTTP_DEFAULT_TIMEOUT;
//when closing socket
// sock_destroy( &info,SD_RECEIVE);
membuffer_destroy( &start_msg );
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; struct Handle_Info *handle_info;
ThreadPoolJob job; 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 //validate context
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) { if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
@@ -354,18 +365,27 @@ static void genaNotifyThread(
HandleUnlock(); HandleUnlock();
return; return;
} }
#ifdef UPNP_ENABLE_NOTIFICATION_REORDERING
//If the event is out of order push it back to the job queue //If the event is out of order push it back to the job queue
if( in->eventKey != sub->ToSendEventKey ) { if( in->eventKey != sub->ToSendEventKey ) {
TPJobInit( &job, ( start_routine ) genaNotifyThread, input ); TPJobInit( &job, ( start_routine ) genaNotifyThread, input );
TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct ); TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY ); 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 ); ThreadPoolAdd( &gSendThreadPool, &job, NULL );
freeSubscription( &sub_copy ); freeSubscription( &sub_copy );
HandleUnlock(); HandleUnlock();
return; return;
} }
#endif
HandleUnlock(); HandleUnlock();

File diff suppressed because it is too large Load Diff

View File

@@ -72,7 +72,6 @@ static str_int_entry Http_Method_Table[NUM_HTTP_METHODS] = {
{"SUBSCRIBE", HTTPMETHOD_SUBSCRIBE}, {"SUBSCRIBE", HTTPMETHOD_SUBSCRIBE},
{"UNSUBSCRIBE", HTTPMETHOD_UNSUBSCRIBE}, {"UNSUBSCRIBE", HTTPMETHOD_UNSUBSCRIBE},
{"POST", SOAPMETHOD_POST}, {"POST", SOAPMETHOD_POST},
}; };
#define NUM_HTTP_HEADER_NAMES 33 #define NUM_HTTP_HEADER_NAMES 33
@@ -113,9 +112,7 @@ str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES] = {
}; };
/***********************************************************************/ /***********************************************************************/
/************* scanner *************/ /************* scanner *************/
/***********************************************************************/ /***********************************************************************/
#define TOKCHAR_CR 0xD #define TOKCHAR_CR 0xD
@@ -134,13 +131,11 @@ str_int_entry Http_Header_Names[NUM_HTTP_HEADER_NAMES] = {
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE void static UPNP_INLINE void scanner_init(OUT scanner_t *scanner, IN membuffer *bufptr)
scanner_init( OUT scanner_t *scanner,
IN membuffer *bufptr )
{ {
scanner->cursor = 0; scanner->cursor = 0;
scanner->msg = bufptr; scanner->msg = bufptr;
scanner->entire_msg_loaded = FALSE; scanner->entire_msg_loaded = FALSE;
} }
/************************************************************************ /************************************************************************
@@ -155,10 +150,9 @@ scanner_init( OUT scanner_t *scanner,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE xboolean static UPNP_INLINE xboolean is_separator_char(IN char c)
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 : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE xboolean static UPNP_INLINE xboolean is_identifier_char(IN char c)
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 : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE xboolean static UPNP_INLINE xboolean is_control_char(IN char c)
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 : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE xboolean static UPNP_INLINE xboolean is_qdtext_char(IN char cc)
is_qdtext_char( IN char cc )
{ {
unsigned char c = ( unsigned char )cc; unsigned char c = ( unsigned char )cc;
@@ -244,10 +235,10 @@ is_qdtext_char( IN char cc )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static parse_status_t static parse_status_t scanner_get_token(
scanner_get_token( INOUT scanner_t * scanner, INOUT scanner_t *scanner,
OUT memptr * token, OUT memptr *token,
OUT token_type_t * tok_type ) OUT token_type_t *tok_type)
{ {
char *cursor; char *cursor;
char *null_terminator; // point to null-terminator in buffer char *null_terminator; // point to null-terminator in buffer
@@ -388,57 +379,11 @@ scanner_get_token( INOUT scanner_t * scanner,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE char * static UPNP_INLINE char *scanner_get_str(IN scanner_t * scanner)
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 * Function : httpmsg_compare
@@ -453,15 +398,14 @@ scanner_pushback( INOUT scanner_t * scanner,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static int static int httpmsg_compare(void *param1, void *param2)
httpmsg_compare( void *param1,
void *param2 )
{ {
assert( param1 != NULL ); assert( param1 != NULL );
assert( param2 != NULL ); assert( param2 != NULL );
return ( ( http_header_t * ) param1 )->name_id == return
( ( http_header_t * ) param2 )->name_id; ((http_header_t *)param1)->name_id ==
((http_header_t *)param2)->name_id;
} }
/************************************************************************ /************************************************************************
@@ -476,8 +420,7 @@ httpmsg_compare( void *param1,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static void static void httpheader_free(void *msg)
httpheader_free( void *msg )
{ {
http_header_t *hdr = ( http_header_t * ) msg; http_header_t *hdr = ( http_header_t * ) msg;
@@ -498,8 +441,7 @@ httpheader_free( void *msg )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
void void httpmsg_init(INOUT http_message_t *msg)
httpmsg_init( INOUT http_message_t * msg )
{ {
msg->initialized = 1; msg->initialized = 1;
msg->entity.buf = NULL; msg->entity.buf = NULL;
@@ -521,8 +463,7 @@ httpmsg_init( INOUT http_message_t * msg )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
void void httpmsg_destroy( INOUT http_message_t * msg )
httpmsg_destroy( INOUT http_message_t * msg )
{ {
assert( msg != NULL ); assert( msg != NULL );
@@ -550,9 +491,9 @@ httpmsg_destroy( INOUT http_message_t * msg )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
http_header_t * http_header_t *httpmsg_find_hdr_str(
httpmsg_find_hdr_str( IN http_message_t * msg, IN http_message_t *msg,
IN const char *header_name ) IN const char *header_name)
{ {
http_header_t *header; http_header_t *header;
@@ -587,27 +528,21 @@ httpmsg_find_hdr_str( IN http_message_t * msg,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
http_header_t * http_header_t *httpmsg_find_hdr(
httpmsg_find_hdr( IN http_message_t * msg, IN http_message_t *msg,
IN int header_name_id, IN int header_name_id,
OUT memptr * value ) OUT memptr *value)
{ {
http_header_t header; // temp header for searching http_header_t header; // temp header for searching
ListNode *node; ListNode *node;
http_header_t *data; http_header_t *data;
header.name_id = header_name_id; header.name_id = header_name_id;
node = ListFind( &msg->headers, NULL, &header ); node = ListFind( &msg->headers, NULL, &header );
if( node == NULL ) { if( node == NULL ) {
return NULL; return NULL;
} }
data = ( http_header_t * ) node->item; data = ( http_header_t * ) node->item;
if( value != NULL ) { if( value != NULL ) {
value->buf = data->value.buf; value->buf = data->value.buf;
value->length = data->value.length; value->length = data->value.length;
@@ -616,12 +551,6 @@ httpmsg_find_hdr( IN http_message_t * msg,
return data; return data;
} }
/***********************************************************************/
/************* http_parser_t **************/
/***********************************************************************/
/************************************************************************ /************************************************************************
* Function : skip_blank_lines * Function : skip_blank_lines
* *
@@ -634,26 +563,23 @@ httpmsg_find_hdr( IN http_message_t * msg,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE int static UPNP_INLINE int skip_blank_lines(INOUT scanner_t *scanner)
skip_blank_lines( INOUT scanner_t * scanner )
{ {
memptr token; memptr token;
token_type_t tok_type; token_type_t tok_type;
parse_status_t status; parse_status_t status;
// skip ws, crlf /* skip ws, crlf */
do { do {
status = scanner_get_token( scanner, &token, &tok_type ); status = scanner_get_token(scanner, &token, &tok_type);
} while( status == PARSE_OK && } while (status == PARSE_OK &&
( tok_type == TT_WHITESPACE || tok_type == TT_CRLF ) ); (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 ) { return status;
// pushback a non-whitespace token
scanner->cursor -= token.length;
//scanner_pushback( scanner, token.length );
}
return status;
} }
/************************************************************************ /************************************************************************
@@ -671,8 +597,7 @@ skip_blank_lines( INOUT scanner_t * scanner )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE int static UPNP_INLINE int skip_lws(INOUT scanner_t *scanner)
skip_lws( INOUT scanner_t * scanner )
{ {
memptr token; memptr token;
token_type_t tok_type; token_type_t tok_type;
@@ -726,9 +651,9 @@ skip_lws( INOUT scanner_t * scanner )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE parse_status_t static UPNP_INLINE parse_status_t match_non_ws_string(
match_non_ws_string( INOUT scanner_t * scanner, INOUT scanner_t *scanner,
OUT memptr * str ) OUT memptr *str)
{ {
memptr token; memptr token;
token_type_t tok_type; token_type_t tok_type;
@@ -792,9 +717,9 @@ match_non_ws_string( INOUT scanner_t * scanner,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE parse_status_t static UPNP_INLINE parse_status_t match_raw_value(
match_raw_value( INOUT scanner_t * scanner, INOUT scanner_t * scanner,
OUT memptr * raw_value ) OUT memptr *raw_value)
{ {
memptr token; memptr token;
token_type_t tok_type; token_type_t tok_type;
@@ -883,10 +808,10 @@ match_raw_value( INOUT scanner_t * scanner,
* PARSE_FAILURE -- bad input * PARSE_FAILURE -- bad input
* PARSE_INCOMPLETE * PARSE_INCOMPLETE
************************************************************************/ ************************************************************************/
static UPNP_INLINE int static UPNP_INLINE int match_int(
match_int( INOUT scanner_t * scanner, INOUT scanner_t *scanner,
IN int base, IN int base,
OUT int *value ) OUT int *value)
{ {
memptr token; memptr token;
token_type_t tok_type; token_type_t tok_type;
@@ -970,36 +895,6 @@ read_until_crlf( INOUT scanner_t * scanner,
return status; 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 * 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 * 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 ); assert( parser->ent_position == ENTREAD_USING_CLEN );
// determine entity (i.e. body) length so far // determine entity (i.e. body) length so far
//entity_length = parser->msg.msg.length - parser->entity_start_position;
parser->msg.entity.length = 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 ) { if( parser->msg.entity.length < parser->content_length ) {
// more data to be read // more data to be read
@@ -1919,7 +1680,8 @@ parser_parse_entity_using_clen( INOUT http_parser_t * parser )
} else { } else {
if( parser->msg.entity.length > parser->content_length ) { if( parser->msg.entity.length > parser->content_length ) {
// silently discard extra data // 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'; parser->content_length] = '\0';
} }
// save entity length // save entity length
@@ -2304,6 +2066,7 @@ parser_response_init( OUT http_parser_t * parser,
parser_init( parser ); parser_init( parser );
parser->msg.is_request = FALSE; parser->msg.is_request = FALSE;
parser->msg.request_method = request_method; parser->msg.request_method = request_method;
parser->msg.entity_offset = 0;
parser->position = POS_RESPONSE_LINE; parser->position = POS_RESPONSE_LINE;
} }
@@ -2399,10 +2162,6 @@ parser_append( INOUT http_parser_t * parser,
return parser_parse( parser ); return parser_parse( parser );
} }
/************************************************************************
********** end of parser ***********
************************************************************************/
/************************************************************************ /************************************************************************
* Function: raw_to_int * Function: raw_to_int
* *
@@ -2415,9 +2174,7 @@ parser_append( INOUT http_parser_t * parser,
* Returns: * Returns:
* int * int
************************************************************************/ ************************************************************************/
int int raw_to_int(IN memptr *raw_value, IN int base)
raw_to_int( IN memptr * raw_value,
IN int base )
{ {
long num; long num;
char *end_ptr; char *end_ptr;
@@ -2454,9 +2211,7 @@ raw_to_int( IN memptr * raw_value,
* Returns: * Returns:
* int - index at which the substring is found. * int - index at which the substring is found.
************************************************************************/ ************************************************************************/
int int raw_find_str(IN memptr *raw_value, IN const char *str)
raw_find_str( IN memptr *raw_value,
IN const char *str )
{ {
char c; char c;
char *ptr; char *ptr;
@@ -2499,8 +2254,7 @@ raw_find_str( IN memptr *raw_value,
* Returns: * Returns:
* const char* ptr - Ptr to the HTTP Method * const char* ptr - Ptr to the HTTP Method
************************************************************************/ ************************************************************************/
const char * const char *method_to_str(IN http_method_t method)
method_to_str( IN http_method_t method )
{ {
int index; int index;
@@ -2544,5 +2298,5 @@ void print_http_headers(http_message_t *hmsg)
/* NNS: node = dlist_next( &hmsg->headers, node ); */ /* NNS: node = dlist_next( &hmsg->headers, node ); */
} }
} }
#endif #endif /* DEBUG */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -29,304 +29,186 @@
* *
**************************************************************************/ **************************************************************************/
/*!
/************************************************************************ * \file
* Purpose: This file implements the sockets functionality *
************************************************************************/ * \brief Implements the sockets functionality.
*/
#include "config.h" #include "config.h"
#include "sock.h" #include "sock.h"
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
#include "upnp.h" #include "upnp.h"
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#ifndef MSG_NOSIGNAL #ifndef MSG_NOSIGNAL
#define MSG_NOSIGNAL 0 #define MSG_NOSIGNAL 0
#endif #endif
/************************************************************************ int sock_init(OUT SOCKINFO *info, IN SOCKET sockfd)
* Function : sock_init
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
* IN SOCKET sockfd ; Socket Descriptor
*
* Description : Assign the passed in socket descriptor to socket
* descriptor in the SOCKINFO structure.
*
* Return : int;
* UPNP_E_SUCCESS
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
*
* Note :
************************************************************************/
int
sock_init( OUT SOCKINFO * info,
IN SOCKET sockfd )
{ {
assert( info ); assert(info);
memset( info, 0, sizeof( SOCKINFO ) ); memset(info, 0, sizeof(SOCKINFO));
info->socket = sockfd;
info->socket = sockfd; return UPNP_E_SUCCESS;
return UPNP_E_SUCCESS;
} }
/************************************************************************ int sock_init_with_ip(OUT SOCKINFO *info, IN SOCKET sockfd,
* Function : sock_init_with_ip IN struct sockaddr *foreign_sockaddr)
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
* IN SOCKET sockfd ; Socket Descriptor
* IN struct sockaddr* foreign_sockaddr; remote socket address.
*
* Description : Calls the sock_init function and assigns the passed in
* IP address and port to the IP address and port in the SOCKINFO
* structure.
*
* Return : int;
* UPNP_E_SUCCESS
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
*
* Note :
************************************************************************/
int
sock_init_with_ip( OUT SOCKINFO * info,
IN SOCKET sockfd,
IN struct sockaddr* foreign_sockaddr )
{ {
int ret; int ret;
ret = sock_init( info, sockfd ); ret = sock_init(info, sockfd);
if( ret != UPNP_E_SUCCESS ) { if (ret != UPNP_E_SUCCESS) {
return ret; return ret;
} }
memcpy( &info->foreign_sockaddr, foreign_sockaddr, memcpy(&info->foreign_sockaddr, foreign_sockaddr,
sizeof( info->foreign_sockaddr) ); sizeof(info->foreign_sockaddr));
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/************************************************************************ int sock_destroy(INOUT SOCKINFO *info, int ShutdownMethod)
* Function : sock_destroy
*
* Parameters :
* INOUT SOCKINFO* info ; Socket Information Object
* int ShutdownMethod ; How to shutdown the socket. Used by
* sockets's shutdown()
*
* Description : Shutsdown the socket using the ShutdownMethod to
* indicate whether sends and receives on the socket will be
* dis-allowed. After shutting down the socket, closesocket is called
* to release system resources used by the socket calls.
*
* Return : int;
* UPNP_E_SOCKET_ERROR on failure
* UPNP_E_SUCCESS on success
*
* Note :
************************************************************************/
int
sock_destroy( INOUT SOCKINFO * info,
int ShutdownMethod )
{ {
if( info->socket != INVALID_SOCKET ) { int ret = UPNP_E_SUCCESS;
shutdown( info->socket, ShutdownMethod );
if( UpnpCloseSocket( info->socket ) == -1 ) {
return UPNP_E_SOCKET_ERROR;
}
}
return UPNP_E_SUCCESS; if (info->socket != -1) {
shutdown(info->socket, ShutdownMethod);
if (sock_close(info->socket) == -1) {
ret = UPNP_E_SOCKET_ERROR;
}
info->socket = -1;
}
return ret;
} }
/************************************************************************ /*!
* Function : sock_read_write * \brief Receives or sends data. Also returns the time taken to receive or
* * send data.
* Parameters : *
* IN SOCKINFO *info ; Socket Information Object * \return
* OUT char* buffer ; Buffer to get data to or send data from * \li \c numBytes - On Success, no of bytes received or sent or
* IN size_t bufsize ; Size of the buffer * \li \c UPNP_E_TIMEDOUT - Timeout
* IN int *timeoutSecs ; timeout value * \li \c UPNP_E_SOCKET_ERROR - Error on socket calls
* IN xboolean bRead ; Boolean value specifying read or write option */
* static int sock_read_write(
* Description : Receives or sends data. Also returns the time taken /*! Socket Information Object. */
* to receive or send data. IN SOCKINFO *info,
* /*! Buffer to get data to or send data from. */
* Return :int ; OUT char *buffer,
* numBytes - On Success, no of bytes received or sent /*! Size of the buffer. */
* UPNP_E_TIMEDOUT - Timeout IN size_t bufsize,
* UPNP_E_SOCKET_ERROR - Error on socket calls /*! timeout value. */
* IN int *timeoutSecs,
* Note : /*! Boolean value specifying read or write option. */
************************************************************************/ IN xboolean bRead)
static int
sock_read_write( IN SOCKINFO * info,
OUT char *buffer,
IN size_t bufsize,
IN int *timeoutSecs,
IN xboolean bRead )
{ {
int retCode; int retCode;
fd_set readSet; fd_set readSet;
fd_set writeSet; fd_set writeSet;
struct timeval timeout; struct timeval timeout;
int numBytes; int numBytes;
time_t start_time = time( NULL ); time_t start_time = time(NULL);
SOCKET sockfd = info->socket; SOCKET sockfd = info->socket;
long bytes_sent = 0, long bytes_sent = 0, byte_left = 0, num_written;
byte_left = 0,
num_written;
if( *timeoutSecs < 0 ) {
return UPNP_E_TIMEDOUT;
}
FD_ZERO( &readSet );
FD_ZERO( &writeSet );
if( bRead ) {
FD_SET( sockfd, &readSet );
} else {
FD_SET( sockfd, &writeSet );
}
timeout.tv_sec = *timeoutSecs;
timeout.tv_usec = 0;
while( TRUE ) {
if( *timeoutSecs == 0 ) {
retCode =
select( sockfd + 1, &readSet, &writeSet, NULL, NULL );
} else {
retCode =
select( sockfd + 1, &readSet, &writeSet, NULL, &timeout );
}
if( retCode == 0 ) {
return UPNP_E_TIMEDOUT;
}
if( retCode == -1 ) {
if( errno == EINTR )
continue;
return UPNP_E_SOCKET_ERROR; // error
} else {
break; // read or write
}
}
if (*timeoutSecs < 0) {
return UPNP_E_TIMEDOUT;
}
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
if (bRead) {
FD_SET(sockfd, &readSet);
} else {
FD_SET(sockfd, &writeSet);
}
timeout.tv_sec = *timeoutSecs;
timeout.tv_usec = 0;
while (TRUE) {
if (*timeoutSecs == 0) {
retCode = select(sockfd + 1, &readSet, &writeSet,
NULL, NULL);
} else {
retCode = select(sockfd + 1, &readSet, &writeSet,
NULL, &timeout);
}
if (retCode == 0) {
return UPNP_E_TIMEDOUT;
}
if (retCode == -1) {
if (errno == EINTR)
continue;
return UPNP_E_SOCKET_ERROR;
} else {
/* read or write. */
break;
}
}
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
{ {
int old; int old;
int set = 1; int set = 1;
socklen_t olen = sizeof(old); socklen_t olen = sizeof(old);
getsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, &olen); getsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, &olen);
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set)); setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &set, sizeof(set));
#endif #endif
if (bRead) {
if( bRead ) { /* read data. */
// read data numBytes = recv(sockfd, buffer, bufsize, MSG_NOSIGNAL);
numBytes = recv( sockfd, buffer, bufsize,MSG_NOSIGNAL); } else {
} else { byte_left = bufsize;
byte_left = bufsize; bytes_sent = 0;
bytes_sent = 0; while (byte_left > 0) {
while( byte_left > 0 ) { /* write data. */
// write data num_written = send(sockfd,
num_written = buffer + bytes_sent, byte_left,
send( sockfd, buffer + bytes_sent, byte_left, MSG_DONTROUTE | MSG_NOSIGNAL);
MSG_DONTROUTE|MSG_NOSIGNAL); if (num_written == -1) {
if( num_written == -1 ) {
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen); setsockopt(sockfd, SOL_SOCKET,
SO_NOSIGPIPE, &old, olen);
#endif #endif
return num_written; return num_written;
} }
byte_left = byte_left - num_written;
byte_left = byte_left - num_written; bytes_sent += num_written;
bytes_sent += num_written; }
} numBytes = bytes_sent;
}
numBytes = bytes_sent;
}
#ifdef SO_NOSIGPIPE #ifdef SO_NOSIGPIPE
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen); setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen);
} }
#endif #endif
if (numBytes < 0) {
return UPNP_E_SOCKET_ERROR;
}
/* subtract time used for reading/writing. */
if (*timeoutSecs != 0) {
*timeoutSecs -= time(NULL) - start_time;
}
if( numBytes < 0 ) { return numBytes;
return UPNP_E_SOCKET_ERROR;
}
// subtract time used for reading/writing
if( *timeoutSecs != 0 ) {
*timeoutSecs -= time( NULL ) - start_time;
}
return numBytes;
} }
/************************************************************************ int sock_read(IN SOCKINFO *info, OUT char *buffer, IN size_t bufsize,
* Function : sock_read INOUT int *timeoutSecs)
*
* Parameters :
* IN SOCKINFO *info ; Socket Information Object
* OUT char* buffer ; Buffer to get data to
* IN size_t bufsize ; Size of the buffer
* IN int *timeoutSecs ; timeout value
*
* Description : Calls sock_read_write() for reading data on the
* socket
*
* Return : int;
* Values returned by sock_read_write()
*
* Note :
************************************************************************/
int
sock_read( IN SOCKINFO * info,
OUT char *buffer,
IN size_t bufsize,
INOUT int *timeoutSecs )
{ {
return sock_read_write( info, buffer, bufsize, timeoutSecs, TRUE ); return sock_read_write(info, buffer, bufsize, timeoutSecs, TRUE);
} }
/************************************************************************ int sock_write(IN SOCKINFO *info, IN char *buffer, IN size_t bufsize,
* Function : sock_write INOUT int *timeoutSecs)
*
* Parameters :
* IN SOCKINFO *info ; Socket Information Object
* IN char* buffer ; Buffer to send data from
* IN size_t bufsize ; Size of the buffer
* IN int *timeoutSecs ; timeout value
*
* Description : Calls sock_read_write() for writing data on the
* socket
*
* Return : int;
* sock_read_write()
*
* Note :
************************************************************************/
int
sock_write( IN SOCKINFO * info,
IN char *buffer,
IN size_t bufsize,
INOUT int *timeoutSecs )
{ {
return sock_read_write( info, buffer, bufsize, timeoutSecs, FALSE ); return sock_read_write(info, buffer, bufsize, timeoutSecs, FALSE);
} }

View File

@@ -153,31 +153,15 @@ subscription *GetSubscriptionSID(const Upnp_SID sid, service_info *service)
} }
/************************************************************************
* Function : GetNextSubscription subscription *GetNextSubscription(service_info *service, subscription *current)
*
* Parameters :
* service_info * service ; service object providing the list of
* subscriptions
* subscription *current ; current subscription object
*
* Description : Get current and valid subscription from the service
* table.
*
* Return : subscription * - Pointer to the next subscription node;
*
* Note :
************************************************************************/
subscription *
GetNextSubscription( service_info * service,
subscription * current )
{ {
time_t current_time; time_t current_time;
subscription *next = NULL; subscription *next = NULL;
subscription *previous = NULL; subscription *previous = NULL;
int notDone = 1; int notDone = 1;
//get the current_time // get the current_time
time( &current_time ); time( &current_time );
while( ( notDone ) && ( current ) ) { while( ( notDone ) && ( current ) ) {
previous = current; previous = current;
@@ -202,52 +186,26 @@ GetNextSubscription( service_info * service,
return next; return next;
} }
/************************************************************************
* Function : GetFirstSubscription
*
* Parameters :
* service_info *service ; service object providing the list of
* subscriptions
*
* Description : Gets pointer to the first subscription node in the
* service table.
*
* Return : subscription * - pointer to the first subscription node ;
*
* Note :
************************************************************************/
subscription *
GetFirstSubscription( service_info * service )
{
subscription temp;
subscription *next = NULL;
temp.next = service->subscriptionList; subscription *GetFirstSubscription(service_info *service)
next = GetNextSubscription( service, &temp ); {
service->subscriptionList = temp.next; subscription temp;
// service->subscriptionList=next; subscription *next = NULL;
return next;
temp.next = service->subscriptionList;
next = GetNextSubscription(service, &temp);
service->subscriptionList = temp.next;
// service->subscriptionList = next;
return next;
} }
/************************************************************************
* Function : freeSubscription void freeSubscription(subscription *sub)
*
* Parameters :
* subscription * sub ; subscription to be freed
*
* Description : Free's the memory allocated for storing the URL of
* the subscription.
*
* Return : void ;
*
* Note :
************************************************************************/
void
freeSubscription( subscription * sub )
{ {
if( sub ) { if (sub) {
free_URL_list( &sub->DeliveryURLs ); free_URL_list(&sub->DeliveryURLs);
} }
} }
/************************************************************************ /************************************************************************
@@ -913,8 +871,10 @@ getServiceList( IXML_Node * node,
( *end ) = current; ( *end ) = current;
return head; return head;
} else } else {
( *end ) = NULL;
return NULL; return NULL;
}
} }
@@ -960,7 +920,8 @@ getAllServiceList( IXML_Node * node,
if( head ) { if( head ) {
end->next = end->next =
getServiceList( currentDevice, &next_end, URLBase ); getServiceList( currentDevice, &next_end, URLBase );
end = next_end; if ( next_end )
end = next_end;
} else } else
head = getServiceList( currentDevice, &end, URLBase ); head = getServiceList( currentDevice, &end, URLBase );

View File

@@ -1,65 +1,59 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
/*!
* \file
*
* \brief Contains a function for freeing the memory associated with a upnp
* time out event.
*/
/************************************************************************
* Purpose: This file contains a function for freeing the memory associated
* wuth a upnp time out event.
************************************************************************/
#include "config.h" #include "config.h"
#include "upnp_timeout.h" #include "upnp_timeout.h"
#include <stdlib.h>
/************************************************************************ #include <stdlib.h> /* for free() */
* Function : free_upnp_timeout
*
* Parameters : void free_upnp_timeout(upnp_timeout *event)
* upnp_timeout *event ; Event which needs to be freed
*
* Description : Free memory associated with event and memory for any
* sub-elements
*
* Return : void ;
*
* Note :
************************************************************************/
void
free_upnp_timeout( upnp_timeout * event )
{ {
if (event) {
if( event ) { if (event->Event) {
if( event->Event ) free(event->Event);
free( event->Event ); }
free( event ); free(event);
}
}
} }

View File

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

View File

@@ -1,52 +1,64 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef GENA_CTRLPT_H
#define GENA_CTRLPT_H
/*!
* \file
*/
#include "sock.h" #include "sock.h"
/************************************************************************
* Function : gena_process_notification_event /*!
* * \brief This function processes NOTIFY events that are sent by devices.
* Parameters: *
* IN SOCKINFO *info: Socket structure containing the device socket * Parameters:
* information * IN SOCKINFO *info: Socket structure containing the device socket
* IN http_message_t* event: The http message contains the GENA * information
* notification * IN http_message_t *event: The http message contains the GENA
* * notification
* Description: *
* This function processes NOTIFY events that are sent by devices. * \note called by genacallback()
* called by genacallback() */
* void gena_process_notification_event(
* Returns: void /*! [in] Socket info of the device. */
* SOCKINFO *info,
* Note : called by genacallback() /*! [in] The http message contains the GENA notification. */
****************************************************************************/ http_message_t *event);
void gena_process_notification_event( INOUT SOCKINFO *info,
IN http_message_t* request );
#endif /* GENA_CTRLPT_H */

View File

@@ -1,88 +1,79 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef GENA_DEVICE_H
#define GENA_DEVICE_H
/*!
* \file
*/
#include "sock.h" #include "sock.h"
/****************************************************************************
* Function : gena_process_subscription_request /*!
* * \brief Handles a subscription request from a ctrl point. The socket is not
* Parameters : * closed on return.
* IN SOCKINFO *info : socket info of the device */
* IN http_message_t* request : SUBSCRIPTION request from the control void gena_process_subscription_request(
* point /*! [in] Socket info of the device. */
* SOCKINFO *info,
* Description : This function handles a subscription request from a /*! [in] Subscription request from the control point. */
* ctrl point. The socket is not closed on return. http_message_t *request);
*
* Return : void
*
* Note :
****************************************************************************/
void gena_process_subscription_request( IN SOCKINFO *info,
IN http_message_t* request );
/**************************************************************************** /*!
* Function : gena_process_subscription_renewal_request * \brief Handles a subscription renewal request from a ctrl point.
* * The connection is not destroyed on return.
* Parameters : */
* IN SOCKINFO *info : socket info of the device void gena_process_subscription_renewal_request(
* IN http_message_t* request : subscription renewal request from the /*! [in] Socket info of the device. */
* control point SOCKINFO *info,
* /*! [in] Subscription renewal request from the control point. */
* Description : This function handles a subscription renewal request http_message_t *request);
* from a ctrl point. The connection is not destroyed on return.
*
* Return : void
*
* Note :
****************************************************************************/
void gena_process_subscription_renewal_request( IN SOCKINFO *info,
IN http_message_t* request );
/**************************************************************************** /*!
* Function : gena_process_unsubscribe_request * \brief Handles a subscription cancellation request from a ctrl point.
* * The connection is not destroyed on return.
* Parameters : */
* IN SOCKINFO *info : socket info of the device void gena_process_unsubscribe_request(
* IN http_message_t* request : UNSUBSCRIBE request from the control /*! [in] Socket info of the device. */
* point SOCKINFO *info,
* /*! [in] UNSUBSCRIBE request from the control point. */
* Description : This function Handles a subscription cancellation request http_message_t *request);
* from a ctrl point. The connection is not destroyed on return.
*
* Return : void #endif /* GENA_DEVICE_H */
*
* Note :
****************************************************************************/
void gena_process_unsubscribe_request( IN SOCKINFO *info,
IN http_message_t* request );

View File

@@ -1,42 +1,49 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef GENLIB_NET_HTTP_HTTPPARSER_H #ifndef GENLIB_NET_HTTP_HTTPPARSER_H
#define GENLIB_NET_HTTP_HTTPPARSER_H #define GENLIB_NET_HTTP_HTTPPARSER_H
#include "util.h"
#include "membuffer.h" /*!
#include "uri.h" * \file
*/
#include "LinkedList.h" #include "LinkedList.h"
#include "membuffer.h"
#include "uri.h"
#include "util.h"
////// private types //////////// ////// private types ////////////
@@ -193,7 +200,8 @@ typedef struct // http_message_t
// private fields // private fields
membuffer msg; // entire raw message membuffer msg; // entire raw message
char *urlbuf; // storage for url string char *urlbuf; // storage for url string
size_t entity_offset;
} http_message_t; } http_message_t;
typedef struct // http_parser_t typedef struct // http_parser_t
@@ -477,27 +485,22 @@ int raw_find_str( IN memptr* raw_value, IN const char* str );
************************************************************************/ ************************************************************************/
const char* method_to_str( IN http_method_t method ); const char* method_to_str( IN http_method_t method );
/************************************************************************
* Function: print_http_headers /*!
* * \brief Print the HTTP headers.
* Parameters: */
* http_message_t* hmsg ; HTTP Message object
*
* Description:
*
* Returns:
* void
************************************************************************/
#ifdef DEBUG #ifdef DEBUG
void print_http_headers( IN http_message_t *hmsg ); void print_http_headers(
/*! [in] HTTP Message object. */
http_message_t *hmsg );
#else #else
static UPNP_INLINE void print_http_headers( IN http_message_t *hmsg ) {} static UPNP_INLINE void print_http_headers(http_message_t *hmsg) {}
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } /* extern "C" */
#endif // __cplusplus #endif /* __cplusplus */
#endif // GENLIB_NET_HTTP_HTTPPARSER_H #endif /* GENLIB_NET_HTTP_HTTPPARSER_H */

View File

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

View File

@@ -1,38 +1,43 @@
/************************************************************************ /**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Copyright (c) 2000-2003 Intel Corporation
* modification, are permitted provided that the following conditions are met: * All rights reserved.
* *
* * Redistributions of source code must retain the above copyright notice, * Redistribution and use in source and binary forms, with or without
* this list of conditions and the following disclaimer. * modification, are permitted provided that the following conditions are met:
* * Redistributions in binary form must reproduce the above copyright notice, *
* this list of conditions and the following disclaimer in the documentation * - Redistributions of source code must retain the above copyright notice,
* and/or other materials provided with the distribution. * this list of conditions and the following disclaimer.
* Neither name of Intel Corporation nor the names of its contributors * - Redistributions in binary form must reproduce the above copyright notice,
* may be used to endorse or promote products derived from this software * 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. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
************************************************************************/ **************************************************************************/
#ifndef MINISERVER_H #ifndef MINISERVER_H
#define MINISERVER_H #define MINISERVER_H
/*!
* \file
*/
#include "sock.h" #include "sock.h"
#include "httpparser.h" #include "httpparser.h"
@@ -41,30 +46,43 @@ extern SOCKET gMiniServerStopSock;
typedef struct MServerSockArray { typedef struct MServerSockArray {
/* socket for listening for miniserver requests */ /*! IPv4 socket for listening for miniserver requests. */
SOCKET miniServerSock4; SOCKET miniServerSock4;
/*! IPv6 Socket for listening for miniserver requests. */
SOCKET miniServerSock6; SOCKET miniServerSock6;
/* socket for stopping miniserver */ /*! Socket for stopping miniserver */
SOCKET miniServerStopSock; SOCKET miniServerStopSock;
/* socket for incoming advertisments and search requests */ /*! IPv4 SSDP Socket for incoming advertisments and search requests. */
SOCKET ssdpSock4; SOCKET ssdpSock4;
/*! IPv6 SSDP Socket for incoming advertisments and search requests. */
SOCKET ssdpSock6; SOCKET ssdpSock6;
/*! IPv6 SSDP Socket for incoming advertisments and search requests. */
SOCKET ssdpSock6UlaGua; SOCKET ssdpSock6UlaGua;
/* ! . */
SOCKET stopPort; SOCKET stopPort;
/* ! . */
SOCKET miniServerPort4; SOCKET miniServerPort4;
/* ! . */
SOCKET miniServerPort6; SOCKET miniServerPort6;
#ifdef INCLUDE_CLIENT_APIS
/* socket for sending search requests and receiving search replies */ /*! IPv4 SSDP socket for sending search requests and receiving search
CLIENTONLY(SOCKET ssdpReqSock4;) * replies */
CLIENTONLY(SOCKET ssdpReqSock6;) SOCKET ssdpReqSock4;
/*! IPv6 SSDP socket for sending search requests and receiving search
* replies */
SOCKET ssdpReqSock6;
#endif /* INCLUDE_CLIENT_APIS */
} MiniServerSockArray; } MiniServerSockArray;
/*! . */
typedef void (*MiniServerCallback)( typedef void (*MiniServerCallback)(
/* ! . */
IN http_parser_t *parser, IN http_parser_t *parser,
/* ! . */
IN http_message_t* request, IN http_message_t* request,
IN SOCKINFO *info ); /* ! . */
IN SOCKINFO *info);
#ifdef __cplusplus #ifdef __cplusplus
@@ -116,9 +134,11 @@ void SetGenaCallback(
* \li On error: UPNP_E_XXX. * \li On error: UPNP_E_XXX.
*/ */
int StartMiniServer( int StartMiniServer(
/*! [in,out] Port on which the server listens for incoming IPv4 connections. */ /*! [in,out] Port on which the server listens for incoming IPv4
* connections. */
unsigned short *listen_port4, unsigned short *listen_port4,
/*! [in,out] Port on which the server listens for incoming IPv6 connections. */ /*! [in,out] Port on which the server listens for incoming IPv6
* connections. */
unsigned short *listen_port6); unsigned short *listen_port6);

View File

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

View File

@@ -29,149 +29,143 @@
* *
**************************************************************************/ **************************************************************************/
#ifndef GENLIB_NET_SOCK_H #ifndef GENLIB_NET_SOCK_H
#define GENLIB_NET_SOCK_H #define GENLIB_NET_SOCK_H
/*!
* \file
*/
#include "util.h" #include "util.h"
#ifdef WIN32 #ifdef WIN32
/* Do not #include <netinet/in.h> */ /* Do not #include <netinet/in.h> */
#else #else
#include <netinet/in.h> #include <netinet/in.h>
#endif #endif
/* The following are not defined under winsock.h */
/* Following variable is not defined under winsock.h */
#ifndef SD_RECEIVE #ifndef SD_RECEIVE
#define SD_RECEIVE 0x00 #define SD_RECEIVE 0x00
#define SD_SEND 0x01 #define SD_SEND 0x01
#define SD_BOTH 0x02 #define SD_BOTH 0x02
#endif #endif
/*! */
typedef struct typedef struct
{ {
/* handle/descriptor to a socket */ /*! Handle/descriptor to a socket. */
SOCKET socket; SOCKET socket;
/*! The following two fields are filled only in incoming requests. */
/* the following two fields are filled only in incoming requests; */
struct sockaddr_storage foreign_sockaddr; struct sockaddr_storage foreign_sockaddr;
} SOCKINFO; } SOCKINFO;
#ifdef __cplusplus #ifdef __cplusplus
#extern "C" { #extern "C" {
#endif #endif
/*!
* \brief Assign the passed in socket descriptor to socket descriptor in the
* SOCKINFO structure.
*
* \return Integer:
* \li \c UPNP_E_SUCCESS
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_SOCKET_ERROR
*/
int sock_init(
/*! Socket Information Object. */
OUT SOCKINFO *info,
/*! Socket Descriptor. */
IN SOCKET sockfd);
/************************************************************************ /*!
* Function : sock_init * \brief Calls the sock_init function and assigns the passed in IP address
* * and port to the IP address and port in the SOCKINFO structure.
* Parameters : *
* OUT SOCKINFO* info ; Socket Information Object * \return Integer:
* IN SOCKET sockfd ; Socket Descriptor * \li \c UPNP_E_SUCCESS
* * \li \c UPNP_E_OUTOF_MEMORY
* Description : Assign the passed in socket descriptor to socket * \li \c UPNP_E_SOCKET_ERROR
* descriptor in the SOCKINFO structure. */
*
* Return : int;
* UPNP_E_SUCCESS
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* Note :
************************************************************************/
int sock_init(OUT SOCKINFO* info, IN SOCKET sockfd);
/************************************************************************
* Function : sock_init_with_ip
*
* Parameters :
* OUT SOCKINFO* info ; Socket Information Object
* IN SOCKET sockfd ; Socket Descriptor
* IN struct sockaddr* foreign_sockaddr; Remote socket address
*
* Description : Calls the sock_init function and assigns the passed in
* IP address and port to the IP address and port in the SOCKINFO
* structure.
*
* Return : int;
* UPNP_E_SUCCESS
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
*
* Note :
************************************************************************/
int sock_init_with_ip( int sock_init_with_ip(
/*! Socket Information Object. */
OUT SOCKINFO* info, OUT SOCKINFO* info,
/*! Socket Descriptor. */
IN SOCKET sockfd, IN SOCKET sockfd,
/*! Remote socket address. */
IN struct sockaddr *foreign_sockaddr); IN struct sockaddr *foreign_sockaddr);
/************************************************************************ /*!
* Function : sock_read * \brief Reads data on socket in sockinfo.
* *
* Parameters : * \return Integer:
* IN SOCKINFO *info ; Socket Information Object * \li \c numBytes - On Success, no of bytes received.
* OUT char* buffer ; Buffer to get data to * \li \c UPNP_E_TIMEDOUT - Timeout.
* IN size_t bufsize ; Size of the buffer * \li \c UPNP_E_SOCKET_ERROR - Error on socket calls.
* IN int *timeoutSecs ; timeout value */
* int sock_read(
* Description : Reads data on socket in sockinfo /*! Socket Information Object. */
* IN SOCKINFO *info,
* Return : int; /*! Buffer to get data to. */
* numBytes - On Success, no of bytes received OUT char* buffer,
* UPNP_E_TIMEDOUT - Timeout /*! Size of the buffer. */
* UPNP_E_SOCKET_ERROR - Error on socket calls IN size_t bufsize,
* /*! timeout value. */
* Note : INOUT int *timeoutSecs);
************************************************************************/
int sock_read( IN SOCKINFO *info, OUT char* buffer, IN size_t bufsize,
INOUT int *timeoutSecs );
/************************************************************************ /*!
* Function : sock_write * \brief Writes data on the socket in sockinfo.
* *
* Parameters : * \return Integer:
* IN SOCKINFO *info ; Socket Information Object * \li \c numBytes - On Success, no of bytes received.
* IN char* buffer ; Buffer to send data from * \li \c UPNP_E_TIMEDOUT - Timeout.
* IN size_t bufsize ; Size of the buffer * \li \c UPNP_E_SOCKET_ERROR - Error on socket calls.
* IN int *timeoutSecs ; timeout value */
* int sock_write(
* Description : Writes data on the socket in sockinfo /*! Socket Information Object. */
* IN SOCKINFO *info,
* Return : int; /*! Buffer to send data from. */
* numBytes - On Success, no of bytes sent IN char* buffer,
* UPNP_E_TIMEDOUT - Timeout /*! Size of the buffer. */
* UPNP_E_SOCKET_ERROR - Error on socket calls IN size_t bufsize,
* /*! timeout value. */
* Note : INOUT int *timeoutSecs);
************************************************************************/
int sock_write( IN SOCKINFO *info, IN char* buffer, IN size_t bufsize,
INOUT int *timeoutSecs );
/************************************************************************ /*!
* Function : sock_destroy * \brief Shutsdown the socket using the ShutdownMethod to indicate whether
* * sends and receives on the socket will be dis-allowed.
* Parameters : *
* INOUT SOCKINFO* info ; Socket Information Object * After shutting down the socket, closesocket is called to release system
* int ShutdownMethod ; How to shutdown the socket. Used by * resources used by the socket calls.
* sockets's shutdown() *
* * \return Integer:
* Description : Shutsdown the socket using the ShutdownMethod to * \li \c UPNP_E_SOCKET_ERROR on failure.
* indicate whether sends and receives on the socket will be * \li \c UPNP_E_SUCCESS on success.
* dis-allowed. After shutting down the socket, closesocket is called */
* to release system resources used by the socket calls. int sock_destroy(
* /*! Socket Information Object. */
* Return : int; INOUT SOCKINFO* info,
* UPNP_E_SOCKET_ERROR on failure /*! How to shutdown the socket. Used by sockets's shutdown(). */
* UPNP_E_SUCCESS on success int ShutdownMethod);
*
* Note :
************************************************************************/
int sock_destroy(INOUT SOCKINFO* info, int);
/*!
* \brief Closes the socket if it is different from -1.
*
* \return -1 if an error occurred or if the socket is -1.
*/
static inline int sock_close(
/*! Socket descriptor. */
int sock)
{
int ret = -1;
if (sock != -1) {
ret = UpnpCloseSocket(sock);
}
return ret;
}
#ifdef __cplusplus #ifdef __cplusplus
} /* #extern "C" */ } /* #extern "C" */

View File

@@ -47,15 +47,17 @@
#ifdef WIN32 #ifdef WIN32
#else #else /* WIN32 */
#include <syslog.h> #include <syslog.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in_systm.h> #ifndef __APPLE__
#include <netinet/ip.h> #include <netinet/in_systm.h>
#include <netinet/ip_icmp.h> #include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#endif /* __APPLE__ */
#include <sys/time.h> #include <sys/time.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#endif #endif /* WIN32 */
/* Enumeration to define all different types of ssdp searches */ /* Enumeration to define all different types of ssdp searches */
@@ -138,12 +140,12 @@ typedef void (* SsdpFunPtr)(Event *);
typedef Event SsdpEvent ; typedef Event SsdpEvent ;
//Structure to contain Discovery response // Structure to contain Discovery response
typedef struct resultData typedef struct resultData
{ {
struct Upnp_Discovery param; struct Upnp_Discovery param;
void *cookie; void *cookie;
Upnp_FunPtr ctrlpt_callback; Upnp_FunPtr ctrlpt_callback;
}ResultData; }ResultData;
@@ -183,9 +185,12 @@ typedef struct
/* globals */ /* globals */
CLIENTONLY(extern SOCKET gSsdpReqSocket4;); #ifdef INCLUDE_CLIENT_APIS
CLIENTONLY(extern SOCKET gSsdpReqSocket6;); extern SOCKET gSsdpReqSocket4;
#ifdef UPNP_ENABLE_IPV6
extern SOCKET gSsdpReqSocket6;
#endif /* UPNP_ENABLE_IPV6 */
#endif /* INCLUDE_CLIENT_APIS */
typedef int (*ParserFun)(char *, Event *); typedef int (*ParserFun)(char *, Event *);
@@ -219,12 +224,12 @@ int Make_Socket_NoBlocking (int sock);
***************************************************************************/ ***************************************************************************/
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
void ssdp_handle_device_request( void ssdp_handle_device_request(
IN http_message_t* hmsg, IN http_message_t *hmsg,
IN struct sockaddr* dest_addr ); IN struct sockaddr *dest_addr);
#else #else
static inline void ssdp_handle_device_request( static inline void ssdp_handle_device_request(
IN http_message_t* hmsg, IN http_message_t *hmsg,
IN struct sockaddr* dest_addr ) {} IN struct sockaddr* dest_addr) {}
#endif #endif
/************************************************************************ /************************************************************************
@@ -248,10 +253,10 @@ static inline void ssdp_handle_device_request(
* *
***************************************************************************/ ***************************************************************************/
void ssdp_handle_ctrlpt_msg( void ssdp_handle_ctrlpt_msg(
IN http_message_t* hmsg, IN http_message_t *hmsg,
IN struct sockaddr* dest_addr, IN struct sockaddr *dest_addr,
IN xboolean timeout, IN xboolean timeout,
IN void* cookie ); IN void *cookie);
/************************************************************************ /************************************************************************
* Function : unique_service_name * Function : unique_service_name

View File

@@ -1,58 +1,62 @@
/////////////////////////////////////////////////////////////////////////// /*******************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// ******************************************************************************/
#ifndef _UPNPTIMEOUTH_
#define _UPNPTIMEOUTH_
#ifndef UPNPTIMEOUT_H
#define UPNPTIMEOUT_H
/*!
* \file
*/
/*!
* The upnp_timeout structure definition.
*/
typedef struct UPNP_TIMEOUT { typedef struct UPNP_TIMEOUT {
int EventType; int EventType;
int handle; int handle;
int eventId; int eventId;
void *Event; void *Event;
} upnp_timeout; } upnp_timeout;
/************************************************************************ /*!
* Function : free_upnp_timeout * \brief Free memory associated with event and memory for any sub-elements.
* */
* Parameters : void free_upnp_timeout(
* upnp_timeout *event ; Event which needs to be freed /*! [in] Event which needs to be freed. */
* upnp_timeout *event);
* Description : Free memory associated with event and memory for any
* sub-elements
* #endif /* UPNPTIMEOUT_H */
* Return : void ;
*
* Note :
************************************************************************/
void free_upnp_timeout(upnp_timeout *event);
#endif

View File

@@ -1,37 +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 UPNPCLOSESOCKET_H
#define UPNPCLOSESOCKET_H
#define UpnpCloseSocket close
#endif

View File

@@ -1,33 +1,33 @@
/////////////////////////////////////////////////////////////////////////// /**************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// **************************************************************************/
#ifndef GENLIB_NET_HTTP_WEBSERVER_H #ifndef GENLIB_NET_HTTP_WEBSERVER_H
#define GENLIB_NET_HTTP_WEBSERVER_H #define GENLIB_NET_HTTP_WEBSERVER_H
@@ -43,103 +43,90 @@ extern "C" {
struct SendInstruction struct SendInstruction
{ {
int IsVirtualFile; int IsVirtualFile;
int IsChunkActive; int IsChunkActive;
int IsRangeActive; int IsRangeActive;
int IsTrailers; int IsTrailers;
char RangeHeader[200]; char RangeHeader[200];
off_t RangeOffset; char AcceptLanguageHeader[200];
off_t ReadSendSize; // Read from local source and send on the network. off_t RangeOffset;
long RecvWriteSize; // Recv from the network and write into local file. /*! Read from local source and send on the network. */
off_t ReadSendSize;
//Later few more member could be added depending on the requirement. /*! Recv from the network and write into local file. */
long RecvWriteSize;
/* Later few more member could be added depending
* on the requirement.*/
}; };
/************************************************************************
* Function: web_server_init
*
* Parameters:
* none
*
* Description: Initilialize the different documents. Initialize the
* memory for root directory for web server. Call to initialize global
* XML document. Sets bWebServerState to WEB_SERVER_ENABLED
*
* Returns:
* 0 - OK
* UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here
************************************************************************/
int web_server_init( void );
/************************************************************************ /*!
* Function: web_server_destroy * \brief Initilialize the different documents. Initialize the memory
* * for root directory for web server. Call to initialize global XML
* Parameters: * document. Sets bWebServerState to WEB_SERVER_ENABLED.
* none *
* * \note alias_content is not freed here
* Description: Release memory allocated for the global web server root *
* directory and the global XML document * \return
* Resets the flag bWebServerState to WEB_SERVER_DISABLED * \li \c 0 - OK
* * \li \c UPNP_E_OUTOF_MEMORY
* Returns: */
* void int web_server_init(void);
************************************************************************/
void web_server_destroy( void );
/************************************************************************
* Function: web_server_set_alias
*
* Parameters:
* alias_name: webserver name of alias; created by caller and freed by
* caller (doesn't even have to be malloc()d .)
* alias_content: the xml doc; this is allocated by the caller; and
* freed by the web server
* alias_content_length: length of alias body in bytes
* last_modified: time when the contents of alias were last
* changed (local time)
*
* Description: Replaces current alias with the given alias. To remove
* the current alias, set alias_name to NULL.
*
* Returns:
* 0 - OK
* UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here
************************************************************************/
int web_server_set_alias( IN const char* alias_name,
IN const char* alias_content, IN size_t alias_content_length,
IN time_t last_modified );
/************************************************************************ /*!
* Function: web_server_set_root_dir * \brief Release memory allocated for the global web server root
* * directory and the global XML document. Resets the flag bWebServerState
* Parameters: * to WEB_SERVER_DISABLED.
* IN const char* root_dir ; String having the root directory for the */
* document void web_server_destroy(void);
*
* Description: Assign the path specfied by the IN const char* root_dir
* parameter to the global Document root directory. Also check for
* path names ending in '/'
*
* Returns:
* int
************************************************************************/
int web_server_set_root_dir( IN const char* root_dir );
/************************************************************************
* Function: web_server_callback /*!
* * \brief Replaces current alias with the given alias. To remove the current
* Parameters: * alias, set alias_name to NULL.
* IN http_parser_t *parser, *
* INOUT http_message_t* req, * \note alias_content is not freed here
* IN SOCKINFO *info *
* * \return
* Description: main entry point into web server; * \li \c 0 - OK
* handles HTTP GET and HEAD requests * \li \c UPNP_E_OUTOF_MEMORY
* */
* Returns: int web_server_set_alias(
* void /*! [in] Webserver name of alias; created by caller and freed by caller
************************************************************************/ * (doesn't even have to be malloc()d. */
void web_server_callback( IN http_parser_t *parser, IN http_message_t* req, INOUT SOCKINFO *info ); const char* alias_name,
/*! [in] The xml doc; this is allocated by the caller; and freed by
* the web server. */
const char* alias_content,
/*! [in] Length of alias body in bytes. */
size_t alias_content_length,
/*! [in] Time when the contents of alias were last changed (local time). */
time_t last_modified);
/*!
* \brief Assign the path specfied by the input const char* root_dir parameter
* to the global Document root directory. Also check for path names ending
* in '/'.
*
* \return Integer.
*/
int web_server_set_root_dir(
/*! [in] String having the root directory for the document. */
const char* root_dir);
/*!
* \brief Main entry point into web server; Handles HTTP GET and HEAD
* requests.
*/
void web_server_callback(
/*! [in] . */
http_parser_t *parser,
/*! [in] . */
http_message_t *req,
/*! [in,out] . */
SOCKINFO *info);
#ifdef __cplusplus #ifdef __cplusplus

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

@@ -74,11 +74,10 @@
***************************************************************************/ ***************************************************************************/
void send_search_result(IN void *data) void send_search_result(IN void *data)
{ {
ResultData *temp = ( ResultData * ) data; ResultData *temp = ( ResultData * ) data;
temp->ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, temp->ctrlpt_callback(UPNP_DISCOVERY_SEARCH_RESULT, &temp->param, temp->cookie);
&temp->param, temp->cookie ); free(temp);
free( temp );
} }
/************************************************************************ /************************************************************************
@@ -127,7 +126,7 @@ void ssdp_handle_ctrlpt_msg(
ListNode *node = NULL; ListNode *node = NULL;
SsdpSearchArg *searchArg = NULL; SsdpSearchArg *searchArg = NULL;
int matched = 0; int matched = 0;
ResultData *threadData; ResultData *threadData = NULL;
ThreadPoolJob job; ThreadPoolJob job;
// we are assuming that there can be only one client supported at a time // we are assuming that there can be only one client supported at a time
@@ -136,7 +135,7 @@ void ssdp_handle_ctrlpt_msg(
if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
HandleUnlock(); HandleUnlock();
return; return;
} }
// copy // copy
ctrlpt_callback = ctrlpt_info->Callback; ctrlpt_callback = ctrlpt_info->Callback;
@@ -146,14 +145,15 @@ void ssdp_handle_ctrlpt_msg(
// search timeout // search timeout
if ( timeout ) { if ( timeout ) {
ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie ); ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
return; return;
} }
param.ErrCode = UPNP_E_SUCCESS; param.ErrCode = UPNP_E_SUCCESS;
// MAX-AGE // MAX-AGE
param.Expires = -1; // assume error // assume error
if( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) { param.Expires = -1;
if ( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) {
if( matchstr( hdr_value.buf, hdr_value.length, if( matchstr( hdr_value.buf, hdr_value.length,
"%imax-age = %d%0", &param.Expires ) != PARSE_OK ) "%imax-age = %d%0", &param.Expires ) != PARSE_OK )
return; return;
@@ -161,7 +161,7 @@ void ssdp_handle_ctrlpt_msg(
// DATE // DATE
param.Date[0] = '\0'; param.Date[0] = '\0';
if( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) { if ( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) {
linecopylen( param.Date, hdr_value.buf, hdr_value.length ); linecopylen( param.Date, hdr_value.buf, hdr_value.length );
} }
@@ -170,17 +170,17 @@ void ssdp_handle_ctrlpt_msg(
// EXT // EXT
param.Ext[0] = '\0'; param.Ext[0] = '\0';
if( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) { if ( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) {
linecopylen( param.Ext, hdr_value.buf, hdr_value.length ); linecopylen( param.Ext, hdr_value.buf, hdr_value.length );
} }
// LOCATION // LOCATION
param.Location[0] = '\0'; param.Location[0] = '\0';
if( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) { if ( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) {
linecopylen( param.Location, hdr_value.buf, hdr_value.length ); linecopylen( param.Location, hdr_value.buf, hdr_value.length );
} }
// SERVER / USER-AGENT // SERVER / USER-AGENT
param.Os[0] = '\0'; param.Os[0] = '\0';
if( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL || if ( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL ||
httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) { httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) {
linecopylen( param.Os, hdr_value.buf, hdr_value.length ); linecopylen( param.Os, hdr_value.buf, hdr_value.length );
} }
@@ -327,7 +327,7 @@ void ssdp_handle_ctrlpt_msg(
TPJobInit( &job, ( start_routine ) send_search_result, TPJobInit( &job, ( start_routine ) send_search_result,
threadData ); threadData );
TPJobSetPriority(&job, MED_PRIORITY); TPJobSetPriority(&job, MED_PRIORITY);
TPJobSetFreeFunction( &job, ( free_routine ) free ); TPJobSetFreeFunction(&job, (free_routine)free);
ThreadPoolAdd(&gRecvThreadPool, &job, NULL); ThreadPoolAdd(&gRecvThreadPool, &job, NULL);
} }
} }
@@ -510,7 +510,6 @@ int SearchByTarget(
IN void *Cookie) IN void *Cookie)
{ {
char errorBuffer[ERROR_BUFFER_LEN]; char errorBuffer[ERROR_BUFFER_LEN];
int socklen = sizeof( struct sockaddr_storage );
int *id = NULL; int *id = NULL;
int ret = 0; int ret = 0;
char ReqBufv4[BUFSIZE]; char ReqBufv4[BUFSIZE];
@@ -595,12 +594,14 @@ int SearchByTarget(
FD_SET(gSsdpReqSocket4, &wrSet); FD_SET(gSsdpReqSocket4, &wrSet);
max_fd = max(max_fd, gSsdpReqSocket4); max_fd = max(max_fd, gSsdpReqSocket4);
} }
#ifdef UPNP_ENABLE_IPV6
if (gSsdpReqSocket6 != INVALID_SOCKET) { if (gSsdpReqSocket6 != INVALID_SOCKET) {
setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF, setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char *)&gIF_INDEX, sizeof (gIF_INDEX)); (char *)&gIF_INDEX, sizeof (gIF_INDEX));
FD_SET(gSsdpReqSocket6, &wrSet); FD_SET(gSsdpReqSocket6, &wrSet);
max_fd = max(max_fd, gSsdpReqSocket6); max_fd = max(max_fd, gSsdpReqSocket6);
} }
#endif
ret = select(max_fd + 1, NULL, &wrSet, NULL, NULL); ret = select(max_fd + 1, NULL, &wrSet, NULL, NULL);
if (ret == -1) { if (ret == -1) {
@@ -610,11 +611,13 @@ int SearchByTarget(
errorBuffer); errorBuffer);
shutdown(gSsdpReqSocket4, SD_BOTH); shutdown(gSsdpReqSocket4, SD_BOTH);
UpnpCloseSocket(gSsdpReqSocket4); UpnpCloseSocket(gSsdpReqSocket4);
#ifdef UPNP_ENABLE_IPV6
shutdown(gSsdpReqSocket6, SD_BOTH); shutdown(gSsdpReqSocket6, SD_BOTH);
UpnpCloseSocket(gSsdpReqSocket6); UpnpCloseSocket(gSsdpReqSocket6);
#endif
return UPNP_E_INTERNAL_ERROR; return UPNP_E_INTERNAL_ERROR;
} }
#ifdef UPNP_ENABLE_IPV6
if (gSsdpReqSocket6 != INVALID_SOCKET && if (gSsdpReqSocket6 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket6, &wrSet)) { FD_ISSET(gSsdpReqSocket6, &wrSet)) {
int NumCopy = 0; int NumCopy = 0;
@@ -622,28 +625,38 @@ int SearchByTarget(
while (NumCopy < NUM_SSDP_COPY) { while (NumCopy < NUM_SSDP_COPY) {
sendto(gSsdpReqSocket6, sendto(gSsdpReqSocket6,
ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0, ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
(struct sockaddr *)&__ss_v6, socklen); (struct sockaddr *)&__ss_v6,
sizeof(struct sockaddr_in));
NumCopy++; NumCopy++;
imillisleep(SSDP_PAUSE); imillisleep(SSDP_PAUSE);
} }
NumCopy = 0; NumCopy = 0;
inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr); inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
while (NumCopy < NUM_SSDP_COPY) { while (NumCopy < NUM_SSDP_COPY) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND M-SEARCH >>>\n%s\n",
ReqBufv6);
sendto(gSsdpReqSocket6, sendto(gSsdpReqSocket6,
ReqBufv6, strlen(ReqBufv6), 0, ReqBufv6, strlen(ReqBufv6), 0,
(struct sockaddr *)&__ss_v6, socklen); (struct sockaddr *)&__ss_v6,
sizeof(struct sockaddr_in6));
NumCopy++; NumCopy++;
imillisleep(SSDP_PAUSE); imillisleep(SSDP_PAUSE);
} }
} }
#endif //IPv6
if (gSsdpReqSocket4 != INVALID_SOCKET && if (gSsdpReqSocket4 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket4, &wrSet)) { FD_ISSET(gSsdpReqSocket4, &wrSet)) {
int NumCopy = 0; int NumCopy = 0;
while (NumCopy < NUM_SSDP_COPY) { while (NumCopy < NUM_SSDP_COPY) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND M-SEARCH >>>\n%s\n",
ReqBufv4);
sendto(gSsdpReqSocket4, sendto(gSsdpReqSocket4,
ReqBufv4, strlen(ReqBufv4), 0, ReqBufv4, strlen(ReqBufv4), 0,
(struct sockaddr *)&__ss_v4, socklen); (struct sockaddr *)&__ss_v4,
sizeof(struct sockaddr_in));
NumCopy++; NumCopy++;
imillisleep(SSDP_PAUSE); imillisleep(SSDP_PAUSE);
} }

View File

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

View File

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