Compare commits

..

61 Commits

Author SHA1 Message Date
Marcelo Roberto Jimenez
79aa205657 Adjust the library numbers for release. 2010-12-11 16:35:29 -02:00
Marcelo Roberto Jimenez
9a28fcc95b Fixes a bug introduced in a previous commit in http_SendMessage.
The variable num_read was beeing used without beeing initialized.

Also, clean up the function return path and make sure va_end()
is beeing called.
2010-11-24 11:26:00 -02:00
Marcelo Roberto Jimenez
bfbd07cb40 Reformat calls to http_SendMessage(). 2010-11-24 11:12:33 -02:00
Marcelo Roberto Jimenez
255d5ee874 soap_device: Doxygen and code reformat. 2010-11-24 11:10:18 -02:00
Fabrice Fontaine
2c3bce13bd Major bug fix in http_SendMessage.
Currently, http_SendMessage was not able to write to write a buffer
due to a bad use of file_buf instead of buf. This bug was introduced by
the 0197-Doxygen-reformating-compiler-warnings patch.
2010-11-24 08:21:41 -02:00
Fabrice Fontaine
bda942b22a Returning the SID in Upnp_Event_Subscribe.
Currently, Upnp_Event_Subscribe always contains an empty chain in the
Sid parameter. This patch now saves the client Subscription ID in this
parameter so Control Points can see and use the same SID in the
Upnp_Event_Subscribe and in the Upnp_Event structures.
2010-11-24 08:21:33 -02:00
Juergen Lock
ed0ebe1588 Two fixes from Juergen Lock <nox(at)jelal.kn-bremen.de>:
1. varargs:  pass size of CRLF as size_t not as int:

--- upnp/src/gena/gena_device.c.orig
+++ upnp/src/gena/gena_device.c
@@ -225,7 +225,7 @@ static UPNP_INLINE int notify_send_and_r
		"bbb",
		start_msg.buf, start_msg.length,
		propertySet, strlen(propertySet),
-		"\r\n", 2);
+		"\r\n", sizeof "\r\n" - 1);
	if (ret_code) {
		membuffer_destroy(&start_msg);
		sock_destroy(&info, SD_BOTH);

2. Remove "b" arg here, there is no buffer passed:  (this caused a pointer
to be interpreted as a buffer size to be alloc'd/copied, hence the 32 GB.)

--- upnp/src/genlib/net/http/webserver.c.orig
+++ upnp/src/genlib/net/http/webserver.c
@@ -1262,7 +1262,7 @@ static int process_request(
			// Content-Range: bytes 222-3333/4000  HTTP_PARTIAL_CONTENT
			// Transfer-Encoding: chunked
			if (http_MakeMessage(headers, resp_major, resp_minor,
-				"R" "TLD" "s" "tcS" "b" "Xc" "sCc",
+				"R" "TLD" "s" "tcS" "Xc" "sCc",
				HTTP_OK,    // status code
				finfo.content_type, // content type
				RespInstr,  // language info
2010-11-22 23:28:56 -02:00
Marcelo Roberto Jimenez
a39f3a63c3 White spaces. 2010-11-22 13:21:30 -02:00
Marcelo Roberto Jimenez
6e7a2bb2dc Remove the "xboolean" typedef from the code base. 2010-11-22 09:28:17 -02:00
Marcelo Roberto Jimenez
c21a67f2d1 Doxygen, reformating, compiler warnings. 2010-11-21 21:40:07 -02:00
Marcelo Roberto Jimenez
c449fd1521 ssdp, soap, genlib: fix compiler warnings. 2010-11-20 19:08:20 -02:00
Marcelo Roberto Jimenez
594c611a33 gena: fix several compiler warnings. 2010-11-20 13:48:50 -02:00
Marcelo Roberto Jimenez
09f2b6ca30 uuid.c: fix compiler warnings. 2010-11-20 11:30:22 -02:00
Marcelo Roberto Jimenez
9b3a0999a9 upnp: fix for compiler warnings. 2010-11-18 14:57:11 -02:00
Marcelo Roberto Jimenez
d8a27bca96 upnp: fix for compiler warnings and incorrect API. 2010-11-18 14:55:39 -02:00
Marcelo Roberto Jimenez
6bee05a517 samples: One more code reorganization. 2010-11-18 13:59:08 -02:00
Marcelo Roberto Jimenez
2e96edcbc5 samples: fix compiler warnings. 2010-11-18 13:34:04 -02:00
Marcelo Roberto Jimenez
ef0aa38958 samples: More code reorganization. 2010-11-18 12:02:38 -02:00
Marcelo Roberto Jimenez
86159bc2a6 samples: Put more data in common_data.h. 2010-11-18 01:02:27 -02:00
Marcelo Roberto Jimenez
bd8d6cfc8b samples: Unified sample code.
This patch removes duplicated code in samples.
2010-11-18 00:47:45 -02:00
Marcelo Roberto Jimenez
8434e1e936 Update autoconfig.h. 2010-11-17 23:31:07 -02:00
Marcelo Roberto Jimenez
2765bc39c5 Remove "upnp_" prefix from samples. 2010-11-17 23:30:29 -02:00
Marcelo Roberto Jimenez
75695fcaf1 samples: Fix compiler warnings. 2010-11-17 11:54:31 -02:00
Marcelo Roberto Jimenez
5abd1a3b3e Fix some compiler warnings and some Doxygen. 2010-11-17 01:24:38 -02:00
Marcelo Roberto Jimenez
6c31683e29 Some Doxygen in upnp_tv_device.
(cherry picked from commit d5fa48bd37)
2010-11-16 23:22:59 -02:00
Marcelo Roberto Jimenez
d92e26779a Some Doxygen on sample_util.
(cherry picked from commit 0d625bd2e1)
2010-11-16 23:22:51 -02:00
Marcelo Roberto Jimenez
5d6bcabd45 Removes C++ style comments. 2010-11-16 03:14:12 -02:00
Marcelo Roberto Jimenez
7c524df1d9 threadutil: Doxygenation and compiler warnings. 2010-11-16 00:17:44 -02:00
Marcelo Roberto Jimenez
58c694f57d ixml: Fix for compiler warnings for size_t and ptrdiff_t.
ixmlparser.c static functions have been reordered.
2010-11-15 21:29:07 -02:00
Marcelo Roberto Jimenez
da7f3bf1c1 Deal with "inline" when "-ansi" compiler option is active.
This mode can be recognized by the macro __STRICT_ANSI__.

From man gcc:

-ansi
 In C mode, this is equivalent to -std=c89. In C++ mode, it is equivalent to
-std=c++98.

 This turns off certain features of GCC that are incompatible with ISO C90
(when compiling C code), or of standard (when compiling code), such as the
asm and typeof keywords, and predefined macros such as unix and vax that
identify the type of system you are using. It also enables the undesirable
and rarely used ISO trigraph feature. For the C compiler, it disables
recognition of style // comments as well as the inline keyword.

 The alternate keywords _ _asm_ _, _ _extension_ _, _ _inline_ _ and
_ _typeof_ _ continue to work despite -ansi. You would not want to use them
in an ISO C program, of course, but it is useful to put them in header files
that might be included in compilations done with -ansi. Alternate predefined
macros such as _ _unix_ _ and _ _vax_ _ are also available, with or without
-ansi.

 The -ansi option does not cause non-ISO programs to be rejected gratuitously.
For that, -pedantic is required in addition to -ansi.

 The macro _ _STRICT_ANSI_ _ is predefined when the -ansi option is used.
Some header files may notice this macro and refrain from declaring certain
functions or defining certain macros that the ISO standard doesn't call for;
this is to avoid interfering with any programs that might use these names for
other things.

 Functions that would normally be built in but do not have semantics defined
by ISO C (such as alloca and ffs) are not built-in functions when -ansi is
used.
2010-11-15 12:50:38 -02:00
Marcelo Roberto Jimenez
8651174861 Added the convenience function UpnpResolveURL2() to upnptools.c.
This function avoids some unecessary memory allocation.
The memory alloc'd by this function must be freed later by the caller.
2010-11-15 01:01:07 -02:00
Marcelo Roberto Jimenez
2dd19e5894 ReadResponseLineAndHeaders() is static.
(cherry picked from commit eb5db65692)
2010-11-11 22:00:27 -02:00
Fabrice Fontaine
e6c548f57a Add GENA_NOTIFICATION_xxx_TIMEOUT variable.
Currently, in notify_send_and_recv function, pupnp waits for
HTTP_DEFAULT_TIMEOUT seconds when trying to send a GENA notification.
When there is a lot of notifications with CPs which was disconnected
without unsusbcribing, all the pupnp threads are blocked on this
timeout. To correct, this issue, this patch adds a new variable,
GENA_NOTIFICATION_SENDING_TIMEOUT, which can be used to lower the
timeout so GENA threads return quickly when writing is impossible. By
the same mean, pupnp waits the CP's answer to the NOTIFY for
HTTP_DEFAULT_TIMEOUT seconds, so this patch adds a new variable,
GENA_NOTIFICATION_ANSWERING_TIMEOUT, to customize this value.
2010-11-11 21:42:50 -02:00
Fabrice Fontaine
32cffb5bb5 Add --disable-blocking-tcp-connections flag.
Currently, pupnp is using a blocking connect to sends GENA
notifications. As a result, when there is a lot of notifications with
CPs which were disconnected without unsusbcribing, all the pupnp
threads are blocked for 20s (timeout). To correct this issue, this
patch replace the call to connect with a call to private_connect and add
a compilation flag to disable blocking TCP connections, so if we are not
able to connect to the CP, the notification is lost.
2010-11-11 21:40:22 -02:00
Marcelo Roberto Jimenez
2b30575ca5 Remove commented old code from webserver.c. 2010-11-11 21:31:53 -02:00
Marcelo Roberto Jimenez
d32212a6fd Changelog and THANKS update. 2010-11-07 19:20:03 -02:00
Stefan Sommerfeld
508b782c79 Fixed some typos. 2010-11-07 18:42:44 -02:00
Stefan Sommerfeld
38d5e58e22 Add a simple strndup() implementation for win32. 2010-11-07 18:31:48 -02:00
Stefan Sommerfeld
ee5bd670d4 Fix for size_t in UpnpString. 2010-11-07 18:31:48 -02:00
Stefan Sommerfeld
fcb5e7c438 Fix for size_t related warnings. 2010-11-07 18:31:48 -02:00
Stefan Sommerfeld
243cd41974 Fix for inline usage. 2010-11-07 18:31:48 -02:00
Marcelo Roberto Jimenez
853cd32cfe Remove unused parameter bufferLen from GetDescDocumentAndURL(). 2010-11-07 18:31:48 -02:00
Marcelo Roberto Jimenez
f384e54fc6 Consistent usage of win32 INVALID_SOCKET and SOCKET_ERROR.
On win32 socket() returns INVALID_SOCKET, which is unsigned,
on error, not -1.

Also, most network functions return SOCKET_ERROR.

This patch tries to make the usage consistent.
2010-11-07 18:31:47 -02:00
Stefan Sommerfeld
9e12768cdb Fixed server port definition. 2010-11-07 18:31:47 -02:00
Stefan Sommerfeld
4b47e6a51d Fix for mixed usage of SOCKET and int. 2010-11-07 17:52:14 -02:00
Stefan Sommerfeld
a5fb5edfc9 Make notify_send_and_recv() return the appropriate error code.
notify_send_and_recv() was returning the connection fd.
2010-11-07 17:52:14 -02:00
Marcelo Roberto Jimenez
8bd32d330b Proper inclusion of inet_pton.h for win32. 2010-11-07 17:52:14 -02:00
Stefan Sommerfeld
00eb52cc85 fixed wrong declaration of inet_ntop4 2010-11-07 17:52:14 -02:00
Marcelo Roberto Jimenez
ff006272b5 PTHREAD_MUTEX_RECURSIVE on DragonFly is an enum.
SF Bug Tracker - ID: 3104527
Submitted: OBATA Akio ( obache ) - 2010-11-07 07:10:28 BRST

In threadutil/inc/ithread.h, it is expected that
PTHREAD_MUTEX_RECURSIVE is defined as macro. But on DragonFly BSD,
it is defined as enum, so not works as expected.

Attachment patch treat that DragonFly BSD always
have PTHREAD_MUTEX_RECURSIVE.
2010-11-07 11:49:33 -02:00
Marcelo Roberto Jimenez
852c301c5c ftime(3) in -lcompat should not be checked.
SF Bug Tracker - ID: 3104521
Submitted: OBATA Akio ( obache ) - 2010-11-07 07:03:44 BRST

In configure.ac
AC_CHECK_FUNCS(ftime,, [AC_CHECK_LIB(compat, ftime)])

But since version 1.6.3, ftime(3) is not used, so it should be
removed, or introduce unwanted linkage with -lcompat.
2010-11-07 09:45:05 -02:00
Marcelo Roberto Jimenez
d270499cd8 Homekeeping for the next release. 2010-11-07 01:43:50 -02:00
Marcelo Roberto Jimenez
6ac867bbb1 Fix the library numbers for release. 2010-11-07 01:33:18 -02:00
Marcelo Roberto Jimenez
9052ca95be Fix broken Makefile.am and remove unused file utilall.h. 2010-11-06 19:41:47 -02:00
Marcelo Roberto Jimenez
ef7edf6cf8 Fix for "SampleUtil_Initialize was called multiple times!" bug.
Fix for bug introduced in samples code in svn revision 502, commit
git:25c908c558c8e60eb386c155a6b93add447ffec0

Sample device and combo were aborting with the message:
"***** SampleUtil_Initialize was called multiple times!"
2010-11-06 00:45:24 -02:00
Fabrice Fontaine
c65ec8a720 Make multiple SSDP advertisements faster.
Put the loop to send multiple copies of each SSDP advertisements in
ssdp_server.c instead of ssdp_device.c so we have only one call to
imillisleep ( SSDP_PAUSE ) to speed up advertisements.
2010-11-05 23:52:17 -02:00
Fabrice Fontaine
2d22e997e1 Removing unused NUM_COPY variable.
Previously, NUM_COPY was used in ssdp_device.c to send multiple copies
of each advertisements but also multiple replies to each M-SEARCH
request. As sending multiple replies is not compliant with HTTPU/MU
spec, NUM_COPY has been set to 1 in an older patch. However, as this
variable is not needed and has been replaced with SSDP_COPY, it has
been removed.
2010-11-05 23:52:11 -02:00
Fabrice Fontaine
96dc968f18 Use SSDP_COPY to send multiple SSDP advertisements.
Currently, SSDP_COPY is used only to send multiple M-SEARCH requests (in
ssdp_ctrlpt.c). With this patch, SSDP_COPY is also used to send multiple
copies of each advertisements packets (in ssdp_device.c).
2010-11-05 13:25:40 -02:00
Carl Benson
8e846368e0 patch for taking notice of UPNP_USE_RWLOCK flag in threadutil
By "Carl Benson" <carl.benson@windriver.com>:

I had to do some modifications myself though, because the Android
build system insists on having a file named "util.h" taking precedence
in its include path, libupnp gets confused because of the same filename
in upnp/src/inc/util.h
2010-11-01 01:06:11 -02:00
Marcelo Roberto Jimenez
d6671c464f Bump config to 1.6.9. 2010-11-01 01:03:40 -02:00
Marcelo Roberto Jimenez
699dd3c82e Missed this line in configure.ac in the homekeeping commit. 2010-10-21 09:55:54 -02:00
Marcelo Roberto Jimenez
9be360bcd1 Homekeeping for the next release. 2010-10-20 11:15:23 -02:00
103 changed files with 12149 additions and 19438 deletions

6
.gitignore vendored
View File

@@ -98,8 +98,8 @@ 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
upnp/sample/tv_combo
upnp/sample/tv_ctrlpt
upnp/sample/tv_device
docs/doxygen

167
ChangeLog
View File

@@ -1,3 +1,170 @@
*******************************************************************************
Version 1.6.10
*******************************************************************************
2010-11-23 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Major bug fix in http_SendMessage.
Currently, http_SendMessage was not able to write to write a buffer
due to a bad use of file_buf instead of buf. This bug was introduced by
the 0197-Doxygen-reformating-compiler-warnings patch.
2010-11-23 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Returning the Sid in Upnp_Event_Subscribe.
Currently, Upnp_Event_Subscribe always contains an empty chain in the
Sid parameter. This patch now saves the client Subscription ID in this
parameter so Control Points can see and use the same SID in the
Upnp_Event_Subscribe and in the Upnp_Event structures.
2010-11-22 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Two fixes from Juergen Lock <nox(at)jelal.kn-bremen.de>:
1. varargs: pass size of CRLF as size_t not as int:
--- upnp/src/gena/gena_device.c.orig
+++ upnp/src/gena/gena_device.c
@@ -225,7 +225,7 @@ static UPNP_INLINE int notify_send_and_r
"bbb",
start_msg.buf, start_msg.length,
propertySet, strlen(propertySet),
- "\r\n", 2);
+ "\r\n", sizeof "\r\n" - 1);
if (ret_code) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
2. Remove "b" arg here, there is no buffer passed: (this caused a pointer
to be interpreted as a buffer size to be alloc'd/copied, hence the 32 GB.)
--- upnp/src/genlib/net/http/webserver.c.orig
+++ upnp/src/genlib/net/http/webserver.c
@@ -1262,7 +1262,7 @@ static int process_request(
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
if (http_MakeMessage(headers, resp_major, resp_minor,
- "R" "TLD" "s" "tcS" "b" "Xc" "sCc",
+ "R" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
RespInstr, // language info
2010-11-15 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Added the convenience function UpnpResolveURL2() to upnptools.c.
This function avoids some unecessary memory allocation.
The memory alloc'd by this function must be freed later by the caller.
2010-11-10 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Add GENA_NOTIFICATION_xxx_TIMEOUT variable.
Currently, in notify_send_and_recv function, pupnp waits for
HTTP_DEFAULT_TIMEOUT seconds when trying to send a GENA notification.
When there is a lot of notifications with CPs which was disconnected
without unsusbcribing, all the pupnp threads are blocked on this
timeout. To correct, this issue, this patch adds a new variable,
GENA_NOTIFICATION_SENDING_TIMEOUT, which can be used to lower the
timeout so GENA threads return quickly when writing is impossible. By
the same mean, pupnp waits the CP's answer to the NOTIFY for
HTTP_DEFAULT_TIMEOUT seconds, so this patch adds a new variable,
GENA_NOTIFICATION_ANSWERING_TIMEOUT, to customize this value.
2010-11-10 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Add --disable-blocking-tcp-connections flag.
Currently, pupnp is using a blocking connect to sends GENA
notifications. As a result, when there is a lot of notifications with
CPs which were disconnected without unsusbcribing, all the pupnp
threads are blocked for 20s (timeout). To correct this issue, this
patch replace the call to connect with a call to private_connect and add
a compilation flag to disable blocking TCP connections, so if we are not
able to connect to the CP, the notification is lost.
2010-11-07 Stefan Sommerfeld <zerocom(at)cs.tu-berlin.de>
Several patches for windows compatibility and fixing warnings.
2010-11-07 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
PTHREAD_MUTEX_RECURSIVE on DragonFly is an enum.
SF Bug Tracker - ID: 3104527
Submitted: OBATA Akio ( obache ) - 2010-11-07 07:10:28 BRST
In threadutil/inc/ithread.h, it is expected that
PTHREAD_MUTEX_RECURSIVE is defined as macro. But on DragonFly BSD,
it is defined as enum, so not works as expected.
Attachment patch treat that DragonFly BSD always
have PTHREAD_MUTEX_RECURSIVE.
2010-11-07 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
ftime(3) in -lcompat should not be checked.
SF Bug Tracker - ID: 3104521
Submitted: OBATA Akio ( obache ) - 2010-11-07 07:03:44 BRST
In configure.ac
AC_CHECK_FUNCS(ftime,, [AC_CHECK_LIB(compat, ftime)])
But since version 1.6.3, ftime(3) is not used, so it should be
removed, or introduce unwanted linkage with -lcompat.
*******************************************************************************
Version 1.6.9
*******************************************************************************
2010-11-06 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Fix for bug introduced in samples code in svn revision 502, commit
git:25c908c558c8e60eb386c155a6b93add447ffec0
Sample device and combo were aborting with the message:
"***** SampleUtil_Initialize was called multiple times!"
2010-11-06 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Make multiple SSDP advertisements faster.
Put the loop to send multiple copies of each SSDP advertisements in
ssdp_server.c instead of ssdp_device.c so we have only one call to
imillisleep ( SSDP_PAUSE ) to speed up advertisements.
2010-11-05 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Removing unused NUM_COPY variable.
Previously, NUM_COPY was used in ssdp_device.c to send multiple copies
of each advertisements but also multiple replies to each M-SEARCH
request. As sending multiple replies is not compliant with HTTPU/MU
spec, NUM_COPY has been set to 1 in an older patch. However, as this
variable is not needed and has been replaced with SSDP_COPY, it has
been removed.
2010-11-05 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Use SSDP_COPY to send multiple SSDP advertisements.
Currently, SSDP_COPY is used only to send multiple M-SEARCH requests (in
ssdp_ctrlpt.c). With this patch, SSDP_COPY is also used to send multiple
copies of each advertisements packets (in ssdp_device.c).
2010-11-01 Carl Benson <carl.benson(at)windriver.com>
Fix for Android build.
I had to do some modifications myself though, because the Android
build system insists on having a file named "util.h" taking precedence
in its include path, libupnp gets confused because of the same filename
in upnp/src/inc/util.h
*******************************************************************************
Version 1.6.8
*******************************************************************************

View File

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

6
THANKS
View File

@@ -13,6 +13,7 @@ exempt of errors.
- Arno Willig
- Bob Ciora
- Carlo Parata
- Carl Benson
- Chandra (inactiveneurons)
- Chaos
- Charles Nepveu (cnepveu)
@@ -29,12 +30,13 @@ exempt of errors.
- Fabrice Fontaine
- Fredrik Svensson
- Glen Masgai
- Hartmut Holzgraefe - hholzgra
- Hartmut Holzgraefe (hholzgra)
- Ingo Hofmann
- Jiri Zouhar
- John Dennis
- Jonathan Casiot (no_dice)
- Josh Carroll
- Juergen Lock
- Keith Brindley
- Leuk_He
- Loigu
@@ -44,6 +46,7 @@ exempt of errors.
- Nektarios K. Papadopoulos (npapadop)
- Nicholas Kraft
- Nick Leverton (leveret)
- Obata Akio (obache)
- Oskar Liljeblad
- Michael (oxygenic)
- Paul Vixie
@@ -52,6 +55,7 @@ exempt of errors.
- Robert Gingher (robsbox)
- Ronan Menard
- Siva Chandran
- Stefan Sommerfeld (zerocom)
- Stéphane Corthésy
- Steve Bresson
- Timothy Redaelli

View File

@@ -19,15 +19,9 @@
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#define HAVE_FSEEKO 1
/* Define to 1 if you have the `ftime' function. */
#define HAVE_FTIME 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `compat' library (-lcompat). */
/* #undef HAVE_LIBCOMPAT */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
@@ -105,13 +99,13 @@
#define PACKAGE_NAME "libupnp"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libupnp 1.6.8"
#define PACKAGE_STRING "libupnp 1.6.10"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libupnp"
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.6.8"
#define PACKAGE_VERSION "1.6.10"
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
@@ -120,6 +114,9 @@
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* see upnpconfig.h */
#define UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS 1
/* see upnpconfig.h */
/* #undef UPNP_ENABLE_IPV6 */
@@ -151,19 +148,19 @@
#define UPNP_VERSION_MINOR 6
/* see upnpconfig.h */
#define UPNP_VERSION_PATCH 8
#define UPNP_VERSION_PATCH 10
/* see upnpconfig.h */
#define UPNP_VERSION_STRING "1.6.8"
#define UPNP_VERSION_STRING "1.6.10"
/* Version number of package */
#define VERSION "1.6.8"
#define VERSION "1.6.10"
/* File Offset size */
#define _FILE_OFFSET_BITS 64
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
/* #undef _LARGEFILE_SOURCE */
#define _LARGEFILE_SOURCE 1
/* Large files support */
#define _LARGE_FILE_SOURCE /**/

View File

@@ -40,7 +40,7 @@
***************************************************************************/
/** The library version (string) e.g. "1.3.0" */
#define UPNP_VERSION_STRING "1.6.8"
#define UPNP_VERSION_STRING "1.6.10"
/** Major version of the library */
#define UPNP_VERSION_MAJOR 1
@@ -49,7 +49,7 @@
#define UPNP_VERSION_MINOR 6
/** Patch version of the library */
#define UPNP_VERSION_PATCH 8
#define UPNP_VERSION_PATCH 10
/** The library version (numeric) e.g. 10300 means version 1.3.0 */
#define UPNP_VERSION \

View File

@@ -9,7 +9,7 @@
AC_PREREQ(2.60)
AC_INIT([libupnp], [1.6.8], [mroberto@users.sourceforge.net])
AC_INIT([libupnp], [1.6.10], [mroberto@users.sourceforge.net])
dnl ############################################################################
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:
@@ -175,14 +175,46 @@ dnl # - Code has changed in threadutil
dnl # revision: 0 -> 1
dnl # - Code has changed in upnp
dnl # revision: 0 -> 1
dnl #
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 # Release 1.6.9:
dnl # "current:revision:age"
dnl #
dnl # - Code has changed in threadutil
dnl # revision: 1 -> 2
dnl # - Code has changed in upnp
dnl # revision: 1 -> 2
dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:5:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:2:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [4:2:0])
dnl #
dnl ############################################################################
dnl # Release 1.6.10:
dnl # "current:revision:age"
dnl #
dnl # - Code has changed inxml
dnl # revision: 5 -> 6
dnl # - Code has changed in threadutil
dnl # revision: 2 -> 3
dnl # - Code has changed in upnp
dnl # revision: 2 -> 3
dnl # - interface has changed in upnp
dnl # current: 4 -> 5
dnl # revision: 3 -> 0
dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:6:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:3:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [5:0:0])
dnl #
############################################################################
AC_SUBST([LT_VERSION_IXML], [2:6:0])
AC_SUBST([LT_VERSION_THREADUTIL], [5:3:2])
AC_SUBST([LT_VERSION_UPNP], [5:0:0])
dnl ############################################################################
dnl # Repeating the algorithm to place it closer to the modificatin place:
dnl # - library code modified: revision++
@@ -286,6 +318,11 @@ if test "x$enable_notification_reordering" = xyes ; then
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([blocking_tcp_connections], [yes], [blocking TCP connections])
if test "x$enable_blocking_tcp_connections" = xyes ; then
AC_DEFINE(UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code])
@@ -450,7 +487,6 @@ fi
#
AC_FUNC_VPRINTF
AC_FUNC_FSEEKO
AC_CHECK_FUNCS(ftime,, [AC_CHECK_LIB(compat, ftime)])
#
# Solaris needs -lsocket -lnsl -lrt
AC_SEARCH_LIBS([bind], [socket])

View File

@@ -40,8 +40,11 @@ void IxmlPrintf(
;
#else /* DEBUG */
static UPNP_INLINE void IxmlPrintf(
const char* FmtStr,
...) {}
const char *FmtStr,
...)
{
FmtStr = FmtStr;
}
#endif /* DEBUG */
@@ -59,6 +62,8 @@ static UPNP_INLINE void printNodes(
IXML_Node *tmpRoot,
int depth)
{
tmpRoot = tmpRoot;
depth = depth;
}
#endif

View File

@@ -139,7 +139,7 @@ int ixmlDocument_createElementEx(
errCode = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler;
}
// set the node fields
/* set the node fields */
newElement->n.nodeType = eELEMENT_NODE;
newElement->n.nodeName = strdup(tagName);
if (newElement->n.nodeName == NULL) {
@@ -229,7 +229,7 @@ int ixmlDocument_createTextNodeEx(
rc = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler;
}
// initialize the node
/* initialize the node */
ixmlNode_init(returnNode);
returnNode->nodeName = strdup(TEXTNODENAME);
@@ -239,7 +239,7 @@ int ixmlDocument_createTextNodeEx(
rc = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler;
}
// add in node value
/* add in node value */
if (data != NULL) {
returnNode->nodeValue = strdup(data);
if (returnNode->nodeValue == NULL) {
@@ -295,7 +295,7 @@ int ixmlDocument_createAttributeEx(
ixmlAttr_init(attrNode);
attrNode->n.nodeType = eATTRIBUTE_NODE;
// set the node fields
/* set the node fields */
attrNode->n.nodeName = strdup(name);
if (attrNode->n.nodeName == NULL) {
ixmlAttr_free(attrNode);
@@ -343,7 +343,7 @@ int ixmlDocument_createAttributeNSEx(
if (errCode != IXML_SUCCESS) {
goto ErrorHandler;
}
// set the namespaceURI field
/* set the namespaceURI field */
attrNode->n.namespaceURI = strdup(namespaceURI);
if (attrNode->n.namespaceURI == NULL) {
ixmlAttr_free(attrNode);
@@ -351,7 +351,7 @@ int ixmlDocument_createAttributeNSEx(
errCode = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler;
}
// set the localName and prefix
/* set the localName and prefix */
errCode =
ixmlNode_setNodeName((IXML_Node *)attrNode, qualifiedName);
if (errCode != IXML_SUCCESS) {
@@ -458,7 +458,7 @@ int ixmlDocument_createElementNSEx(
line = __LINE__;
goto ErrorHandler;
}
// set the namespaceURI field
/* set the namespaceURI field */
newElement->n.namespaceURI = strdup(namespaceURI);
if (newElement->n.namespaceURI == NULL) {
line = __LINE__;
@@ -467,7 +467,7 @@ int ixmlDocument_createElementNSEx(
ret = IXML_INSUFFICIENT_MEMORY;
goto ErrorHandler;
}
// set the localName and prefix
/* set the localName and prefix */
ret = ixmlNode_setNodeName((IXML_Node *)newElement, qualifiedName);
if (ret != IXML_SUCCESS) {
line = __LINE__;

View File

@@ -110,7 +110,7 @@ int ixmlElement_setAttribute(
{
IXML_Node *attrNode;
IXML_Attr *newAttrNode;
short errCode = IXML_SUCCESS;
int errCode = IXML_SUCCESS;
if (element == NULL || name == NULL || value == NULL) {
errCode = IXML_INVALID_PARAMETER;
@@ -208,7 +208,8 @@ IXML_Attr *ixmlElement_getAttributeNode(IXML_Element *element, const DOMString n
attrNode = element->n.firstAttr;
while (attrNode != NULL) {
if (strcmp(attrNode->nodeName, name) == 0) { // found it
if (strcmp(attrNode->nodeName, name) == 0) {
/* found it */
break;
} else {
attrNode = attrNode->nextSibling;
@@ -555,7 +556,7 @@ IXML_Attr *ixmlElement_getAttributeNodeNS(
while (attrNode != NULL) {
if (strcmp(attrNode->localName, localName) == 0 &&
strcmp(attrNode->namespaceURI, namespaceURI) == 0) {
// found it
/* found it */
break;
} else {
attrNode = attrNode->nextSibling;

View File

@@ -166,7 +166,7 @@ int ixml_membuf_insert(
size_t buf_len,
/*! [in] The point of insertion relative to the beggining of the
* ixml_membuf internal buffer. */
int index);
size_t index);
#endif /* IXML_MEMBUF_H */

View File

@@ -54,37 +54,29 @@ static void copy_with_escape(
/*! [in] The string to copy from. */
const char *p)
{
int i;
int plen;
size_t i;
size_t plen;
if (p == NULL) {
if (p == NULL)
return;
}
plen = strlen( p );
for (i = 0; i < plen; i++) {
plen = strlen(p);
for (i = 0; i < plen; ++i) {
switch (p[i]) {
case '<':
ixml_membuf_append_str(buf, "&lt;");
break;
case '>':
ixml_membuf_append_str(buf, "&gt;");
break;
case '&':
ixml_membuf_append_str(buf, "&amp;");
break;
case '\'':
ixml_membuf_append_str(buf, "&apos;");
break;
case '\"':
ixml_membuf_append_str(buf, "&quot;");
break;
default:
ixml_membuf_append(buf, &p[i]);
break;
@@ -161,11 +153,11 @@ static void ixmlPrintDomTreeRecursive(
} else {
ixml_membuf_append_str(buf, ">");
}
// output the children
/* output the children */
ixmlPrintDomTreeRecursive(
ixmlNode_getFirstChild(nodeptr), buf);
// Done with children. Output the end tag.
/* Done with children. Output the end tag. */
ixml_membuf_append_str(buf, "</");
ixml_membuf_append_str(buf, nodeName);
@@ -242,11 +234,11 @@ static void ixmlPrintDomTree(
ixml_membuf_append_str(buf, ">");
}
// output the children
/* output the children */
ixmlPrintDomTreeRecursive(
ixmlNode_getFirstChild(nodeptr), buf);
// Done with children. Output the end tag.
/* Done with children. Output the end tag. */
ixml_membuf_append_str(buf, "</");
ixml_membuf_append_str(buf, nodeName);
ixml_membuf_append_str(buf, ">\r\n");
@@ -314,10 +306,10 @@ static void ixmlDomTreetoString(
ixml_membuf_append_str(buf, ">");
}
// output the children
/* output the children */
ixmlPrintDomTreeRecursive(ixmlNode_getFirstChild(nodeptr), buf);
// Done with children. Output the end tag.
/* Done with children. Output the end tag. */
ixml_membuf_append_str(buf, "</");
ixml_membuf_append_str(buf, nodeName);
ixml_membuf_append_str(buf, ">");

View File

@@ -41,7 +41,7 @@ void IxmlPrintf(
void printNodes(IXML_Node *tmpRoot, int depth)
{
int i;
unsigned long i;
IXML_NodeList *NodeList1;
IXML_Node *ChildNode1;
unsigned short NodeType;

View File

@@ -75,10 +75,10 @@ static int ixml_membuf_set_size(
diff = new_length - m->length;
alloc_len = MAXVAL(m->size_inc, diff) + m->capacity;
} else {
// decrease length
/* decrease length */
assert(new_length <= m->length);
// if diff is 0..m->size_inc, don't free
/* if diff is 0..m->size_inc, don't free */
if ((m->capacity - new_length) <= m->size_inc) {
return 0;
}
@@ -135,21 +135,21 @@ int ixml_membuf_assign(
assert(m != NULL);
// set value to null
/* set value to null */
if (buf == NULL) {
ixml_membuf_destroy(m);
return IXML_SUCCESS;
}
// alloc mem
/* alloc mem */
return_code = ixml_membuf_set_size(m, buf_len);
if (return_code != 0) {
return return_code;
}
// copy
/* copy */
memcpy(m->buf, buf, buf_len);
// null-terminate
/* null-terminate */
m->buf[buf_len] = 0;
m->length = buf_len;
@@ -187,13 +187,13 @@ int ixml_membuf_insert(
INOUT ixml_membuf *m,
IN const void *buf,
IN size_t buf_len,
int index)
size_t index)
{
int return_code = 0;
assert(m != NULL);
if (index < 0 || index > (int)m->length) {
if (index > m->length) {
return IXML_INDEX_SIZE_ERR;
}

File diff suppressed because it is too large Load Diff

View File

@@ -85,7 +85,7 @@ IXML_Node *ixmlNamedNodeMap_getNamedItem(
IXML_NamedNodeMap *nnMap,
const DOMString name)
{
long index;
unsigned long index;
if (nnMap == NULL || name == NULL) {
return NULL;
@@ -95,7 +95,7 @@ IXML_Node *ixmlNamedNodeMap_getNamedItem(
if (index == IXML_INVALID_ITEM_NUMBER) {
return NULL;
} else {
return ixmlNamedNodeMap_item(nnMap, (unsigned long)index);
return ixmlNamedNodeMap_item(nnMap, index);
}
}
@@ -165,7 +165,7 @@ int ixmlNamedNodeMap_addToNamedNodeMap(
}
if (*nnMap == NULL) {
// nodelist is empty
/* nodelist is empty */
*nnMap = (IXML_NamedNodeMap *)malloc(sizeof (IXML_NamedNodeMap));
if (*nnMap == NULL) {
return IXML_INSUFFICIENT_MEMORY;

View File

@@ -542,11 +542,11 @@ int ixmlNode_replaceChild(
if (ixmlNode_allowChildren(nodeptr, newChild) == FALSE) {
return IXML_HIERARCHY_REQUEST_ERR;
}
// if newChild was created from a different document
/* if newChild was created from a different document */
if (nodeptr->ownerDocument != newChild->ownerDocument) {
return IXML_WRONG_DOCUMENT_ERR;
}
// if refChild is not a child of nodeptr
/* if refChild is not a child of nodeptr */
if (ixmlNode_isParent(nodeptr, oldChild) != TRUE) {
return IXML_NOT_FOUND_ERR;
}
@@ -763,6 +763,10 @@ static IXML_Element *ixmlNode_cloneElement(
/*!
* \brief Returns a clone of a document node.
*
* Currently, the IXML_Document struct is just a node, so this function
* just mallocs the IXML_Document, sets the node type and name. Curiously,
* the parameter nodeptr is not actually used.
*
* \return A clone of a document node.
*/
static IXML_Document *ixmlNode_cloneDoc(
@@ -781,7 +785,7 @@ static IXML_Document *ixmlNode_cloneDoc(
}
ixmlDocument_init(newDoc);
docNode = (IXML_Node *) newDoc;
docNode = (IXML_Node *)newDoc;
rc = ixmlNode_setNodeName(docNode, DOCUMENTNODENAME);
if (rc != IXML_SUCCESS) {
@@ -792,6 +796,7 @@ static IXML_Document *ixmlNode_cloneDoc(
newDoc->n.nodeType = eDOCUMENT_NODE;
return newDoc;
nodeptr = nodeptr;
}
/*!

View File

@@ -57,11 +57,11 @@ IXML_Node *ixmlNodeList_item(
IXML_NodeList *next;
unsigned int i;
// if the list ptr is NULL
/* if the list ptr is NULL */
if (nList == NULL) {
return NULL;
}
// if index is more than list length
/* if index is more than list length */
if (index > ixmlNodeList_length(nList) - 1) {
return NULL;
}
@@ -93,7 +93,7 @@ int ixmlNodeList_addToNodeList(
}
if (*nList == NULL) {
// nodelist is empty
/* nodelist is empty */
*nList = (IXML_NodeList *)malloc(sizeof (IXML_NodeList));
if (*nList == NULL) {
return IXML_INSUFFICIENT_MEMORY;

View File

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

View File

@@ -29,118 +29,99 @@
*
******************************************************************************/
#ifndef FREE_LIST_H
#define FREE_LIST_H
/*!
* \file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "ithread.h"
#include <errno.h>
/****************************************************************************
* Name: FreeListNode
*
* Description:
* free list node. points to next free item.
* memory for node is borrowed from allocated items.
* Internal Use Only.
*****************************************************************************/
/*!
* Free list node. points to next free item.
* Memory for node is borrowed from allocated items.
* \internal
*/
typedef struct FREELISTNODE
{
struct FREELISTNODE *next;
} FreeListNode;
/****************************************************************************
* Name: FreeList
*
* Description:
/*!
* Stores head and size of free list, as well as mutex for protection.
* Internal Use Only.
*****************************************************************************/
* \internal
*/
typedef struct FREELIST
{
FreeListNode *head;
size_t element_size;
int maxFreeListLength;
int freeListLength;
} FreeList;
}FreeList;
/****************************************************************************
* Function: FreeListInit
/*!
* \brief Initializes Free List.
*
* Description:
* Initializes Free List. Must be called first.
* And only once for FreeList.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* size_t - size of elements to store in free list
* maxFreeListSize - max size that the free list can grow to
* before returning memory to O.S.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListInit(FreeList *free_list,
* Must be called first and only once for FreeList.
*
* \return:
* \li \c 0 on success.
* \li \c EINVAL on failure.
*/
int FreeListInit(
/*! Must be valid, non null, pointer to a linked list. */
FreeList *free_list,
/*! Size of elements to store in free list. */
size_t elementSize,
int maxFreeListSize);
/*! Max size that the free list can grow to before returning
* memory to O.S. */
int maxFreeListLength);
/****************************************************************************
* Function: FreeListAlloc
/*!
* \brief Allocates chunk of set size.
*
* Description:
* Allocates chunk of set size.
* If a free item is available in the list, returnes the stored item.
* Otherwise calls the O.S. to allocate memory.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* Non NULL on success. NULL on failure.
*****************************************************************************/
void * FreeListAlloc (FreeList *free_list);
/****************************************************************************
* Function: FreeListFree
* If a free item is available in the list, returnes the stored item,
* otherwise calls the O.S. to allocate memory.
*
* Description:
* Returns an item to the Free List.
* If the free list is smaller than the max size than
* adds the item to the free list.
* Otherwise returns the item to the O.S.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListFree (FreeList *free_list,void * element);
* \return Non NULL on success. NULL on failure.
*/
void *FreeListAlloc(
/*! Must be valid, non null, pointer to a linked list. */
FreeList *free_list);
/****************************************************************************
* Function: FreeListDestroy
/*!
* \brief Returns an item to the Free List.
*
* Description:
* Releases the resources stored with the free list.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int FreeListDestroy (FreeList *free_list);
* If the free list is smaller than the max size then adds the item to the
* free list, otherwise returns the item to the O.S.
*
* \return:
* \li \c 0 on success.
* \li \c EINVAL on failure.
*/
int FreeListFree(
/*! Must be valid, non null, pointer to a free list. */
FreeList *free_list,
/*! Must be a pointer allocated by FreeListAlloc. */
void *element);
/*!
* \brief Releases the resources stored with the free list.
*
* \return:
* \li \c 0 on success.
* \li \c EINVAL on failure.
*/
int FreeListDestroy(
/*! Must be valid, non null, pointer to a linked list. */
FreeList *free_list);
#ifdef __cplusplus
}

View File

@@ -29,58 +29,34 @@
*
******************************************************************************/
#ifndef LINKED_LIST_H
#define LINKED_LIST_H
/*!
* \file
*/
#include "FreeList.h"
#ifdef __cplusplus
extern "C" {
#endif
#define EOUTOFMEM (-7 & 1<<29)
#define FREELISTSIZE 100
#define LIST_SUCCESS 1
#define LIST_FAIL 0
/****************************************************************************
* Name: free_routine
*
* Description:
* Function for freeing list items
*****************************************************************************/
/*! Function for freeing list items. */
typedef void (*free_function)(void *arg);
/****************************************************************************
* Name: cmp_routine
*
* Description:
* Function for comparing list items
* Returns 1 if itemA==itemB
*****************************************************************************/
/*! Function for comparing list items. Returns 1 if itemA==itemB */
typedef int (*cmp_routine)(void *itemA,void *itemB);
/****************************************************************************
* Name: ListNode
*
* Description:
* linked list node. stores generic item and pointers to next and prev.
* Internal Use Only.
*****************************************************************************/
/*! Linked list node. Stores generic item and pointers to next and prev.
* \internal
*/
typedef struct LISTNODE
{
struct LISTNODE *prev;
@@ -88,14 +64,10 @@ typedef struct LISTNODE
void *item;
} ListNode;
/****************************************************************************
* Name: LinkedList
/*!
* Linked list (no protection).
*
* Description:
* linked list (no protection). Internal Use Only.
* Because this is for internal use, parameters are NOT checked for
* validity.
* Because this is for internal use, parameters are NOT checked for validity.
* The first item of the list is stored at node: head->next
* The last item of the list is stored at node: tail->prev
* If head->next=tail, then list is empty.
@@ -103,249 +75,211 @@ typedef struct LISTNODE
*
* LinkedList g;
* ListNode *temp = NULL;
* for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp))
* {
* for (temp = ListHead(g);temp!=NULL;temp = ListNext(g,temp)) {
* }
*
*****************************************************************************/
* \internal
*/
typedef struct LINKEDLIST
{
ListNode head; /* head, first item is stored at: head->next */
ListNode tail; /* tail, last item is stored at: tail->prev */
long size; /* size of list */
FreeList freeNodeList; /* free list to use */
free_function free_func; /* free function to use */
cmp_routine cmp_func; /* compare function to use */
/*! head, first item is stored at: head->next */
ListNode head;
/*! tail, last item is stored at: tail->prev */
ListNode tail;
/*! size of list */
long size;
/*! free list to use */
FreeList freeNodeList;
/*! free function to use */
free_function free_func;
/*! compare function to use */
cmp_routine cmp_func;
} LinkedList;
/****************************************************************************
* Function: ListInit
/*!
* \brief Initializes LinkedList. Must be called first and only once for List.
*
* Description:
* Initializes LinkedList. Must be called first.
* And only once for List.
* Parameters:
* list - must be valid, non null, pointer to a linked list.
* cmp_func - function used to compare items. (May be NULL)
* free_func - function used to free items. (May be NULL)
* Returns:
* 0 on success, EOUTOFMEM on failure.
*****************************************************************************/
int ListInit(LinkedList *list,cmp_routine cmp_func, free_function free_func);
* \return
* \li \c 0 on success.
* \li \c EOUTOFMEM on failure.
*/
int ListInit(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Function used to compare items. (May be NULL). */
cmp_routine cmp_func,
/*! Function used to free items. (May be NULL). */
free_function free_func);
/****************************************************************************
* Function: ListAddHead
/*!
* \brief Adds a node to the head of the list. Node gets immediately after
* list head.
*
* Description:
* Adds a node to the head of the list.
* Node gets immediately after list.head.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddHead(LinkedList *list, void *item);
/****************************************************************************
* Function: ListAddTail
*
* Description:
* Adds a node to the tail of the list.
* Node gets added immediately before list.tail.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddTail(LinkedList *list, void *item);
* \return The pointer to the ListNode on success, NULL on failure.
*/
ListNode *ListAddHead(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item);
/*!
* \brief Adds a node to the tail of the list. Node gets added immediately
* before list.tail.
*
* Precondition: The list has been initialized.
*
* \return The pointer to the ListNode on success, NULL on failure.
*/
ListNode *ListAddTail(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item);
/****************************************************************************
* Function: ListAddAfter
/*!
* \brief Adds a node after the specified node. Node gets added immediately
* after bnode.
*
* Description:
* Adds a node after the specified node.
* Node gets added immediately after bnode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* ListNode * bnode - node to add after
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode);
* Precondition: The list has been initialized.
*
* \return The pointer to the ListNode on success, NULL on failure.
*/
ListNode *ListAddAfter(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item,
/*! Node to add after. */
ListNode *bnode);
/*!
* \brief Adds a node before the specified node. Node gets added immediately
* before anode.
*
* Precondition: The list has been initialized.
*
* \return The pointer to the ListNode on success, NULL on failure.
*/
ListNode *ListAddBefore(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Item to be added. */
void *item,
/*! Node to add in front of. */
ListNode *anode);
/****************************************************************************
* Function: ListAddBefore
/*!
* \brief Removes a node from the list. The memory for the node is freed.
*
* Description:
* Adds a node before the specified node.
* Node gets added immediately before anode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode * anode - node to add the in front of.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *ListAddBefore(LinkedList *list,void *item, ListNode *anode);
* Precondition: The list has been initialized.
*
* \return The pointer to the item stored in the node or NULL if the item
* is freed.
*/
void *ListDelNode(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Node to delete. */
ListNode *dnode,
/*! if !0 then item is freed using free function. If 0 (or free
* function is NULL) then item is not freed. */
int freeItem);
/*!
* \brief Removes all memory associated with list nodes. Does not free
* LinkedList *list.
*
* Precondition: The list has been initialized.
*
* \return 0 on success, EINVAL on failure.
*/
int ListDestroy(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! if !0 then item is freed using free function. If 0 (or free
* function is NULL) then item is not freed. */
int freeItem);
/****************************************************************************
* Function: ListDelNode
/*!
* \brief Returns the head of the list.
*
* Description:
* Removes a node from the list
* The memory for the node is freed.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *dnode - done to delete.
* freeItem - if !0 then item is freed using free function.
* if 0 (or free function is NULL) then item is not freed
* Returns:
* The pointer to the item stored in the node or NULL if the item is freed.
* Precondition:
* The list has been initialized.
*****************************************************************************/
void *ListDelNode(LinkedList *list,ListNode *dnode, int freeItem);
* Precondition: The list has been initialized.
*
* \return The head of the list. NULL if list is empty.
*/
ListNode *ListHead(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list);
/*!
* \brief Returns the tail of the list.
*
* Precondition: The list has been initialized.
*
* \return The tail of the list. NULL if list is empty.
*/
ListNode *ListTail(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list);
/****************************************************************************
* Function: ListDestroy
/*!
* \brief Returns the next item in the list.
*
* Description:
* Removes all memory associated with list nodes.
* Does not free LinkedList *list.
* Precondition: The list has been initialized.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* freeItem - if !0 then items are freed using the free_function.
* if 0 (or free function is NULL) then items are not freed.
* Returns:
* 0 on success. Always returns 0.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int ListDestroy(LinkedList *list, int freeItem);
* \return The next item in the list. NULL if there are no more items in list.
*/
ListNode *ListNext(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Node from the list. */
ListNode *node);
/*!
* \brief Returns the previous item in the list.
*
* Precondition: The list has been initialized.
*
* \return The previous item in the list. NULL if there are no more items in list.
*/
ListNode *ListPrev(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! Node from the list. */
ListNode *node);
/****************************************************************************
* Function: ListHead
/*!
* \brief Finds the specified item in the list.
*
* Description:
* Returns the head of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The head of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListHead(LinkedList *list);
/****************************************************************************
* Function: ListTail
*
* Description:
* Returns the tail of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The tail of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListTail(LinkedList *list);
/****************************************************************************
* Function: ListNext
*
* Description:
* Returns the next item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The next item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListNext(LinkedList *list, ListNode * node);
/****************************************************************************
* Function: ListPrev
*
* Description:
* Returns the previous item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The previous item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListPrev(LinkedList *list, ListNode * node);
/****************************************************************************
* Function: ListFind
*
* Description:
* Finds the specified item in the list.
* Uses the compare function specified in ListInit. If compare function
* is NULL then compares items as pointers.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *start - the node to start from, NULL if to start from
* beginning.
* void * item - the item to search for.
* Returns:
* The node containing the item. NULL if no node contains the item.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode* ListFind(LinkedList *list, ListNode *start, void * item);
/****************************************************************************
* Function: ListSize
*
* Description:
* Returns the size of the list.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* The number of items in the list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int ListSize(LinkedList* list);
* Precondition: The list has been initialized.
*
* \return The node containing the item. NULL if no node contains the item.
*/
ListNode* ListFind(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList *list,
/*! The node to start from, NULL if to start from beginning. */
ListNode *start,
/*! The item to search for. */
void *item);
/*!
* \brief Returns the size of the list.
*
* Precondition: The list has been initialized.
*
* \return The number of items in the list.
*/
long ListSize(
/*! Must be valid, non null, pointer to a linked list. */
LinkedList* list);
#ifdef __cplusplus
}

View File

@@ -29,26 +29,21 @@
*
******************************************************************************/
#ifndef THREADPOOL_H
#define THREADPOOL_H
/*!
* \file
*/
#include "FreeList.h"
#include "ithread.h"
#include "LinkedList.h"
#include "UpnpInet.h"
#include "UpnpGlobal.h" /* for UPNP_INLINE, EXPORT_SPEC */
#include <errno.h>
#ifdef WIN32
#include <time.h>
struct timezone
@@ -63,82 +58,63 @@
#if defined(__OSX__) || defined(__APPLE__) || defined(__NetBSD__)
#include <sys/resource.h> /* for setpriority() */
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! Size of job free list */
#define JOBFREELISTSIZE 100
#define INFINITE_THREADS -1
#define EMAXTHREADS (-8 & 1<<29)
/*! Invalid Policy */
#define INVALID_POLICY (-9 & 1<<29)
/*! Invalid JOB Id */
#define INVALID_JOB_ID (-2 & 1<<29)
typedef enum duration {
SHORT_TERM,
PERSISTENT
} Duration;
typedef enum priority {
LOW_PRIORITY,
MED_PRIORITY,
HIGH_PRIORITY
} ThreadPriority;
/*! default priority used by TPJobInit */
#define DEFAULT_PRIORITY MED_PRIORITY
/*! default minimum used by TPAttrInit */
#define DEFAULT_MIN_THREADS 1
/*! default max used by TPAttrInit */
#define DEFAULT_MAX_THREADS 10
/*! default stack size used by TPAttrInit */
#define DEFAULT_STACK_SIZE 0
/*! default jobs per thread used by TPAttrInit */
#define DEFAULT_JOBS_PER_THREAD 10
/*! default starvation time used by TPAttrInit */
#define DEFAULT_STARVATION_TIME 500
/*! default idle time used by TPAttrInit */
#define DEFAULT_IDLE_TIME 10 * 1000
/*! default free routine used TPJobInit */
#define DEFAULT_FREE_ROUTINE NULL
/*! default max jobs used TPAttrInit */
#define DEFAULT_MAX_JOBS_TOTAL 100
/*!
* \brief Statistics.
*
@@ -146,71 +122,43 @@ typedef enum priority {
*/
#define STATS 1
#ifdef _DEBUG
#define DEBUG 1
#endif
typedef int PolicyType;
#define DEFAULT_POLICY SCHED_OTHER
/****************************************************************************
* Name: free_routine
*
* Description:
* Function for freeing a thread argument
*****************************************************************************/
/*! Function for freeing a thread argument. */
typedef void (*free_routine)(void *arg);
/****************************************************************************
* Name: ThreadPoolAttr
*
* Description:
* Attributes for thread pool. Used to set and change parameters of
* thread pool
*****************************************************************************/
/*! Attributes for thread pool. Used to set and change parameters of thread
* pool. */
typedef struct THREADPOOLATTR
{
/* minThreads, ThreadPool will always maintain at least this many threads */
/*! ThreadPool will always maintain at least this many threads. */
int minThreads;
/* maxThreads, ThreadPool will never have more than this number of threads */
/*! ThreadPool will never have more than this number of threads. */
int maxThreads;
/* stackSize (in bytes), this is the minimum stack size allocated for each
* thread */
/*! This is the minimum stack size allocated for each thread. */
size_t stackSize;
/* maxIdleTime (in milliseconds) this is the maximum time a thread will
* remain idle before dying */
/*! This is the maximum time a thread will
* remain idle before dying (in milliseconds). */
int maxIdleTime;
/* jobs per thread to maintain */
/*! Jobs per thread to maintain. */
int jobsPerThread;
/* maximum number of jobs that can be queued totally. */
/*! Maximum number of jobs that can be queued totally. */
int maxJobsTotal;
/* the time a low priority or med priority job waits before getting bumped
* up a priority (in milliseconds) */
/*! the time a low priority or med priority job waits before getting
* bumped up a priority (in milliseconds). */
int starvationTime;
/* scheduling policy to use */
/*! scheduling policy to use. */
PolicyType schedPolicy;
} ThreadPoolAttr;
/****************************************************************************
* Name: ThreadPool
*
* Description:
* Internal ThreadPool Job
*****************************************************************************/
/*! Internal ThreadPool Job. */
typedef struct THREADPOOLJOB
{
start_routine func;
@@ -221,13 +169,7 @@ typedef struct THREADPOOLJOB
int jobId;
} ThreadPoolJob;
/****************************************************************************
* Name: ThreadPoolStats
*
* Description:
* Structure to hold statistics
*****************************************************************************/
/*! Structure to hold statistics. */
typedef struct TPOOLSTATS
{
double totalTimeHQ;
@@ -251,7 +193,6 @@ typedef struct TPOOLSTATS
int currentJobsMQ;
} ThreadPoolStats;
/*!
* \brief A thread pool similar to the thread pool in the UPnP SDK.
*
@@ -269,374 +210,324 @@ typedef struct TPOOLSTATS
*/
typedef struct THREADPOOL
{
ithread_mutex_t mutex; /* mutex to protect job qs */
ithread_cond_t condition; /* condition variable to signal Q */
ithread_cond_t start_and_shutdown; /* condition variable for start and stop */
int lastJobId; /* ids for jobs */
int shutdown; /* whether or not we are shutting down */
int totalThreads; /* total number of threads */
int busyThreads; /* number of threads that are currently executing jobs */
int persistentThreads; /* number of persistent threads */
FreeList jobFreeList; /* free list of jobs */
LinkedList lowJobQ; /* low priority job Q */
LinkedList medJobQ; /* med priority job Q */
LinkedList highJobQ; /* high priority job Q */
ThreadPoolJob *persistentJob; /* persistent job */
ThreadPoolAttr attr; /* thread pool attributes */
/* statistics */
/*! Mutex to protect job qs. */
ithread_mutex_t mutex;
/*! Condition variable to signal Q. */
ithread_cond_t condition;
/*! Condition variable for start and stop. */
ithread_cond_t start_and_shutdown;
/*! ids for jobs */
int lastJobId;
/*! whether or not we are shutting down */
int shutdown;
/*! total number of threads */
int totalThreads;
/*! number of threads that are currently executing jobs */
int busyThreads;
/*! number of persistent threads */
int persistentThreads;
/*! free list of jobs */
FreeList jobFreeList;
/*! low priority job Q */
LinkedList lowJobQ;
/*! med priority job Q */
LinkedList medJobQ;
/*! high priority job Q */
LinkedList highJobQ;
/*! persistent job */
ThreadPoolJob *persistentJob;
/*! thread pool attributes */
ThreadPoolAttr attr;
/*! statistics */
ThreadPoolStats stats;
} ThreadPool;
/*!
* \brief Initializes and starts ThreadPool. Must be called first and
* only once for ThreadPool.
*
* \return
* \li \c 0 on success.
* \li \c EAGAIN if not enough system resources to create minimum threads.
* \li \c INVALID_POLICY if schedPolicy can't be set.
* \li \c EMAXTHREADS if minimum threads is greater than maximum threads.
*/
int ThreadPoolInit(
/*! Must be valid, non null, pointer to ThreadPool. */
ThreadPool *tp,
/*! Can be null. if not null then attr contains the following fields:
* \li \c minWorkerThreads - minimum number of worker threads thread
* pool will never have less than this number of threads.
* \li \c maxWorkerThreads - maximum number of worker threads thread
* pool will never have more than this number of threads.
* \li \c maxIdleTime - maximum time that a worker thread will spend
* idle. If a worker is idle longer than this time and there are more
* than the min number of workers running, then the worker thread
* exits.
* \li \c jobsPerThread - ratio of jobs to thread to try and maintain
* if a job is scheduled and the number of jobs per thread is greater
* than this number,and if less than the maximum number of workers are
* running then a new thread is started to help out with efficiency.
* \li \c schedPolicy - scheduling policy to try and set (OS dependent).
*/
ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolInit
/*!
* \brief Adds a persistent job to the thread pool.
*
* Description:
* Initializes and starts ThreadPool. Must be called first.
* And only once for ThreadPool.
* Parameters:
* tp - must be valid, non null, pointer to ThreadPool.
* attr - can be null
* Job will be run as soon as possible. Call will block until job is scheduled.
*
* if not null then attr contains the following fields:
*
* minWorkerThreads - minimum number of worker threads
* thread pool will never have less than this
* number of threads.
* maxWorkerThreads - maximum number of worker threads
* thread pool will never have more than this
* number of threads.
* maxIdleTime - maximum time that a worker thread will spend
* idle. If a worker is idle longer than this
* time and there are more than the min
* number of workers running, than the
* worker thread exits.
* jobsPerThread - ratio of jobs to thread to try and maintain
* if a job is scheduled and the number of jobs per
* thread is greater than this number,and
* if less than the maximum number of
* workers are running then a new thread is
* started to help out with efficiency.
* schedPolicy - scheduling policy to try and set (OS dependent)
* Returns:
* 0 on success, nonzero on failure.
* EAGAIN if not enough system resources to create minimum threads.
* INVALID_POLICY if schedPolicy can't be set
* EMAXTHREADS if minimum threads is greater than maximum threads
*****************************************************************************/
int ThreadPoolInit(ThreadPool *tp, ThreadPoolAttr *attr);
* \return
* \li \c 0 on success.
* \li \c EOUTOFMEM not enough memory to add job.
* \li \c EMAXTHREADS not enough threads to add persistent job.
*/
int ThreadPoolAddPersistent(
/*! Valid thread pool pointer. */
ThreadPool*tp,
/*! Valid thread pool job. */
ThreadPoolJob *job,
/*! . */
int *jobId);
/****************************************************************************
* Function: ThreadPoolAddPersistent
/*!
* \brief Gets the current set of attributes associated with the thread pool.
*
* Description:
* Adds a persistent job to the thread pool.
* Job will be run as soon as possible.
* Call will block until job is scheduled.
* Parameters:
* tp - valid thread pool pointer
* ThreadPoolJob - valid thread pool job with the following fields:
*
* func - ThreadFunction to run
* arg - argument to function.
* priority - priority of job.
*
* Returns:
* 0 on success, nonzero on failure
* EOUTOFMEM not enough memory to add job.
* EMAXTHREADS not enough threads to add persistent job.
*****************************************************************************/
int ThreadPoolAddPersistent(ThreadPool*tp, ThreadPoolJob *job, int *jobId);
* \return
* \li \c 0 on success, nonzero on failure.
*/
int ThreadPoolGetAttr(
/*! valid thread pool pointer. */
ThreadPool *tp,
/*! non null pointer to store attributes. */
ThreadPoolAttr *out);
/****************************************************************************
* Function: ThreadPoolGetAttr
*
* Description:
* Gets the current set of attributes
* associated with the thread pool.
* Parameters:
* tp - valid thread pool pointer
* out - non null pointer to store attributes
* Returns:
* 0 on success, nonzero on failure
* Always returns 0.
*****************************************************************************/
int ThreadPoolGetAttr(ThreadPool *tp, ThreadPoolAttr *out);
/****************************************************************************
* Function: ThreadPoolSetAttr
*
* Description:
* Sets the attributes for the thread pool.
/*!
* \brief Sets the attributes for the thread pool.
* Only affects future calculations.
* Parameters:
* tp - valid thread pool pointer
* attr - pointer to attributes, null sets attributes to default.
* Returns:
* 0 on success, nonzero on failure
* Returns INVALID_POLICY if policy can not be set.
*****************************************************************************/
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolAdd
*
* Description:
* Adds a job to the thread pool.
* Job will be run as soon as possible.
* Parameters:
* tp - valid thread pool pointer
* func - ThreadFunction to run
* arg - argument to function.
* priority - priority of job.
* poolid - id of job
* free_function - function to use when freeing argument
* Returns:
* 0 on success, nonzero on failure
* EOUTOFMEM if not enough memory to add job.
*****************************************************************************/
int ThreadPoolAdd (ThreadPool*tp, ThreadPoolJob *job, int *jobId);
* \return
* \li \c 0 on success, nonzero on failure.
* \li \c INVALID_POLICY if policy can not be set.
*/
int ThreadPoolSetAttr(
/*! valid thread pool pointer. */
ThreadPool *tp,
/*! pointer to attributes, null sets attributes to default. */
ThreadPoolAttr *attr);
/****************************************************************************
* Function: ThreadPoolRemove
/*!
* \brief Adds a job to the thread pool. Job will be run as soon as possible.
*
* Description:
* Removes a job from the thread pool.
* Can only remove jobs which are not
* currently running.
* Parameters:
* tp - valid thread pool pointer
* jobid - id of job
* out - space for removed job.
* Returns:
* 0 on success, nonzero on failure.
* INVALID_JOB_ID if job not found.
*****************************************************************************/
int ThreadPoolRemove(ThreadPool *tp, int jobId, ThreadPoolJob *out);
* \return
* \li \c 0 on success, nonzero on failure.
* \li \c EOUTOFMEM if not enough memory to add job.
*/
int ThreadPoolAdd(
/*! valid thread pool pointer. */
ThreadPool*tp,
/*! . */
ThreadPoolJob *job,
/*! id of job. */
int *jobId);
/****************************************************************************
* Function: ThreadPoolShutdown
/*!
* \brief Removes a job from the thread pool. Can only remove jobs which
* are not currently running.
*
* Description:
* Shuts the thread pool down.
* Waits for all threads to finish.
* May block indefinitely if jobs do not
* exit.
* Parameters:
* tp - must be valid tp
* Returns:
* 0 on success, nonzero on failure
* Always returns 0.
*****************************************************************************/
int ThreadPoolShutdown(ThreadPool *tp);
* \return
* \li \c 0 on success, nonzero on failure.
* \li \c INVALID_JOB_ID if job not found.
*/
int ThreadPoolRemove(
/*! valid thread pool pointer. */
ThreadPool *tp,
/*! id of job. */
int jobId,
/*! space for removed job. */
ThreadPoolJob *out);
/****************************************************************************
* Function: TPJobInit
/*!
* \brief Shuts the thread pool down. Waits for all threads to finish.
* May block indefinitely if jobs do not exit.
*
* Description:
* Initializes thread pool job.
* Sets the priority to default defined in ThreadPool.h.
* Sets the free_routine to default defined in ThreadPool.h
* Parameters:
* ThreadPoolJob *job - must be valid thread pool attributes.
* start_routine func - function to run, must be valid
* void * arg - argument to pass to function.
* Returns:
* Always returns 0.
*****************************************************************************/
int TPJobInit(ThreadPoolJob *job, start_routine func, void *arg);
* \return 0 on success, nonzero on failure
*/
int ThreadPoolShutdown(
/*! must be valid tp. */
ThreadPool *tp);
/****************************************************************************
* Function: TPJobSetPriority
/*!
* \brief Initializes thread pool job. Sets the priority to default defined
* in ThreadPool.h. Sets the free_routine to default defined in ThreadPool.h.
*
* Description:
* Sets the max threads for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* maxThreads - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPJobSetPriority(ThreadPoolJob *job, ThreadPriority priority);
* \return Always returns 0.
*/
int TPJobInit(
/*! must be valid thread pool attributes. */
ThreadPoolJob *job,
/*! function to run, must be valid. */
start_routine func,
/*! argument to pass to function. */
void *arg);
/****************************************************************************
* Function: TPJobSetFreeFunction
/*!
* \brief Sets the max threads for the thread pool attributes.
*
* Description:
* Sets the max threads for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* maxThreads - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPJobSetFreeFunction(ThreadPoolJob *job, free_routine func);
* \return Always returns 0.
*/
int TPJobSetPriority(
/*! must be valid thread pool attributes. */
ThreadPoolJob *job,
/*! value to set. */
ThreadPriority priority);
/****************************************************************************
* Function: TPAttrInit
/*!
* \brief Sets the max threads for the thread pool attributes.
*
* Description:
* Initializes thread pool attributes.
* Sets values to defaults defined in ThreadPool.h.
* Parameters:
* attr - must be valid thread pool attributes.
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrInit(ThreadPoolAttr *attr);
* \return Always returns 0.
*/
int TPJobSetFreeFunction(
/*! must be valid thread pool attributes. */
ThreadPoolJob *job,
/*! value to set. */
free_routine func);
/****************************************************************************
* Function: TPAttrSetMaxThreads
/*!
* \brief Initializes thread pool attributes. Sets values to defaults defined
* in ThreadPool.h.
*
* Description:
* Sets the max threads for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* maxThreads - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetMaxThreads(ThreadPoolAttr *attr, int maxThreads);
* \return Always returns 0.
*/
int TPAttrInit(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr);
/****************************************************************************
* Function: TPAttrSetMinThreads
/*!
* \brief Sets the max threads for the thread pool attributes.
*
* Description:
* Sets the min threads for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* minThreads - value to set
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetMinThreads(ThreadPoolAttr *attr, int minThreads);
* \return Always returns 0.
*/
int TPAttrSetMaxThreads(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! value to set. */
int maxThreads);
/****************************************************************************
* Function: TPAttrSetStackSize
/*!
* \brief Sets the min threads for the thread pool attributes.
*
* 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);
* \return Always returns 0.
*/
int TPAttrSetMinThreads(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! value to set. */
int minThreads);
/****************************************************************************
* Function: TPAttrSetIdleTime
/*!
* \brief Sets the stack size for the thread pool attributes.
*
* Description:
* Sets the idle time for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetIdleTime(ThreadPoolAttr *attr, int idleTime);
* \return Always returns 0.
*/
int TPAttrSetStackSize(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! value to set. */
size_t stackSize);
/****************************************************************************
* Function: TPAttrSetJobsPerThread
/*!
* \brief Sets the idle time for the thread pool attributes.
*
* Description:
* Sets the jobs per thread ratio
* Parameters:
* attr - must be valid thread pool attributes.
* jobsPerThread - number of jobs per thread to maintain
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetJobsPerThread(ThreadPoolAttr *attr, int jobsPerThread);
* \return Always returns 0.
*/
int TPAttrSetIdleTime(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! . */
int idleTime);
/****************************************************************************
* Function: TPAttrSetStarvationTime
/*!
* \brief Sets the jobs per thread ratio
*
* Description:
* Sets the starvation time for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* int starvationTime - milliseconds
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetStarvationTime(ThreadPoolAttr *attr, int starvationTime);
* \return Always returns 0.
*/
int TPAttrSetJobsPerThread(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! number of jobs per thread to maintain. */
int jobsPerThread);
/****************************************************************************
* Function: TPAttrSetSchedPolicy
/*!
* \brief Sets the starvation time for the thread pool attributes.
*
* Description:
* Sets the scheduling policy for the thread pool attributes.
* Parameters:
* attr - must be valid thread pool attributes.
* PolicyType schedPolicy - must be a valid policy type.
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetSchedPolicy(ThreadPoolAttr *attr, PolicyType schedPolicy);
* \return Always returns 0.
*/
int TPAttrSetStarvationTime(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! milliseconds. */
int starvationTime);
/****************************************************************************
* Function: TPAttrSetMaxJobsTotal
/*!
* \brief Sets the scheduling policy for the thread pool attributes.
*
* Description:
* Sets the maximum number jobs that can be qeued totally.
* Parameters:
* attr - must be valid thread pool attributes.
* maxJobsTotal - maximum number of jobs
* Returns:
* Always returns 0.
*****************************************************************************/
int TPAttrSetMaxJobsTotal(ThreadPoolAttr *attr, int maxJobsTotal);
* \return Always returns 0.
*/
int TPAttrSetSchedPolicy(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! must be a valid policy type. */
PolicyType schedPolicy);
/****************************************************************************
* Function: ThreadPoolGetStats
/*!
* \brief Sets the maximum number jobs that can be qeued totally.
*
* \return Always returns 0.
*/
int TPAttrSetMaxJobsTotal(
/*! must be valid thread pool attributes. */
ThreadPoolAttr *attr,
/*! maximum number of jobs. */
int maxJobsTotal);
/*!
* \brief Returns various statistics about the thread pool.
*
* Description:
* Returns various statistics about the
* thread pool.
* Only valid if STATS has been defined.
* Parameters:
* ThreadPool *tp - valid initialized threadpool
* ThreadPoolStats *stats - valid stats, out parameter
* Returns:
* Always returns 0.
*****************************************************************************/
*
* \return Always returns 0.
*/
#ifdef STATS
EXPORT_SPEC int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats);
EXPORT_SPEC void ThreadPoolPrintStats(ThreadPoolStats *stats);
EXPORT_SPEC int ThreadPoolGetStats(
/*! Valid initialized threadpool. */
ThreadPool *tp,
/*! Valid stats, out parameter. */
ThreadPoolStats *stats);
#else
static UPNP_INLINE int ThreadPoolGetStats(ThreadPool *tp, ThreadPoolStats *stats) {}
static UPNP_INLINE void ThreadPoolPrintStats(ThreadPoolStats *stats) {}
static UPNP_INLINE int ThreadPoolGetStats(
/*! Valid initialized threadpool. */
ThreadPool *tp,
/*! Valid stats, out parameter. */
ThreadPoolStats *stats) {}
#endif
/*!
* \brief
*/
#ifdef STATS
EXPORT_SPEC void ThreadPoolPrintStats(
/*! . */
ThreadPoolStats *stats);
#else
static UPNP_INLINE void ThreadPoolPrintStats(
/*! . */
ThreadPoolStats *stats) {}
#endif
#ifdef __cplusplus
}
#endif
#endif /* THREADPOOL_H */

View File

@@ -29,35 +29,31 @@
*
******************************************************************************/
#ifndef TIMERTHREAD_H
#define TIMERTHREAD_H
/*!
* \file
*/
#include "FreeList.h"
#include "ithread.h"
#include "LinkedList.h"
#include "ThreadPool.h"
#ifdef __cplusplus
extern "C" {
#endif
#define INVALID_EVENT_ID (-10 & 1<<29)
/* Timeout Types */
/* absolute means in seconds from Jan 1, 1970 */
/* relative means in seconds from current time */
typedef enum timeoutType {ABS_SEC,REL_SEC} TimeoutType;
/*! Timeout Types. */
typedef enum timeoutType {
/*! seconds from Jan 1, 1970. */
ABS_SEC,
/*! seconds from current time. */
REL_SEC
} TimeoutType;
/*!
* A timer thread similar to the one in the Upnp SDK that allows
@@ -79,7 +75,6 @@ typedef struct TIMERTHREAD
ThreadPool *tp;
} TimerThread;
/*!
* Struct to contain information for a timer event.
*
@@ -95,7 +90,6 @@ typedef struct TIMEREVENT
int id;
} TimerEvent;
/*!
* \brief Initializes and starts timer thread.
*
@@ -109,7 +103,6 @@ int TimerThreadInit(
* lifetime of timer. Timer must be shutdown BEFORE thread pool. */
ThreadPool *tp);
/*!
* \brief Schedules an event to run at a specified time.
*
@@ -132,7 +125,6 @@ int TimerThreadSchedule(
/*! [in] Id of timer event. (out, can be null). */
int *id);
/*!
* \brief Removes an event from the timer Q.
*
@@ -148,7 +140,6 @@ int TimerThreadRemove(
/*! [in] Space for thread pool job. */
ThreadPoolJob *out);
/*!
* \brief Shutdown the timer thread.
*
@@ -162,7 +153,6 @@ int TimerThreadShutdown(
/*! [in] Valid timer thread pointer. */
TimerThread *timer);
#ifdef __cplusplus
}
#endif

View File

@@ -65,7 +65,7 @@ extern "C" {
#endif
#ifdef PTHREAD_MUTEX_RECURSIVE
#if defined(PTHREAD_MUTEX_RECURSIVE) || defined(__DragonFly__)
/* This system has SuS2-compliant mutex attributes.
* E.g. on Cygwin, where we don't have the old nonportable (NP) symbols
*/
@@ -188,7 +188,10 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t;
* Internal Use Only
***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlock_t ithread_rwlock_t;
typedef pthread_rwlock_t ithread_rwlock_t;
#else
/* Read-write locks aren't available: use mutex instead. */
typedef ithread_mutex_t ithread_rwlock_t;
#endif /* UPNP_USE_RWLOCK */
@@ -333,11 +336,11 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Returns EINVAL if the kind is not supported.
* See man page for pthread_mutexattr_setkind_np
*****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE
#if defined(PTHREAD_MUTEX_RECURSIVE) || defined(__DragonFly__)
#define ithread_mutexattr_setkind_np pthread_mutexattr_settype
#else
#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
#endif
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
* Function: ithread_mutexattr_getkind_np
@@ -358,11 +361,11 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0.
* See man page for pthread_mutexattr_getkind_np
*****************************************************************************/
#ifdef PTHREAD_MUTEX_RECURSIVE
#if defined(PTHREAD_MUTEX_RECURSIVE) || defined(__DragonFly__)
#define ithread_mutexattr_getkind_np pthread_mutexattr_gettype
#else
#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
#endif
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
@@ -536,8 +539,10 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
*****************************************************************************/
#if UPNP_USE_RWLOCK
#define ithread_rwlock_init pthread_rwlock_init
#endif /* UPNP_USE_RWLOCK */
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_init ithread_mutex_init
#endif
/****************************************************************************
* Function: ithread_rwlock_rdlock
@@ -555,9 +560,11 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
*****************************************************************************/
#if UPNP_USE_RWLOCK
#define ithread_rwlock_rdlock pthread_rwlock_rdlock
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_rdlock ithread_mutex_lock
#endif /* UPNP_USE_RWLOCK */
/****************************************************************************
* Function: ithread_rwlock_wrlock
*
@@ -574,6 +581,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
*****************************************************************************/
#if UPNP_USE_RWLOCK
#define ithread_rwlock_wrlock pthread_rwlock_wrlock
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_wrlock ithread_mutex_lock
#endif /* UPNP_USE_RWLOCK */
@@ -594,6 +604,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
*****************************************************************************/
#if UPNP_USE_RWLOCK
#define ithread_rwlock_unlock pthread_rwlock_unlock
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_unlock ithread_mutex_unlock
#endif /* UPNP_USE_RWLOCK */
@@ -615,6 +628,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
*****************************************************************************/
#if UPNP_USE_RWLOCK
#define ithread_rwlock_destroy pthread_rwlock_destroy
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_destroy ithread_mutex_destroy
#endif /* UPNP_USE_RWLOCK */
@@ -917,7 +933,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
#endif
#ifndef PTHREAD_MUTEX_RECURSIVE
#if !defined(PTHREAD_MUTEX_RECURSIVE) && !defined(__DragonFly__)
/* NK: Added for satisfying the gcc compiler */
EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
#endif

View File

@@ -1,177 +1,111 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/**************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************/
#include "FreeList.h"
#include <assert.h>
#include <stdlib.h>
/****************************************************************************
* Function: FreeListInit
*
* Description:
* Initializes Free List. Must be called first.
* And only once for FreeList.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* size_t - size of elements to store in free list
* maxFreeListSize - max size that the free list can grow to
* before returning memory to O.S.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListInit( FreeList * free_list,
size_t elementSize,
int maxFreeListLength )
int FreeListInit(FreeList *free_list, size_t elementSize, int maxFreeListLength)
{
assert( free_list != NULL );
assert(free_list != NULL);
if( free_list == NULL )
if (free_list == NULL)
return EINVAL;
free_list->element_size = elementSize;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
return 0;
}
/****************************************************************************
* Function: FreeListAlloc
*
* Description:
* Allocates chunk of set size.
* If a free item is available in the list, returnes the stored item.
* Otherwise calls the O.S. to allocate memory.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* Non NULL on success. NULL on failure.
*****************************************************************************/
void *
FreeListAlloc( FreeList * free_list )
void *FreeListAlloc(FreeList *free_list)
{
FreeListNode *ret = NULL;
assert( free_list != NULL );
assert(free_list != NULL);
if( free_list == NULL )
if (free_list == NULL)
return NULL;
if( free_list->head ) {
if (free_list->head) {
ret = free_list->head;
free_list->head = free_list->head->next;
free_list->freeListLength--;
} else {
ret = malloc( free_list->element_size );
ret = malloc(free_list->element_size);
}
return ret;
}
/****************************************************************************
* Function: FreeListFree
*
* Description:
* Returns an item to the Free List.
* If the free list is smaller than the max size than
* adds the item to the free list.
* Otherwise returns the item to the O.S.
* Parameters:
* free_list - must be valid, non null, pointer to a free list.
* element - must be a pointer allocated by FreeListAlloc
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListFree( FreeList * free_list,
void *element )
int FreeListFree(FreeList *free_list, void *element)
{
FreeListNode *temp = NULL;
assert( free_list != NULL );
assert(free_list != NULL);
if( free_list == NULL )
if (free_list == NULL)
return EINVAL;
if( ( element != NULL ) &&
( ( free_list->freeListLength + 1 ) <
free_list->maxFreeListLength ) ) {
if (element != NULL &&
free_list->freeListLength + 1 < free_list->maxFreeListLength) {
free_list->freeListLength++;
temp = ( FreeListNode * ) element;
temp = (FreeListNode *)element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free( element );
free(element);
}
return 0;
}
/****************************************************************************
* Function: FreeListDestroy
*
* Description:
* Releases the resources stored with the free list.
* Parameters:
* free_list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
*****************************************************************************/
int
FreeListDestroy( FreeList * free_list )
int FreeListDestroy(FreeList *free_list)
{
FreeListNode *temp = NULL;
int i = 0;
assert( free_list != NULL );
assert(free_list != NULL);
if( free_list == NULL )
if (!free_list)
return EINVAL;
while( free_list->head ) {
while (free_list->head) {
i++;
temp = free_list->head->next;
free( free_list->head );
free(free_list->head);
free_list->head = temp;
}
free_list->freeListLength = 0;
return 0;
}

View File

@@ -29,105 +29,75 @@
*
**************************************************************************/
#include "LinkedList.h"
#ifdef WIN32
/* Do not #include <sys/param.h> */
#else
#include <sys/param.h>
#endif
#if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__)
#include <stdlib.h>
#else
#include <malloc.h>
#endif
#include <assert.h>
static int
freeListNode( ListNode * node,
LinkedList * list )
static int freeListNode(ListNode *node, LinkedList *list)
{
assert( list != NULL );
assert(list != NULL);
return FreeListFree( &list->freeNodeList, node );
return FreeListFree(&list->freeNodeList, node);
}
/****************************************************************************
* Function: CreateListNode
*
* Description:
* Creates a list node. Dynamically.
/*!
* \brief Dynamically creates a list node.
*
* Parameters:
* void * item - the item to store
* Returns:
* The new node, NULL on failure.
*****************************************************************************/
static ListNode *
CreateListNode( void *item,
LinkedList * list )
*/
static ListNode *CreateListNode(
/*! the item to store. */
void *item,
/*! The list to add it to. */
LinkedList *list)
{
ListNode *temp = NULL;
assert( list != NULL );
assert(list != NULL);
temp = ( ListNode * ) FreeListAlloc( &list->freeNodeList );
if( temp ) {
temp = (ListNode *)FreeListAlloc(&list->freeNodeList);
if (temp) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
return temp;
}
/****************************************************************************
* Function: ListInit
*
* Description:
* Initializes LinkedList. Must be called first.
* And only once for List.
* Parameters:
* list - must be valid, non null, pointer to a linked list.
* cmp_func - function used to compare items. (May be NULL)
* free_func - function used to free items. (May be NULL)
* Returns:
* 0 on success, EOUTOFMEM on failure.
*****************************************************************************/
int
ListInit( LinkedList * list,
cmp_routine cmp_func,
free_function free_func )
int ListInit(LinkedList *list, cmp_routine cmp_func, free_function free_func)
{
int retCode = 0;
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (!list)
return EINVAL;
list->size = 0;
list->cmp_func = cmp_func;
list->free_func = free_func;
retCode = FreeListInit(&list->freeNodeList, sizeof(ListNode), FREELISTSIZE);
retCode =
FreeListInit( &list->freeNodeList, sizeof( ListNode ),
FREELISTSIZE );
assert( retCode == 0 );
assert(retCode == 0);
list->head.item = NULL;
list->head.next = &list->tail;
list->head.prev = NULL;
list->tail.item = NULL;
list->tail.prev = &list->head;
list->tail.next = NULL;
@@ -135,87 +105,36 @@ ListInit( LinkedList * list,
return 0;
}
/****************************************************************************
* Function: ListAddHead
*
* Description:
* Adds a node to the head of the list.
* Node gets immediately after list.head.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddHead( LinkedList * list,
void *item )
ListNode *ListAddHead(LinkedList *list, void *item)
{
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (list == NULL)
return NULL;
return ListAddAfter( list, item, &list->head );
return ListAddAfter(list, item, &list->head);
}
/****************************************************************************
* Function: ListAddTail
*
* Description:
* Adds a node to the tail of the list.
* Node gets added immediately before list.tail.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddTail( LinkedList * list,
void *item )
ListNode *ListAddTail(LinkedList *list, void *item)
{
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (!list)
return NULL;
return ListAddBefore( list, item, &list->tail );
return ListAddBefore(list, item, &list->tail);
}
/****************************************************************************
* Function: ListAddAfter
*
* Description:
* Adds a node after the specified node.
* Node gets added immediately after bnode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* void * item - item to be added
* ListNode * bnode - node to add after
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddAfter( LinkedList * list,
void *item,
ListNode * bnode )
ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode)
{
ListNode *newNode = NULL;
assert( list != NULL );
assert(list != NULL);
if( ( list == NULL ) || ( bnode == NULL ) )
if (!list || !bnode)
return NULL;
newNode = CreateListNode( item, list );
if( newNode ) {
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = bnode->next;
bnode->next = newNode;
@@ -223,41 +142,23 @@ ListAddAfter( LinkedList * list,
newNode->next = temp;
temp->prev = newNode;
list->size++;
return newNode;
}
return NULL;
}
/****************************************************************************
* Function: ListAddBefore
*
* Description:
* Adds a node before the specified node.
* Node gets added immediately before anode.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode * anode - node to add the in front of.
* void * item - item to be added
* Returns:
* The pointer to the ListNode on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListAddBefore( LinkedList * list,
void *item,
ListNode * anode )
ListNode *ListAddBefore(LinkedList *list, void *item, ListNode *anode)
{
ListNode *newNode = NULL;
assert( list != NULL );
assert(list != NULL);
if( ( list == NULL ) || ( anode == NULL ) )
if (!list || !anode)
return NULL;
newNode = CreateListNode( item, list );
if( newNode ) {
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = anode->prev;
anode->prev = newNode;
@@ -265,281 +166,142 @@ ListAddBefore( LinkedList * list,
newNode->prev = temp;
temp->next = newNode;
list->size++;
return newNode;
}
return NULL;
}
/****************************************************************************
* Function: ListDelNode
*
* Description:
* Removes a node from the list
* The memory for the node is freed but the
* the memory for the items are not.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *dnode - done to delete.
* Returns:
* The pointer to the item stored in node on success, NULL on failure.
* Precondition:
* The list has been initialized.
*****************************************************************************/
void *
ListDelNode( LinkedList * list,
ListNode * dnode,
int freeItem )
void *ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)
{
void *temp;
assert( list != NULL );
assert( dnode != &list->head );
assert( dnode != &list->tail );
assert(list != NULL);
assert(dnode != &list->head);
assert(dnode != &list->tail);
if( ( list == NULL ) ||
( dnode == &list->head ) ||
( dnode == &list->tail ) || ( dnode == NULL ) ) {
if (!list || dnode == &list->head || dnode == &list->tail || !dnode)
return NULL;
}
temp = dnode->item;
dnode->prev->next = dnode->next;
dnode->next->prev = dnode->prev;
freeListNode( dnode, list );
freeListNode(dnode, list);
list->size--;
if( freeItem && list->free_func ) {
list->free_func( temp );
if (freeItem && list->free_func) {
list->free_func(temp);
temp = NULL;
}
return temp;
}
/****************************************************************************
* Function: ListDestroy
*
* Description:
* Removes all memory associated with list nodes.
* Does not free LinkedList *list.
* Items stored in the list are not freed, only nodes are.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* 0 on success. Nonzero on failure.
* Always returns 0.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListDestroy( LinkedList * list,
int freeItem )
int ListDestroy(LinkedList *list, int freeItem)
{
ListNode *dnode = NULL;
ListNode *temp = NULL;
if( list == NULL )
if(!list)
return EINVAL;
for( dnode = list->head.next; dnode != &list->tail; ) {
for (dnode = list->head.next; dnode != &list->tail; ) {
temp = dnode->next;
ListDelNode( list, dnode, freeItem );
ListDelNode(list, dnode, freeItem);
dnode = temp;
}
list->size = 0;
FreeListDestroy( &list->freeNodeList );
FreeListDestroy(&list->freeNodeList);
return 0;
}
/****************************************************************************
* Function: ListHead
*
* Description:
* Returns the head of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The head of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListHead( LinkedList * list )
ListNode *ListHead(LinkedList *list)
{
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (!list)
return NULL;
if( list->size == 0 )
if (!list->size)
return NULL;
else
return list->head.next;
}
/****************************************************************************
* Function: ListTail
*
* Description:
* Returns the tail of the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The tail of the list. NULL if list is empty.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListTail( LinkedList * list )
ListNode *ListTail(LinkedList *list)
{
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (!list)
return NULL;
if( list->size == 0 )
if (!list->size)
return NULL;
else
return list->tail.prev;
}
/****************************************************************************
* Function: ListNext
*
* Description:
* Returns the next item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The next item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListNext( LinkedList * list,
ListNode * node )
ListNode *ListNext(LinkedList *list, ListNode *node)
{
assert( list != NULL );
assert( node != NULL );
assert(list != NULL);
assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) )
if (!list || !node)
return NULL;
if( node->next == &list->tail )
if (node->next == &list->tail)
return NULL;
else
return node->next;
}
/****************************************************************************
* Function: ListPrev
*
* Description:
* Returns the previous item in the list.
*
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
*
* Returns:
* The previous item in the list. NULL if there are no more items in list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListPrev( LinkedList * list,
ListNode * node )
ListNode *ListPrev(LinkedList *list, ListNode *node)
{
assert( list != NULL );
assert( node != NULL );
assert(list != NULL);
assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) )
if (!list || !node)
return NULL;
if( node->prev == &list->head )
if (node->prev == &list->head)
return NULL;
else
return node->prev;
}
/****************************************************************************
* Function: ListFind
*
* Description:
* Finds the specified item in the list.
* Uses the compare function specified in ListInit. If compare function
* is NULL then compares items as pointers.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* ListNode *start - the node to start from, NULL if to start from
* beginning.
* void * item - the item to search for.
* Returns:
* The node containing the item. NULL if no node contains the item.
* Precondition:
* The list has been initialized.
*****************************************************************************/
ListNode *
ListFind( LinkedList * list,
ListNode * start,
void *item )
ListNode *ListFind(LinkedList *list, ListNode *start, void *item)
{
ListNode *finger = NULL;
if( list == NULL )
if (!list)
return NULL;
if( start == NULL )
if (!start)
start = &list->head;
assert( start );
assert(start);
finger = start->next;
assert( finger );
assert(finger);
while( finger != &list->tail ) {
if( list->cmp_func ) {
if( list->cmp_func( item, finger->item ) )
while (finger != &list->tail) {
if (list->cmp_func) {
if (list->cmp_func(item, finger->item))
return finger;
} else {
if( item == finger->item )
if (item == finger->item)
return finger;
}
finger = finger->next;
}
return NULL;
}
/****************************************************************************
* Function: ListSize
*
* Description:
* Returns the size of the list.
* Parameters:
* LinkedList *list - must be valid, non null, pointer to a linked list.
* Returns:
* The number of items in the list.
* Precondition:
* The list has been initialized.
*****************************************************************************/
int
ListSize( LinkedList * list )
long ListSize(LinkedList *list)
{
assert( list != NULL );
assert(list != NULL);
if( list == NULL )
if (!list)
return EINVAL;
return list->size;

File diff suppressed because it is too large Load Diff

View File

@@ -29,18 +29,14 @@
*
******************************************************************************/
/*!
* \file
*/
#include "TimerThread.h"
#include <assert.h>
/*!
* \brief Deallocates a dynamically allocated TimerEvent.
*/
@@ -55,7 +51,6 @@ static void FreeTimerEvent(
FreeListFree(&timer->freeEvents, event);
}
/*!
* \brief Implements timer thread.
*
@@ -67,46 +62,34 @@ static void *TimerThreadWorker(
{
TimerThread *timer = ( TimerThread * ) arg;
ListNode *head = NULL;
TimerEvent *nextEvent = NULL;
time_t currentTime = 0;
time_t nextEventTime = 0;
struct timespec timeToWait;
int tempId;
assert( timer != NULL );
ithread_mutex_lock( &timer->mutex );
while( 1 )
{
//mutex should always be locked at top of loop
//Check for shutdown
if( timer->shutdown )
{
while (1) {
/* mutex should always be locked at top of loop */
/* Check for shutdown. */
if (timer->shutdown) {
timer->shutdown = 0;
ithread_cond_signal( &timer->condition );
ithread_mutex_unlock( &timer->mutex );
return NULL;
}
nextEvent = NULL;
//Get the next event if possible
if( timer->eventQ.size > 0 )
{
/* Get the next event if possible. */
if (timer->eventQ.size > 0) {
head = ListHead( &timer->eventQ );
nextEvent = ( TimerEvent * ) head->item;
nextEventTime = nextEvent->eventTime;
}
currentTime = time( NULL );
//If time has elapsed, schedule job
if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
{
currentTime = time(NULL);
/* If time has elapsed, schedule job. */
if (nextEvent && currentTime >= nextEventTime) {
if( nextEvent->persistent ) {
ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
&tempId );
@@ -117,8 +100,7 @@ static void *TimerThreadWorker(
FreeTimerEvent( timer, nextEvent );
continue;
}
if( nextEvent != NULL ) {
if (nextEvent) {
timeToWait.tv_nsec = 0;
timeToWait.tv_sec = nextEvent->eventTime;
ithread_cond_timedwait( &timer->condition, &timer->mutex,
@@ -146,16 +128,15 @@ static int CalculateEventTime(
assert( timeout != NULL );
if( type == ABS_SEC )
if (type == ABS_SEC)
return 0;
else if( type == REL_SEC ) {
time( &now );
else /*if (type == REL_SEC) */{
time(&now);
( *timeout ) += now;
return 0;
}
return -1;
}
/*!
@@ -246,10 +227,8 @@ int TimerThreadInit(TimerThread *timer, ThreadPool *tp)
}
return rc;
}
int TimerThreadSchedule(
TimerThread *timer,
time_t timeout,
@@ -258,7 +237,6 @@ int TimerThreadSchedule(
Duration duration,
int *id)
{
int rc = EOUTOFMEM;
int found = 0;
int tempId = 0;
@@ -291,35 +269,25 @@ int TimerThreadSchedule(
}
tempNode = ListHead( &timer->eventQ );
//add job to Q
//Q is ordered by eventTime
//with the head of the Q being the next event
/* add job to Q. Q is ordered by eventTime with the head of the Q being
* the next event. */
while( tempNode != NULL ) {
temp = ( TimerEvent * ) tempNode->item;
if( temp->eventTime >= timeout )
{
if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) !=
NULL )
if( temp->eventTime >= timeout ) {
if (ListAddBefore( &timer->eventQ, newEvent, tempNode))
rc = 0;
found = 1;
break;
}
tempNode = ListNext( &timer->eventQ, tempNode );
}
//add to the end of Q
if( !found ) {
/* add to the end of Q. */
if (!found) {
if( ListAddTail( &timer->eventQ, newEvent ) != NULL )
rc = 0;
}
//signal change in Q
/* signal change in Q. */
if( rc == 0 ) {
ithread_cond_signal( &timer->condition );
} else {
FreeTimerEvent( timer, newEvent );
@@ -330,7 +298,6 @@ int TimerThreadSchedule(
return rc;
}
int TimerThreadRemove(
TimerThread *timer,
int id,
@@ -369,7 +336,6 @@ int TimerThreadRemove(
return rc;
}
int TimerThreadShutdown(TimerThread *timer)
{
ListNode *tempNode2 = NULL;
@@ -386,9 +352,7 @@ int TimerThreadShutdown(TimerThread *timer)
timer->shutdown = 1;
tempNode = ListHead( &timer->eventQ );
//Delete nodes in Q
//call registered free function
//on argument
/* Delete nodes in Q. Call registered free function on argument. */
while( tempNode != NULL ) {
TimerEvent *temp = ( TimerEvent * ) tempNode->item;
@@ -406,19 +370,17 @@ int TimerThreadShutdown(TimerThread *timer)
ithread_cond_broadcast( &timer->condition );
while( timer->shutdown ) //wait for timer thread to shutdown
{
while (timer->shutdown) {
/* wait for timer thread to shutdown. */
ithread_cond_wait( &timer->condition, &timer->mutex );
}
ithread_mutex_unlock(&timer->mutex);
ithread_mutex_unlock( &timer->mutex );
//destroy condition
while( ithread_cond_destroy( &timer->condition ) != 0 ) {
/* destroy condition. */
while(ithread_cond_destroy(&timer->condition) != 0) {
}
//destroy mutex
while( ithread_mutex_destroy( &timer->mutex ) != 0 ) {
/* destroy mutex. */
while (ithread_mutex_destroy(&timer->mutex) != 0) {
}
return 0;

View File

@@ -70,8 +70,7 @@ libupnp_la_SOURCES = \
src/inc/upnp_timeout.h \
src/inc/uri.h \
src/inc/urlconfig.h \
src/inc/util.h \
src/inc/utilall.h \
src/inc/upnputil.h \
src/inc/uuid.h \
src/inc/VirtualDir.h \
src/inc/webserver.h

View File

@@ -88,7 +88,11 @@
* inline keyword. This definition makes the use of this keyword
* portable to these systems.
*/
#ifdef __STRICT_ANSI__
#define UPNP_INLINE __inline__
#else
#define UPNP_INLINE inline
#endif
/*!
* \brief Supply the PRId64 printf() macro.

View File

@@ -1,16 +1,13 @@
#ifndef UPNPINET_H
#define UPNPINET_H
/*!
* \file
*
* \brief Provides a platform independent way to include TCP/IP types and functions.
*/
#ifdef WIN32
#include <iphlpapi.h>
#include <winsock2.h>
@@ -27,12 +24,17 @@
#endif
#include <netinet/in.h>
#include <unistd.h> /* for close(). Do not include in WIN32. */
/* include <unistd.h> for close().
* Do not include this file in win32. */
#include <unistd.h>
/* SOCKET is unsigned and is not a file descriptor on win32. */
#define SOCKET int
#define INVALID_SOCKET ((SOCKET)(-1))
/* INVALID_SOCKET is unsigned on win32. */
#define INVALID_SOCKET (-1)
/* select() returns SOCKET_ERROR on win32. */
#define SOCKET_ERROR (-1)
#define UpnpCloseSocket close
#endif
#endif /* UPNPINET_H */

View File

@@ -17,7 +17,7 @@
*
* \file
*
* \brief UpnpString object declarartion.
* \brief UpnpString object declaration.
*/

View File

@@ -1328,7 +1328,7 @@ EXPORT_SPEC int UpnpSetContentLength(
* length needs to be set. */
UpnpClient_Handle Hnd,
/*! [in] Permissible content length */
int contentLength);
size_t contentLength);
/*!
@@ -2412,7 +2412,7 @@ EXPORT_SPEC int UpnpReadHttpGet(
/*! [in,out] The buffer to store the read item. */
char *buf,
/*! [in,out] The size of the buffer to be read. */
unsigned int *size,
size_t *size,
/*! [in] The time out value sent with the request during which a response is
* expected from the server, failing which, an error is reported back to
* the user. */
@@ -2431,9 +2431,9 @@ EXPORT_SPEC int UpnpHttpGetProgress(
/*! [in] The token created by the call to \b UpnpOpenHttpGet. */
void *handle,
/*! [out] The number of bytes received. */
unsigned int *length,
size_t *length,
/*! [out] The content length. */
unsigned int *total);
size_t *total);
/*!
@@ -2522,7 +2522,7 @@ EXPORT_SPEC int UpnpWriteHttpPost(
/*! [in] The buffer to be posted. */
char *buf,
/*! [in] The size, in bytes of \b buf. */
unsigned int *size,
size_t *size,
/*! [in] A timeout value sent with the request during which a response is
* expected from the server, failing which, an error is reported. */
int timeout);

View File

@@ -1,7 +1,7 @@
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net>
* Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -33,32 +33,27 @@
#ifndef UPNP_DEBUG_H
#define UPNP_DEBUG_H
/*!
* \file
*/
#include "ThreadPool.h"
#include "upnpconfig.h"
#include "UpnpGlobal.h" /* for UPNP_INLINE */
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/** \name Other debugging features
/*! \name Other debugging features
*
* The UPnP SDK contains other features to aid in debugging.
*/
/*@{*/
/** \name Upnp_LogLevel
/*! \name Upnp_LogLevel
* The user has the option to select 4 different types of debugging levels,
* see \c UpnpSetLogLevel.
* The critical level will show only those messages
@@ -85,7 +80,6 @@ typedef enum Upnp_Module {
HTTP
} Dbg_Module;
/*@{*/
typedef enum Upnp_LogLevel_e {
UPNP_CRITICAL,
@@ -95,14 +89,11 @@ typedef enum Upnp_LogLevel_e {
} Upnp_LogLevel;
/*@}*/
/**
/*!
* Default log level : see \c Upnp_LogLevel
*/
#define UPNP_DEFAULT_LOG_LEVEL UPNP_ALL
/*!
* \brief Initialize the log files.
*
@@ -117,7 +108,6 @@ static UPNP_INLINE int UpnpInitLog(void)
}
#endif
/*!
* \brief Set the log level (see \c Upnp_LogLevel).
*/
@@ -126,10 +116,13 @@ void UpnpSetLogLevel(
/*! [in] Log level. */
Upnp_LogLevel log_level);
#else
static UPNP_INLINE void UpnpSetLogLevel(Upnp_LogLevel log_level) {}
static UPNP_INLINE void UpnpSetLogLevel(Upnp_LogLevel log_level)
{
return;
log_level = log_level;
}
#endif
/*!
* \brief Closes the log files.
*/
@@ -139,7 +132,6 @@ void UpnpCloseLog(void);
static UPNP_INLINE void UpnpCloseLog(void) {}
#endif
/*!
* \brief Set the name for error and information files, respectively.
*/
@@ -152,10 +144,14 @@ void UpnpSetLogFileNames(
#else
static UPNP_INLINE void UpnpSetLogFileNames(
const char *ErrFileName,
const char *InfoFileName) {}
const char *InfoFileName)
{
return;
ErrFileName = ErrFileName;
InfoFileName = InfoFileName;
}
#endif
/*!
* \brief Check if the module is turned on for debug and returns the file
* descriptor corresponding to the debug level
@@ -174,6 +170,8 @@ FILE *UpnpGetDebugFile(
static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module)
{
return NULL;
level = level;
module = module;
}
#endif
@@ -196,6 +194,8 @@ static UPNP_INLINE int DebugAtThisLevel(
Dbg_Module Module)
{
return 0;
DLevel = DLevel;
Module = Module;
}
#endif
@@ -234,6 +234,12 @@ static UPNP_INLINE void UpnpPrintf(
const char* FmtStr,
...)
{
return;
DLevel = DLevel;
Module = Module;
DbgFileName = DbgFileName;
DbgLineNo = DbgLineNo;
FmtStr = FmtStr;
}
#endif /* DEBUG */
@@ -254,7 +260,13 @@ void UpnpDisplayFileAndLine(
static UPNP_INLINE void UpnpDisplayFileAndLine(
FILE *fd,
const char *DbgFileName,
int DbgLineNo) {}
int DbgLineNo)
{
return;
fd = fd;
DbgFileName = DbgFileName;
DbgLineNo = DbgLineNo;
}
#endif
@@ -270,13 +282,20 @@ void UpnpDisplayBanner(
/*! [in] Size of the buffer. */
size_t size,
/*! [in] This parameter provides the width of the banner. */
int starlength);
size_t starlength);
#else
static UPNP_INLINE void UpnpDisplayBanner(
FILE *fd,
const char **lines,
size_t size,
int starlength) {}
int starlength)
{
return;
fd = fd;
lines = lines;
size = size;
starlength = starlength;
}
#endif
@@ -300,10 +319,14 @@ static UPNP_INLINE void PrintThreadPoolStats(
int DbgLineNo,
const char *msg)
{
return;
tp = tp;
DbgFileName = DbgFileName;
DbgLineNo = DbgLineNo;
msg = msg;
}
#endif
/*@}*/
#ifdef __cplusplus

View File

@@ -96,6 +96,30 @@ EXPORT_SPEC int UpnpResolveURL(
char *AbsURL);
/*!
* \brief Combines a base URL and a relative URL into a single absolute URL.
*
* The memory for \b AbsURL becomes owned by the caller and should be freed
* later.
*
* \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.
* \li <tt>UPNP_E_OUTOF_MEMORY</tt>: Insufficient resources exist to
* complete this operation.
*/
EXPORT_SPEC int UpnpResolveURL2(
/*! [in] The base URL to combine. */
const char *BaseURL,
/*! [in] The relative URL to \b BaseURL. */
const char *RelURL,
/*! [out] A pointer to a pointer to a buffer to store the
* absolute URL. Must be freed later by the caller. */
char **AbsURL);
/*!
* \brief Creates an action request packet based on its input parameters
* (status variable name and value pair).

View File

@@ -19,21 +19,21 @@ LDADD = \
noinst_PROGRAMS =
if ENABLE_SAMPLES
if ENABLE_CLIENT
noinst_PROGRAMS += upnp_tv_ctrlpt
upnp_tv_ctrlpt_CPPFLAGS = \
noinst_PROGRAMS += tv_ctrlpt
tv_ctrlpt_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(srcdir)/common/ \
-I$(srcdir)/tvctrlpt
if ENABLE_DEVICE
noinst_PROGRAMS += upnp_tv_combo
upnp_tv_combo_CPPFLAGS = $(AM_CPPFLAGS) \
noinst_PROGRAMS += tv_combo
tv_combo_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(srcdir)/common/ \
-I$(srcdir)/tvcombo
endif
endif
if ENABLE_DEVICE
noinst_PROGRAMS += upnp_tv_device
upnp_tv_device_CPPFLAGS = \
noinst_PROGRAMS += tv_device
tv_device_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(srcdir)/common/ \
-I$(srcdir)/tvdevice
@@ -41,37 +41,37 @@ endif
endif
upnp_tv_device_SOURCES = \
tv_device_SOURCES = \
common/sample_util.c \
common/sample_util.h \
tvdevice/upnp_tv_device.c \
tvdevice/upnp_tv_device.h \
tvdevice/linux/upnp_tv_device_main.c
common/tv_device.c \
common/tv_device.h \
linux/tv_device_main.c
upnp_tv_ctrlpt_SOURCES = \
tv_ctrlpt_SOURCES = \
common/sample_util.c \
common/sample_util.h \
tvctrlpt/upnp_tv_ctrlpt.c \
tvctrlpt/upnp_tv_ctrlpt.h \
tvctrlpt/linux/upnp_tv_ctrlpt_main.c
common/tv_ctrlpt.c \
common/tv_ctrlpt.h \
linux/tv_ctrlpt_main.c
upnp_tv_combo_SOURCES = \
tv_combo_SOURCES = \
common/sample_util.c \
common/sample_util.h \
tvcombo/upnp_tv_ctrlpt.c \
tvcombo/upnp_tv_ctrlpt.h \
tvcombo/upnp_tv_device.c \
tvcombo/upnp_tv_device.h \
tvcombo/linux/upnp_tv_combo_main.c
common/tv_ctrlpt.c \
common/tv_ctrlpt.h \
common/tv_device.c \
common/tv_device.h \
linux/tv_combo_main.c
if WITH_DOCUMENTATION
examplesdir = $(docdir)/examples
examples_DATA = \
$(sort \
$(upnp_tv_ctrlpt_SOURCES) \
$(upnp_tv_device_SOURCES))
$(tv_ctrlpt_SOURCES) \
$(tv_device_SOURCES))
endif

View File

@@ -30,8 +30,11 @@
******************************************************************************/
#define SAMPLE_UTIL_C
#include "sample_util.h"
#include "tv_ctrlpt.h"
#include "tv_device.h"
#include <assert.h>
#include <stdarg.h>
@@ -54,18 +57,6 @@ state_update gStateUpdateFun = NULL;
/*! mutex to control displaying of events */
ithread_mutex_t display_mutex;
/*******************************************************************************
* SampleUtil_Initialize
*
* Description:
* Initializes the sample util. Must be called before any sample util
* functions. May be called multiple times.
* But the initialization is done only once.
*
* Parameters:
* print_function - print function to use in SampleUtil_Print
*
******************************************************************************/
int SampleUtil_Initialize(print_string print_function)
{
if (initialize_init) {
@@ -82,22 +73,11 @@ int SampleUtil_Initialize(print_string print_function)
ithread_mutex_unlock(&display_mutex);
initialize_init = 0;
} else {
SampleUtil_Print("***** SampleUtil_Initialize was called multiple times!\n");
abort();
}
return UPNP_E_SUCCESS;
}
/*******************************************************************************
* SampleUtil_RegisterUpdateFunction
*
* Description:
*
* Parameters:
*
******************************************************************************/
int SampleUtil_RegisterUpdateFunction(state_update update_function)
{
if (initialize_register) {
@@ -108,15 +88,6 @@ int SampleUtil_RegisterUpdateFunction(state_update update_function)
return UPNP_E_SUCCESS;
}
/*******************************************************************************
* SampleUtil_Finish
*
* Description:
* Releases Resources held by sample util.
*
* Parameters:
*
******************************************************************************/
int SampleUtil_Finish()
{
ithread_mutex_destroy(&display_mutex);
@@ -128,21 +99,7 @@ int SampleUtil_Finish()
return UPNP_E_SUCCESS;
}
/*******************************************************************************
* SampleUtil_GetElementValue
*
* Description:
* Given a DOM node such as <Channel>11</Channel>, this routine
* extracts the value (e.g., 11) from the node and returns it as
* a string. The string must be freed by the caller using
* free.
*
* Parameters:
* node -- The DOM node from which to extract the value
*
******************************************************************************/
char *SampleUtil_GetElementValue(IN IXML_Element *element)
char *SampleUtil_GetElementValue(IXML_Element *element)
{
IXML_Node *child = ixmlNode_getFirstChild((IXML_Node *)element);
char *temp = NULL;
@@ -154,20 +111,7 @@ char *SampleUtil_GetElementValue(IN IXML_Element *element)
return temp;
}
/*******************************************************************************
* SampleUtil_GetFirstServiceList
*
* Description:
* Given a DOM node representing a UPnP Device Description Document,
* this routine parses the document and finds the first service list
* (i.e., the service list for the root device). The service list
* is returned as a DOM node list.
*
* Parameters:
* node -- The DOM node from which to extract the service list
*
******************************************************************************/
IXML_NodeList *SampleUtil_GetFirstServiceList(IN IXML_Document *doc)
IXML_NodeList *SampleUtil_GetFirstServiceList(IXML_Document *doc)
{
IXML_NodeList *ServiceList = NULL;
IXML_NodeList *servlistnodelist = NULL;
@@ -179,7 +123,6 @@ IXML_NodeList *SampleUtil_GetFirstServiceList(IN IXML_Document *doc)
/* we only care about the first service list, from the root
* device */
servlistnode = ixmlNodeList_item(servlistnodelist, 0);
/* create as list of DOM nodes */
ServiceList = ixmlElement_getElementsByTagName(
(IXML_Element *)servlistnode, "service");
@@ -195,23 +138,24 @@ IXML_NodeList *SampleUtil_GetFirstServiceList(IN IXML_Document *doc)
* Obtain the service list
* n == 0 the first
* n == 1 the next in the device list, etc..
*
*/
IXML_NodeList *SampleUtil_GetNthServiceList(IN IXML_Document *doc , int n)
static IXML_NodeList *SampleUtil_GetNthServiceList(
/*! [in] . */
IXML_Document *doc,
/*! [in] . */
unsigned int n)
{
IXML_NodeList *ServiceList = NULL;
IXML_NodeList *servlistnodelist = NULL;
IXML_Node *servlistnode = NULL;
/*
* ixmlDocument_getElementsByTagName()
/* ixmlDocument_getElementsByTagName()
* Returns a NodeList of all Elements that match the given
* tag name in the order in which they were encountered in a preorder
* traversal of the Document tree.
*
* return (NodeList*) A pointer to a NodeList containing the
* matching items or NULL on an error.
*/
* matching items or NULL on an error. */
SampleUtil_Print("SampleUtil_GetNthServiceList called : n = %d\n", n);
servlistnodelist =
ixmlDocument_getElementsByTagName(doc, "serviceList");
@@ -226,8 +170,7 @@ IXML_NodeList *SampleUtil_GetNthServiceList(IN IXML_Document *doc , int n)
* numerical index.
*
* return (Node*) A pointer to a Node or NULL if there was an
* error.
*/
* error. */
servlistnode = ixmlNodeList_item(servlistnodelist, n);
assert(servlistnode != 0);
@@ -244,20 +187,7 @@ IXML_NodeList *SampleUtil_GetNthServiceList(IN IXML_Document *doc , int n)
return ServiceList;
}
/*******************************************************************************
* SampleUtil_GetFirstDocumentItem
*
* Description:
* Given a document node, this routine searches for the first element
* named by the input string item, and returns its value as a string.
* String must be freed by caller using free.
* Parameters:
* doc -- The DOM document from which to extract the value
* item -- The item to search for
*
******************************************************************************/
char *SampleUtil_GetFirstDocumentItem(
IN IXML_Document *doc, IN const char *item)
char *SampleUtil_GetFirstDocumentItem(IXML_Document *doc, const char *item)
{
IXML_NodeList *nodeList = NULL;
IXML_Node *textNode = NULL;
@@ -302,20 +232,7 @@ epilogue:
return ret;
}
/*******************************************************************************
* SampleUtil_GetFirstElementItem
*
* Description:
* Given a DOM element, this routine searches for the first element
* named by the input string item, and returns its value as a string.
* The string must be freed using free.
* Parameters:
* node -- The DOM element from which to extract the value
* item -- The item to search for
*
******************************************************************************/
char *SampleUtil_GetFirstElementItem(
IN IXML_Element *element, IN const char *item)
char *SampleUtil_GetFirstElementItem(IXML_Element *element, const char *item)
{
IXML_NodeList *nodeList = NULL;
IXML_Node *textNode = NULL;
@@ -349,17 +266,7 @@ char *SampleUtil_GetFirstElementItem(
return ret;
}
/*******************************************************************************
* SampleUtil_PrintEventType
*
* Description:
* Prints a callback event type as a string.
*
* Parameters:
* S -- The callback event
*
******************************************************************************/
void SampleUtil_PrintEventType(IN Upnp_EventType S)
void SampleUtil_PrintEventType(Upnp_EventType S)
{
switch (S) {
/* Discovery */
@@ -413,18 +320,7 @@ void SampleUtil_PrintEventType(IN Upnp_EventType S)
}
}
/*******************************************************************************
* SampleUtil_PrintEvent
*
* Description:
* Prints callback event structure details.
*
* Parameters:
* EventType -- The type of callback event
* Event -- The callback event structure
*
******************************************************************************/
int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
int SampleUtil_PrintEvent(Upnp_EventType EventType, void *Event)
{
ithread_mutex_lock(&display_mutex);
@@ -542,7 +438,6 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
SampleUtil_Print("CurrentVal = %s\n", sv_event->CurrentVal);
break;
}
/* GENA */
case UPNP_EVENT_SUBSCRIPTION_REQUEST: {
struct Upnp_Subscription_Request *sr_event =
@@ -610,31 +505,14 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
return 0;
}
/*******************************************************************************
* SampleUtil_FindAndParseService
*
* Description:
* This routine finds the first occurance of a service in a DOM representation
* of a description document and parses it.
*
* Parameters:
* DescDoc -- The DOM description document
* location -- The location of the description document
* serviceSearchType -- The type of service to search for
* serviceId -- OUT -- The service ID
* eventURL -- OUT -- The event URL for the service
* controlURL -- OUT -- The control URL for the service
*
******************************************************************************/
int SampleUtil_FindAndParseService(
IN IXML_Document *DescDoc, IN const char *location, IN char *serviceType,
OUT char **serviceId, OUT char **eventURL, OUT char **controlURL)
int SampleUtil_FindAndParseService(IXML_Document *DescDoc, const char *location,
const char *serviceType, char **serviceId, char **eventURL, char **controlURL)
{
int i;
int length;
unsigned int i;
unsigned long length;
int found = 0;
int ret;
int sindex = 0;
unsigned int sindex = 0;
char *tempServiceType = NULL;
char *baseURL = NULL;
const char *base = NULL;
@@ -653,7 +531,7 @@ int SampleUtil_FindAndParseService(
/* Top level */
for (sindex = 0;
(serviceList = SampleUtil_GetNthServiceList(DescDoc , sindex)) != NULL;
sindex ++) {
sindex++) {
tempServiceType = NULL;
relcontrolURL = NULL;
releventURL = NULL;
@@ -714,20 +592,7 @@ int SampleUtil_FindAndParseService(
return found;
}
/*******************************************************************************
* SampleUtil_Print
*
* Description:
* Provides platform-specific print functionality. This function should be
* called when you want to print content suitable for console output (i.e.,
* in a large text box or on a screen). If your device/operating system is
* not supported here, you should add a port.
*
* Parameters:
* Same as printf()
*
******************************************************************************/
int SampleUtil_Print(char *fmt, ...)
int SampleUtil_Print(const char *fmt, ...)
{
#define MAX_BUF (8 * 1024)
va_list ap;
@@ -740,9 +605,8 @@ int SampleUtil_Print(char *fmt, ...)
va_start(ap, fmt);
rc = vsnprintf(buf, MAX_BUF, fmt, ap);
va_end(ap);
if (gPrintFun) {
gPrintFun(buf);
gPrintFun("%s", buf);
}
ithread_mutex_unlock(&display_mutex);
@@ -750,14 +614,6 @@ int SampleUtil_Print(char *fmt, ...)
return rc;
}
/*******************************************************************************
* SampleUtil_StateUpdate
*
* Description:
*
* Parameters:
*
******************************************************************************/
void SampleUtil_StateUpdate(const char *varName, const char *varValue,
const char *UDN, eventType type)
{
@@ -767,3 +623,15 @@ void SampleUtil_StateUpdate(const char *varName, const char *varValue,
}
}
/*!
* \brief Prints a string to standard out.
*/
void linux_print(const char *format, ...)
{
va_list argList;
va_start(argList, format);
vfprintf(stdout, format, argList);
fflush(stdout);
va_end(argList);
}

View File

@@ -29,30 +29,38 @@
*
******************************************************************************/
#ifndef SAMPLE_UTIL_H
#define SAMPLE_UTIL_H
/*!
* \file
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include "ithread.h"
#include "ixml.h" /* for IXML_Document, IXML_Element */
#include "upnp.h" /* for Upnp_EventType */
#include "upnptools.h"
#include <stdlib.h>
#include <string.h>
#ifdef SAMPLE_UTIL_C
/*! Service types for tv services. */
const char *TvServiceType[] = {
"urn:schemas-upnp-org:service:tvcontrol:1",
"urn:schemas-upnp-org:service:tvpicture:1"
};
#else /* SAMPLE_UTIL_C */
extern const char *TvServiceType[];
#endif /* SAMPLE_UTIL_C */
/* mutex to control displaying of events */
extern ithread_mutex_t display_mutex;
typedef enum {
STATE_UPDATE = 0,
DEVICE_ADDED = 1,
@@ -60,233 +68,196 @@ typedef enum {
GET_VAR_COMPLETE = 3
} eventType;
/********************************************************************************
* SampleUtil_GetElementValue
*
* Description:
* Given a DOM node such as <Channel>11</Channel>, this routine
/*!
* \brief Given a DOM node such as <Channel>11</Channel>, this routine
* extracts the value (e.g., 11) from the node and returns it as
* a string. The string must be freed by the caller using
* free.
* a string. The string must be freed by the caller using free.
*
* Parameters:
* node -- The DOM node from which to extract the value
*
********************************************************************************/
char *SampleUtil_GetElementValue(IN IXML_Element *element);
* \return The DOM node as a string.
*/
char *SampleUtil_GetElementValue(
/*! [in] The DOM node from which to extract the value. */
IXML_Element *element);
/********************************************************************************
* SampleUtil_GetFirstServiceList
*
* Description:
* Given a DOM node representing a UPnP Device Description Document,
/*!
* \brief Given a DOM node representing a UPnP Device Description Document,
* this routine parses the document and finds the first service list
* (i.e., the service list for the root device). The service list
* is returned as a DOM node list. The NodeList must be freed using
* NodeList_free.
*
* Parameters:
* node -- The DOM node from which to extract the service list
*
********************************************************************************/
* \return The service list is returned as a DOM node list.
*/
IXML_NodeList *SampleUtil_GetFirstServiceList(
/*! [in] The DOM node from which to extract the service list. */
IXML_Document *doc);
IXML_NodeList *SampleUtil_GetFirstServiceList(IN IXML_Document *doc);
/********************************************************************************
* SampleUtil_GetFirstDocumentItem
*
* Description:
* Given a document node, this routine searches for the first element
/*!
* \brief Given a document node, this routine searches for the first element
* named by the input string item, and returns its value as a string.
* String must be freed by caller using free.
* Parameters:
* doc -- The DOM document from which to extract the value
* item -- The item to search for
*
********************************************************************************/
char *SampleUtil_GetFirstDocumentItem(IN IXML_Document *doc, IN const char *item);
*/
char *SampleUtil_GetFirstDocumentItem(
/*! [in] The DOM document from which to extract the value. */
IXML_Document *doc,
/*! [in] The item to search for. */
const char *item);
/********************************************************************************
* SampleUtil_GetFirstElementItem
*
* Description:
* Given a DOM element, this routine searches for the first element
/*!
* \brief Given a DOM element, this routine searches for the first element
* named by the input string item, and returns its value as a string.
* The string must be freed using free.
* Parameters:
* node -- The DOM element from which to extract the value
* item -- The item to search for
*
********************************************************************************/
char *SampleUtil_GetFirstElementItem(IN IXML_Element *element, IN const char *item);
*/
char *SampleUtil_GetFirstElementItem(
/*! [in] The DOM element from which to extract the value. */
IXML_Element *element,
/*! [in] The item to search for. */
const char *item);
/********************************************************************************
* SampleUtil_PrintEventType
*
* Description:
* Prints a callback event type as a string.
*
* Parameters:
* S -- The callback event
*
********************************************************************************/
void SampleUtil_PrintEventType(IN Upnp_EventType S);
/*!
* \brief Prints a callback event type as a string.
*/
void SampleUtil_PrintEventType(
/*! [in] The callback event. */
Upnp_EventType S);
/********************************************************************************
* SampleUtil_PrintEvent
*
* Description:
* Prints callback event structure details.
*
* Parameters:
* EventType -- The type of callback event
* Event -- The callback event structure
*
********************************************************************************/
int SampleUtil_PrintEvent(IN Upnp_EventType EventType,
IN void *Event);
/*!
* \brief Prints callback event structure details.
*/
int SampleUtil_PrintEvent(
/*! [in] The type of callback event. */
Upnp_EventType EventType,
/*! [in] The callback event structure. */
void *Event);
/********************************************************************************
* SampleUtil_FindAndParseService
*
* Description:
* This routine finds the first occurance of a service in a DOM representation
* of a description document and parses it. Note that this function currently
* assumes that the eventURL and controlURL values in the service definitions
* are full URLs. Relative URLs are not handled here.
*
* Parameters:
* DescDoc -- The DOM description document
* location -- The location of the description document
* serviceSearchType -- The type of service to search for
* serviceId -- OUT -- The service ID
* eventURL -- OUT -- The event URL for the service
* controlURL -- OUT -- The control URL for the service
*
********************************************************************************/
/*!
* \brief This routine finds the first occurance of a service in a DOM
* representation of a description document and parses it. Note that this
* function currently assumes that the eventURL and controlURL values in
* the service definitions are full URLs. Relative URLs are not handled here.
*/
int SampleUtil_FindAndParseService (
IN IXML_Document *DescDoc,
IN const char* location,
IN char *serviceType,
OUT char **serviceId,
OUT char **eventURL,
OUT char **controlURL);
/*! [in] The DOM description document. */
IXML_Document *DescDoc,
/*! [in] The location of the description document. */
const char *location,
/*! [in] The type of service to search for. */
const char *serviceType,
/*! [out] The service ID. */
char **serviceId,
/*! [out] The event URL for the service. */
char **eventURL,
/*! [out] The control URL for the service. */
char **controlURL);
/********************************************************************************
* print_string
*
* Description:
* Prototype for displaying strings. All printing done by the device,
/*!
* \brief Prototype for displaying strings. All printing done by the device,
* control point, and sample util, ultimately use this to display strings
* to the user.
*
* Parameters:
* const char * string.
*
********************************************************************************/
typedef void (*print_string)(const char *string);
*/
typedef void (*print_string)(
/*! [in] Format. */
const char *string,
/*! [in] Arguments. */
...)
#if (__GNUC__ >= 3)
/* This enables printf like format checking by the compiler */
__attribute__((format (__printf__, 1, 2)))
#endif
;
//global print function used by sample util
/*! global print function used by sample util */
extern print_string gPrintFun;
/********************************************************************************
* state_update
*
* Description:
* Prototype for passing back state changes
*
* Parameters:
* const char * varName
* const char * varValue
* const char * UDN
* int newDevice
********************************************************************************/
/*!
* \brief Prototype for passing back state changes.
*/
typedef void (*state_update)(
/*! [in] . */
const char *varName,
/*! [in] . */
const char *varValue,
/*! [in] . */
const char *UDN,
/*! [in] . */
eventType type);
//global state update function used by smaple util
/*! global state update function used by smaple util */
extern state_update gStateUpdateFun;
/********************************************************************************
* SampleUtil_Initialize
*
* Description:
* Initializes the sample util. Must be called before any sample util
/*!
* \brief Initializes the sample util. Must be called before any sample util
* functions. May be called multiple times.
*
* Parameters:
* print_function - print function to use in SampleUtil_Print
*
********************************************************************************/
int SampleUtil_Initialize(print_string print_function);
*/
int SampleUtil_Initialize(
/*! [in] Print function to use in SampleUtil_Print. */
print_string print_function);
/********************************************************************************
* SampleUtil_Finish
*
* Description:
* Releases Resources held by sample util.
*
* Parameters:
*
********************************************************************************/
/*!
* \brief Releases Resources held by sample util.
*/
int SampleUtil_Finish();
/********************************************************************************
* SampleUtil_Print
*
* Description:
* Function emulating printf that ultimately calls the registered print
/*!
* \brief Function emulating printf that ultimately calls the registered print
* function with the formatted string.
*
* Parameters:
* fmt - format (see printf)
* . . . - variable number of args. (see printf)
* Provides platform-specific print functionality. This function should be
* called when you want to print content suitable for console output (i.e.,
* in a large text box or on a screen). If your device/operating system is
* not supported here, you should add a port.
*
********************************************************************************/
int SampleUtil_Print(char *fmt, ...);
* \return The same as printf.
*/
int SampleUtil_Print(
/*! [in] Format (see printf). */
const char *fmt,
/*! [in] Format data. */
...)
#if (__GNUC__ >= 3)
/* This enables printf like format checking by the compiler */
__attribute__((format (__printf__, 1, 2)))
#endif
;
/********************************************************************************
* SampleUtil_RegisterUpdateFunction
*
* Description:
*
* Parameters:
*
********************************************************************************/
int SampleUtil_RegisterUpdateFunction(state_update update_function);
/*!
* \brief
*/
int SampleUtil_RegisterUpdateFunction(
/*! [in] . */
state_update update_function);
/********************************************************************************
* SampleUtil_StateUpdate
*
* Description:
*
* Parameters:
*
********************************************************************************/
/*!
* \brief
*/
void SampleUtil_StateUpdate(
/*! [in] . */
const char *varName,
/*! [in] . */
const char *varValue,
/*! [in] . */
const char *UDN,
/*! [in] . */
eventType type);
/*!
* \brief Prints a string to standard out.
*/
void linux_print(const char *format, ...)
#if (__GNUC__ >= 3)
/* This enables printf like format checking by the compiler */
__attribute__((format (__printf__, 1, 2)))
#endif
;
#ifdef __cplusplus
};
#endif /* __cplusplus */
#ifdef WIN32
#define snprintf _snprintf
#define strcasecmp stricmp
#endif
#endif /* SAMPLE_UTIL_H */

File diff suppressed because it is too large Load Diff

View File

@@ -29,39 +29,36 @@
*
**************************************************************************/
#ifndef UPNP_TV_CTRLPT_H
#define UPNP_TV_CTRLPT_H
/*!
* \file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "sample_util.h"
#include "ithread.h"
#include "upnp.h"
#include "UpnpString.h"
#include "upnptools.h"
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
#define TV_SERVICE_SERVCOUNT 2
#define TV_SERVICE_CONTROL 0
#define TV_SERVICE_PICTURE 1
@@ -86,10 +83,8 @@ extern "C" {
/* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[];
extern char *TvServiceType[];
extern char *TvServiceName[];
extern char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS];
extern const char *TvServiceName[];
extern const char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS];
extern char TvVarCount[];
struct tv_service {
@@ -127,9 +122,8 @@ int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll(void);
int TvCtrlPointRefresh(void);
int TvCtrlPointSendAction(int, int, char *, char **, char **, int);
int TvCtrlPointSendActionNumericArg(int devnum, int service, char *actionName, char *paramName, int paramValue);
int TvCtrlPointSendAction(int, int, const char *, const char **, char **, int);
int TvCtrlPointSendActionNumericArg(int devnum, int service, const char *actionName, const char *paramName, int paramValue);
int TvCtrlPointSendPowerOn(int devnum);
int TvCtrlPointSendPowerOff(int devnum);
int TvCtrlPointSendSetChannel(int, int);
@@ -139,7 +133,7 @@ int TvCtrlPointSendSetTint(int, int);
int TvCtrlPointSendSetContrast(int, int);
int TvCtrlPointSendSetBrightness(int, int);
int TvCtrlPointGetVar(int, int, char*);
int TvCtrlPointGetVar(int, int, const char *);
int TvCtrlPointGetPower(int devnum);
int TvCtrlPointGetChannel(int);
int TvCtrlPointGetVolume(int);
@@ -153,19 +147,76 @@ int TvCtrlPointPrintList(void);
int TvCtrlPointPrintDevice(int);
void TvCtrlPointAddDevice(IXML_Document *, const char *, int);
void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString);
void TvStateUpdate(char*,int, IXML_Document * , char **);
/*!
* \brief Update a Tv state table. Called when an event is received.
*
* Note: this function is NOT thread save. It must be called from another
* function that has locked the global device list.
**/
void TvStateUpdate(
/*! [in] The UDN of the parent device. */
char *UDN,
/*! [in] The service state table to update. */
int Service,
/*! [out] DOM document representing the XML received with the event. */
IXML_Document *ChangedVariables,
/*! [out] pointer to the state table for the Tv service to update. */
char **State);
void TvCtrlPointHandleEvent(const char *, int, IXML_Document *);
void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int);
int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *);
void TvCtrlPointVerifyTimeouts(int);
/*!
* \brief Checks the advertisement each device in the global device list.
*
* If an advertisement expires, the device is removed from the list.
*
* If an advertisement is about to expire, a search request is sent for that
* device.
*/
void TvCtrlPointVerifyTimeouts(
/*! [in] The increment to subtract from the timeouts each time the
* function is called. */
int incr);
void TvCtrlPointPrintCommands(void);
void* TvCtrlPointCommandLoop(void *);
int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr);
int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr, int combo);
int TvCtrlPointStop(void);
int TvCtrlPointProcessCommand(char *cmdline);
/*!
* \brief Print help info for this application.
*/
void TvCtrlPointPrintShortHelp(void);
/*!
* \brief Print long help info for this application.
*/
void TvCtrlPointPrintLongHelp(void);
/*!
* \briefPrint the list of valid command line commands to the user
*/
void TvCtrlPointPrintCommands(void);
/*!
* \brief Function that receives commands from the user at the command prompt
* during the lifetime of the device, and calls the appropriate
* functions for those commands.
*/
void *TvCtrlPointCommandLoop(void *args);
/*!
* \brief
*/
int TvCtrlPointProcessCommand(char *cmdline);
#ifdef __cplusplus
};
#endif
#endif //UPNP_TV_CTRLPT_H
#endif /* UPNP_TV_CTRLPT_H */

View File

@@ -0,0 +1,566 @@
/**************************************************************************
*
* 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 UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H
/*!
* \file
*/
#include <stdio.h>
#include <signal.h>
#ifdef __cplusplus
extern "C" {
#endif
#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 */
#define MAX_COLOR 10
#define MIN_COLOR 1
/*! Brightness constants */
#define MAX_BRIGHTNESS 10
#define MIN_BRIGHTNESS 1
/*! Power constants */
#define POWER_ON 1
#define POWER_OFF 0
/*! Tint constants */
#define MAX_TINT 10
#define MIN_TINT 1
/*! Volume constants */
#define MAX_VOLUME 10
#define MIN_VOLUME 1
/*! Contrast constants */
#define MAX_CONTRAST 10
#define MIN_CONTRAST 1
/*! Channel constants */
#define MAX_CHANNEL 100
#define MIN_CHANNEL 1
/*! Number of services. */
#define TV_SERVICE_SERVCOUNT 2
/*! Index of control service */
#define TV_SERVICE_CONTROL 0
/*! Index of picture service */
#define TV_SERVICE_PICTURE 1
/*! Number of control variables */
#define TV_CONTROL_VARCOUNT 3
/*! Index of power variable */
#define TV_CONTROL_POWER 0
/*! Index of channel variable */
#define TV_CONTROL_CHANNEL 1
/*! Index of volume variable */
#define TV_CONTROL_VOLUME 2
/*! Number of picture variables */
#define TV_PICTURE_VARCOUNT 4
/*! Index of color variable */
#define TV_PICTURE_COLOR 0
/*! Index of tint variable */
#define TV_PICTURE_TINT 1
/*! Index of contrast variable */
#define TV_PICTURE_CONTRAST 2
/*! Index of brightness variable */
#define TV_PICTURE_BRIGHTNESS 3
/*! Max value length */
#define TV_MAX_VAL_LEN 5
/*! Max actions */
#define TV_MAXACTIONS 12
/*! This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT
/*!
* \brief Prototype for all actions. For each action that a service
* implements, there is a corresponding function with this prototype.
*
* Pointers to these functions, along with action names, are stored
* in the service table. When an action request comes in the action
* name is matched, and the appropriate function is called.
* Each function returns UPNP_E_SUCCESS, on success, and a nonzero
* error code on failure.
*/
typedef int (*upnp_action)(
/*! [in] Document of action request. */
IXML_Document *request,
/*! [out] Action result. */
IXML_Document **out,
/*! [out] Error string in case action was unsuccessful. */
const char **errorString);
/*! Structure for storing Tv Service identifiers and state table. */
struct TvService {
/*! Universally Unique Device Name. */
char UDN[NAME_SIZE];
/*! . */
char ServiceId[NAME_SIZE];
/*! . */
char ServiceType[NAME_SIZE];
/*! . */
const char *VariableName[TV_MAXVARS];
/*! . */
char *VariableStrVal[TV_MAXVARS];
/*! . */
const char *ActionNames[TV_MAXACTIONS];
/*! . */
upnp_action actions[TV_MAXACTIONS];
/*! . */
int VariableCount;
};
/*! Array of service structures */
extern struct TvService tv_service_table[];
/*! Device handle returned from sdk */
extern UpnpDevice_Handle device_handle;
/*! Mutex for protecting the global state table data
* in a multi-threaded, asynchronous environment.
* All functions should lock this mutex before reading
* or writing the state table data. */
extern ithread_mutex_t TVDevMutex;
/*!
* \brief Initializes the action table for the specified service.
*
* Note that knowledge of the service description is assumed.
* Action names are hardcoded.
*/
int SetActionTable(
/*! [in] one of TV_SERVICE_CONTROL or, TV_SERVICE_PICTURE. */
int serviceType,
/*! [in,out] service containing action table to set. */
struct TvService *out);
/*!
* \brief Initialize the device state table for this TvDevice, pulling
* identifier info from the description Document.
*
* Note that knowledge of the service description is assumed.
* State table variables and default values are currently hardcoded in
* this file rather than being read from service description documents.
*/
int TvDeviceStateTableInit(
/*! [in] The description document URL. */
char *DescDocURL);
/*!
* \brief Called during a subscription request callback.
*
* If the subscription request is for this device and either its
* control service or picture service, then accept it.
*/
int TvDeviceHandleSubscriptionRequest(
/*! [in] The subscription request event structure. */
struct Upnp_Subscription_Request *sr_event);
/*!
* \brief Called during a get variable request callback.
*
* If the request is for this device and either its control service or
* picture service, then respond with the variable value.
*/
int TvDeviceHandleGetVarRequest(
/*! [in,out] The control get variable request event structure. */
struct Upnp_State_Var_Request *cgv_event);
/*!
* \brief Called during an action request callback.
*
* If the request is for this device and either its control service
* or picture service, then perform the action and respond.
*/
int TvDeviceHandleActionRequest(
/*! [in,out] The control action request event structure. */
struct Upnp_Action_Request *ca_event);
/*!
* \brief The callback handler registered with the SDK while registering
* root device.
*
* Dispatches the request to the appropriate procedure
* based on the value of EventType. The four requests handled by the
* device are:
* \li 1) Event Subscription requests.
* \li 2) Get Variable requests.
* \li 3) Action requests.
*/
int TvDeviceCallbackEventHandler(
/*! [in] The type of callback event. */
Upnp_EventType,
/*! [in] Data structure containing event data. */
void *Event,
/*! [in] Optional data specified during callback registration. */
void *Cookie);
/*!
* \brief Update the TvDevice service state table, and notify all subscribed
* control points of the updated state.
*
* Note that since this function blocks on the mutex TVDevMutex,
* to avoid a hang this function should not be called within any other
* function that currently has this mutex locked.
*/
int TvDeviceSetServiceTableVar(
/*! [in] The service number (TV_SERVICE_CONTROL or TV_SERVICE_PICTURE). */
unsigned int service,
/*! [in] The variable number (TV_CONTROL_POWER, TV_CONTROL_CHANNEL,
* TV_CONTROL_VOLUME, TV_PICTURE_COLOR, TV_PICTURE_TINT,
* TV_PICTURE_CONTRAST, or TV_PICTURE_BRIGHTNESS). */
int variable,
/*! [in] The string representation of the new value. */
char *value);
/* Control Service Actions */
/*!
* \brief Turn the power on.
*/
int TvDevicePowerOn(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Turn the power off.
*/
int TvDevicePowerOff(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Change the channel, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetChannel(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase the channel.
*/
int TvDeviceIncreaseChannel(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease the channel.
*/
int TvDeviceDecreaseChannel(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Change the volume, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetVolume(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase the volume.
*/
int TvDeviceIncreaseVolume(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease the volume.
*/
int TvDeviceDecreaseVolume(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*Picture Service Actions */
/*!
* \brief Change the color, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetColor(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase the color.
*/
int TvDeviceIncreaseColor(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease the color.
*/
int TvDeviceDecreaseColor(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Change the tint, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetTint(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase tint.
*/
int TvDeviceIncreaseTint(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease tint.
*/
int TvDeviceDecreaseTint(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Change the contrast, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetContrast(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase the contrast.
*/
int TvDeviceIncreaseContrast(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease the contrast.
*/
int TvDeviceDecreaseContrast(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Change the brightness, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*/
int TvDeviceSetBrightness(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Increase brightnesss.
*/
int TvDeviceIncreaseBrightness(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Decrease brightnesss.
*/
int TvDeviceDecreaseBrightness(
/*! [in] Document of action request. */
IXML_Document *in,
/*! [in] Action result. */
IXML_Document **out,
/*! [out] ErrorString in case action was unsuccessful. */
const char **errorString);
/*!
* \brief Initializes the UPnP Sdk, registers the device, and sends out
* advertisements.
*/
int TvDeviceStart(
/*! [in] ip address to initialize the sdk (may be NULL)
* if null, then the first non null loopback address is used. */
char *ip_address,
/*! [in] port number to initialize the sdk (may be 0)
* if zero, then a random number is used. */
unsigned short port,
/*! [in] name of description document.
* may be NULL. Default is tvdevicedesc.xml. */
const char *desc_doc_name,
/*! [in] path of web directory.
* may be NULL. Default is ./web (for Linux) or ../tvdevice/web. */
const char *web_dir_path,
/*! [in] print function to use. */
print_string pfun,
/*! [in] Non-zero if called from the combo application. */
int combo);
/*!
* \brief Stops the device. Uninitializes the sdk.
*/
int TvDeviceStop(void);
/*!
* \brief Function that receives commands from the user at the command prompt
* during the lifetime of the device, and calls the appropriate
* functions for those commands. Only one command, exit, is currently
* defined.
*/
void *TvDeviceCommandLoop(void *args);
/*!
* \brief Main entry point for tv device application.
*
* Initializes and registers with the sdk.
* Initializes the state stables of the service.
* Starts the command loop.
*
* Accepts the following optional arguments:
* \li \c -ip ipaddress
* \li \c -port port
* \li \c -desc desc_doc_name
* \li \c -webdir web_dir_path
* \li \c -help
*/
int device_main(int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,72 @@
/*******************************************************************************
*
* 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.
*
******************************************************************************/
#include "sample_util.h"
#include "tv_ctrlpt.h"
#include "tv_device.h"
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
device_main(argc, argv);
rc = TvCtrlPointStart(linux_print, NULL, 1);
if (rc != TV_SUCCESS) {
SampleUtil_Print("Error starting UPnP TV Control Point\n");
return rc;
}
/* start a command loop thread */
code = ithread_create(&cmdloop_thread, NULL, TvCtrlPointCommandLoop, NULL);
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/* Catch Ctrl-C and properly shutdown */
sigemptyset(&sigs_to_catch);
sigaddset(&sigs_to_catch, SIGINT);
sigwait(&sigs_to_catch, &sig);
SampleUtil_Print("Shutting down on signal %d...\n", sig);
#endif
TvDeviceStop();
rc = TvCtrlPointStop();
return rc;
}

View File

@@ -0,0 +1,72 @@
/*******************************************************************************
*
* 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.
*
******************************************************************************/
#include "sample_util.h"
#include "tv_ctrlpt.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
rc = TvCtrlPointStart(linux_print, NULL, 0);
if (rc != TV_SUCCESS) {
SampleUtil_Print("Error starting UPnP TV Control Point\n");
return rc;
}
/* start a command loop thread */
code = ithread_create(&cmdloop_thread, NULL, TvCtrlPointCommandLoop, NULL);
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/* Catch Ctrl-C and properly shutdown */
sigemptyset(&sigs_to_catch);
sigaddset(&sigs_to_catch, SIGINT);
sigwait(&sigs_to_catch, &sig);
SampleUtil_Print("Shutting down on signal %d...\n", sig);
#endif
rc = TvCtrlPointStop();
return rc;
argc = argc;
argv = argv;
}

View File

@@ -0,0 +1,65 @@
/*******************************************************************************
*
* 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.
*
******************************************************************************/
#include "sample_util.h"
#include "tv_device.h"
#include <stdarg.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
device_main(argc, argv);
/* start a command loop thread */
code = ithread_create(&cmdloop_thread, NULL, TvDeviceCommandLoop, NULL);
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/* Catch Ctrl-C and properly shutdown */
sigemptyset(&sigs_to_catch);
sigaddset(&sigs_to_catch, SIGINT);
sigwait(&sigs_to_catch, &sig);
SampleUtil_Print("Shutting down on signal %d...\n", sig);
#endif
rc = TvDeviceStop();
return rc;
}

View File

@@ -1,491 +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.
*
******************************************************************************/
#include "sample_util.h"
#include "upnp_tv_ctrlpt.h"
#include "upnp_tv_device.h"
#include <stdio.h>
#include <string.h>
/*
Tags for valid commands issued at the command prompt
*/
enum cmdloop_tvcmds {
PRTHELP = 0, PRTFULLHELP, POWON, POWOFF,
SETCHAN, SETVOL, SETCOL, SETTINT, SETCONT, SETBRT,
CTRLACTION, PICTACTION, CTRLGETVAR, PICTGETVAR,
PRTDEV, LSTDEV, REFRESH, EXITCMD
};
/*
Data structure for parsing commands from the command line
*/
struct cmdloop_commands {
char *str; // the string
int cmdnum; // the command
int numargs; // the number of arguments
char *args; // the args
} cmdloop_commands;
/*
Mappings between command text names, command tag,
and required command arguments for command line
commands
*/
static struct cmdloop_commands cmdloop_cmdlist[] = {
{"Help", PRTHELP, 1, ""},
{"HelpFull", PRTFULLHELP, 1, ""},
{"ListDev", LSTDEV, 1, ""},
{"Refresh", REFRESH, 1, ""},
{"PrintDev", PRTDEV, 2, "<devnum>"},
{"PowerOn", POWON, 2, "<devnum>"},
{"PowerOff", POWOFF, 2, "<devnum>"},
{"SetChannel", SETCHAN, 3, "<devnum> <channel (int)>"},
{"SetVolume", SETVOL, 3, "<devnum> <volume (int)>"},
{"SetColor", SETCOL, 3, "<devnum> <color (int)>"},
{"SetTint", SETTINT, 3, "<devnum> <tint (int)>"},
{"SetContrast", SETCONT, 3, "<devnum> <contrast (int)>"},
{"SetBrightness", SETBRT, 3, "<devnum> <brightness (int)>"},
{"CtrlAction", CTRLACTION, 2, "<devnum> <action (string)>"},
{"PictAction", PICTACTION, 2, "<devnum> <action (string)>"},
{"CtrlGetVar", CTRLGETVAR, 2, "<devnum> <varname (string)>"},
{"PictGetVar", PICTGETVAR, 2, "<devnum> <varname (string)>"},
{"Exit", EXITCMD, 1, ""}
};
void
linux_print( const char *string )
{
puts( string );
}
/********************************************************************************
* TvCtrlPointPrintHelp
*
* Description:
* Print help info for this application.
********************************************************************************/
void
TvCtrlPointPrintShortHelp( void )
{
SampleUtil_Print( "Commands:" );
SampleUtil_Print( " Help" );
SampleUtil_Print( " HelpFull" );
SampleUtil_Print( " ListDev" );
SampleUtil_Print( " Refresh" );
SampleUtil_Print( " PrintDev <devnum>" );
SampleUtil_Print( " PowerOn <devnum>" );
SampleUtil_Print( " PowerOff <devnum>" );
SampleUtil_Print( " SetChannel <devnum> <channel>" );
SampleUtil_Print( " SetVolume <devnum> <volume>" );
SampleUtil_Print( " SetColor <devnum> <color>" );
SampleUtil_Print( " SetTint <devnum> <tint>" );
SampleUtil_Print( " SetContrast <devnum> <contrast>" );
SampleUtil_Print( " SetBrightness <devnum> <brightness>" );
SampleUtil_Print( " CtrlAction <devnum> <action>" );
SampleUtil_Print( " PictAction <devnum> <action>" );
SampleUtil_Print( " CtrlGetVar <devnum> <varname>" );
SampleUtil_Print( " PictGetVar <devnum> <action>" );
SampleUtil_Print( " Exit" );
}
void
TvCtrlPointPrintLongHelp( void )
{
SampleUtil_Print( "" );
SampleUtil_Print( "******************************" );
SampleUtil_Print( "* TV Control Point Help Info *" );
SampleUtil_Print( "******************************" );
SampleUtil_Print( "" );
SampleUtil_Print( "This sample control point application automatically searches" );
SampleUtil_Print( "for and subscribes to the services of television device emulator" );
SampleUtil_Print( "devices, described in the tvdevicedesc.xml description document." );
SampleUtil_Print( "It also registers itself as a tv device." );
SampleUtil_Print( "" );
SampleUtil_Print( "Commands:" );
SampleUtil_Print( " Help" );
SampleUtil_Print( " Print this help info." );
SampleUtil_Print( " ListDev" );
SampleUtil_Print( " Print the current list of TV Device Emulators that this" );
SampleUtil_Print( " control point is aware of. Each device is preceded by a" );
SampleUtil_Print( " device number which corresponds to the devnum argument of" );
SampleUtil_Print( " commands listed below." );
SampleUtil_Print( " Refresh" );
SampleUtil_Print( " Delete all of the devices from the device list and issue new" );
SampleUtil_Print( " search request to rebuild the list from scratch." );
SampleUtil_Print( " PrintDev <devnum>" );
SampleUtil_Print( " Print the state table for the device <devnum>." );
SampleUtil_Print( " e.g., 'PrintDev 1' prints the state table for the first" );
SampleUtil_Print( " device in the device list." );
SampleUtil_Print( " PowerOn <devnum>" );
SampleUtil_Print( " Sends the PowerOn action to the Control Service of" );
SampleUtil_Print( " device <devnum>." );
SampleUtil_Print( " PowerOff <devnum>" );
SampleUtil_Print( " Sends the PowerOff action to the Control Service of" );
SampleUtil_Print( " device <devnum>." );
SampleUtil_Print( " SetChannel <devnum> <channel>" );
SampleUtil_Print( " Sends the SetChannel action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the channel to be changed" );
SampleUtil_Print( " to <channel>." );
SampleUtil_Print( " SetVolume <devnum> <volume>" );
SampleUtil_Print( " Sends the SetVolume action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the volume to be changed" );
SampleUtil_Print( " to <volume>." );
SampleUtil_Print( " SetColor <devnum> <color>" );
SampleUtil_Print( " Sends the SetColor action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the color to be changed" );
SampleUtil_Print( " to <color>." );
SampleUtil_Print( " SetTint <devnum> <tint>" );
SampleUtil_Print( " Sends the SetTint action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the tint to be changed" );
SampleUtil_Print( " to <tint>." );
SampleUtil_Print( " SetContrast <devnum> <contrast>" );
SampleUtil_Print( " Sends the SetContrast action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the contrast to be changed" );
SampleUtil_Print( " to <contrast>." );
SampleUtil_Print( " SetBrightness <devnum> <brightness>" );
SampleUtil_Print( " Sends the SetBrightness action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the brightness to be changed" );
SampleUtil_Print( " to <brightness>." );
SampleUtil_Print( " CtrlAction <devnum> <action>" );
SampleUtil_Print( " Sends an action request specified by the string <action>" );
SampleUtil_Print( " to the Control Service of device <devnum>. This command" );
SampleUtil_Print( " only works for actions that have no arguments." );
SampleUtil_Print( " (e.g., \"CtrlAction 1 IncreaseChannel\")" );
SampleUtil_Print( " PictAction <devnum> <action>" );
SampleUtil_Print( " Sends an action request specified by the string <action>" );
SampleUtil_Print( " to the Picture Service of device <devnum>. This command" );
SampleUtil_Print( " only works for actions that have no arguments." );
SampleUtil_Print( " (e.g., \"PictAction 1 DecreaseContrast\")" );
SampleUtil_Print( " CtrlGetVar <devnum> <varname>" );
SampleUtil_Print( " Requests the value of a variable specified by the string <varname>" );
SampleUtil_Print( " from the Control Service of device <devnum>." );
SampleUtil_Print( " (e.g., \"CtrlGetVar 1 Volume\")" );
SampleUtil_Print( " PictGetVar <devnum> <action>" );
SampleUtil_Print( " Requests the value of a variable specified by the string <varname>" );
SampleUtil_Print( " from the Picture Service of device <devnum>." );
SampleUtil_Print( " (e.g., \"PictGetVar 1 Tint\")" );
SampleUtil_Print( " Exit" );
SampleUtil_Print( " Exits the control point application." );
}
/********************************************************************************
* TvCtrlPointPrintCommands
*
* Description:
* Print the list of valid command line commands to the user
*
* Parameters:
* None
*
********************************************************************************/
void
TvCtrlPointPrintCommands()
{
int i;
int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands );
SampleUtil_Print( "Valid Commands:" );
for( i = 0; i < numofcmds; i++ ) {
SampleUtil_Print( " %-14s %s", cmdloop_cmdlist[i].str,
cmdloop_cmdlist[i].args );
}
SampleUtil_Print( "" );
}
/********************************************************************************
* TvCtrlPointCommandLoop
*
* Description:
* Function that receives commands from the user at the command prompt
* during the lifetime of the control point, and calls the appropriate
* functions for those commands.
*
* Parameters:
* None
*
********************************************************************************/
void *
TvCtrlPointCommandLoop( void *args )
{
char cmdline[100];
while( 1 ) {
SampleUtil_Print( "\n>> " );
fgets( cmdline, 100, stdin );
TvCtrlPointProcessCommand( cmdline );
}
return NULL;
}
int
TvCtrlPointProcessCommand( char *cmdline )
{
char cmd[100];
char strarg[100];
int arg_val_err = -99999;
int arg1 = arg_val_err;
int arg2 = arg_val_err;
int cmdnum = -1;
int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands );
int cmdfound = 0;
int i,
rc;
int invalidargs = 0;
int validargs;
validargs = sscanf( cmdline, "%s %d %d", cmd, &arg1, &arg2 );
for( i = 0; i < numofcmds; i++ ) {
if( strcasecmp( cmd, cmdloop_cmdlist[i].str ) == 0 ) {
cmdnum = cmdloop_cmdlist[i].cmdnum;
cmdfound++;
if( validargs != cmdloop_cmdlist[i].numargs )
invalidargs++;
break;
}
}
if( !cmdfound ) {
SampleUtil_Print( "Command not found; try 'Help'" );
return TV_SUCCESS;
}
if( invalidargs ) {
SampleUtil_Print( "Invalid arguments; try 'Help'" );
return TV_SUCCESS;
}
switch ( cmdnum ) {
case PRTHELP:
TvCtrlPointPrintShortHelp();
break;
case PRTFULLHELP:
TvCtrlPointPrintLongHelp();
break;
case POWON:
TvCtrlPointSendPowerOn( arg1 );
break;
case POWOFF:
TvCtrlPointSendPowerOff( arg1 );
break;
case SETCHAN:
TvCtrlPointSendSetChannel( arg1, arg2 );
break;
case SETVOL:
TvCtrlPointSendSetVolume( arg1, arg2 );
break;
case SETCOL:
TvCtrlPointSendSetColor( arg1, arg2 );
break;
case SETTINT:
TvCtrlPointSendSetTint( arg1, arg2 );
break;
case SETCONT:
TvCtrlPointSendSetContrast( arg1, arg2 );
break;
case SETBRT:
TvCtrlPointSendSetBrightness( arg1, arg2 );
break;
case CTRLACTION:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointSendAction( TV_SERVICE_CONTROL, arg1, strarg,
NULL, NULL, 0 );
else
invalidargs++;
break;
case PICTACTION:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointSendAction( TV_SERVICE_PICTURE, arg1, strarg,
NULL, NULL, 0 );
else
invalidargs++;
break;
case CTRLGETVAR:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointGetVar( TV_SERVICE_CONTROL, arg1, strarg );
else
invalidargs++;
break;
case PICTGETVAR:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointGetVar( TV_SERVICE_PICTURE, arg1, strarg );
else
invalidargs++;
break;
case PRTDEV:
TvCtrlPointPrintDevice( arg1 );
break;
case LSTDEV:
TvCtrlPointPrintList();
break;
case REFRESH:
TvCtrlPointRefresh();
break;
case EXITCMD:
rc = TvCtrlPointStop();
exit( rc );
break;
default:
SampleUtil_Print( "Command not implemented; see 'Help'" );
break;
}
if( invalidargs )
SampleUtil_Print( "Invalid args in command; see 'Help'" );
return TV_SUCCESS;
}
int
device_main( int argc, char **argv )
{
unsigned int portTemp = 0;
char *ip_address = NULL,
*desc_doc_name = NULL,
*web_dir_path = NULL;
unsigned int port = 0;
int i = 0;
SampleUtil_Initialize( linux_print );
// Parse options
for( i = 1; i < argc; i++ ) {
if( strcmp( argv[i], "-ip" ) == 0 ) {
ip_address = argv[++i];
} else if( strcmp( argv[i], "-port" ) == 0 ) {
sscanf( argv[++i], "%u", &portTemp );
} else if( strcmp( argv[i], "-desc" ) == 0 ) {
desc_doc_name = argv[++i];
} else if( strcmp( argv[i], "-webdir" ) == 0 ) {
web_dir_path = argv[++i];
} else if( strcmp( argv[i], "-help" ) == 0 ) {
SampleUtil_Print( "Usage: %s -ip ipaddress -port port"
" -desc desc_doc_name -webdir web_dir_path"
" -help (this message)\n", argv[0] );
SampleUtil_Print( "\tipaddress: IP address of the device"
" (must match desc. doc)\n" );
SampleUtil_Print( "\t\te.g.: 192.168.0.4\n" );
SampleUtil_Print( "\tport: Port number to use for "
"receiving UPnP messages (must match desc. doc)\n" );
SampleUtil_Print( "\t\te.g.: 5431\n" );
SampleUtil_Print
( "\tdesc_doc_name: name of device description document\n" );
SampleUtil_Print( "\t\te.g.: tvcombodesc.xml\n" );
SampleUtil_Print
( "\tweb_dir_path: Filesystem path where web files "
"related to the device are stored\n" );
SampleUtil_Print( "\t\te.g.: /upnp/sample/web\n" );
return 1;
}
}
port = ( unsigned short )portTemp;
return TvDeviceStart( ip_address, port, desc_doc_name, web_dir_path, linux_print );
}
int main( int argc, char **argv )
{
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
device_main(argc, argv);
rc = TvCtrlPointStart( linux_print, NULL );
if( rc != TV_SUCCESS ) {
SampleUtil_Print( "Error starting UPnP TV Control Point" );
return rc;
}
/* start a command loop thread */
code = ithread_create( &cmdloop_thread, NULL, TvCtrlPointCommandLoop, NULL );
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/*
Catch Ctrl-C and properly shutdown
*/
sigemptyset( &sigs_to_catch );
sigaddset( &sigs_to_catch, SIGINT );
sigwait( &sigs_to_catch, &sig );
SampleUtil_Print( "Shutting down on signal %d...\n", sig );
#endif
TvDeviceStop();
rc = TvCtrlPointStop();
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,171 +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 UPNP_TV_CTRLPT_H
#define UPNP_TV_CTRLPT_H
#ifdef __cplusplus
extern "C" {
#endif
#include "sample_util.h"
#include "ithread.h"
#include "upnp.h"
#include "UpnpString.h"
#include "upnptools.h"
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
#define TV_SERVICE_SERVCOUNT 2
#define TV_SERVICE_CONTROL 0
#define TV_SERVICE_PICTURE 1
#define TV_CONTROL_VARCOUNT 3
#define TV_CONTROL_POWER 0
#define TV_CONTROL_CHANNEL 1
#define TV_CONTROL_VOLUME 2
#define TV_PICTURE_VARCOUNT 4
#define TV_PICTURE_COLOR 0
#define TV_PICTURE_TINT 1
#define TV_PICTURE_CONTRAST 2
#define TV_PICTURE_BRIGHTNESS 3
#define TV_MAX_VAL_LEN 5
#define TV_SUCCESS 0
#define TV_ERROR (-1)
#define TV_WARNING 1
/* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[];
extern char *TvServiceType[];
extern char *TvServiceName[];
extern char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS];
extern char TvVarCount[];
struct tv_service {
char ServiceId[NAME_SIZE];
char ServiceType[NAME_SIZE];
char *VariableStrVal[TV_MAXVARS];
char EventURL[NAME_SIZE];
char ControlURL[NAME_SIZE];
char SID[NAME_SIZE];
};
extern struct TvDeviceNode *GlobalDeviceList;
struct TvDevice {
char UDN[250];
char DescDocURL[250];
char FriendlyName[250];
char PresURL[250];
int AdvrTimeOut;
struct tv_service TvService[TV_SERVICE_SERVCOUNT];
};
struct TvDeviceNode {
struct TvDevice device;
struct TvDeviceNode *next;
};
extern ithread_mutex_t DeviceListMutex;
extern UpnpClient_Handle ctrlpt_handle;
void TvCtrlPointPrintHelp(void);
int TvCtrlPointDeleteNode(struct TvDeviceNode *);
int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll(void);
int TvCtrlPointRefresh(void);
int TvCtrlPointSendAction(int, int, char *, char **, char **, int);
int TvCtrlPointSendActionNumericArg(int devnum, int service, char *actionName, char *paramName, int paramValue);
int TvCtrlPointSendPowerOn(int devnum);
int TvCtrlPointSendPowerOff(int devnum);
int TvCtrlPointSendSetChannel(int, int);
int TvCtrlPointSendSetVolume(int, int);
int TvCtrlPointSendSetColor(int, int);
int TvCtrlPointSendSetTint(int, int);
int TvCtrlPointSendSetContrast(int, int);
int TvCtrlPointSendSetBrightness(int, int);
int TvCtrlPointGetVar(int, int, char*);
int TvCtrlPointGetPower(int devnum);
int TvCtrlPointGetChannel(int);
int TvCtrlPointGetVolume(int);
int TvCtrlPointGetColor(int);
int TvCtrlPointGetTint(int);
int TvCtrlPointGetContrast(int);
int TvCtrlPointGetBrightness(int);
int TvCtrlPointGetDevice(int, struct TvDeviceNode **);
int TvCtrlPointPrintList(void);
int TvCtrlPointPrintDevice(int);
void TvCtrlPointAddDevice(IXML_Document *, const char *, int);
void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString);
void TvStateUpdate(char*,int, IXML_Document * , char **);
void TvCtrlPointHandleEvent(const char *, int, IXML_Document *);
void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int);
int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *);
void TvCtrlPointVerifyTimeouts(int);
void TvCtrlPointPrintCommands(void);
void* TvCtrlPointCommandLoop(void *);
int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr);
int TvCtrlPointStop(void);
int TvCtrlPointProcessCommand(char *cmdline);
#ifdef __cplusplus
};
#endif
#endif //UPNP_TV_CTRLPT_H

View File

@@ -1,632 +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 UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H
#include <stdio.h>
#include <signal.h>
#ifdef __cplusplus
extern "C" {
#endif
#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
#define MAX_COLOR 10
#define MIN_COLOR 1
//Brightness constants
#define MAX_BRIGHTNESS 10
#define MIN_BRIGHTNESS 1
//Power constants
#define POWER_ON 1
#define POWER_OFF 0
//Tint constants
#define MAX_TINT 10
#define MIN_TINT 1
//Volume constants
#define MAX_VOLUME 10
#define MIN_VOLUME 1
//Contrast constants
#define MAX_CONTRAST 10
#define MIN_CONTRAST 1
//Channel constants
#define MAX_CHANNEL 100
#define MIN_CHANNEL 1
//Number of services.
#define TV_SERVICE_SERVCOUNT 2
//Index of control service
#define TV_SERVICE_CONTROL 0
//Index of picture service
#define TV_SERVICE_PICTURE 1
//Number of control variables
#define TV_CONTROL_VARCOUNT 3
//Index of power variable
#define TV_CONTROL_POWER 0
//Index of channel variable
#define TV_CONTROL_CHANNEL 1
//Index of volume variable
#define TV_CONTROL_VOLUME 2
//Number of picture variables
#define TV_PICTURE_VARCOUNT 4
//Index of color variable
#define TV_PICTURE_COLOR 0
//Index of tint variable
#define TV_PICTURE_TINT 1
//Index of contrast variable
#define TV_PICTURE_CONTRAST 2
//Index of brightness variable
#define TV_PICTURE_BRIGHTNESS 3
//Max value length
#define TV_MAX_VAL_LEN 5
//Max actions
#define TV_MAXACTIONS 12
/* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[];
extern char *TvServiceType[];
/******************************************************************************
* upnp_action
*
* Description:
* Prototype for all actions. For each action that a service
* implements, there is a corresponding function with this prototype.
* Pointers to these functions, along with action names, are stored
* in the service table. When an action request comes in the action
* name is matched, and the appropriate function is called.
* Each function returns UPNP_E_SUCCESS, on success, and a nonzero
* error code on failure.
*
* Parameters:
*
* IXML_Document * request - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, char **errorString);
/* Structure for storing Tv Service
identifiers and state table */
struct TvService {
char UDN[NAME_SIZE]; /* Universally Unique Device Name */
char ServiceId[NAME_SIZE];
char ServiceType[NAME_SIZE];
char *VariableName[TV_MAXVARS];
char *VariableStrVal[TV_MAXVARS];
char *ActionNames[TV_MAXACTIONS];
upnp_action actions[TV_MAXACTIONS];
unsigned int VariableCount;
};
//Array of service structures
extern struct TvService tv_service_table[];
//Device handle returned from sdk
extern UpnpDevice_Handle device_handle;
/* Mutex for protecting the global state table data
in a multi-threaded, asynchronous environment.
All functions should lock this mutex before reading
or writing the state table data. */
extern ithread_mutex_t TVDevMutex;
/******************************************************************************
* SetActionTable
*
* Description:
* Initializes the action table for the specified service.
* Note that
* knowledge of the service description is
* assumed. Action names are hardcoded.
* Parameters:
* int serviceType - one of TV_SERVICE_CONTROL or, TV_SERVICE_PICTURE
* struct TvService *out - service containing action table to set.
*
*****************************************************************************/
int SetActionTable(int serviceType, struct TvService *out);
/******************************************************************************
* TvDeviceStateTableInit
*
* Description:
* Initialize the device state table for
* this TvDevice, pulling identifier info
* from the description Document. Note that
* knowledge of the service description is
* assumed. State table variables and default
* values are currently hardcoded in this file
* rather than being read from service description
* documents.
*
* Parameters:
* DescDocURL -- The description document URL
*
*****************************************************************************/
int TvDeviceStateTableInit(char*);
/******************************************************************************
* TvDeviceHandleSubscriptionRequest
*
* Description:
* Called during a subscription request callback. If the
* subscription request is for this device and either its
* control service or picture service, then accept it.
*
* Parameters:
* sr_event -- The subscription request event structure
*
*****************************************************************************/
int TvDeviceHandleSubscriptionRequest(struct Upnp_Subscription_Request *);
/******************************************************************************
* TvDeviceHandleGetVarRequest
*
* Description:
* Called during a get variable request callback. If the
* request is for this device and either its control service
* or picture service, then respond with the variable value.
*
* Parameters:
* cgv_event -- The control get variable request event structure
*
*****************************************************************************/
int TvDeviceHandleGetVarRequest(struct Upnp_State_Var_Request *);
/******************************************************************************
* TvDeviceHandleActionRequest
*
* Description:
* Called during an action request callback. If the
* request is for this device and either its control service
* or picture service, then perform the action and respond.
*
* Parameters:
* ca_event -- The control action request event structure
*
*****************************************************************************/
int TvDeviceHandleActionRequest(struct Upnp_Action_Request *);
/******************************************************************************
* TvDeviceCallbackEventHandler
*
* Description:
* The callback handler registered with the SDK while registering
* root device. Dispatches the request to the appropriate procedure
* based on the value of EventType. The four requests handled by the
* device are:
* 1) Event Subscription requests.
* 2) Get Variable requests.
* 3) Action requests.
*
* Parameters:
*
* EventType -- The type of callback event
* Event -- Data structure containing event data
* Cookie -- Optional data specified during callback registration
*
*****************************************************************************/
int TvDeviceCallbackEventHandler(Upnp_EventType, void*, void*);
/******************************************************************************
* TvDeviceSetServiceTableVar
*
* Description:
* Update the TvDevice service state table, and notify all subscribed
* control points of the updated state. Note that since this function
* blocks on the mutex TVDevMutex, to avoid a hang this function should
* not be called within any other function that currently has this mutex
* locked.
*
* Parameters:
* service -- The service number (TV_SERVICE_CONTROL or TV_SERVICE_PICTURE)
* variable -- The variable number (TV_CONTROL_POWER, TV_CONTROL_CHANNEL,
* TV_CONTROL_VOLUME, TV_PICTURE_COLOR, TV_PICTURE_TINT,
* TV_PICTURE_CONTRAST, or TV_PICTURE_BRIGHTNESS)
* value -- The string representation of the new value
*
*****************************************************************************/
int TvDeviceSetServiceTableVar(unsigned int, unsigned int, char*);
//Control Service Actions
/******************************************************************************
* TvDevicePowerOn
*
* Description:
* Turn the power on.
*
* Parameters:
*
* IXML_Document * in - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDevicePowerOff
*
* Description:
* Turn the power off.
*
* Parameters:
*
* IXML_Document * in - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetChannel
*
* Description:
* Change the channel, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseChannel
*
* Description:
* Increase the channel.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseChannel
*
* Description:
* Decrease the channel.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetVolume
*
* Description:
* Change the volume, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseVolume
*
* Description:
* Increase the volume.
*
* Parameters:
*
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseVolume
*
* Description:
* Decrease the volume.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
//Picture Service Actions
/******************************************************************************
* TvDeviceSetColor
*
* Description:
* Change the color, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseColor
*
* Description:
* Increase the color.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseColor
*
* Description:
* Decrease the color.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetTint
*
* Description:
* Change the tint, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseTint
*
* Description:
* Increase tint.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseTint
*
* Description:
* Decrease tint.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/*****************************************************************************
* TvDeviceSetContrast
*
* Description:
* Change the contrast, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
****************************************************************************/
int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseContrast
*
* Description:
*
* Increase the contrast.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseContrast
*
* Description:
* Decrease the contrast.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetBrightness
*
* Description:
* Change the brightness, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
* brightness -- The brightness value to change to.
*
*****************************************************************************/
int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseBrightness
*
* Description:
* Increase brightness.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseBrightness
*
* Description:
* Decrease brightnesss.
*
* Parameters:
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name,
char *web_dir_path, print_string pfun);
int TvDeviceStop(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,441 +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.
*
******************************************************************************/
#include "sample_util.h"
#include "upnp_tv_ctrlpt.h"
#include <stdio.h>
#include <string.h>
/*
Tags for valid commands issued at the command prompt
*/
enum cmdloop_tvcmds {
PRTHELP = 0, PRTFULLHELP, POWON, POWOFF,
SETCHAN, SETVOL, SETCOL, SETTINT, SETCONT, SETBRT,
CTRLACTION, PICTACTION, CTRLGETVAR, PICTGETVAR,
PRTDEV, LSTDEV, REFRESH, EXITCMD
};
/*
Data structure for parsing commands from the command line
*/
struct cmdloop_commands {
char *str; // the string
int cmdnum; // the command
int numargs; // the number of arguments
char *args; // the args
} cmdloop_commands;
/*
Mappings between command text names, command tag,
and required command arguments for command line
commands
*/
static struct cmdloop_commands cmdloop_cmdlist[] = {
{"Help", PRTHELP, 1, ""},
{"HelpFull", PRTFULLHELP, 1, ""},
{"ListDev", LSTDEV, 1, ""},
{"Refresh", REFRESH, 1, ""},
{"PrintDev", PRTDEV, 2, "<devnum>"},
{"PowerOn", POWON, 2, "<devnum>"},
{"PowerOff", POWOFF, 2, "<devnum>"},
{"SetChannel", SETCHAN, 3, "<devnum> <channel (int)>"},
{"SetVolume", SETVOL, 3, "<devnum> <volume (int)>"},
{"SetColor", SETCOL, 3, "<devnum> <color (int)>"},
{"SetTint", SETTINT, 3, "<devnum> <tint (int)>"},
{"SetContrast", SETCONT, 3, "<devnum> <contrast (int)>"},
{"SetBrightness", SETBRT, 3, "<devnum> <brightness (int)>"},
{"CtrlAction", CTRLACTION, 2, "<devnum> <action (string)>"},
{"PictAction", PICTACTION, 2, "<devnum> <action (string)>"},
{"CtrlGetVar", CTRLGETVAR, 2, "<devnum> <varname (string)>"},
{"PictGetVar", PICTGETVAR, 2, "<devnum> <varname (string)>"},
{"Exit", EXITCMD, 1, ""}
};
void
linux_print( const char *string )
{
puts( string );
}
/********************************************************************************
* TvCtrlPointPrintHelp
*
* Description:
* Print help info for this application.
********************************************************************************/
void
TvCtrlPointPrintShortHelp( void )
{
SampleUtil_Print( "Commands:" );
SampleUtil_Print( " Help" );
SampleUtil_Print( " HelpFull" );
SampleUtil_Print( " ListDev" );
SampleUtil_Print( " Refresh" );
SampleUtil_Print( " PrintDev <devnum>" );
SampleUtil_Print( " PowerOn <devnum>" );
SampleUtil_Print( " PowerOff <devnum>" );
SampleUtil_Print( " SetChannel <devnum> <channel>" );
SampleUtil_Print( " SetVolume <devnum> <volume>" );
SampleUtil_Print( " SetColor <devnum> <color>" );
SampleUtil_Print( " SetTint <devnum> <tint>" );
SampleUtil_Print( " SetContrast <devnum> <contrast>" );
SampleUtil_Print( " SetBrightness <devnum> <brightness>" );
SampleUtil_Print( " CtrlAction <devnum> <action>" );
SampleUtil_Print( " PictAction <devnum> <action>" );
SampleUtil_Print( " CtrlGetVar <devnum> <varname>" );
SampleUtil_Print( " PictGetVar <devnum> <action>" );
SampleUtil_Print( " Exit" );
}
void
TvCtrlPointPrintLongHelp( void )
{
SampleUtil_Print( "" );
SampleUtil_Print( "******************************" );
SampleUtil_Print( "* TV Control Point Help Info *" );
SampleUtil_Print( "******************************" );
SampleUtil_Print( "" );
SampleUtil_Print( "This sample control point application automatically searches" );
SampleUtil_Print( "for and subscribes to the services of television device emulator" );
SampleUtil_Print( "devices, described in the tvdevicedesc.xml description document." );
SampleUtil_Print( "" );
SampleUtil_Print( "Commands:" );
SampleUtil_Print( " Help" );
SampleUtil_Print( " Print this help info." );
SampleUtil_Print( " ListDev" );
SampleUtil_Print( " Print the current list of TV Device Emulators that this" );
SampleUtil_Print( " control point is aware of. Each device is preceded by a" );
SampleUtil_Print( " device number which corresponds to the devnum argument of" );
SampleUtil_Print( " commands listed below." );
SampleUtil_Print( " Refresh" );
SampleUtil_Print( " Delete all of the devices from the device list and issue new" );
SampleUtil_Print( " search request to rebuild the list from scratch." );
SampleUtil_Print( " PrintDev <devnum>" );
SampleUtil_Print( " Print the state table for the device <devnum>." );
SampleUtil_Print( " e.g., 'PrintDev 1' prints the state table for the first" );
SampleUtil_Print( " device in the device list." );
SampleUtil_Print( " PowerOn <devnum>" );
SampleUtil_Print( " Sends the PowerOn action to the Control Service of" );
SampleUtil_Print( " device <devnum>." );
SampleUtil_Print( " PowerOff <devnum>" );
SampleUtil_Print( " Sends the PowerOff action to the Control Service of" );
SampleUtil_Print( " device <devnum>." );
SampleUtil_Print( " SetChannel <devnum> <channel>" );
SampleUtil_Print( " Sends the SetChannel action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the channel to be changed" );
SampleUtil_Print( " to <channel>." );
SampleUtil_Print( " SetVolume <devnum> <volume>" );
SampleUtil_Print( " Sends the SetVolume action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the volume to be changed" );
SampleUtil_Print( " to <volume>." );
SampleUtil_Print( " SetColor <devnum> <color>" );
SampleUtil_Print( " Sends the SetColor action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the color to be changed" );
SampleUtil_Print( " to <color>." );
SampleUtil_Print( " SetTint <devnum> <tint>" );
SampleUtil_Print( " Sends the SetTint action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the tint to be changed" );
SampleUtil_Print( " to <tint>." );
SampleUtil_Print( " SetContrast <devnum> <contrast>" );
SampleUtil_Print( " Sends the SetContrast action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the contrast to be changed" );
SampleUtil_Print( " to <contrast>." );
SampleUtil_Print( " SetBrightness <devnum> <brightness>" );
SampleUtil_Print( " Sends the SetBrightness action to the Control Service of" );
SampleUtil_Print( " device <devnum>, requesting the brightness to be changed" );
SampleUtil_Print( " to <brightness>." );
SampleUtil_Print( " CtrlAction <devnum> <action>" );
SampleUtil_Print( " Sends an action request specified by the string <action>" );
SampleUtil_Print( " to the Control Service of device <devnum>. This command" );
SampleUtil_Print( " only works for actions that have no arguments." );
SampleUtil_Print( " (e.g., \"CtrlAction 1 IncreaseChannel\")" );
SampleUtil_Print( " PictAction <devnum> <action>" );
SampleUtil_Print( " Sends an action request specified by the string <action>" );
SampleUtil_Print( " to the Picture Service of device <devnum>. This command" );
SampleUtil_Print( " only works for actions that have no arguments." );
SampleUtil_Print( " (e.g., \"PictAction 1 DecreaseContrast\")" );
SampleUtil_Print( " CtrlGetVar <devnum> <varname>" );
SampleUtil_Print( " Requests the value of a variable specified by the string <varname>" );
SampleUtil_Print( " from the Control Service of device <devnum>." );
SampleUtil_Print( " (e.g., \"CtrlGetVar 1 Volume\")" );
SampleUtil_Print( " PictGetVar <devnum> <action>" );
SampleUtil_Print( " Requests the value of a variable specified by the string <varname>" );
SampleUtil_Print( " from the Picture Service of device <devnum>." );
SampleUtil_Print( " (e.g., \"PictGetVar 1 Tint\")" );
SampleUtil_Print( " Exit" );
SampleUtil_Print( " Exits the control point application." );
}
/********************************************************************************
* TvCtrlPointPrintCommands
*
* Description:
* Print the list of valid command line commands to the user
*
* Parameters:
* None
*
********************************************************************************/
void
TvCtrlPointPrintCommands()
{
int i;
int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands );
SampleUtil_Print( "Valid Commands:" );
for( i = 0; i < numofcmds; i++ ) {
SampleUtil_Print( " %-14s %s", cmdloop_cmdlist[i].str,
cmdloop_cmdlist[i].args );
}
SampleUtil_Print( "" );
}
/********************************************************************************
* TvCtrlPointCommandLoop
*
* Description:
* Function that receives commands from the user at the command prompt
* during the lifetime of the control point, and calls the appropriate
* functions for those commands.
*
* Parameters:
* None
*
********************************************************************************/
void *
TvCtrlPointCommandLoop( void *args )
{
char cmdline[100];
while( 1 ) {
SampleUtil_Print( "\n>> " );
fgets( cmdline, 100, stdin );
TvCtrlPointProcessCommand( cmdline );
}
return NULL;
}
int
TvCtrlPointProcessCommand( char *cmdline )
{
char cmd[100];
char strarg[100];
int arg_val_err = -99999;
int arg1 = arg_val_err;
int arg2 = arg_val_err;
int cmdnum = -1;
int numofcmds = sizeof( cmdloop_cmdlist ) / sizeof( cmdloop_commands );
int cmdfound = 0;
int i,
rc;
int invalidargs = 0;
int validargs;
validargs = sscanf( cmdline, "%s %d %d", cmd, &arg1, &arg2 );
for( i = 0; i < numofcmds; i++ ) {
if( strcasecmp( cmd, cmdloop_cmdlist[i].str ) == 0 ) {
cmdnum = cmdloop_cmdlist[i].cmdnum;
cmdfound++;
if( validargs != cmdloop_cmdlist[i].numargs )
invalidargs++;
break;
}
}
if( !cmdfound ) {
SampleUtil_Print( "Command not found; try 'Help'" );
return TV_SUCCESS;
}
if( invalidargs ) {
SampleUtil_Print( "Invalid arguments; try 'Help'" );
return TV_SUCCESS;
}
switch ( cmdnum ) {
case PRTHELP:
TvCtrlPointPrintShortHelp();
break;
case PRTFULLHELP:
TvCtrlPointPrintLongHelp();
break;
case POWON:
TvCtrlPointSendPowerOn( arg1 );
break;
case POWOFF:
TvCtrlPointSendPowerOff( arg1 );
break;
case SETCHAN:
TvCtrlPointSendSetChannel( arg1, arg2 );
break;
case SETVOL:
TvCtrlPointSendSetVolume( arg1, arg2 );
break;
case SETCOL:
TvCtrlPointSendSetColor( arg1, arg2 );
break;
case SETTINT:
TvCtrlPointSendSetTint( arg1, arg2 );
break;
case SETCONT:
TvCtrlPointSendSetContrast( arg1, arg2 );
break;
case SETBRT:
TvCtrlPointSendSetBrightness( arg1, arg2 );
break;
case CTRLACTION:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointSendAction( TV_SERVICE_CONTROL, arg1, strarg,
NULL, NULL, 0 );
else
invalidargs++;
break;
case PICTACTION:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointSendAction( TV_SERVICE_PICTURE, arg1, strarg,
NULL, NULL, 0 );
else
invalidargs++;
break;
case CTRLGETVAR:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointGetVar( TV_SERVICE_CONTROL, arg1, strarg );
else
invalidargs++;
break;
case PICTGETVAR:
/*
re-parse commandline since second arg is string
*/
validargs = sscanf( cmdline, "%s %d %s", cmd, &arg1, strarg );
if( 3 == validargs )
TvCtrlPointGetVar( TV_SERVICE_PICTURE, arg1, strarg );
else
invalidargs++;
break;
case PRTDEV:
TvCtrlPointPrintDevice( arg1 );
break;
case LSTDEV:
TvCtrlPointPrintList();
break;
case REFRESH:
TvCtrlPointRefresh();
break;
case EXITCMD:
rc = TvCtrlPointStop();
exit( rc );
break;
default:
SampleUtil_Print( "Command not implemented; see 'Help'" );
break;
}
if( invalidargs )
SampleUtil_Print( "Invalid args in command; see 'Help'" );
return TV_SUCCESS;
}
int main( int argc, char **argv )
{
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
rc = TvCtrlPointStart( linux_print, NULL );
if( rc != TV_SUCCESS ) {
SampleUtil_Print( "Error starting UPnP TV Control Point" );
return rc;
}
/* start a command loop thread */
code = ithread_create( &cmdloop_thread, NULL, TvCtrlPointCommandLoop, NULL );
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/*
Catch Ctrl-C and properly shutdown
*/
sigemptyset( &sigs_to_catch );
sigaddset( &sigs_to_catch, SIGINT );
sigwait( &sigs_to_catch, &sig );
SampleUtil_Print( "Shutting down on signal %d...\n", sig );
#endif
rc = TvCtrlPointStop();
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,198 +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.
*
******************************************************************************/
#include "sample_util.h"
#include "upnp_tv_device.h"
#include <stdio.h>
/******************************************************************************
* linux_print
*
* Description:
* Prints a string to standard out.
*
* Parameters:
* None
*
*****************************************************************************/
void
linux_print( const char *string )
{
printf( "%s", string );
}
/******************************************************************************
* TvDeviceCommandLoop
*
* Description:
* Function that receives commands from the user at the command prompt
* during the lifetime of the device, and calls the appropriate
* functions for those commands. Only one command, exit, is currently
* defined.
*
* Parameters:
* None
*
*****************************************************************************/
void *
TvDeviceCommandLoop( void *args )
{
int stoploop = 0;
char cmdline[100];
char cmd[100];
while( !stoploop ) {
sprintf( cmdline, " " );
sprintf( cmd, " " );
SampleUtil_Print( "\n>> " );
// Get a command line
fgets( cmdline, 100, stdin );
sscanf( cmdline, "%s", cmd );
if( strcasecmp( cmd, "exit" ) == 0 ) {
SampleUtil_Print( "Shutting down...\n" );
TvDeviceStop();
exit( 0 );
} else {
SampleUtil_Print( "\n Unknown command: %s\n\n", cmd );
SampleUtil_Print( " Valid Commands:\n" );
SampleUtil_Print( " Exit\n\n" );
}
}
return NULL;
}
/******************************************************************************
* main
*
* Description:
* Main entry point for tv device application.
* Initializes and registers with the sdk.
* Initializes the state stables of the service.
* Starts the command loop.
*
* Parameters:
* int argc - count of arguments
* char ** argv -arguments. The application
* accepts the following optional arguments:
*
* -ip ipaddress
* -port port
* -desc desc_doc_name
* -webdir web_dir_path"
* -help
*
*
*****************************************************************************/
int main( IN int argc, IN char **argv )
{
unsigned int portTemp = 0;
char *ip_address = NULL,
*desc_doc_name = NULL,
*web_dir_path = NULL;
int rc;
ithread_t cmdloop_thread;
#ifdef WIN32
#else
int sig;
sigset_t sigs_to_catch;
#endif
int code;
unsigned int port = 0;
int i = 0;
SampleUtil_Initialize( linux_print );
// Parse options
for( i = 1; i < argc; i++ ) {
if( strcmp( argv[i], "-ip" ) == 0 ) {
ip_address = argv[++i];
} else if( strcmp( argv[i], "-port" ) == 0 ) {
sscanf( argv[++i], "%u", &portTemp );
} else if( strcmp( argv[i], "-desc" ) == 0 ) {
desc_doc_name = argv[++i];
} else if( strcmp( argv[i], "-webdir" ) == 0 ) {
web_dir_path = argv[++i];
} else if( strcmp( argv[i], "-help" ) == 0 ) {
SampleUtil_Print( "Usage: %s -ip ipaddress -port port"
" -desc desc_doc_name -webdir web_dir_path"
" -help (this message)\n", argv[0] );
SampleUtil_Print( "\tipaddress: IP address of the device"
" (must match desc. doc)\n" );
SampleUtil_Print( "\t\te.g.: 192.168.0.4\n" );
SampleUtil_Print( "\tport: Port number to use for "
"receiving UPnP messages (must match desc. doc)\n" );
SampleUtil_Print( "\t\te.g.: 5431\n" );
SampleUtil_Print
( "\tdesc_doc_name: name of device description document\n" );
SampleUtil_Print( "\t\te.g.: tvdevicedesc.xml\n" );
SampleUtil_Print
( "\tweb_dir_path: Filesystem path where web files "
"related to the device are stored\n" );
SampleUtil_Print( "\t\te.g.: /upnp/sample/tvdevice/web\n" );
return 1;
}
}
port = ( unsigned short )portTemp;
TvDeviceStart( ip_address, port, desc_doc_name, web_dir_path, linux_print );
/* start a command loop thread */
code = ithread_create( &cmdloop_thread, NULL, TvDeviceCommandLoop, NULL );
#ifdef WIN32
ithread_join(cmdloop_thread, NULL);
#else
/*
Catch Ctrl-C and properly shutdown
*/
sigemptyset( &sigs_to_catch );
sigaddset( &sigs_to_catch, SIGINT );
sigwait( &sigs_to_catch, &sig );
SampleUtil_Print( "Shutting down on signal %d...\n", sig );
#endif
rc = TvDeviceStop();
return rc;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,632 +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 UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H
#include <stdio.h>
#include <signal.h>
#ifdef __cplusplus
extern "C" {
#endif
#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
#define MAX_COLOR 10
#define MIN_COLOR 1
//Brightness constants
#define MAX_BRIGHTNESS 10
#define MIN_BRIGHTNESS 1
//Power constants
#define POWER_ON 1
#define POWER_OFF 0
//Tint constants
#define MAX_TINT 10
#define MIN_TINT 1
//Volume constants
#define MAX_VOLUME 10
#define MIN_VOLUME 1
//Contrast constants
#define MAX_CONTRAST 10
#define MIN_CONTRAST 1
//Channel constants
#define MAX_CHANNEL 100
#define MIN_CHANNEL 1
//Number of services.
#define TV_SERVICE_SERVCOUNT 2
//Index of control service
#define TV_SERVICE_CONTROL 0
//Index of picture service
#define TV_SERVICE_PICTURE 1
//Number of control variables
#define TV_CONTROL_VARCOUNT 3
//Index of power variable
#define TV_CONTROL_POWER 0
//Index of channel variable
#define TV_CONTROL_CHANNEL 1
//Index of volume variable
#define TV_CONTROL_VOLUME 2
//Number of picture variables
#define TV_PICTURE_VARCOUNT 4
//Index of color variable
#define TV_PICTURE_COLOR 0
//Index of tint variable
#define TV_PICTURE_TINT 1
//Index of contrast variable
#define TV_PICTURE_CONTRAST 2
//Index of brightness variable
#define TV_PICTURE_BRIGHTNESS 3
//Max value length
#define TV_MAX_VAL_LEN 5
//Max actions
#define TV_MAXACTIONS 12
/* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[];
extern char *TvServiceType[];
/******************************************************************************
* upnp_action
*
* Description:
* Prototype for all actions. For each action that a service
* implements, there is a corresponding function with this prototype.
* Pointers to these functions, along with action names, are stored
* in the service table. When an action request comes in the action
* name is matched, and the appropriate function is called.
* Each function returns UPNP_E_SUCCESS, on success, and a nonzero
* error code on failure.
*
* Parameters:
*
* IXML_Document * request - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
typedef int (*upnp_action) (IXML_Document *request, IXML_Document **out, char **errorString);
/* Structure for storing Tv Service
identifiers and state table */
struct TvService {
char UDN[NAME_SIZE]; /* Universally Unique Device Name */
char ServiceId[NAME_SIZE];
char ServiceType[NAME_SIZE];
char *VariableName[TV_MAXVARS];
char *VariableStrVal[TV_MAXVARS];
char *ActionNames[TV_MAXACTIONS];
upnp_action actions[TV_MAXACTIONS];
unsigned int VariableCount;
};
//Array of service structures
extern struct TvService tv_service_table[];
//Device handle returned from sdk
extern UpnpDevice_Handle device_handle;
/* Mutex for protecting the global state table data
in a multi-threaded, asynchronous environment.
All functions should lock this mutex before reading
or writing the state table data. */
extern ithread_mutex_t TVDevMutex;
/******************************************************************************
* SetActionTable
*
* Description:
* Initializes the action table for the specified service.
* Note that
* knowledge of the service description is
* assumed. Action names are hardcoded.
* Parameters:
* int serviceType - one of TV_SERVICE_CONTROL or, TV_SERVICE_PICTURE
* struct TvService *out - service containing action table to set.
*
*****************************************************************************/
int SetActionTable(int serviceType, struct TvService *out);
/******************************************************************************
* TvDeviceStateTableInit
*
* Description:
* Initialize the device state table for
* this TvDevice, pulling identifier info
* from the description Document. Note that
* knowledge of the service description is
* assumed. State table variables and default
* values are currently hardcoded in this file
* rather than being read from service description
* documents.
*
* Parameters:
* DescDocURL -- The description document URL
*
*****************************************************************************/
int TvDeviceStateTableInit(char*);
/******************************************************************************
* TvDeviceHandleSubscriptionRequest
*
* Description:
* Called during a subscription request callback. If the
* subscription request is for this device and either its
* control service or picture service, then accept it.
*
* Parameters:
* sr_event -- The subscription request event structure
*
*****************************************************************************/
int TvDeviceHandleSubscriptionRequest(struct Upnp_Subscription_Request *);
/******************************************************************************
* TvDeviceHandleGetVarRequest
*
* Description:
* Called during a get variable request callback. If the
* request is for this device and either its control service
* or picture service, then respond with the variable value.
*
* Parameters:
* cgv_event -- The control get variable request event structure
*
*****************************************************************************/
int TvDeviceHandleGetVarRequest(struct Upnp_State_Var_Request *);
/******************************************************************************
* TvDeviceHandleActionRequest
*
* Description:
* Called during an action request callback. If the
* request is for this device and either its control service
* or picture service, then perform the action and respond.
*
* Parameters:
* ca_event -- The control action request event structure
*
*****************************************************************************/
int TvDeviceHandleActionRequest(struct Upnp_Action_Request *);
/******************************************************************************
* TvDeviceCallbackEventHandler
*
* Description:
* The callback handler registered with the SDK while registering
* root device. Dispatches the request to the appropriate procedure
* based on the value of EventType. The four requests handled by the
* device are:
* 1) Event Subscription requests.
* 2) Get Variable requests.
* 3) Action requests.
*
* Parameters:
*
* EventType -- The type of callback event
* Event -- Data structure containing event data
* Cookie -- Optional data specified during callback registration
*
*****************************************************************************/
int TvDeviceCallbackEventHandler(Upnp_EventType, void*, void*);
/******************************************************************************
* TvDeviceSetServiceTableVar
*
* Description:
* Update the TvDevice service state table, and notify all subscribed
* control points of the updated state. Note that since this function
* blocks on the mutex TVDevMutex, to avoid a hang this function should
* not be called within any other function that currently has this mutex
* locked.
*
* Parameters:
* service -- The service number (TV_SERVICE_CONTROL or TV_SERVICE_PICTURE)
* variable -- The variable number (TV_CONTROL_POWER, TV_CONTROL_CHANNEL,
* TV_CONTROL_VOLUME, TV_PICTURE_COLOR, TV_PICTURE_TINT,
* TV_PICTURE_CONTRAST, or TV_PICTURE_BRIGHTNESS)
* value -- The string representation of the new value
*
*****************************************************************************/
int TvDeviceSetServiceTableVar(unsigned int, unsigned int, char*);
//Control Service Actions
/******************************************************************************
* TvDevicePowerOn
*
* Description:
* Turn the power on.
*
* Parameters:
*
* IXML_Document * in - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDevicePowerOn(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDevicePowerOff
*
* Description:
* Turn the power off.
*
* Parameters:
*
* IXML_Document * in - document of action request
* IXML_Document **out - action result
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDevicePowerOff(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetChannel
*
* Description:
* Change the channel, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseChannel
*
* Description:
* Increase the channel.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseChannel
*
* Description:
* Decrease the channel.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseChannel(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetVolume
*
* Description:
* Change the volume, update the TvDevice control service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseVolume
*
* Description:
* Increase the volume.
*
* Parameters:
*
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceIncreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseVolume
*
* Description:
* Decrease the volume.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseVolume(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
//Picture Service Actions
/******************************************************************************
* TvDeviceSetColor
*
* Description:
* Change the color, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetColor(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseColor
*
* Description:
* Increase the color.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceIncreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseColor
*
* Description:
* Decrease the color.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*****************************************************************************/
int TvDeviceDecreaseColor(IN IXML_Document * in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetTint
*
* Description:
* Change the tint, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceSetTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseTint
*
* Description:
* Increase tint.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseTint
*
* Description:
* Decrease tint.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseTint(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/*****************************************************************************
* TvDeviceSetContrast
*
* Description:
* Change the contrast, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
****************************************************************************/
int TvDeviceSetContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseContrast
*
* Description:
*
* Increase the contrast.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseContrast
*
* Description:
* Decrease the contrast.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseContrast(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceSetBrightness
*
* Description:
* Change the brightness, update the TvDevice picture service
* state table, and notify all subscribed control points of the
* updated state.
*
* Parameters:
* brightness -- The brightness value to change to.
*
*****************************************************************************/
int TvDeviceSetBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceIncreaseBrightness
*
* Description:
* Increase brightness.
*
* Parameters:
*
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceIncreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
/******************************************************************************
* TvDeviceDecreaseBrightness
*
* Description:
* Decrease brightnesss.
*
* Parameters:
* IXML_Document * in - action request document
* IXML_Document **out - action result document
* char **errorString - errorString (in case action was unsuccessful)
*
*****************************************************************************/
int TvDeviceDecreaseBrightness(IN IXML_Document *in, OUT IXML_Document **out, OUT char **errorString);
int TvDeviceStart(char * ip_address, unsigned short port,char * desc_doc_name,
char *web_dir_path, print_string pfun);
int TvDeviceStop(void);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -37,7 +37,15 @@
/* strndup() is a GNU extension. Other systems must fix it with elif's. */
#ifdef __GNUC__
extern char *strndup(__const char *__string, size_t __n);
extern char *strndup(__const char *__string, size_t __n);
#elif defined(WIN32)
static char *strndup(const char *__string, size_t __n)
{
size_t strsize = strnlen(__string,__n);
char *newstr = (char *) malloc(strsize + 1);
strncpy(newstr,__string,__n);
return(newstr);
}
#endif
@@ -49,7 +57,7 @@ extern char *strndup(__const char *__string, size_t __n);
struct SUpnpString
{
/*! \brief Length of the string. */
int m_length;
size_t m_length;
/*! \brief Pointer to a dynamically allocated area that holds the NULL
* terminated string. */
char *m_string;
@@ -58,7 +66,7 @@ struct SUpnpString
UpnpString *UpnpString_new()
{
// All bytes are zero, and so is the length of the string.
/* All bytes are zero, and so is the length of the string. */
struct SUpnpString *p = calloc(1, sizeof (struct SUpnpString));
if (p == NULL) {
goto error_handler1;
@@ -67,7 +75,7 @@ UpnpString *UpnpString_new()
p->m_length = 0;
#endif
// This byte is zero, calloc does initialize it.
/* This byte is zero, calloc does initialize it. */
p->m_string = calloc(1, 1);
if (p->m_string == NULL) {
goto error_handler2;
@@ -75,7 +83,7 @@ UpnpString *UpnpString_new()
return (UpnpString *)p;
//free(p->m_string);
/*free(p->m_string); */
error_handler2:
free(p);
error_handler1:
@@ -112,7 +120,7 @@ UpnpString *UpnpString_dup(const UpnpString *p)
return (UpnpString *)q;
//free(q->m_string);
/*free(q->m_string); */
error_handler2:
free(q);
error_handler1:

View File

@@ -122,6 +122,7 @@ ithread_mutex_t GlobalClientSubscribeMutex;
/*! rwlock to synchronize handles (root device or control point handle). */
ithread_rwlock_t GlobalHndRWLock;
/*! Mutex to synchronize the uuid creation process. */
ithread_mutex_t gUUIDMutex;
@@ -156,7 +157,7 @@ char gIF_IPV6[65]/* INET6_ADDRSTRLEN*/ = { '\0' };
char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN] = { '\0' };
/*! Contains interface index. (extern'ed in upnp.h) */
int gIF_INDEX = -1;
unsigned gIF_INDEX = (unsigned)-1;
/*! local IPv4 port for the mini-server */
unsigned short LOCAL_PORT_V4;
@@ -469,7 +470,7 @@ int UpnpInit(const char *HostIP, unsigned short DestPort)
}
}
/* Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized. */
/* Set the UpnpSdkInit flag to 1 to indicate we're successfully initialized. */
UpnpSdkInit = 1;
/* Finish initializing the SDK. */
@@ -521,7 +522,7 @@ int UpnpInit2(const char *IfName, unsigned short DestPort)
goto exit_function;
}
/* Set the UpnpSdkInit flag to 1 to indicate we're sucessfully initialized. */
/* Set the UpnpSdkInit flag to 1 to indicate we're successfully initialized. */
UpnpSdkInit = 1;
/* Finish initializing the SDK. */
@@ -867,8 +868,6 @@ static int GetDescDocumentAndURL(
/* [in] . */
char *description,
/* [in] . */
unsigned int bufferLen,
/* [in] . */
int config_baseURL,
/* [in] . */
int AddressFamily,
@@ -882,7 +881,7 @@ static int GetDescDocumentAndURL(
int UpnpRegisterRootDevice2(
Upnp_DescType descriptionType,
const char *description_const,
size_t bufferLen, // ignored unless descType == UPNPREG_BUF_DESC
size_t bufferLen, /* ignored */
int config_baseURL,
Upnp_FunPtr Fun,
const void *Cookie,
@@ -926,11 +925,11 @@ int UpnpRegisterRootDevice2(
}
HandleTable[*Hnd] = HInfo;
// prevent accidental removal of a non-existent alias
/* prevent accidental removal of a non-existent alias */
HInfo->aliasInstalled = 0;
retVal = GetDescDocumentAndURL(
descriptionType, description, bufferLen,
descriptionType, description,
config_baseURL, AF_INET,
&HInfo->DescDocument, HInfo->DescURL);
if (retVal != UPNP_E_SUCCESS) {
@@ -1008,6 +1007,7 @@ exit_function:
HandleUnlock();
return retVal;
bufferLen = bufferLen;
}
#endif /* INCLUDE_DEVICE_APIS */
@@ -1190,7 +1190,7 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
HandleUnlock();
return UPNP_E_INVALID_HANDLE;
}
//info = (struct Handle_Info *) HandleTable[Hnd];
/*info = (struct Handle_Info *) HandleTable[Hnd]; */
ixmlNodeList_free( HInfo->DeviceList );
ixmlNodeList_free( HInfo->ServiceList );
ixmlDocument_free( HInfo->DescDocument );
@@ -1203,7 +1203,7 @@ int UpnpUnRegisterRootDevice(UpnpDevice_Handle Hnd)
if( HInfo->aliasInstalled ) {
web_server_set_alias( NULL, NULL, 0, 0 );
}
#endif // INTERNAL_WEB_SERVER
#endif /* INTERNAL_WEB_SERVER */
if( HInfo->DeviceAf == AF_INET ) {
UpnpSdkDeviceRegisteredV4 = 0;
@@ -1399,7 +1399,6 @@ static void get_server_addr6(
static int GetDescDocumentAndURL(
Upnp_DescType descriptionType,
char *description,
unsigned int bufferLen,
int config_baseURL,
int AddressFamily,
IXML_Document **xmlDoc,
@@ -1410,38 +1409,33 @@ static int GetDescDocumentAndURL(
char aliasStr[LINE_SIZE];
char *temp_str = NULL;
FILE *fp = NULL;
off_t fileLen;
size_t fileLen;
size_t num_read;
time_t last_modified;
struct stat file_info;
struct sockaddr_storage serverAddr;
int rc = UPNP_E_SUCCESS;
if (description == NULL) {
if (description == NULL)
return UPNP_E_INVALID_PARAM;
}
/* non-URL description must have configuration specified */
if (descriptionType != UPNPREG_URL_DESC && !config_baseURL) {
if (descriptionType != UPNPREG_URL_DESC && !config_baseURL)
return UPNP_E_INVALID_PARAM;
}
/* Get XML doc and last modified time */
if (descriptionType == UPNPREG_URL_DESC) {
retVal = UpnpDownloadXmlDoc(description, xmlDoc);
if (retVal != UPNP_E_SUCCESS) {
if (retVal != UPNP_E_SUCCESS)
return retVal;
}
last_modified = time(NULL);
} else if (descriptionType == UPNPREG_FILENAME_DESC) {
retVal = stat( description, &file_info );
if (retVal == -1) {
retVal = stat(description, &file_info);
if (retVal == -1)
return UPNP_E_FILE_NOT_FOUND;
}
fileLen = file_info.st_size;
fileLen = (size_t)file_info.st_size;
last_modified = file_info.st_mtime;
fp = fopen(description, "rb");
if (fp == NULL) {
if (fp == NULL)
return UPNP_E_FILE_NOT_FOUND;
}
membuf = (char *)malloc(fileLen + 1);
if (membuf == NULL) {
fclose(fp);
@@ -1465,16 +1459,15 @@ static int GetDescDocumentAndURL(
}
if (rc != IXML_SUCCESS && descriptionType != UPNPREG_URL_DESC) {
if (rc == IXML_INSUFFICIENT_MEMORY) {
if (rc == IXML_INSUFFICIENT_MEMORY)
return UPNP_E_OUTOF_MEMORY;
} else {
else
return UPNP_E_INVALID_DESC;
}
}
/* Determine alias */
if (config_baseURL) {
if (descriptionType == UPNPREG_BUF_DESC) {
strcpy( aliasStr, "description.xml" );
strcpy(aliasStr, "description.xml");
} else {
/* URL or filename */
retVal = GetNameForAlias(description, &temp_str);
@@ -1489,14 +1482,15 @@ static int GetDescDocumentAndURL(
}
strcpy(aliasStr, temp_str);
}
if(AddressFamily == AF_INET) {
if (AddressFamily == AF_INET) {
get_server_addr((struct sockaddr *)&serverAddr);
} else {
get_server_addr6((struct sockaddr *)&serverAddr);
}
/* config */
retVal = configure_urlbase(*xmlDoc, (struct sockaddr *)&serverAddr,
retVal =
configure_urlbase(*xmlDoc, (struct sockaddr *)&serverAddr,
aliasStr, last_modified, descURL);
if (retVal != UPNP_E_SUCCESS) {
ixmlDocument_free(*xmlDoc);
@@ -1521,7 +1515,6 @@ static int GetDescDocumentAndURL(
static int GetDescDocumentAndURL(
Upnp_DescType descriptionType,
char *description,
unsigned int bufferLen,
int config_baseURL,
int AddressFamily,
IXML_Document **xmlDoc,
@@ -2808,7 +2801,7 @@ int UpnpOpenHttpPost(
int UpnpWriteHttpPost(
void *handle,
char *buf,
unsigned int *size,
size_t *size,
int timeout)
{
return http_WriteHttpPost(handle, buf, size, timeout);
@@ -2880,13 +2873,13 @@ int UpnpCloseHttpGet(void *Handle)
}
int UpnpReadHttpGet(void *Handle, char *buf, unsigned int *size, int timeout)
int UpnpReadHttpGet(void *Handle, char *buf, size_t *size, int timeout)
{
return http_ReadHttpGet(Handle, buf, size, timeout);
}
int UpnpHttpGetProgress(void *Handle, unsigned int *length, unsigned int *total)
int UpnpHttpGetProgress(void *Handle, size_t *length, size_t *total)
{
return http_HttpGetProgress(Handle, length, total);
}
@@ -2895,18 +2888,15 @@ int UpnpHttpGetProgress(void *Handle, unsigned int *length, unsigned int *total)
int UpnpDownloadUrlItem(const char *url, char **outBuf, char *contentType)
{
int ret_code;
int dummy;
size_t dummy;
if( url == NULL || outBuf == NULL || contentType == NULL ) {
if (url == NULL || outBuf == NULL || contentType == NULL)
return UPNP_E_INVALID_PARAM;
}
ret_code = http_Download( url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy,
contentType );
if( ret_code > 0 ) {
ret_code = http_Download(url, HTTP_DEFAULT_TIMEOUT, outBuf, &dummy,
contentType);
if (ret_code > 0)
/* error reply was received */
ret_code = UPNP_E_INVALID_URL;
}
return ret_code;
}
@@ -2976,13 +2966,13 @@ int UpnpDownloadXmlDoc(const char *url, IXML_Document **xmlDoc)
int UpnpGetIfInfo(const char *IfName)
{
#ifdef WIN32
// ----------------------------------------------------
// WIN32 implementation will use the IpHlpAPI library.
// ----------------------------------------------------
/* ---------------------------------------------------- */
/* WIN32 implementation will use the IpHlpAPI library. */
/* ---------------------------------------------------- */
PIP_ADAPTER_ADDRESSES adapts = NULL;
PIP_ADAPTER_ADDRESSES adapts_item;
PIP_ADAPTER_UNICAST_ADDRESS uni_addr;
SOCKADDR* ip_addr;
SOCKADDR *ip_addr;
struct in_addr v4_addr;
struct in6_addr v6_addr;
ULONG adapts_sz = 0;
@@ -2990,105 +2980,105 @@ int UpnpGetIfInfo(const char *IfName)
int ifname_found = 0;
int valid_addr_found = 0;
// Get Adapters addresses required size.
/* Get Adapters addresses required size. */
ret = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL, adapts, &adapts_sz );
if( ret != ERROR_BUFFER_OVERFLOW ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n" );
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_DNS_SERVER, NULL, adapts,
&adapts_sz);
if (ret != ERROR_BUFFER_OVERFLOW) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n");
return UPNP_E_INIT;
}
// Allocate enough memory.
adapts = (PIP_ADAPTER_ADDRESSES)malloc( adapts_sz );
if( adapts == NULL ) {
/* Allocate enough memory. */
adapts = (PIP_ADAPTER_ADDRESSES) malloc(adapts_sz);
if (adapts == NULL) {
return UPNP_E_OUTOF_MEMORY;
}
// Do the call that will actually return the info.
ret = GetAdaptersAddresses( AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL, adapts, &adapts_sz );
if( ret != ERROR_SUCCESS ) {
free( adapts );
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n" );
/* Do the call that will actually return the info. */
ret = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_DNS_SERVER, NULL, adapts,
&adapts_sz);
if (ret != ERROR_SUCCESS) {
free(adapts);
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n");
return UPNP_E_INIT;
}
// Copy interface name, if it was provided.
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
adapts_item = adapts;
while( adapts_item != NULL ) {
if( adapts_item->Flags & IP_ADAPTER_NO_MULTICAST ) {
while (adapts_item != NULL) {
if (adapts_item->Flags & IP_ADAPTER_NO_MULTICAST) {
continue;
}
if( ifname_found == 0 ) {
// We have found a valid interface name. Keep it.
strncpy( gIF_NAME, adapts_item->FriendlyName, sizeof(gIF_NAME) );
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, adapts_item->FriendlyName,
sizeof(gIF_NAME));
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, adapts_item->FriendlyName, sizeof(gIF_NAME) ) != 0 ) {
// This is not the interface we're looking for.
if (strncmp
(gIF_NAME, adapts_item->FriendlyName,
sizeof(gIF_NAME)) != 0) {
/* This is not the interface we're looking for. */
continue;
}
}
// Loop thru this adapter's unicast IP addresses.
/* Loop thru this adapter's unicast IP addresses. */
uni_addr = adapts_item->FirstUnicastAddress;
while( uni_addr ) {
while (uni_addr) {
ip_addr = uni_addr->Address.lpSockaddr;
switch( ip_addr->sa_family ) {
switch (ip_addr->sa_family) {
case AF_INET:
memcpy( &v4_addr, &((struct sockaddr_in *)ip_addr)->sin_addr, sizeof(v4_addr) );
memcpy(&v4_addr,
&((struct sockaddr_in *)ip_addr)->
sin_addr, sizeof(v4_addr));
valid_addr_found = 1;
break;
case AF_INET6:
// Only keep IPv6 link-local addresses.
if( IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ip_addr)->sin6_addr) ) {
memcpy( &v6_addr, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, sizeof(v6_addr) );
/* Only keep IPv6 link-local addresses. */
if (IN6_IS_ADDR_LINKLOCAL
(&((struct sockaddr_in6 *)ip_addr)->
sin6_addr)) {
memcpy(&v6_addr,
&((struct sockaddr_in6 *)
ip_addr)->sin6_addr,
sizeof(v6_addr));
valid_addr_found = 1;
}
break;
default:
if( valid_addr_found == 0 ) {
// Address is not IPv4 or IPv6 and no valid address has
// yet been found for this interface. Discard interface name.
if (valid_addr_found == 0) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
// Next address.
/* Next address. */
uni_addr = uni_addr->Next;
}
if( valid_addr_found == 1 ) {
if (valid_addr_found == 1) {
gIF_INDEX = adapts_item->IfIndex;
break;
}
// Next adapter.
/* Next adapter. */
adapts_item = adapts_item->Next;
}
// Failed to find a valid interface, or valid address.
if( ifname_found == 0 || valid_addr_found == 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n" );
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
#elif (defined(BSD) && BSD >= 199306) || defined(__FreeBSD_kernel__)
@@ -3098,202 +3088,205 @@ int UpnpGetIfInfo(const char *IfName)
int ifname_found = 0;
int valid_addr_found = 0;
// Copy interface name, if it was provided.
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
// Get system interface addresses.
if( getifaddrs(&ifap) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"getifaddrs failed to find list of addresses\n" );
/* Get system interface addresses. */
if (getifaddrs(&ifap) != 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"getifaddrs failed to find list of addresses\n");
return UPNP_E_INIT;
}
// cycle through available interfaces and their addresses.
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
{
// Skip LOOPBACK interfaces, DOWN interfaces and interfaces that
// don't support MULTICAST.
if( ( ifa->ifa_flags & IFF_LOOPBACK )
|| ( !( ifa->ifa_flags & IFF_UP ) )
|| ( !( ifa->ifa_flags & IFF_MULTICAST ) ) ) {
/* cycle through available interfaces and their addresses. */
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if ((ifa->ifa_flags & IFF_LOOPBACK)
|| (!(ifa->ifa_flags & IFF_UP))
|| (!(ifa->ifa_flags & IFF_MULTICAST))) {
continue;
}
if( ifname_found == 0 ) {
// We have found a valid interface name. Keep it.
strncpy( gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME) );
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME));
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME) ) != 0 ) {
// This is not the interface we're looking for.
if (strncmp(gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME))
!= 0) {
/* This is not the interface we're looking for. */
continue;
}
}
// Keep interface addresses for later.
switch( ifa->ifa_addr->sa_family )
{
/* Keep interface addresses for later. */
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
memcpy( &v4_addr, &((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr, sizeof(v4_addr) );
memcpy(&v4_addr,
&((struct sockaddr_in *)(ifa->ifa_addr))->
sin_addr, sizeof(v4_addr));
valid_addr_found = 1;
break;
case AF_INET6:
// Only keep IPv6 link-local addresses.
if( IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr) ) {
memcpy( &v6_addr, &((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr, sizeof(v6_addr) );
/* Only keep IPv6 link-local addresses. */
if (IN6_IS_ADDR_LINKLOCAL
(&((struct sockaddr_in6 *)(ifa->ifa_addr))->
sin6_addr)) {
memcpy(&v6_addr,
&((struct sockaddr_in6 *)(ifa->
ifa_addr))->
sin6_addr, sizeof(v6_addr));
valid_addr_found = 1;
}
break;
default:
if( valid_addr_found == 0 ) {
// Address is not IPv4 or IPv6 and no valid address has
// yet been found for this interface. Discard interface name.
if (valid_addr_found == 0) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
}
freeifaddrs(ifap);
// Failed to find a valid interface, or valid address.
if( ifname_found == 0 || valid_addr_found == 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n" );
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
gIF_INDEX = if_nametoindex(gIF_NAME);
#else
char szBuffer[MAX_INTERFACES * sizeof( struct ifreq )];
char szBuffer[MAX_INTERFACES * sizeof(struct ifreq)];
struct ifconf ifConf;
struct ifreq ifReq;
FILE* inet6_procfd;
int i;
FILE *inet6_procfd;
size_t i;
int LocalSock;
struct in6_addr v6_addr;
int if_idx;
unsigned if_idx;
char addr6[8][5];
char buf[65]; // INET6_ADDRSTRLEN
char buf[65]; /* INET6_ADDRSTRLEN */
int ifname_found = 0;
int valid_addr_found = 0;
// Copy interface name, if it was provided.
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
// Create an unbound datagram socket to do the SIOCGIFADDR ioctl on.
if( ( LocalSock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Can't create addrlist socket\n" );
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((LocalSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Can't create addrlist socket\n");
return UPNP_E_INIT;
}
// Get the interface configuration information...
/* Get the interface configuration information... */
ifConf.ifc_len = sizeof szBuffer;
ifConf.ifc_ifcu.ifcu_buf = ( caddr_t ) szBuffer;
ifConf.ifc_ifcu.ifcu_buf = (caddr_t) szBuffer;
if( ioctl( LocalSock, SIOCGIFCONF, &ifConf ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"DiscoverInterfaces: SIOCGIFCONF returned error\n" );
if (ioctl(LocalSock, SIOCGIFCONF, &ifConf) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"DiscoverInterfaces: SIOCGIFCONF returned error\n");
return UPNP_E_INIT;
}
// Cycle through the list of interfaces looking for IP addresses.
for( i = 0; i < ifConf.ifc_len ; ) {
/* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < (size_t)ifConf.ifc_len;) {
struct ifreq *pifReq =
( struct ifreq * )( ( caddr_t ) ifConf.ifc_req + i );
(struct ifreq *)((caddr_t) ifConf.ifc_req + i);
i += sizeof *pifReq;
// See if this is the sort of interface we want to deal with.
strcpy( ifReq.ifr_name, pifReq->ifr_name );
if( ioctl( LocalSock, SIOCGIFFLAGS, &ifReq ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
/* See if this is the sort of interface we want to deal with. */
strcpy(ifReq.ifr_name, pifReq->ifr_name);
if (ioctl(LocalSock, SIOCGIFFLAGS, &ifReq) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Can't get interface flags for %s:\n",
ifReq.ifr_name );
ifReq.ifr_name);
}
// Skip LOOPBACK interfaces, DOWN interfaces and interfaces that
// don't support MULTICAST.
if( ( ifReq.ifr_flags & IFF_LOOPBACK )
|| ( !( ifReq.ifr_flags & IFF_UP ) )
|| ( !( ifReq.ifr_flags & IFF_MULTICAST ) ) ) {
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if ((ifReq.ifr_flags & IFF_LOOPBACK)
|| (!(ifReq.ifr_flags & IFF_UP))
|| (!(ifReq.ifr_flags & IFF_MULTICAST))) {
continue;
}
if( ifname_found == 0 ) {
// We have found a valid interface name. Keep it.
strncpy( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) );
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME));
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) ) != 0 ) {
// This is not the interface we're looking for.
if (strncmp
(gIF_NAME, pifReq->ifr_name,
sizeof(gIF_NAME)) != 0) {
/* This is not the interface we're looking for. */
continue;
}
}
// Check address family.
if( pifReq->ifr_addr.sa_family == AF_INET ) {
// Copy interface name, IPv4 address and interface index.
strncpy( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) );
inet_ntop(AF_INET, &((struct sockaddr_in*)&pifReq->ifr_addr)->sin_addr, gIF_IPV4, sizeof(gIF_IPV4));
/* Check address family. */
if (pifReq->ifr_addr.sa_family == AF_INET) {
/* Copy interface name, IPv4 address and interface index. */
strncpy(gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME));
inet_ntop(AF_INET,
&((struct sockaddr_in *)&pifReq->ifr_addr)->
sin_addr, gIF_IPV4, sizeof(gIF_IPV4));
gIF_INDEX = if_nametoindex(gIF_NAME);
valid_addr_found = 1;
break;
} else {
// Address is not IPv4
/* Address is not IPv4 */
ifname_found = 0;
}
}
close( LocalSock );
// Failed to find a valid interface, or valid address.
close(LocalSock);
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE;
}
// Try to get the IPv6 address for the same interface
// from "/proc/net/if_inet6", if possible.
/* Try to get the IPv6 address for the same interface */
/* from "/proc/net/if_inet6", if possible. */
inet6_procfd = fopen("/proc/net/if_inet6", "r");
if (inet6_procfd) {
while (fscanf(inet6_procfd,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*20s\n",
addr6[0],addr6[1],addr6[2],addr6[3],
addr6[4],addr6[5],addr6[6],addr6[7], &if_idx) != EOF) {
// Get same interface as IPv4 address retrieved.
if( gIF_INDEX == if_idx ) {
snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s:%s:%s",
addr6[0],addr6[1],addr6[2],addr6[3],
addr6[4],addr6[5],addr6[6],addr6[7]);
// Validate formed address and check for link-local.
addr6[0], addr6[1], addr6[2], addr6[3],
addr6[4], addr6[5], addr6[6], addr6[7],
&if_idx) != EOF) {
/* Get same interface as IPv4 address retrieved. */
if (gIF_INDEX == if_idx) {
snprintf(buf, sizeof(buf),
"%s:%s:%s:%s:%s:%s:%s:%s", addr6[0],
addr6[1], addr6[2], addr6[3], addr6[4],
addr6[5], addr6[6], addr6[7]);
/* Validate formed address and check for link-local. */
if (inet_pton(AF_INET6, buf, &v6_addr) > 0) {
if (IN6_IS_ADDR_ULA(&v6_addr)) {
// Got valid IPv6 ula.
strncpy(gIF_IPV6_ULA_GUA, buf, sizeof(gIF_IPV6_ULA_GUA));
} else if (IN6_IS_ADDR_GLOBAL(&v6_addr) &&
strlen(gIF_IPV6_ULA_GUA) == 0) {
// got a GUA, should store it while no ULA is found
strncpy(gIF_IPV6_ULA_GUA, buf, sizeof(gIF_IPV6_ULA_GUA));
} else if (IN6_IS_ADDR_LINKLOCAL(&v6_addr) &&
strlen(gIF_IPV6) == 0) {
// got a Link local IPv6 address.
strncpy(gIF_IPV6, buf, sizeof(gIF_IPV6));
/* Got valid IPv6 ula. */
strncpy(gIF_IPV6_ULA_GUA, buf,
sizeof
(gIF_IPV6_ULA_GUA));
} else if (IN6_IS_ADDR_GLOBAL(&v6_addr)
&& strlen(gIF_IPV6_ULA_GUA)
== 0) {
/* got a GUA, should store it while no ULA is found */
strncpy(gIF_IPV6_ULA_GUA, buf,
sizeof
(gIF_IPV6_ULA_GUA));
} else
if (IN6_IS_ADDR_LINKLOCAL(&v6_addr)
&& strlen(gIF_IPV6) == 0) {
/* got a Link local IPv6 address. */
strncpy(gIF_IPV6, buf,
sizeof(gIF_IPV6));
}
}
}
@@ -3301,10 +3294,9 @@ int UpnpGetIfInfo(const char *IfName)
fclose(inet6_procfd);
}
#endif
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__,
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Interface name=%s, index=%d, v4=%s, v6=%s, ULA or GUA v6=%s\n",
gIF_NAME, gIF_INDEX, gIF_IPV4, gIF_IPV6, gIF_IPV6_ULA_GUA );
gIF_NAME, gIF_INDEX, gIF_IPV4, gIF_IPV6, gIF_IPV6_ULA_GUA);
return UPNP_E_SUCCESS;
}
@@ -3330,7 +3322,6 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
UpnpString *Sid = UpnpString_new();
UpnpString *Url = UpnpString_new();
UpnpString_set_String(Url, Param->Url);
UpnpString_set_String(Sid, (char *)Evt.Sid);
Evt.ErrCode = genaSubscribe(
Param->Handle,
Url,
@@ -3338,6 +3329,7 @@ void UpnpThreadDistribution(struct UpnpNonblockParam *Param)
Sid);
strcpy(Evt.PublisherUrl, Param->Url);
Evt.TimeOut = Param->TimeOut;
strcpy((char *)Evt.Sid, UpnpString_get_String(Sid));
Param->Fun(UPNP_EVENT_SUBSCRIBE_COMPLETE, &Evt, Param->Cookie);
UpnpString_delete(Sid);
UpnpString_delete(Url);
@@ -3523,7 +3515,7 @@ int PrintHandleInfo(UpnpClient_Handle Hnd)
}
int getlocalhostname(char *out, const int out_len)
int getlocalhostname(char *out, size_t out_len)
{
int ret = UPNP_E_SUCCESS;
char tempstr[16];
@@ -3598,7 +3590,7 @@ int getlocalhostname(char *out, const int out_len)
struct ifconf ifConf;
struct ifreq ifReq;
int nResult;
int i;
long unsigned int i;
int LocalSock;
struct sockaddr_in LocalAddr;
int j = 0;
@@ -3627,7 +3619,7 @@ int getlocalhostname(char *out, const int out_len)
}
/* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < ifConf.ifc_len && j < DEFAULT_INTERFACE; ) {
for (i = 0; i < (long unsigned int)ifConf.ifc_len && j < DEFAULT_INTERFACE; ) {
struct ifreq *pifReq =
(struct ifreq *)((caddr_t)ifConf.ifc_req + i);
i += sizeof *pifReq;
@@ -3713,7 +3705,7 @@ int UpnpAddVirtualDir(const char *newDirName)
char dirName[NAME_SIZE];
if( UpnpSdkInit != 1 ) {
// SDK is not initialized
/* SDK is not initialized */
return UPNP_E_FINISH;
}
@@ -3730,7 +3722,7 @@ int UpnpAddVirtualDir(const char *newDirName)
pCurVirtualDir = pVirtualDirList;
while( pCurVirtualDir != NULL ) {
// already has this entry
/* already has this entry */
if( strcmp( pCurVirtualDir->dirName, dirName ) == 0 ) {
return UPNP_E_SUCCESS;
}
@@ -3747,7 +3739,7 @@ int UpnpAddVirtualDir(const char *newDirName)
strcpy( pNewVirtualDir->dirName, dirName );
*( pNewVirtualDir->dirName + strlen( dirName ) ) = 0;
if( pVirtualDirList == NULL ) { // first virtual dir
if( pVirtualDirList == NULL ) { /* first virtual dir */
pVirtualDirList = pNewVirtualDir;
} else {
pLast = pVirtualDirList;
@@ -3778,11 +3770,8 @@ int UpnpRemoveVirtualDir(const char *dirName)
if( pVirtualDirList == NULL ) {
return UPNP_E_INVALID_PARAM;
}
//
// Handle the special case where the directory that we are
// removing is the first and only one in the list.
//
/* Handle the special case where the directory that we are */
/* removing is the first and only one in the list. */
if( ( pVirtualDirList->next == NULL ) &&
( strcmp( pVirtualDirList->dirName, dirName ) == 0 ) ) {
free( pVirtualDirList );
@@ -3958,10 +3947,7 @@ int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback)
return ret;
}
int UpnpSetContentLength(
UpnpClient_Handle Hnd,
int contentLength)
int UpnpSetContentLength(UpnpClient_Handle Hnd, size_t contentLength)
{
int errCode = UPNP_E_SUCCESS;
struct Handle_Info *HInfo = NULL;
@@ -3975,25 +3961,21 @@ int UpnpSetContentLength(
HandleLock();
errCode = GetHandleInfo(Hnd, &HInfo);
if (errCode != HND_DEVICE) {
errCode = UPNP_E_INVALID_HANDLE;
break;
}
if (contentLength > MAX_SOAP_CONTENT_LENGTH) {
errCode = UPNP_E_OUTOF_BOUNDS;
break;
}
g_maxContentLength = contentLength;
} while(0);
} while (0);
HandleUnlock();
return errCode;
}
int UpnpSetMaxContentLength(size_t contentLength)
{
int errCode = UPNP_E_SUCCESS;

View File

@@ -229,51 +229,50 @@ void UpnpDisplayFileAndLine(
fflush(fd);
}
void UpnpDisplayBanner(
FILE * fd,
const char **lines,
size_t size,
int starLength)
size_t starLength)
{
int leftMarginLength = starLength / 2 + 1;
int rightMarginLength = starLength / 2 + 1;
int i = 0;
int LineSize = 0;
int starLengthMinus2 = starLength - 2;
size_t leftMarginLength = starLength / 2 + 1;
size_t rightMarginLength = starLength / 2 + 1;
size_t i = 0;
size_t LineSize = 0;
size_t starLengthMinus2 = starLength - 2;
char *leftMargin = ( char * )malloc( leftMarginLength );
char *rightMargin = ( char * )malloc( rightMarginLength );
char *stars = ( char * )malloc( starLength + 1 );
char *currentLine = ( char * )malloc( starLength + 1 );
char *leftMargin = malloc(leftMarginLength);
char *rightMargin = malloc(rightMarginLength);
char *stars = malloc(starLength + 1);
char *currentLine = malloc(starLength + 1);
const char *line = NULL;
memset( stars, '*', starLength );
memset(stars, '*', starLength);
stars[starLength] = 0;
memset( leftMargin, 0, leftMarginLength );
memset( rightMargin, 0, rightMarginLength );
fprintf( fd, "\n%s\n", stars );
for( i = 0; i < size; i++ ) {
LineSize = strlen( lines[i] );
memset(leftMargin, 0, leftMarginLength);
memset(rightMargin, 0, rightMarginLength);
fprintf(fd, "\n%s\n", stars);
for (i = 0; i < size; i++) {
LineSize = strlen(lines[i]);
line = lines[i];
while( LineSize > starLengthMinus2 ) {
memcpy( currentLine, line, starLengthMinus2 );
while (LineSize > starLengthMinus2) {
memcpy(currentLine, line, starLengthMinus2);
currentLine[starLengthMinus2] = 0;
fprintf( fd, "*%s*\n", currentLine );
fprintf(fd, "*%s*\n", currentLine);
LineSize -= starLengthMinus2;
line += starLengthMinus2;
}
leftMarginLength = (starLengthMinus2 - LineSize)/2;
if( LineSize % 2 == 0 ) {
leftMarginLength = (starLengthMinus2 - LineSize) / 2;
if (LineSize % 2 == 0) {
rightMarginLength = leftMarginLength;
} else {
rightMarginLength = leftMarginLength + 1;
}
memset( leftMargin, ' ', leftMarginLength );
memset( rightMargin, ' ', rightMarginLength );
memset(leftMargin, ' ', leftMarginLength);
memset(rightMargin, ' ', rightMarginLength);
leftMargin[leftMarginLength] = 0;
rightMargin[rightMarginLength] = 0;
fprintf( fd, "*%s%s%s*\n", leftMargin, line, rightMargin );
fprintf(fd, "*%s%s%s*\n", leftMargin, line, rightMargin);
}
fprintf(fd, "%s\n\n", stars);
@@ -283,7 +282,6 @@ void UpnpDisplayBanner(
free(leftMargin);
}
void PrintThreadPoolStats(
ThreadPool *tp,
const char *DbgFileName,

View File

@@ -119,10 +119,9 @@ struct ErrorString ErrorMessages[] = {
{UPNP_E_INTERNAL_ERROR, "UPNP_E_INTERNAL_ERROR"},
};
const char *UpnpGetErrorMessage(int rc)
{
int i;
size_t i;
for (i = 0; i < sizeof (ErrorMessages) / sizeof (ErrorMessages[0]); ++i) {
if (rc == ErrorMessages[i].rc) {
@@ -133,7 +132,6 @@ const char *UpnpGetErrorMessage(int rc)
return "Unknown error code";
}
/*!
* \todo There is some unnecessary allocation and deallocation going on here
* because of the way resolve_rel_url() was originally written and used. In the
@@ -147,18 +145,36 @@ int UpnpResolveURL(
int ret = UPNP_E_SUCCESS;
char *tempRel = NULL;
if (RelURL == NULL) {
if (!RelURL) {
ret = UPNP_E_INVALID_PARAM;
goto ExitFunction;
}
tempRel = resolve_rel_url((char *)BaseURL, (char *)RelURL);
if (tempRel) {
strcpy(AbsURL, tempRel);
free(tempRel);
} else {
} else
ret = UPNP_E_INVALID_URL;
ExitFunction:
return UPNP_E_SUCCESS;
}
int UpnpResolveURL2(
const char *BaseURL,
const char *RelURL,
char **AbsURL)
{
int ret = UPNP_E_SUCCESS;
if (!RelURL) {
ret = UPNP_E_INVALID_PARAM;
goto ExitFunction;
}
*AbsURL = resolve_rel_url((char *)BaseURL, (char *)RelURL);
if (!*AbsURL)
ret = UPNP_E_INVALID_URL;
ExitFunction:
return UPNP_E_SUCCESS;
@@ -296,7 +312,7 @@ static IXML_Document *makeAction(
}
if (NumArg > 0) {
//va_start(ArgList, Arg);
/*va_start(ArgList, Arg); */
ArgName = Arg;
for ( ; ; ) {
ArgValue = va_arg(ArgList, const char *);
@@ -315,7 +331,7 @@ static IXML_Document *makeAction(
break;
}
}
//va_end(ArgList);
/*va_end(ArgList); */
}
return ActionDoc;

View File

@@ -1,33 +1,33 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include "config.h"
#if EXCLUDE_GENA == 0
@@ -63,7 +63,7 @@ error_respond( IN SOCKINFO * info,
int major,
minor;
// retrieve the minor and major version from the GENA request
/* retrieve the minor and major version from the GENA request */
http_CalcResponseVersion( hmsg->major_version,
hmsg->minor_version, &major, &minor );
@@ -90,38 +90,40 @@ genaCallback( IN http_parser_t * parser,
IN http_message_t * request,
INOUT SOCKINFO * info )
{
xboolean found_function = FALSE;
int found_function = FALSE;
if( request->method == HTTPMETHOD_SUBSCRIBE ) {
#ifdef INCLUDE_DEVICE_APIS
found_function = TRUE;
if( httpmsg_find_hdr( request, HDR_NT, NULL ) == NULL ) {
// renew subscription
/* renew subscription */
gena_process_subscription_renewal_request
( info, request );
} else {
// subscribe
/* subscribe */
gena_process_subscription_request( info, request );
}
UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__,
"got subscription request\n" );
} else if( request->method == HTTPMETHOD_UNSUBSCRIBE ) {
found_function = TRUE;
// unsubscribe
/* unsubscribe */
gena_process_unsubscribe_request( info, request );
#endif
} else if( request->method == HTTPMETHOD_NOTIFY ) {
#ifdef INCLUDE_CLIENT_APIS
found_function = TRUE;
// notify
/* notify */
gena_process_notification_event( info, request );
#endif
}
if( !found_function ) {
// handle missing functions of device or ctrl pt
/* handle missing functions of device or ctrl pt */
error_respond( info, HTTP_NOT_IMPLEMENTED, request );
}
return;
parser = parser;
}
#endif // EXCLUDE_GENA
#endif /* EXCLUDE_GENA */

View File

@@ -106,7 +106,7 @@ static void GenaAutoRenewSubscription(
}
UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "HANDLE IS VALID");
// make callback
/* make callback */
callback_fun = handle_info->Callback;
cookie = handle_info->Cookie;
HandleUnlock();
@@ -160,14 +160,14 @@ static int ScheduleGenaAutoRenew(
goto end_function;
}
// schedule expire event
/* schedule expire event */
RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
RenewEventStruct->TimeOut = TimeOut;
strcpy(RenewEventStruct->Sid, UpnpString_get_String(tmpSID));
strncpy(RenewEventStruct->PublisherUrl,
UpnpString_get_String(tmpEventURL), NAME_SIZE - 1);
// RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE;
/* RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE; */
RenewEvent->handle = client_handle;
RenewEvent->Event = RenewEventStruct;
@@ -175,7 +175,7 @@ static int ScheduleGenaAutoRenew(
TPJobSetFreeFunction(&job, (free_routine)free_upnp_timeout);
TPJobSetPriority(&job, MED_PRIORITY);
// Schedule the job
/* Schedule the job */
return_code = TimerThreadSchedule(
&gTimerThread,
TimeOut - AUTO_RENEW_TIME,
@@ -215,7 +215,7 @@ static int gena_unsubscribe(
uri_type dest_url;
membuffer request;
// parse url
/* parse url */
return_code = http_FixStrUrl(
UpnpString_get_String(url),
UpnpString_get_Length(url),
@@ -224,7 +224,7 @@ static int gena_unsubscribe(
return return_code;
}
// make request msg
/* make request msg */
membuffer_init(&request);
request.size_inc = 30;
return_code = http_MakeMessage(
@@ -233,14 +233,14 @@ static int gena_unsubscribe(
HTTPMETHOD_UNSUBSCRIBE, &dest_url,
"SID: ", UpnpString_get_String(sid));
// Not able to make the message so destroy the existing buffer
/* Not able to make the message so destroy the existing buffer */
if (return_code != 0) {
membuffer_destroy(&request);
return return_code;
}
// send request and get reply
/* send request and get reply */
return_code = http_RequestAndResponse(
&dest_url, request.buf, request.length,
HTTPMETHOD_UNSUBSCRIBE, HTTP_DEFAULT_TIMEOUT, response);
@@ -286,7 +286,7 @@ static int gena_subscribe(
UpnpString_clear(sid);
// request timeout to string
/* request timeout to string */
if (timeout == NULL) {
timeout = &local_timeout;
}
@@ -298,7 +298,7 @@ static int gena_subscribe(
sprintf(timeout_str, "%d", *timeout);
}
// parse url
/* parse url */
return_code = http_FixStrUrl(
UpnpString_get_String(url),
UpnpString_get_Length(url),
@@ -307,11 +307,11 @@ static int gena_subscribe(
return return_code;
}
// make request msg
/* make request msg */
membuffer_init(&request);
request.size_inc = 30;
if (renewal_sid) {
// renew subscription
/* renew subscription */
return_code = http_MakeMessage(
&request, 1, 1,
"q" "ssc" "sscc",
@@ -319,7 +319,7 @@ static int gena_subscribe(
"SID: ", UpnpString_get_String(renewal_sid),
"TIMEOUT: Second-", timeout_str );
} else {
// subscribe
/* subscribe */
if (dest_url.hostport.IPaddress.ss_family == AF_INET6) {
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&dest_url.hostport.IPaddress;
return_code = http_MakeMessage(
@@ -346,7 +346,7 @@ static int gena_subscribe(
return return_code;
}
// send request and get reply
/* send request and get reply */
return_code = http_RequestAndResponse(&dest_url, request.buf,
request.length,
HTTPMETHOD_SUBSCRIBE,
@@ -365,7 +365,7 @@ static int gena_subscribe(
return UPNP_E_SUBSCRIBE_UNACCEPTED;
}
// get SID and TIMEOUT
/* get SID and TIMEOUT */
if (httpmsg_find_hdr(&response.msg, HDR_SID, &sid_hdr) == NULL ||
sid_hdr.length == 0 ||
httpmsg_find_hdr( &response.msg, HDR_TIMEOUT, &timeout_hdr ) == NULL ||
@@ -375,10 +375,10 @@ static int gena_subscribe(
return UPNP_E_BAD_RESPONSE;
}
// save timeout
/* save timeout */
parse_ret = matchstr(timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0", timeout);
if (parse_ret == PARSE_OK) {
// nothing to do
/* nothing to do */
} else if (memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
*timeout = -1;
} else {
@@ -387,7 +387,7 @@ static int gena_subscribe(
return UPNP_E_BAD_RESPONSE;
}
// save SID
/* save SID */
UpnpString_set_StringN(sid, sid_hdr.buf, sid_hdr.length);
if (UpnpString_get_String(sid) == NULL) {
httpmsg_destroy(&response.msg);
@@ -456,7 +456,7 @@ int genaUnSubscribe(
ClientSubscription *sub_copy = UpnpClientSubscription_new();
http_parser_t response;
// validate handle and sid
/* validate handle and sid */
HandleLock();
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock();
@@ -518,7 +518,7 @@ int genaSubscribe(
UpnpString_clear(out_sid);
HandleReadLock();
// validate handle
/* validate handle */
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock();
@@ -526,7 +526,7 @@ int genaSubscribe(
}
HandleUnlock();
// subscribe
/* subscribe */
SubscribeLock();
return_code = gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID);
HandleLock();
@@ -542,16 +542,16 @@ int genaSubscribe(
goto error_handler;
}
// generate client SID
/* generate client SID */
uuid_create(&uid );
uuid_unpack(&uid, temp_sid);
sprintf(temp_sid2, "uuid:%s", temp_sid);
UpnpString_set_String(out_sid, temp_sid2);
// create event url
/* create event url */
UpnpString_assign(EventURL, PublisherURL);
// fill subscription
/* fill subscription */
if (newSubscription == NULL) {
return_code = UPNP_E_OUTOF_MEMORY;
goto error_handler;
@@ -563,7 +563,7 @@ int genaSubscribe(
UpnpClientSubscription_set_Next(newSubscription, handle_info->ClientSubList);
handle_info->ClientSubList = newSubscription;
// schedule expiration event
/* schedule expiration event */
return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, newSubscription);
error_handler:
@@ -594,7 +594,7 @@ int genaRenewSubscription(
HandleLock();
// validate handle and sid
/* validate handle and sid */
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock();
@@ -610,7 +610,7 @@ int genaRenewSubscription(
goto exit_function;
}
// remove old events
/* remove old events */
if (TimerThreadRemove(
&gTimerThread,
UpnpClientSubscription_get_RenewEventId(sub),
@@ -639,17 +639,17 @@ int genaRenewSubscription(
goto exit_function;
}
// we just called GetHandleInfo, so we don't check for return value
//GetHandleInfo(client_handle, &handle_info);
/* we just called GetHandleInfo, so we don't check for return value */
/*GetHandleInfo(client_handle, &handle_info); */
if (return_code != UPNP_E_SUCCESS) {
// network failure (remove client sub)
/* network failure (remove client sub) */
RemoveClientSubClientSID(&handle_info->ClientSubList, in_sid);
free_client_subscription(sub_copy);
HandleUnlock();
goto exit_function;
}
// get subscription
/* get subscription */
sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid);
if (sub == NULL) {
free_client_subscription(sub_copy);
@@ -658,10 +658,10 @@ int genaRenewSubscription(
goto exit_function;
}
// store actual sid
/* store actual sid */
UpnpClientSubscription_set_ActualSID(sub, ActualSID);
// start renew subscription timer
/* start renew subscription timer */
return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, sub);
if (return_code != GENA_SUCCESS) {
RemoveClientSubClientSID(
@@ -698,7 +698,7 @@ void gena_process_notification_event(
nts_hdr;
memptr seq_hdr;
// get SID
/* get SID */
if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) {
error_respond(info, HTTP_PRECONDITION_FAILED, event);
goto exit_function;
@@ -706,28 +706,28 @@ void gena_process_notification_event(
sid.buff = sid_hdr.buf;
sid.size = sid_hdr.length;
// get event key
/* get event key */
if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL ||
matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) {
error_respond( info, HTTP_BAD_REQUEST, event );
goto exit_function;
}
// get NT and NTS headers
/* get NT and NTS headers */
if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL ||
httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) {
error_respond( info, HTTP_BAD_REQUEST, event );
goto exit_function;
}
// verify NT and NTS headers
/* verify NT and NTS headers */
if (memptr_cmp(&nt_hdr, "upnp:event") != 0 ||
memptr_cmp(&nts_hdr, "upnp:propchange") != 0) {
error_respond(info, HTTP_PRECONDITION_FAILED, event);
goto exit_function;
}
// parse the content (should be XML)
/* parse the content (should be XML) */
if (!has_xml_content_type(event) ||
event->msg.length == 0 ||
ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) {
@@ -737,28 +737,28 @@ void gena_process_notification_event(
HandleLock();
// get client info
/* get client info */
if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
error_respond(info, HTTP_PRECONDITION_FAILED, event);
HandleUnlock();
goto exit_function;
}
// get subscription based on SID
/* get subscription based on SID */
subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
if (subscription == NULL) {
if (eventKey == 0) {
// wait until we've finished processing a subscription
// (if we are in the middle)
// this is to avoid mistakenly rejecting the first event if we
// receive it before the subscription response
/* wait until we've finished processing a subscription */
/* (if we are in the middle) */
/* this is to avoid mistakenly rejecting the first event if we */
/* receive it before the subscription response */
HandleUnlock();
// try and get Subscription Lock
// (in case we are in the process of subscribing)
/* try and get Subscription Lock */
/* (in case we are in the process of subscribing) */
SubscribeLock();
// get HandleLock again
/* get HandleLock again */
HandleLock();
if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
@@ -784,25 +784,25 @@ void gena_process_notification_event(
}
}
// success
/* success */
error_respond(info, HTTP_OK, event);
// fill event struct
/* fill event struct */
tmpSID = UpnpClientSubscription_get_SID(subscription);
strcpy(event_struct.Sid, UpnpString_get_String(tmpSID));
event_struct.EventKey = eventKey;
event_struct.ChangedVariables = ChangedVars;
// copy callback
/* copy callback */
callback = handle_info->Callback;
cookie = handle_info->Cookie;
HandleUnlock();
// make callback with event struct
// In future, should find a way of mainting
// that the handle is not unregistered in the middle of a
// callback
/* make callback with event struct */
/* In future, should find a way of mainting */
/* that the handle is not unregistered in the middle of a */
/* callback */
callback(UPNP_EVENT_RECEIVED, &event_struct, cookie);
exit_function:

View File

@@ -29,19 +29,15 @@
*
******************************************************************************/
/*!
* \file
*/
#include "config.h"
#if EXCLUDE_GENA == 0
#ifdef INCLUDE_DEVICE_APIS
#include "gena.h"
#include "httpparser.h"
#include "httpreadwrite.h"
@@ -53,7 +49,6 @@
#include "upnpapi.h"
#include "uuid.h"
/*!
* \brief Unregisters a device.
*
@@ -81,7 +76,6 @@ int genaUnregisterDevice(
return ret;
}
/*!
* \brief Generates XML property set for notifications.
*
@@ -102,7 +96,7 @@ static int GeneratePropertySet(
{
char *buffer;
int counter = 0;
int size = 0;
size_t size = 0;
int temp_counter = 0;
/*size += strlen(XML_VERSION);*/
@@ -116,9 +110,8 @@ static int GeneratePropertySet(
}
buffer = (char *)malloc(size + 1);
if (buffer == NULL) {
if (buffer == NULL)
return UPNP_E_OUTOF_MEMORY;
}
memset(buffer, 0, size + 1);
/*
strcpy(buffer,XML_VERSION);
@@ -140,7 +133,6 @@ static int GeneratePropertySet(
return XML_SUCCESS;
}
/*!
* \brief Frees memory used in notify_threads if the reference count is 0,
* otherwise decrements the refrence count.
@@ -160,7 +152,6 @@ static void free_notify_struct(
free(input);
}
/*!
* \brief Sends the notify message and returns a reply.
*
@@ -179,12 +170,13 @@ static UPNP_INLINE int notify_send_and_recv(
http_parser_t *response)
{
uri_type url;
int conn_fd;
SOCKET conn_fd;
membuffer start_msg;
int ret_code;
int err_code;
int timeout;
SOCKINFO info;
const char *CRLF = "\r\n";
/* connect */
UpnpPrintf(UPNP_ALL, GENA, __FILE__, __LINE__,
@@ -193,16 +185,12 @@ static UPNP_INLINE int notify_send_and_recv(
destination_url->hostport.text.buff);
conn_fd = http_Connect(destination_url, &url);
if (conn_fd < 0) {
if (conn_fd < 0)
/* return UPNP error */
return conn_fd;
}
return UPNP_E_SOCKET_CONNECT;
ret_code = sock_init(&info, conn_fd);
if (ret_code) {
sock_destroy(&info, SD_BOTH);
return ret_code;
}
/* make start line and HOST header */
@@ -214,35 +202,29 @@ static UPNP_INLINE int notify_send_and_recv(
mid_msg->buf) != 0) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
return UPNP_E_OUTOF_MEMORY;
}
timeout = HTTP_DEFAULT_TIMEOUT;
timeout = GENA_NOTIFICATION_SENDING_TIMEOUT;
/* 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);
CRLF, sizeof CRLF);
if (ret_code) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
return ret_code;
}
timeout = GENA_NOTIFICATION_ANSWERING_TIMEOUT;
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);
@@ -250,7 +232,6 @@ static UPNP_INLINE int notify_send_and_recv(
return UPNP_E_SUCCESS;
}
/*!
* \brief Function to Notify a particular subscription of a particular event.
*
@@ -270,52 +251,44 @@ static int genaNotify(
/*! [in] subscription to be Notified, assumes this is valid for life of function. */
subscription *sub)
{
int i;
size_t i;
membuffer mid_msg;
membuffer endmsg;
uri_type *url;
http_parser_t response;
int return_code = -1;
membuffer_init( &mid_msg );
// make 'end' msg (the part that won't vary with the destination)
membuffer_init(&mid_msg);
/* make 'end' msg (the part that won't vary with the destination) */
endmsg.size_inc = 30;
if( http_MakeMessage(
&mid_msg, 1, 1,
if (http_MakeMessage(&mid_msg, 1, 1,
"s" "ssc" "sdcc",
headers,
"SID: ", sub->sid,
"SEQ: ", sub->ToSendEventKey ) != 0 ) {
membuffer_destroy( &mid_msg );
"SEQ: ", sub->ToSendEventKey) != 0) {
membuffer_destroy(&mid_msg);
return UPNP_E_OUTOF_MEMORY;
}
// send a notify to each url until one goes thru
for( i = 0; i < sub->DeliveryURLs.size; i++ ) {
/* send a notify to each url until one goes thru */
for (i = 0; i < sub->DeliveryURLs.size; i++) {
url = &sub->DeliveryURLs.parsedURLs[i];
if( ( return_code = notify_send_and_recv( url,
&mid_msg, propertySet,
&response ) ) ==
UPNP_E_SUCCESS ) {
return_code = notify_send_and_recv(
url, &mid_msg, propertySet, &response);
if (return_code == UPNP_E_SUCCESS)
break;
}
}
membuffer_destroy( &mid_msg );
if( return_code == UPNP_E_SUCCESS ) {
if( response.msg.status_code == HTTP_OK ) {
membuffer_destroy(&mid_msg);
if (return_code == UPNP_E_SUCCESS) {
if (response.msg.status_code == HTTP_OK)
return_code = GENA_SUCCESS;
} else {
if( response.msg.status_code == HTTP_PRECONDITION_FAILED ) {
//Invalid SID gets removed
else {
if (response.msg.status_code == HTTP_PRECONDITION_FAILED)
/*Invalid SID gets removed */
return_code = GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;
} else {
else
return_code = GENA_E_NOTIFY_UNACCEPTED;
}
}
httpmsg_destroy( &response.msg );
httpmsg_destroy(&response.msg);
}
return return_code;
@@ -337,7 +310,7 @@ static void genaNotifyThread(
subscription *sub;
service_info *service;
subscription sub_copy;
notify_thread_struct *in = ( notify_thread_struct * ) input;
notify_thread_struct *in = (notify_thread_struct *) input;
int return_code;
struct Handle_Info *handle_info;
ThreadPoolJob job;
@@ -346,42 +319,36 @@ static void genaNotifyThread(
* 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();
/*HandleReadLock(); */
HandleLock();
//validate context
/* validate context */
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
free_notify_struct( in );
if (GetHandleInfo(in->device_handle, &handle_info) != HND_DEVICE) {
free_notify_struct(in);
HandleUnlock();
return;
}
if( ( ( service = FindServiceId( &handle_info->ServiceTable,
in->servId, in->UDN ) ) == NULL )
|| ( !service->active )
|| ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL )
|| ( ( copy_subscription( sub, &sub_copy ) != HTTP_SUCCESS ) ) ) {
free_notify_struct( in );
if (!(service = FindServiceId(&handle_info->ServiceTable, in->servId, in->UDN)) ||
!service->active ||
!(sub = GetSubscriptionSID(in->sid, service)) ||
copy_subscription(sub, &sub_copy) != HTTP_SUCCESS) {
free_notify_struct(in);
HandleUnlock();
return;
}
#ifdef UPNP_ENABLE_NOTIFICATION_REORDERING
//If the event is out of order push it back to the job queue
if( in->eventKey != sub->ToSendEventKey ) {
TPJobInit( &job, ( start_routine ) genaNotifyThread, input );
TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
/*If the event is out of order push it back to the job queue */
if (in->eventKey != sub->ToSendEventKey) {
TPJobInit(&job, (start_routine) genaNotifyThread, input);
TPJobSetFreeFunction(&job, (free_function) free_notify_struct);
TPJobSetPriority(&job, MED_PRIORITY);
/* Sleep a little before creating another thread otherwise if there is
* a lot of notifications to send, the device will take 100% of the CPU
* to create threads and push them back to the job queue. */
imillisleep( 1 );
ThreadPoolAdd( &gSendThreadPool, &job, NULL );
freeSubscription( &sub_copy );
imillisleep(1);
ThreadPoolAdd(&gSendThreadPool, &job, NULL);
freeSubscription(&sub_copy);
HandleUnlock();
return;
}
@@ -389,38 +356,31 @@ static void genaNotifyThread(
HandleUnlock();
//send the notify
return_code = genaNotify( in->headers, in->propertySet, &sub_copy );
freeSubscription( &sub_copy );
/* send the notify */
return_code = genaNotify(in->headers, in->propertySet, &sub_copy);
freeSubscription(&sub_copy);
HandleLock();
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {
free_notify_struct( in );
if (GetHandleInfo(in->device_handle, &handle_info) != HND_DEVICE) {
free_notify_struct(in);
HandleUnlock();
return;
}
//validate context
if( ( ( service = FindServiceId( &handle_info->ServiceTable,
in->servId, in->UDN ) ) == NULL )
|| ( !service->active )
|| ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL ) ) {
free_notify_struct( in );
/* validate context */
if (!(service = FindServiceId(&handle_info->ServiceTable, in->servId, in->UDN)) ||
!service->active ||
!(sub = GetSubscriptionSID(in->sid, service))) {
free_notify_struct(in);
HandleUnlock();
return;
}
sub->ToSendEventKey++;
if( sub->ToSendEventKey < 0 ) //wrap to 1 for overflow
if (sub->ToSendEventKey < 0)
/* wrap to 1 for overflow */
sub->ToSendEventKey = 1;
if (return_code == GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB)
RemoveSubscriptionSID(in->sid, service);
free_notify_struct(in);
if( return_code == GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB ) {
RemoveSubscriptionSID( in->sid, service );
}
free_notify_struct( in );
HandleUnlock();
}
@@ -448,7 +408,7 @@ static char *AllocGenaHeaders(
static const char *HEADER_LINE_4 =
"NTS: upnp:propchange\r\n";
char *headers = NULL;
int headers_size = 0;
size_t headers_size = 0;
int line = 0;
headers_size =
@@ -1135,8 +1095,8 @@ static int create_url_list(
/*! [out] . */
URL_list *out)
{
int URLcount = 0;
int i;
size_t URLcount = 0;
size_t i;
int return_code = 0;
uri_type temp;
token urls;
@@ -1166,12 +1126,11 @@ static int create_url_list(
}
if( URLcount > 0 ) {
out->URLs = ( char * )malloc( URLS->size + 1 );
out->parsedURLs =
( uri_type * ) malloc( sizeof( uri_type ) * URLcount );
if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) {
free( out->URLs );
free( out->parsedURLs );
out->URLs = malloc(URLS->size + 1);
out->parsedURLs = malloc(sizeof(uri_type) * URLcount);
if (!out->URLs || !out->parsedURLs) {
free(out->URLs);
free(out->parsedURLs);
out->URLs = NULL;
out->parsedURLs = NULL;
return UPNP_E_OUTOF_MEMORY;
@@ -1202,7 +1161,7 @@ static int create_url_list(
}
out->size = URLcount;
return URLcount;
return (int)URLcount;
}
@@ -1234,20 +1193,20 @@ void gena_process_subscription_request(
goto exit_function;
}
// check NT header
// Windows Millenium Interoperability:
// we accept either upnp:event, or upnp:propchange for the NT header
/* check NT header */
/* Windows Millenium Interoperability: */
/* we accept either upnp:event, or upnp:propchange for the NT header */
if (memptr_cmp_nocase(&nt_hdr, "upnp:event") != 0) {
error_respond(info, HTTP_PRECONDITION_FAILED, request);
goto exit_function;
}
// if a SID is present then the we have a bad request "incompatible headers"
/* if a SID is present then the we have a bad request "incompatible headers" */
if (httpmsg_find_hdr(request, HDR_SID, NULL) != NULL) {
error_respond(info, HTTP_BAD_REQUEST, request);
goto exit_function;
}
// look up service by eventURL
/* look up service by eventURL */
event_url_path = str_alloc(request->uri.pathquery.buff, request->uri.pathquery.size);
if (event_url_path == NULL) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
@@ -1260,7 +1219,7 @@ void gena_process_subscription_request(
HandleLock();
// CURRENTLY, ONLY ONE DEVICE
/* CURRENTLY, ONLY ONE DEVICE */
if (GetDeviceHandleInfo(info->foreign_sockaddr.ss_family ,
&device_handle, &handle_info) != HND_DEVICE) {
free(event_url_path);
@@ -1283,14 +1242,14 @@ void gena_process_subscription_request(
service->TotalSubscriptions,
handle_info->MaxSubscriptions);
// too many subscriptions
/* too many subscriptions */
if (handle_info->MaxSubscriptions != -1 &&
service->TotalSubscriptions >= handle_info->MaxSubscriptions) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
HandleUnlock();
goto exit_function;
}
// generate new subscription
/* generate new subscription */
sub = (subscription *)malloc(sizeof (subscription));
if (sub == NULL) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
@@ -1305,7 +1264,7 @@ void gena_process_subscription_request(
sub->DeliveryURLs.URLs = NULL;
sub->DeliveryURLs.parsedURLs = NULL;
// check for valid callbacks
/* check for valid callbacks */
if (httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr) == NULL) {
error_respond(info, HTTP_PRECONDITION_FAILED, request);
freeSubscriptionList(sub);
@@ -1325,20 +1284,20 @@ void gena_process_subscription_request(
HandleUnlock();
goto exit_function;
}
// set the timeout
/* set the timeout */
if (httpmsg_find_hdr(request, HDR_TIMEOUT, &timeout_hdr) != NULL) {
if (matchstr(timeout_hdr.buf, timeout_hdr.length,
"%iSecond-%d%0", &time_out) == PARSE_OK) {
// nothing
/* nothing */
} else if(memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
// infinite timeout
/* infinite timeout */
time_out = -1;
} else {
// default is > 1800 seconds
/* default is > 1800 seconds */
time_out = DEFAULT_TIMEOUT;
}
}
// replace infinite timeout with max timeout, if possible
/* replace infinite timeout with max timeout, if possible */
if (handle_info->MaxSubscriptionTimeOut != -1) {
if (time_out == -1 ||
time_out > handle_info->MaxSubscriptionTimeOut) {
@@ -1348,40 +1307,40 @@ void gena_process_subscription_request(
if (time_out >= 0) {
sub->expireTime = time(NULL) + time_out;
} else {
// infinite time
/* infinite time */
sub->expireTime = 0;
}
// generate SID
/* generate SID */
uuid_create(&uid);
uuid_unpack(&uid, temp_sid);
sprintf(sub->sid, "uuid:%s", temp_sid);
// respond OK
/* respond OK */
if (respond_ok(info, time_out, sub, request) != UPNP_E_SUCCESS) {
freeSubscriptionList(sub);
HandleUnlock();
goto exit_function;
}
// add to subscription list
/* add to subscription list */
sub->next = service->subscriptionList;
service->subscriptionList = sub;
service->TotalSubscriptions++;
// finally generate callback for init table dump
/* finally generate callback for init table dump */
request_struct.ServiceId = service->serviceId;
request_struct.UDN = service->UDN;
strcpy((char *)request_struct.Sid, sub->sid);
// copy callback
/* copy callback */
callback_fun = handle_info->Callback;
cookie = handle_info->Cookie;
HandleUnlock();
// make call back with request struct
// in the future should find a way of mainting that the handle
// is not unregistered in the middle of a callback
/* make call back with request struct */
/* in the future should find a way of mainting that the handle */
/* is not unregistered in the middle of a callback */
callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, &request_struct, cookie);
exit_function:
@@ -1403,13 +1362,13 @@ void gena_process_subscription_renewal_request(
membuffer event_url_path;
memptr timeout_hdr;
// if a CALLBACK or NT header is present, then it is an error
/* if a CALLBACK or NT header is present, then it is an error */
if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
error_respond( info, HTTP_BAD_REQUEST, request );
return;
}
// get SID
/* get SID */
if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
temp_hdr.length > SID_SIZE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1418,7 +1377,7 @@ void gena_process_subscription_renewal_request(
memcpy( sid, temp_hdr.buf, temp_hdr.length );
sid[temp_hdr.length] = '\0';
// lookup service by eventURL
/* lookup service by eventURL */
membuffer_init( &event_url_path );
if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
request->uri.pathquery.size ) != 0 ) {
@@ -1428,7 +1387,7 @@ void gena_process_subscription_renewal_request(
HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE
/* CURRENTLY, ONLY SUPPORT ONE DEVICE */
if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
&device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1440,7 +1399,7 @@ void gena_process_subscription_renewal_request(
event_url_path.buf );
membuffer_destroy( &event_url_path );
// get subscription
/* get subscription */
if( service == NULL ||
!service->active ||
( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
@@ -1454,7 +1413,7 @@ void gena_process_subscription_renewal_request(
"Max Subscriptions allowed:%d\n",
service->TotalSubscriptions,
handle_info->MaxSubscriptions );
// too many subscriptions
/* too many subscriptions */
if( handle_info->MaxSubscriptions != -1 &&
service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
@@ -1462,25 +1421,25 @@ void gena_process_subscription_renewal_request(
HandleUnlock();
return;
}
// set the timeout
/* set the timeout */
if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
if( matchstr( timeout_hdr.buf, timeout_hdr.length,
"%iSecond-%d%0", &time_out ) == PARSE_OK ) {
//nothing
/*nothing */
} else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
0 ) {
time_out = -1; // inifinite timeout
time_out = -1; /* inifinite timeout */
} else {
time_out = DEFAULT_TIMEOUT; // default is > 1800 seconds
time_out = DEFAULT_TIMEOUT; /* default is > 1800 seconds */
}
}
// replace infinite timeout with max timeout, if possible
/* replace infinite timeout with max timeout, if possible */
if( handle_info->MaxSubscriptionTimeOut != -1 ) {
if( time_out == -1 ||
time_out > handle_info->MaxSubscriptionTimeOut ) {
@@ -1514,13 +1473,13 @@ void gena_process_unsubscribe_request(
memptr temp_hdr;
membuffer event_url_path;
// if a CALLBACK or NT header is present, then it is an error
/* if a CALLBACK or NT header is present, then it is an error */
if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
error_respond( info, HTTP_BAD_REQUEST, request );
return;
}
// get SID
/* get SID */
if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
temp_hdr.length > SID_SIZE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1529,7 +1488,7 @@ void gena_process_unsubscribe_request(
memcpy( sid, temp_hdr.buf, temp_hdr.length );
sid[temp_hdr.length] = '\0';
// lookup service by eventURL
/* lookup service by eventURL */
membuffer_init( &event_url_path );
if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
request->uri.pathquery.size ) != 0 ) {
@@ -1539,7 +1498,7 @@ void gena_process_unsubscribe_request(
HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE
/* CURRENTLY, ONLY SUPPORT ONE DEVICE */
if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
&device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1551,7 +1510,7 @@ void gena_process_unsubscribe_request(
event_url_path.buf );
membuffer_destroy( &event_url_path );
// validate service
/* validate service */
if( service == NULL ||
!service->active || GetSubscriptionSID( sid, service ) == NULL )
{
@@ -1561,7 +1520,7 @@ void gena_process_unsubscribe_request(
}
RemoveSubscriptionSID(sid, service);
error_respond(info, HTTP_OK, request); // success
error_respond(info, HTTP_OK, request); /* success */
HandleUnlock();
}

View File

@@ -46,7 +46,7 @@
#ifdef INCLUDE_CLIENT_APIS
#include <stdlib.h> // for calloc(), free()
#include <stdlib.h> /* for calloc(), free() */
struct SClientSubscription {
@@ -113,12 +113,12 @@ ClientSubscription *UpnpClientSubscription_dup(const ClientSubscription *p)
void UpnpClientSubscription_assign(ClientSubscription *q, const ClientSubscription *p)
{
if (q != p) {
// Do not copy RenewEventId
/* Do not copy RenewEventId */
((struct SClientSubscription *)q)->m_renewEventId = -1;
UpnpClientSubscription_set_SID(q, UpnpClientSubscription_get_SID(p));
UpnpClientSubscription_set_ActualSID(q, UpnpClientSubscription_get_ActualSID(p));
UpnpClientSubscription_set_EventURL(q, UpnpClientSubscription_get_EventURL(p));
// Do not copy m_next
/* Do not copy m_next */
((struct SClientSubscription *)q)->m_next = NULL;
}
}
@@ -238,8 +238,8 @@ void free_client_subscription(ClientSubscription *sub)
UpnpClientSubscription_strcpy_ActualSID(sub, "");
UpnpClientSubscription_strcpy_EventURL(sub, "");
if (renewEventId != -1) {
// do not remove timer event of copy
// invalid timer event id
/* do not remove timer event of copy */
/* invalid timer event id */
if (TimerThreadRemove(&gTimerThread, renewEventId, &tempJob) == 0) {
event = (upnp_timeout *)tempJob.arg;
free_upnp_timeout(event);

View File

@@ -57,7 +57,7 @@
#include "ThreadPool.h"
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
#include "upnpapi.h"
#include "util.h"
#include "upnputil.h"
#include <assert.h>
@@ -74,7 +74,7 @@
struct mserv_request_t {
/*! Connection handle. */
int connfd;
SOCKET connfd;
/*! . */
struct sockaddr_storage foreign_sockaddr;
};
@@ -92,7 +92,7 @@ typedef enum {
/*! . */
unsigned short miniStopSockPort;
uint16_t miniStopSockPort;
/*!
@@ -218,7 +218,7 @@ static void handle_request(
http_message_t *hmsg = NULL;
int timeout = HTTP_DEFAULT_TIMEOUT;
struct mserv_request_t *request = (struct mserv_request_t *)args;
int connfd = request->connfd;
SOCKET connfd = request->connfd;
UpnpPrintf( UPNP_INFO, MSERV, __FILE__, __LINE__,
"miniserver %d: READING\n", connfd );
@@ -269,7 +269,7 @@ error_handler:
*/
static UPNP_INLINE void schedule_request_job(
/*! [in] Socket Descriptor on which connection is accepted. */
int connfd,
SOCKET connfd,
/*! [in] Clients Address information. */
struct sockaddr *clientAddr)
{
@@ -301,26 +301,26 @@ static UPNP_INLINE void schedule_request_job(
}
#endif
static inline void fdset_if_valid(int sock, fd_set *set)
static UPNP_INLINE void fdset_if_valid(SOCKET sock, fd_set *set)
{
if (sock != -1) {
if (sock != INVALID_SOCKET) {
FD_SET(sock, set);
}
}
static void web_server_accept(int lsock, fd_set *set)
static void web_server_accept(SOCKET lsock, fd_set *set)
{
#ifdef INTERNAL_WEB_SERVER
int asock;
SOCKET asock;
socklen_t clientLen;
struct sockaddr_storage clientAddr;
char errorBuffer[ERROR_BUFFER_LEN];
if (lsock != -1 && FD_ISSET(lsock, set)) {
if (lsock != INVALID_SOCKET && FD_ISSET(lsock, set)) {
clientLen = sizeof(clientAddr);
asock = accept(lsock, (struct sockaddr *)&clientAddr,
&clientLen);
if (asock == -1) {
if (asock == INVALID_SOCKET) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"miniserver: Error in accept(): %s\n",
@@ -333,16 +333,16 @@ static void web_server_accept(int lsock, fd_set *set)
#endif /* INTERNAL_WEB_SERVER */
}
static void ssdp_read(int rsock, fd_set *set)
static void ssdp_read(SOCKET rsock, fd_set *set)
{
if (rsock != -1 && FD_ISSET(rsock, set)) {
if (rsock != INVALID_SOCKET && FD_ISSET(rsock, set)) {
readFromSSDPSocket(rsock);
}
}
static int receive_from_stopSock(int ssock, fd_set *set)
static int receive_from_stopSock(SOCKET ssock, fd_set *set)
{
int byteReceived;
ssize_t byteReceived;
socklen_t clientLen;
struct sockaddr_storage clientAddr;
char requestBuf[256];
@@ -387,9 +387,9 @@ static void RunMiniServer(
char errorBuffer[ERROR_BUFFER_LEN];
fd_set expSet;
fd_set rdSet;
int maxMiniSock;
SOCKET maxMiniSock;
int ret = 0;
int stopSock = 0;
SOCKET stopSock = 0;
maxMiniSock = 0;
maxMiniSock = max(maxMiniSock, miniSock->miniServerSock4);
@@ -417,11 +417,11 @@ static void RunMiniServer(
fdset_if_valid(miniSock->ssdpReqSock4, &rdSet);
fdset_if_valid(miniSock->ssdpReqSock6, &rdSet);
/* select() */
ret = select(maxMiniSock, &rdSet, NULL, &expSet, NULL);
if (ret == -1 && errno == EINTR) {
ret = select((int) maxMiniSock, &rdSet, NULL, &expSet, NULL);
if (ret == SOCKET_ERROR && errno == EINTR) {
continue;
}
if (ret == -1) {
if (ret == SOCKET_ERROR) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Error in select(): %s\n", errorBuffer);
@@ -460,16 +460,17 @@ static void RunMiniServer(
/*!
* \brief Returns port to which socket, sockfd, is bound.
*
* \return -1 on error; check errno, otherwise > 0 means port number.
* \return -1 on error; check errno. 0 if successfull.
*/
static int get_port(
/*! [in] Socket descriptor. */
int sockfd)
SOCKET sockfd,
/*! [out] The port value if successful, otherwise, untouched. */
uint16_t *port)
{
struct sockaddr_storage sockinfo;
socklen_t len;
int code;
int port = 0;
len = sizeof(sockinfo);
code = getsockname(sockfd, (struct sockaddr *)&sockinfo, &len);
@@ -477,14 +478,14 @@ static int get_port(
return -1;
}
if (sockinfo.ss_family == AF_INET) {
port = ntohs(((struct sockaddr_in*)&sockinfo)->sin_port);
*port = ntohs(((struct sockaddr_in*)&sockinfo)->sin_port);
} else if(sockinfo.ss_family == AF_INET6) {
port = ntohs(((struct sockaddr_in6*)&sockinfo)->sin6_port);
*port = ntohs(((struct sockaddr_in6*)&sockinfo)->sin6_port);
}
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"sockfd = %d, .... port = %d\n", sockfd, port);
"sockfd = %d, .... port = %u\n", sockfd, *port);
return port;
return 0;
}
@@ -509,10 +510,10 @@ static int get_miniserver_sockets(
MiniServerSockArray *out,
/*! [in] port on which the server is listening for incoming IPv4
* connections. */
unsigned short listen_port4,
uint16_t listen_port4,
/*! [in] port on which the server is listening for incoming IPv6
* connections. */
unsigned short listen_port6)
uint16_t listen_port6)
{
char errorBuffer[ERROR_BUFFER_LEN];
struct sockaddr_storage __ss_v4;
@@ -533,12 +534,12 @@ static int get_miniserver_sockets(
/* Create listen socket for IPv4/IPv6. An error here may indicate
* that we don't have an IPv4/IPv6 stack. */
listenfd4 = socket(AF_INET, SOCK_STREAM, 0);
if (listenfd4 == -1) {
if (listenfd4 == INVALID_SOCKET) {
return UPNP_E_OUTOF_SOCKET;
}
#ifdef UPNP_ENABLE_IPV6
listenfd6 = socket(AF_INET6, SOCK_STREAM, 0);
if (listenfd6 == -1) {
if (listenfd6 == INVALID_SOCKET) {
return UPNP_E_OUTOF_SOCKET;
}
#endif
@@ -572,11 +573,11 @@ static int get_miniserver_sockets(
* HOWEVER IT HAS BEEN SUGESTED FOR TCP SERVERS. */
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"get_miniserver_sockets: resuseaddr is set.\n");
if (listenfd4 != -1) {
if (listenfd4 != INVALID_SOCKET) {
sockError = setsockopt(listenfd4, SOL_SOCKET,
SO_REUSEADDR,
(const char *)&reuseaddr_on, sizeof (int));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
sock_close(listenfd4);
#ifdef UPNP_ENABLE_IPV6
sock_close(listenfd6);
@@ -587,7 +588,7 @@ static int get_miniserver_sockets(
sockError = bind(listenfd4,
(struct sockaddr *)&__ss_v4,
sizeof (__ss_v4));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
strerror_r(errno, errorBuffer,
ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV,
@@ -604,11 +605,11 @@ static int get_miniserver_sockets(
}
}
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != -1) {
if (listenfd6 != INVALID_SOCKET) {
sockError = setsockopt(listenfd6, SOL_SOCKET,
SO_REUSEADDR,
(const char *)&reuseaddr_on, sizeof (int));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
sock_close(listenfd4);
sock_close(listenfd6);
return UPNP_E_SOCKET_BIND;
@@ -617,7 +618,7 @@ static int get_miniserver_sockets(
sockError = bind(listenfd6,
(struct sockaddr *)&__ss_v6,
sizeof (__ss_v6));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
strerror_r(errno, errorBuffer,
ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV,
@@ -633,14 +634,14 @@ static int get_miniserver_sockets(
}
#endif /* IPv6 */
} else {
if (listenfd4 != -1) {
if (listenfd4 != INVALID_SOCKET) {
unsigned short orig_listen_port4 = listen_port4;
do {
serverAddr4->sin_port = htons(listen_port4++);
sockError = bind(listenfd4,
(struct sockaddr *)serverAddr4,
sizeof(*serverAddr4));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
#ifdef WIN32
errCode = WSAGetLastError();
#else
@@ -654,7 +655,7 @@ static int get_miniserver_sockets(
}
} while (errCode != 0 &&
listen_port4 >= orig_listen_port4);
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
strerror_r(errno, errorBuffer,
ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV,
@@ -671,14 +672,14 @@ static int get_miniserver_sockets(
}
}
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != -1) {
if (listenfd6 != INVALID_SOCKET) {
unsigned short orig_listen_port6 = listen_port6;
do {
serverAddr6->sin6_port = htons(listen_port6++);
sockError = bind(listenfd6,
(struct sockaddr *)serverAddr6,
sizeof(*serverAddr6));
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
#ifdef WIN32
errCode = WSAGetLastError();
#else
@@ -692,7 +693,7 @@ static int get_miniserver_sockets(
}
} while (errCode != 0 &&
listen_port6 >= orig_listen_port6);
if (sockError == -1) {
if (sockError == SOCKET_ERROR) {
strerror_r(errno, errorBuffer,
ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV,
@@ -710,9 +711,9 @@ static int get_miniserver_sockets(
}
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"get_miniserver_sockets: bind successful\n");
if (listenfd4 != -1) {
if (listenfd4 != INVALID_SOCKET) {
ret_code = listen(listenfd4, SOMAXCONN);
if (ret_code == -1) {
if (ret_code == SOCKET_ERROR) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"mserv start: Error in IPv4 listen(): %s\n",
@@ -723,8 +724,8 @@ static int get_miniserver_sockets(
#endif
return UPNP_E_LISTEN;
}
actual_port4 = get_port(listenfd4);
if (actual_port4 <= 0) {
ret_code = get_port(listenfd4, &actual_port4);
if (ret_code < 0) {
sock_close(listenfd4);
#ifdef UPNP_ENABLE_IPV6
sock_close(listenfd6);
@@ -734,9 +735,9 @@ static int get_miniserver_sockets(
out->miniServerPort4 = actual_port4;
}
#ifdef UPNP_ENABLE_IPV6
if (listenfd6 != -1) {
if (listenfd6 != INVALID_SOCKET) {
ret_code = listen(listenfd6, SOMAXCONN);
if (ret_code == -1) {
if (ret_code == SOCKET_ERROR) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, MSERV, __FILE__, __LINE__,
"mserv start: Error in IPv6 listen(): %s\n",
@@ -745,8 +746,8 @@ static int get_miniserver_sockets(
sock_close(listenfd6);
return UPNP_E_LISTEN;
}
actual_port6 = get_port(listenfd6);
if (actual_port6 <= 0) {
ret_code = get_port(listenfd6, &actual_port6);
if (ret_code <= 0) {
sock_close(listenfd4);
sock_close(listenfd6);
return UPNP_E_INTERNAL_ERROR;
@@ -779,11 +780,11 @@ static int get_miniserver_stopsock(
{
char errorBuffer[ERROR_BUFFER_LEN];
struct sockaddr_in stop_sockaddr;
int miniServerStopSock = 0;
SOCKET miniServerStopSock = 0;
int ret = 0;
miniServerStopSock = socket(AF_INET, SOCK_DGRAM, 0);
if (miniServerStopSock == -1) {
if (miniServerStopSock == INVALID_SOCKET) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_CRITICAL, MSERV, __FILE__, __LINE__,
"Error in socket(): %s\n", errorBuffer);
@@ -795,15 +796,15 @@ static int get_miniserver_stopsock(
stop_sockaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(miniServerStopSock, (struct sockaddr *)&stop_sockaddr,
sizeof(stop_sockaddr));
if (ret == -1) {
if (ret == SOCKET_ERROR) {
UpnpPrintf(UPNP_CRITICAL,
MSERV, __FILE__, __LINE__,
"Error in binding localhost!!!\n");
sock_close(miniServerStopSock);
return UPNP_E_SOCKET_BIND;
}
miniStopSockPort = get_port( miniServerStopSock );
if (miniStopSockPort <= 0) {
ret = get_port(miniServerStopSock, &miniStopSockPort);
if (ret < 0) {
sock_close(miniServerStopSock);
return UPNP_E_INTERNAL_ERROR;
}
@@ -813,19 +814,19 @@ static int get_miniserver_stopsock(
return UPNP_E_SUCCESS;
}
static inline void InitMiniServerSockArray(MiniServerSockArray *miniSocket)
static UPNP_INLINE void InitMiniServerSockArray(MiniServerSockArray *miniSocket)
{
miniSocket->miniServerSock4 = -1;
miniSocket->miniServerSock6 = -1;
miniSocket->miniServerStopSock = -1;
miniSocket->ssdpSock4 = -1;
miniSocket->ssdpSock6 = -1;
miniSocket->ssdpSock6UlaGua = -1;
miniSocket->stopPort = -1;
miniSocket->miniServerPort4 = -1;
miniSocket->miniServerPort6 = -1;
miniSocket->ssdpReqSock4 = -1;
miniSocket->ssdpReqSock6 = -1;
miniSocket->miniServerSock4 = INVALID_SOCKET;
miniSocket->miniServerSock6 = INVALID_SOCKET;
miniSocket->miniServerStopSock = INVALID_SOCKET;
miniSocket->ssdpSock4 = INVALID_SOCKET;
miniSocket->ssdpSock6 = INVALID_SOCKET;
miniSocket->ssdpSock6UlaGua = INVALID_SOCKET;
miniSocket->stopPort = 0;
miniSocket->miniServerPort4 = 0;
miniSocket->miniServerPort6 = 0;
miniSocket->ssdpReqSock4 = INVALID_SOCKET;
miniSocket->ssdpReqSock6 = INVALID_SOCKET;
}
int StartMiniServer(
@@ -924,11 +925,11 @@ int StartMiniServer(
int StopMiniServer()
{
char errorBuffer[ERROR_BUFFER_LEN];
int socklen = sizeof (struct sockaddr_in);
socklen_t socklen = sizeof (struct sockaddr_in);
SOCKET sock;
struct sockaddr_in ssdpAddr;
char buf[256] = "ShutDown";
int bufLen = strlen(buf);
size_t bufLen = strlen(buf);
if(gMServState == MSERV_RUNNING) {
gMServState = MSERV_STOPPING;
@@ -936,7 +937,7 @@ int StopMiniServer()
return 0;
}
sock = socket(AF_INET, SOCK_DGRAM, 0);
if (sock == -1) {
if (sock == INVALID_SOCKET) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP_SERVER: StopSSDPServer: Error in socket() %s\n",
@@ -947,8 +948,8 @@ int StopMiniServer()
ssdpAddr.sin_family = AF_INET;
ssdpAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
ssdpAddr.sin_port = htons(miniStopSockPort);
sendto(sock, buf, bufLen, 0, (struct sockaddr *)&ssdpAddr,
socklen);
sendto(sock, buf, bufLen, 0,
(struct sockaddr *)&ssdpAddr, socklen);
usleep(1000);
if (gMServState == MSERV_IDLE) {
break;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,71 +1,60 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/************************************************************************
* Purpose: This file a function to extract the header information from *
* an http message and then matches the data with XML data. *
************************************************************************/
/*!
* \file
*
* Purpose: This file a function to extract the header information from
* an http message and then matches the data with XML data.
*/
#include "config.h"
#include <assert.h>
#include "util.h"
#include "upnputil.h"
#include "membuffer.h"
#include "httpparser.h"
#include "statcodes.h"
#include "parsetools.h"
/************************************************************************
* Function: has_xml_content_type
*
* Parameters:
* IN http_message_t* hmsg ; HTTP Message object
*
* Description: Find the header from the HTTP message and match the
* header for xml data.
*
* Returns:
* BOOLEAN
************************************************************************/
xboolean
has_xml_content_type( IN http_message_t * hmsg )
int has_xml_content_type(http_message_t *hmsg)
{
memptr hdr_value;
assert( hmsg );
assert(hmsg);
// find 'content-type' header which must have text/xml
if( httpmsg_find_hdr( hmsg, HDR_CONTENT_TYPE, &hdr_value ) != NULL &&
matchstr( hdr_value.buf, hdr_value.length,
"%itext%w/%wxml" ) == PARSE_OK ) {
/* find 'content-type' header which must have text/xml */
if (httpmsg_find_hdr(hmsg, HDR_CONTENT_TYPE, &hdr_value) &&
matchstr(hdr_value.buf, hdr_value.length, "%itext%w/%wxml" ) == PARSE_OK) {
return TRUE;
}
return FALSE;
}

View File

@@ -1,33 +1,33 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/************************************************************************
* Purpose: This file defines status codes, buffers to store the status *
@@ -37,7 +37,7 @@
#include "config.h"
#include <stdio.h>
#include <string.h>
#include "util.h"
#include "upnputil.h"
#include "statcodes.h"
#ifdef WIN32
@@ -96,7 +96,7 @@ static const char *Http5xxStr =
"Service Unavailable\0"
"Gateway Timeout\0" "HTTP Version Not Supported\0";
static xboolean gInitialized = FALSE;
static int gInitialized = FALSE;
/************************************************************************
************************* Functions *************************************
@@ -128,7 +128,7 @@ init_table( IN const char *encoded_str,
for( i = 0; i < tbl_size; i++ ) {
table[i] = s;
s += strlen( s ) + 1; // next entry
s += strlen( s ) + 1; /* next entry */
}
}
@@ -153,7 +153,7 @@ init_tables( void )
init_table( Http4xxStr, Http4xxCodes, NUM_4XX_CODES );
init_table( Http5xxStr, Http5xxCodes, NUM_5XX_CODES );
gInitialized = TRUE; // mark only after complete
gInitialized = TRUE; /* mark only after complete */
}
/************************************************************************

View File

@@ -51,7 +51,7 @@
#include "unixutil.h"
#include "upnp.h"
#include "upnpapi.h"
#include "util.h"
#include "upnputil.h"
#include "VirtualDir.h"
#include <assert.h>
@@ -309,28 +309,25 @@ static UPNP_INLINE int get_content_type(
const char *extension;
const char *type;
const char *subtype;
xboolean ctype_found = FALSE;
int ctype_found = FALSE;
char *temp = NULL;
int length = 0;
size_t length = 0;
(*content_type) = NULL;
// get ext
/* get ext */
extension = strrchr(filename, '.');
if (extension != NULL) {
if (search_extension(extension + 1, &type, &subtype) == 0) {
ctype_found = TRUE;
}
}
if (!ctype_found) {
// unknown content type
/* unknown content type */
type = gMediaTypes[APPLICATION_INDEX];
subtype = "octet-stream";
}
length = strlen(type) + strlen("/") + strlen(subtype) + 1;
temp = (char *)malloc(length);
temp = malloc(length);
if (!temp) {
return UPNP_E_OUTOF_MEMORY;
}
@@ -341,7 +338,6 @@ static UPNP_INLINE int get_content_type(
if (!content_type) {
return UPNP_E_OUTOF_MEMORY;
}
return 0;
}
@@ -364,7 +360,7 @@ static UPNP_INLINE void glob_alias_init(void)
*
* \return BOOLEAN.
*/
static UPNP_INLINE xboolean is_valid_alias(
static UPNP_INLINE int is_valid_alias(
/*! [in] XML alias object. */
const struct xml_alias_t *alias)
{
@@ -395,13 +391,13 @@ static void alias_release(
struct xml_alias_t *alias)
{
ithread_mutex_lock(&gWebMutex);
// ignore invalid alias
/* ignore invalid alias */
if (!is_valid_alias(alias)) {
ithread_mutex_unlock(&gWebMutex);
return;
}
assert(alias->ct > 0);
*alias->ct = *alias->ct - 1;
assert(*alias->ct > 0);
*alias->ct -= 1;
if (*alias->ct <= 0) {
membuffer_destroy(&alias->doc);
membuffer_destroy(&alias->name);
@@ -419,7 +415,7 @@ int web_server_set_alias(const char *alias_name,
alias_release(&gAliasDoc);
if (alias_name == NULL) {
// don't serve aliased doc anymore
/* don't serve aliased doc anymore */
return 0;
}
assert(alias_content != NULL);
@@ -427,24 +423,24 @@ int web_server_set_alias(const char *alias_name,
membuffer_init(&alias.name);
alias.ct = NULL;
do {
// insert leading /, if missing
/* insert leading /, if missing */
if (*alias_name != '/') {
if (membuffer_assign_str(&alias.name, "/") != 0) {
break; // error; out of mem
break; /* error; out of mem */
}
}
ret_code = membuffer_append_str(&alias.name, alias_name);
if (ret_code != 0) {
break; // error
break; /* error */
}
if ((alias.ct = (int *)malloc(sizeof(int))) == NULL) {
break; // error
break; /* error */
}
*alias.ct = 1;
membuffer_attach(&alias.doc, (char *)alias_content,
alias_content_length);
alias.last_modified = last_modified;
// save in module var
/* save in module var */
ithread_mutex_lock(&gWebMutex);
gAliasDoc = alias;
ithread_mutex_unlock(&gWebMutex);
@@ -452,8 +448,8 @@ int web_server_set_alias(const char *alias_name,
return 0;
} while (FALSE);
// error handler
// free temp alias
/* error handler */
/* free temp alias */
membuffer_destroy(&alias.name);
membuffer_destroy(&alias.doc);
free(alias.ct);
@@ -464,13 +460,13 @@ int web_server_init()
{
int ret = 0;
if (bWebServerState == WEB_SERVER_DISABLED) {
// decode media list
/* decode media list */
media_list_init();
membuffer_init(&gDocumentRootDir);
glob_alias_init();
pVirtualDirList = NULL;
// Initialize callbacks
/* Initialize callbacks */
virtualDirCallback.get_info = NULL;
virtualDirCallback.open = NULL;
virtualDirCallback.read = NULL;
@@ -541,7 +537,7 @@ static int get_file_info(
return -1;
}
// check readable
/* check readable */
fp = fopen(filename, "r");
info->is_readable = (fp != NULL);
if (fp) {
@@ -563,16 +559,16 @@ static int get_file_info(
int web_server_set_root_dir(const char *root_dir)
{
int index;
size_t index;
int ret;
ret = membuffer_assign_str(&gDocumentRootDir, root_dir);
if (ret != 0) {
return ret;
}
// remove trailing '/', if any
/* remove trailing '/', if any */
if (gDocumentRootDir.length > 0) {
index = gDocumentRootDir.length - 1; // last char
index = gDocumentRootDir.length - 1; /* last char */
if (gDocumentRootDir.buf[index] == '/') {
membuffer_delete(&gDocumentRootDir, index, 1);
}
@@ -589,7 +585,7 @@ int web_server_set_root_dir(const char *root_dir)
* \li \c TRUE - On Success
* \li \c FALSE if request is not an alias
*/
static UPNP_INLINE xboolean get_alias(
static UPNP_INLINE int get_alias(
/*! [in] request file passed in to be compared with. */
const char *request_file,
/*! [out] xml alias object which has a file name stored. */
@@ -600,8 +596,8 @@ static UPNP_INLINE xboolean get_alias(
{
int cmp = strcmp(alias->name.buf, request_file);
if (cmp == 0) {
// fill up info
info->file_length = alias->doc.length;
/* fill up info */
info->file_length = (off_t)alias->doc.length;
info->is_readable = TRUE;
info->is_directory = FALSE;
info->last_modified = alias->last_modified;
@@ -614,32 +610,36 @@ static UPNP_INLINE xboolean get_alias(
* \brief Compares filePath with paths from the list of virtual directory
* lists.
*
* \return BOOLEAN
* \return BOOLEAN.
*/
static int isFileInVirtualDir(
/*! [in] Directory path to be tested for virtual directory. */
char *filePath)
{
virtualDirList *pCurVirtualDir;
int webDirLen;
size_t webDirLen;
pCurVirtualDir = pVirtualDirList;
while (pCurVirtualDir != NULL) {
webDirLen = strlen(pCurVirtualDir->dirName);
if (webDirLen) {
if (pCurVirtualDir->dirName[webDirLen - 1] == '/') {
if (strncmp(pCurVirtualDir->dirName, filePath, webDirLen) == 0)
return TRUE;
if (strncmp(pCurVirtualDir->dirName, filePath,
webDirLen) == 0)
return !0;
} else {
if (strncmp(pCurVirtualDir->dirName, filePath, webDirLen) == 0 &&
if (strncmp(pCurVirtualDir->dirName, filePath,
webDirLen) == 0 &&
(filePath[webDirLen] == '/' ||
filePath[webDirLen] == '\0' ||
filePath[webDirLen] == '?'))
return TRUE;
return !0;
}
}
pCurVirtualDir = pCurVirtualDir->next;
}
return FALSE;
return 0;
}
/*!
@@ -650,7 +650,7 @@ static void ToUpperCase(
char *s)
{
while (*s) {
*s = toupper(*s);
*s = (char)toupper(*s);
++s;
}
}
@@ -664,13 +664,12 @@ static char *StrStr(
/*! Input string. */
char *s1,
/*! Input sub-string. */
char *s2)
const char *s2)
{
char *Str1;
char *Str2;
char *Ptr;
const char *Ptr;
char *ret = NULL;
int Pos;
Str1 = strdup(s1);
if (!Str1)
@@ -685,8 +684,7 @@ static char *StrStr(
if (!Ptr) {
ret = NULL;
} else {
Pos = Ptr - Str1;
ret = s1 + Pos;
ret = s1 + (Ptr - Str1);
}
free(Str2);
@@ -705,9 +703,10 @@ static char *StrTok(
/*! String containing the token. */
char **Src,
/*! Set of delimiter characters. */
char *Del)
const char *Del)
{
char *TmpPtr, *RetPtr;
char *TmpPtr;
char *RetPtr;
if (*Src != NULL) {
RetPtr = *Src;
@@ -794,7 +793,8 @@ static int CreateHTTPRangeResponseHeader(
struct SendInstruction *Instr)
{
off_t FirstByte, LastByte;
char *RangeInput, *Ptr;
char *RangeInput;
char *Ptr;
Instr->IsRangeActive = 1;
Instr->ReadSendSize = FileLength;
@@ -896,7 +896,7 @@ static int CheckOtherHTTPHeaders(
{
http_header_t *header;
ListNode *node;
//NNS: dlist_node* node;
/*NNS: dlist_node* node; */
int index, RetCode = HTTP_OK;
char *TmpBuf;
@@ -906,7 +906,7 @@ static int CheckOtherHTTPHeaders(
node = ListHead(&Req->headers);
while (node != NULL) {
header = (http_header_t *) node->item;
// find header type.
/* find header type. */
index = map_str_to_int((const char *)header->name.buf,
header->name.length, Http_Header_Names,
NUM_HTTP_HEADER_NAMES, FALSE);
@@ -955,23 +955,23 @@ static int CheckOtherHTTPHeaders(
header.value is the value.
*/
/*
case HDR_CONTENT_TYPE: //return 1;
case HDR_CONTENT_LANGUAGE://return 1;
case HDR_LOCATION: //return 1;
case HDR_CONTENT_LOCATION://return 1;
case HDR_ACCEPT: //return 1;
case HDR_ACCEPT_CHARSET://return 1;
case HDR_USER_AGENT: break;//return 1;
case HDR_CONTENT_TYPE: return 1;
case HDR_CONTENT_LANGUAGE:return 1;
case HDR_LOCATION: return 1;
case HDR_CONTENT_LOCATION:return 1;
case HDR_ACCEPT: return 1;
case HDR_ACCEPT_CHARSET: return 1;
case HDR_USER_AGENT: return 1;
*/
//Header check for encoding
/*Header check for encoding */
/*
case HDR_ACCEPT_RANGE: //Server capability.
case HDR_CONTENT_RANGE://Response.
case HDR_ACCEPT_RANGE:
case HDR_CONTENT_RANGE:
case HDR_IF_RANGE:
*/
//Header check for encoding
/*Header check for encoding */
/*
case HDR_ACCEPT_ENCODING:
if(StrStr(TmpBuf, "identity"))
@@ -980,7 +980,7 @@ static int CheckOtherHTTPHeaders(
}
else return -1;
case HDR_CONTENT_ENCODING:
case HDR_TRANSFER_ENCODING: //Response
case HDR_TRANSFER_ENCODING:
*/
break;
}
@@ -1020,13 +1020,13 @@ static int process_request(
char *request_doc;
struct File_Info finfo;
xboolean using_alias;
xboolean using_virtual_dir;
int using_alias;
int using_virtual_dir;
uri_type *url;
char *temp_str;
const char *temp_str;
int resp_major;
int resp_minor;
xboolean alias_grabbed;
int alias_grabbed;
size_t dummy;
const char *extra_headers = NULL;
@@ -1036,22 +1036,22 @@ static int process_request(
req->method == HTTPMETHOD_HEAD ||
req->method == HTTPMETHOD_POST ||
req->method == HTTPMETHOD_SIMPLEGET);
// init
/* init */
request_doc = NULL;
finfo.content_type = NULL;
alias_grabbed = FALSE;
err_code = HTTP_INTERNAL_SERVER_ERROR; // default error
err_code = HTTP_INTERNAL_SERVER_ERROR; /* default error */
using_virtual_dir = FALSE;
using_alias = FALSE;
http_CalcResponseVersion(req->major_version, req->minor_version,
&resp_major, &resp_minor);
//
// remove dots
//
/* */
/* remove dots */
/* */
request_doc = malloc(url->pathquery.size + 1);
if (request_doc == NULL) {
goto error_handler; // out of mem
goto error_handler; /* out of mem */
}
memcpy(request_doc, url->pathquery.buff, url->pathquery.size);
request_doc[url->pathquery.size] = '\0';
@@ -1063,7 +1063,7 @@ static int process_request(
goto error_handler;
}
if (*request_doc != '/') {
// no slash
/* no slash */
err_code = HTTP_BAD_REQUEST;
goto error_handler;
}
@@ -1078,7 +1078,6 @@ static int process_request(
if (is_valid_alias(&gAliasDoc)) {
alias_grab(alias);
alias_grabbed = TRUE;
using_alias = get_alias(request_doc, alias, &finfo);
if (using_alias == TRUE) {
finfo.content_type =
@@ -1092,13 +1091,13 @@ static int process_request(
}
if (using_virtual_dir) {
if (req->method != HTTPMETHOD_POST) {
// get file info
/* get file info */
if (virtualDirCallback.
get_info(filename->buf, &finfo) != 0) {
err_code = HTTP_NOT_FOUND;
goto error_handler;
}
// try index.html if req is a dir
/* try index.html if req is a dir */
if (finfo.is_directory) {
if (filename->buf[filename->length - 1] == '/') {
temp_str = "index.html";
@@ -1109,7 +1108,7 @@ static int process_request(
0) {
goto error_handler;
}
// get info
/* get info */
if ((virtualDirCallback.
get_info(filename->buf,
&finfo) != UPNP_E_SUCCESS)
@@ -1118,42 +1117,42 @@ static int process_request(
goto error_handler;
}
}
// not readable
/* not readable */
if (!finfo.is_readable) {
err_code = HTTP_FORBIDDEN;
goto error_handler;
}
// finally, get content type
// if ( get_content_type(filename->buf, &content_type) != 0 )
//{
// goto error_handler;
// }
/* finally, get content type */
/* if ( get_content_type(filename->buf, &content_type) != 0 ) */
/*{ */
/* goto error_handler; */
/* } */
}
} else if (!using_alias) {
if (gDocumentRootDir.length == 0) {
goto error_handler;
}
//
// get file name
//
/* */
/* get file name */
/* */
// filename str
/* filename str */
if (membuffer_assign_str(filename, gDocumentRootDir.buf) != 0 ||
membuffer_append_str(filename, request_doc) != 0) {
goto error_handler; // out of mem
goto error_handler; /* out of mem */
}
// remove trailing slashes
/* remove trailing slashes */
while (filename->length > 0 &&
filename->buf[filename->length - 1] == '/') {
membuffer_delete(filename, filename->length - 1, 1);
}
if (req->method != HTTPMETHOD_POST) {
// get info on file
/* get info on file */
if (get_file_info(filename->buf, &finfo) != 0) {
err_code = HTTP_NOT_FOUND;
goto error_handler;
}
// try index.html if req is a dir
/* try index.html if req is a dir */
if (finfo.is_directory) {
if (filename->buf[filename->length - 1] == '/') {
temp_str = "index.html";
@@ -1164,27 +1163,27 @@ static int process_request(
0) {
goto error_handler;
}
// get info
/* get info */
if (get_file_info(filename->buf, &finfo) != 0 ||
finfo.is_directory) {
err_code = HTTP_NOT_FOUND;
goto error_handler;
}
}
// not readable
/* not readable */
if (!finfo.is_readable) {
err_code = HTTP_FORBIDDEN;
goto error_handler;
}
}
// finally, get content type
// if ( get_content_type(filename->buf, &content_type) != 0 )
// {
// goto error_handler;
// }
/* finally, get content type */
/* if ( get_content_type(filename->buf, &content_type) != 0 ) */
/* { */
/* goto error_handler; */
/* } */
}
RespInstr->ReadSendSize = finfo.file_length;
// Check other header field.
/* Check other header field. */
if ((err_code =
CheckOtherHTTPHeaders(req, RespInstr,
finfo.file_length)) != HTTP_OK) {
@@ -1200,58 +1199,58 @@ static int process_request(
extra_headers = "";
}
if (RespInstr->IsRangeActive && RespInstr->IsChunkActive) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
/* Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT */
/* Transfer-Encoding: chunked */
if (http_MakeMessage(headers, resp_major, resp_minor,
"R" "T" "GKLD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
finfo.content_type, // content type
RespInstr, // range info
RespInstr, // language info
HTTP_PARTIAL_CONTENT, /* status code */
finfo.content_type, /* content type */
RespInstr, /* range info */
RespInstr, /* language info */
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT, extra_headers) != 0) {
goto error_handler;
}
} else if (RespInstr->IsRangeActive && !RespInstr->IsChunkActive) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
/* Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT */
/* Transfer-Encoding: chunked */
if (http_MakeMessage(headers, resp_major, resp_minor,
"R" "N" "T" "GLD" "s" "tcS" "Xc" "sCc",
HTTP_PARTIAL_CONTENT, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
RespInstr, // range info
RespInstr, // language info
HTTP_PARTIAL_CONTENT, /* status code */
RespInstr->ReadSendSize, /* content length */
finfo.content_type, /* content type */
RespInstr, /* range info */
RespInstr, /* language info */
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT, extra_headers) != 0) {
goto error_handler;
}
} else if (!RespInstr->IsRangeActive && RespInstr->IsChunkActive) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
/* Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT */
/* Transfer-Encoding: chunked */
if (http_MakeMessage(headers, resp_major, resp_minor,
"RK" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
RespInstr, // language info
HTTP_OK, /* status code */
finfo.content_type, /* content type */
RespInstr, /* language info */
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT, extra_headers) != 0) {
goto error_handler;
}
} else {
// !RespInstr->IsRangeActive && !RespInstr->IsChunkActive
/* !RespInstr->IsRangeActive && !RespInstr->IsChunkActive */
if (RespInstr->ReadSendSize >= 0) {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
/* Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT */
/* Transfer-Encoding: chunked */
if (http_MakeMessage(headers, resp_major, resp_minor,
"R" "N" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, // status code
RespInstr->ReadSendSize, // content length
finfo.content_type, // content type
RespInstr, // language info
HTTP_OK, /* status code */
RespInstr->ReadSendSize, /* content length */
finfo.content_type, /* content type */
RespInstr, /* language info */
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1259,13 +1258,13 @@ static int process_request(
goto error_handler;
}
} else {
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
// Transfer-Encoding: chunked
/* Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT */
/* Transfer-Encoding: chunked */
if (http_MakeMessage(headers, resp_major, resp_minor,
"R" "TLD" "s" "tcS" "b" "Xc" "sCc",
HTTP_OK, // status code
finfo.content_type, // content type
RespInstr, // language info
"R" "TLD" "s" "tcS" "Xc" "sCc",
HTTP_OK, /* status code */
finfo.content_type, /* content type */
RespInstr, /* language info */
"LAST-MODIFIED: ",
&finfo.last_modified,
X_USER_AGENT,
@@ -1277,16 +1276,16 @@ static int process_request(
if (req->method == HTTPMETHOD_HEAD) {
*rtype = RESP_HEADERS;
} else if (using_alias) {
// GET xml
/* GET xml */
*rtype = RESP_XMLDOC;
} else if (using_virtual_dir) {
*rtype = RESP_WEBDOC;
} else {
// GET filename
/* GET filename */
*rtype = RESP_FILEDOC;
}
// simple get http 0.9 as specified in http 1.0
// don't send headers
/* simple get http 0.9 as specified in http 1.0 */
/* don't send headers */
if (req->method == HTTPMETHOD_SIMPLEGET) {
membuffer_destroy(headers);
}
@@ -1322,14 +1321,13 @@ static int http_RecvPostMessage(
* is a virtual file or not. */
struct SendInstruction *Instr)
{
unsigned int Data_Buf_Size = 1024;
size_t Data_Buf_Size = 1024;
char Buf[1024];
int Timeout = 0;
long Num_Write = 0;
FILE *Fp;
parse_status_t status = PARSE_OK;
xboolean ok_on_close = FALSE;
unsigned int entity_offset = 0;
int ok_on_close = FALSE;
size_t entity_offset = 0;
int num_read = 0;
int ret_code = 0;
@@ -1346,37 +1344,37 @@ static int http_RecvPostMessage(
}
parser->position = POS_ENTITY;
do {
// first parse what has already been gotten
/* first parse what has already been gotten */
if (parser->position != POS_COMPLETE) {
status = parser_parse_entity(parser);
}
if (status == PARSE_INCOMPLETE_ENTITY) {
// read until close
/* read until close */
ok_on_close = TRUE;
} else if ((status != PARSE_SUCCESS)
&& (status != PARSE_CONTINUE_1)
&& (status != PARSE_INCOMPLETE)) {
// error
/* error */
fclose(Fp);
return HTTP_BAD_REQUEST;
}
// read more if necessary entity
/* read more if necessary entity */
while (entity_offset + Data_Buf_Size > parser->msg.entity.length &&
parser->position != POS_COMPLETE) {
num_read = sock_read(info, Buf, sizeof(Buf), &Timeout);
if (num_read > 0) {
// append data to buffer
/* append data to buffer */
ret_code = membuffer_append(&parser->msg.msg,
Buf, num_read);
Buf, (size_t)num_read);
if (ret_code != 0) {
// set failure status
/* set failure status */
parser->http_error_code =
HTTP_INTERNAL_SERVER_ERROR;
return HTTP_INTERNAL_SERVER_ERROR;
}
status = parser_parse_entity(parser);
if (status == PARSE_INCOMPLETE_ENTITY) {
// read until close
/* read until close */
ok_on_close = TRUE;
} else if ((status != PARSE_SUCCESS)
&& (status != PARSE_CONTINUE_1)
@@ -1391,7 +1389,7 @@ static int http_RecvPostMessage(
print_http_headers(&parser->msg);
parser->position = POS_COMPLETE;
} else {
// partial msg or response
/* partial msg or response */
parser->http_error_code = HTTP_BAD_REQUEST;
return HTTP_BAD_REQUEST;
}
@@ -1408,14 +1406,14 @@ static int http_RecvPostMessage(
Data_Buf_Size);
entity_offset += Data_Buf_Size;
if (Instr->IsVirtualFile) {
Num_Write = virtualDirCallback.write(Fp, Buf, Data_Buf_Size);
if (Num_Write < 0) {
int n = virtualDirCallback.write(Fp, Buf, Data_Buf_Size);
if (n < 0) {
virtualDirCallback.close(Fp);
return HTTP_INTERNAL_SERVER_ERROR;
}
} else {
Num_Write = fwrite(Buf, 1, Data_Buf_Size, Fp);
if (Num_Write < 0) {
size_t n = fwrite(Buf, 1, Data_Buf_Size, Fp);
if (n != Data_Buf_Size) {
fclose(Fp);
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -1428,27 +1426,6 @@ static int http_RecvPostMessage(
fclose(Fp);
}
/*
while(TotalByteReceived < Instr->RecvWriteSize &&
(NumReceived = sock_read(info,Buf, Data_Buf_Size,&Timeout) ) > 0 )
{
TotalByteReceived = TotalByteReceived + NumReceived;
Num_Write = virtualDirCallback.write(Fp, Buf, NumReceived);
if (ferror(Fp))
{
virtualDirCallback.close(Fp);
return HTTP_INTERNAL_SERVER_ERROR;
}
}
if(TotalByteReceived < Instr->RecvWriteSize)
{
return HTTP_INTERNAL_SERVER_ERROR;
}
virtualDirCallback.close(Fp);
}
*/
return HTTP_OK;
}
@@ -1463,72 +1440,70 @@ void web_server_callback(http_parser_t *parser, INOUT http_message_t *req,
struct xml_alias_t xmldoc;
struct SendInstruction RespInstr;
//Initialize instruction header.
/*Initialize instruction header. */
RespInstr.IsVirtualFile = 0;
RespInstr.IsChunkActive = 0;
RespInstr.IsRangeActive = 0;
RespInstr.IsTrailers = 0;
memset(RespInstr.AcceptLanguageHeader, 0,
sizeof(RespInstr.AcceptLanguageHeader));
// init
/* init */
membuffer_init(&headers);
membuffer_init(&filename);
//Process request should create the different kind of header depending on the
//the type of request.
/*Process request should create the different kind of header depending on the */
/*the type of request. */
ret = process_request(req, &rtype, &headers, &filename, &xmldoc,
&RespInstr);
if (ret != UPNP_E_SUCCESS) {
// send error code
/* send error code */
http_SendStatusResponse(info, ret, req->major_version,
req->minor_version);
} else {
// send response
/* send response */
switch (rtype) {
case RESP_FILEDOC:
// send file, I = further instruction to send data.
http_SendMessage(info, &timeout, "Ibf", &RespInstr,
http_SendMessage(info, &timeout, "Ibf",
&RespInstr,
headers.buf, headers.length,
filename.buf);
break;
case RESP_XMLDOC:
// send xmldoc , I = further instruction to send data.
http_SendMessage(info, &timeout,
"Ibb", &RespInstr,
http_SendMessage(info, &timeout, "Ibb",
&RespInstr,
headers.buf, headers.length,
xmldoc.doc.buf, xmldoc.doc.length);
alias_release(&xmldoc);
break;
case RESP_WEBDOC:
//, I = further instruction to send data.
/*
http_SendVirtualDirDoc( info, &timeout, "Ibf",&RespInstr,
/*http_SendVirtualDirDoc(info, &timeout, "Ibf",
&RespInstr,
headers.buf, headers.length,
filename.buf );
*/
http_SendMessage(info, &timeout,
"Ibf", &RespInstr,
filename.buf);*/
http_SendMessage(info, &timeout, "Ibf",
&RespInstr,
headers.buf, headers.length,
filename.buf);
break;
case RESP_HEADERS:
// headers only
http_SendMessage(info, &timeout,
"b",
/* headers only */
http_SendMessage(info, &timeout, "b",
headers.buf, headers.length);
break;
case RESP_POST:
// headers only
/* headers only */
ret = http_RecvPostMessage(parser, info, filename.buf,
&RespInstr);
// Send response.
/* Send response. */
http_MakeMessage(&headers, 1, 1,
"RTLSXcCc",
ret, "text/html", X_USER_AGENT);
http_SendMessage(info, &timeout, "b", headers.buf,
headers.length);
http_SendMessage(info, &timeout, "b",
headers.buf, headers.length);
break;
default:
UpnpPrintf(UPNP_INFO, HTTP, __FILE__, __LINE__,
"webserver: Invalid response type received.\n");
assert(0);
}
}

View File

@@ -107,53 +107,50 @@ static int sock_read_write(
/*! Buffer to get data to or send data from. */
OUT char *buffer,
/*! Size of the buffer. */
IN size_t bufsize,
IN int bufsize,
/*! timeout value. */
IN int *timeoutSecs,
/*! Boolean value specifying read or write option. */
IN xboolean bRead)
IN int bRead)
{
int retCode;
fd_set readSet;
fd_set writeSet;
struct timeval timeout;
int numBytes;
long numBytes;
time_t start_time = time(NULL);
SOCKET sockfd = info->socket;
long bytes_sent = 0, byte_left = 0, num_written;
long bytes_sent = 0;
long byte_left = 0;
long num_written;
if (*timeoutSecs < 0) {
if (*timeoutSecs < 0)
return UPNP_E_TIMEDOUT;
}
FD_ZERO(&readSet);
FD_ZERO(&writeSet);
if (bRead) {
if (bRead)
FD_SET(sockfd, &readSet);
} else {
else
FD_SET(sockfd, &writeSet);
}
timeout.tv_sec = *timeoutSecs;
timeout.tv_usec = 0;
while (TRUE) {
if (*timeoutSecs == 0) {
if (*timeoutSecs == 0)
retCode = select(sockfd + 1, &readSet, &writeSet,
NULL, NULL);
} else {
else
retCode = select(sockfd + 1, &readSet, &writeSet,
NULL, &timeout);
}
if (retCode == 0) {
if (retCode == 0)
return UPNP_E_TIMEDOUT;
}
if (retCode == -1) {
if (errno == EINTR)
continue;
return UPNP_E_SOCKET_ERROR;
} else {
} else
/* read or write. */
break;
}
}
#ifdef SO_NOSIGPIPE
{
int old;
@@ -164,21 +161,21 @@ static int sock_read_write(
#endif
if (bRead) {
/* read data. */
numBytes = recv(sockfd, buffer, bufsize, MSG_NOSIGNAL);
numBytes = (long)recv(sockfd, buffer, (size_t)bufsize, MSG_NOSIGNAL);
} else {
byte_left = bufsize;
bytes_sent = 0;
while (byte_left > 0) {
/* write data. */
num_written = send(sockfd,
buffer + bytes_sent, byte_left,
buffer + bytes_sent, (size_t)byte_left,
MSG_DONTROUTE | MSG_NOSIGNAL);
if (num_written == -1) {
#ifdef SO_NOSIGPIPE
setsockopt(sockfd, SOL_SOCKET,
SO_NOSIGPIPE, &old, olen);
#endif
return num_written;
return (int)num_written;
}
byte_left = byte_left - num_written;
bytes_sent += num_written;
@@ -189,26 +186,24 @@ static int sock_read_write(
setsockopt(sockfd, SOL_SOCKET, SO_NOSIGPIPE, &old, olen);
}
#endif
if (numBytes < 0) {
if (numBytes < 0)
return UPNP_E_SOCKET_ERROR;
}
/* subtract time used for reading/writing. */
if (*timeoutSecs != 0) {
*timeoutSecs -= time(NULL) - start_time;
}
if (*timeoutSecs != 0)
*timeoutSecs -= (int)(time(NULL) - start_time);
return numBytes;
return (int)numBytes;
}
int sock_read(IN SOCKINFO *info, OUT char *buffer, IN size_t bufsize,
int sock_read(IN SOCKINFO *info, OUT char *buffer, IN int bufsize,
INOUT int *timeoutSecs)
{
return sock_read_write(info, buffer, bufsize, timeoutSecs, TRUE);
}
int sock_write(IN SOCKINFO *info, IN char *buffer, IN size_t bufsize,
int sock_write(IN SOCKINFO *info, IN const char *buffer, IN int bufsize,
INOUT int *timeoutSecs)
{
return sock_read_write(info, buffer, bufsize, timeoutSecs, FALSE);
return sock_read_write(info, (char *)buffer, bufsize, timeoutSecs, FALSE);
}

View File

@@ -128,13 +128,12 @@ int is_escaped(
}
}
int replace_escaped(char *in, int index, size_t *max)
int replace_escaped(char *in, size_t index, size_t *max)
{
int tempInt = 0;
char tempChar = 0;
int i = 0;
int j = 0;
size_t i = 0;
size_t j = 0;
if (in[index] == '%' && isxdigit(in[index + 1]) && isxdigit(in[index + 2])) {
/* Note the "%2x", makes sure that we convert a maximum of two
@@ -142,8 +141,7 @@ int replace_escaped(char *in, int index, size_t *max)
if (sscanf(&in[index + 1], "%2x", &tempInt) != 1) {
return 0;
}
tempChar = ( char )tempInt;
tempChar = (char)tempInt;
for (i = index + 3, j = index; j < *max; i++, j++) {
in[j] = tempChar;
if (i < *max) {
@@ -166,15 +164,15 @@ int replace_escaped(char *in, int index, size_t *max)
*
* \return
*/
static int parse_uric(
static size_t parse_uric(
/*! [in] String of characters. */
const char *in,
/*! [in] Maximum limit. */
int max,
size_t max,
/*! [out] Token object where the string of characters is copied. */
token *out)
{
int i = 0;
size_t i = 0;
while (i < max &&
(is_unreserved(in[i]) ||
@@ -211,28 +209,24 @@ static void copy_token(
int copy_URL_list(URL_list *in, URL_list *out)
{
int len = strlen( in->URLs ) + 1;
int i = 0;
size_t len = strlen(in->URLs) + 1;
size_t i = 0;
out->URLs = NULL;
out->parsedURLs = NULL;
out->size = 0;
out->URLs = ( char * )malloc( len );
out->parsedURLs =
( uri_type * ) malloc( sizeof( uri_type ) * in->size );
out->URLs = malloc(len);
out->parsedURLs = malloc(sizeof(uri_type) * in->size);
if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) )
if ( !out->URLs || !out->parsedURLs)
return UPNP_E_OUTOF_MEMORY;
memcpy( out->URLs, in->URLs, len );
memcpy(out->URLs, in->URLs, len);
for( i = 0; i < in->size; i++ ) {
//copy the parsed uri
/*copy the parsed uri */
out->parsedURLs[i].type = in->parsedURLs[i].type;
copy_token( &in->parsedURLs[i].scheme, in->URLs,
&out->parsedURLs[i].scheme, out->URLs );
out->parsedURLs[i].path_type = in->parsedURLs[i].path_type;
copy_token( &in->parsedURLs[i].pathquery, in->URLs,
&out->parsedURLs[i].pathquery, out->URLs );
@@ -241,7 +235,6 @@ int copy_URL_list(URL_list *in, URL_list *out)
copy_token( &in->parsedURLs[i].hostport.text,
in->URLs, &out->parsedURLs[i].hostport.text,
out->URLs );
memcpy( &out->parsedURLs[i].hostport.IPaddress,
&in->parsedURLs[i].hostport.IPaddress,
sizeof(struct sockaddr_storage) );
@@ -278,113 +271,100 @@ void print_uri(uri_type *in)
#ifdef DEBUG
void print_token(token * in)
{
int i = 0;
printf( "Token Size : %"PRIzu"\n\'", in->size );
for( i = 0; i < in->size; i++ ) {
putchar( in->buff[i] );
}
putchar( '\'' );
putchar( '\n' );
size_t i = 0;
printf("Token Size : %" PRIzu "\n\'", in->size);
for (i = 0; i < in->size; i++)
putchar(in->buff[i]);
putchar('\'');
putchar('\n');
}
#endif /* DEBUG */
int token_string_casecmp(token *in1, char *in2)
int token_string_casecmp(token *in1, const char *in2)
{
int in2_length = strlen(in2);
if (in1->size != in2_length) {
size_t in2_length = strlen(in2);
if (in1->size != in2_length)
return 1;
} else {
else
return strncasecmp(in1->buff, in2, in1->size);
}
}
int token_string_cmp(token * in1, char *in2)
{
int in2_length = strlen(in2);
if (in1->size != in2_length) {
size_t in2_length = strlen(in2);
if (in1->size != in2_length)
return 1;
} else {
else
return strncmp(in1->buff, in2, in1->size);
}
}
int token_cmp(token *in1, token *in2)
{
if (in1->size != in2->size) {
if (in1->size != in2->size)
return 1;
} else {
else
return memcmp(in1->buff, in2->buff, in1->size);
}
}
int parse_hostport(
const char *in,
int max,
size_t max,
hostport_type *out)
{
char workbuf[256];
char* c;
struct sockaddr_in* sai4 = (struct sockaddr_in*)&out->IPaddress;
struct sockaddr_in6* sai6 = (struct sockaddr_in6*)&out->IPaddress;
char *c;
struct sockaddr_in *sai4 = (struct sockaddr_in *)&out->IPaddress;
struct sockaddr_in6 *sai6 = (struct sockaddr_in6 *)&out->IPaddress;
char *srvname = NULL;
char *srvport = NULL;
char *last_dot = NULL;
unsigned short int port;
int af = AF_UNSPEC;
int hostport_size;
size_t hostport_size;
int has_port = 0;
int ret;
memset( out, 0, sizeof(hostport_type) );
// Work on a copy of the input string.
strncpy( workbuf, in, sizeof(workbuf) );
memset(out, 0, sizeof(hostport_type));
/* Work on a copy of the input string. */
strncpy(workbuf, in, sizeof(workbuf));
c = workbuf;
if( *c == '[' ) {
// IPv6 addresses are enclosed in square brackets.
if (*c == '[') {
/* IPv6 addresses are enclosed in square brackets. */
srvname = ++c;
while( *c != '\0' && *c != ']' ) {
while (*c != '\0' && *c != ']')
c++;
}
if( *c == '\0' ) {
// did not find closing bracket.
if (*c == '\0')
/* did not find closing bracket. */
return UPNP_E_INVALID_URL;
}
// NULL terminate the srvname and then increment c.
*c++ = '\0'; // overwrite the ']'
if( *c == ':' ) {
/* NULL terminate the srvname and then increment c. */
*c++ = '\0'; /* overwrite the ']' */
if (*c == ':') {
has_port = 1;
c++;
}
af = AF_INET6;
}
else {
// IPv4 address -OR- host name.
} else {
/* IPv4 address -OR- host name. */
srvname = c;
while( (*c != ':') && (*c != '/') && ( (isalnum(*c)) || (*c == '.') || (*c == '-') ) ) {
if( *c == '.' )
while (*c != ':' && *c != '/' &&
(isalnum(*c) || *c == '.' || *c == '-')) {
if (*c == '.')
last_dot = c;
c++;
}
has_port = (*c == ':') ? 1 : 0;
// NULL terminate the srvname
/* NULL terminate the srvname */
*c = '\0';
if( has_port == 1 )
if (has_port == 1)
c++;
if( last_dot != NULL && isdigit(*(last_dot+1)) ) {
// Must be an IPv4 address.
if (last_dot != NULL && isdigit(*(last_dot + 1)))
/* Must be an IPv4 address. */
af = AF_INET;
}
else {
// Must be a host name.
/* Must be a host name. */
struct addrinfo hints, *res, *res0;
memset(&hints, 0, sizeof(hints));
@@ -392,82 +372,69 @@ int parse_hostport(
hints.ai_socktype = SOCK_STREAM;
ret = getaddrinfo(srvname, NULL, &hints, &res0);
if( ret == 0 ) {
if (ret == 0) {
for (res = res0; res; res = res->ai_next) {
if( res->ai_family == AF_INET ||
res->ai_family == AF_INET6 ) {
// Found a valid IPv4 or IPv6 address.
memcpy( &out->IPaddress, res->ai_addr,
res->ai_addrlen );
if (res->ai_family == AF_INET ||
res->ai_family == AF_INET6) {
/* Found a valid IPv4 or IPv6 address. */
memcpy(&out->IPaddress,
res->ai_addr,
res->ai_addrlen);
break;
}
}
freeaddrinfo(res0);
if( res == NULL ) {
// Didn't find an AF_INET or AF_INET6 address.
if (res == NULL)
/* Didn't find an AF_INET or AF_INET6 address. */
return UPNP_E_INVALID_URL;
} else
/* getaddrinfo failed. */
return UPNP_E_INVALID_URL;
}
}
else {
// getaddrinfo failed.
return UPNP_E_INVALID_URL;
}
}
}
// Check if a port is specified.
if( has_port == 1 ) {
// Port is specified.
/* Check if a port is specified. */
if (has_port == 1) {
/* Port is specified. */
srvport = c;
while( *c != '\0' && isdigit(*c) ) {
while (*c != '\0' && isdigit(*c))
c++;
}
port = (unsigned short int)atoi(srvport);
if( port == 0 ) {
// Bad port number.
if (port == 0)
/* Bad port number. */
return UPNP_E_INVALID_URL;
}
}
else {
// Port was not specified, use default port.
} else
/* Port was not specified, use default port. */
port = 80;
}
// The length of the host and port string can be calculated by
// subtracting pointers.
hostport_size = (int)(c - workbuf);
// Fill in the 'out' information.
if( af == AF_INET ) {
/* The length of the host and port string can be calculated by */
/* subtracting pointers. */
hostport_size = (size_t)(c - workbuf);
/* Fill in the 'out' information. */
if (af == AF_INET) {
sai4->sin_family = AF_INET;
sai4->sin_port = htons(port);
ret = inet_pton(AF_INET, srvname, &sai4->sin_addr);
}
else if( af == AF_INET6 ) {
} else if (af == AF_INET6) {
sai6->sin6_family = AF_INET6;
sai6->sin6_port = htons(port);
sai6->sin6_scope_id = gIF_INDEX;
ret = inet_pton(AF_INET6, srvname, &sai6->sin6_addr);
} else {
// IP address was set by the hostname (getaddrinfo).
// Override port:
if( out->IPaddress.ss_family == AF_INET )
/* IP address was set by the hostname (getaddrinfo). */
/* Override port: */
if (out->IPaddress.ss_family == AF_INET)
sai4->sin_port = htons(port);
else
sai6->sin6_port = htons(port);
ret = 1;
}
/* Check if address was converted successfully. */
if (ret <= 0) {
if (ret <= 0)
return UPNP_E_INVALID_URL;
}
out->text.size = hostport_size;
out->text.buff = in;
return hostport_size;
return (int)hostport_size;
max = max;
}
/*!
@@ -480,29 +447,27 @@ int parse_hostport(
*
* \return
*/
static int parse_scheme(
static size_t parse_scheme(
/*! [in] String of characters representing a scheme. */
const char *in,
/*! [in] Maximum number of characters. */
int max,
size_t max,
/*! [out] Output parameter whose buffer is filled in with the scheme. */
token *out)
{
int i = 0;
size_t i = 0;
out->size = 0;
out->buff = NULL;
if( ( max == 0 ) || ( !isalpha( in[0] ) ) )
return FALSE;
return 0;
i++;
while( ( i < max ) && ( in[i] != ':' ) ) {
if( !( isalnum( in[i] ) || ( in[i] == '+' ) || ( in[i] == '-' )
|| ( in[i] == '.' ) ) )
return FALSE;
return 0;
i++;
}
if( i < max ) {
@@ -511,18 +476,18 @@ static int parse_scheme(
return i;
}
return FALSE;
return 0;
}
int remove_escaped_chars(INOUT char *in, INOUT size_t *size )
int remove_escaped_chars(INOUT char *in, INOUT size_t *size)
{
int i = 0;
size_t i = 0;
for( i = 0; i < *size; i++ ) {
replace_escaped( in, i, size );
for (i = 0; i < *size; i++) {
replace_escaped(in, i, size);
}
return UPNP_E_SUCCESS;
}
@@ -562,7 +527,7 @@ int remove_dots(char *in, size_t size)
copyTo = Segments[--lastSegment];
} else {
free( Segments );
//TRACE("ERROR RESOLVING URL, ../ at ROOT");
/*TRACE("ERROR RESOLVING URL, ../ at ROOT"); */
return UPNP_E_INVALID_URL;
}
continue;
@@ -599,7 +564,7 @@ char *resolve_rel_url(char *base_url, char *rel_url)
uri_type rel;
char temp_path = '/';
int i = 0;
size_t i = 0;
char *finger = NULL;
char *last_slash = NULL;
@@ -665,7 +630,6 @@ char *resolve_rel_url(char *base_url, char *rel_url)
finger = out_finger;
last_slash = finger;
i = 0;
while( ( i < base.pathquery.size ) &&
( base.pathquery.buff[i] != '?' ) ) {
( *finger ) = base.pathquery.buff[i];
@@ -675,7 +639,6 @@ char *resolve_rel_url(char *base_url, char *rel_url)
finger++;
}
i = 0;
strcpy( last_slash, rel_url );
if( remove_dots( out_finger,
strlen( out_finger ) ) !=
@@ -705,13 +668,14 @@ char *resolve_rel_url(char *base_url, char *rel_url)
}
int parse_uri(const char *in, int max, uri_type *out)
int parse_uri(const char *in, size_t max, uri_type *out)
{
int begin_path = 0;
int begin_hostport = 0;
int begin_fragment = 0;
size_t begin_hostport = 0;
size_t begin_fragment = 0;
if( ( begin_hostport = parse_scheme( in, max, &out->scheme ) ) ) {
begin_hostport = parse_scheme(in, max, &out->scheme);
if (begin_hostport) {
out->type = ABSOLUTE;
out->path_type = OPAQUE_PART;
begin_hostport++;
@@ -719,44 +683,40 @@ int parse_uri(const char *in, int max, uri_type *out)
out->type = RELATIVE;
out->path_type = REL_PATH;
}
if( ( ( begin_hostport + 1 ) < max ) && ( in[begin_hostport] == '/' )
&& ( in[begin_hostport + 1] == '/' ) ) {
if (begin_hostport + 1 < max &&
in[begin_hostport] == '/' &&
in[begin_hostport + 1] == '/') {
begin_hostport += 2;
if( ( begin_path = parse_hostport( &in[begin_hostport],
begin_path = parse_hostport(&in[begin_hostport],
max - begin_hostport,
&out->hostport ) ) >= 0 ) {
begin_path += begin_hostport;
&out->hostport);
if (begin_path >= 0) {
begin_path += (int)begin_hostport;
} else
return begin_path;
} else {
memset( &out->hostport, 0, sizeof(out->hostport) );
begin_path = begin_hostport;
memset(&out->hostport, 0, sizeof(out->hostport));
begin_path = (int)begin_hostport;
}
begin_fragment =
parse_uric( &in[begin_path], max - begin_path,
&out->pathquery ) + begin_path;
if( ( out->pathquery.size ) && ( out->pathquery.buff[0] == '/' ) ) {
begin_fragment = parse_uric(&in[begin_path],
max - (size_t)begin_path,
&out->pathquery) + (size_t)begin_path;
if (out->pathquery.size && out->pathquery.buff[0] == '/') {
out->path_type = ABS_PATH;
}
if( ( begin_fragment < max ) && ( in[begin_fragment] == '#' ) ) {
if (begin_fragment < max && in[begin_fragment] == '#') {
begin_fragment++;
parse_uric( &in[begin_fragment], max - begin_fragment,
&out->fragment );
parse_uric(&in[begin_fragment], max - begin_fragment,
&out->fragment);
} else {
out->fragment.buff = NULL;
out->fragment.size = 0;
}
return HTTP_SUCCESS;
}
int parse_uri_and_unescape(char *in, int max, uri_type *out)
int parse_uri_and_unescape(char *in, size_t max, uri_type *out)
{
int ret = parse_uri(in, max, out);

View File

@@ -52,7 +52,7 @@
* Description : Makes a copy of the subscription
*
* Return : int ;
* HTTP_SUCCESS - On Sucess
* HTTP_SUCCESS - On success
*
* Note :
************************************************************************/
@@ -135,7 +135,7 @@ subscription *GetSubscriptionSID(const Upnp_SID sid, service_info *service)
}
}
if( found ) {
//get the current_time
/*get the current_time */
time( &current_time );
if( ( found->expireTime != 0 )
&& ( found->expireTime < current_time ) ) {
@@ -161,7 +161,7 @@ subscription *GetNextSubscription(service_info *service, subscription *current)
subscription *previous = NULL;
int notDone = 1;
// get the current_time
/* get the current_time */
time( &current_time );
while( ( notDone ) && ( current ) ) {
previous = current;
@@ -195,7 +195,7 @@ subscription *GetFirstSubscription(service_info *service)
temp.next = service->subscriptionList;
next = GetNextSubscription(service, &temp);
service->subscriptionList = temp.next;
// service->subscriptionList = next;
/* service->subscriptionList = next; */
return next;
}
@@ -718,10 +718,10 @@ getSubElement( const char *element_name,
*
* Note :
************************************************************************/
service_info *
getServiceList( IXML_Node * node,
service_info ** end,
char *URLBase )
service_info *getServiceList(
IXML_Node *node,
service_info **end,
char *URLBase)
{
IXML_Node *serviceList = NULL;
IXML_Node *current_service = NULL;
@@ -737,43 +737,32 @@ getServiceList( IXML_Node * node,
service_info *current = NULL;
service_info *previous = NULL;
IXML_NodeList *serviceNodeList = NULL;
int NumOfServices = 0;
int i = 0;
long unsigned int NumOfServices = 0;
long unsigned int i = 0;
int fail = 0;
if( getSubElement( "UDN", node, &UDN ) &&
getSubElement( "serviceList", node, &serviceList ) ) {
serviceNodeList = ixmlElement_getElementsByTagName( ( IXML_Element
* )
serviceList,
"service" );
if( serviceNodeList != NULL ) {
NumOfServices = ixmlNodeList_length( serviceNodeList );
for( i = 0; i < NumOfServices; i++ ) {
current_service = ixmlNodeList_item( serviceNodeList, i );
if (getSubElement("UDN", node, &UDN) &&
getSubElement("serviceList", node, &serviceList)) {
serviceNodeList = ixmlElement_getElementsByTagName(
(IXML_Element *)serviceList, "service");
if (serviceNodeList != NULL) {
NumOfServices = ixmlNodeList_length(serviceNodeList);
for (i = 0; i < NumOfServices; i++) {
current_service =
ixmlNodeList_item(serviceNodeList, i);
fail = 0;
if( current ) {
current->next =
( service_info * )
malloc( sizeof( service_info ) );
if (current) {
current->next = malloc(sizeof(service_info));
previous = current;
current = current->next;
} else {
head =
( service_info * )
malloc( sizeof( service_info ) );
head = malloc(sizeof(service_info));
current = head;
}
if( !current ) {
freeServiceList( head );
if (!current) {
freeServiceList(head);
return NULL;
}
current->next = NULL;
current->controlURL = NULL;
current->eventURL = NULL;
@@ -783,99 +772,65 @@ getServiceList( IXML_Node * node,
current->active = 1;
current->subscriptionList = NULL;
current->TotalSubscriptions = 0;
if( !( current->UDN = getElementValue( UDN ) ) )
if (!(current->UDN = getElementValue(UDN)))
fail = 1;
if( ( !getSubElement( "serviceType", current_service,
&serviceType ) ) ||
( !( current->serviceType =
getElementValue( serviceType ) ) ) )
if (!getSubElement("serviceType", current_service, &serviceType) ||
!(current->serviceType = getElementValue(serviceType)))
fail = 1;
if( ( !getSubElement( "serviceId", current_service,
&serviceId ) ) ||
( !
( current->serviceId =
getElementValue( serviceId ) ) ) )
if (!getSubElement("serviceId", current_service, &serviceId) ||
!(current->serviceId = getElementValue(serviceId)))
fail = 1;
if( ( !
( getSubElement
( "SCPDURL", current_service, &SCPDURL ) ) )
|| ( !( tempDOMString = getElementValue( SCPDURL ) ) )
||
( !
( current->SCPDURL =
resolve_rel_url( URLBase, tempDOMString ) ) ) )
if (!getSubElement("SCPDURL", current_service, &SCPDURL) ||
!(tempDOMString = getElementValue(SCPDURL)) ||
!(current->SCPDURL = resolve_rel_url(URLBase, tempDOMString)))
fail = 1;
ixmlFreeDOMString( tempDOMString );
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if( ( !
( getSubElement
( "controlURL", current_service, &controlURL ) ) )
||
( !( tempDOMString = getElementValue( controlURL ) ) )
||
( !
( current->controlURL =
resolve_rel_url( URLBase, tempDOMString ) ) ) ) {
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"BAD OR MISSING CONTROL URL" );
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"CONTROL URL SET TO NULL IN SERVICE INFO" );
if (!(getSubElement("controlURL", current_service, &controlURL)) ||
!(tempDOMString = getElementValue(controlURL)) ||
!(current->controlURL = resolve_rel_url(URLBase, tempDOMString))) {
UpnpPrintf(UPNP_INFO, GENA, __FILE__,
__LINE__,
"BAD OR MISSING CONTROL URL");
UpnpPrintf(UPNP_INFO, GENA, __FILE__,
__LINE__,
"CONTROL URL SET TO NULL IN SERVICE INFO");
current->controlURL = NULL;
fail = 0;
}
ixmlFreeDOMString( tempDOMString );
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if( ( !
( getSubElement
( "eventSubURL", current_service, &eventURL ) ) )
|| ( !( tempDOMString = getElementValue( eventURL ) ) )
||
( !
( current->eventURL =
resolve_rel_url( URLBase, tempDOMString ) ) ) ) {
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"BAD OR MISSING EVENT URL" );
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"EVENT URL SET TO NULL IN SERVICE INFO" );
if (!getSubElement("eventSubURL", current_service, &eventURL) ||
!(tempDOMString = getElementValue(eventURL)) ||
!(current->eventURL = resolve_rel_url(URLBase, tempDOMString))) {
UpnpPrintf(UPNP_INFO, GENA, __FILE__,
__LINE__,
"BAD OR MISSING EVENT URL");
UpnpPrintf(UPNP_INFO, GENA, __FILE__,
__LINE__,
"EVENT URL SET TO NULL IN SERVICE INFO");
current->eventURL = NULL;
fail = 0;
}
ixmlFreeDOMString( tempDOMString );
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if( fail ) {
freeServiceList( current );
if( previous )
if (fail) {
freeServiceList(current);
if (previous)
previous->next = NULL;
else
head = NULL;
current = previous;
}
}
ixmlNodeList_free( serviceNodeList );
ixmlNodeList_free(serviceNodeList);
}
( *end ) = current;
(*end) = current;
return head;
} else {
( *end ) = NULL;
(*end) = NULL;
return NULL;
}
}
/************************************************************************
@@ -905,32 +860,30 @@ getAllServiceList( IXML_Node * node,
IXML_NodeList *deviceList = NULL;
IXML_Node *currentDevice = NULL;
int NumOfDevices = 0;
int i = 0;
long unsigned int NumOfDevices = 0;
long unsigned int i = 0;
( *out_end ) = NULL;
(*out_end) = NULL;
deviceList =
ixmlElement_getElementsByTagName( ( IXML_Element * ) node,
"device" );
if( deviceList != NULL ) {
NumOfDevices = ixmlNodeList_length( deviceList );
for( i = 0; i < NumOfDevices; i++ ) {
currentDevice = ixmlNodeList_item( deviceList, i );
if( head ) {
end->next =
getServiceList( currentDevice, &next_end, URLBase );
if ( next_end )
deviceList = ixmlElement_getElementsByTagName(
(IXML_Element *)node, "device");
if (deviceList) {
NumOfDevices = ixmlNodeList_length(deviceList);
for (i = 0; i < NumOfDevices; i++) {
currentDevice = ixmlNodeList_item(deviceList, i);
if (head) {
end->next = getServiceList(currentDevice,
&next_end, URLBase);
if (next_end)
end = next_end;
} else
head = getServiceList( currentDevice, &end, URLBase );
head = getServiceList(currentDevice, &end,
URLBase);
}
ixmlNodeList_free(deviceList);
}
ixmlNodeList_free( deviceList );
}
( *out_end ) = end;
(*out_end) = end;
return head;
}
@@ -963,8 +916,8 @@ removeServiceTable( IXML_Node * node,
service_info *current_service = NULL;
service_info *start_search = NULL;
service_info *prev_service = NULL;
int NumOfDevices = 0;
int i = 0;
long unsigned int NumOfDevices = 0;
long unsigned int i = 0;
if( getSubElement( "root", node, &root ) ) {
current_service = in->serviceList;
@@ -980,9 +933,9 @@ removeServiceTable( IXML_Node * node,
&& ( ( getSubElement( "UDN", node, &currentUDN ) )
&& ( UDN = getElementValue( currentUDN ) ) ) ) {
current_service = start_search;
//Services are put in the service table in the order in which they appear in the
//description document, therefore we go through the list only once to remove a particular
//root device
/*Services are put in the service table in the order in which they appear in the */
/*description document, therefore we go through the list only once to remove a particular */
/*root device */
while( ( current_service )
&& ( strcmp( current_service->UDN, UDN ) ) ) {
current_service = current_service->next;
@@ -1108,4 +1061,5 @@ getServiceTable( IXML_Node * node,
return 0;
}
#endif // INCLUDE_DEVICE_APIS
#endif /* INCLUDE_DEVICE_APIS */

View File

@@ -70,7 +70,7 @@ str_alloc( IN const char *str,
s = ( char * )malloc( str_len + 1 );
if( s == NULL ) {
return NULL; // no mem
return NULL; /* no mem */
}
memcpy( s, str, str_len );
@@ -111,8 +111,8 @@ memptr_cmp( IN memptr * m,
cmp = strncmp( m->buf, s, m->length );
if( cmp == 0 && m->length < strlen( s ) ) {
// both strings equal for 'm->length' chars
// if m is shorter than s, then s is greater
/* both strings equal for 'm->length' chars */
/* if m is shorter than s, then s is greater */
return -1;
}
@@ -147,8 +147,8 @@ memptr_cmp_nocase( IN memptr * m,
cmp = strncasecmp( m->buf, s, m->length );
if( cmp == 0 && m->length < strlen( s ) ) {
// both strings equal for 'm->length' chars
// if m is shorter than s, then s is greater
/* both strings equal for 'm->length' chars */
/* if m is shorter than s, then s is greater */
return -1;
}
@@ -204,20 +204,20 @@ membuffer_set_size( INOUT membuffer * m,
size_t alloc_len;
char *temp_buf;
if( new_length >= m->length ) // increase length
if( new_length >= m->length ) /* increase length */
{
// need more mem?
/* need more mem? */
if( new_length <= m->capacity ) {
return 0; // have enough mem; done
return 0; /* have enough mem; done */
}
diff = new_length - m->length;
alloc_len = MAXVAL( m->size_inc, diff ) + m->capacity;
} else // decrease length
} else /* decrease length */
{
assert( new_length <= m->length );
// if diff is 0..m->size_inc, don't free
/* if diff is 0..m->size_inc, don't free */
if( ( m->capacity - new_length ) <= m->size_inc ) {
return 0;
}
@@ -227,21 +227,21 @@ membuffer_set_size( INOUT membuffer * m,
assert( alloc_len >= new_length );
temp_buf = realloc( m->buf, alloc_len + 1 ); //LEAK_FIX_MK
temp_buf = realloc( m->buf, alloc_len + 1 ); /*LEAK_FIX_MK */
//temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
/*temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );LEAK_FIX_MK */
if( temp_buf == NULL ) {
// try smaller size
/* try smaller size */
alloc_len = new_length;
temp_buf = realloc( m->buf, alloc_len + 1 ); //LEAK_FIX_MK
//temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );//LEAK_FIX_MK
temp_buf = realloc( m->buf, alloc_len + 1 ); /*LEAK_FIX_MK */
/*temp_buf = Realloc( m->buf,m->length, alloc_len + 1 );LEAK_FIX_MK */
if( temp_buf == NULL ) {
return UPNP_E_OUTOF_MEMORY;
}
}
// save
/* save */
m->buf = temp_buf;
m->capacity = alloc_len;
return 0;
@@ -311,29 +311,27 @@ membuffer_destroy( INOUT membuffer * m )
*
* Note :
************************************************************************/
int
membuffer_assign( INOUT membuffer * m,
int membuffer_assign( INOUT membuffer * m,
IN const void *buf,
IN size_t buf_len )
{
int return_code;
assert( m != NULL );
assert(m != NULL);
// set value to null
if( buf == NULL ) {
membuffer_destroy( m );
/* set value to null */
if (buf == NULL) {
membuffer_destroy(m);
return 0;
}
// alloc mem
return_code = membuffer_set_size( m, buf_len );
if( return_code != 0 ) {
/* alloc mem */
return_code = membuffer_set_size(m, buf_len);
if (return_code != 0)
return return_code;
}
// copy
if( buf_len ) {
memcpy( m->buf, buf, buf_len );
m->buf[buf_len] = 0; // null-terminate
/* copy */
if (buf_len) {
memcpy(m->buf, buf, buf_len);
m->buf[buf_len] = 0; /* null-terminate */
}
m->length = buf_len;
@@ -411,110 +409,60 @@ membuffer_append_str( INOUT membuffer * m,
return membuffer_insert( m, c_str, strlen( c_str ), m->length );
}
/************************************************************************
* Function : membuffer_insert
*
* Parameters :
* INOUT membuffer* m ; buffer whose memory size is to be increased
* and appended.
* IN const void* buf ; source buffer whose contents will be
* copied
* IN size_t buf_len ; size of the source buffer
* int index ; index to determine the bounds while movinf the data
*
* Description : Allocates memory for the new data to be inserted. Does
* memory management by moving the data from the existing memory to
* the newly allocated memory and then appending the new data.
*
* Return : int ;
*
* Note :
************************************************************************/
int
membuffer_insert( INOUT membuffer * m,
IN const void *buf,
IN size_t buf_len,
int index )
int membuffer_insert(membuffer *m, const void *buf, size_t buf_len, size_t index)
{
int return_code;
assert( m != NULL );
assert(m != NULL);
if( index < 0 || index > ( int )m->length )
if (index > m->length)
return UPNP_E_OUTOF_BOUNDS;
if( buf == NULL || buf_len == 0 ) {
if (!buf || !buf_len) {
return 0;
}
// alloc mem
return_code = membuffer_set_size( m, m->length + buf_len );
if( return_code != 0 ) {
/* alloc mem */
return_code = membuffer_set_size(m, m->length + buf_len);
if (return_code) {
return return_code;
}
// insert data
// move data to right of insertion point
memmove( m->buf + index + buf_len, m->buf + index, m->length - index );
memcpy( m->buf + index, buf, buf_len );
/* insert data */
/* move data to right of insertion point */
memmove(m->buf + index + buf_len, m->buf + index, m->length - index);
memcpy(m->buf + index, buf, buf_len);
m->length += buf_len;
m->buf[m->length] = 0; // null-terminate
/* null-terminate */
m->buf[m->length] = 0;
return 0;
}
/************************************************************************
* Function : membuffer_delete
*
* Parameters :
* INOUT membuffer* m ; buffer whose memory size is to be decreased
* and copied to the odified location
* IN int index ; index to determine bounds while moving data
* IN size_t num_bytes ; number of bytes that the data needs to
* shrink by
*
* Description : Shrink the size of the buffer depending on the current
* size of the bufer and te input parameters. Move contents from the
* old buffer to the new sized buffer.
*
* Return : void ;
*
* Note :
************************************************************************/
void
membuffer_delete( INOUT membuffer * m,
IN int index,
IN size_t num_bytes )
void membuffer_delete(membuffer *m, size_t index, size_t num_bytes)
{
int return_value;
int new_length;
size_t new_length;
size_t copy_len;
assert( m != NULL );
assert(m != NULL);
if (!m) return;
if( m->length == 0 ) {
if (!m || !m->length)
return;
}
assert( index >= 0 && index < ( int )m->length );
// shrink count if it goes beyond buffer
if( index + num_bytes > m->length ) {
num_bytes = m->length - ( size_t ) index;
copy_len = 0; // every thing at and after index purged
/* shrink count if it goes beyond buffer */
if (index + num_bytes > m->length) {
num_bytes = m->length - index;
/* every thing at and after index purged */
copy_len = 0;
} else {
// calc num bytes after deleted string
copy_len = m->length - ( index + num_bytes );
/* calc num bytes after deleted string */
copy_len = m->length - (index + num_bytes);
}
memmove( m->buf + index, m->buf + index + num_bytes, copy_len );
memmove(m->buf + index, m->buf + index + num_bytes, copy_len);
new_length = m->length - num_bytes;
return_value = membuffer_set_size( m, new_length ); // trim buffer
assert( return_value == 0 ); // shrinking should always work
/* trim buffer */
return_value = membuffer_set_size(m, new_length);
/* shrinking should always work */
assert(return_value == 0);
// don't modify until buffer is set
/* don't modify until buffer is set */
m->length = new_length;
m->buf[new_length] = 0;
}
@@ -543,7 +491,7 @@ membuffer_detach( INOUT membuffer * m )
buf = m->buf;
// free all
/* free all */
membuffer_initialize( m );
return buf;

View File

@@ -1,33 +1,33 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/************************************************************************
* Purpose: This file contains string to integer and integer to string
@@ -48,7 +48,7 @@
* matched.
* IN int num_entries ; number of entries in the table that need
* to be searched.
* IN xboolean case_sensitive ; whether the case should be case
* IN int case_sensitive ; whether the case should be case
* sensitive or not
*
* Description : Match the given name with names from the entries in the
@@ -65,7 +65,7 @@ map_str_to_int( IN const char *name,
IN size_t name_len,
IN str_int_entry * table,
IN int num_entries,
IN xboolean case_sensitive )
IN int case_sensitive )
{
int top,
mid,
@@ -82,24 +82,24 @@ map_str_to_int( IN const char *name,
while( top <= bot ) {
mid = ( top + bot ) / 2;
if( case_sensitive ) {
//cmp = strcmp( name, table[mid].name );
/*cmp = strcmp( name, table[mid].name ); */
cmp = memptr_cmp( &name_ptr, table[mid].name );
} else {
//cmp = strcasecmp( name, table[mid].name );
/*cmp = strcasecmp( name, table[mid].name ); */
cmp = memptr_cmp_nocase( &name_ptr, table[mid].name );
}
if( cmp > 0 ) {
top = mid + 1; // look below mid
top = mid + 1; /* look below mid */
} else if( cmp < 0 ) {
bot = mid - 1; // look above mid
} else // cmp == 0
bot = mid - 1; /* look above mid */
} else /* cmp == 0 */
{
return mid; // match; return table index
return mid; /* match; return table index */
}
}
return -1; // header name not found
return -1; /* header name not found */
}
/************************************************************************

View File

@@ -29,90 +29,39 @@
*
******************************************************************************/
/************************************************************************
* Purpose: This file contains functions for copying strings based on
* different options.
************************************************************************/
/*!
* \file
*
* Purpose: This file contains functions for copying strings based on
* different options.
*/
#include "config.h"
#include "upnp.h"
#include "util.h"
#include "upnputil.h"
#include <string.h>
/************************************************************************
* Function : linecopy
*
* Parameters :
* OUT char dest[LINE_SIZE] ; output buffer
* IN const char* src ; input buffer
*
* Description : Copy no of bytes spcified by the LINE_SIZE constant,
* from the source buffer. Null terminate the destination buffer
*
* Return : void ;
*
* Note :
************************************************************************/
void
linecopy( OUT char dest[LINE_SIZE],
IN const char *src )
void linecopy(char dest[LINE_SIZE], const char *src)
{
strncpy( dest, src, LINE_SIZE - 1 );
dest[LINE_SIZE - 1] = '\0'; // null-terminate if len(src) >= LINE_SIZE
strncpy(dest, src, LINE_SIZE - 1);
/* null-terminate if len(src) >= LINE_SIZE. */
dest[LINE_SIZE - 1] = '\0';
}
/************************************************************************
* Function : namecopy
*
* Parameters :
* OUT char dest[NAME_SIZE] ; output buffer
* IN const char* src ; input buffer
*
* Description : Copy no of bytes spcified by the NAME_SIZE constant,
* from the source buffer. Null terminate the destination buffer
*
* Return : void ;
*
* Note :
************************************************************************/
void
namecopy( OUT char dest[NAME_SIZE],
IN const char *src )
void namecopy(char dest[NAME_SIZE], const char *src)
{
strncpy( dest, src, NAME_SIZE - 1 );
dest[NAME_SIZE - 1] = '\0'; // null-terminate if len(src) >= NAME_SIZE
strncpy(dest, src, NAME_SIZE - 1);
/* null-terminate if len(src) >= NAME_SIZE. */
dest[NAME_SIZE - 1] = '\0';
}
/************************************************************************
* Function : linecopylen
*
* Parameters :
* OUT char dest[LINE_SIZE] ; output buffer
* IN const char* src ; input buffer
* IN size_t srclen ; bytes to be copied.
*
* Description : Determine if the srclen passed in paramter is less than
* the permitted LINE_SIZE. If it is use the passed parameter, if not
* use the permitted LINE_SIZE as the length parameter
* Copy no of bytes spcified by the LINE_SIZE constant,
* from the source buffer. Null terminate the destination buffer
*
* Return : void ;
*
* Note :
************************************************************************/
void
linecopylen( OUT char dest[LINE_SIZE],
IN const char *src,
IN size_t srclen )
void linecopylen(char dest[LINE_SIZE], const char *src, size_t srclen)
{
int len;
size_t len;
len = srclen < ( LINE_SIZE - 1 ) ? srclen : ( LINE_SIZE - 1 );
strncpy( dest, src, len );
len = srclen < (LINE_SIZE - 1) ? srclen : (LINE_SIZE - 1);
strncpy(dest, src, len);
dest[len] = '\0';
}

View File

@@ -294,6 +294,50 @@
/* @} */
/*!
* \name GENA_NOTIFICATION_SENDING_TIMEOUT
*
* The {\tt GENA_NOTIFICATION_SENDING_TIMEOUT} specifies the number of seconds
* to wait for sending GENA notifications to the Control Point.
*
* This timeout will be used to know how many seconds GENA notification threads
* will wait to write on the socket to send the notification. By putting a
* lower value than HTTP_DEFAULT_TIMEOUT, the thread will not wait too long and
* will return quickly if writing is impossible. This is very useful as some
* Control Points disconnect from the network without unsubscribing as a result
* if HTTP_DEFAULT_TIMEOUT is used, all the GENA threads will be blocked to send
* notifications to those disconnected Control Points until the subscription
* expires.
*
* @{
*/
#define GENA_NOTIFICATION_SENDING_TIMEOUT HTTP_DEFAULT_TIMEOUT
/* @} */
/*!
* \name GENA_NOTIFICATION_ANSWERING_TIMEOUT
*
* The {\tt GENA_NOTIFICATION_ANSWERING_TIMEOUT} specifies the number of seconds
* to wait for receiving the answer to a GENA notification from the Control
* Point.
*
* This timeout will be used to know how many seconds GENA notification threads
* will wait on the socket to read for an answer from the CP. By putting a
* lower value than HTTP_DEFAULT_TIMEOUT, the thread will not wait too long and
* will return quickly if there is no answer from the CP. This is very useful as
* some Control Points disconnect from the network without unsubscribing and if
* HTTP_DEFAULT_TIMEOUT is used, all the GENA threads will be blocked to wait
* for an answer from those disconnected Control Points until the subscription
* expires. However, it should be noted that UDA specifies a value of 30s for
* waiting the CP's answer.
*
* @{
*/
#define GENA_NOTIFICATION_ANSWERING_TIMEOUT HTTP_DEFAULT_TIMEOUT
/* @} */
/*!
* \name Module Exclusion
*

View File

@@ -29,11 +29,9 @@
*
**************************************************************************/
#ifndef GLOBAL_H
#define GLOBAL_H
/* GLOBAL.H - RSAREF types and constants */
/* PROTOTYPES should be set to one if and only if the compiler supports
function argument prototyping.
@@ -42,7 +40,6 @@
been defined with C compiler flags.
*/
#ifndef PROTOTYPES
#define PROTOTYPES 1
#endif

View File

@@ -29,49 +29,45 @@
*
******************************************************************************/
#ifndef GENLIB_NET_HTTP_HTTPPARSER_H
#define GENLIB_NET_HTTP_HTTPPARSER_H
/*!
* \file
*/
#include "LinkedList.h"
#include "membuffer.h"
#include "uri.h"
#include "util.h"
#include "upnputil.h"
/* private types */
////// private types ////////////
/* scanner */
//////////////////////
// scanner
///////////////////////
// Used to represent different types of tokens in input
typedef enum // token_type_t
/* Used to represent different types of tokens in input. */
typedef enum
{
TT_IDENTIFIER,
TT_WHITESPACE,
TT_CRLF,
TT_CTRL, // needed ??
TT_SEPARATOR, // ??
TT_QUOTEDSTRING, // ??
TT_CTRL,
TT_SEPARATOR,
TT_QUOTEDSTRING,
} token_type_t;
typedef struct // scanner_t
typedef struct
{
membuffer* msg; // raw http msg
size_t cursor; // current position in buffer
xboolean entire_msg_loaded; // set this to TRUE if the entire msg is loaded in
// in 'msg'; else FALSE if only partial msg in 'msg'
// (default is FALSE)
/*! raw http msg. */
membuffer* msg;
/*! current position in buffer. */
size_t cursor;
/*! set this to TRUE if the entire msg is loaded in 'msg';
* else FALSE if only partial msg in 'msg' (default is FALSE). */
int entire_msg_loaded;
} scanner_t;
typedef enum // parser_pos_t
typedef enum
{
POS_REQUEST_LINE,
POS_RESPONSE_LINE,
@@ -80,7 +76,6 @@ typedef enum // parser_pos_t
POS_COMPLETE,
} parser_pos_t;
#define ENTREAD_DETERMINE_READ_METHOD 1
#define ENTREAD_USING_CLEN 2
#define ENTREAD_USING_CHUNKED 3
@@ -88,13 +83,10 @@ typedef enum // parser_pos_t
#define ENTREAD_CHUNKY_BODY 5
#define ENTREAD_CHUNKY_HEADERS 6
/* end of private section. */
// end of private section
//////////////////
// ##################################################################################
// method in a HTTP request
typedef enum // http_method_t
/* method in a HTTP request. */
typedef enum
{
HTTPMETHOD_POST,
HTTPMETHOD_MPOST,
@@ -105,11 +97,11 @@ typedef enum // http_method_t
HTTPMETHOD_HEAD,
HTTPMETHOD_MSEARCH,
HTTPMETHOD_UNKNOWN,
SOAPMETHOD_POST, //murari
SOAPMETHOD_POST,
HTTPMETHOD_SIMPLEGET
} http_method_t;
// different types of HTTP headers
/* different types of HTTP headers */
#define HDR_UNKNOWN -1
#define HDR_CACHE_CONTROL 1
#define HDR_CALLBACK 2
@@ -118,9 +110,9 @@ typedef enum // http_method_t
#define HDR_DATE 5
#define HDR_EXT 6
#define HDR_HOST 7
//#define HDR_IF_MODIFIED_SINCE 8
//#define HDR_IF_UNMODIFIED_SINCE 9
//#define HDR_LAST_MODIFIED 10
/*define HDR_IF_MODIFIED_SINCE 8 */
/*define HDR_IF_UNMODIFIED_SINCE 9 */
/*define HDR_LAST_MODIFIED 10 */
#define HDR_LOCATION 11
#define HDR_MAN 12
#define HDR_MX 13
@@ -136,7 +128,7 @@ typedef enum // http_method_t
#define HDR_USN 23
#define HDR_USER_AGENT 24
//Adding new header difinition//Beg_Murari
/* Adding new header difinition */
#define HDR_ACCEPT 25
#define HDR_ACCEPT_ENCODING 26
#define HDR_ACCEPT_CHARSET 27
@@ -149,72 +141,77 @@ typedef enum // http_method_t
#define HDR_IF_RANGE 34
#define HDR_RANGE 35
#define HDR_TE 36
//End_Murari
// status of parsing
typedef enum // parse_status_t
{
PARSE_SUCCESS = 0, // msg was parsed successfully
PARSE_INCOMPLETE, // need more data to continue
PARSE_INCOMPLETE_ENTITY, // for responses that don't have length specified
PARSE_FAILURE, // parse failed; check status code for details
PARSE_OK, // done partial
PARSE_NO_MATCH, // token not matched
// private
/*! status of parsing */
typedef enum {
/*! msg was parsed successfully. */
PARSE_SUCCESS = 0,
/*! need more data to continue. */
PARSE_INCOMPLETE,
/*! for responses that don't have length specified. */
PARSE_INCOMPLETE_ENTITY,
/*! parse failed; check status code for details. */
PARSE_FAILURE,
/*! done partial. */
PARSE_OK,
/*! token not matched. */
PARSE_NO_MATCH,
/*! private. */
PARSE_CONTINUE_1
} parse_status_t;
typedef struct // http_header_t
{
memptr name; // header name as a string
int name_id; // header name id (for a selective group of headers only)
membuffer value; // raw-value; could be multi-lined; min-length = 0
// private
typedef struct {
/*! header name as a string. */
memptr name;
/*! header name id (for a selective group of headers only). */
int name_id;
/*! raw-value; could be multi-lined; min-length = 0. */
membuffer value;
/* private. */
membuffer name_buf;
} http_header_t;
typedef struct // http_message_t
{
typedef struct {
int initialized;
// request only
/*! request only. */
http_method_t method;
/*! request only. */
uri_type uri;
// response only
/*! response only. */
http_method_t request_method;
/*! response only. */
int status_code;
/*! response only. */
membuffer status_msg;
// fields used in both request or response messages
xboolean is_request; // if TRUE, msg is a request, else response
int major_version; // http major.minor version
/* fields used in both request or response messages. */
/*! if TRUE, msg is a request, else response. */
int is_request;
/* http major version. */
int major_version;
/* http minor version. */
int minor_version;
/*! . */
LinkedList headers;
//NNS: dlist headers; // dlist<http_header_t *>
memptr entity; // message body(entity)
// private fields
membuffer msg; // entire raw message
char *urlbuf; // storage for url string
/*! message body(entity). */
memptr entity;
/* private fields. */
/*! entire raw message. */
membuffer msg;
/*! storage for url string. */
char *urlbuf;
/*! . */
size_t entity_offset;
} http_message_t;
typedef struct // http_parser_t
{
typedef struct {
http_message_t msg;
int http_error_code; // read-only; in case of parse error, this
// contains the HTTP error code (4XX or 5XX)
// read-only; this is set to true if a NOTIFY request has no content-length.
// used to read valid sspd notify msg.
xboolean valid_ssdp_notify_hack;
// private data -- don't touch
/*! read-only; in case of parse error, this
* contains the HTTP error code (4XX or 5XX). */
int http_error_code;
/*! read-only; this is set to true if a NOTIFY request has no
* content-length. used to read valid sspd notify msg. */
int valid_ssdp_notify_hack;
/* private data -- don't touch. */
parser_pos_t position;
int ent_position;
unsigned int content_length;
@@ -223,15 +220,9 @@ typedef struct // http_parser_t
scanner_t scanner;
} http_parser_t;
//--------------------------------------------------
//////////////// functions /////////////////////////
//--------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#endif /* __cplusplus */
/************************************************************************
* Function : httpmsg_init
@@ -273,7 +264,6 @@ void httpmsg_destroy( INOUT http_message_t* msg );
*
* Return : http_header_t* - Pointer to a header on success;
* NULL on failure
*
* Note :
************************************************************************/
http_header_t* httpmsg_find_hdr_str( IN http_message_t* msg,
@@ -289,7 +279,7 @@ http_header_t* httpmsg_find_hdr_str( IN http_message_t* msg,
*
* Description : Finds header from a list, with the given 'name_id'.
*
* Return : http_header_t* - Pointer to a header on success; *
* Return : http_header_t* - Pointer to a header on success;
* NULL on failure
*
* Note :
@@ -437,10 +427,6 @@ parse_status_t parser_append( INOUT http_parser_t* parser,
************************************************************************/
int matchstr( IN char *str, IN size_t slen, IN const char* fmt, ... );
// ====================================================
// misc functions
/************************************************************************
* Function: raw_to_int
*
@@ -481,26 +467,28 @@ int raw_find_str( IN memptr* raw_value, IN const char* str );
* nameConverts a http_method id stored in the HTTP Method
*
* Returns:
* const char* ptr - Ptr to the HTTP Method *
* const char* ptr - Ptr to the HTTP Method
************************************************************************/
const char* method_to_str( IN http_method_t method );
/*!
* \brief Print the HTTP headers.
*/
#ifdef DEBUG
void print_http_headers(
/*! [in] HTTP Message object. */
http_message_t *hmsg );
http_message_t *hmsg);
#else
static UPNP_INLINE void print_http_headers(http_message_t *hmsg) {}
static UPNP_INLINE void print_http_headers(http_message_t *hmsg)
{
return;
hmsg = hmsg;
}
#endif
#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* GENLIB_NET_HTTP_HTTPPARSER_H */

View File

@@ -1,88 +1,82 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef GENLIB_NET_HTTP_HTTPREADWRITE_H
#define GENLIB_NET_HTTP_HTTPREADWRITE_H
/*
* \file
*/
#include "config.h"
#include "util.h"
#include "upnputil.h"
#include "sock.h"
#include "httpparser.h"
// timeout in secs
/*! timeout in secs. */
#define HTTP_DEFAULT_TIMEOUT 30
#ifdef __cplusplus
#extern "C" {
#endif
int
http_CancelHttpGet( IN void *Handle );
int http_CancelHttpGet(IN void *Handle);
/************************************************************************
* Function: http_FixUrl
/*!
* \brief Validates URL.
*
* Parameters:
* IN uri_type* url; URL to be validated and fixed
* OUT uri_type* fixed_url; URL after being fixed.
*
* Description:
* Validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
int http_FixUrl( IN uri_type* url, OUT uri_type* fixed_url );
* \return
* \li \c UPNP_E_INVALID_URL
* \li \c UPNP_E_SUCCESS
*/
int http_FixUrl(
/*! [in] URL to be validated and fixed. */
uri_type *url,
/*! [out] URL after being fixed. */
uri_type *fixed_url);
/************************************************************************
* Function: http_FixStrUrl
/*!
* \brief Parses URL and then validates URL.
*
* Parameters:
* IN char* urlstr ; Character string as a URL
* IN int urlstrlen ; Length of the character string
* OUT uri_type* fixed_url ; Fixed and corrected URL
*
* Description:
* Parses URL and then validates URL
*
* Returns:
* UPNP_E_INVALID_URL
* UPNP_E_SUCCESS
************************************************************************/
int http_FixStrUrl( IN const char* urlstr, IN int urlstrlen, OUT uri_type* fixed_url );
* \return
* \li \c UPNP_E_INVALID_URL
* \li \c UPNP_E_SUCCESS
*/
int http_FixStrUrl(
/*! [in] Character string as a URL. */
const char *urlstr,
/*! [in] Length of the character string. */
size_t urlstrlen,
/*! [out] Fixed and corrected URL. */
uri_type *fixed_url);
/************************************************************************
* Function: http_Connect
@@ -95,7 +89,7 @@ int http_FixStrUrl( IN const char* urlstr, IN int urlstrlen, OUT uri_type* fixed
* Gets destination address from URL and then connects to the remote end
*
* Returns:
* socket descriptor on sucess
* socket descriptor on success
* UPNP_E_OUTOF_SOCKET
* UPNP_E_SOCKET_CONNECT on error
************************************************************************/
@@ -128,37 +122,37 @@ int http_RecvMessage( IN SOCKINFO *info, OUT http_parser_t* parser,
OUT int* http_error_code );
/************************************************************************
* Function: http_SendMessage
/*!
* \brief Sends a message to the destination based on the format parameter.
*
* Parameters:
* IN SOCKINFO *info ; Socket information object
* IN OUT int * TimeOut ; time out value
* IN const char* fmt, ... Pattern format to take actions upon
*
* Description:
* Sends a message to the destination based on the
* IN const char* fmt parameter
* fmt types:
* 'f': arg = const char * file name
* 'm': arg1 = const char * mem_buffer; arg2= size_t buf_length
* E.g.:
* char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
* char *filename = "foo.dat";
* int status = http_SendMessage( tcpsock, "mf",
* buf, strlen(buf), // args for memory buffer
* filename ); // arg for file
* \li \c 'f': arg = "const char *" file name
* \li \c 'b': arg1 = "const char *" mem_buffer; arg2 = "size_t" buffer length.
* \li \c 'I': arg = "struct SendInstruction *"
*
* Returns:
* UPNP_E_OUTOF_MEMORY
* UPNP_E_FILE_READ_ERROR
* UPNP_E_SUCCESS
************************************************************************/
* E.g.:
\verbatim
char *buf = "POST /xyz.cgi http/1.1\r\n\r\n";
char *filename = "foo.dat";
int status = http_SendMessage(tcpsock, "bf",
buf, strlen(buf), // args for memory buffer
filename); // arg for file
\endverbatim
*
* \return
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_FILE_READ_ERROR
* \li \c UPNP_E_SUCCESS
*/
int http_SendMessage(
IN SOCKINFO *info,
IN OUT int* timeout_secs,
IN const char* fmt, ... );
/* [in] Socket information object. */
SOCKINFO *info,
/* [in,out] Time out value. */
int* timeout_secs,
/* [in] Pattern format to take actions upon. */
const char* fmt,
/* [in] Variable parameter list. */
...);
/************************************************************************
* Function: http_RequestAndResponse
@@ -212,7 +206,7 @@ int http_RequestAndResponse(
* IN int timeout_secs; time out value
* OUT char** document; buffer to store the document extracted
* from the donloaded message.
* OUT int* doc_length; length of the extracted document
* OUT size_t* doc_length; length of the extracted document
* OUT char* content_type; Type of content
*
* Description:
@@ -227,7 +221,7 @@ int http_Download(
IN const char* url,
IN int timeout_secs,
OUT char** document,
OUT int* doc_length,
OUT size_t *doc_length,
OUT char* content_type );
@@ -238,7 +232,7 @@ int http_Download(
* IN void *Handle: Handle to the http post object
* IN char *buf: Buffer to send to peer, if format used
* is not UPNP_USING_CHUNKED,
* IN unsigned int *size: Size of the data to be sent.
* IN size_t *size: Size of the data to be sent.
* IN int timeout: time out value
*
* Description:
@@ -252,7 +246,7 @@ int http_Download(
************************************************************************/
int http_WriteHttpPost(IN void *Handle,
IN char *buf,
IN unsigned int *size,
IN size_t *size,
IN int timeout);
@@ -271,7 +265,7 @@ int http_WriteHttpPost(IN void *Handle,
* associated memory. Frees handle associated with the HTTP POST msg.
*
* Return: int
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_SUCCESS - On success
* UPNP_E_INVALID_PARAM - Invalid Parameter
************************************************************************/
int http_CloseHttpPost(IN void *Handle,
@@ -296,7 +290,7 @@ int http_CloseHttpPost(IN void *Handle,
* such handles
*
* Return : int;
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_SUCCESS - On success
* UPNP_E_INVALID_PARAM - Invalid Parameter
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
@@ -315,7 +309,7 @@ int http_OpenHttpPost(IN const char *url_str,
* Parameters:
* IN void *Handle; Handle to the HTTP get object
* IN OUT char *buf; Buffer to get the read and parsed data
* IN OUT unsigned int *size; Size of the buffer passed
* IN OUT size_t *size; Size of the buffer passed
* IN int timeout; time out value
*
* Description:
@@ -323,7 +317,7 @@ int http_OpenHttpPost(IN const char *url_str,
* Parses and extracts information from the new data.
*
* Return: int
* UPNP_E_SUCCESS - On Sucess
* UPNP_E_SUCCESS - On success
* UPNP_E_INVALID_PARAM - Invalid Parameter
* UPNP_E_BAD_RESPONSE
* UPNP_E_BAD_HTTPMSG
@@ -332,7 +326,7 @@ int http_OpenHttpPost(IN const char *url_str,
int http_ReadHttpGet(
IN void *Handle,
IN OUT char *buf,
IN OUT unsigned int *size,
IN OUT size_t *size,
IN int timeout);
@@ -341,8 +335,8 @@ int http_ReadHttpGet(
*
* Parameters:
* IN void *Handle; Handle to the HTTP get object
* OUT unsigned int *length; Buffer to get the read and parsed data
* OUT unsigned int *total; Size of tge buffer passed
* OUT size_t *length; Buffer to get the read and parsed data
* OUT size_t *total; Size of tge buffer passed
*
* Description:
* Extracts information from the Handle to the HTTP get object.
@@ -353,9 +347,8 @@ int http_ReadHttpGet(
************************************************************************/
int http_HttpGetProgress(
IN void *Handle,
OUT unsigned int *length,
OUT unsigned int *total );
OUT size_t *length,
OUT size_t *total);
/************************************************************************
* Function: http_CloseHttpGet
@@ -373,74 +366,61 @@ int http_HttpGetProgress(
************************************************************************/
int http_CloseHttpGet(IN void *Handle);
/************************************************************************
* Function: http_OpenHttpGet
*
* Parameters:
* IN const char *url_str: String as a URL
* IN OUT void **Handle: Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType: Type of content
* OUT int *contentLength: length of content
* OUT int *httpStatus: HTTP status returned on receiving a
* response message
* IN int timeout: time out value
*
* Description:
* Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the
* response.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Paramters
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE
************************************************************************/
int http_OpenHttpGet(
IN const char *url_str,
IN OUT void **Handle,
IN OUT char **contentType,
OUT int *contentLength,
OUT int *httpStatus,
IN int timeout);
/************************************************************************
* Function: http_OpenHttpGetProxy
*
* Parameters:
* IN const char *url_str; String as a URL
* IN const char *proxy_str; String as a URL
* IN OUT void **Handle; Pointer to buffer to store HTTP
* post handle
* IN OUT char **contentType; Type of content
* OUT int *contentLength; length of content
* OUT int *httpStatus; HTTP status returned on receiving a
* response message
* IN int timeout: time out value
*
* Description:
* Makes the HTTP GET message, connects to the peer,
/*!
* \brief Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the response.
*
* If a proxy URL is defined then the connection is made there.
*
* Return: int
* UPNP_E_SUCCESS - On Success
* UPNP_E_INVALID_PARAM - Invalid Paramters
* UPNP_E_OUTOF_MEMORY
* UPNP_E_SOCKET_ERROR
* UPNP_E_BAD_RESPONSE
************************************************************************/
int http_OpenHttpGetProxy(IN const char *url_str,
IN const char *proxy_str,
IN OUT void **Handle,
IN OUT char **contentType,
OUT int *contentLength,
OUT int *httpStatus,
IN int timeout);
* \return integer
* \li \c UPNP_E_SUCCESS - On Success
* \li \c UPNP_E_INVALID_PARAM - Invalid Paramters
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_SOCKET_ERROR
* \li \c UPNP_E_BAD_RESPONSE
*/
int http_OpenHttpGet(
/* [in] String as a URL. */
const char *url_str,
/* [in,out] Pointer to buffer to store HTTP post handle. */
void **Handle,
/* [in,out] Type of content. */
char **contentType,
/* [out] length of content. */
int *contentLength,
/* [out] HTTP status returned on receiving a response message. */
int *httpStatus,
/* [in] time out value. */
int timeout);
/*!
* \brief Makes the HTTP GET message, connects to the peer,
* sends the HTTP GET request, gets the response and parses the response.
*
* If a proxy URL is defined then the connection is made there.
*
* \return integer
* \li \c UPNP_E_SUCCESS - On Success
* \li \c UPNP_E_INVALID_PARAM - Invalid Paramters
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_SOCKET_ERROR
* \li \c UPNP_E_BAD_RESPONSE
*/
int http_OpenHttpGetProxy(
/* [in] String as a URL. */
const char *url_str,
/* [in] String as a URL. */
const char *proxy_str,
/* [in,out] Pointer to buffer to store HTTP post handle. */
void **Handle,
/* [in,out] Type of content. */
char **contentType,
/* [out] length of content. */
int *contentLength,
/* [out] HTTP status returned on receiving a response message. */
int *httpStatus,
/* [in] time out value. */
int timeout);
/************************************************************************
@@ -469,61 +449,55 @@ int http_SendStatusResponse(
IN int request_major_version,
IN int request_minor_version );
/************************************************************************
* Function: http_MakeMessage
/*!
* \brief Generate an HTTP message based on the format that is specified in
* the input parameters.
*
* Parameters:
* INOUT membuffer* buf; buffer with the contents of the
* message
* IN int http_major_version; HTTP major version
* IN int http_minor_version; HTTP minor version
* IN const char* fmt; Pattern format
* ...;
\verbatim
Format types:
'B': arg = int status_code -- appends content-length, content-type and HTML body for given code.
'b': arg1 = const char *buf;
arg2 = size_t buf_length memory ptr
'C': (no args) -- appends a HTTP CONNECTION: close header depending on major, minor version.
'c': (no args) -- appends CRLF "\r\n"
'D': (no args) -- appends HTTP DATE: header
'd': arg = int number -- appends decimal number
'G': arg = range information -- add range header
'h': arg = off_t number -- appends off_t number
'K': (no args) -- add chunky header
'L': arg = language information -- add Content-Language header if Accept-Language header is not empty and if
WEB_SERVER_CONTENT_LANGUAGE is not empty
'N': arg1 = off_t content_length -- content-length header
'q': arg1 = http_method_t -- request start line and HOST header
arg2 = (uri_type *)
'Q': arg1 = http_method_t; -- start line of request
arg2 = char* url;
arg3 = size_t url_length
'R': arg = int status_code -- adds a response start line
'S': (no args) -- appends HTTP SERVER: header
's': arg = const char * -- C_string
'T': arg = char * content_type; -- format e.g: "text/html"; content-type header
't': arg = time_t * gmt_time -- appends time in RFC 1123 fmt
'U': (no args) -- appends HTTP USER-AGENT: header
'X': arg = const char * -- useragent; "redsonic" HTTP X-User-Agent: useragent
\endverbatim
*
* Description:
* Generate an HTTP message based on the format that is specified
* in the input parameters.
*
* fmt types:
* 'B': arg = int status_code
* appends content-length, content-type and HTML body
* for given code
* 'b': arg1 = const char* buf;
* arg2 = size_t buf_length memory ptr
* 'C': (no args) appends a HTTP CONNECTION: close header
* depending on major,minor version
* 'c': (no args) appends CRLF "\r\n"
* 'D': (no args) appends HTTP DATE: header
* 'd': arg = int number // appends decimal number
* 'G': arg = range information // add range header
* 'h': arg = off_t number // appends off_t number
* 'K': (no args) // add chunky header
* 'N': arg1 = off_t content_length // content-length header
* 'q': arg1 = http_method_t // request start line and HOST header
* arg2 = (uri_type *)
* 'Q': arg1 = http_method_t; // start line of request
* arg2 = char* url;
* arg3 = size_t url_length
* 'R': arg = int status_code // adds a response start line
* 'S': (no args) appends HTTP SERVER: header
* 's': arg = const char* C_string
* 'T': arg = char * content_type; format
* e.g: "text/html"; content-type header
* 't': arg = time_t * gmt_time // appends time in RFC 1123 fmt
* 'U': (no args) appends HTTP USER-AGENT: header
* 'X': arg = const char useragent; "redsonic" HTTP X-User-Agent: useragent
*
* Return: int
* 0 - On Success
* UPNP_E_OUTOF_MEMORY
* UPNP_E_INVALID_URL
************************************************************************/
* \return
* \li \c 0 - On Success
* \li \c UPNP_E_OUTOF_MEMORY
* \li \c UPNP_E_INVALID_URL
*/
int http_MakeMessage(
/* [in,out] Buffer with the contents of the message. */
INOUT membuffer* buf,
/* [in] HTTP major version. */
IN int http_major_version,
/* [in] HTTP minor version. */
IN int http_minor_version,
IN const char* fmt, ... );
/* [in] Pattern format. */
IN const char* fmt,
/* [in] Format arguments. */
... );
/************************************************************************
@@ -597,9 +571,9 @@ int http_OpenHttpGetEx(IN const char *url_str,
void get_sdk_info( OUT char *info );
#ifdef __cplusplus
} // #extern "C"
} /* #extern "C" */
#endif
#endif // GENLIB_NET_HTTP_HTTPREADWRITE_H
#endif /* GENLIB_NET_HTTP_HTTPREADWRITE_H */

View File

@@ -40,7 +40,7 @@
* \li (2) takes a u_char* not an in_addr as input
*
*/
extern const char *inet_ntop4(const u_char src, char *dst, socklen_t size);
extern const char *inet_ntop4(const u_char *src, char *dst, socklen_t size);
/*!

View File

@@ -1,72 +1,76 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef GENLIB_UTIL_MEMBUFFER_H
#define GENLIB_UTIL_MEMBUFFER_H
/*!
* \file
*/
#include <stdlib.h>
#include "util.h"
#include "upnputil.h"
#define MINVAL( a, b ) ( (a) < (b) ? (a) : (b) )
#define MAXVAL( a, b ) ( (a) > (b) ? (a) : (b) )
// pointer to a chunk of memory
typedef struct // memptr
/*! pointer to a chunk of memory. */
typedef struct
{
char *buf; // start of memory (read/write)
size_t length; // length of memory (read-only)
/*! start of memory (read/write). */
char *buf;
/*! length of memory (read-only). */
size_t length;
} memptr;
// maintains a block of dynamically allocated memory
// note: Total length/capacity should not exceed MAX_INT
typedef struct // membuffer
/*! Maintains a block of dynamically allocated memory
* note: Total length/capacity should not exceed MAX_INT */
typedef struct
{
char *buf; // mem buffer; must not write beyond buf[length-1] (read/write)
size_t length; // length of buffer (read-only)
size_t capacity; // total allocated memory (read-only)
size_t size_inc; // used to increase size; MUST be > 0; (read/write)
// default value of size_inc
/*! mem buffer; must not write beyond buf[length-1] (read/write). */
char *buf;
/*! length of buffer (read-only). */
size_t length;
/*! total allocated memory (read-only). */
size_t capacity;
/*! used to increase size; MUST be > 0; (read/write). */
size_t size_inc;
/*! default value of size_inc. */
#define MEMBUF_DEF_SIZE_INC 5
} membuffer;
//--------------------------------------------------
//////////////// functions /////////////////////////
//--------------------------------------------------
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#endif /* __cplusplus */
/************************************************************************
* Function : str_alloc
@@ -84,7 +88,7 @@ extern "C" {
*
* Note :
************************************************************************/
char* str_alloc( IN const char* str, IN size_t str_len );
char *str_alloc( IN const char* str, IN size_t str_len );
/************************************************************************
* Function : memptr_cmp
@@ -253,47 +257,37 @@ int membuffer_append( INOUT membuffer* m, IN const void* buf, IN size_t buf_len
************************************************************************/
int membuffer_append_str( INOUT membuffer* m, IN const char* c_str );
/************************************************************************
* Function : membuffer_insert
*
* Parameters :
* INOUT membuffer* m ; buffer whose memory size is to be increased
* and appended.
* IN const void* buf ; source buffer whose contents will be
* copied
* IN size_t buf_len ; size of the source buffer
* int index ; index to determine the bounds while movinf the data
*
* Description : Allocates memory for the new data to be inserted. Does
* memory management by moving the data from the existing memory to
* the newly allocated memory and then appending the new data.
*
* Return : int ;
*
* Note :
************************************************************************/
int membuffer_insert( INOUT membuffer* m, IN const void* buf, IN size_t buf_len, int index );
/*!
* \brief Allocates memory for the new data to be inserted. Does
* memory management by moving the data from the existing memory to
* the newly allocated memory and then appending the new data.
*
* \return 0 if successful, error code if error.
*/
int membuffer_insert(
/* [in,out] Buffer whose memory size is to be increased and appended. */
membuffer *m,
/* [in] source buffer whose contents will be copied. */
const void *buf,
/* [in] size of the source buffer. */
size_t buf_len,
/* [in] index to determine the bounds while movinf the data. */
size_t index);
/************************************************************************
* Function : membuffer_delete
*
* Parameters :
* INOUT membuffer* m ; buffer whose memory size is to be decreased
* and copied to the odified location
* IN int index ; index to determine bounds while moving data
* IN size_t num_bytes ; number of bytes that the data needs to
* shrink by
*
* Description : Shrink the size of the buffer depending on the current
* size of the bufer and te input parameters. Move contents from the
* old buffer to the new sized buffer.
*
* Return : void ;
*
* Note :
************************************************************************/
void membuffer_delete( INOUT membuffer* m, IN int index, IN size_t num_bytes );
/*!
* \brief Shrink the size of the buffer depending on the current size of the
* bufer and te input parameters. Move contents from the old buffer to the
* new sized buffer.
*/
void membuffer_delete(
/* [in,out] Buffer whose memory size is to be decreased and copied
* to the modified location. */
INOUT membuffer *m,
/* [in] Index to determine bounds while moving data. */
IN size_t index,
/* [in] Number of bytes that the data needs to shrink by. */
IN size_t num_bytes);
/************************************************************************
@@ -332,7 +326,8 @@ char* membuffer_detach( INOUT membuffer* m );
************************************************************************/
void membuffer_attach( INOUT membuffer* m, IN char* new_buf, IN size_t buf_len );
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
} /* extern "C" */
#endif /* __cplusplus */
#endif /* GENLIB_UTIL_H */
#endif // GENLIB_UTIL_H

View File

@@ -59,11 +59,11 @@ typedef struct MServerSockArray {
/*! IPv6 SSDP Socket for incoming advertisments and search requests. */
SOCKET ssdpSock6UlaGua;
/* ! . */
SOCKET stopPort;
uint16_t stopPort;
/* ! . */
SOCKET miniServerPort4;
uint16_t miniServerPort4;
/* ! . */
SOCKET miniServerPort6;
uint16_t miniServerPort6;
#ifdef INCLUDE_CLIENT_APIS
/*! IPv4 SSDP socket for sending search requests and receiving search
* replies */
@@ -106,7 +106,7 @@ void SetSoapCallback(
/*! [in] SOAP Callback to be invoked . */
MiniServerCallback callback);
#else /* INCLUDE_DEVICE_APIS */
static inline void SetSoapCallback(MiniServerCallback callback) {}
static UPNP_INLINE void SetSoapCallback(MiniServerCallback callback) {}
#endif /* INCLUDE_DEVICE_APIS */

View File

@@ -1,63 +1,61 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef GENLIB_NET_HTTP_PARSETOOLS_H
#define GENLIB_NET_HTTP_PARSETOOLS_H
#include "util.h"
#include "httpparser.h"
/*!
* \file
*/
#include "upnputil.h"
#include "httpparser.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************************************************************
* Function: has_xml_content_type
*
* Parameters:
* IN http_message_t* hmsg ; HTTP Message object
*
* Description: Find the header from the HTTP message and match the
* header for xml data.
*
* Returns:
* BOOLEAN
************************************************************************/
xboolean has_xml_content_type( IN http_message_t* hmsg );
/*!
* \brief Find the header from the HTTP message and match the header for
* xml data.
*
* \return boolean.
*/
int has_xml_content_type(
/*! HTTP Message object. */
IN http_message_t *hmsg);
#ifdef __cplusplus
} // extern C
} /* extern C */
#endif
#endif /* GENLIB_NET_HTTP_PARSETOOLS_H */
#endif // GENLIB_NET_HTTP_PARSETOOLS_H

View File

@@ -29,38 +29,30 @@
*
******************************************************************************/
#ifndef SERVICE_TABLE_H
#define SERVICE_TABLE_H
/*!
* \file
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "config.h"
#include "uri.h"
#include "ixml.h"
#include "upnp.h"
#include "upnpdebug.h"
#include <stdio.h>
#include <time.h>
#define SID_SIZE 41
#ifdef INCLUDE_DEVICE_APIS
typedef struct SUBSCRIPTION {
Upnp_SID sid;
int eventKey;
@@ -71,7 +63,6 @@ typedef struct SUBSCRIPTION {
struct SUBSCRIPTION *next;
} subscription;
typedef struct SERVICE_INFO {
DOMString serviceType;
DOMString serviceId;
@@ -85,21 +76,18 @@ typedef struct SERVICE_INFO {
struct SERVICE_INFO *next;
} service_info;
typedef struct SERVICE_TABLE {
DOMString URLBase;
service_info *serviceList;
service_info *endServiceList;
} service_table;
/* Functions for Subscriptions */
/*!
* \brief Makes a copy of the subscription.
*
* \return HTTP_SUCCESS on Sucess.
* \return HTTP_SUCCESS on success.
*/
int copy_subscription(
/*! [in] Source subscription. */
@@ -107,7 +95,6 @@ int copy_subscription(
/*! [in] Destination subscription. */
subscription *out);
/*
* \brief Remove the subscription represented by the const Upnp_SID sid parameter
* from the service table and update the service table.
@@ -118,7 +105,6 @@ void RemoveSubscriptionSID(
/*! [in] Service object providing the list of subscriptions. */
service_info *service);
/*!
* \brief Return the subscription from the service table that matches
* const Upnp_SID sid value.
@@ -131,7 +117,6 @@ subscription *GetSubscriptionSID(
/*! [in] Service object providing the list of subscriptions. */
service_info *service);
/*!
* \brief Gets pointer to the first subscription node in the service table.
*
@@ -141,7 +126,6 @@ subscription *GetFirstSubscription(
/*! [in] Service object providing the list of subscriptions. */
service_info *service);
/*!
* \brief Get current and valid subscription from the service table.
*
@@ -153,7 +137,6 @@ subscription *GetNextSubscription(
/*! [in] Current subscription object. */
subscription *current);
/*!
* \brief Free's the memory allocated for storing the URL of the subscription.
*/
@@ -161,7 +144,6 @@ void freeSubscription(
/*! [in] Subscription object to be freed. */
subscription *sub);
/*!
* \brief Free's memory allocated for all the subscriptions in the service table.
*/
@@ -169,7 +151,6 @@ void freeSubscriptionList(
/*! [in] Head of the subscription list. */
subscription * head);
/*!
* \brief Traverses through the service table and returns a pointer to the
* service node that matches a known service id and a known UDN.
@@ -186,7 +167,6 @@ service_info *FindServiceId(
* table. */
const char *UDN);
/*!
* \brief Traverses the service table and finds the node whose event URL Path
* matches a know value.
@@ -200,7 +180,6 @@ service_info *FindServiceEventURLPath(
/*! [in] Event URL path used to find a service from the table. */
char *eventURLPath);
/*!
* \brief Traverses the service table and finds the node whose control URL Path
* matches a know value.
@@ -214,7 +193,6 @@ service_info * FindServiceControlURLPath(
/*! [in] Control URL path used to find a service from the table. */
const char *controlURLPath);
/*!
* \brief For debugging purposes prints information from the service passed
* into the function.
@@ -231,10 +209,15 @@ void printService(
static UPNP_INLINE void printService(
service_info *service,
Upnp_LogLevel level,
Dbg_Module module) {}
Dbg_Module module)
{
return;
service = service;
level = level;
module = module;
}
#endif
/*!
* \brief For debugging purposes prints information of each service from the
* service table passed into the function.
@@ -251,10 +234,15 @@ void printServiceList(
static UPNP_INLINE void printServiceList(
service_info *service,
Upnp_LogLevel level,
Dbg_Module module) {}
Dbg_Module module)
{
return;
service = service;
level = level;
module = module;
}
#endif
/*!
* \brief For debugging purposes prints the URL base of the table and information
* of each service from the service table passed into the function.
@@ -271,10 +259,15 @@ void printServiceTable(
static UPNP_INLINE void printServiceTable(
service_table *table,
Upnp_LogLevel level,
Dbg_Module module) {}
Dbg_Module module)
{
return;
table = table;
level = level;
module = module;
}
#endif
/*!
* \brief Free's memory allocated for the various components of the service
* entry in the service table.
@@ -283,7 +276,6 @@ void freeService(
/*! [in] Service information that is to be freed. */
service_info *in);
/*!
* \brief Free's memory allocated for the various components of each service
* entry in the service table.
@@ -292,7 +284,6 @@ void freeServiceList(
/*! [in] Head of the service list to be freed. */
service_info *head);
/*!
* \brief Free's dynamic memory in table (does not free table, only memory
* within the structure).
@@ -301,7 +292,6 @@ void freeServiceTable(
/*! [in] Service table whose internal memory needs to be freed. */
service_table *table);
/*!
* \brief This function assumes that services for a particular root device are
* placed linearly in the service table, and in the order in which they are
@@ -316,7 +306,6 @@ int removeServiceTable(
/*! [in] Service table from which services will be removed. */
service_table *in);
/*!
* \brief Add Service to the table.
*/
@@ -329,7 +318,6 @@ int addServiceTable(
* service list. */
const char *DefaultURLBase);
/*!
* \brief Retrieve service from the table.
*
@@ -343,10 +331,8 @@ int getServiceTable(
/*! [in] Default base URL on which the URL will be returned. */
const char *DefaultURLBase);
/* Misc helper functions */
/*!
* \brief Returns the clone of the element value.
*
@@ -358,7 +344,6 @@ DOMString getElementValue(
/*! [in] Input node which provides the list of child nodes. */
IXML_Node *node);
/*!
* \brief Traverses through a list of XML nodes to find the node with the
* known element name.
@@ -375,7 +360,6 @@ int getSubElement(
/*! [out] Ouput node to which the matched child node is returned. */
IXML_Node **out);
#endif /* INCLUDE_DEVICE_APIS */
#ifdef __cplusplus

View File

@@ -32,31 +32,25 @@
#ifndef SOAPLIB_H
#define SOAPLIB_H
/*!
* \file
*/
/* 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:
****************************************************************************/
/*!
* \brief 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.
*/
void soap_device_callback(
IN http_parser_t *parser,
IN http_message_t* request,
INOUT SOCKINFO *info);
/*! [in] Parsed request received by the device. */
http_parser_t *parser,
/*! [in] HTTP request. */
http_message_t *request,
/*! [in,out] Socket info. */
SOCKINFO *info);
/****************************************************************************

View File

@@ -36,7 +36,7 @@
* \file
*/
#include "util.h"
#include "upnputil.h"
#ifdef WIN32
/* Do not #include <netinet/in.h> */
@@ -110,7 +110,7 @@ int sock_read(
/*! Buffer to get data to. */
OUT char* buffer,
/*! Size of the buffer. */
IN size_t bufsize,
IN int bufsize,
/*! timeout value. */
INOUT int *timeoutSecs);
@@ -126,9 +126,9 @@ int sock_write(
/*! Socket Information Object. */
IN SOCKINFO *info,
/*! Buffer to send data from. */
IN char* buffer,
IN const char *buffer,
/*! Size of the buffer. */
IN size_t bufsize,
IN int bufsize,
/*! timeout value. */
INOUT int *timeoutSecs);
@@ -154,9 +154,9 @@ int sock_destroy(
*
* \return -1 if an error occurred or if the socket is -1.
*/
static inline int sock_close(
static UPNP_INLINE int sock_close(
/*! Socket descriptor. */
int sock)
SOCKET sock)
{
int ret = -1;

View File

@@ -29,7 +29,6 @@
*
**************************************************************************/
#ifndef SSDPLIB_H
#define SSDPLIB_H
@@ -90,7 +89,6 @@ typedef enum SsdpCmdType{
#define SSDP_IPV6_SITELOCAL "FF05::C"
#define SSDP_PORT 1900
#define NUM_TRY 3
#define NUM_COPY 1
#define THREAD_LIMIT 50
#define COMMAND_LEN 300
@@ -114,11 +112,8 @@ typedef enum SsdpCmdType{
#define E_SOCKET -7
#define RQST_TIMEOUT 20
/* Structure to store the SSDP information */
typedef struct SsdpEventStruct
{
/*! Structure to store the SSDP information */
typedef struct SsdpEventStruct {
enum SsdpCmdType Cmd;
enum SsdpSearchType RequestType;
int ErrCode;
@@ -126,7 +121,8 @@ typedef struct SsdpEventStruct
int Mx;
char UDN[LINE_SIZE];
char DeviceType[LINE_SIZE];
char ServiceType[LINE_SIZE]; //NT or ST
/* NT or ST */
char ServiceType[LINE_SIZE];
char Location[LINE_SIZE];
char HostAddr[LINE_SIZE];
char Os[LINE_SIZE];
@@ -140,13 +136,13 @@ typedef void (* SsdpFunPtr)(Event *);
typedef Event SsdpEvent ;
// Structure to contain Discovery response
/*! Structure to contain Discovery response. */
typedef struct resultData
{
struct Upnp_Discovery param;
void *cookie;
Upnp_FunPtr ctrlpt_callback;
}ResultData;
} ResultData;
typedef struct TData
@@ -156,7 +152,7 @@ typedef struct TData
char * Data;
struct sockaddr_storage DestAddr;
}ThreadData;
} ThreadData;
typedef struct ssdpsearchreply
{
@@ -165,7 +161,7 @@ typedef struct ssdpsearchreply
struct sockaddr_storage dest_addr;
SsdpEvent event;
}SsdpSearchReply;
} SsdpSearchReply;
typedef struct ssdpsearcharg
{
@@ -238,7 +234,7 @@ static inline void ssdp_handle_device_request(
* Parameters:
* IN http_message_t* hmsg: SSDP message from the device
* IN struct sockaddr* dest_addr: Address of the device
* IN xboolean timeout: timeout kept by the control point while sending
* IN int timeout: timeout kept by the control point while sending
* search message
* IN void* cookie: Cookie stored by the control point application.
* This cookie will be returned to the control point
@@ -255,7 +251,7 @@ static inline void ssdp_handle_device_request(
void ssdp_handle_ctrlpt_msg(
IN http_message_t *hmsg,
IN struct sockaddr *dest_addr,
IN xboolean timeout,
IN int timeout,
IN void *cookie);
/************************************************************************

View File

@@ -1,38 +1,38 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef GENLIB_NET_HTTP_STATCODES_H
#define GENLIB_NET_HTTP_STATCODES_H
// HTTP response status codes
/* HTTP response status codes */
#define HTTP_CONTINUE 100
#define HTTP_SWITCHING_PROCOTOLS 101
@@ -80,15 +80,13 @@
#define HTTP_GATEWAY_TIMEOUT 504
#define HTTP_HTTP_VERSION_NOT_SUPPORTED 505
// *********** HTTP lib error codes **********
/* HTTP lib error codes */
#define HTTP_E_OUT_OF_MEMORY -2
#define HTTP_E_BAD_MSG_FORMAT -3
#define HTTP_E_TIMEDOUT -4
#define HTTP_E_FILE_READ -5
// *******************************************
#ifdef __cplusplus
extern "C" {
#endif
@@ -109,7 +107,8 @@ extern "C" {
const char* http_get_code_text( int statusCode );
#ifdef __cplusplus
} // extern C
} /* extern C */
#endif
#endif /* GENLIB_NET_HTTP_STATCODES_H */

View File

@@ -1,46 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#ifndef GENLIB_UTIL_STRINTMAP_H
#define GENLIB_UTIL_STRINTMAP_H
#include <stdlib.h>
#include "util.h"
#include "upnputil.h"
// Util to map from a string to an integer and vice versa
/* Util to map from a string to an integer and vice versa */
typedef struct // str_int_entry
typedef struct /* str_int_entry */
{
char *name; // a value in string form
int id; // same value in integer form
const char *name; /* a value in string form */
int id; /* same value in integer form */
} str_int_entry;
#ifdef __cplusplus
@@ -57,7 +57,7 @@ extern "C" {
* matched.
* IN int num_entries ; number of entries in the table that need
* to be searched.
* IN xboolean case_sensitive ; whether the case should be case
* IN int case_sensitive ; whether the case should be case
* sensitive or not
*
* Description : Match the given name with names from the entries in the
@@ -71,7 +71,7 @@ extern "C" {
************************************************************************/
int map_str_to_int( IN const char* name, IN size_t name_len,
IN str_int_entry* table, IN int num_entries,
IN xboolean case_sensitive );
IN int case_sensitive );
/************************************************************************
@@ -95,8 +95,9 @@ int map_int_to_str( IN int id, IN str_int_entry* table,
IN int num_entries );
#ifdef __cplusplus
} // extern C
} /* extern C */
#endif
#endif // GENLIB_UTIL_STRINTMAP_H
#endif /* GENLIB_UTIL_STRINTMAP_H */

View File

@@ -109,10 +109,8 @@ struct Handle_Info
#endif
};
extern ithread_rwlock_t GlobalHndRWLock;
/*!
* \brief Get handle information.
*
@@ -181,7 +179,7 @@ extern char gIF_IPV6[65];
extern char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN];
extern int gIF_INDEX;
extern unsigned gIF_INDEX;
extern unsigned short LOCAL_PORT_V4;
@@ -294,7 +292,7 @@ int getlocalhostname(
/*! [out] IP address of the interface. */
char *out,
/*! [in] Length of the output buffer. */
const int out_len);
size_t out_len);
/*!

136
upnp/src/inc/upnputil.h Normal file
View File

@@ -0,0 +1,136 @@
/*******************************************************************************
*
* 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 UTIL_H
#define UTIL_H
/*!
* \file
*/
#include "upnp.h"
/* usually used to specify direction of parameters in functions */
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif
#define GEMD_OUT_OF_MEMORY -1
#define EVENT_TIMEDOUT -2
#define EVENT_TERMINATE -3
/*! boolean type in C. */
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*!
* \brief Copy no of bytes spcified by the LINE_SIZE constant, from the
* source buffer. Null terminate the destination buffer.
*/
void linecopy(
/*! [out] output buffer. */
char dest[LINE_SIZE],
/*! [in] input buffer. */
const char *src);
/*!
* \brief Copy no of bytes spcified by the NAME_SIZE constant, from the
* source buffer. Null terminate the destination buffer
*/
void namecopy(
/*! [out] output buffer. */
char dest[NAME_SIZE],
/*! [in] input buffer. */
const char *src);
/*!
* \brief Determine if the srclen passed in paramter is less than the
* permitted LINE_SIZE. If it is use the passed parameter, if not
* use the permitted LINE_SIZE as the length parameter.
*
* Copy no of bytes spcified by the LINE_SIZE constant, from the source
* buffer. Null terminate the destination buffer.
*/
void linecopylen(
/*! [out] output buffer. */
char dest[LINE_SIZE],
/*! [in] input buffer. */
const char *src,
/*! [in] bytes to be copied. */
size_t srclen);
#ifdef __cplusplus
}
#endif
/* Size of the errorBuffer variable, passed to the strerror_r() function */
#define ERROR_BUFFER_LEN 256
/* C specific */
#ifndef __cplusplus
#ifdef WIN32
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#define EADDRINUSE WSAEADDRINUSE
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define sleep(a) Sleep((a)*1000)
#define usleep(a) Sleep((a)/1000)
#define strerror_r(a,b,c) (strerror_s((b),(c),(a)))
#else
#define max(a, b) (((a)>(b))? (a):(b))
#define min(a, b) (((a)<(b))? (a):(b))
#endif /* WIN32 */
#endif /* __cplusplus */
#endif /* UTIL_H */

View File

@@ -29,11 +29,9 @@
*
******************************************************************************/
#ifndef GENLIB_NET_URI_H
#define GENLIB_NET_URI_H
/*!
* \file
*/
@@ -42,11 +40,9 @@
#include <sys/param.h>
#endif
#include "UpnpGlobal.h" /* for */
#include "UpnpInet.h"
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
@@ -58,56 +54,52 @@
#include <sys/types.h>
#include <time.h>
#ifdef WIN32
#include "inet_pton.h"
#else
#include <arpa/inet.h> /* for inet_pton() */
#include <netdb.h> /* for struct addrinfo */
#endif
#ifdef WIN32
#define strncasecmp strnicmp
#else
/* Other systems have strncasecmp */
#endif
#ifdef __cplusplus
extern "C" {
#endif
/*! length for HTTP DATE: "DATE: Sun, 01 Jul 2000 08:15:23 GMT<cr><lf>" */
#define HTTP_DATE_LENGTH 37
#define HTTP_DATE_LENGTH 37 // length for HTTP DATE:
//"DATE: Sun, 01 Jul 2000 08:15:23 GMT<cr><lf>"
#define SEPARATORS "()<>@,;:\\\"/[]?={} \t"
#define MARK "-_.!~*'()"
#define RESERVED ";/?:@&=+$,{}" //added {} for compatibility
/*! added {} for compatibility */
#define RESERVED ";/?:@&=+$,{}"
#define HTTP_SUCCESS 1
#define FALSE 0
#define TAB 9
#define CR 13
#define LF 10
#define SOCKET_BUFFER_SIZE 5000
enum hostType {
HOSTNAME,
IPv4address
};
enum pathType {
ABS_PATH,
REL_PATH,
OPAQUE_PART
};
#ifdef WIN32
/* there is a conflict in windows with other symbols */
/* there is a conflict in windows with other symbols. */
enum uriType {
absolute,
relative
@@ -119,7 +111,6 @@ enum pathType {
};
#endif
/*!
* \brief Buffer used in parsinghttp messages, urls, etc. generally this simply
* holds a pointer into a larger array.
@@ -129,7 +120,6 @@ typedef struct TOKEN {
size_t size;
} token;
/*!
* \brief Represents a host port: e.g. "127.127.0.1:80" text is a token
* pointing to the full string representation.
@@ -141,7 +131,6 @@ typedef struct HOSTPORT {
struct sockaddr_storage IPaddress;
} hostport_type;
/*!
* \brief Represents a URI used in parse_uri and elsewhere
*/
@@ -154,21 +143,19 @@ typedef struct URI{
hostport_type hostport;
} uri_type;
/*!
* \brief Represents a list of URLs as in the "callback" header of SUBSCRIBE
* message in GENA. "char *" URLs holds dynamic memory.
*/
typedef struct URL_LIST {
/*! */
int size;
size_t size;
/*! All the urls, delimited by <> */
char *URLs;
/*! */
uri_type *parsedURLs;
} URL_list;
/*!
* \brief Replaces an escaped sequence with its unescaped version as in
* http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
@@ -182,14 +169,13 @@ typedef struct URL_LIST {
* \return
*/
int replace_escaped(
/*! [in] String of characters. */
/*! [in,out] String of characters. */
char *in,
/*! [in] Index at which to start checking the characters. */
int index,
size_t index,
/*! [out] . */
size_t *max);
/*!
* \brief Copies one URL_list into another.
*
@@ -217,7 +203,6 @@ void free_URL_list(
/*! [in] URL list object. */
URL_list *list);
/*!
* \brief Function useful in debugging for printing a parsed uri.
*/
@@ -226,10 +211,13 @@ void print_uri(
/*! [in] URI object to print. */
uri_type *in);
#else
static UPNP_INLINE void print_uri(uri_type *in) {}
static UPNP_INLINE void print_uri(uri_type *in)
{
return;
in = in;
}
#endif
/*!
* \brief Function useful in debugging for printing a token.
*/
@@ -238,10 +226,15 @@ void print_token(
/*! [in] Token object to print. */
token *in);
#else
static UPNP_INLINE void print_token(token * in) {}
static UPNP_INLINE void print_token(
/*! [in] Token object to print. */
token *in)
{
return;
in = in;
}
#endif
/*!
* \brief Compares buffer in the token object with the buffer in in2.
*
@@ -254,8 +247,7 @@ int token_string_casecmp(
/*! [in] Token object whose buffer is to be compared. */
token *in1,
/*! [in] String of characters to compare with. */
char *in2);
const char *in2);
/*!
* \brief Compares a null terminated string to a token (exact).
@@ -271,7 +263,6 @@ int token_string_cmp(
/*! [in] String of characters to compare with. */
char *in2);
/*!
* \brief Compares two tokens.
*
@@ -286,7 +277,6 @@ int token_cmp(
/*! [in] Second token object used for the comparison. */
token *in2);
/*!
* \brief Parses a string representing a host and port (e.g. "127.127.0.1:80"
* or "localhost") and fills out a hostport_type struct with internet address
@@ -298,12 +288,11 @@ int parse_hostport(
/*! [in] String of characters representing host and port. */
const char *in,
/*! [in] Sets a maximum limit. */
int max,
size_t max,
/*! [out] Output parameter where the host and port are represented as
* an internet address. */
hostport_type *out);
/*!
* \brief Removes http escaped characters such as: "%20" and replaces them with
* their character representation. i.e. "hello%20foo" -> "hello foo".
@@ -319,7 +308,6 @@ int remove_escaped_chars(
/*! [in,out] Size limit for the number of characters. */
size_t *size);
/*!
* \brief Removes ".", and ".." from a path.
*
@@ -348,7 +336,6 @@ int remove_dots(
/*! [in] Size limit for the number of characters. */
size_t size);
/*!
* \brief resolves a relative url with a base url returning a NEW (dynamically
* allocated with malloc) full url.
@@ -369,7 +356,6 @@ char *resolve_rel_url(
/*! [in] Relative URL. */
char *rel_url);
/*!
* \brief Parses a uri as defined in http://www.ietf.org/rfc/rfc2396.txt
* (RFC explaining URIs).
@@ -386,11 +372,10 @@ int parse_uri(
/*! [in] Character string containing uri information to be parsed. */
const char *in,
/*! [in] Maximum limit on the number of characters. */
int max,
size_t max,
/*! [out] Output parameter which will have the parsed uri information. */
uri_type *out);
/*!
* \brief Same as parse_uri(), except that all strings are unescaped
* (%XX replaced by chars).
@@ -403,11 +388,10 @@ int parse_uri_and_unescape(
/*! [in] Character string containing uri information to be parsed. */
char *in,
/*! [in] Maximum limit on the number of characters. */
int max,
size_t max,
/*! [out] Output parameter which will have the parsed uri information. */
uri_type *out);
/*!
* \brief
*
@@ -421,7 +405,6 @@ int parse_token(
/*! [in] . */
int max_size);
/* Commented #defines, functions and typdefs */
#if 0

View File

@@ -1,173 +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 UTIL_H
#define UTIL_H
#include "upnp.h"
// usually used to specify direction of parameters in functions
#ifndef IN
#define IN
#endif
#ifndef OUT
#define OUT
#endif
#ifndef INOUT
#define INOUT
#endif
#define GEMD_OUT_OF_MEMORY -1
#define EVENT_TIMEDOUT -2
#define EVENT_TERMINATE -3
// boolean type in C
typedef char xboolean;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
///////////////////////////
// funcs
#ifdef __cplusplus
extern "C" {
#endif
/************************************************************************
* Function: logerror
*
* Parameters:
* IN const char *fmt; format string
*
* Description: Log an error message.
*
* Return: void
************************************************************************/
void log_error( IN const char *fmt, ... );
/************************************************************************
* Function: linecopy
*
* Parameters:
* OUT char dest[LINE_SIZE]; output buffer
* IN const char *src; input buffer
*
* Description: Copy no of bytes spcified by the LINE_SIZE constant,
* from the source buffer. Null terminate the destination buffer.
*
* Return: void
************************************************************************/
void linecopy( OUT char dest[LINE_SIZE], IN const char* src );
/************************************************************************
* Function: namecopy
*
* Parameters:
* OUT char dest[NAME_SIZE]; output buffer
* IN const char *src; input buffer
*
* Description: Copy no of bytes spcified by the NAME_SIZE constant,
* from the source buffer. Null terminate the destination buffer
*
* Return: void
************************************************************************/
void namecopy( OUT char dest[NAME_SIZE], IN const char* src );
/************************************************************************
* Function: linecopylen
*
* Parameters:
* OUT char dest[LINE_SIZE]; output buffer
* IN const char *src; input buffer
* IN size_t srclen; bytes to be copied.
*
* Description : Determine if the srclen passed in paramter is less than
* the permitted LINE_SIZE. If it is use the passed parameter, if not
* use the permitted LINE_SIZE as the length parameter
* Copy no of bytes spcified by the LINE_SIZE constant,
* from the source buffer. Null terminate the destination buffer
*
* Return: void
************************************************************************/
void linecopylen( OUT char dest[LINE_SIZE], IN const char* src, IN size_t srclen );
#ifdef __cplusplus
} // extern C
#endif
/* Size of the errorBuffer variable, passed to the strerror_r() function */
#define ERROR_BUFFER_LEN 256
//////////////////////////////////
// C specific
#ifndef __cplusplus
#ifdef WIN32
#ifndef S_ISREG
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
#endif
#define EADDRINUSE WSAEADDRINUSE
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define sleep(a) Sleep((a)*1000)
#define usleep(a) Sleep((a)/1000)
#define strerror_r(a,b,c) (strerror_s((b),(c),(a)))
#else
#define max(a, b) (((a)>(b))? (a):(b))
#define min(a, b) (((a)<(b))? (a):(b))
#endif /* WIN32 */
#endif // __cplusplus
#endif /* UTIL_H */

View File

@@ -1,34 +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.
//
///////////////////////////////////////////////////////////////////////////
#include <genlib/util/util.h>
#include <genlib/util/xstring.h>

View File

@@ -130,9 +130,9 @@ void web_server_callback(
#ifdef __cplusplus
} // extern C
} /* extern C */
#endif
#endif // GENLIB_NET_HTTP_WEBSERVER_H
#endif /* GENLIB_NET_HTTP_WEBSERVER_H */

View File

@@ -6,7 +6,5 @@
#include "sock.h"
#include "soaplib.h"
#endif // EXCLUDE_SOAP
#endif /* EXCLUDE_SOAP */

View File

@@ -1,33 +1,33 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2000-2003 Intel Corporation
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
#include "config.h"
#ifdef INCLUDE_CLIENT_APIS
@@ -54,149 +54,119 @@
#define SOAP_ACTION_RESP 1
#define SOAP_VAR_RESP 2
//#define SOAP_ERROR_RESP 3
/*#define SOAP_ERROR_RESP 3*/
#define SOAP_ACTION_RESP_ERROR 3
#define SOAP_VAR_RESP_ERROR 4
/****************************************************************************
* Function : dom_cmp_name
*
* Parameters :
* IN char *name : lookup name
* IN IXML_Node *node : xml node
*
* Description : This function compares 'name' and node's name
*
* Return : int
* 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY
*
* Note :
****************************************************************************/
static int
dom_cmp_name( IN char *name,
IN IXML_Node * node )
/*!
* \brief Compares 'name' and node's name.
*
* \return 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY.
*/
static int dom_cmp_name(
/* [in] lookup name. */
const char *name,
/* [in] xml node. */
IXML_Node *node)
{
const DOMString node_name = NULL;
memptr nameptr,
dummy;
memptr nameptr;
memptr dummy;
int ret_code;
assert( name );
assert( node );
assert(name);
assert(node);
node_name = ixmlNode_getNodeName( node );
if( node_name == NULL ) {
node_name = ixmlNode_getNodeName(node);
if (node_name == NULL)
return UPNP_E_OUTOF_MEMORY;
}
if( strcmp( name, node_name ) == 0 ) {
if (strcmp(name, node_name) == 0)
ret_code = 0;
} else if( matchstr( ( char * )node_name, strlen( node_name ),
"%s:%s%0", &dummy, &nameptr ) == PARSE_OK &&
strcmp( nameptr.buf, name ) == 0 ) {
else if (matchstr((char *)node_name, strlen(node_name),
"%s:%s%0", &dummy, &nameptr) == PARSE_OK &&
strcmp(nameptr.buf, name) == 0)
ret_code = 0;
} else {
ret_code = 1; // names are not the same
}
else
/* names are not the same */
ret_code = 1;
return ret_code;
}
/****************************************************************************
* Function : dom_find_node
*
* Parameters :
* IN char* node_name : name of the node
* IN IXML_Node *start_node : complete xml node
* OUT IXML_Node ** matching_node : matched node
*
* Description : This function goes thru each child of 'start_node'
* looking for a node having the name 'node_name'.
*
* Return : int
* return UPNP_E_SUCCESS if successful else returns appropriate error
*
* Note :
****************************************************************************/
static int
dom_find_node( IN char *node_name,
IN IXML_Node * start_node,
OUT IXML_Node ** matching_node )
/*!
* \brief Goes thru each child of 'start_node' looking for a node having
* the name 'node_name'.
*
* \return UPNP_E_SUCCESS if successful else returns appropriate error.
*/
static int dom_find_node(
/* [in] name of the node. */
const char *node_name,
/* [in] complete xml node. */
IXML_Node *start_node,
/* [out] matched node. */
IXML_Node **matching_node)
{
IXML_Node *node;
// invalid args
if( node_name == NULL || start_node == NULL ) {
/* invalid args */
if (!node_name || !start_node)
return UPNP_E_NOT_FOUND;
}
node = ixmlNode_getFirstChild( start_node );
while( node != NULL ) {
// match name
if( dom_cmp_name( node_name, node ) == 0 ) {
node = ixmlNode_getFirstChild(start_node);
while (node != NULL) {
/* match name */
if (dom_cmp_name(node_name, node) == 0) {
*matching_node = node;
return UPNP_E_SUCCESS;
}
// free and next node
node = ixmlNode_getNextSibling( node ); // next node
/* free and next node */
node = ixmlNode_getNextSibling(node);
}
return UPNP_E_NOT_FOUND;
}
/****************************************************************************
* Function : dom_find_deep_node
*
* Parameters :
* IN char* names[] : array of names
* IN int num_names : size of array
* IN IXML_Node *start_node : Node from where it should should be
* searched
* OUT IXML_Node ** matching_node : Node that matches the last name
* of the array
*
* Description : This function searches for the node specifed by the last
* name in the 'name' array.
*
* Return : int
* return UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
static int
dom_find_deep_node( IN char *names[],
IN int num_names,
IN IXML_Node * start_node,
OUT IXML_Node ** matching_node )
/*!
* \brief Searches for the node specifed by the last name in the 'name' array.
*
* \return UPNP_E_SUCCESS if successful, else returns appropriate error.
*/
static int dom_find_deep_node(
/* [in] array of names. */
const char *names[],
/* [in] size of array. */
int num_names,
/* [in] Node from where it should should be searched. */
IXML_Node *start_node,
/* [out] Node that matches the last name of the array. */
IXML_Node **matching_node)
{
int i;
IXML_Node *node;
IXML_Node *match_node;
assert( num_names > 0 );
assert(num_names > 0);
node = start_node;
if( dom_cmp_name( names[0], start_node ) == 0 ) {
if( num_names == 1 ) {
if (dom_cmp_name(names[0], start_node) == 0) {
if (num_names == 1) {
*matching_node = start_node;
return UPNP_E_SUCCESS;
}
}
for( i = 1; i < num_names; i++ ) {
if( dom_find_node( names[i], node, &match_node ) !=
UPNP_E_SUCCESS ) {
for (i = 1; i < num_names; i++) {
if (dom_find_node(names[i], node, &match_node) != UPNP_E_SUCCESS)
return UPNP_E_NOT_FOUND;
}
if( i == num_names - 1 ) {
if (i == num_names - 1) {
*matching_node = match_node;
return UPNP_E_SUCCESS;
}
node = match_node; // try again
/* try again */
node = match_node;
}
return UPNP_E_NOT_FOUND; // this line not reached
/* this line not reached */
return UPNP_E_NOT_FOUND;
}
/****************************************************************************
@@ -240,7 +210,7 @@ get_node_value( IN IXML_Node * node )
* control URL
*
* Return : int
* returns 0 on sucess; -1 on error
* returns 0 on success; -1 on error
*
* Note :
****************************************************************************/
@@ -253,7 +223,7 @@ get_host_and_path( IN char *ctrl_url,
if( parse_uri( ctrl_url, strlen( ctrl_url ), url ) != HTTP_SUCCESS ) {
return -1;
}
// This is done to ensure that the buffer is kept const
/* This is done to ensure that the buffer is kept const */
((memptr *)host)->buf = (char *)url->hostport.text.buff;
((memptr *)host)->length = url->hostport.text.size;
@@ -290,39 +260,30 @@ get_action_name( IN char *action,
return ret_code == PARSE_OK ? 0 : -1;
}
/****************************************************************************
* Function : add_man_header
*
* Parameters :
* INOUT membuffer* headers : HTTP header
*
* Description : This function adds "MAN" field in the HTTP header
*
* Return : int
* returns 0 on success; UPNP_E_OUTOFMEMORY on error
*
* Note :
****************************************************************************/
static UPNP_INLINE int
add_man_header( INOUT membuffer * headers )
/*!
* \brief Adds "MAN" field in the HTTP header.
*
* \return 0 on success, UPNP_E_OUTOFMEMORY on error.
*/
static UPNP_INLINE int add_man_header(
/* [in,out] HTTP header. */
membuffer *headers)
{
size_t n;
char *soap_action_hdr;
char *man_hdr = "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; "
"ns=01\r\n01-";
const char *man_hdr =
"MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; ns=01\r\n01-";
// change POST to M-POST
if( membuffer_insert( headers, "M-", 2, 0 ) != 0 ) {
/* change POST to M-POST */
if (membuffer_insert(headers, "M-", 2, 0) != 0)
return UPNP_E_OUTOF_MEMORY;
}
soap_action_hdr = strstr( headers->buf, "SOAPACTION:" );
assert( soap_action_hdr != NULL ); // can't fail
// insert MAN header
if( membuffer_insert( headers, man_hdr, strlen( man_hdr ),
soap_action_hdr - headers->buf ) != 0 ) {
soap_action_hdr = strstr(headers->buf, "SOAPACTION:");
/* can't fail */
assert(soap_action_hdr != NULL);
/* insert MAN header */
n = (size_t)(soap_action_hdr - headers->buf);
if (membuffer_insert(headers, man_hdr, strlen(man_hdr), n))
return UPNP_E_OUTOF_MEMORY;
}
return 0;
}
@@ -357,16 +318,16 @@ soap_request_and_response( IN membuffer * request,
httpmsg_destroy( &response->msg );
return ret_code;
}
// method-not-allowed error
/* method-not-allowed error */
if( response->msg.status_code == HTTP_METHOD_NOT_ALLOWED ) {
ret_code = add_man_header( request ); // change to M-POST msg
ret_code = add_man_header( request ); /* change to M-POST msg */
if( ret_code != 0 ) {
return ret_code;
}
httpmsg_destroy( &response->msg ); // about to reuse response
httpmsg_destroy( &response->msg ); /* about to reuse response */
// try again
/* try again */
ret_code = http_RequestAndResponse( destination_url, request->buf,
request->length,
HTTPMETHOD_MPOST,
@@ -418,140 +379,109 @@ get_response_value( IN http_message_t * hmsg,
char *node_str = NULL;
const char *temp_str = NULL;
DOMString error_node_str = NULL;
int err_code;
xboolean done = FALSE;
char *names[5];
int err_code = UPNP_E_BAD_RESPONSE; /* default error */ ;
int done = FALSE;
const char *names[5];
const DOMString nodeValue;
err_code = UPNP_E_BAD_RESPONSE; // default error
// only 200 and 500 status codes are relevant
if( ( hmsg->status_code != HTTP_OK &&
hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) ||
!has_xml_content_type( hmsg ) ) {
/* only 200 and 500 status codes are relevant */
if ((hmsg->status_code != HTTP_OK &&
hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR) ||
!has_xml_content_type(hmsg))
goto error_handler;
}
if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {
if (ixmlParseBufferEx(hmsg->entity.buf, &doc) != IXML_SUCCESS)
goto error_handler;
}
root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
if( root_node == NULL ) {
root_node = ixmlNode_getFirstChild((IXML_Node *) doc);
if (root_node == NULL)
goto error_handler;
}
if( code == SOAP_ACTION_RESP ) {
//
// try reading soap action response
//
assert( action_value != NULL );
if (code == SOAP_ACTION_RESP) {
/* try reading soap action response */
assert(action_value != NULL);
*action_value = NULL;
names[0] = "Envelope";
names[1] = "Body";
names[2] = name;
if( dom_find_deep_node( names, 3, root_node, &node ) ==
UPNP_E_SUCCESS ) {
node_str = ixmlPrintNode( node );
if( node_str == NULL ) {
if (dom_find_deep_node(names, 3, root_node, &node) ==
UPNP_E_SUCCESS) {
node_str = ixmlPrintNode(node);
if (node_str == NULL) {
err_code = UPNP_E_OUTOF_MEMORY;
goto error_handler;
}
if( ixmlParseBufferEx( node_str,
( IXML_Document ** ) action_value ) !=
IXML_SUCCESS ) {
if (ixmlParseBufferEx(node_str,
(IXML_Document **) action_value)
!= IXML_SUCCESS) {
err_code = UPNP_E_BAD_RESPONSE;
goto error_handler;
}
err_code = SOAP_ACTION_RESP;
done = TRUE;
}
} else if( code == SOAP_VAR_RESP ) {
// try reading var response
assert( str_value != NULL );
*str_value = NULL;
} else if (code == SOAP_VAR_RESP) {
/* try reading var response */
assert(str_value != NULL);
*str_value = NULL;
names[0] = "Envelope";
names[1] = "Body";
names[2] = "QueryStateVariableResponse";
names[3] = "return";
if( dom_find_deep_node( names, 4, root_node, &node )
== UPNP_E_SUCCESS ) {
nodeValue = get_node_value( node );
if( nodeValue == NULL ) {
if (dom_find_deep_node(names, 4, root_node, &node)
== UPNP_E_SUCCESS) {
nodeValue = get_node_value(node);
if (nodeValue == NULL)
goto error_handler;
}
*str_value = ixmlCloneDOMString( nodeValue );
*str_value = ixmlCloneDOMString(nodeValue);
err_code = SOAP_VAR_RESP;
done = TRUE;
}
}
if( !done ) {
// not action or var resp; read error code and description
if (!done) {
/* not action or var resp; read error code and description */
*str_value = NULL;
names[0] = "Envelope";
names[1] = "Body";
names[2] = "Fault";
names[3] = "detail";
names[4] = "UPnPError";
if( dom_find_deep_node( names, 5, root_node, &error_node )
!= UPNP_E_SUCCESS ) {
if (dom_find_deep_node(names, 5, root_node, &error_node) !=
UPNP_E_SUCCESS)
goto error_handler;
}
if( dom_find_node( "errorCode", error_node, &node )
!= UPNP_E_SUCCESS ) {
if (dom_find_node("errorCode", error_node, &node) !=
UPNP_E_SUCCESS)
goto error_handler;
}
temp_str = get_node_value( node );
if( temp_str == NULL ) {
temp_str = get_node_value(node);
if (!temp_str)
goto error_handler;
}
*upnp_error_code = atoi( temp_str );
if( *upnp_error_code < 400 ) {
*upnp_error_code = atoi(temp_str);
if (*upnp_error_code < 400) {
err_code = *upnp_error_code;
goto error_handler; // bad SOAP error code
goto error_handler; /* bad SOAP error code */
}
if( code == SOAP_VAR_RESP ) {
if( dom_find_node( "errorDescription", error_node, &node )
!= UPNP_E_SUCCESS ) {
if (code == SOAP_VAR_RESP) {
if (dom_find_node("errorDescription", error_node, &node)
!= UPNP_E_SUCCESS) {
goto error_handler;
}
nodeValue = get_node_value( node );
if( nodeValue == NULL ) {
nodeValue = get_node_value(node);
if (nodeValue == NULL) {
goto error_handler;
}
*str_value = ixmlCloneDOMString( nodeValue );
if( *str_value == NULL ) {
*str_value = ixmlCloneDOMString(nodeValue);
if (*str_value == NULL) {
goto error_handler;
}
err_code = SOAP_VAR_RESP_ERROR;
}
else if( code == SOAP_ACTION_RESP ) {
error_node_str = ixmlPrintNode( error_node );
if( error_node_str == NULL ) {
} else if (code == SOAP_ACTION_RESP) {
error_node_str = ixmlPrintNode(error_node);
if (error_node_str == NULL) {
err_code = UPNP_E_OUTOF_MEMORY;
goto error_handler;
}
if( ixmlParseBufferEx( error_node_str,
( IXML_Document ** ) action_value ) !=
IXML_SUCCESS ) {
if (ixmlParseBufferEx(error_node_str,
(IXML_Document **) action_value)
!= IXML_SUCCESS) {
err_code = UPNP_E_BAD_RESPONSE;
goto error_handler;
@@ -561,10 +491,9 @@ get_response_value( IN http_message_t * hmsg,
}
error_handler:
ixmlDocument_free( doc );
ixmlFreeDOMString( node_str );
ixmlFreeDOMString( error_node_str );
ixmlDocument_free(doc);
ixmlFreeDOMString(node_str);
ixmlFreeDOMString(error_node_str);
return err_code;
}
@@ -601,42 +530,42 @@ SoapSendAction( IN char *action_url,
uri_type url;
int upnp_error_code;
char *upnp_error_str;
xboolean got_response = FALSE;
int got_response = FALSE;
off_t content_length;
char *xml_start =
const char *xml_start =
"<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
"<s:Body>";
char *xml_end =
const char *xml_end =
"</s:Body>\r\n"
"</s:Envelope>\r\n\r\n";
size_t xml_start_len;
size_t xml_end_len;
size_t action_str_len;
*response_node = NULL; // init
*response_node = NULL; /* init */
err_code = UPNP_E_OUTOF_MEMORY; // default error
err_code = UPNP_E_OUTOF_MEMORY; /* default error */
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
"Inside SoapSendAction():" );
// init
/* init */
membuffer_init( &request );
membuffer_init( &responsename );
// print action
/* print action */
action_str = ixmlPrintNode( ( IXML_Node * ) action_node );
if( action_str == NULL ) {
goto error_handler;
}
// get action name
/* get action name */
if( get_action_name( action_str, &name ) != 0 ) {
err_code = UPNP_E_INVALID_ACTION;
goto error_handler;
}
// parse url
/* parse url */
if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
err_code = UPNP_E_INVALID_URL;
goto error_handler;
@@ -653,9 +582,9 @@ SoapSendAction( IN char *action_url,
xml_end_len = strlen( xml_end );
action_str_len = strlen( action_str );
// make request msg
/* make request msg */
request.size_inc = 50;
content_length = xml_start_len + action_str_len + xml_end_len;
content_length = (off_t)(xml_start_len + action_str_len + xml_end_len);
if (http_MakeMessage(
&request, 1, 1,
"q" "N" "s" "sssbsc" "Uc" "b" "b" "b",
@@ -680,7 +609,7 @@ SoapSendAction( IN char *action_url,
membuffer_append_str( &responsename, "Response" ) != 0 ) {
goto error_handler;
}
// get action node from the response
/* get action node from the response */
ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
responsename.buf, &upnp_error_code,
( IXML_Node ** ) response_node,
@@ -725,8 +654,8 @@ error_handler:
* returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
int
SoapSendActionEx( IN char *action_url,
int SoapSendActionEx(
IN char *action_url,
IN char *service_type,
IN IXML_Document * header,
IN IXML_Document * action_node,
@@ -743,19 +672,18 @@ SoapSendActionEx( IN char *action_url,
uri_type url;
int upnp_error_code;
char *upnp_error_str;
xboolean got_response = FALSE;
char *xml_start =
int got_response = FALSE;
const char *xml_start =
"<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n";
char *xml_header_start =
const char *xml_header_start =
"<s:Header>\r\n";
char *xml_header_end =
const char *xml_header_end =
"</s:Header>\r\n";
char *xml_body_start =
const char *xml_body_start =
"<s:Body>";
char *xml_end =
const char *xml_end =
"</s:Body>\r\n"
"</s:Envelope>\r\n";
size_t xml_start_len;
@@ -767,32 +695,32 @@ SoapSendActionEx( IN char *action_url,
size_t xml_end_len;
off_t content_length;
*response_node = NULL; // init
*response_node = NULL; /* init */
err_code = UPNP_E_OUTOF_MEMORY; // default error
err_code = UPNP_E_OUTOF_MEMORY; /* default error */
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
"Inside SoapSendActionEx():" );
// init
/* init */
membuffer_init( &request );
membuffer_init( &responsename );
// header string
/* header string */
xml_header_str = ixmlPrintNode( ( IXML_Node * ) header );
if( xml_header_str == NULL ) {
goto error_handler;
}
// print action
/* print action */
action_str = ixmlPrintNode( ( IXML_Node * ) action_node );
if( action_str == NULL ) {
goto error_handler;
}
// get action name
/* get action name */
if( get_action_name( action_str, &name ) != 0 ) {
err_code = UPNP_E_INVALID_ACTION;
goto error_handler;
}
// parse url
/* parse url */
if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
err_code = UPNP_E_INVALID_URL;
goto error_handler;
@@ -814,12 +742,11 @@ SoapSendActionEx( IN char *action_url,
xml_header_end_len = strlen( xml_header_end );
xml_header_str_len = strlen( xml_header_str );
// make request msg
/* make request msg */
request.size_inc = 50;
content_length =
xml_start_len +
xml_header_start_len + xml_header_str_len + xml_header_end_len +
xml_body_start_len + action_str_len + xml_end_len;
content_length = (off_t)(xml_start_len + xml_header_start_len +
xml_header_str_len + xml_header_end_len +
xml_body_start_len + action_str_len + xml_end_len);
if (http_MakeMessage(
&request, 1, 1,
"q" "N" "s" "sssbsc" "Uc" "b" "b" "b" "b" "b" "b" "b",
@@ -848,7 +775,7 @@ SoapSendActionEx( IN char *action_url,
membuffer_append_str( &responsename, "Response" ) != 0 ) {
goto error_handler;
}
// get action node from the response
/* get action node from the response */
ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
responsename.buf, &upnp_error_code,
( IXML_Node ** ) response_node,
@@ -896,40 +823,37 @@ SoapGetServiceVarStatus( IN char *action_url,
IN char *var_name,
OUT char **var_value )
{
const memptr host; // value for HOST header
const memptr path; // ctrl path in first line in msg
const memptr host; /* value for HOST header */
const memptr path; /* ctrl path in first line in msg */
uri_type url;
membuffer request;
int ret_code;
http_parser_t response;
int upnp_error_code;
off_t content_length;
char *xml_start =
const char *xml_start =
"<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
"<s:Body>\r\n"
"<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n"
"<u:varName>";
char *xml_end =
const char *xml_end =
"</u:varName>\r\n"
"</u:QueryStateVariable>\r\n"
"</s:Body>\r\n"
"</s:Envelope>\r\n";
*var_value = NULL; // return NULL in case of an error
*var_value = NULL; /* return NULL in case of an error */
membuffer_init( &request );
// get host hdr and url path
/* get host hdr and url path */
if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) {
return UPNP_E_INVALID_URL;
}
// make headers
/* make headers */
request.size_inc = 50;
content_length = strlen( xml_start ) + strlen( var_name ) + strlen( xml_end );
content_length = (off_t)(strlen(xml_start) + strlen(var_name) +
strlen(xml_end));
if (http_MakeMessage(
&request, 1, 1,
"Q" "sbc" "N" "s" "sc" "Ucc" "sss",
@@ -941,18 +865,16 @@ SoapGetServiceVarStatus( IN char *action_url,
xml_start, var_name, xml_end ) != 0 ) {
return UPNP_E_OUTOF_MEMORY;
}
// send msg and get reply
/* send msg and get reply */
ret_code = soap_request_and_response( &request, &url, &response );
membuffer_destroy( &request );
if( ret_code != UPNP_E_SUCCESS ) {
return ret_code;
}
// get variable value from the response
/* get variable value from the response */
ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL,
&upnp_error_code, NULL, var_value );
httpmsg_destroy( &response.msg );
if( ret_code == SOAP_VAR_RESP ) {
return UPNP_E_SUCCESS;
} else if( ret_code == SOAP_VAR_RESP_ERROR ) {
@@ -962,5 +884,6 @@ SoapGetServiceVarStatus( IN char *action_url,
}
}
#endif // EXCLUDE_SOAP
#endif // INCLUDE_CLIENT_APIS
#endif /* EXCLUDE_SOAP */
#endif /* INCLUDE_CLIENT_APIS */

File diff suppressed because it is too large Load Diff

View File

@@ -29,17 +29,13 @@
*
**************************************************************************/
#include "config.h"
#include "util.h"
#include "upnputil.h"
#ifdef INCLUDE_CLIENT_APIS
#if EXCLUDE_SSDP == 0
#include "httpparser.h"
#include "httpreadwrite.h"
/*#include "ssdp_ResultData.h"*/
@@ -50,15 +46,12 @@
#include "UpnpInet.h"
#include "ThreadPool.h"
#include <stdio.h>
#ifdef WIN32
#include <string.h>
#endif /* WIN32 */
/************************************************************************
* Function: send_search_result
*
@@ -88,7 +81,7 @@ void send_search_result(IN void *data)
* SSDP message from the device
* IN struct sockaddr *dest_addr:
* Address of the device
* IN xboolean timeout:
* IN int timeout:
* timeout kept by the control point while
* sending search message
* IN void* cookie:
@@ -107,18 +100,21 @@ void send_search_result(IN void *data)
void ssdp_handle_ctrlpt_msg(
IN http_message_t *hmsg,
IN struct sockaddr *dest_addr,
IN xboolean timeout, // only in search reply
IN void *cookie) // only in search reply
/* only in search reply */
IN int timeout,
/* only in search reply */
IN void *cookie)
{
int handle;
struct Handle_Info *ctrlpt_info = NULL;
memptr hdr_value;
xboolean is_byebye; // byebye or alive
/* byebye or alive */
int is_byebye;
struct Upnp_Discovery param;
SsdpEvent event;
xboolean nt_found;
xboolean usn_found;
xboolean st_found;
int nt_found;
int usn_found;
int st_found;
char save_char;
Upnp_EventType event_type;
Upnp_FunPtr ctrlpt_callback;
@@ -129,213 +125,202 @@ void ssdp_handle_ctrlpt_msg(
ResultData *threadData = NULL;
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 */
HandleReadLock();
if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
HandleUnlock();
return;
}
// copy
/* copy */
ctrlpt_callback = ctrlpt_info->Callback;
ctrlpt_cookie = ctrlpt_info->Cookie;
HandleUnlock();
// search timeout
if ( timeout ) {
ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
/* search timeout */
if (timeout) {
ctrlpt_callback(UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie);
return;
}
param.ErrCode = UPNP_E_SUCCESS;
// MAX-AGE
// assume error
/* MAX-AGE, assume error */
param.Expires = -1;
if ( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) {
if( matchstr( hdr_value.buf, hdr_value.length,
"%imax-age = %d%0", &param.Expires ) != PARSE_OK )
if (httpmsg_find_hdr(hmsg, HDR_CACHE_CONTROL, &hdr_value) != NULL) {
if (matchstr(hdr_value.buf, hdr_value.length,
"%imax-age = %d%0", &param.Expires) != PARSE_OK)
return;
}
// DATE
/* DATE */
param.Date[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) {
linecopylen( param.Date, hdr_value.buf, hdr_value.length );
if (httpmsg_find_hdr(hmsg, HDR_DATE, &hdr_value) != NULL) {
linecopylen(param.Date, hdr_value.buf, hdr_value.length);
}
// dest addr
memcpy(&param.DestAddr, dest_addr, sizeof(struct sockaddr_in) );
// EXT
/* dest addr */
memcpy(&param.DestAddr, dest_addr, sizeof(struct sockaddr_in));
/* EXT */
param.Ext[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) {
linecopylen( param.Ext, hdr_value.buf, hdr_value.length );
if (httpmsg_find_hdr(hmsg, HDR_EXT, &hdr_value) != NULL) {
linecopylen(param.Ext, hdr_value.buf, hdr_value.length);
}
// LOCATION
/* LOCATION */
param.Location[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) {
linecopylen( param.Location, hdr_value.buf, hdr_value.length );
if (httpmsg_find_hdr(hmsg, HDR_LOCATION, &hdr_value) != NULL) {
linecopylen(param.Location, hdr_value.buf, hdr_value.length);
}
// SERVER / USER-AGENT
/* SERVER / USER-AGENT */
param.Os[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL ||
httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) {
linecopylen( param.Os, hdr_value.buf, hdr_value.length );
if (httpmsg_find_hdr(hmsg, HDR_SERVER, &hdr_value) != NULL ||
httpmsg_find_hdr(hmsg, HDR_USER_AGENT, &hdr_value) != NULL) {
linecopylen(param.Os, hdr_value.buf, hdr_value.length);
}
// clear everything
/* clear everything */
param.DeviceId[0] = '\0';
param.DeviceType[0] = '\0';
param.ServiceType[0] = '\0';
param.ServiceVer[0] = '\0'; // not used; version is in ServiceType
/* not used; version is in ServiceType */
param.ServiceVer[0] = '\0';
event.UDN[0] = '\0';
event.DeviceType[0] = '\0';
event.ServiceType[0] = '\0';
nt_found = FALSE;
if ( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
if (httpmsg_find_hdr(hmsg, HDR_NT, &hdr_value) != NULL) {
save_char = hdr_value.buf[hdr_value.length];
hdr_value.buf[hdr_value.length] = '\0';
nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );
nt_found = (ssdp_request_type(hdr_value.buf, &event) == 0);
hdr_value.buf[hdr_value.length] = save_char;
}
usn_found = FALSE;
if ( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
if (httpmsg_find_hdr(hmsg, HDR_USN, &hdr_value) != NULL) {
save_char = hdr_value.buf[hdr_value.length];
hdr_value.buf[hdr_value.length] = '\0';
usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );
usn_found = (unique_service_name(hdr_value.buf, &event) == 0);
hdr_value.buf[hdr_value.length] = save_char;
}
if ( nt_found || usn_found ) {
strcpy( param.DeviceId, event.UDN );
strcpy( param.DeviceType, event.DeviceType );
strcpy( param.ServiceType, event.ServiceType );
if (nt_found || usn_found) {
strcpy(param.DeviceId, event.UDN);
strcpy(param.DeviceType, event.DeviceType);
strcpy(param.ServiceType, event.ServiceType);
}
// ADVERT. OR BYEBYE
if( hmsg->is_request ) {
// use NTS hdr to determine advert., or byebye
if ( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
return; // error; NTS header not found
/* ADVERT. OR BYEBYE */
if (hmsg->is_request) {
/* use NTS hdr to determine advert., or byebye */
if (httpmsg_find_hdr(hmsg, HDR_NTS, &hdr_value) == NULL) {
return; /* error; NTS header not found */
}
if ( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
if (memptr_cmp(&hdr_value, "ssdp:alive") == 0) {
is_byebye = FALSE;
} else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
} else if (memptr_cmp(&hdr_value, "ssdp:byebye") == 0) {
is_byebye = TRUE;
} else {
return; // bad value
return; /* bad value */
}
if ( is_byebye ) {
// check device byebye
if( !nt_found || !usn_found ) {
return; // bad byebye
if (is_byebye) {
/* check device byebye */
if (!nt_found || !usn_found) {
return; /* bad byebye */
}
event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
} else {
// check advertisement
// .Expires is valid if positive. This is for testing
// only. Expires should be greater than 1800 (30 mins)
if( !nt_found ||
/* check advertisement.
* Expires is valid if positive. This is for testing
* only. Expires should be greater than 1800 (30 mins) */
if (!nt_found ||
!usn_found ||
strlen( param.Location ) == 0 || param.Expires <= 0 ) {
return; // bad advertisement
strlen(param.Location) == 0 || param.Expires <= 0) {
return; /* bad advertisement */
}
event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
}
// call callback
ctrlpt_callback( event_type, &param, ctrlpt_cookie );
} else // reply (to a SEARCH)
{
// only checking to see if there is a valid ST header
/* call callback */
ctrlpt_callback(event_type, &param, ctrlpt_cookie);
} else {
/* reply (to a SEARCH) */
/* only checking to see if there is a valid ST header */
st_found = FALSE;
if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) {
if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) != NULL) {
save_char = hdr_value.buf[hdr_value.length];
hdr_value.buf[hdr_value.length] = '\0';
st_found = ssdp_request_type( hdr_value.buf, &event ) == 0;
st_found =
ssdp_request_type(hdr_value.buf, &event) == 0;
hdr_value.buf[hdr_value.length] = save_char;
}
if( hmsg->status_code != HTTP_OK ||
if (hmsg->status_code != HTTP_OK ||
param.Expires <= 0 ||
strlen( param.Location ) == 0 || !usn_found || !st_found ) {
return; // bad reply
strlen(param.Location) == 0 || !usn_found || !st_found) {
return; /* bad reply */
}
// check each current search
/* check each current search */
HandleLock();
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
HandleUnlock();
return;
}
node = ListHead( &ctrlpt_info->SsdpSearchList );
// temporary add null termination
//save_char = hdr_value.buf[ hdr_value.length ];
//hdr_value.buf[ hdr_value.length ] = '\0';
while( node != NULL ) {
node = ListHead(&ctrlpt_info->SsdpSearchList);
/* temporary add null termination */
/*save_char = hdr_value.buf[ hdr_value.length ]; */
/*hdr_value.buf[ hdr_value.length ] = '\0'; */
while (node != NULL) {
searchArg = node->item;
matched = 0;
// check for match of ST header and search target
switch ( searchArg->requestType ) {
/* check for match of ST header and search target */
switch (searchArg->requestType) {
case SSDP_ALL:
matched = 1;
break;
case SSDP_ROOTDEVICE:
matched = ( event.RequestType == SSDP_ROOTDEVICE );
matched =
(event.RequestType == SSDP_ROOTDEVICE);
break;
case SSDP_DEVICEUDN:
matched = !( strncmp( searchArg->searchTarget,
matched = !strncmp(searchArg->searchTarget,
hdr_value.buf,
hdr_value.length ) );
hdr_value.length);
break;
case SSDP_DEVICETYPE: {
int m = min( hdr_value.length,
strlen( searchArg->searchTarget ) );
matched = !( strncmp( searchArg->searchTarget,
hdr_value.buf, m ) );
case SSDP_DEVICETYPE:{
size_t m = min(hdr_value.length,
strlen(searchArg->
searchTarget));
matched = !strncmp(searchArg->searchTarget,
hdr_value.buf, m);
break;
}
case SSDP_SERVICE: {
int m = min( hdr_value.length,
strlen( searchArg->searchTarget ) );
matched = !( strncmp( searchArg->searchTarget,
hdr_value.buf, m ) );
case SSDP_SERVICE:{
size_t m = min(hdr_value.length,
strlen(searchArg->
searchTarget));
matched = !strncmp(searchArg->searchTarget,
hdr_value.buf, m);
break;
}
default:
matched = 0;
break;
}
if (matched) {
// schedule call back
/* schedule call back */
threadData =
( ResultData * ) malloc( sizeof( ResultData ) );
(ResultData *) malloc(sizeof(ResultData));
if (threadData != NULL) {
threadData->param = param;
threadData->cookie = searchArg->cookie;
threadData->ctrlpt_callback = ctrlpt_callback;
TPJobInit( &job, ( start_routine ) send_search_result,
threadData );
threadData->ctrlpt_callback =
ctrlpt_callback;
TPJobInit(&job,
(start_routine)
send_search_result,
threadData);
TPJobSetPriority(&job, MED_PRIORITY);
TPJobSetFreeFunction(&job, (free_routine)free);
ThreadPoolAdd(&gRecvThreadPool, &job, NULL);
TPJobSetFreeFunction(&job,
(free_routine)
free);
ThreadPoolAdd(&gRecvThreadPool, &job,
NULL);
}
}
node = ListNext( &ctrlpt_info->SsdpSearchList, node );
node = ListNext(&ctrlpt_info->SsdpSearchList, node);
}
HandleUnlock();
//ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie );
/*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie ); */
}
}
@@ -428,15 +413,14 @@ static void CreateClientRequestPacketUlaGua(
* Returns: void
*
***************************************************************************/
void
searchExpired( void *arg )
void searchExpired(void *arg)
{
int *id = ( int * )arg;
int *id = (int *)arg;
int handle = -1;
struct Handle_Info *ctrlpt_info = NULL;
//remove search Target from list and call client back
/* remove search Target from list and call client back */
ListNode *node = NULL;
SsdpSearchArg *item;
Upnp_FunPtr ctrlpt_callback;
@@ -445,18 +429,14 @@ searchExpired( void *arg )
HandleLock();
//remove search target from search list
/* remove search target from search list */
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
free( id );
HandleUnlock();
return;
}
ctrlpt_callback = ctrlpt_info->Callback;
node = ListHead( &ctrlpt_info->SsdpSearchList );
while( node != NULL ) {
item = ( SsdpSearchArg * ) node->item;
if( item->timeoutEventId == ( *id ) ) {
@@ -528,7 +508,7 @@ int SearchByTarget(
unsigned long addrv4 = inet_addr(gIF_IPV4);
int max_fd = 0;
//ThreadData *ThData;
/*ThreadData *ThData;*/
ThreadPoolJob job;
requestType = ssdp_request_type1(St);
@@ -644,7 +624,7 @@ int SearchByTarget(
imillisleep(SSDP_PAUSE);
}
}
#endif //IPv6
#endif /* IPv6 */
if (gSsdpReqSocket4 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket4, &wrSet)) {
@@ -665,5 +645,6 @@ int SearchByTarget(
return 1;
}
#endif // EXCLUDE_SSDP
#endif // INCLUDE_CLIENT_APIS
#endif /* EXCLUDE_SSDP */
#endif /* INCLUDE_CLIENT_APIS */

View File

@@ -120,34 +120,38 @@ void ssdp_handle_device_request(
int replyTime;
int maxAge;
// check man hdr
/* check man hdr. */
if( httpmsg_find_hdr( hmsg, HDR_MAN, &hdr_value ) == NULL ||
memptr_cmp( &hdr_value, "\"ssdp:discover\"" ) != 0 ) {
return; // bad or missing hdr
/* bad or missing hdr. */
return;
}
// MX header
/* MX header. */
if( httpmsg_find_hdr( hmsg, HDR_MX, &hdr_value ) == NULL ||
( mx = raw_to_int( &hdr_value, 10 ) ) < 0 ) {
return;
}
// ST header
/* ST header. */
if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) == NULL ) {
return;
}
save_char = hdr_value.buf[hdr_value.length];
hdr_value.buf[hdr_value.length] = '\0';
ret_code = ssdp_request_type( hdr_value.buf, &event );
hdr_value.buf[hdr_value.length] = save_char; // restore
/* restore. */
hdr_value.buf[hdr_value.length] = save_char;
if( ret_code == -1 ) {
return; // bad ST header
/* bad ST header. */
return;
}
HandleLock();
// device info
/* device info. */
if( GetDeviceHandleInfo( dest_addr->sa_family,
&handle, &dev_info ) != HND_DEVICE ) {
HandleUnlock();
return; // no info found
/* no info found. */
return;
}
maxAge = dev_info->MaxAge;
HandleUnlock();
@@ -180,11 +184,9 @@ void ssdp_handle_device_request(
TPJobInit( &job, advertiseAndReplyThread, threadArg );
TPJobSetFreeFunction( &job, ( free_routine ) free );
//Subtract a percentage from the mx
//to allow for network and processing delays
// (i.e. if search is for 30 seconds,
// respond withing 0 - 27 seconds)
/* Subtract a percentage from the mx to allow for network and processing
* delays (i.e. if search is for 30 seconds, respond
* within 0 - 27 seconds). */
if( mx >= 2 ) {
mx -= MAXVAL( 1, mx / MX_FUDGE_FACTOR );
}
@@ -215,94 +217,73 @@ void ssdp_handle_device_request(
* Returns: void *
* 1 if successful else appropriate error
***************************************************************************/
static int
NewRequestHandler( IN struct sockaddr *DestAddr,
IN int NumPacket,
IN char **RqPacket )
static int NewRequestHandler(IN struct sockaddr *DestAddr, IN int NumPacket,
IN char **RqPacket)
{
char errorBuffer[ERROR_BUFFER_LEN];
SOCKET ReplySock;
int socklen = sizeof( struct sockaddr_storage );
int NumCopy;
socklen_t socklen = sizeof(struct sockaddr_storage);
int Index;
unsigned long replyAddr = inet_addr( gIF_IPV4 );
int ttl = 4; // a/c to UPNP Spec
unsigned long replyAddr = inet_addr(gIF_IPV4);
/* a/c to UPNP Spec */
int ttl = 4;
int hops = 1;
char buf_ntop[64];
int ret = UPNP_E_SUCCESS;
ReplySock = socket( DestAddr->sa_family, SOCK_DGRAM, 0 );
if ( ReplySock == -1 ) {
ReplySock = socket(DestAddr->sa_family, SOCK_DGRAM, 0);
if (ReplySock == -1) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP_LIB: New Request Handler:"
"Error in socket(): %s\n", errorBuffer );
"Error in socket(): %s\n", errorBuffer);
return UPNP_E_OUTOF_SOCKET;
}
if( DestAddr->sa_family == AF_INET ) {
inet_ntop(AF_INET, &((struct sockaddr_in*)DestAddr)->sin_addr,
if (DestAddr->sa_family == AF_INET) {
inet_ntop(AF_INET, &((struct sockaddr_in *)DestAddr)->sin_addr,
buf_ntop, sizeof(buf_ntop));
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&replyAddr, sizeof (replyAddr) );
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&ttl, sizeof (int) );
setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&replyAddr, sizeof(replyAddr));
setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&ttl, sizeof(int));
socklen = sizeof(struct sockaddr_in);
} else if( DestAddr->sa_family == AF_INET6 ) {
inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr,
} else if (DestAddr->sa_family == AF_INET6) {
inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)DestAddr)->sin6_addr,
buf_ntop, sizeof(buf_ntop));
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char *)&gIF_INDEX, sizeof(gIF_INDEX) );
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(char *)&hops, sizeof(hops) );
setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char *)&gIF_INDEX, sizeof(gIF_INDEX));
setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(char *)&hops, sizeof(hops));
} else {
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Invalid destination address specified." );
UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Invalid destination address specified.");
ret = UPNP_E_NETWORK_ERROR;
goto end_NewRequestHandler;
}
for( Index = 0; Index < NumPacket; Index++ ) {
int rc;
// The reason to keep this loop is purely historical/documentation,
// according to section 9.2 of HTTPU spec:
//
// "If a multicast resource would send a response(s) to any copy of the
// request, it SHOULD send its response(s) to each copy of the request
// it receives. It MUST NOT repeat its response(s) per copy of the
// request."
//
// http://www.upnp.org/download/draft-goland-http-udp-04.txt
//
// So, NUM_COPY has been changed from 2 to 1.
NumCopy = 0;
while( NumCopy < NUM_COPY ) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
for (Index = 0; Index < NumPacket; Index++) {
ssize_t rc;
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND to %s >>>\n%s\n",
buf_ntop, *( RqPacket + Index ) );
rc = sendto( ReplySock, *( RqPacket + Index ),
strlen( *( RqPacket + Index ) ),
0, DestAddr, socklen );
buf_ntop, *(RqPacket + Index));
rc = sendto(ReplySock, *(RqPacket + Index),
strlen(*(RqPacket + Index)), 0, DestAddr, socklen);
if (rc == -1) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP_LIB: New Request Handler:"
"Error in socket(): %s\n", errorBuffer );
"Error in socket(): %s\n", errorBuffer);
ret = UPNP_E_SOCKET_WRITE;
goto end_NewRequestHandler;
}
imillisleep( SSDP_PAUSE );
++NumCopy;
}
}
end_NewRequestHandler:
shutdown( ReplySock, SD_BOTH );
UpnpCloseSocket( ReplySock );
end_NewRequestHandler:
shutdown(ReplySock, SD_BOTH);
UpnpCloseSocket(ReplySock);
return ret;
}
@@ -383,9 +364,9 @@ int isUrlV6UlaGua(char *descdocUrl)
* Returns: void
*
***************************************************************************/
void CreateServicePacket(
static void CreateServicePacket(
IN int msg_type,
IN char *nt,
const IN char *nt,
IN char *usn,
IN char *location,
IN int duration,
@@ -393,7 +374,7 @@ void CreateServicePacket(
IN int AddressFamily)
{
int ret_code;
char *nts;
const char *nts;
membuffer buf;
/* Notf == 0 means service shutdown,
@@ -421,24 +402,23 @@ void CreateServicePacket(
}
} else if (msg_type == MSGTYPE_ADVERTISEMENT ||
msg_type == MSGTYPE_SHUTDOWN) {
char *host = NULL;
if (msg_type == MSGTYPE_ADVERTISEMENT) {
const char *host = NULL;
if (msg_type == MSGTYPE_ADVERTISEMENT)
nts = "ssdp:alive";
} else {
else
/* shutdown */
nts = "ssdp:byebye";
}
/* NOTE: The CACHE-CONTROL and LOCATION headers are not present in
* a shutdown msg, but are present here for MS WinMe interop. */
if (AddressFamily == AF_INET) {
if (AddressFamily == AF_INET)
host = SSDP_IP;
} else {
if (isUrlV6UlaGua(location)) {
else {
if (isUrlV6UlaGua(location))
host = "[" SSDP_IPV6_SITELOCAL "]";
} else {
else
host = "[" SSDP_IPV6_LINKLOCAL "]";
}
}
ret_code = http_MakeMessage(
&buf, 1, 1,
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
@@ -453,14 +433,11 @@ void CreateServicePacket(
"NTS: ", nts,
X_USER_AGENT,
"USN: ", usn );
if (ret_code != 0) {
if (ret_code)
return;
}
} else {
} else
/* unknown msg */
assert(0);
}
/* return msg */
*packet = membuffer_detach(&buf);
membuffer_destroy(&buf);
@@ -499,10 +476,10 @@ DeviceAdvertisement( IN char *DevType,
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
//char Mil_Nt[LINE_SIZE]
/* char Mil_Nt[LINE_SIZE] */
char Mil_Usn[LINE_SIZE];
char *msgs[3];
int ret_code;
int ret_code = UPNP_E_SUCCESS;
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"In function DeviceAdvertisement\n" );
@@ -528,24 +505,20 @@ DeviceAdvertisement( IN char *DevType,
msgs[1] = NULL;
msgs[2] = NULL;
//If deviceis a root device , here we need to
//send 3 advertisement or reply
/* If deviceis a root device , here we need to send 3 advertisement
* or reply */
if( RootDev ) {
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
}
// both root and sub-devices need to send these two messages
//
/* both root and sub-devices need to send these two messages */
CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
Location, Duration, &msgs[1], AddressFamily );
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
Location, Duration, &msgs[2], AddressFamily );
// check error
/* check error */
if( ( RootDev && msgs[0] == NULL ) ||
msgs[1] == NULL || msgs[2] == NULL ) {
free( msgs[0] );
@@ -553,17 +526,17 @@ DeviceAdvertisement( IN char *DevType,
free( msgs[2] );
return UPNP_E_OUTOF_MEMORY;
}
// send packets
/* send packets */
if( RootDev ) {
// send 3 msg types
/* send 3 msg types */
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
} else // sub-device
} else /* sub-device */
{
// send 2 msg types
/* send 2 msg types */
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
}
// free msgs
/* free msgs */
free( msgs[0] );
free( msgs[1] );
free( msgs[2] );
@@ -609,17 +582,17 @@ SendReply( IN struct sockaddr *DestAddr,
msgs[1] = NULL;
if( RootDev ) {
// one msg for root device
/* one msg for root device */
num_msgs = 1;
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], DestAddr->sa_family );
} else {
// two msgs for embedded devices
/* two msgs for embedded devices */
num_msgs = 1;
//NK: FIX for extra response when someone searches by udn
/*NK: FIX for extra response when someone searches by udn */
if( !ByType ) {
CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
Duration, &msgs[0], DestAddr->sa_family );
@@ -630,7 +603,7 @@ SendReply( IN struct sockaddr *DestAddr,
}
}
// check error
/* check error */
for( i = 0; i < num_msgs; i++ ) {
if( msgs[i] == NULL ) {
free( msgs[0] );
@@ -638,7 +611,7 @@ SendReply( IN struct sockaddr *DestAddr,
}
}
// send msgs
/* send msgs */
ret_code = NewRequestHandler( DestAddr, num_msgs, msgs );
for( i = 0; i < num_msgs; i++ ) {
if( msgs[i] != NULL )
@@ -682,28 +655,23 @@ DeviceReply( IN struct sockaddr *DestAddr,
szReq[1] = NULL;
szReq[2] = NULL;
// create 2 or 3 msgs
/* create 2 or 3 msgs */
if( RootDev ) {
// 3 replies for root device
/* 3 replies for root device */
strcpy( Mil_Nt, "upnp:rootdevice" );
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[0], DestAddr->sa_family );
}
sprintf( Mil_Nt, "%s", Udn );
sprintf( Mil_Usn, "%s", Udn );
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[1], DestAddr->sa_family );
sprintf( Mil_Nt, "%s", DevType );
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
Location, Duration, &szReq[2], DestAddr->sa_family );
// check error
/* check error */
if( ( RootDev && szReq[0] == NULL ) ||
szReq[1] == NULL || szReq[2] == NULL ) {
free( szReq[0] );
@@ -711,14 +679,13 @@ DeviceReply( IN struct sockaddr *DestAddr,
free( szReq[2] );
return UPNP_E_OUTOF_MEMORY;
}
// send replies
/* send replies */
if( RootDev ) {
RetVal = NewRequestHandler( DestAddr, 3, szReq );
} else {
RetVal = NewRequestHandler( DestAddr, 2, &szReq[1] );
}
// free
/* free */
free( szReq[0] );
free( szReq[1] );
free( szReq[2] );
@@ -751,7 +718,7 @@ ServiceAdvertisement( IN char *Udn,
{
char Mil_Usn[LINE_SIZE];
char *szReq[1];
int RetVal;
int RetVal = UPNP_E_SUCCESS;
struct sockaddr_storage __ss;
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
@@ -775,8 +742,8 @@ ServiceAdvertisement( IN char *Udn,
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
//CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
//Server,Location,Duration);
/* CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
* Server,Location,Duration); */
CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
Location, Duration, &szReq[0], AddressFamily );
if( szReq[0] == NULL ) {
@@ -860,7 +827,7 @@ ServiceShutdown( IN char *Udn,
struct sockaddr_storage __ss;
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
int RetVal;
int RetVal = UPNP_E_SUCCESS;
memset( &__ss, 0, sizeof(__ss) );
if( AddressFamily == AF_INET ) {
@@ -879,10 +846,10 @@ ServiceShutdown( IN char *Udn,
"Invalid device address family.\n" );
}
//sprintf(Mil_Nt,"%s",ServType);
/* sprintf(Mil_Nt,"%s",ServType); */
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
//CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
//Server,Location,Duration);
/* CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
* Server,Location,Duration); */
CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
Location, Duration, &szReq[0], AddressFamily );
if( szReq[0] == NULL ) {
@@ -926,7 +893,7 @@ DeviceShutdown( IN char *DevType,
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
char *msgs[3];
char Mil_Usn[LINE_SIZE];
int ret_code;
int ret_code = UPNP_E_SUCCESS;
msgs[0] = NULL;
msgs[1] = NULL;
@@ -948,25 +915,21 @@ DeviceShutdown( IN char *DevType,
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Invalid device address family.\n" );
}
// root device has one extra msg
/* root device has one extra msg */
if( RootDev ) {
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
}
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"In function DeviceShutdown\n" );
// both root and sub-devices need to send these two messages
/* both root and sub-devices need to send these two messages */
CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
Location, Duration, &msgs[1], AddressFamily );
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
Location, Duration, &msgs[2], AddressFamily );
// check error
/* check error */
if( ( RootDev && msgs[0] == NULL ) ||
msgs[1] == NULL || msgs[2] == NULL ) {
free( msgs[0] );
@@ -974,24 +937,24 @@ DeviceShutdown( IN char *DevType,
free( msgs[2] );
return UPNP_E_OUTOF_MEMORY;
}
// send packets
/* send packets */
if( RootDev ) {
// send 3 msg types
/* send 3 msg types */
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
} else // sub-device
{
// send 2 msg types
} else {
/* sub-device */
/* send 2 msg types */
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
}
// free msgs
/* free msgs */
free( msgs[0] );
free( msgs[1] );
free( msgs[2] );
return ret_code;
_Server = _Server;
}
#endif // EXCLUDE_SSDP
#endif // INCLUDE_DEVICE_APIS
#endif /* EXCLUDE_SSDP */
#endif /* INCLUDE_DEVICE_APIS */

View File

@@ -120,8 +120,8 @@ int AdvertiseAndReply(
int Exp)
{
int retVal = UPNP_E_SUCCESS;
int i;
int j;
long unsigned int i;
long unsigned int j;
int defaultExp = DEFAULT_MAXAGE;
struct Handle_Info *SInfo = NULL;
char UDNstr[100];
@@ -135,6 +135,7 @@ int AdvertiseAndReply(
const DOMString tmpStr;
char SERVER[200];
const DOMString dbgStr;
int NumCopy = 0;
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Inside AdvertiseAndReply with AdFlag = %d\n", AdFlag);
@@ -152,41 +153,43 @@ int AdvertiseAndReply(
get_sdk_info(SERVER);
/* parse the device list and send advertisements/replies */
while (NumCopy == 0 || (AdFlag && NumCopy < NUM_SSDP_COPY)) {
if (NumCopy != 0)
imillisleep(SSDP_PAUSE);
NumCopy++;
for (i = 0;; i++) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Entering new device list with i = %d\n\n", i);
"Entering new device list with i = %lu\n\n", i);
tmpNode = ixmlNodeList_item(SInfo->DeviceList, i);
if (!tmpNode) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Exiting new device list with i = %d\n\n", i);
"Exiting new device list with i = %lu\n\n", i);
break;
}
dbgStr = ixmlNode_getNodeName(tmpNode);
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
"Extracting device type once for %s\n", dbgStr);
ixmlNodeList_free(nodeList);
nodeList = ixmlElement_getElementsByTagName(
(IXML_Element *)tmpNode, "deviceType");
if (!nodeList) continue;
if (!nodeList)
continue;
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Extracting UDN for %s\n", dbgStr);
dbgStr = ixmlNode_getNodeName(tmpNode);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Extracting device type\n");
tmpNode2 = ixmlNodeList_item(nodeList, 0);
if (!tmpNode2) continue;
if (!tmpNode2)
continue;
textNode = ixmlNode_getFirstChild(tmpNode2);
if (!textNode) continue;
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Extracting device type \n");
tmpStr = ixmlNode_getNodeValue(textNode);
if (!tmpStr) continue;
if (!tmpStr)
continue;
strcpy(devType, tmpStr);
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Extracting device type = %s\n", devType);
@@ -195,7 +198,6 @@ int AdvertiseAndReply(
"TempNode is NULL\n");
}
dbgStr = ixmlNode_getNodeName(tmpNode);
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Extracting UDN for %s\n", dbgStr);
ixmlNodeList_free(nodeList);
@@ -220,8 +222,8 @@ int AdvertiseAndReply(
}
tmpStr = ixmlNode_getNodeValue(textNode);
if (!tmpStr) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"UDN not found!\n");
UpnpPrintf(UPNP_CRITICAL, API, __FILE__,
__LINE__, "UDN not found!\n");
continue;
}
strcpy(UDNstr, tmpStr);
@@ -231,11 +233,13 @@ int AdvertiseAndReply(
/* send the device advertisement */
if (AdFlag == 1) {
DeviceAdvertisement(devType, i == 0,
UDNstr, SInfo->DescURL, Exp, SInfo->DeviceAf );
UDNstr, SInfo->DescURL, Exp,
SInfo->DeviceAf);
} else {
/* AdFlag == -1 */
DeviceShutdown(devType, i == 0, UDNstr,
SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf );
SERVER, SInfo->DescURL, Exp,
SInfo->DeviceAf);
}
} else {
switch (SearchType) {
@@ -392,6 +396,7 @@ int AdvertiseAndReply(
ixmlNodeList_free(nodeList);
nodeList = NULL;
}
}
end_function:
ixmlNodeList_free(tmpNodeList);
@@ -461,78 +466,64 @@ int unique_service_name(IN char *cmd, IN SsdpEvent *Evt)
char *ptr2 = NULL;
char *ptr3 = NULL;
int CommandFound = 0;
int length = 0;
size_t n = 0;
if( ( TempPtr = strstr( cmd, "uuid:schemas" ) ) != NULL ) {
ptr1 = strstr( cmd, ":device" );
if( ptr1 != NULL ) {
ptr2 = strstr( ptr1 + 1, ":" );
} else {
if ((TempPtr = strstr(cmd, "uuid:schemas")) != NULL) {
ptr1 = strstr(cmd, ":device");
if (ptr1 != NULL)
ptr2 = strstr(ptr1 + 1, ":");
else
return -1;
}
if( ptr2 != NULL ) {
ptr3 = strstr( ptr2 + 1, ":" );
} else {
if (ptr2 != NULL)
ptr3 = strstr(ptr2 + 1, ":");
else
return -1;
}
if( ptr3 != NULL ) {
sprintf( Evt->UDN, "uuid:%s", ptr3 + 1 );
} else {
if (ptr3 != NULL)
sprintf(Evt->UDN, "uuid:%s", ptr3 + 1);
else
return -1;
}
ptr1 = strstr( cmd, ":" );
if( ptr1 != NULL ) {
strncpy( TempBuf, ptr1, ptr3 - ptr1 );
TempBuf[ptr3 - ptr1] = '\0';
sprintf( Evt->DeviceType, "urn%s", TempBuf );
} else {
ptr1 = strstr(cmd, ":");
if (ptr1 != NULL) {
n = (size_t)(ptr3 - ptr1);
strncpy(TempBuf, ptr1, n);
TempBuf[n] = '\0';
sprintf(Evt->DeviceType, "urn%s", TempBuf);
} else
return -1;
}
return 0;
}
if( ( TempPtr = strstr( cmd, "uuid" ) ) != NULL ) {
if( ( Ptr = strstr( cmd, "::" ) ) != NULL ) {
strncpy( Evt->UDN, TempPtr, Ptr - TempPtr );
Evt->UDN[Ptr - TempPtr] = '\0';
} else {
strcpy( Evt->UDN, TempPtr );
}
if ((TempPtr = strstr(cmd, "uuid")) != NULL) {
if ((Ptr = strstr(cmd, "::")) != NULL) {
n = (size_t)(Ptr - TempPtr);
strncpy(Evt->UDN, TempPtr, n);
Evt->UDN[n] = '\0';
} else
strcpy(Evt->UDN, TempPtr);
CommandFound = 1;
}
if( strstr( cmd, "urn:" ) != NULL
&& strstr( cmd, ":service:" ) != NULL ) {
if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
strcpy( Evt->ServiceType, TempPtr );
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":service:") != NULL) {
if ((TempPtr = strstr(cmd, "urn")) != NULL) {
strcpy(Evt->ServiceType, TempPtr);
CommandFound = 1;
}
}
if( strstr( cmd, "urn:" ) != NULL
&& strstr( cmd, ":device:" ) != NULL ) {
if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
strcpy( Evt->DeviceType, TempPtr );
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":device:") != NULL) {
if ((TempPtr = strstr(cmd, "urn")) != NULL) {
strcpy(Evt->DeviceType, TempPtr);
CommandFound = 1;
}
}
if( ( TempPtr = strstr( cmd, "::upnp:rootdevice" ) ) != NULL ) {
if ((TempPtr = strstr(cmd, "::upnp:rootdevice")) != NULL) {
/* Everything before "::upnp::rootdevice" is the UDN. */
if( TempPtr != cmd ) {
length = TempPtr - cmd;
strncpy(Evt->UDN, cmd, length);
Evt->UDN[length] = 0;
if (TempPtr != cmd) {
n = (size_t)(TempPtr - cmd);
strncpy(Evt->UDN, cmd, n);
Evt->UDN[n] = 0;
CommandFound = 1;
}
}
if( CommandFound == 0 ) {
if (CommandFound == 0)
return -1;
}
return 0;
}
@@ -588,11 +579,9 @@ ssdp_request_type1( IN char *cmd )
* Returns: int
* 0 on success; -1 on error
***************************************************************************/
int
ssdp_request_type( IN char *cmd,
OUT SsdpEvent * Evt )
int ssdp_request_type(IN char *cmd, OUT SsdpEvent *Evt)
{
// clear event
/* clear event */
memset( Evt, 0, sizeof( SsdpEvent ) );
unique_service_name( cmd, Evt );
Evt->ErrCode = NO_ERROR_FOUND;
@@ -617,15 +606,13 @@ ssdp_request_type( IN char *cmd,
* Returns: VOID
*
***************************************************************************/
static void
free_ssdp_event_handler_data( void *the_data )
static void free_ssdp_event_handler_data(void *the_data)
{
ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;
if( data != NULL ) {
http_message_t *hmsg = &data->parser.msg;
// free data
/* free data */
httpmsg_destroy( hmsg );
free( data );
}
@@ -641,10 +628,10 @@ free_ssdp_event_handler_data( void *the_data )
* Description:
* This function do some quick checking of the ssdp msg
*
* Returns: xboolean
* Returns: int
* returns TRUE if msg is valid else FALSE
***************************************************************************/
static UPNP_INLINE xboolean valid_ssdp_msg(IN http_message_t *hmsg)
static UPNP_INLINE int valid_ssdp_msg(IN http_message_t *hmsg)
{
memptr hdr_value;
@@ -692,8 +679,7 @@ static UPNP_INLINE xboolean valid_ssdp_msg(IN http_message_t *hmsg)
* Returns: int
* 0 if successful -1 if error
***************************************************************************/
static UPNP_INLINE int
start_event_handler( void *Data )
static UPNP_INLINE int start_event_handler(void *Data)
{
http_parser_t *parser = NULL;
@@ -709,23 +695,23 @@ start_event_handler( void *Data )
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP recvd bad msg code = %d\n",
status );
// ignore bad msg, or not enuf mem
/* ignore bad msg, or not enuf mem */
goto error_handler;
}
// valid notify msg
/* valid notify msg */
} else if( status != PARSE_SUCCESS ) {
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
"SSDP recvd bad msg code = %d\n", status );
goto error_handler;
}
// check msg
/* check msg */
if( valid_ssdp_msg( &parser->msg ) != TRUE ) {
goto error_handler;
}
return 0; //////// done; thread will free 'data'
return 0; /* done; thread will free 'data' */
error_handler:
error_handler:
free_ssdp_event_handler_data( data );
return -1;
}
@@ -777,107 +763,85 @@ static void ssdp_event_handler_thread(void *the_data)
* Returns: void
*
***************************************************************************/
void
readFromSSDPSocket( SOCKET socket )
void readFromSSDPSocket(SOCKET socket)
{
char *requestBuf = NULL;
char staticBuf[BUFSIZE];
struct sockaddr_storage __ss;
ThreadPoolJob job;
ssdp_thread_data *data = NULL;
socklen_t socklen = sizeof( __ss );
int byteReceived = 0;
socklen_t socklen = sizeof(__ss);
ssize_t byteReceived = 0;
char ntop_buf[64];
requestBuf = staticBuf;
//in case memory
//can't be allocated, still drain the
//socket using a static buffer
data = ( ssdp_thread_data * )
malloc( sizeof( ssdp_thread_data ) );
if( data != NULL ) {
//initialize parser
/* in case memory can't be allocated, still drain the socket using a
* static buffer. */
data = malloc(sizeof(ssdp_thread_data));
if (data) {
/* initialize parser */
#ifdef INCLUDE_CLIENT_APIS
#ifdef UPNP_ENABLE_IPV6
if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) {
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
} else {
parser_request_init( &data->parser );
}
#else
if( socket == gSsdpReqSocket4 ) {
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
} else {
parser_request_init( &data->parser );
}
#endif
#else
parser_request_init( &data->parser );
#endif
//set size of parser buffer
if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) {
//use this as the buffer for recv
if (socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6)
parser_response_init(&data->parser, HTTPMETHOD_MSEARCH);
else
parser_request_init(&data->parser);
#else /* UPNP_ENABLE_IPV6 */
if (socket == gSsdpReqSocket4)
parser_response_init(&data->parser, HTTPMETHOD_MSEARCH);
else
parser_request_init(&data->parser);
#endif /* UPNP_ENABLE_IPV6 */
#else /* INCLUDE_CLIENT_APIS */
parser_request_init(&data->parser);
#endif /* INCLUDE_CLIENT_APIS */
/* set size of parser buffer */
if (membuffer_set_size(&data->parser.msg.msg, BUFSIZE) == 0)
/* use this as the buffer for recv */
requestBuf = data->parser.msg.msg.buf;
} else {
free( data );
else {
free(data);
data = NULL;
}
}
byteReceived = recvfrom( socket, requestBuf,
BUFSIZE - 1, 0,
(struct sockaddr *)&__ss, &socklen );
if( byteReceived > 0 ) {
byteReceived = recvfrom(socket, requestBuf, BUFSIZE - 1, 0,
(struct sockaddr *)&__ss, &socklen);
if (byteReceived > 0) {
requestBuf[byteReceived] = '\0';
if( __ss.ss_family == AF_INET )
inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) );
if (__ss.ss_family == AF_INET)
inet_ntop(AF_INET,
&((struct sockaddr_in *)&__ss)->sin_addr,
ntop_buf, sizeof(ntop_buf));
#ifdef UPNP_ENABLE_IPV6
else if( __ss.ss_family == AF_INET6 )
inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) );
else if (__ss.ss_family == AF_INET6)
inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)&__ss)->sin6_addr,
ntop_buf, sizeof(ntop_buf));
#endif
else
strncpy( ntop_buf, "<Invalid address family>", sizeof(ntop_buf) );
UpnpPrintf( UPNP_INFO, SSDP,
__FILE__, __LINE__,
strncpy(ntop_buf, "<Invalid address family>",
sizeof(ntop_buf));
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
"Start of received response ----------------------------------------------------\n"
"%s\n"
"End of received response ------------------------------------------------------\n"
"From host %s\n",
requestBuf,
ntop_buf );
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
"Start of received multicast packet --------------------------------------------\n"
"%s\n"
"End of received multicast packet ----------------------------------------------\n",
requestBuf );
//add thread pool job to handle request
if( data != NULL ) {
data->parser.msg.msg.length += byteReceived;
// null-terminate
"From host %s\n", requestBuf, ntop_buf);
/* add thread pool job to handle request */
if (data != NULL) {
data->parser.msg.msg.length += (size_t)byteReceived;
/* null-terminate */
data->parser.msg.msg.buf[byteReceived] = 0;
memcpy( &data->dest_addr, &__ss, sizeof(__ss) );
TPJobInit( &job, ( start_routine )
ssdp_event_handler_thread, data );
TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
TPJobSetPriority( &job, MED_PRIORITY );
if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {
free_ssdp_event_handler_data( data );
}
}
} else {
free_ssdp_event_handler_data( data );
memcpy(&data->dest_addr, &__ss, sizeof(__ss));
TPJobInit(&job, (start_routine)
ssdp_event_handler_thread, data);
TPJobSetFreeFunction(&job,
free_ssdp_event_handler_data);
TPJobSetPriority(&job, MED_PRIORITY);
if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0)
free_ssdp_event_handler_data(data);
}
} else
free_ssdp_event_handler_data(data);
}
@@ -910,10 +874,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
}
/* For use by ssdp control point. */
gSsdpReqSocket4 = out->ssdpReqSock4;
} else {
} else
out->ssdpReqSock4 = INVALID_SOCKET;
}
/* Create the IPv6 socket for SSDP REQUESTS */
#ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) {
@@ -925,14 +887,10 @@ int get_ssdp_sockets(MiniServerSockArray *out)
}
/* For use by ssdp control point. */
gSsdpReqSocket6 = out->ssdpReqSock6;
} else {
} else
out->ssdpReqSock6 = INVALID_SOCKET;
}
#endif //IPv6
#endif /* IPv6 */
#endif /* INCLUDE_CLIENT_APIS */
/* Create the IPv4 socket for SSDP */
if (strlen(gIF_IPV4) > 0) {
retVal = create_ssdp_sock_v4(&out->ssdpSock4);
@@ -945,10 +903,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif
return retVal;
}
} else {
} else
out->ssdpSock4 = INVALID_SOCKET;
}
/* Create the IPv6 socket for SSDP */
#ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) {
@@ -964,10 +920,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif
return retVal;
}
} else {
} else
out->ssdpSock6 = INVALID_SOCKET;
}
if (strlen(gIF_IPV6_ULA_GUA) > 0) {
retVal = create_ssdp_sock_v6_ula_gua(&out->ssdpSock6UlaGua);
if (retVal != UPNP_E_SUCCESS) {
@@ -983,11 +937,9 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif
return retVal;
}
} else {
} else
out->ssdpSock6UlaGua = INVALID_SOCKET;
}
#endif //IPv6
#endif /* IPv6 */
return UPNP_E_SUCCESS;
}
@@ -1007,24 +959,22 @@ int get_ssdp_sockets(MiniServerSockArray *out)
* Returns:
* UPNP_E_SUCCESS on successful socket creation.
***************************************************************************/
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock )
int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock)
{
char errorBuffer[ERROR_BUFFER_LEN];
u_char ttl = 4;
*ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );
if ( *ssdpReqSock == -1 ) {
*ssdpReqSock = socket(AF_INET, SOCK_DGRAM, 0);
if (*ssdpReqSock == -1) {
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Error in socket(): %s\n", errorBuffer );
UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Error in socket(): %s\n", errorBuffer);
return UPNP_E_OUTOF_SOCKET;
}
setsockopt( *ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, sizeof (ttl) );
// just do it, regardless if fails or not.
Make_Socket_NoBlocking( *ssdpReqSock );
setsockopt(*ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
&ttl, sizeof(ttl));
/* just do it, regardless if fails or not. */
Make_Socket_NoBlocking(*ssdpReqSock);
return UPNP_E_SUCCESS;
}
@@ -1057,18 +1007,18 @@ int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock )
return UPNP_E_OUTOF_SOCKET;
}
// MUST use scoping of IPv6 addresses to control the propagation os SSDP
// messages instead of relying on the Hop Limit (Equivalent to the TTL
// limit in IPv4).
/* MUST use scoping of IPv6 addresses to control the propagation os SSDP
* messages instead of relying on the Hop Limit (Equivalent to the TTL
* limit in IPv4). */
setsockopt( *ssdpReqSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
&hops, sizeof(hops) );
// just do it, regardless if fails or not.
/* just do it, regardless if fails or not. */
Make_Socket_NoBlocking( *ssdpReqSock );
return UPNP_E_SUCCESS;
}
#endif // IPv6
#endif /* IPv6 */
#endif /* INCLUDE_CLIENT_APIS */
@@ -1310,7 +1260,7 @@ int create_ssdp_sock_v6( SOCKET* ssdpSock )
return UPNP_E_SUCCESS;
}
#endif // IPv6
#endif /* IPv6 */
/************************************************************************
* Function : create_ssdp_sock_v6_ula_gua
@@ -1422,7 +1372,7 @@ int create_ssdp_sock_v6_ula_gua(SOCKET *ssdpSock)
return UPNP_E_SUCCESS;
}
#endif //IPv6
#endif /* IPv6 */
#endif /* EXCLUDE_SSDP */

Some files were not shown because too many files have changed in this diff Show More