Compare commits

..

247 Commits

Author SHA1 Message Date
Marcelo Roberto Jimenez
b1629b8ac8 Adjust the library numbers for release. 2011-02-07 22:35:57 -02:00
Marcelo Roberto Jimenez
32e510b45a Remove PrintThreadPoolStats() from the public API.
This function uses a ThreadPool object as an argument, which is not
supposed to be exported. Also, debug compilation was broken.
2011-02-07 22:33:42 -02:00
Fabrice Fontaine
063d472f80 Major bug fix in IPv6 code.
Major bug fix in miniserver.c for IPv6, bug was introduced when
changing implementation of get_port in November 20th 2010 ("gena:fix
several compiler warnings" commit).
2011-02-07 21:27:41 -02:00
Marcelo Roberto Jimenez
0bbe9f62df Fix for incorrectly exported include files.
The files FreeList.h, LinkedList.h, ThreadPool.h and TimerThread.h
from the threautil library were being installed in the include
directory of the library, incorrectly exposing internal data structure
of the library.
2011-02-06 11:52:47 -02:00
Marcelo Roberto Jimenez
fdb8b9ef2f White spaces and indentation. 2011-01-30 09:40:48 -02:00
Chandra Penke
6c125feea0 Fix for compilation errors
Fix for compilation warnings of unused variables in upnpdebug.c in
release builds.
2011-01-30 09:36:05 -02:00
Chandra Penke
c4e9757bcf Fix for Race condition can hang miniserver thread.
Add 'requiredThreads' field to the ThreadPool structure, to avoid
a race condition when waiting for a new thread to be created. The
race condition occurs when a thread is destroyed while the master
thread is waiting for a new thread to be created.

Thanks to Chuck Thomason for pointing the problem.

Summary: Race condition can hang miniserver thread - ID: 3158591

Details:
Hello,

I have found a race condition in the thread pool handling of
libupnp-1.6.6 that periodically results in the miniserver thread
getting blocked infinitely.

In my setup, I have the miniserver thread pool configured with 1
job per thread, 2 threads minimum, and 50 threads maximum.

Just before the lockup occurs, the miniserver thread pool contains
2 threads: one worker thread hanging around from a previous HTTP
request job (let's call that thread "old_worker") and the
miniserver thread itself.

A new HTTP request comes in. Accordingly, the miniserver enters
schedule_request_job() and then ThreadPoolAdd(). In
ThreadPoolAdd(), the job gets added to the medium-priority queue,
and AddWorker() is called. In AddWorker(), jobs = 1 and threads =
1, so CreateWorker gets called.

When we enter CreateWorker(), tp->totalThreads is 2, so
currentThreads is 3. The function creates a new thread and then
blocks on tp->start_and_shutdown. The miniserver thread expects
the newly created thread to increment tp->totalThreads and then
signal the condition variable to wake up the miniserver thread and
let it proceed.

The newly created thread starts in the WorkerThread() function. It
increments tp->totalThreads to 3, does a broadcast on the
start_and_shutdown condition, and starts running its job. However,
before the miniserver thread wakes up, "old_worker" times out. It
sees that there are no jobs in any queue and that the total number
of threads (3) is more than the minimum (2). As a result, it
reduces tp->totalThreads to 2 and dies.

Now the miniserver thread finally wakes up. It checks
tp->totalThreads and sees that its value is 2, so it blocks on
tp->start_and_shutdown again. It has now "missed" seeing
tp->totalThreads get incremented to 3 and will never be unblocked
again.

When this issue does occur for a server device, the miniserver
port remains open, but becomes unresponsive since the miniserver
thread is stuck. SSDP alive messages keep getting sent out, as
they are handled by a separate thread. Reproducing the issue is
difficult due to the timing coincidence involved, but in my
environment I am presently seeing it at least once a day. I
figured out the sequence described above through addition of my
own debug logs.

The relevant code involved in this bug has not changed
substantially in libupnp-1.6.10, though I am planning to test
against 1.6.10 as well in the near future.

Do you have any input for an elegant fix for this issue?

Thanks,

Chuck Thomason
2011-01-20 04:45:27 -02:00
Marcelo Roberto Jimenez
639d3a5a03 Update the documentation about samples in README.
Thanks to Tom (tomdev2).
2011-01-17 11:36:52 -02:00
Chandra Penke
f46683fd0e Fix for typo in strndup() function definition. 2011-01-17 09:03:34 -02:00
Marcelo Roberto Jimenez
abfa841318 Define _FILE_OFFSET_BITS, _LARGEFILE_SOURCE and _LARGE_FILE_SOURCE in upnpconfig.h.
Make these definitions available to programs using the library.
Thanks to Chandra Penke for pointing the problem.
2011-01-16 22:38:18 -02:00
Chandra Penke
3c4ff99cdb Allow virtual callbacks to use chunked encoding by setting the file length of a UpnpFileInfo object to be UPNP_USING_CHUNKED. 2011-01-16 21:28:13 -02:00
Marcelo Roberto Jimenez
541679d651 Use config.h to test for the availability of strndup() and strnlen(). 2011-01-16 21:05:07 -02:00
Chandra Penke
cb1188d2bc Fixes chunked transfer encoding in HTTP client API 2011-01-15 21:11:24 -02:00
Marcelo Roberto Jimenez
189ce59dbe Null termination of strndup() implementation on systems missing it.
Also, implementation of strnlen() on systems missing it.
2011-01-14 22:05:22 -02:00
Marcelo Roberto Jimenez
4815e52586 Doxygen on membuffer. 2011-01-14 10:26:45 -02:00
Marcelo Roberto Jimenez
9051731a93 Minor change in membuffer.c to include "membuffer.h"
...without looking in the standard header path. This allows pupnp
to build in xcode.
2011-01-14 09:54:59 -02:00
Marcelo Roberto Jimenez
39fd869db8 Leave just one call to gmtime() in http_MakeMessage(). 2011-01-02 22:36:13 -02:00
Marcelo Roberto Jimenez
8997e7fff6 Make sure va_end() is called in http_MakeMessage(). 2011-01-02 22:31:10 -02:00
Marcelo Roberto Jimenez
7e8d1787c9 Fixes many problems in sample code.
In particular, undoes 25c908c558:
SF Patch Tracker [ 2836704 ] Search for nested serviceList (not
stopping at the first lis
Submitted By: zephyrus ( zephyrus00jp )

The original zephyrus' code is still #ifdef'd in the file, if someone
wishes to fix it, check for "#ifdef OLD_FIND_SERVICE_CODE".
2010-12-23 22:22:32 -02:00
Marcelo Roberto Jimenez
70d2a7c9e7 Simplify code in SampleUtil_GetFirstDocumentItem(). 2010-12-23 18:40:53 -02:00
Marcelo Roberto Jimenez
40e6e4503c Doxygen and white spaces in samples. 2010-12-22 11:54:45 -02:00
Marcelo Roberto Jimenez
4b0c8d52b8 Remove unnecessary inclusion of param.h. 2010-12-22 11:02:14 -02:00
Marcelo Roberto Jimenez
c05bbec6ec Fix for segfault in sample code. 2010-12-22 10:52:29 -02:00
Marcelo Roberto Jimenez
d5af7efeb8 Fix debug compilation when CFLAGS is set on the configure line. 2010-12-22 09:58:48 -02:00
Marcelo Roberto Jimenez
c8af5ec806 White spaces and some debugging information. 2010-12-22 09:55:48 -02:00
Marcelo Roberto Jimenez
1ee8cd9e1a Ivan Romanov's system file inclusion patch for WIN32 (mingw). 2010-12-21 08:33:57 -02:00
Marcelo Roberto Jimenez
a0ebf23785 Missed this inline in ssdplib.h. 2010-12-19 22:57:01 -02:00
Marcelo Roberto Jimenez
cdf35baa34 Remove unused enum SsdpCmdType and unused typedef Event. 2010-12-19 22:53:08 -02:00
Marcelo Roberto Jimenez
6d7702d3a7 Syncronize ssdplib in 1.6.x and 1.8.x, part 2. 2010-12-19 21:39:19 -02:00
Marcelo Roberto Jimenez
6af93e6ca6 White spaces. 2010-12-19 21:19:44 -02:00
Marcelo Roberto Jimenez
2ce88f80f0 Syncronize ssdplib in 1.6.x and 1.8.x. 2010-12-19 21:14:39 -02:00
Marcelo Roberto Jimenez
f67ed1949b Less include file mess and doxygenation. 2010-12-19 19:02:42 -02:00
Marcelo Roberto Jimenez
04d64a893b Doxygenation of SSDP library. 2010-12-19 13:41:58 -02:00
Marcelo Roberto Jimenez
704dca3df1 Doxygen. 2010-12-18 20:01:49 -02:00
Marcelo Roberto Jimenez
b2a88aa70b SF Tracker: Patches - Fedora mingw32 compilation - ID: 3138849
Details:
Hello. I trying compile libupnp-1.6.10 on the Fedora 14 MinGW
Environment and get many errors. I create patch to fix it. With this
patch i can get static library. This patch is very raw.

Submitted: Ivan Romanov (ivanromanov) - 2010-12-16 23:29:19 UTC
2010-12-18 19:29:24 -02:00
Marcelo Roberto Jimenez
bb5a80c05b Get rid of useless integer typedefs.
Remove unsigned32, unsigned16 and unsigned8 references in the code.
2010-12-18 18:17:14 -02:00
Marcelo Roberto Jimenez
7e8e5621a8 Remove unnecessary header <sys/utsname.h> from upnpapi.c. 2010-12-18 18:09:35 -02:00
Marcelo Roberto Jimenez
462505ff62 Use the new include files UpnpIntTypes.h, UpnpStdInt.h and UpnpUniStd.h.
Trying to keep platform dependency on the headers and clean the main
code a little bit.
2010-12-18 17:08:36 -02:00
Marcelo Roberto Jimenez
d6418b3e17 White spaces. 2010-12-18 16:00:35 -02:00
Marcelo Roberto Jimenez
e8106e4f05 Doxygen. 2010-12-13 09:33:49 -02:00
Marcelo Roberto Jimenez
3dd133a03c Homekeeping for the next release. 2010-12-11 16:42:20 -02:00
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
Marcelo Roberto Jimenez
593b8d0a2b Fixes in configure.ac for release. 2010-10-20 11:11:45 -02:00
Marcelo Roberto Jimenez
890c1b6ef8 Disable debug for release. 2010-10-20 10:36:11 -02:00
Marcelo Roberto Jimenez
c127a3a87e Add docs/doxygen to .gitignore. 2010-10-20 10:35:15 -02:00
Marcelo Roberto Jimenez
bd5758186c White spaces. 2010-10-20 10:29:45 -02:00
Marcelo Roberto Jimenez
cc472bc2cd Doxygen and indentation for sock. 2010-10-20 09:05:42 -02:00
Marcelo Roberto Jimenez
6128296e5f Doxygen and indentation for miniserver. 2010-10-20 08:56:06 -02:00
Marcelo Roberto Jimenez
d84c6a7e9f Indent plus Doxygen in webserver. 2010-10-20 01:28:37 -02:00
Marcelo Roberto Jimenez
113ebd1f91 Slightly better implementation for ToUpperCase(). 2010-10-20 00:36:47 -02:00
Marcelo Roberto Jimenez
bf1450bf81 Fix a long date memory leak in webserver.c:StrStr(). 2010-10-20 00:29:08 -02:00
Marcelo Roberto Jimenez
56b9c75056 Changelog fix. 2010-10-19 16:11:39 -02:00
Marcelo Roberto Jimenez
2bdc9e075e Bug fix in select of miniserver.c
Fix a bug in miniserver.c, in which maxMiniSock was wrongly declared as
unsigned int and as a result it was beeng set to ((unsigned int)(-1)).
As a result, after beeing incremented, it became zero, and this value
was beeing used in the select() call.

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

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

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

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

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

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

I set all ...Sock6 variables to INVALID_SOCKET to make sure that they
do not get added to the FD_SET and the problem is gone.
2010-10-15 12:41:36 -03:00
Marcelo Roberto Jimenez
8401a59ed5 New function, sock_close(). 2010-10-15 12:25:35 -03:00
Marcelo Roberto Jimenez
5b40cfa272 Misplaced declaration of UpnpCloseSocket. 2010-10-15 12:17:15 -03:00
Marcelo Roberto Jimenez
fcda28ba75 Remove of unused file. 2010-10-15 11:53:25 -03:00
Marcelo Roberto Jimenez
7cd434225f White spaces and comments. 2010-10-04 17:05:43 -03:00
Marcelo Roberto Jimenez
78e5ba89fa Merge of similar files. 2010-10-04 15:48:45 -03:00
Marcelo Roberto Jimenez
ebb8f209b0 Merge of similar files. 2010-10-04 15:36:11 -03:00
Marcelo Roberto Jimenez
73afd667e1 Fix for bug introduced in the last commit. 2010-10-04 13:24:38 -03:00
Marcelo Roberto Jimenez
cc294a6cf1 Merge similar code. 2010-10-04 13:03:20 -03:00
Marcelo Roberto Jimenez
458a9416c6 Merge of work from 1.8.x. 2010-10-04 12:04:38 -03:00
Marcelo Roberto Jimenez
b9eeb89250 Bumped Doxyfile version. 2010-10-04 11:44:06 -03:00
Marcelo Roberto Jimenez
a6e68b481d Updated THANKS. 2010-10-04 11:33:37 -03:00
Marcelo Roberto Jimenez
a19a896e88 Updated TODO list. 2010-10-04 11:28:37 -03:00
Marcelo Roberto Jimenez
cdee5b7cde UTF-8. 2010-10-04 11:11:33 -03:00
Marcelo Roberto Jimenez
dec78c8ef1 Echo the copy on configure output. 2010-10-04 11:01:28 -03:00
Marcelo Roberto Jimenez
fb62a5d42a Update files for windows compilation. 2010-10-04 10:51:30 -03:00
Marcelo Roberto Jimenez
a9b5081a08 Update build/inc/autoconfig.h and build/inc/upnpconfig.h at configure
time.
2010-10-04 10:47:39 -03:00
Marcelo Roberto Jimenez
3886a697b5 Remove build/inc/config.h. The right file is upnp/src/inc/config.h. 2010-10-04 10:42:32 -03:00
Marcelo Roberto Jimenez
3dab2bd00a Homekeeping for the next release. 2010-10-04 09:58:15 -03:00
Marcelo Roberto Jimenez
95f7a7eeef Whitespace fix on soaplib.h. 2010-10-02 18:57:35 -03:00
Marcelo Roberto Jimenez
ca50c2153e Remove extra soaplib.h. 2010-10-02 18:57:13 -03:00
Fabrice Fontaine
c73d870f46 Adding --disable-notification-reordering option
Adding a configure flag to disable GENA notification reordering as even
with an imillisleep(1), this mechanism consumes too much CPU on embedded
devices when there is a burst of notifications.
2010-10-02 13:44:52 -03:00
Fabrice Fontaine
ab54cb3dc5 Bug fix when there is no service in embedded devices
When a device with embedded devices (like IGD) when created and one of
the embedded devices did not have any service, there was a Segmentation
Fault (see SF Tracker [ 2688125 ]).
2010-09-30 11:51:06 -03:00
Fabrice Fontaine
c33b11d09f Bug fix on burst of GENA notification
When a lot of notifications were generated by a device in a short
period of time then 100% of the CPU was used to reorder those
notifications by pushing back the thread in the job queue. This
mechanism has been modified so now thread sleep 1 ms before being
pushed back into the job queue.

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

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

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

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

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

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

Please see this patch in attached file.

I hope it helps.

Regards,

David Hoeung
Consultant Extia
Orange Labs R&D

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Patch by Fabrice Fontaine.
2010-09-03 21:49:49 -03:00
Marcelo Roberto Jimenez
842a6ce5c8 Adding .gitignore. 2010-09-03 21:49:20 -03:00
Marcelo Roberto Jimenez
2d978c32b8 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@581 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-22 02:10:50 +00:00
Marcelo Roberto Jimenez
e386dd0d68 The last part of Ronan Menard's patch.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@580 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-22 02:05:34 +00:00
Marcelo Roberto Jimenez
5a2cc884c1 * upnp/src/ssdp/ssdp_device.c: Fix for IPV6 ULA/GUA issues.
* upnp/src/ssdp/ssdp_ctrlpt.c: Fix for IPV6 ULA/GUA issues.
* upnp/src/ssdp/ssdp_server.c: Fix for IPV6 ULA/GUA issues.

Patch submitted by Ronan Menard.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@578 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-22 01:34:35 +00:00
Marcelo Roberto Jimenez
a362d06dff upnp/src/genlib/miniserver/miniserver.c: Fix for IPV6 ULA/GUA issues.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@576 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 22:13:26 +00:00
Marcelo Roberto Jimenez
0e73448ea8 * gena_subscribe(): Fix for IPV6 ULA/GUA issues.
Patch submitted by Ronan Menard.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@574 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 21:53:09 +00:00
Marcelo Roberto Jimenez
a7966b6597 * SOCKET ssdpSock6UlaGua: created variable for later use.
Patch submitted by Ronan Menard.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@572 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 21:40:00 +00:00
Marcelo Roberto Jimenez
2d5c6310a9 * SSDP_IPV6_SITELOCAL: new macro.
Patch submitted by Ronan Menard.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@569 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 21:31:55 +00:00
Marcelo Roberto Jimenez
c9bcee536e The scope of the macro NUM_HANDLE is now restricted to upnpapi.c.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@568 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 21:22:09 +00:00
Marcelo Roberto Jimenez
1605744278 * InitHandleList() has never been implemented, I guess no one has ever
called it, so remove it.
* GetFreeHandle() and FreeHandle() are now static as they should.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@566 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 21:10:50 +00:00
Marcelo Roberto Jimenez
ce0d2833a3 * New internal buffer added to store global/ula IPV6 address.
* Macros to test whether an IPV6 address is global or ula.
* UpnpGetServerUlaGuaIp6Address(): added interface.
* IN6_IS_ADDR_GLOBAL, IN6_IS_ADDR_ULA: new macros.
* gIF_IPV6_ULA_GUA: new buffer.
* UpnpRegisterRootDevice3(): Change to the test of already registered
devices for IPV6.
* UpnpGetIfInfo(): gua/ula issues.

Patch submitted by Ronan Menard.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@564 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-21 20:42:43 +00:00
Marcelo Roberto Jimenez
74db05ff1e English mispelling.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@562 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-19 13:54:44 +00:00
Marcelo Roberto Jimenez
9468e0224a libUPnP does support IPV6 now.
Patch submitted by Ronan Menard.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@560 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-19 13:48:17 +00:00
Marcelo Roberto Jimenez
cb89781a55 HTTP version equal to 1.0 should failed as required by the UPnP
certification tool. Patch submitted by Ronan Menard.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@558 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-08-19 13:27:50 +00:00
Marcelo Roberto Jimenez
3de0765893 Backport of svn rev 556:
SF Bug Tracker [ 3022490 ] String declaration fix for patch applied in 3007407
	Hello,

	When my patch for tracker ID 3007407 was accepted, the definition of the
	serviceList string was changed from

	#define SERVICELIST_STR "serviceList"

	to

	static const char *SERVICELIST_STR = "serviceList";

	During internal code review of the final patch, it was pointed out that 
	sizeof(SERVICELIST_STR) == 4 since SERVICELIST_STR is now declared as
	a pointer instead of an array.

	If you wish to use a variable instead of a define, I suggest the
	following instead:

	static const char SERVICELIST_STR[] = "serviceList";

	Thanks,
	Chuck Thomason



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@557 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-06-28 20:40:21 +00:00
Marcelo Roberto Jimenez
ce0e5b664f Backport of svn rev. 554:
Remove excessive 'dnl's from libupnp.m4.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@555 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-06-26 11:09:49 +00:00
Marcelo Roberto Jimenez
eec36896c3 2010-06-10 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Backport of svn revision 552:
	SF Bug Tracker [ 3007407 ] Service traversal issue in AdvertiseAndReply()
	Submitted: Chuck Thomason ( cyt4 ) - 2010-05-26 15:07:39 UTC

	When the UPnP server is started, one alive message is broadcast for each
	service in each device. It appears that libupnp's implementation of the
	alive message generation does not correctly navigate the XML description
	document when locating the services. This can result in the wrong UDN
	being used in the alive message sent for a service.

	In my specific case (see attached XML), the root EchoSTB device contains
	no services, but its embedded MediaServer device contains 2 services.
	When the existing libupnp code traverses the EchoSTB device in the XML,
	it searches the global list of serviceLists within the document instead
	of searching for a serviceList that is its direct child node. The
	ContentDirectory and ConnectionManager services are then announced with
	the UDN of EchoSTB1 (the root device) instead of with the UDN of
	MediaServer, which is actually their parent device.

	I discovered this behavior using libupnp-1.6.6. I have generated a patch
	against branch-1.6.x that corrects the XML navigation such that all
	services are traversed from their parent device, which results in the
	correct UDN being sent in the alive message for each service. I built
	from branch-1.6.x without this patch, tested, and confirmed that the
	issue still exists as I observed it in libupnp-1.6.6. I then built
	from branch-1.6.x with this patch, tested, and confirmed that the
	issue was resolved.

	Thanks,
	Chuck Thomason



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@553 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-06-17 17:07:41 +00:00
Nick Leverton
00cf8052de Add PTHREAD_CFLAGS to Libs: in libupnp.pc, as assumed by acx_pthread.m4
(fixes binutils-gold link failure)


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@551 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-05-14 13:09:59 +00:00
Marcelo Roberto Jimenez
74b8730f0f SF Bug Tracker [ 2995758 ] libupnp 1.6.6, wrong bind when reuseaddr is 1.
Submitted: viallard anthony ( homer242 )
When trying to use reuseaddr option in miniserver/miniserver.c, there
isn't a affectation of the port chosen (serverAddr.sin_port isn't
receive listen_port variable value).




git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@548 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-05-07 11:07:26 +00:00
Marcelo Roberto Jimenez
1b45bec411 Backport of r544:
Define PROTOTYPES to be one by default in global.h. This affects the
RSA MD5 code.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@546 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-25 14:59:32 +00:00
Marcelo Roberto Jimenez
21163f491d Comment.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@541 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-25 12:04:48 +00:00
Marcelo Roberto Jimenez
a54e07bfb2 Code convergence for client_table (ClientSubscription).
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@539 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-25 08:47:37 +00:00
Marcelo Roberto Jimenez
0dea692199 Allow null pointer deletions in membuffer.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@538 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-25 00:47:37 +00:00
Marcelo Roberto Jimenez
dc457414d1 Adding UpnpString.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@537 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-25 00:44:34 +00:00
Nick Leverton
e1d09004eb Subscription auto-renewals copy the renewal time from old subscription.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@533 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-21 12:28:27 +00:00
Marcelo Roberto Jimenez
640fa8b1be Code base convergence.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@530 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-04-01 20:36:30 +00:00
Marcelo Roberto Jimenez
2bcbdffd89 1 - Ported some of IPV6 code to 1.6.7.
2 - Backport of svn revision 527:
* Added API to ithread, created the following functions:
- int ithread_initialize_library(void);
- int ithread_cleanup_library(void);
- int ithread_initialize_thread(void);
- int ithread_cleanup_thread(void);
* SF Bug Tracker [ 2876374 ] Access Violation when compiling with Visual Studio 2008
Submitted: Stulle ( stulleamgym ) - 2009-10-10 19:05

Hi,

I am one of the devs of the MorphXT project and I use this lib in some
other of my projects, too. When I tried to upgrade the lib earlier for one
of my projects I had to realise that something did not work at first and
while most of the things were reasonably ease to be fixed. Now, the last
thing I encountered was not so easy to fix and I am uncertain if my fix is
any good so I'll just post it here and wait for some comments.

The problem was that I got an Access Violation when calling "UpnpInit". It
would call "ithread_rwlock_init(&GlobalHndRWLock, NULL)" which eventually
led to calling "pthread_cond_init" and I got the error notice at
"EnterCriticalSection (&ptw32_cond_list_lock);". It appeared that
"ptw32_cond_list_lock" was NULL. Now, I found two ways to fix this. Firstly
moving the whole block after at least one of the "ThreadPoolInit" calls
will fix the issue. Secondly, you could add:
#ifdef WIN32
#ifdef PTW32_STATIC_LIB
// to get the following working we need this... is it a good patch or
not... I do not know!
pthread_win32_process_attach_np();
#endif
#endif
right before "ithread_rwlock_init(&GlobalHndRWLock, NULL)".

Just so you know, I am using libupnp 1.6.6 and libpthreads 2.8.0 and both
are linked static into the binaries. I am currently using Visual Studio
2008 for development with Windows being the target OS. Any comment at your
end?

Regards, Stulle



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@529 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-31 17:53:16 +00:00
Marcelo Roberto Jimenez
6c8a4dd361 SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
Submitted By: zephyrus ( zephyrus00jp )
This second part covers the issue on linking with -lsocket -lnsl -lrt.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@525 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-27 14:45:47 +00:00
Marcelo Roberto Jimenez
e9941f7ac8 UTF-8 stuff.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@524 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-27 14:41:25 +00:00
Marcelo Roberto Jimenez
5a465a5cf2 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@523 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-22 09:08:15 +00:00
Marcelo Roberto Jimenez
6aa2419cfd SF Bug Tracker [ 2392166 ] ithread_detach not called for finished worker thread
Submitted: Ulrik ( ulsv_enea ) - 2008-12-05 08:24

	Valgrind reports a memory leak due to that the function ithread_detach is
	not called for finished worker threads in ThreadPool.c.

	==21137== 2,176 bytes in 8 blocks are possibly lost in loss record 5 of 5
	==21137== at 0x4C20F3F: calloc (vg_replace_malloc.c:279)
	==21137== by 0x4010F58: _dl_allocate_tls (in /lib/ld-2.6.1.so)
	==21137== by 0x544BA92: pthread_create@@GLIBC_2.2.5 (in
	/lib/libpthread-2.6.1.so)
	==21137== by 0x5F94592: CreateWorker (ThreadPool.c:639)
	==21137== by 0x5F95079: ThreadPoolInit (ThreadPool.c:784)

	I'm using libupnp 1.6.6

	For more info on pthread_detach, see:
	http://gelorakan.wordpress.com/2007/11/26/pthead_create-valgrind-memory-lea
	k-solved/



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@520 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 22:41:49 +00:00
Marcelo Roberto Jimenez
712ed6d2ff SF Bug Tracker [ 2392304 ] Memory leak in SSDP AdvertiseAndReply
Submitted: Ulrik ( ulsv_enea ) - 2008-12-05 08:24

	Valgrind reports a memory leak function in AdvertiseAndReply
	(ssdp/ssdp_server.c) in libupnp 1.6.6

	There are continue statements in many places in AdvertiseAndReply. In some
	of those error handling cases the variable nodelist is not free'ed before
	continuing to the next iteration. The next iteration will take care of
	free'ing the nodelist from the previous iteration in most cases, but not
	when breaking out of the for loop after the last element.

	I belive this memory leak can be solved by makeing sure that the rows

	ixmlNodeList_free( nodeList );
	nodeList = NULL;

	are always executed, also in the beginning of the last iteration when we
	found out that there are not more elements.

	==29110== at 0x4C21C16: malloc (vg_replace_malloc.c:149)
	==29110== by 0x5D8DE0E: ixmlNodeList_addToNodeList (nodeList.c:106)
	==29110== by 0x5D8B7E2: ixmlNode_getElementsByTagNameRecursive
	(node.c:1438)
	==29110== by 0x5D8E587: ixmlElement_getElementsByTagName
	(element.c:491)
	==29110== by 0x5B6C0F1: AdvertiseAndReply (ssdp_server.c:201)
	==29110== by 0x5B7AB74: UpnpSendAdvertisement (upnpapi.c:1495)



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@518 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 21:19:13 +00:00
Marcelo Roberto Jimenez
53d5e61b33 Thanks update.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@517 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 19:53:20 +00:00
Marcelo Roberto Jimenez
324931ca8f Backport of svn revision 514:
libupnp and multi-flows scenario patch
	Submited by Carlo Parata from STMicroelectronics.
Hi Roberto and Nektarios,
after an analysis of the problem of libupnp with a multi-flows scenario, I
noticed that the only cause of the freezed system is the ThreadPool
management. There are not mutex problems. In practise, if all threads in the
thread pool are busy executing jobs, a new worker thread should be created if
a job is scheduled (I inspired to tombupnp library). So I solved the problem
with a little patch in threadutil library that you can find attached in this
e-mail. I hope to have helped you.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@515 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 19:51:18 +00:00
Marcelo Roberto Jimenez
edc0638640 Backport of svn revision 512:
Style compatibilization between two similar constructions addressed in two
separate recent patches.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@513 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 17:07:09 +00:00
Marcelo Roberto Jimenez
e1ea72a5fb Backport of svn revision 510:
SF Patch Tracker [ 2964973 ] install: will not overwrite just-created
	...blah... with...
	Submitted: Nick Leverton ( leveret ) - 2010-03-07 05:18

	Full error:
	/usr/bin/install: will not overwrite just-created
	`/tmp/buildd/libupnp-1.6.6/debian/tmp/usr/share/doc/libupnp3-dev/examples/s
	ample_util.c' with `common/sample_util.c'

	This seems to be from Automake 1.11 which doesn't like having duplicate
	files in a Makefile.am. Patch attached, kindly provided by Stefan Potyra
	for Debian (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=543068)

	This fix will be needed for both 1.6.x and 1.8.x branches.




git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@511 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 16:13:59 +00:00
Marcelo Roberto Jimenez
5eb55e0fb2 Backport of svn revision 504:
SF Patch Tracker [ 2969188 ] 1.8.0: patch for FreeBSD compilation
	Submitted By: Nick Leverton (leveret)
	Fix the order of header inclusion for FreeBSD.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@509 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 15:42:40 +00:00
Marcelo Roberto Jimenez
9226dd833b SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
Submitted By: zephyrus ( zephyrus00jp )
	Obs by Marcelo: The issue with linking with -lsocket -lnsl -lrt is not
	covered in this changeset beacuse I don't have solaris to test. I will
	need some help from zephyrus in this regard. The issue will be addressed
	in a future changeset.

	Compilation for solaris

	I have used gcc3.x and gcc4.x under solaris 10 for x86 / 64 bits.

	A couple of Source file fixes were necessary for successful compilation
	and runtime behavior.

	threadutil/src/ThreadPool.c

	POSIX
	sched_setschduler() returns non-negative value for success.

	Without the fix, UpnpInit() fails immediately.

	upnpp/src/api/upnpai.c

	There is a typo of a macro name "__sun" in one of the
	CPP conditional.
	Without the fix, the compilation aborts due to unknown constant
	in socket ioctl call.

	A few structs and an array is not properly initialized.
	Well, I think it may be safe as is, but when I checked it
	using purify evaluation version, it was reported that
	uninitizlied iszBuffer may cause read of uninitialized memory.
	So play it safe.

	Configure issue.
	This has to be more of a configure magic.
	To link a program successfully using network, we need
	-lsocket and -lnsl library specifications on the link line.
	We also need -lrt for programs that use thread scheduling features.

	The sample program under upnp/sample requires
	-lsocket -lnsl -lrt
	for successful linking.
	I added -lsocket -lnsl -lrt to Makefile.in.
	configure probably needs to take care of these.

	I don't know much about configure, automake, etc., so
	I am just raising a flag here.

	TIA



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@505 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-21 11:47:17 +00:00
Marcelo Roberto Jimenez
25c908c558 SF Patch Tracker [ 2836704 ] Search for nested serviceList (not
stopping at the first lis
	Submitted By: zephyrus ( zephyrus00jp )
	
	Internet Gateway Device description contains nested serviceList (rootdevice
	-> servicelist, subdevice
	and subdevice has the lower-level serviceList, etc..)

	Unfrotunately, the sample code sample_util.c used by tv_device sample,
	etc.
	has a code that looks for only the first top-level serviceList.
	This results in the failure to read all the services of an IGD xml
	description.

	Attached patch modifies this behavior and looks for the service by
	visiting all the serviceList in xml document in turn.

	With the modified patch (ad additional modification), I could
	simulate an IGD device and created a modified control program for that.

	Patch against 1.6.6

	TIA.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@502 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-20 21:32:38 +00:00
Marcelo Roberto Jimenez
16e91b5dcc Backport of svn revision 497:
* SF Patch Tracker [ 2203721 ] timeb.h check obsolete



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@498 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-15 23:51:09 +00:00
Marcelo Roberto Jimenez
01d17e5c4b Backport of svn revision 495:
* SF Patch Tracker [ 2970872 ] Update ErrorMessages for latest return
	code list
	Submitted By: Nick Leverton ( leveret )
	
	ErrorMessage[] in upnptools.c has got a bit out of sync, the attached
	patch (generated from grep 'define UPNP_E_') should bring it up to date.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@496 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-15 23:39:48 +00:00
Marcelo Roberto Jimenez
a1d707ac81 Backport of svn revision 493: Declare a few functions to have proper
(void) argument list.

	* SF Patch Tracker [ 2857611 ] Declare a few functions to have proper
	(void) argument list.
	Submitted By: zephyrus ( zephyrus00jp )
	
	In a publicly installed headers, a few functions are declared without any
	arguments at all, a la "()".
	When I used gcc's -Wimplict and -Wstrict-prototypes to check for the
	mismatch of
	function prototype declarations and their usage in my own program,
	some headers from libupnp-1.6.6 produced warnings.

	They are not strictly bugs, but pretty much annoying. This is 2009, and
	almost all the important compilers
	understand ISO-C.

	So the offending functions are declared as "(void") to show that they have
	no arguments at all.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@494 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-15 15:34:54 +00:00
Marcelo Roberto Jimenez
4ad6ea3545 Backport of svn revision 484:
SF Patch Tracker [ 2546532 ] Missing carriage return between
    	SOAPACTION and User-Agent headers.
    
    	There is something going wrong in soap_ctrlpt.c at line 931 (based on
    	version 1.6.6 release).
    
    	The http_Makemessage call looks as follows:
    
    	if (http_MakeMessage(
    	&request, 1, 1,
    	"Q" "sbc" "N" "s" "s" "Ucc" "sss",
    	SOAPMETHOD_POST, path.buf, path.length,
    	"HOST: ", host.buf, host.length,
    	content_length,
    	ContentTypeHeader,
    	"SOAPACTION:
    	\"urn:schemas-upnp-org:control-1-0#QueryStateVariable\"",
    	xml_start, var_name, xml_end ) != 0 ) {
    	return UPNP_E_OUTOF_MEMORY;
    	}
    
    	This will result in the SOAPACTION header to be immediately followed by the
    	User-Agent header, while a cr-lf should separate the two. I propose to fix
    	this by changing the second "s" to "sc" to force the addition of a cr-lf
    	after the SOAPACTION. This looks consistent to the other Makemessage calls.



git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@487 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-14 18:53:12 +00:00
Marcelo Roberto Jimenez
70a0aff4e7 Backport of svn revision 482:
wrong order in parameters corrected


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@486 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2010-03-14 18:38:31 +00:00
Marcelo Roberto Jimenez
aaacf65f41 Do not use C++ like comments. Some compilers don't like it.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@481 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-08-14 12:06:22 +00:00
Marcelo Roberto Jimenez
cd8ce90e19 Backport of svn rev. 479: Fix for application compiler warning: "PRId64" redefined.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@480 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-08-14 12:02:20 +00:00
Marcelo Roberto Jimenez
812d019d12 Backport of ixml from 1.8.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@478 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-27 05:01:52 +00:00
Marcelo Roberto Jimenez
881b212690 Backport of svn 371: Removing the useless, unused and undocumented function UpnpFree().
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@477 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-27 03:31:07 +00:00
Marcelo Roberto Jimenez
223c0e8816 Backport of Doxyfile.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@476 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-27 03:11:28 +00:00
Marcelo Roberto Jimenez
ceca478180 Backport of most of upnp.h with documentation.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@475 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-27 03:06:21 +00:00
Marcelo Roberto Jimenez
7963e97469 Backport of svn 367: Removing dead code.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@471 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-26 12:24:24 +00:00
Marcelo Roberto Jimenez
0080c080cd Update of win32 files.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@470 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 04:21:11 +00:00
Marcelo Roberto Jimenez
405451e34c Backport of svn 468: Added upnp/m4/libupnp.m4 to the distribution tarball.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@469 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 04:11:17 +00:00
Marcelo Roberto Jimenez
a772b1a754 Backport of svn 403: Bob Ciora's patch for "UpnpCreatePropertySet can leak memory".
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@466 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 03:42:30 +00:00
Marcelo Roberto Jimenez
ffc4668e0b Backport of 406: Updating Makefile.am for missing files in the "make dist" tarball.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@465 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 03:35:12 +00:00
Marcelo Roberto Jimenez
56a7f038dc Changelog update for a fixed bug of a missing HandleUnlock() that went in
in one of the latest comitts.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@463 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 03:25:42 +00:00
Marcelo Roberto Jimenez
3ba4e34662 Added ixmldebug and UpnpGlobal.h to the 1.6.x branch.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@462 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 03:22:35 +00:00
Marcelo Roberto Jimenez
515233ca56 Backport of svn 395 and 434:
395: Bob Ciora's patch for lazy UpnpAcceptSubscription().
434: Fixed a buffer overflow due to a bug in the calculation of the
     CONTENT-TYPE header line size, the length was beeing calculated with
     the wrong string, there was a missing colon.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@461 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-25 02:56:04 +00:00
Marcelo Roberto Jimenez
423808a095 Backport of svn 453: Andre Sodermans (wienerschnitzel) patch for building
libupnp under windows systems with VC8/VC9.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@460 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-24 11:40:33 +00:00
Marcelo Roberto Jimenez
f22a69b487 Backport of 457: SF Bug Tracker [ 2026431 ] pupnp does not build on GNU/KfreeBSD.
Submitted By: Nick Leverton - leveret
	Gnu/KFreeBSD is one of the Debian architectures, it includes a FreeBSD
	kernel with GNU userspace (glibc etc). The Gnu/KfreeBSD developers
	provided the attached patch to test the appropriate #define and allow pupnp
	to build in their environment, and asked me to forward it to you.

	Since the test is a simple check for defined(__GLIBC__), this would
	presumably also help with other ports of GNU libc to non-Linux kernels.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@458 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-24 11:30:42 +00:00
Marcelo Roberto Jimenez
bcf5a5c5e0 Backport: Debug code for http_RecvMessage().
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@450 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-10 04:15:36 +00:00
Marcelo Roberto Jimenez
e0c9de0b1d Backport: Added an m4 macro to deal with finding libupnp in the users'
configure script.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@449 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-07-10 04:02:16 +00:00
Marcelo Roberto Jimenez
94e4a3bdda Fix in function SetSeed() in threadutil/src/ThreadPool.c for CYGWIN
compilation. Thanks to Gary Chan.


git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@355 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-04-29 15:42:18 +00:00
Marcelo Roberto Jimenez
b7b3bb7d05 Homekeeping for the next release.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@354 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-04-29 15:38:35 +00:00
Marcelo Roberto Jimenez
f0161c7274 Merge of trunk into branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@351 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-04-26 00:49:39 +00:00
Marcelo Roberto Jimenez
4b40e94b03 Merge of trunk into branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@339 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-03-25 10:21:08 +00:00
Marcelo Roberto Jimenez
1c9632dcc3 White spaces.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@329 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-03-05 03:55:33 +00:00
Marcelo Roberto Jimenez
cc0c2ffc50 Merge of trunk into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@327 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-02-22 04:48:10 +00:00
Marcelo Roberto Jimenez
f812b124d7 Merge of trunk into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@324 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-02-10 02:27:45 +00:00
Marcelo Roberto Jimenez
a785465222 Merge of trunk into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@322 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-02-08 02:29:26 +00:00
Marcelo Roberto Jimenez
078f3f8faf Merge of trunk into branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@312 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-02-03 01:36:23 +00:00
Marcelo Roberto Jimenez
1eeaf99b83 Merge of trunk into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@306 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2008-01-27 02:13:08 +00:00
Marcelo Roberto Jimenez
f6dd5062fe Merge of trunk into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@284 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-12-27 02:14:02 +00:00
Marcelo Roberto Jimenez
7d4a610b93 Merge of head into branch-1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@265 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-12-10 23:18:38 +00:00
Marcelo Roberto Jimenez
0a074d1989 Merge of trunk into branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@263 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-12-10 22:56:56 +00:00
Marcelo Roberto Jimenez
0475a46680 Merge of current trunk to branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@251 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-11-19 14:15:45 +00:00
Marcelo Roberto Jimenez
2a76749682 Creating branch 1.6.x.
git-svn-id: https://pupnp.svn.sourceforge.net/svnroot/pupnp/branches/branch-1.6.x@210 119443c7-1b9e-41f8-b6fc-b9c35fce742c
2007-06-23 14:23:29 +00:00
148 changed files with 20015 additions and 31919 deletions

105
.gitignore vendored Normal file
View File

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

772
ChangeLog
View File

@@ -1,221 +1,607 @@
******************************************************************************* *******************************************************************************
Version 1.8.0 Version 1.6.11
******************************************************************************* *******************************************************************************
2010-08-22 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2011-02-07 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
* upnp/src/api/Discovery.c: Fix a serious bug and memory leak in
UpnpDiscovery_strcpy_DeviceType(). Thanks to David Blanchet for the
patch.
2010-04-25 Marcelo Jimenez <mroberto(at)users.sourceforge.net> Remove PrintThreadPoolStats() from the public API. This function uses
Separation of the ClientSubscription object. a ThreadPool object as an argument, which is not supposed to be
exported.
2010-04-24 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2011-02-07 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Protect the object destructors agains null pointers on deletion, which
should be something valid.
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net> Major bug fix in IPv6 code.
SF Patch Tracker [ 2987390 ] upnp_debug vs. ixml_debug
Thanks for the load of updates, I'm still assimilating them ! Could I make
a suggestion though? The addition of printNodes(IXML_Node) to upnpdebug a
dds a new dependency on ixml.h for anything using upnpdebug.h. I'm making
quite a bit of use of upnpdebug in porting things to version 1.8.0, and I'd
prefer it if printNodes could be added to ixmldebug.h instead. I'm attach
ing a patch, what do you think ?
Nick Major bug fix in miniserver.c for IPv6, bug was introduced when
changing implementation of get_port in November 20th 2010 ("gena:fix
several compiler warnings" commit).
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2011-02-06 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
* Forward port of svn revision 505:
SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
Submitted By: zephyrus ( zephyrus00jp )
2010-03-20 Marcelo Jimenez <mroberto(at)users.sourceforge.net> Fix for incorrectly exported include files.
* SF Patch Tracker [ 2969188 ] 1.8.0: patch for FreeBSD compilation
Submitted By: Nick Leverton (leveret)
Fix the order of header inclusion for FreeBSD.
2010-03-20 Marcelo Jimenez <mroberto(at)users.sourceforge.net> The files FreeList.h, LinkedList.h, ThreadPool.h and TimerThread.h
* Forward port of svn revision 502: from the threautil library were being installed in the include
SF Patch Tracker [ 2836704 ] Search for nested serviceList (not directory of the library, incorrectly exposing internal data structure
stopping at the first lis of the library.
Submitted By: zephyrus ( zephyrus00jp )
2011-01-30 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for compilation warnings of unused variables in upnpdebug.c in
release builds.
2011-01-20 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for Race condition can hang miniserver thread.
Add 'requiredThreads' field to the ThreadPool structure, to avoid
a race condition when waiting for a new thread to be created. The
race condition occurs when a thread is destroyed while the master
thread is waiting for a new thread to be created.
Thanks to Chuck Thomason for pointing the problem.
Summary: Race condition can hang miniserver thread - ID: 3158591
Details:
Hello,
I have found a race condition in the thread pool handling of
libupnp-1.6.6 that periodically results in the miniserver thread
getting blocked infinitely.
In my setup, I have the miniserver thread pool configured with 1
job per thread, 2 threads minimum, and 50 threads maximum.
Just before the lockup occurs, the miniserver thread pool contains
2 threads: one worker thread hanging around from a previous HTTP
request job (let's call that thread "old_worker") and the
miniserver thread itself.
A new HTTP request comes in. Accordingly, the miniserver enters
schedule_request_job() and then ThreadPoolAdd(). In
ThreadPoolAdd(), the job gets added to the medium-priority queue,
and AddWorker() is called. In AddWorker(), jobs = 1 and threads =
1, so CreateWorker gets called.
When we enter CreateWorker(), tp->totalThreads is 2, so
currentThreads is 3. The function creates a new thread and then
blocks on tp->start_and_shutdown. The miniserver thread expects
the newly created thread to increment tp->totalThreads and then
signal the condition variable to wake up the miniserver thread and
let it proceed.
The newly created thread starts in the WorkerThread() function. It
increments tp->totalThreads to 3, does a broadcast on the
start_and_shutdown condition, and starts running its job. However,
before the miniserver thread wakes up, "old_worker" times out. It
sees that there are no jobs in any queue and that the total number
of threads (3) is more than the minimum (2). As a result, it
reduces tp->totalThreads to 2 and dies.
Now the miniserver thread finally wakes up. It checks
tp->totalThreads and sees that its value is 2, so it blocks on
tp->start_and_shutdown again. It has now "missed" seeing
tp->totalThreads get incremented to 3 and will never be unblocked
again.
When this issue does occur for a server device, the miniserver
port remains open, but becomes unresponsive since the miniserver
thread is stuck. SSDP alive messages keep getting sent out, as
they are handled by a separate thread. Reproducing the issue is
difficult due to the timing coincidence involved, but in my
environment I am presently seeing it at least once a day. I
figured out the sequence described above through addition of my
own debug logs.
The relevant code involved in this bug has not changed
substantially in libupnp-1.6.10, though I am planning to test
against 1.6.10 as well in the near future.
Do you have any input for an elegant fix for this issue?
Thanks,
Chuck Thomason
2011-01-16 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Define _FILE_OFFSET_BITS, _LARGEFILE_SOURCE and _LARGE_FILE_SOURCE in
upnpconfig.h.
Make these definitions available to programs using the library.
Thanks to Chandra Penke for pointing the problem.
Summary: Problem with large file support in pupnp build - ID: 3158969
Submitted: Chandra ( inactiveneurons ) - 2011-01-15 16:17:02 BRST
Details:
First off, I apologize in advance for the length of this comment, it's
the only way I could describe the problem accurately.
Secondly, a brief thanks (again). The company I'm working for has been
using pupnp for a massively cross-platform project which involves iphone,
osx, windows, linux x86, arm, and mips hosts. It's amazing how well it
works, so kudos to the maintainers!
We came across a problem when compiling with the following tool-chain:
http://www.codesourcery.com/sgpp/lite/mips/portal/release824. The
problem is the following:
In configure.ac the following lines exist to enable large file support:
AC_DEFINE([_LARGE_FILE_SOURCE], [], [Large files support])
AC_DEFINE([_FILE_OFFSET_BITS], [64], [File Offset size])
Which in turn result in the following #defines in autoconfig.h:
#define _LARGE_FILE_SOURCE /**/
#define _FILE_OFFSET_BITS 64
However, this file is not exported as part of the upnp build. Therefore,
while the entire library gets built with large file support, it's
possible that dependent libraries which only rely on the include files
may not use large file support.
In the particular case of the above tool-chain, the 'off_t' type is 8
bytes when large file support is enabled, but only 4 bytes when it's
not. As a result part our stack built on top of pupnp, which did not
have large file support (because it did not use the above autoconf
directives), was relying on 'a off_t' that was 4 bytes.
This caused, among many things, for the UpnpFileInfo struct to break.
Since the struct is completely invisible outside of pupnp (because of
some template macro magic), pupnp thought that 'FileLength' field was
8 bytes, but the header setter/getter methods being used by dependent
libraries thought that it was 4, which caused some erratic behavior
when going through pupnp's webserver and HTTP client API.
We put in a temporary work around by adding the following preprocessor
flags: -D_LARGE_FILE_SOURCE, -D_FILE_OFFSET_BITS=64 as part of our
build process. However, it's a hack, and I was wondering if I'm missing
something and there's a better way to approach this.
Thanks,
Chandra
2011-01-16 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Use config.h to test for the availability of strndup() and strnlen().
2011-01-14 Chandra Penke <chandrapenke(at)mcntech.com>
- Null termination of strndup() implementation on systems missing it.
- Implementation of strnlen() on systems missing it.
2011-01-14 Chandra Penke <chandrapenke(at)mcntech.com>
Fixes transfer encoding in the HTTP client API, which is currently
broken. The break was due to a regression caused by another
fix (tracker 3056713), which fixed an out of memory crash when
downloading large files. The previous fix changed the
http_ReadHttpGet() implementation so that data already read by the
user was discarded. However, it only worked for transfers where
the content length was specified. This fix extends the previous
implementation to cover chunked transfer encoding.
2011-01-14 Chandra Penke <chandrapenke(at)mcntech.com>
Minor change in membuffer.c to include "membuffer.h" without looking
in the standard header path. This allows pupnp to build in xcode.
2010-12-18 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
SF Tracker: Patches
Fedora mingw32 compilation - ID: 3138849
Details:
Hello. I trying compile libupnp-1.6.10 on the Fedora 14 MinGW
Environment and get many errors. I create patch to fix it. With this
patch i can get static library. This patch is very raw.
Submitted: Ivan Romanov (ivanromanov) - 2010-12-16 23:29:19 UTC
*******************************************************************************
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
*******************************************************************************
2010-10-20 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Fix a long date memory leak in webserver.c:StrStr().
2010-10-19 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
Bug fix in select of miniserver.c
Internet Gateway Device description contains nested serviceList (rootdevice Fix a bug in miniserver.c, in which maxMiniSock was wrongly declared as
-> servicelist, subdevice unsigned int and as a result it was beeng set to ((unsigned int)(-1)).
and subdevice has the lower-level serviceList, etc..) As a result, after beeing incremented, it became zero, and this value
was beeing used in the select() call.
Unfrotunately, the sample code sample_util.c used by tv_device sample, Thanks to Fabrice Fontaine for helping and testing with this issue.
etc.
has a code that looks for only the first top-level serviceList.
This results in the failure to read all the services of an IGD xml
description.
Attached patch modifies this behavior and looks for the service by 2010-10-15 Marcelo Roberto Jimenez <mroberto(at)users.sourceforge.net>
visiting all the serviceList in xml document in turn.
With the modified patch (ad additional modification), I could Fix for 100% CPU issue in select() in miniserv.c. I have also removed
simulate an IGD device and created a modified control program for that. the sleep() call, it was just a workaround.
Patch against 1.6.6 SF Bug Tracker [ 3086852 ] 99% CPU loop in miniserver.c on a non ipv6
system.
TIA. Submitted by: Jin ( jin_eld ) - 2010-10-13 19:29:13 UTC
2010-03-20 Marcelo Jimenez <mroberto(at)users.sourceforge.net> I cross compiled libupnp 1.6.7 for ARM9 using the --disable-ipv6
* SF Patch Tracker [ 2973319 ] Problem in commit 499 option, my system is an ipv4 only setup.
Submitted By: Nick Leverton (leveret)
Afraid that this doesn't compile, it seems retval should be retVal in two
places.
2010-03-16 Marcelo Jimenez <mroberto(at)users.sourceforge.net> I do not know why this problem only appears when running the app in the
* Fix for the ithread_mutex_unlock() logic in UpnpInit(). background (for instance using nohup &), but then it starts using 99%
Thanks for Nicholas Kraft. CPU.
2010-03-15 Marcelo Jimenez <mroberto(at)users.sourceforge.net> I traced the problem down to the select() call in miniserver.c in the
* SF Patch Tracker [ 2962606 ] Autorenewal errors: invalid SID, RunMiniServer() function. Select returns code 1, but errno is set to
too-short renewal interval "Socket operation on non-socket", I also see this when running my app
Submitted By: Nick Leverton (leveret) under strace.
Auto-renewals send an invalid SID due to a missing UpnpString_get_String
call. They also send a renewal interval of 0 instead of copying it from
the original subscription.
2010-03-15 Marcelo Jimenez <mroberto(at)users.sourceforge.net> I set all ...Sock6 variables to INVALID_SOCKET to make sure that they
* SF Patch Tracker [ 2964685 ] patch for avoiding inet_ntoa (1.8.0) do not get added to the FD_SET and the problem is gone.
Submitted By: Nick Leverton (leveret)
Seems like SF's tracker won't let me add a patch to someone else's issue ?!
This refers to https://sourceforge.net/support/tracker.php?aid=2724578
The calls to inet_ntoa are in getlocalhostname(), which is called from
UpnpInit when it is returning the bound IP address.
UpnpInit/getlocalhostname hasn't been updated to IPv6, I presume this is
deliberate so that it doesn't start returning IPv6 addresses and
overwriting the caller's IPv4-sized allocation.
The attached patch just updates getlocalhostname to use inet_ntop instead
of inet_ntoa, and also documents the fact that UpnpInit is IPv4 only whilst
UpnpInnit2 is both IPv4 and IPv6.
A fuller solution might be to change UpnpInit to use some variant on
UpnpGetIfInfo. UpnpInit could still be left as IPv4 only if desired -
perhaps UpnpGetIfInfo could take an option for the desired address family.
getlocalhostname and its own copy of the interface scanning code would then
be redundant. I don't have IPv6 capability here though so I'm reluctant to
change the IPv6 code, as I have no way to test it.
2010-03-15 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Patch Tracker [ 2724578 ] patch for avoiding memory leaks when
add devices
each time a device been added, UpnpInit() is called, on exit, UpnpFinish()
is called, but the memories allocated by ThreadPoolInit() may lost because
there's no code to call ThreadPoolShutdown() to release the memories. And
inet_ntoa() is not thread safe, so in my patch, I substitute inet_ntoa()
with inet_ntop().
2010-03-14 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Patch Tracker [ 2964687 ] Add new string based accessors to upnp
object API
As per email to pupnp-devel, this is the patch to add the _strget_
accessors for string-like objects in the interface.
Will add a further patch shortly to udpate the sample programs.
2008-06-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Nicholas Kraft's patch to fix some IPv6 copy/paste issues. He
reported to be getting infinite loops with the svn code.
2008-06-13 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1984541 ]
ixmlDocumenttoString does not render the namespace tag.
Submitted By: Beliveau - belivo
Undoing the patch that fixed this problem. In fact, there was no
problem and the patch was wrong.
2008-06-11 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Ingo Hofmann's patch for "Content-Type in Subscription responses".
Adds charset="utf-8" attribute to the CONTENT-TYPE header line.
Hi,
I have found an inconsistency regarding the text/xml content-type
returned by libupnp. It looks like only subscription responses send
"text/xml" where all other messages contain "text/xml; charset="utf-8"".
Since I'm working on an DLNA device the latter behaviour is mandatory.
I changed the according lines in gena_device.c (see attached patch).
I'm not sure if it would be ok for other device to have the charset
field but it would help me a lot :)
Best regards,
Ingo
2008-06-04 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* SF Bug Tracker [ 1984541 ]
ixmlDocumenttoString does not render the namespace tag.
Submitted By: Beliveau - belivo
The problem occurs when converting a xml document using
ixmlDocumenttoString containing a namespace tag created with
ixmlDocument_createElementNS. The namespace tag doesn't get rendered.
example: The following code fragment prints:
<?xml version="1.0"?>
<root></root>
instead of:
<?xml version="1.0"?>
<root xmlns="urn:schemas-upnp-org:device-1-0"></root>
Code:
#include <stdlib.h>
#include <upnp/ixml.h>
int main()
{
IXML_Document* wDoc = ixmlDocument_createDocument();
IXML_Element* wRoot = ixmlDocument_createElementNS(wDoc,
"urn:schemas-upnp-org:device-1-0", "root");
ixmlNode_appendChild((IXML_Node *)wDoc,(IXML_Node *)wRoot);
DOMString wString = ixmlDocumenttoString(wDoc);
printf(wString);
free(wString);
ixmlDocument_free(wDoc);
return 0;
}
The problem was in the printing routine, not in the library data
structure.
2008-05-31 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Charles Nepveu's suggestion of not allocating a thread for
MiniServer when it is not compiled.
2008-05-24 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Ported Peter Hartley's patch to compile with mingw.
2008-05-24 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Added some debug capability to ixml.
2008-05-02 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Merged Charles Nepveu's IPv6 work. libupnp now is IPv6 enabled.
2008-02-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Breaking API so that we now hide internal data structures.
2008-02-06 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Rewrote Peter Hartley's patch to include a new extra header field in
FileInfo.
******************************************************************************* *******************************************************************************
Version 1.6.7 Version 1.6.7
******************************************************************************* *******************************************************************************
2010-10-01 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Adding --disable-notification-reordering option
Adding a configure flag to disable GENA notification reordering as even
with an imillisleep(1), this mechanism consumes too much CPU on embedded
devices when there is a burst of notifications.
2010-09-30 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Bug fix when there is no service in embedded devices
When a device with embedded devices (like IGD) when created and one of
the embedded devices did not have any service, there was a Segmentation
Fault (see SF Tracker [ 2688125 ]).
Original SF Tracker issue follows:
SF Tracker [ 2688125 ] v1.6.6 crashes on subdevices without services
Submitted by: Arno Willig ( akw ) - 2009-03-15 22:45:23 BRT
I discovered a bug, which will make libupnp (1.6.6) segfault, when you
create a upnp description document with multiple devices which have
subdevices, but no own services.
The crash occurs in genlib/service_table.c in line 977:
end->next =
getServiceList( currentDevice, &next_end, URLBase );
In this case "end" seems not to be defined, so end->next crashes.
Can anyone confirm this, please?
2010-09-28 Marc Essayan <marc.essayan(at)orange-ftgroup.com>
Bug fix on burst of GENA notification
When a lot of notifications were generated by a device in a short
period of time then 100% of the CPU was used to reorder those
notifications by pushing back the thread in the job queue. This
mechanism has been modified so now thread sleep 1 ms before being
pushed back into the job queue.
Removing DEFAULT_SCHED_PARAM parameter and use
sched_get_priority_min(DEFAULT_POLICY) instead.
2010-09-22 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Bug fix on M-SEARCH response
Devices must respond to M-SEARCH requests for any supported version and the
response should specify the same version as was contained in the search target.
Previously, the device did not answer if the M-SEARCH request did not
contain the same version number than the version number of the device.
2010-09-21 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Add Content-Language iff Accept-Language
Add Content-Language header in the response if and only if there is an
Accept-Language header in the request.
2010-09-21 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Addition of WEB_SERVER_CONTENT_LANGUAGE parameter
This patch adds the WEB_SERVER_CONTENT_LANGUAGE parameter so the user can specify
the language used by the device during Description and Presentation steps of UPnP
through the HTTP CONTENT-LANGUAGE header.
By default, the WEB_SERVER_CONTENT_LANGUAGE is an empty string so no
CONTENT-LANGUAGE is added.
2010-09-18 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Customize the stack size of the threads used by pupnp through the new
THREAD_STACK_SIZE variable.
This patch allows a user to customize the stack size of the threads used by
pupnp through the new THREAD_STACK_SIZE variable. This is especially useful
on embedded systems with limited memory where the user can set THREAD_STACK_SIZE
to ITHREAD_STACK_MIN.
However, as this modification can have side effects, I set 0 as the default
value, so threads will continue to use the default stack size of the system
(which varies greatly as stated in
https://computing.llnl.gov/tutorials/pthreads/).
2010-09-16 Fabrice Fontaine <fabrice.fontaine(at)orange-ftgroup.com>
Broken IPv6.
IPv6 is currently broken in latest release of branch-1.6.x, so find a
patch attached that correct the issue (small fixes on define, undef and
retVal).
2010-09-10 Warwick Harvey <warwick.harvey(at)tieto.com>
Patch to take notice of UPNP_USE_RWLOCK flag
The configure.ac file included with UPnP checks for the presence of the
pthread_rwlock_t type, and then sets the value of the UPNP_USE_RWLOCK
flag appropriately. However, this flag is not referenced at all in the
source code, and thus the code does not compile on systems that don't
have the pthread_rwlock_t type (such as Android).
Please find attached a patch (against the current 1.6.x head) that checks
the value of this flag and falls back on using mutexes if read-write
locks are not available.
2010-09-10 Jean Sigwald <jean.sigwald(at)orange-ftgroup.com>
I discovered a reliable denial-of-service issue on the last stable
release of libupnp (1.6.6) remotely triggerable by any
unauthenticated user. The issue is related with a bad parsing of
malformed XML.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
* SF Patch Tracker [ 2854711 ] Patch for Solaris10 compilation and usage
Submitted By: zephyrus ( zephyrus00jp )
Patch for Solaris10 compilation and usage.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
Add support for conditionally enabling ipv6.
2010-09-10 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for compilation in debug builds.
Ensure internal methods are declared as static since debug builds don't inline.
2010-09-09 Chandra Penke <chandrapenke(at)mcntech.com>
Fix for regression in SSDP code to send/receive messages over UDP
Sending messages over UDP is broken in some Apple OSes
such as OS X and iOS. This might be broken in other OSes to but didn't
verify.
The fix is to modify the socket lenght argument of sendto to use the correct
sockaddr lenght dependng on whether the socket is IPV4 or IPV6.
Also added some error checks and debugging related to the issue
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Using UpnpReadHttpGet to download large files causes the application to
crash. This happens when the file being downloaded exceeds the device
memory - entirely possible when transferring video files.
The programmatic cause is that the logic implemented in the function
http_ReadHttpGet (which UpnpReadHttpGet calls) reads the entire file
into memory. The fix modifies the existing logic to discard data after
it's been read; there's no reason to keep it around since the caller
of UpnpReadHttpGet already has a copy of it.
This issue exists in 1.6.6 as well as the latest sources.
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
In the latest sources, http_RequestAndResponse and other methods that
use connect() are broken. More specifically, connect() in these methods
is returning with an EINVAL. The programatic cause is that the address_len
argument passed to connect() is different in IPV4 vs IPV6 (as described in:
http://www.opengroup.org/onlinepubs/009695399/functions/connect.html).
The current code always uses the IPV6 size. The fix modifies each use of
connect() to use the correct size based on the address family being used.
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in upnp/src/gena/gena_ctrlpt.c (this is most
likely an error on all platforms).
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in upnp/src/inc/ssdplib.h when compiling in OS X
(the netinet/* headers are not available).
Patch submitted by Chandra (inactiveneurons).
2010-09-07 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
Fix compilation error in ixml/inc/ixml.h when compiling with an
Objective-C compiler (when cross-compiling for iPhone devices).
Patch submitted by Chandra (inactiveneurons).
2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* Issue regarding the GENA notifications. A string termination indicator
was added at the end of the notification ("\r\n") in
notify_send_and_recv() in upnp/src/gena/gena_device.c.
Patch by Fabrice Fontaine.
2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net> 2010-08-21 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
* The last part of Ronan Menard's patch. * The last part of Ronan Menard's patch.

View File

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

View File

@@ -1,7 +1,7 @@
# #
# Top-level "Makefile.am" for libupnp # Top-level "Makefile.am" for libupnp
# #
# Copyright (C) 2005 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> # Copyright (C) 2005 Rémi Turboult <r3mi@users.sourceforge.net>
# #
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
@@ -26,7 +26,6 @@ EXTRA_DIST = \
build/libupnp.dsp \ build/libupnp.dsp \
build/libupnp.dsw \ build/libupnp.dsw \
build/inc/autoconfig.h \ build/inc/autoconfig.h \
build/inc/config.h \
build/inc/upnpconfig.h \ build/inc/upnpconfig.h \
build/msvc/inttypes.h \ build/msvc/inttypes.h \
build/msvc/stdint.h \ build/msvc/stdint.h \

13
README
View File

@@ -1,7 +1,7 @@
Portable SDK for UPnP* Devices (libupnp) Portable SDK for UPnP* Devices (libupnp)
Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved. Copyright (c) 2000-2003 Intel Corporation - All Rights Reserved.
Copyright (c) 2005-2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> Copyright (c) 2005-2006 Rémi Turboult <r3mi@users.sourceforge.net>
Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds@gmx.de> Copyright (c) 2006 Michel Pfeiffer and others <virtual_worlds@gmx.de>
See LICENSE for details. See LICENSE for details.
@@ -227,17 +227,18 @@ To build the samples (note: this is the default behaviour):
% ./configure --enable-samples % ./configure --enable-samples
% make % make
will build the sample device "$(LIBUPNP)/upnp/upnp_tv_device" and will build the sample device "$(LIBUPNP)/upnp/tv_device" and
sample control point "$(LIBUPNP)/upnp/upnp_tv_ctrlpt". sample control point "$(LIBUPNP)/upnp/tv_ctrlpt".
Note : the sample device won't be built if --disable-device has been Note : the sample device won't be built if --disable-device has been
configured, and the sample control point won't be build if --disable-client configured, and the sample control point won't be build if --disable-client
has been configured. has been configured.
To run the sample device, you need the "$(LIBUPNP)/upnp/sample/tvdevice/web" To run the sample device, you need to create a tvdevice directory and move
sub-directory. Example : the web directory there, giving: "$(LIBUPNP)/upnp/sample/tvdevice/web".
To run the sample invoke from the command line as follows:
% cd $(LIBUPNP)/upnp/sample/tvdevice % cd $(LIBUPNP)/upnp/sample/tvdevice
% ../../upnp_tv_device % ../tv_device

9
THANKS
View File

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

24
TODO
View File

@@ -2,29 +2,5 @@
To Be Done To Be Done
========== ==========
- add FreeBSD patches
( http://sf.net/tracker/index.php?func=detail&aid=1332618&group_id=7189&atid=307189 ?)
- non-regression testing - non-regression testing
- replace doc++ by Doxygen for documentation generation
- incorporate public patches and fix reported bugs :
http://sourceforge.net/tracker/?group_id=7189&atid=107189 and
http://sourceforge.net/tracker/?group_id=7189&atid=307189
- RPM packaging (a preliminary one here :
https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=176617 )
- make API clean for large files and 64 bits
- Why is NUM_HANDLE defined to 200 when we can register only:
A) One client(1)
B) An IPv4 and IPv6 device (2)
NUM_HANDLE should be 3
- A sane way to implement the virtual directory callback initialization and checking
against NULL pointers.

View File

@@ -19,15 +19,9 @@
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
#define HAVE_FSEEKO 1 #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 to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1 #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 to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1 #define HAVE_LIMITS_H 1
@@ -55,6 +49,12 @@
/* Define to 1 if you have the <string.h> header file. */ /* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1 #define HAVE_STRING_H 1
/* Defines if strndup is available on your system */
#define HAVE_STRNDUP 1
/* Defines if strnlen is available on your system */
#define HAVE_STRNLEN 1
/* Define to 1 if you have the <syslog.h> header file. */ /* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H 1 #define HAVE_SYSLOG_H 1
@@ -67,9 +67,6 @@
/* Define to 1 if you have the <sys/stat.h> header file. */ /* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1 #define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/timeb.h> header file. */
#define HAVE_SYS_TIMEB_H 1
/* Define to 1 if you have the <sys/time.h> header file. */ /* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H 1 #define HAVE_SYS_TIME_H 1
@@ -85,11 +82,15 @@
/* Define to 1 if you have the <ws2tcpip.h> header file. */ /* Define to 1 if you have the <ws2tcpip.h> header file. */
/* #undef HAVE_WS2TCPIP_H */ /* #undef HAVE_WS2TCPIP_H */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Define to 1 to prevent compilation of assert() */ /* Define to 1 to prevent compilation of assert() */
/* #undef NDEBUG */ #define NDEBUG 1
/* Define to 1 to prevent some debug code */ /* Define to 1 to prevent some debug code */
/* #undef NO_DEBUG */ #define NO_DEBUG 1
/* Define to 1 if your C compiler doesn't accept -c and -o together. */ /* Define to 1 if your C compiler doesn't accept -c and -o together. */
/* #undef NO_MINUS_C_MINUS_O */ /* #undef NO_MINUS_C_MINUS_O */
@@ -104,13 +105,13 @@
#define PACKAGE_NAME "libupnp" #define PACKAGE_NAME "libupnp"
/* Define to the full name and version of this package. */ /* Define to the full name and version of this package. */
#define PACKAGE_STRING "libupnp 1.8.0" #define PACKAGE_STRING "libupnp 1.6.11"
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libupnp" #define PACKAGE_TARNAME "libupnp"
/* Define to the version of this package. */ /* Define to the version of this package. */
#define PACKAGE_VERSION "1.8.0" #define PACKAGE_VERSION "1.6.11"
/* Define to necessary symbol if this constant uses a non-standard name on /* Define to necessary symbol if this constant uses a non-standard name on
your system. */ your system. */
@@ -119,11 +120,20 @@
/* Define to 1 if you have the ANSI C header files. */ /* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1 #define STDC_HEADERS 1
/* see upnpconfig.h */
#define UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS 1
/* see upnpconfig.h */
/* #undef UPNP_ENABLE_IPV6 */
/* see upnpconfig.h */
#define UPNP_ENABLE_NOTIFICATION_REORDERING 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_HAVE_CLIENT 1 #define UPNP_HAVE_CLIENT 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_HAVE_DEBUG 1 /* #undef UPNP_HAVE_DEBUG */
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_HAVE_DEVICE 1 #define UPNP_HAVE_DEVICE 1
@@ -141,25 +151,25 @@
#define UPNP_VERSION_MAJOR 1 #define UPNP_VERSION_MAJOR 1
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_MINOR 8 #define UPNP_VERSION_MINOR 6
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_PATCH 0 #define UPNP_VERSION_PATCH 11
/* see upnpconfig.h */ /* see upnpconfig.h */
#define UPNP_VERSION_STRING "1.8.0" #define UPNP_VERSION_STRING "1.6.11"
/* Version number of package */ /* Version number of package */
#define VERSION "1.8.0" #define VERSION "1.6.11"
/* File Offset size */ /* File Offset size */
#define _FILE_OFFSET_BITS 64 #define _FILE_OFFSET_BITS 64
/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ /* 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 */ /* Large files support */
#define _LARGE_FILE_SOURCE #define _LARGE_FILE_SOURCE /**/
/* Define to empty if `const' does not conform to ANSI C. */ /* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */ /* #undef const */

View File

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

View File

@@ -2,7 +2,7 @@
/* -*- C -*- */ /* -*- C -*- */
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> * Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -40,26 +40,39 @@
***************************************************************************/ ***************************************************************************/
/** The library version (string) e.g. "1.3.0" */ /** The library version (string) e.g. "1.3.0" */
#define UPNP_VERSION_STRING "1.8.0" #define UPNP_VERSION_STRING "1.6.11"
/** Major version of the library */ /** Major version of the library */
#define UPNP_VERSION_MAJOR 1 #define UPNP_VERSION_MAJOR 1
/** Minor version of the library */ /** Minor version of the library */
#define UPNP_VERSION_MINOR 8 #define UPNP_VERSION_MINOR 6
/** Patch version of the library */ /** Patch version of the library */
#define UPNP_VERSION_PATCH 0 #define UPNP_VERSION_PATCH 11
/** The library version (numeric) e.g. 10300 means version 1.3.0 */ /** The library version (numeric) e.g. 10300 means version 1.3.0 */
#define UPNP_VERSION \ #define UPNP_VERSION \
((UPNP_VERSION_MAJOR*100 + UPNP_VERSION_MINOR)*100 + UPNP_VERSION_PATCH) ((UPNP_VERSION_MAJOR * 100 + UPNP_VERSION_MINOR) * 100 + UPNP_VERSION_PATCH)
/***************************************************************************
* Large file support
***************************************************************************/
/** File Offset size */
#define _FILE_OFFSET_BITS 64
/** Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#define _LARGEFILE_SOURCE 1
/** Large files support */
#define _LARGE_FILE_SOURCE /**/
/*************************************************************************** /***************************************************************************
* Library optional features * Library optional features
***************************************************************************/ ***************************************************************************/
/* /*
* The following defines can be tested in order to know which * The following defines can be tested in order to know which
@@ -69,7 +82,7 @@
/** Defined to 1 if the library has been compiled with DEBUG enabled /** Defined to 1 if the library has been compiled with DEBUG enabled
* (i.e. configure --enable-debug) : <upnp/upnpdebug.h> file is available */ * (i.e. configure --enable-debug) : <upnp/upnpdebug.h> file is available */
#define UPNP_HAVE_DEBUG 1 /* #undef UPNP_HAVE_DEBUG */
/** Defined to 1 if the library has been compiled with client API enabled /** Defined to 1 if the library has been compiled with client API enabled
@@ -91,6 +104,9 @@
* (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */ * (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
#define UPNP_HAVE_TOOLS 1 #define UPNP_HAVE_TOOLS 1
/** Defined to 1 if the library has been compiled with ipv6 support
* (i.e. configure --enable-ipv6) */
/* #undef UPNP_ENABLE_IPV6 */
#endif /* UPNP_CONFIG_H */ #endif /* UPNP_CONFIG_H */

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@
AC_PREREQ(2.60) AC_PREREQ(2.60)
AC_INIT([libupnp], [1.8.0], [mroberto@users.sourceforge.net]) AC_INIT([libupnp], [1.6.11], [mroberto@users.sourceforge.net])
dnl ############################################################################ dnl ############################################################################
dnl # *Independently* of the above libupnp package version, the libtool version dnl # *Independently* of the above libupnp package version, the libtool version
dnl # of the 3 libraries need to be updated whenever there is a change released: dnl # of the 3 libraries need to be updated whenever there is a change released:
@@ -144,30 +144,93 @@ dnl #AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0]) dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0])
dnl # dnl #
dnl ############################################################################ dnl ############################################################################
dnl # Release 1.8.0: dnl # Release 1.6.7:
dnl # "current:revision:age" dnl # "current:revision:age"
dnl # dnl #
dnl # - Code has changed in threadutil
dnl # revision: 3 -> 4
dnl # - Code has changed in upnp dnl # - Code has changed in upnp
dnl # revision: 5 -> 6 dnl # revision: 5 -> 6
dnl # - Interfaces have been changed, added and removed in upnp dnl # - Interfaces have been changed, added and removed in upnp
dnl # current: 3 -> 4 dnl # current: 3 -> 4
dnl # revision: 6 -> 0 dnl # revision: 6 -> 0
dnl # - Interface has been removed in upnp dnl # - Interfaces removed in upnp:
dnl # age = 0 dnl # age: -> 0
dnl # - Code has changed in threadutil
dnl # revision: 3 -> 4
dnl # - Interfaces have been changed, added and removed in upnp
dnl # current: 4 -> 5
dnl # revision: 4 -> 0
dnl # dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0]) dnl #AC_SUBST([LT_VERSION_IXML], [2:4:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0])
dnl #
dnl # Obs.: 1.6.7 was released with a version error, the correct nubers should
dnl # have been:
dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0]) dnl #AC_SUBST([LT_VERSION_UPNP], [4:0:0])
dnl # dnl #
dnl ############################################################################ dnl ############################################################################
AC_SUBST([LT_VERSION_IXML], [2:4:0]) dnl # Release 1.6.8:
AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2]) dnl # "current:revision:age"
AC_SUBST([LT_VERSION_UPNP], [4:0:0]) dnl #
dnl # - Code has changed in ixml
dnl # revision: 4 -> 5
dnl # - Code has changed in threadutil
dnl # revision: 0 -> 1
dnl # - Code has changed in upnp
dnl # revision: 0 -> 1
dnl #
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 ############################################################################
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 in ixml
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 #
dnl ############################################################################
dnl # Release 1.6.11:
dnl # "current:revision:age"
dnl #
dnl # - Code has changed in threadutil
dnl # revision: 3 -> 4
dnl # - Code has changed in upnp
dnl # revision: 3 -> 4
dnl # - interface has changed in upnp
dnl # current: 5 -> 6
dnl # revision: 4 -> 0
dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:6:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:4:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [6:0:0])
dnl #
############################################################################
AC_SUBST([LT_VERSION_IXML], [2:6:0])
AC_SUBST([LT_VERSION_THREADUTIL], [5:4:2])
AC_SUBST([LT_VERSION_UPNP], [6:0:0])
dnl ############################################################################ dnl ############################################################################
dnl # Repeating the algorithm to place it closer to the modificatin place: dnl # Repeating the algorithm to place it closer to the modificatin place:
dnl # - library code modified: revision++ dnl # - library code modified: revision++
@@ -261,6 +324,21 @@ if test "x$enable_tools" = xyes ; then
AC_DEFINE(UPNP_HAVE_TOOLS, 1, [see upnpconfig.h]) AC_DEFINE(UPNP_HAVE_TOOLS, 1, [see upnpconfig.h])
fi fi
RT_BOOL_ARG_ENABLE([ipv6], [no], [ipv6 support])
if test "x$enable_ipv6" = xyes ; then
AC_DEFINE(UPNP_ENABLE_IPV6, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([notification_reordering], [yes], [GENA notification reordering in gena_device.c])
if test "x$enable_notification_reordering" = xyes ; then
AC_DEFINE(UPNP_ENABLE_NOTIFICATION_REORDERING, 1, [see upnpconfig.h])
fi
RT_BOOL_ARG_ENABLE([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]) RT_BOOL_ARG_ENABLE([samples], [yes], [compilation of upnp/sample/ code])
@@ -321,10 +399,11 @@ freebsd*)
*) *)
echo "Using non-specific system compiler settings" echo "Using non-specific system compiler settings"
if test x"$enable_debug" = xyes; then if test x"$enable_debug" = xyes; then
# AC_PROG_CC already sets CFLAGS to "-g -O2" by default # AC_PROG_CC already sets CFLAGS to "-g -O2" by default,
# but only if CFLAGS was not previously set.
#: #:
# Use -O0 in debug so that variables do not get optimized out # Use -O0 in debug so that variables do not get optimized out
AX_CFLAGS_GCC_OPTION([-O0]) AX_CFLAGS_GCC_OPTION([-O0, -g])
else else
# add optimise for size # add optimise for size
AX_CFLAGS_GCC_OPTION([-Os]) AX_CFLAGS_GCC_OPTION([-Os])
@@ -425,7 +504,10 @@ fi
# #
AC_FUNC_VPRINTF AC_FUNC_VPRINTF
AC_FUNC_FSEEKO AC_FUNC_FSEEKO
AC_CHECK_FUNCS(ftime,, [AC_CHECK_LIB(compat, ftime)]) AC_CHECK_FUNC(strnlen,
AC_DEFINE(HAVE_STRNLEN, 1, [Defines if strnlen is available on your system]))
AC_CHECK_FUNC(strndup,
AC_DEFINE(HAVE_STRNDUP, 1, [Defines if strndup is available on your system]))
# #
# Solaris needs -lsocket -lnsl -lrt # Solaris needs -lsocket -lnsl -lrt
AC_SEARCH_LIBS([bind], [socket]) AC_SEARCH_LIBS([bind], [socket])
@@ -487,3 +569,11 @@ AC_CONFIG_FILES([
AC_OUTPUT AC_OUTPUT
#
# Files copied for windows compilation.
#
echo "configure: copying \"autoconfig.h\" to \"build/inc/autoconfig.h\""
cp autoconfig.h build/inc/autoconfig.h
echo "configure: copying \"upnp/inc/upnpconfig.h\" to \"build/inc/upnpconfig.h\""
cp upnp/inc/upnpconfig.h build/inc/upnpconfig.h

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -75,10 +75,10 @@ static int ixml_membuf_set_size(
diff = new_length - m->length; diff = new_length - m->length;
alloc_len = MAXVAL(m->size_inc, diff) + m->capacity; alloc_len = MAXVAL(m->size_inc, diff) + m->capacity;
} else { } else {
// decrease length /* decrease length */
assert(new_length <= m->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) { if ((m->capacity - new_length) <= m->size_inc) {
return 0; return 0;
} }
@@ -135,21 +135,21 @@ int ixml_membuf_assign(
assert(m != NULL); assert(m != NULL);
// set value to null /* set value to null */
if (buf == NULL) { if (buf == NULL) {
ixml_membuf_destroy(m); ixml_membuf_destroy(m);
return IXML_SUCCESS; return IXML_SUCCESS;
} }
// alloc mem /* alloc mem */
return_code = ixml_membuf_set_size(m, buf_len); return_code = ixml_membuf_set_size(m, buf_len);
if (return_code != 0) { if (return_code != 0) {
return return_code; return return_code;
} }
// copy /* copy */
memcpy(m->buf, buf, buf_len); memcpy(m->buf, buf, buf_len);
// null-terminate /* null-terminate */
m->buf[buf_len] = 0; m->buf[buf_len] = 0;
m->length = buf_len; m->length = buf_len;
@@ -187,13 +187,13 @@ int ixml_membuf_insert(
INOUT ixml_membuf *m, INOUT ixml_membuf *m,
IN const void *buf, IN const void *buf,
IN size_t buf_len, IN size_t buf_len,
int index) size_t index)
{ {
int return_code = 0; int return_code = 0;
assert(m != NULL); assert(m != NULL);
if (index < 0 || index > (int)m->length) { if (index > m->length) {
return IXML_INDEX_SIZE_ERR; 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, IXML_NamedNodeMap *nnMap,
const DOMString name) const DOMString name)
{ {
long index; unsigned long index;
if (nnMap == NULL || name == NULL) { if (nnMap == NULL || name == NULL) {
return NULL; return NULL;
@@ -95,7 +95,7 @@ IXML_Node *ixmlNamedNodeMap_getNamedItem(
if (index == IXML_INVALID_ITEM_NUMBER) { if (index == IXML_INVALID_ITEM_NUMBER) {
return NULL; return NULL;
} else { } else {
return ixmlNamedNodeMap_item(nnMap, (unsigned long)index); return ixmlNamedNodeMap_item(nnMap, index);
} }
} }
@@ -165,7 +165,7 @@ int ixmlNamedNodeMap_addToNamedNodeMap(
} }
if (*nnMap == NULL) { if (*nnMap == NULL) {
// nodelist is empty /* nodelist is empty */
*nnMap = (IXML_NamedNodeMap *)malloc(sizeof (IXML_NamedNodeMap)); *nnMap = (IXML_NamedNodeMap *)malloc(sizeof (IXML_NamedNodeMap));
if (*nnMap == NULL) { if (*nnMap == NULL) {
return IXML_INSUFFICIENT_MEMORY; return IXML_INSUFFICIENT_MEMORY;

View File

@@ -542,11 +542,11 @@ int ixmlNode_replaceChild(
if (ixmlNode_allowChildren(nodeptr, newChild) == FALSE) { if (ixmlNode_allowChildren(nodeptr, newChild) == FALSE) {
return IXML_HIERARCHY_REQUEST_ERR; 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) { if (nodeptr->ownerDocument != newChild->ownerDocument) {
return IXML_WRONG_DOCUMENT_ERR; 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) { if (ixmlNode_isParent(nodeptr, oldChild) != TRUE) {
return IXML_NOT_FOUND_ERR; return IXML_NOT_FOUND_ERR;
} }
@@ -763,6 +763,10 @@ static IXML_Element *ixmlNode_cloneElement(
/*! /*!
* \brief Returns a clone of a document node. * \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. * \return A clone of a document node.
*/ */
static IXML_Document *ixmlNode_cloneDoc( static IXML_Document *ixmlNode_cloneDoc(
@@ -781,7 +785,7 @@ static IXML_Document *ixmlNode_cloneDoc(
} }
ixmlDocument_init(newDoc); ixmlDocument_init(newDoc);
docNode = (IXML_Node *) newDoc; docNode = (IXML_Node *)newDoc;
rc = ixmlNode_setNodeName(docNode, DOCUMENTNODENAME); rc = ixmlNode_setNodeName(docNode, DOCUMENTNODENAME);
if (rc != IXML_SUCCESS) { if (rc != IXML_SUCCESS) {
@@ -792,6 +796,7 @@ static IXML_Document *ixmlNode_cloneDoc(
newDoc->n.nodeType = eDOCUMENT_NODE; newDoc->n.nodeType = eDOCUMENT_NODE;
return newDoc; return newDoc;
nodeptr = nodeptr;
} }
/*! /*!

View File

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

View File

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

View File

@@ -1,8 +1,7 @@
# $Id: Makefile.am,v 1.2 2006/02/27 21:38:56 r3mi Exp $
# #
# "Makefile.am" for "libupnp/threadutil" # "Makefile.am" for "libupnp/threadutil"
# #
# (C) Copyright 2005 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> # (C) Copyright 2005 Remi Turboult <r3mi@users.sourceforge.net>
# #
AM_CPPFLAGS = -I$(srcdir)/inc -I$(srcdir)/src/inc AM_CPPFLAGS = -I$(srcdir)/inc -I$(srcdir)/src/inc
@@ -19,12 +18,16 @@ lib_LTLIBRARIES = libthreadutil.la
libthreadutil_la_LDFLAGS = -version-info $(LT_VERSION_THREADUTIL) libthreadutil_la_LDFLAGS = -version-info $(LT_VERSION_THREADUTIL)
libthreadutil_la_SOURCES = \ libthreadutil_la_SOURCES = \
src/FreeList.c src/LinkedList.c \ inc/FreeList.h \
src/ThreadPool.c src/TimerThread.c src/FreeList.c \
inc/LinkedList.h \
src/LinkedList.c \
inc/ThreadPool.h \
src/ThreadPool.c \
inc/TimerThread.h \
src/TimerThread.c
upnpincludedir = $(includedir)/upnp upnpincludedir = $(includedir)/upnp
upnpinclude_HEADERS = \ upnpinclude_HEADERS = \
inc/FreeList.h inc/LinkedList.h \
inc/ThreadPool.h inc/TimerThread.h \
inc/ithread.h inc/ithread.h

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,3 +1,6 @@
#ifndef ITHREAD_H
#define ITHREAD_H
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
@@ -29,43 +32,29 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef ITHREAD_H
#define ITHREAD_H
/*! /*!
* \file * \file
*/ */
#if !defined(WIN32) #if !defined(WIN32)
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#include "UpnpGlobal.h" /* For UPNP_INLINE, EXPORT_SPEC */ #include "UpnpGlobal.h" /* For UPNP_INLINE, EXPORT_SPEC */
#include "UpnpUniStd.h" /* for close() */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <pthread.h> #include <pthread.h>
#ifdef WIN32
/* Do not #include <unistd.h> */
#else
#include <unistd.h>
#endif
#if defined(BSD) #if defined(BSD)
#define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE
#endif #endif
#ifdef PTHREAD_MUTEX_RECURSIVE #if defined(PTHREAD_MUTEX_RECURSIVE) || defined(__DragonFly__)
/* This system has SuS2-compliant mutex attributes. /* This system has SuS2-compliant mutex attributes.
* E.g. on Cygwin, where we don't have the old nonportable (NP) symbols * E.g. on Cygwin, where we don't have the old nonportable (NP) symbols
*/ */
@@ -85,7 +74,10 @@ extern "C" {
#define ITHREAD_CANCELED PTHREAD_CANCELED #define ITHREAD_CANCELED PTHREAD_CANCELED
#define ITHREAD_STACK_MIN PTHREAD_STACK_MIN
/*************************************************************************** /***************************************************************************
* Name: ithread_t * Name: ithread_t
* *
@@ -171,7 +163,9 @@ typedef pthread_condattr_t ithread_condattr_t;
* typedef to pthread_rwlockattr_t * typedef to pthread_rwlockattr_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
#if UPNP_USE_RWLOCK
typedef pthread_rwlockattr_t ithread_rwlockattr_t; typedef pthread_rwlockattr_t ithread_rwlockattr_t;
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -182,7 +176,12 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t;
* typedef to pthread_rwlock_t * typedef to pthread_rwlock_t
* Internal Use Only * Internal Use Only
***************************************************************************/ ***************************************************************************/
typedef pthread_rwlock_t ithread_rwlock_t; #if UPNP_USE_RWLOCK
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 */
/**************************************************************************** /****************************************************************************
@@ -326,11 +325,11 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Returns EINVAL if the kind is not supported. * Returns EINVAL if the kind is not supported.
* See man page for pthread_mutexattr_setkind_np * 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 #define ithread_mutexattr_setkind_np pthread_mutexattr_settype
#else #else
#define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np #define ithread_mutexattr_setkind_np pthread_mutexattr_setkind_np
#endif #endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
* Function: ithread_mutexattr_getkind_np * Function: ithread_mutexattr_getkind_np
@@ -351,11 +350,11 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_mutexattr_getkind_np * 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 #define ithread_mutexattr_getkind_np pthread_mutexattr_gettype
#else #else
#define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np #define ithread_mutexattr_getkind_np pthread_mutexattr_getkind_np
#endif #endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -443,7 +442,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlockattr_init * See man page for pthread_rwlockattr_init
***************************************************************************/ ***************************************************************************/
#define ithread_rwlockattr_init pthread_rwlockattr_init #if UPNP_USE_RWLOCK
#define ithread_rwlockattr_init pthread_rwlockattr_init
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -459,7 +460,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlockattr_destroy * See man page for pthread_rwlockattr_destroy
***************************************************************************/ ***************************************************************************/
#define ithread_rwlockattr_destroy pthread_rwlockattr_destroy #if UPNP_USE_RWLOCK
#define ithread_rwlockattr_destroy pthread_rwlockattr_destroy
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -480,7 +483,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Returns EINVAL if the kind is not supported. * Returns EINVAL if the kind is not supported.
* See man page for pthread_rwlockattr_setkind_np * See man page for pthread_rwlockattr_setkind_np
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlockatttr_setpshared pthread_rwlockatttr_setpshared #if UPNP_USE_RWLOCK
#define ithread_rwlockatttr_setpshared pthread_rwlockatttr_setpshared
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -501,7 +506,9 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlockatttr_getpshared * See man page for pthread_rwlockatttr_getpshared
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlockatttr_getpshared pthread_rwlockatttr_getpshared #if UPNP_USE_RWLOCK
#define ithread_rwlockatttr_getpshared pthread_rwlockatttr_getpshared
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -519,8 +526,12 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlock_init * See man page for pthread_rwlock_init
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlock_init pthread_rwlock_init #if UPNP_USE_RWLOCK
#define ithread_rwlock_init pthread_rwlock_init
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_init ithread_mutex_init
#endif
/**************************************************************************** /****************************************************************************
* Function: ithread_rwlock_rdlock * Function: ithread_rwlock_rdlock
@@ -536,8 +547,12 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlock_rdlock * See man page for pthread_rwlock_rdlock
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlock_rdlock pthread_rwlock_rdlock #if UPNP_USE_RWLOCK
#define ithread_rwlock_rdlock pthread_rwlock_rdlock
#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 * Function: ithread_rwlock_wrlock
@@ -553,7 +568,12 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlock_wrlock * See man page for pthread_rwlock_wrlock
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlock_wrlock pthread_rwlock_wrlock #if UPNP_USE_RWLOCK
#define ithread_rwlock_wrlock pthread_rwlock_wrlock
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_wrlock ithread_mutex_lock
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -571,7 +591,12 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlock_unlock * See man page for pthread_rwlock_unlock
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlock_unlock pthread_rwlock_unlock #if UPNP_USE_RWLOCK
#define ithread_rwlock_unlock pthread_rwlock_unlock
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_unlock ithread_mutex_unlock
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -590,7 +615,12 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* Always returns 0. * Always returns 0.
* See man page for pthread_rwlock_destroy * See man page for pthread_rwlock_destroy
*****************************************************************************/ *****************************************************************************/
#define ithread_rwlock_destroy pthread_rwlock_destroy #if UPNP_USE_RWLOCK
#define ithread_rwlock_destroy pthread_rwlock_destroy
#else
/* Read-write locks aren't available: use mutex instead. */
#define ithread_rwlock_destroy ithread_mutex_destroy
#endif /* UPNP_USE_RWLOCK */
/**************************************************************************** /****************************************************************************
@@ -704,6 +734,49 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
***************************************************************************/ ***************************************************************************/
#define ithread_cond_destroy pthread_cond_destroy #define ithread_cond_destroy pthread_cond_destroy
/****************************************************************************
* Function: ithread_attr_init
*
* Description:
* Initialises thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_init
***************************************************************************/
#define ithread_attr_init pthread_attr_init
/****************************************************************************
* Function: ithread_attr_destroy
*
* Description:
* Destroys thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_destroy
***************************************************************************/
#define ithread_attr_destroy pthread_attr_destroy
/****************************************************************************
* Function: ithread_attr_setstacksize
*
* Description:
* Sets stack size of a thread attribute object.
* Parameters:
* ithread_attr_t *attr (must be valid non NULL pointer to
* ithread_attr_t)
* size_t stacksize (value of stacksize must be greater than
* ITHREAD_STACK_MIN and lower than system-imposed limits
* Returns:
* 0 on success. Nonzero on failure.
* See man page for pthread_attr_setstacksize
***************************************************************************/
#define ithread_attr_setstacksize pthread_attr_setstacksize
/**************************************************************************** /****************************************************************************
* Function: ithread_create * Function: ithread_create
@@ -713,7 +786,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
* and argument. * and argument.
* Parameters: * Parameters:
* ithread_t * thread (must be valid non NULL pointer to pthread_t) * ithread_t * thread (must be valid non NULL pointer to pthread_t)
* ithread_attr_t *attr, IGNORED * ithread_attr_t *attr
* void * (start_routine) (void *arg) (start routine) * void * (start_routine) (void *arg) (start routine)
* void * arg - argument. * void * arg - argument.
* Returns: * Returns:
@@ -849,7 +922,7 @@ static UPNP_INLINE int ithread_cleanup_thread(void) {
#endif #endif
#ifndef PTHREAD_MUTEX_RECURSIVE #if !defined(PTHREAD_MUTEX_RECURSIVE) && !defined(__DragonFly__)
/* NK: Added for satisfying the gcc compiler */ /* NK: Added for satisfying the gcc compiler */
EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind); EXPORT_SPEC int pthread_mutexattr_setkind_np(pthread_mutexattr_t *attr, int kind);
#endif #endif

View File

@@ -1,177 +1,111 @@
/////////////////////////////////////////////////////////////////////////// /**************************************************************************
// *
// Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
// All rights reserved. * All rights reserved.
// *
// Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
// *
// * Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
// * Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
// may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
// without specific prior written permission. * without specific prior written permission.
// *
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// *
/////////////////////////////////////////////////////////////////////////// **************************************************************************/
#include "FreeList.h" #include "FreeList.h"
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
/**************************************************************************** int FreeListInit(FreeList *free_list, size_t elementSize, int maxFreeListLength)
* 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 )
{ {
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (free_list == NULL)
return EINVAL; return EINVAL;
free_list->element_size = elementSize;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
free_list->element_size = elementSize; return 0;
free_list->maxFreeListLength = maxFreeListLength;
free_list->head = NULL;
free_list->freeListLength = 0;
return 0;
} }
/**************************************************************************** void *FreeListAlloc(FreeList *free_list)
* 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 )
{ {
FreeListNode *ret = NULL; FreeListNode *ret = NULL;
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (free_list == NULL)
return NULL; return NULL;
if( free_list->head ) { if (free_list->head) {
ret = free_list->head; ret = free_list->head;
free_list->head = free_list->head->next; free_list->head = free_list->head->next;
free_list->freeListLength--; free_list->freeListLength--;
} else { } else {
ret = malloc( free_list->element_size ); ret = malloc(free_list->element_size);
} }
return ret; return ret;
} }
/**************************************************************************** int FreeListFree(FreeList *free_list, void *element)
* 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 )
{ {
FreeListNode *temp = NULL;
FreeListNode *temp = NULL; assert(free_list != NULL);
assert( free_list != NULL ); if (free_list == NULL)
return EINVAL;
if (element != NULL &&
free_list->freeListLength + 1 < free_list->maxFreeListLength) {
free_list->freeListLength++;
temp = (FreeListNode *)element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free(element);
}
if( free_list == NULL ) return 0;
return EINVAL;
if( ( element != NULL ) &&
( ( free_list->freeListLength + 1 ) <
free_list->maxFreeListLength ) ) {
free_list->freeListLength++;
temp = ( FreeListNode * ) element;
temp->next = free_list->head;
free_list->head = temp;
} else {
free( element );
}
return 0;
} }
/**************************************************************************** int FreeListDestroy(FreeList *free_list)
* 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 )
{ {
FreeListNode *temp = NULL; FreeListNode *temp = NULL;
int i = 0; int i = 0;
assert( free_list != NULL ); assert(free_list != NULL);
if( free_list == NULL ) if (!free_list)
return EINVAL; return EINVAL;
while (free_list->head) {
i++;
temp = free_list->head->next;
free(free_list->head);
free_list->head = temp;
}
free_list->freeListLength = 0;
while( free_list->head ) { return 0;
i++;
temp = free_list->head->next;
free( free_list->head );
free_list->head = temp;
}
free_list->freeListLength = 0;
return 0;
} }

View File

@@ -29,519 +29,281 @@
* *
**************************************************************************/ **************************************************************************/
#include "LinkedList.h" #include "LinkedList.h"
#ifdef WIN32 #ifdef WIN32
/* Do not #include <sys/param.h> */ /* Do not #include <sys/param.h> */
#else #else
#include <sys/param.h> #include <sys/param.h>
#endif #endif
#if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__) #if (defined(BSD) && BSD >= 199306) || defined(__OSX__) || defined(__APPLE__)
#include <stdlib.h> #include <stdlib.h>
#else #else
#include <malloc.h> #include <malloc.h>
#endif #endif
#include <assert.h> #include <assert.h>
static int 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 * \brief Dynamically creates a list node.
*
* Description:
* Creates a list node. Dynamically.
* *
* Parameters: * Parameters:
* void * item - the item to store * void * item - the item to store
* Returns: * Returns:
* The new node, NULL on failure. * The new node, NULL on failure.
*****************************************************************************/ */
static ListNode * static ListNode *CreateListNode(
CreateListNode( void *item, /*! the item to store. */
LinkedList * list ) void *item,
/*! The list to add it to. */
LinkedList *list)
{ {
ListNode *temp = NULL;
ListNode *temp = NULL; assert(list != NULL);
assert( list != NULL ); temp = (ListNode *)FreeListAlloc(&list->freeNodeList);
if (temp) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
temp = ( ListNode * ) FreeListAlloc( &list->freeNodeList ); return temp;
if( temp ) {
temp->prev = NULL;
temp->next = NULL;
temp->item = item;
}
return temp;
} }
/**************************************************************************** int ListInit(LinkedList *list, cmp_routine cmp_func, free_function free_func)
* 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 retCode = 0;
int retCode = 0; assert(list != NULL);
assert( 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);
if( list == NULL ) assert(retCode == 0);
return EINVAL;
list->size = 0; list->head.item = NULL;
list->cmp_func = cmp_func; list->head.next = &list->tail;
list->free_func = free_func; list->head.prev = NULL;
list->tail.item = NULL;
list->tail.prev = &list->head;
list->tail.next = NULL;
retCode = return 0;
FreeListInit( &list->freeNodeList, sizeof( ListNode ),
FREELISTSIZE );
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;
return 0;
} }
/**************************************************************************** ListNode *ListAddHead(LinkedList *list, void *item)
* 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 )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (list == NULL)
return NULL; return NULL;
return ListAddAfter( list, item, &list->head ); return ListAddAfter(list, item, &list->head);
} }
/**************************************************************************** ListNode *ListAddTail(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 )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
return ListAddBefore( list, item, &list->tail ); return ListAddBefore(list, item, &list->tail);
} }
/**************************************************************************** ListNode *ListAddAfter(LinkedList *list, void *item, ListNode *bnode)
* 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 *newNode = NULL; ListNode *newNode = NULL;
assert( list != NULL ); assert(list != NULL);
if( ( list == NULL ) || ( bnode == NULL ) ) if (!list || !bnode)
return NULL; return NULL;
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = bnode->next;
newNode = CreateListNode( item, list ); bnode->next = newNode;
if( newNode ) { newNode->prev = bnode;
ListNode *temp = bnode->next; newNode->next = temp;
temp->prev = newNode;
list->size++;
bnode->next = newNode; return newNode;
newNode->prev = bnode; }
newNode->next = temp;
temp->prev = newNode; return NULL;
list->size++;
return newNode;
}
return NULL;
} }
/**************************************************************************** ListNode *ListAddBefore(LinkedList *list, void *item, ListNode *anode)
* 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 *newNode = NULL; ListNode *newNode = NULL;
assert( list != NULL ); assert(list != NULL);
if( ( list == NULL ) || ( anode == NULL ) ) if (!list || !anode)
return NULL; return NULL;
newNode = CreateListNode(item, list);
if (newNode) {
ListNode *temp = anode->prev;
newNode = CreateListNode( item, list ); anode->prev = newNode;
newNode->next = anode;
newNode->prev = temp;
temp->next = newNode;
list->size++;
if( newNode ) { return newNode;
ListNode *temp = anode->prev; }
anode->prev = newNode; return NULL;
newNode->next = anode;
newNode->prev = temp;
temp->next = newNode;
list->size++;
return newNode;
}
return NULL;
} }
/**************************************************************************** void *ListDelNode(LinkedList *list, ListNode *dnode, int freeItem)
* 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 *temp; void *temp;
assert( list != NULL ); assert(list != NULL);
assert( dnode != &list->head ); assert(dnode != &list->head);
assert( dnode != &list->tail ); assert(dnode != &list->tail);
if( ( list == NULL ) || if (!list || dnode == &list->head || dnode == &list->tail || !dnode)
( dnode == &list->head ) || return NULL;
( dnode == &list->tail ) || ( dnode == NULL ) ) { temp = dnode->item;
return NULL; dnode->prev->next = dnode->next;
} dnode->next->prev = dnode->prev;
freeListNode(dnode, list);
list->size--;
if (freeItem && list->free_func) {
list->free_func(temp);
temp = NULL;
}
temp = dnode->item; return temp;
dnode->prev->next = dnode->next;
dnode->next->prev = dnode->prev;
freeListNode( dnode, list );
list->size--;
if( freeItem && list->free_func ) {
list->free_func( temp );
temp = NULL;
}
return temp;
} }
/**************************************************************************** int ListDestroy(LinkedList *list, int freeItem)
* 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 )
{ {
ListNode *dnode = NULL; ListNode *dnode = NULL;
ListNode *temp = NULL; ListNode *temp = NULL;
if( list == NULL ) if(!list)
return EINVAL; return EINVAL;
for( dnode = list->head.next; dnode != &list->tail; ) { for (dnode = list->head.next; dnode != &list->tail; ) {
temp = dnode->next; temp = dnode->next;
ListDelNode( list, dnode, freeItem ); ListDelNode(list, dnode, freeItem);
dnode = temp; dnode = temp;
} }
list->size = 0;
FreeListDestroy(&list->freeNodeList);
list->size = 0; return 0;
FreeListDestroy( &list->freeNodeList );
return 0;
} }
/**************************************************************************** ListNode *ListHead(LinkedList *list)
* 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 )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
if( list->size == 0 ) if (!list->size)
return NULL; return NULL;
else else
return list->head.next; return list->head.next;
} }
/**************************************************************************** ListNode *ListTail(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 )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return NULL; return NULL;
if( list->size == 0 ) if (!list->size)
return NULL; return NULL;
else else
return list->tail.prev; return list->tail.prev;
} }
/**************************************************************************** ListNode *ListNext(LinkedList *list, ListNode *node)
* 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 )
{ {
assert( list != NULL ); assert(list != NULL);
assert( node != NULL ); assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) ) if (!list || !node)
return NULL; return NULL;
if (node->next == &list->tail)
if( node->next == &list->tail ) return NULL;
return NULL; else
else return node->next;
return node->next;
} }
/**************************************************************************** ListNode *ListPrev(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 )
{ {
assert( list != NULL ); assert(list != NULL);
assert( node != NULL ); assert(node != NULL);
if( ( list == NULL ) || ( node == NULL ) ) if (!list || !node)
return NULL; return NULL;
if( node->prev == &list->head ) if (node->prev == &list->head)
return NULL; return NULL;
else else
return node->prev; return node->prev;
} }
/**************************************************************************** ListNode *ListFind(LinkedList *list, ListNode *start, void *item)
* 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 *finger = NULL;
ListNode *finger = NULL; if (!list)
return NULL;
if (!start)
start = &list->head;
if( list == NULL ) assert(start);
return NULL;
if( start == NULL ) finger = start->next;
start = &list->head;
assert( start ); assert(finger);
finger = start->next; while (finger != &list->tail) {
if (list->cmp_func) {
assert( finger ); if (list->cmp_func(item, finger->item))
return finger;
while( finger != &list->tail ) { } else {
if( list->cmp_func ) { if (item == finger->item)
if( list->cmp_func( item, finger->item ) ) return finger;
return finger; }
} else { finger = finger->next;
if( item == finger->item ) }
return finger;
}
finger = finger->next;
}
return NULL;
return NULL;
} }
/**************************************************************************** long ListSize(LinkedList *list)
* 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 )
{ {
assert( list != NULL ); assert(list != NULL);
if( list == NULL ) if (!list)
return EINVAL; return EINVAL;
return list->size; return list->size;
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -19,20 +19,14 @@ LDADD = \
upnpincludedir = $(includedir)/upnp upnpincludedir = $(includedir)/upnp
upnpinclude_HEADERS = \ upnpinclude_HEADERS = \
inc/ActionComplete.h \
inc/ActionRequest.h \
inc/Discovery.h \
inc/Event.h \
inc/EventSubscribe.h \
inc/FileInfo.h \
inc/StateVarComplete.h \
inc/StateVarRequest.h \
inc/SubscriptionRequest.h \
inc/UpnpString.h \ inc/UpnpString.h \
inc/upnp.h \ inc/upnp.h \
inc/upnpdebug.h \ inc/upnpdebug.h \
inc/UpnpGlobal.h \ inc/UpnpGlobal.h \
inc/UpnpInet.h inc/UpnpInet.h \
inc/UpnpIntTypes.h \
inc/UpnpStdInt.h \
inc/UpnpUniStd.h
nodist_upnpinclude_HEADERS = inc/upnpconfig.h nodist_upnpinclude_HEADERS = inc/upnpconfig.h
if ENABLE_TOOLS if ENABLE_TOOLS
@@ -53,7 +47,6 @@ libupnp_la_LDFLAGS = \
libupnp_la_SOURCES = \ libupnp_la_SOURCES = \
src/inc/config.h \ src/inc/config.h \
src/inc/client_table.h \ src/inc/client_table.h \
src/inc/ClientSubscription.h \
src/inc/gena.h \ src/inc/gena.h \
src/inc/gena_ctrlpt.h \ src/inc/gena_ctrlpt.h \
src/inc/gena_device.h \ src/inc/gena_device.h \
@@ -77,20 +70,17 @@ libupnp_la_SOURCES = \
src/inc/sysdep.h \ src/inc/sysdep.h \
src/inc/unixutil.h \ src/inc/unixutil.h \
src/inc/upnpapi.h \ src/inc/upnpapi.h \
src/inc/upnpclosesocket.h \
src/inc/upnp_timeout.h \ src/inc/upnp_timeout.h \
src/inc/uri.h \ src/inc/uri.h \
src/inc/urlconfig.h \ src/inc/urlconfig.h \
src/inc/util.h \ src/inc/upnputil.h \
src/inc/utilall.h \
src/inc/uuid.h \ src/inc/uuid.h \
src/inc/VirtualDir.h \ src/inc/VirtualDir.h \
src/inc/webserver.h src/inc/webserver.h
# ssdp # ssdp
libupnp_la_SOURCES += \ libupnp_la_SOURCES += \
src/ssdp/ssdp_ResultData.c \ src/ssdp/ssdp_ResultData.h \
src/ssdp/ssdp_ResultData.h \
src/ssdp/ssdp_device.c \ src/ssdp/ssdp_device.c \
src/ssdp/ssdp_ctrlpt.c \ src/ssdp/ssdp_ctrlpt.c \
src/ssdp/ssdp_server.c src/ssdp/ssdp_server.c
@@ -104,13 +94,12 @@ libupnp_la_SOURCES += \
# genlib # genlib
libupnp_la_SOURCES += \ libupnp_la_SOURCES += \
src/genlib/miniserver/miniserver.c \ src/genlib/miniserver/miniserver.c \
src/genlib/client_table/client_table.c \
src/genlib/client_table/ClientSubscription.c \
src/genlib/service_table/service_table.c \ src/genlib/service_table/service_table.c \
src/genlib/util/membuffer.c \ src/genlib/util/membuffer.c \
src/genlib/util/strintmap.c \ src/genlib/util/strintmap.c \
src/genlib/util/upnp_timeout.c \ src/genlib/util/upnp_timeout.c \
src/genlib/util/util.c \ src/genlib/util/util.c \
src/genlib/client_table/client_table.c \
src/genlib/net/sock.c \ src/genlib/net/sock.c \
src/genlib/net/http/httpparser.c \ src/genlib/net/http/httpparser.c \
src/genlib/net/http/httpreadwrite.c \ src/genlib/net/http/httpreadwrite.c \
@@ -127,15 +116,6 @@ libupnp_la_SOURCES += \
# api # api
libupnp_la_SOURCES += \ libupnp_la_SOURCES += \
src/api/ActionComplete.c \
src/api/ActionRequest.c \
src/api/Discovery.c \
src/api/Event.c \
src/api/EventSubscribe.c \
src/api/FileInfo.c \
src/api/StateVarComplete.c \
src/api/StateVarRequest.c \
src/api/SubscriptionRequest.c \
src/api/UpnpString.c \ src/api/UpnpString.c \
src/api/upnpapi.c src/api/upnpapi.c

View File

@@ -1,173 +0,0 @@
#ifndef ACTIONCOMPLETE_H
#define ACTIONCOMPLETE_H
/*!
* \file
*
* \brief UpnpActionComplete object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*!
* \brief The type of an UpnpActionComplete object.
*/
typedef struct s_UpnpActionComplete UpnpActionComplete;
#include "ixml.h" /* for IXML_Document */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*!
* \brief Constructor.
*
* \return Pointer to the newly created object.
*/
EXPORT_SPEC UpnpActionComplete *UpnpActionComplete_new();
/*!
* \brief Destructor.
*/
EXPORT_SPEC void UpnpActionComplete_delete(
/*! [in] \b this pointer. */
UpnpActionComplete *p);
/*!
* \brief Copy Constructor.
*/
EXPORT_SPEC UpnpActionComplete *UpnpActionComplete_dup(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief Assignment operator.
*/
EXPORT_SPEC void UpnpActionComplete_assign(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] \b that pointer. */
const UpnpActionComplete *q);
/*!
* \brief Error code getter.
*/
EXPORT_SPEC int UpnpActionComplete_get_ErrCode(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief Error code setter.
*/
EXPORT_SPEC void UpnpActionComplete_set_ErrCode(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] The error code to set. */
int n);
/*!
* \brief Control URL getter.
*
* \return The control URL string.
*/
EXPORT_SPEC const UpnpString *UpnpActionComplete_get_CtrlUrl(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief Control URL getter as a C string
*
* \return The control URL string.
*/
EXPORT_SPEC const char *UpnpActionComplete_get_CtrlUrl_cstr(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief Control URL setter.
*/
EXPORT_SPEC void UpnpActionComplete_set_CtrlUrl(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] The control URL string to copy. */
const UpnpString *s);
/*!
* \brief Set the control URL from a null terminated C string.
*/
EXPORT_SPEC void UpnpActionComplete_strcpy_CtrlUrl(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] The null terminated control URL C string to copy. */
const char *s);
/*!
* \brief ActionRequest document getter.
*
* \return A pointer to the document object.
*/
EXPORT_SPEC IXML_Document *UpnpActionComplete_get_ActionRequest(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief ActionRequest document setter.
*
* \note The ActionComplete object takes ownership of the document parameter,
* i.e. it is responsible for deleting it upon destruction.
*/
EXPORT_SPEC void UpnpActionComplete_set_ActionRequest(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] Document to copy. */
IXML_Document *d);
/*!
* \brief ActionResult document getter.
*/
EXPORT_SPEC IXML_Document *UpnpActionComplete_get_ActionResult(
/*! [in] \b this pointer. */
const UpnpActionComplete *p);
/*!
* \brief ActionResult document setter.
*
* \note The ActionComplete object takes ownership of the document parameter,
* i.e. it is responsible for deleting it upon destruction.
*/
EXPORT_SPEC void UpnpActionComplete_set_ActionResult(
/*! [in] \b this pointer. */
UpnpActionComplete *p,
/*! [in] Document to copy. */
IXML_Document *d);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ACTIONCOMPLETE_H */

View File

@@ -1,96 +0,0 @@
#ifndef ACTIONREQUEST_H
#define ACTIONREQUEST_H
/*!
* \file
*
* \brief UpnpActionRequest object declaration.
*
* \author Marcelo Roberto Jimenez
*/
/*! Returned as part of a \b UPNP_CONTROL_ACTION_COMPLETE callback. */
typedef struct s_UpnpActionRequest UpnpActionRequest;
#include "ixml.h" /* for IXML_Document */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpInet.h" /* for sockaddr, sockaddr_storage */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpActionRequest *UpnpActionRequest_new();
/*! Destructor */
EXPORT_SPEC void UpnpActionRequest_delete(UpnpActionRequest *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpActionRequest *UpnpActionRequest_dup(const UpnpActionRequest *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpActionRequest_assign(UpnpActionRequest *p, const UpnpActionRequest *q);
/*! The result of the operation */
EXPORT_SPEC int UpnpActionRequest_get_ErrCode(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ErrCode(UpnpActionRequest *p, int n);
/*! The socket number of the connection to the requestor */
EXPORT_SPEC int UpnpActionRequest_get_Socket(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_Socket(UpnpActionRequest *p, int n);
/*! The error string in case of error */
EXPORT_SPEC const UpnpString *UpnpActionRequest_get_ErrStr(const UpnpActionRequest *p);
EXPORT_SPEC const char *UpnpActionRequest_get_ErrStr_cstr(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ErrStr(UpnpActionRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpActionRequest_strcpy_ErrStr(UpnpActionRequest *p, const char *s);
/*! The Action Name */
EXPORT_SPEC const UpnpString *UpnpActionRequest_get_ActionName(const UpnpActionRequest *p);
EXPORT_SPEC const char *UpnpActionRequest_get_ActionName_cstr(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ActionName(UpnpActionRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpActionRequest_strcpy_ActionName(UpnpActionRequest *p, const char *s);
/*! The unique device ID */
EXPORT_SPEC const UpnpString *UpnpActionRequest_get_DevUDN(const UpnpActionRequest *p);
EXPORT_SPEC const char *UpnpActionRequest_get_DevUDN_cstr(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_DevUDN(UpnpActionRequest *p, const UpnpString *s);
/*! The service ID */
EXPORT_SPEC const UpnpString *UpnpActionRequest_get_ServiceID(const UpnpActionRequest *p);
EXPORT_SPEC const char *UpnpActionRequest_get_ServiceID_cstr(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ServiceID(UpnpActionRequest *p, const UpnpString *s);
/*! The DOM document describing the action */
EXPORT_SPEC IXML_Document *UpnpActionRequest_get_ActionRequest(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ActionRequest(UpnpActionRequest *p, IXML_Document *d);
/*! The DOM document describing the result of the action */
EXPORT_SPEC IXML_Document *UpnpActionRequest_get_ActionResult(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *d);
/*! The DOM document containing the information from the SOAP header */
EXPORT_SPEC IXML_Document *UpnpActionRequest_get_SoapHeader(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_SoapHeader(UpnpActionRequest *p, IXML_Document *d);
/*! IP address of the control point requesting this action */
EXPORT_SPEC const struct sockaddr *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p);
EXPORT_SPEC void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, const struct sockaddr *sa);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* ACTIONREQUEST_H */

View File

@@ -1,112 +0,0 @@
#ifndef DISCOVERY_H
#define DISCOVERY_H
/*!
* \file
*
* \brief UpnpDiscovery object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Returned in a \b UPNP_DISCOVERY_RESULT callback. */
typedef struct s_UpnpDiscovery UpnpDiscovery;
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpInet.h" /* for sockaddr, sockaddr_storage */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpDiscovery *UpnpDiscovery_new();
/*! Destructor */
EXPORT_SPEC void UpnpDiscovery_delete(UpnpDiscovery *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpDiscovery *UpnpDiscovery_dup(const UpnpDiscovery *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpDiscovery_assign(UpnpDiscovery *p, const UpnpDiscovery *q);
/*! The result code of the \b UpnpSearchAsync call. */
EXPORT_SPEC int UpnpDiscovery_get_ErrCode(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_ErrCode(UpnpDiscovery *p, int n);
/*! The expiration time of the advertisement. */
EXPORT_SPEC int UpnpDiscovery_get_Expires(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_Expires(UpnpDiscovery *p, int n);
/*! The unique device identifier. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_DeviceID(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_DeviceID_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_DeviceID(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_DeviceID(UpnpDiscovery *p, const char *s);
/*! The device type. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_DeviceType(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_DeviceType_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_DeviceType(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_DeviceType(UpnpDiscovery *p, const char *s);
/*! The ServiceType. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_ServiceType(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_ServiceType_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_ServiceType(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_ServiceType(UpnpDiscovery *p, const char *s);
/*! The service version. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_ServiceVer(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_ServiceVer_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_ServiceVer(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_ServiceVer(UpnpDiscovery *p, const char *s);
/*! The URL to the UPnP description document for the device. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_Location(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_Location_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_Location(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_Location(UpnpDiscovery *p, const char *s);
EXPORT_SPEC void UpnpDiscovery_strncpy_Location(UpnpDiscovery *p, const char *s, int n);
/*! The operating system the device is running. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_Os(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_Os_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_Os(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_Os(UpnpDiscovery *p, const char *s);
EXPORT_SPEC void UpnpDiscovery_strncpy_Os(UpnpDiscovery *p, const char *s, int n);
/*! Date when the response was generated. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_Date(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_Date_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_Date(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_Date(UpnpDiscovery *p, const char *s);
/*! Confirmation that the MAN header was understood by the device. */
EXPORT_SPEC const UpnpString *UpnpDiscovery_get_Ext(const UpnpDiscovery *p);
EXPORT_SPEC const char *UpnpDiscovery_get_Ext_cstr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_Ext(UpnpDiscovery *p, const UpnpString *s);
EXPORT_SPEC void UpnpDiscovery_strcpy_Ext(UpnpDiscovery *p, const char *s);
EXPORT_SPEC void UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, int n);
/*! The host address of the device responding to the search. */
EXPORT_SPEC const struct sockaddr *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p);
EXPORT_SPEC void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, const struct sockaddr *sa);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* DISCOVERY_H */

View File

@@ -1,62 +0,0 @@
#ifndef EVENT_H
#define EVENT_H
/*!
* \file
*
* \brief UpnpEvent object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Returned along with a \b UPNP_EVENT_RECEIVED callback. */
typedef struct s_UpnpEvent UpnpEvent;
#include "ixml.h" /* for IXML_Document */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpEvent *UpnpEvent_new();
/*! Destructor */
EXPORT_SPEC void UpnpEvent_delete(UpnpEvent *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpEvent *UpnpEvent_dup(const UpnpEvent *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpEvent_assign(UpnpEvent *p, const UpnpEvent *q);
/*! The event sequence number. */
EXPORT_SPEC int UpnpEvent_get_EventKey(const UpnpEvent *p);
EXPORT_SPEC void UpnpEvent_set_EventKey(UpnpEvent *p, int n);
/*! The DOM tree representing the changes generating the event. */
EXPORT_SPEC IXML_Document *UpnpEvent_get_ChangedVariables(const UpnpEvent *p);
EXPORT_SPEC void UpnpEvent_set_ChangedVariables(UpnpEvent *p, IXML_Document *d);
/*! The subscription ID for this subscription. */
EXPORT_SPEC const UpnpString *UpnpEvent_get_SID(const UpnpEvent *p);
EXPORT_SPEC const char *UpnpEvent_get_SID_cstr(const UpnpEvent *p);
EXPORT_SPEC void UpnpEvent_set_SID(UpnpEvent *p, const UpnpString *s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* EVENT_H */

View File

@@ -1,74 +0,0 @@
#ifndef EVENTSUBSCRIBE_H
#define EVENTSUBSCRIBE_H
/*!
* \file
*
* \brief UpnpEventSubscribe object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Returned along with a \b UPNP_EVENT_SUBSCRIBE_COMPLETE or
* \b UPNP_EVENT_UNSUBSCRIBE_COMPLETE callback. */
typedef struct s_UpnpEventSubscribe UpnpEventSubscribe;
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpEventSubscribe *UpnpEventSubscribe_new();
/*! Destructor */
EXPORT_SPEC void UpnpEventSubscribe_delete(UpnpEventSubscribe *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpEventSubscribe *UpnpEventSubscribe_dup(const UpnpEventSubscribe *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpEventSubscribe_assign(UpnpEventSubscribe *p, const UpnpEventSubscribe *q);
/*! The result of the operation. */
EXPORT_SPEC int UpnpEventSubscribe_get_ErrCode(const UpnpEventSubscribe *p);
EXPORT_SPEC void UpnpEventSubscribe_set_ErrCode(UpnpEventSubscribe *p, int n);
/*! The actual subscription time (for subscriptions only). */
EXPORT_SPEC int UpnpEventSubscribe_get_TimeOut(const UpnpEventSubscribe *p);
EXPORT_SPEC void UpnpEventSubscribe_set_TimeOut(UpnpEventSubscribe *p, int n);
/*! The SID for this subscription. For subscriptions, this only
* contains a valid SID if the \b Upnp_EventSubscribe.result field
* contains a \b UPNP_E_SUCCESS result code. For unsubscriptions,
* this contains the SID from which the subscription is being
* unsubscribed. */
EXPORT_SPEC const UpnpString *UpnpEventSubscribe_get_SID(const UpnpEventSubscribe *p);
EXPORT_SPEC const char *UpnpEventSubscribe_get_SID_cstr(const UpnpEventSubscribe *p);
EXPORT_SPEC void UpnpEventSubscribe_set_SID(UpnpEventSubscribe *p, const UpnpString *s);
EXPORT_SPEC void UpnpEventSubscribe_strcpy_SID(UpnpEventSubscribe *p, const char *s);
/*! The event URL being subscribed to or removed from. */
EXPORT_SPEC const UpnpString *UpnpEventSubscribe_get_PublisherUrl(const UpnpEventSubscribe *p);
EXPORT_SPEC const char *UpnpEventSubscribe_get_PublisherUrl_cstr(const UpnpEventSubscribe *p);
EXPORT_SPEC void UpnpEventSubscribe_set_PublisherUrl(UpnpEventSubscribe *p, const UpnpString *s);
EXPORT_SPEC void UpnpEventSubscribe_strcpy_PublisherUrl(UpnpEventSubscribe *p, const char *s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* EVENTSUBSCRIBE_H */

View File

@@ -1,84 +0,0 @@
#ifndef FILEINFO_H
#define FILEINFO_H
/*!
* \file
*
* \brief UpnpFileInfo object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Detailed description of this class should go here */
typedef struct s_UpnpFileInfo UpnpFileInfo;
#include "ixml.h" /* for DOMString */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include <sys/types.h> /* for off_t */
#include <time.h> /* for time_t */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpFileInfo *UpnpFileInfo_new();
/*! Destructor */
EXPORT_SPEC void UpnpFileInfo_delete(UpnpFileInfo *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpFileInfo *UpnpFileInfo_dup(const UpnpFileInfo *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpFileInfo_assign(UpnpFileInfo *p, const UpnpFileInfo *q);
/*! The length of the file. A length less than 0 indicates the size
* is unknown, and data will be sent until 0 bytes are returned from
* a read call. */
EXPORT_SPEC off_t UpnpFileInfo_get_FileLength(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_FileLength(UpnpFileInfo *p, off_t l);
/*! The time at which the contents of the file was modified;
* The time system is always local (not GMT). */
EXPORT_SPEC const time_t *UpnpFileInfo_get_LastModified(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_LastModified(UpnpFileInfo *p, const time_t *t);
/*! If the file is a directory, \b is_directory contains
* a non-zero value. For a regular file, it should be 0. */
EXPORT_SPEC int UpnpFileInfo_get_IsDirectory(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_IsDirectory(UpnpFileInfo *p, int b);
/*! If the file or directory is readable, this contains
* a non-zero value. If unreadable, it should be set to 0. */
EXPORT_SPEC int UpnpFileInfo_get_IsReadable(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_IsReadable(UpnpFileInfo *p, int b);
/*! The content type of the file. */
EXPORT_SPEC const DOMString UpnpFileInfo_get_ContentType(const UpnpFileInfo *p);
EXPORT_SPEC const char *UpnpFileInfo_get_ContentType_cstr(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_ContentType(UpnpFileInfo *p, const DOMString s);
/*! Additional HTTP headers to return. Each header line should be
* followed by "\r\n". */
EXPORT_SPEC const DOMString UpnpFileInfo_get_ExtraHeaders(const UpnpFileInfo *p);
EXPORT_SPEC const char *UpnpFileInfo_get_ExtraHeaders_cstr(const UpnpFileInfo *p);
EXPORT_SPEC void UpnpFileInfo_set_ExtraHeaders(UpnpFileInfo *p, const DOMString s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* FILEINFO_H */

View File

@@ -1,72 +0,0 @@
#ifndef STATEVARCOMPLETE_H
#define STATEVARCOMPLETE_H
/*!
* \file
*
* \brief UpnpStateVarComplete object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Represents the reply for the current value of a state variable in an
* asynchronous call. */
typedef struct s_UpnpStateVarComplete UpnpStateVarComplete;
#include "ixml.h" /* for DOMString */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpStateVarComplete *UpnpStateVarComplete_new();
/*! Destructor */
EXPORT_SPEC void UpnpStateVarComplete_delete(UpnpStateVarComplete *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpStateVarComplete *UpnpStateVarComplete_dup(const UpnpStateVarComplete *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpStateVarComplete_assign(UpnpStateVarComplete *p, const UpnpStateVarComplete *q);
/*! The result of the operation */
EXPORT_SPEC int UpnpStateVarComplete_get_ErrCode(const UpnpStateVarComplete *p);
EXPORT_SPEC void UpnpStateVarComplete_set_ErrCode(UpnpStateVarComplete *p, int n);
/*! The control URL for the service. */
EXPORT_SPEC const UpnpString *UpnpStateVarComplete_get_CtrlUrl(const UpnpStateVarComplete *p);
EXPORT_SPEC const char *UpnpStateVarComplete_get_CtrlUrl_cstr(const UpnpStateVarComplete *p);
EXPORT_SPEC void UpnpStateVarComplete_set_CtrlUrl(UpnpStateVarComplete *p, const UpnpString *s);
EXPORT_SPEC void UpnpStateVarComplete_strcpy_CtrlUrl(UpnpStateVarComplete *p, const char *s);
/*! The name of the variable. */
EXPORT_SPEC const UpnpString *UpnpStateVarComplete_get_StateVarName(const UpnpStateVarComplete *p);
EXPORT_SPEC const char *UpnpStateVarComplete_get_StateVarName_cstr(const UpnpStateVarComplete *p);
EXPORT_SPEC void UpnpStateVarComplete_set_StateVarName(UpnpStateVarComplete *p, const UpnpString *s);
EXPORT_SPEC void UpnpStateVarComplete_strcpy_StateVarName(UpnpStateVarComplete *p, const char *s);
/*! The current value of the variable. This needs to be allocated by
* the caller. When finished with it, the SDK frees this \b DOMString. */
EXPORT_SPEC const DOMString UpnpStateVarComplete_get_CurrentVal(const UpnpStateVarComplete *p);
EXPORT_SPEC const char *UpnpStateVarComplete_get_CurrentVal_cstr(const UpnpStateVarComplete *p);
EXPORT_SPEC void UpnpStateVarComplete_set_CurrentVal(UpnpStateVarComplete *p, const DOMString s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* STATEVARCOMPLETE_H */

View File

@@ -1,91 +0,0 @@
#ifndef STATEVARREQUEST_H
#define STATEVARREQUEST_H
/*!
* \file
*
* \brief UpnpStateVarRequest object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Represents the request for current value of a state variable in a service
* state table. */
typedef struct s_UpnpStateVarRequest UpnpStateVarRequest;
#include "ixml.h" /* for DOMString */
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpInet.h" /* for sockaddr, sockaddr_storage */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpStateVarRequest *UpnpStateVarRequest_new();
/*! Destructor */
EXPORT_SPEC void UpnpStateVarRequest_delete(UpnpStateVarRequest *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpStateVarRequest *UpnpStateVarRequest_dup(const UpnpStateVarRequest *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpStateVarRequest_assign(UpnpStateVarRequest *p, const UpnpStateVarRequest *q);
/*! The result of the operation */
EXPORT_SPEC int UpnpStateVarRequest_get_ErrCode(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_ErrCode(UpnpStateVarRequest *p, int n);
/*! The socket number of the connection to the requestor */
EXPORT_SPEC int UpnpStateVarRequest_get_Socket(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_Socket(UpnpStateVarRequest *p, int n);
/*! The error string in case of error */
EXPORT_SPEC const UpnpString *UpnpStateVarRequest_get_ErrStr(const UpnpStateVarRequest *p);
EXPORT_SPEC const char *UpnpStateVarRequest_get_ErrStr_cstr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_ErrStr(UpnpStateVarRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpStateVarRequest_strcpy_ErrStr(UpnpStateVarRequest *p, const char *s);
/*! The unique device ID */
EXPORT_SPEC const UpnpString *UpnpStateVarRequest_get_DevUDN(const UpnpStateVarRequest *p);
EXPORT_SPEC const char *UpnpStateVarRequest_get_DevUDN_cstr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_DevUDN(UpnpStateVarRequest *p, const UpnpString *s);
/*! The service ID */
EXPORT_SPEC const UpnpString *UpnpStateVarRequest_get_ServiceID(const UpnpStateVarRequest *p);
EXPORT_SPEC const char *UpnpStateVarRequest_get_ServiceID_cstr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_ServiceID(UpnpStateVarRequest *p, const UpnpString *s);
/*! The name of the variable. */
EXPORT_SPEC const UpnpString *UpnpStateVarRequest_get_StateVarName(const UpnpStateVarRequest *p);
EXPORT_SPEC const char *UpnpStateVarRequest_get_StateVarName_cstr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_StateVarName(UpnpStateVarRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char *s);
/*! IP address of sender requesting the state variable. */
EXPORT_SPEC const struct sockaddr *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, const struct sockaddr *sa);
/*! The current value of the variable. This needs to be allocated by
* the caller. When finished with it, the SDK frees this \b DOMString. */
EXPORT_SPEC const DOMString UpnpStateVarRequest_get_CurrentVal(const UpnpStateVarRequest *p);
EXPORT_SPEC const char *UpnpStateVarRequest_get_CurrentVal_cstr(const UpnpStateVarRequest *p);
EXPORT_SPEC void UpnpStateVarRequest_set_CurrentVal(UpnpStateVarRequest *p, const DOMString s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* STATEVARREQUEST_H */

View File

@@ -1,66 +0,0 @@
#ifndef SUBSCRIPTIONREQUEST_H
#define SUBSCRIPTIONREQUEST_H
/*!
* \file
*
* \brief UpnpSubscriptionRequest object declararion.
*
* \author Marcelo Roberto Jimenez
*/
/*! Returned along with a \b UPNP_EVENT_SUBSCRIPTION_REQUEST callback. */
typedef struct s_UpnpSubscriptionRequest UpnpSubscriptionRequest;
#include "UpnpGlobal.h" /* for EXPORT_SPEC */
#include "UpnpString.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/*! Constructor */
EXPORT_SPEC UpnpSubscriptionRequest *UpnpSubscriptionRequest_new();
/*! Destructor */
EXPORT_SPEC void UpnpSubscriptionRequest_delete(UpnpSubscriptionRequest *p);
/*! Copy Constructor */
EXPORT_SPEC UpnpSubscriptionRequest *UpnpSubscriptionRequest_dup(const UpnpSubscriptionRequest *p);
/*! Assignment operator */
EXPORT_SPEC void UpnpSubscriptionRequest_assign(UpnpSubscriptionRequest *p, const UpnpSubscriptionRequest *q);
/*! The identifier for the service being subscribed to. */
EXPORT_SPEC const UpnpString *UpnpSubscriptionRequest_get_ServiceId(const UpnpSubscriptionRequest *p);
EXPORT_SPEC const char *UpnpSubscriptionRequest_get_ServiceId_cstr(const UpnpSubscriptionRequest *p);
EXPORT_SPEC void UpnpSubscriptionRequest_set_ServiceId(UpnpSubscriptionRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpSubscriptionRequest_strcpy_ServiceId(UpnpSubscriptionRequest *p, const char *s);
/*! Universal device name. */
EXPORT_SPEC const UpnpString *UpnpSubscriptionRequest_get_UDN(const UpnpSubscriptionRequest *p);
EXPORT_SPEC const char *UpnpSubscriptionRequest_get_UDN_cstr(const UpnpSubscriptionRequest *p);
EXPORT_SPEC void UpnpSubscriptionRequest_set_UDN(UpnpSubscriptionRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpSubscriptionRequest_strcpy_UDN(UpnpSubscriptionRequest *p, const char *s);
/*! The assigned subscription ID for this subscription. */
EXPORT_SPEC const UpnpString *UpnpSubscriptionRequest_get_SID(const UpnpSubscriptionRequest *p);
EXPORT_SPEC const char *UpnpSubscriptionRequest_get_SID_cstr(const UpnpSubscriptionRequest *p);
EXPORT_SPEC void UpnpSubscriptionRequest_set_SID(UpnpSubscriptionRequest *p, const UpnpString *s);
EXPORT_SPEC void UpnpSubscriptionRequest_strcpy_SID(UpnpSubscriptionRequest *p, const char *s);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* SUBSCRIPTIONREQUEST_H */

View File

@@ -1,24 +1,19 @@
#ifndef UPNPGLOBAL_H #ifndef UPNPGLOBAL_H
#define UPNPGLOBAL_H #define UPNPGLOBAL_H
/*! /*!
* \file * \file
* *
* \brief Defines constants that for some reason are not defined on some systems. * \brief Defines constants that for some reason are not defined on some systems.
*/ */
#if defined MYLIB_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 != 64 #if defined MYLIB_LARGEFILE_SENSITIVE && _FILE_OFFSET_BITS+0 != 64
#if defined __GNUC__ #if defined __GNUC__
#warning libupnp requires largefile mode - use AC_SYS_LARGEFILE #warning libupnp requires largefile mode - use AC_SYS_LARGEFILE
#else #else
#error libupnp requires largefile mode - use AC_SYS_LARGEFILE #error libupnp requires largefile mode - use AC_SYS_LARGEFILE
#endif #endif
#endif #endif
#ifdef WIN32 #ifdef WIN32
/* /*
@@ -36,7 +31,6 @@
#endif /* LIBUPNP_EXPORTS */ #endif /* LIBUPNP_EXPORTS */
#endif /* UPNP_STATIC_LIB */ #endif /* UPNP_STATIC_LIB */
/* /*
* UPNP_INLINE * UPNP_INLINE
* PRId64 * PRId64
@@ -50,7 +44,6 @@
#define PRIzu "lu" #define PRIzu "lu"
#endif /* UPNP_USE_MSVCPP */ #endif /* UPNP_USE_MSVCPP */
#ifdef UPNP_USE_BCBPP #ifdef UPNP_USE_BCBPP
/* define some things Borland Builder doesn't know */ /* define some things Borland Builder doesn't know */
#define UPNP_INLINE inline #define UPNP_INLINE inline
@@ -61,10 +54,8 @@
#define PRIzu "zu" #define PRIzu "zu"
#endif /* UPNP_USE_BCBPP */ #endif /* UPNP_USE_BCBPP */
#ifdef __GNUC__ #ifdef __GNUC__
#define UPNP_INLINE inline #define UPNP_INLINE inline
/* Note with PRIzu that in the case of Mingw32, it's the MS C /* Note with PRIzu that in the case of Mingw32, it's the MS C
* runtime printf which ends up getting called, not the glibc * runtime printf which ends up getting called, not the glibc
* printf, so it genuinely doesn't have "zu" * printf, so it genuinely doesn't have "zu"
@@ -88,8 +79,12 @@
* inline keyword. This definition makes the use of this keyword * inline keyword. This definition makes the use of this keyword
* portable to these systems. * portable to these systems.
*/ */
#define UPNP_INLINE inline #ifdef __STRICT_ANSI__
#define UPNP_INLINE __inline__
#else
#define UPNP_INLINE inline
#endif
/*! /*!
* \brief Supply the PRId64 printf() macro. * \brief Supply the PRId64 printf() macro.
* *
@@ -107,7 +102,6 @@
#define PRIzu "zu" #define PRIzu "zu"
#endif #endif
/* /*
* Defining this macro here gives some interesting information about unused * Defining this macro here gives some interesting information about unused
* functions in the code. Of course, this should never go uncommented on a * functions in the code. Of course, this should never go uncommented on a
@@ -115,6 +109,4 @@
*/ */
/*#define inline*/ /*#define inline*/
#endif /* UPNPGLOBAL_H */ #endif /* UPNPGLOBAL_H */

View File

@@ -1,30 +1,57 @@
#ifndef UPNPINET_H #ifndef UPNPINET_H
#define UPNPINET_H #define UPNPINET_H
/*! /*!
* \addtogroup Sock
*
* @{
*
* \file * \file
* *
* \brief Provides a platform independent way to include TCP/IP types and functions. * \brief Provides a platform independent way to include TCP/IP types and functions.
*/ */
#include "UpnpUniStd.h" /* for close() */
#ifdef WIN32 #ifdef WIN32
#include <stdarg.h>
#include <windef.h>
#include <winbase.h>
#include <winsock2.h> #include <winsock2.h>
#include <Ws2tcpip.h> #include <iphlpapi.h>
#else #include <ws2tcpip.h>
#define UpnpCloseSocket closesocket
#else /* WIN32 */
#include <sys/param.h> #include <sys/param.h>
#if (defined(BSD) && BSD >= 199306) || defined (__FreeBSD_kernel__) #if defined(__sun)
#include <fcntl.h>
#include <sys/sockio.h>
#elif (defined(BSD) && BSD >= 199306) || defined (__FreeBSD_kernel__)
#include <ifaddrs.h> #include <ifaddrs.h>
/* Do not move or remove the include below for "sys/socket"! /* Do not move or remove the include below for "sys/socket"!
* Will break FreeBSD builds. */ * Will break FreeBSD builds. */
#include <sys/socket.h> #include <sys/socket.h>
#endif #endif
#include <arpa/inet.h> /* for inet_pton() */
#include <net/if.h>
#include <netinet/in.h> #include <netinet/in.h>
#endif
/*! This typedef makes the code slightly more WIN32 tolerant.
* On WIN32 systems, SOCKET is unsigned and is not a file
* descriptor. */
typedef int SOCKET;
/*! INVALID_SOCKET is unsigned on win32. */
#define INVALID_SOCKET (-1)
/*! select() returns SOCKET_ERROR on win32. */
#define SOCKET_ERROR (-1)
/*! Alias to close() to make code more WIN32 tolerant. */
#define UpnpCloseSocket close
#endif /* WIN32 */
/* @} Sock */
#endif /* UPNPINET_H */ #endif /* UPNPINET_H */

11
upnp/inc/UpnpIntTypes.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef UPNPINTTYPES_H
#define UPNPINTTYPES_H
#if !defined(UPNP_USE_BCBPP) && !defined(UPNP_USE_MSVCPP)
/* Printf format for integers. */
#include <inttypes.h>
#endif /* !defined(UPNP_USE_BCBPP) && !defined(UPNP_USE_MSVCPP) */
#endif /* UPNPINTTYPES_H */

11
upnp/inc/UpnpStdInt.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef UPNPSTDINT_H
#define UPNPSTDINT_H
#if !defined(UPNP_USE_BCBPP) && !defined(UPNP_USE_MSVCPP)
/* Sized integer types. */
#include <stdint.h>
#endif /* !defined(UPNP_USE_BCBPP) && !defined(UPNP_USE_MSVCPP) */
#endif /* UPNPSTDINT_H */

View File

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

10
upnp/inc/UpnpUniStd.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef UPNPUNISTD_H
#define UPNPUNISTD_H
#ifdef WIN32
/* Do not #include <unistd.h> on WIN32. */
#else /* WIN32 */
#include <unistd.h> /* for close() */
#endif /* WIN32 */
#endif /* UPNPUNISTD_H */

View File

@@ -1,3 +1,6 @@
#ifndef UPNP_H
#define UPNP_H
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
@@ -29,26 +32,19 @@
* *
******************************************************************************/ ******************************************************************************/
#ifndef UPNP_H
#define UPNP_H
/*! /*!
* \file
*
* \defgroup UPnPAPI UPnP API * \defgroup UPnPAPI UPnP API
* *
* @{ * @{
*
* \file
*/ */
#include "ixml.h" #include "ixml.h"
#include "upnpconfig.h" #include "upnpconfig.h"
#include "UpnpGlobal.h" #include "UpnpGlobal.h"
#include "UpnpInet.h" #include "UpnpInet.h"
/* /*
* \todo Document the exact reason of these include files and solve this * \todo Document the exact reason of these include files and solve this
* include mess in an include file like UpnpTime.h * include mess in an include file like UpnpTime.h
@@ -61,30 +57,6 @@
/* Other systems ??? */ /* Other systems ??? */
#endif #endif
#ifdef WIN32
/* Do not #include <sys/param.h> */
#else
#include <sys/param.h>
#endif
#ifdef WIN32
#include <iphlpapi.h>
#else
#define SOCKET int
#define INVALID_SOCKET (SOCKET)(~0)
#endif
#ifdef WIN32
#define UpnpCloseSocket closesocket
#define fseeko fseek
#else
#define UpnpCloseSocket close
#endif
#define LINE_SIZE 180 #define LINE_SIZE 180
#define NAME_SIZE 256 #define NAME_SIZE 256
#define MNFT_NAME_SIZE 64 #define MNFT_NAME_SIZE 64
@@ -95,7 +67,6 @@
#define UPNP_USING_CHUNKED -3 #define UPNP_USING_CHUNKED -3
#define UPNP_UNTIL_CLOSE -4 #define UPNP_UNTIL_CLOSE -4
/*! /*!
* \name Error codes * \name Error codes
* *
@@ -404,19 +375,7 @@
/* @} ErrorCodes */ /* @} ErrorCodes */
#ifndef OUT #if UPNP_VERSION >= 10800
#define OUT
#endif
#ifndef IN
#define IN
#endif
#ifndef INOUT
#define INOUT
#endif
/* /*
* Opaque data structures. The following includes are data structures that * Opaque data structures. The following includes are data structures that
* must be externally visible. Since version 1.8.0, only an opaque typedef * must be externally visible. Since version 1.8.0, only an opaque typedef
@@ -436,7 +395,7 @@
#include "StateVarComplete.h" #include "StateVarComplete.h"
#include "StateVarRequest.h" #include "StateVarRequest.h"
#include "SubscriptionRequest.h" #include "SubscriptionRequest.h"
#endif /* UPNP_VERSION >= 10800 */
/*! /*!
* \name Constants and Types * \name Constants and Types
@@ -634,6 +593,231 @@ enum Upnp_DescType_e {
typedef enum Upnp_DescType_e Upnp_DescType; typedef enum Upnp_DescType_e Upnp_DescType;
#if UPNP_VERSION < 10800
/** Returned as part of a {\bf UPNP_CONTROL_ACTION_COMPLETE} callback. */
struct Upnp_Action_Request
{
/** The result of the operation. */
int ErrCode;
/** The socket number of the connection to the requestor. */
int Socket;
/** The error string in case of error. */
char ErrStr[LINE_SIZE];
/** The Action Name. */
char ActionName[NAME_SIZE];
/** The unique device ID. */
char DevUDN[NAME_SIZE];
/** The service ID. */
char ServiceID[NAME_SIZE];
/** The DOM document describing the action. */
IXML_Document *ActionRequest;
/** The DOM document describing the result of the action. */
IXML_Document *ActionResult;
/** IP address of the control point requesting this action. */
struct sockaddr_storage CtrlPtIPAddr;
/** The DOM document containing the information from the
the SOAP header. */
IXML_Document *SoapHeader;
};
struct Upnp_Action_Complete
{
/** The result of the operation. */
int ErrCode;
/** The control URL for service. */
char CtrlUrl[NAME_SIZE];
/** The DOM document describing the action. */
IXML_Document *ActionRequest;
/** The DOM document describing the result of the action. */
IXML_Document *ActionResult;
};
/** Represents the request for current value of a state variable in a service
* state table. */
struct Upnp_State_Var_Request
{
/** The result of the operation. */
int ErrCode;
/** The socket number of the connection to the requestor. */
int Socket;
/** The error string in case of error. */
char ErrStr[LINE_SIZE];
/** The unique device ID. */
char DevUDN[NAME_SIZE];
/** The service ID. */
char ServiceID[NAME_SIZE];
/** The name of the variable. */
char StateVarName[NAME_SIZE];
/** IP address of sender requesting the state variable. */
struct sockaddr_storage CtrlPtIPAddr;
/** The current value of the variable. This needs to be allocated by
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
DOMString CurrentVal;
};
/** Represents the reply for the current value of a state variable in an
asynchronous call. */
struct Upnp_State_Var_Complete
{
/** The result of the operation. */
int ErrCode;
/** The control URL for the service. */
char CtrlUrl[NAME_SIZE];
/** The name of the variable. */
char StateVarName[NAME_SIZE];
/** The current value of the variable or error string in case of error. */
DOMString CurrentVal;
};
/** Returned along with a {\bf UPNP_EVENT_RECEIVED} callback. */
struct Upnp_Event
{
/** The subscription ID for this subscription. */
Upnp_SID Sid;
/** The event sequence number. */
int EventKey;
/** The DOM tree representing the changes generating the event. */
IXML_Document *ChangedVariables;
};
/*
* This typedef is required by Doc++ to parse the last entry of the
* Upnp_Discovery structure correctly.
*/
/** Returned in a {\bf UPNP_DISCOVERY_RESULT} callback. */
struct Upnp_Discovery
{
/** The result code of the {\bf UpnpSearchAsync} call. */
int ErrCode;
/** The expiration time of the advertisement. */
int Expires;
/** The unique device identifier. */
char DeviceId[LINE_SIZE];
/** The device type. */
char DeviceType[LINE_SIZE];
/** The service type. */
char ServiceType[LINE_SIZE];
/** The service version. */
char ServiceVer[LINE_SIZE];
/** The URL to the UPnP description document for the device. */
char Location[LINE_SIZE];
/** The operating system the device is running. */
char Os[LINE_SIZE];
/** Date when the response was generated. */
char Date[LINE_SIZE];
/** Confirmation that the MAN header was understood by the device. */
char Ext[LINE_SIZE];
/** The host address of the device responding to the search. */
struct sockaddr_in DestAddr;
};
/** Returned along with a {\bf UPNP_EVENT_SUBSCRIBE_COMPLETE} or {\bf
* UPNP_EVENT_UNSUBSCRIBE_COMPLETE} callback. */
struct Upnp_Event_Subscribe {
/** The SID for this subscription. For subscriptions, this only
* contains a valid SID if the {\bf Upnp_EventSubscribe.result} field
* contains a {\tt UPNP_E_SUCCESS} result code. For unsubscriptions,
* this contains the SID from which the subscription is being
* unsubscribed. */
Upnp_SID Sid;
/** The result of the operation. */
int ErrCode;
/** The event URL being subscribed to or removed from. */
char PublisherUrl[NAME_SIZE];
/** The actual subscription time (for subscriptions only). */
int TimeOut;
};
/** Returned along with a {\bf UPNP_EVENT_SUBSCRIPTION_REQUEST}
* callback. */
struct Upnp_Subscription_Request
{
/** The identifier for the service being subscribed to. */
char *ServiceId;
/** Universal device name. */
char *UDN;
/** The assigned subscription ID for this subscription. */
Upnp_SID Sid;
};
struct File_Info
{
/** The length of the file. A length less than 0 indicates the size
* is unknown, and data will be sent until 0 bytes are returned from
* a read call. */
off_t file_length;
/** The time at which the contents of the file was modified;
* The time system is always local (not GMT). */
time_t last_modified;
/** If the file is a directory, {\bf is_directory} contains
* a non-zero value. For a regular file, it should be 0. */
int is_directory;
/** If the file or directory is readable, this contains
* a non-zero value. If unreadable, it should be set to 0. */
int is_readable;
/** The content type of the file. This string needs to be allocated
* by the caller using {\bf ixmlCloneDOMString}. When finished
* with it, the SDK frees the {\bf DOMString}. */
DOMString content_type;
};
#endif /* UPNP_VERSION < 10800 */
/*! /*!
* All callback functions share the same prototype, documented below. * All callback functions share the same prototype, documented below.
@@ -670,19 +854,16 @@ typedef int (*Upnp_FunPtr)(
/* @} Constants and Types */ /* @} Constants and Types */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
/*! /*!
* \name Initialization and Registration * \name Initialization and Registration
* *
* @{ * @{
*/ */
/*! /*!
* \brief Initializes the Linux SDK for UPnP Devices (IPv4 only). * \brief Initializes the Linux SDK for UPnP Devices (IPv4 only).
* *
@@ -724,7 +905,6 @@ EXPORT_SPEC int UpnpInit(
* \c NULL will pick an arbitrary free port. */ * \c NULL will pick an arbitrary free port. */
unsigned short DestPort); unsigned short DestPort);
/*! /*!
* \brief Initializes the Linux SDK for UPnP Devices (IPv4 or IPv6). * \brief Initializes the Linux SDK for UPnP Devices (IPv4 or IPv6).
* *
@@ -757,6 +937,7 @@ EXPORT_SPEC int UpnpInit(
* \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not * \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not
* have a valid IPv4 or IPv6 addresss configured. * have a valid IPv4 or IPv6 addresss configured.
*/ */
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC int UpnpInit2( EXPORT_SPEC int UpnpInit2(
/*! The interface name to use by the UPnP SDK operations. /*! The interface name to use by the UPnP SDK operations.
* Examples: "eth0", "xl0", "Local Area Connection", \c NULL to * Examples: "eth0", "xl0", "Local Area Connection", \c NULL to
@@ -765,7 +946,7 @@ EXPORT_SPEC int UpnpInit2(
/*! Local Port to listen for incoming connections. /*! Local Port to listen for incoming connections.
* \c NULL will pick an arbitrary free port. */ * \c NULL will pick an arbitrary free port. */
unsigned short DestPort); unsigned short DestPort);
#endif
/*! /*!
* \brief Terminates the Linux SDK for UPnP Devices. * \brief Terminates the Linux SDK for UPnP Devices.
@@ -788,7 +969,6 @@ EXPORT_SPEC int UpnpInit2(
*/ */
EXPORT_SPEC int UpnpFinish(void); EXPORT_SPEC int UpnpFinish(void);
/*! /*!
* \brief Returns the internal server IPv4 UPnP listening port. * \brief Returns the internal server IPv4 UPnP listening port.
* *
@@ -802,7 +982,6 @@ EXPORT_SPEC int UpnpFinish(void);
*/ */
EXPORT_SPEC unsigned short UpnpGetServerPort(void); EXPORT_SPEC unsigned short UpnpGetServerPort(void);
/*! /*!
* \brief Returns the internal server IPv6 UPnP listening port. * \brief Returns the internal server IPv6 UPnP listening port.
* *
@@ -814,8 +993,9 @@ EXPORT_SPEC unsigned short UpnpGetServerPort(void);
* related requests. * related requests.
* \li On error: 0 is returned if \b UpnpInit has not succeeded. * \li On error: 0 is returned if \b UpnpInit has not succeeded.
*/ */
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC unsigned short UpnpGetServerPort6(void); EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
#endif
/*! /*!
* \brief Returns the local IPv4 listening ip address. * \brief Returns the local IPv4 listening ip address.
* *
@@ -829,7 +1009,6 @@ EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
*/ */
EXPORT_SPEC char *UpnpGetServerIpAddress(void); EXPORT_SPEC char *UpnpGetServerIpAddress(void);
/*! /*!
* \brief Returns the local IPv6 listening ip address. * \brief Returns the local IPv6 listening ip address.
* *
@@ -841,10 +1020,11 @@ EXPORT_SPEC char *UpnpGetServerIpAddress(void);
* listening for UPnP related requests. * listening for UPnP related requests.
* \li On error: \c NULL is returned if \b UpnpInit has not succeeded. * \li On error: \c NULL is returned if \b UpnpInit has not succeeded.
*/ */
#ifdef UPNP_ENABLE_IPV6
EXPORT_SPEC char *UpnpGetServerIp6Address(void); EXPORT_SPEC char *UpnpGetServerIp6Address(void);
EXPORT_SPEC char *UpnpGetServerUlaGuaIp6Address(void); EXPORT_SPEC char *UpnpGetServerUlaGuaIp6Address(void);
#endif
/*! /*!
* \brief Registers a device application with the UPnP Library. * \brief Registers a device application with the UPnP Library.
* *
@@ -980,7 +1160,6 @@ EXPORT_SPEC int UpnpRegisterRootDevice2(
/*! [out] Pointer to a variable to store the new device handle. */ /*! [out] Pointer to a variable to store the new device handle. */
UpnpDevice_Handle* Hnd); UpnpDevice_Handle* Hnd);
/*! /*!
* \brief Registers a device application for a specific address family with * \brief Registers a device application for a specific address family with
* the UPnP library. * the UPnP library.
@@ -1030,7 +1209,6 @@ EXPORT_SPEC int UpnpRegisterRootDevice3(
* AF_INET6 for an IPv6 device. Defaults to AF_INET. */ * AF_INET6 for an IPv6 device. Defaults to AF_INET. */
const int AddressFamily); const int AddressFamily);
/*! /*!
* \brief Unregisters a root device registered with \b UpnpRegisterRootDevice or * \brief Unregisters a root device registered with \b UpnpRegisterRootDevice or
* \b UpnpRegisterRootDevice2. * \b UpnpRegisterRootDevice2.
@@ -1050,7 +1228,6 @@ EXPORT_SPEC int UpnpUnRegisterRootDevice(
/*! [in] The handle of the root device instance to unregister. */ /*! [in] The handle of the root device instance to unregister. */
UpnpDevice_Handle Hnd); UpnpDevice_Handle Hnd);
/*! /*!
* \brief Registers a control point application with the UPnP Library. * \brief Registers a control point application with the UPnP Library.
* *
@@ -1077,7 +1254,6 @@ EXPORT_SPEC int UpnpRegisterClient(
/*! [out] Pointer to a variable to store the new control point handle. */ /*! [out] Pointer to a variable to store the new control point handle. */
UpnpClient_Handle *Hnd); UpnpClient_Handle *Hnd);
/*! /*!
* \brief Unregisters a control point application, unsubscribing all active * \brief Unregisters a control point application, unsubscribing all active
* subscriptions. * subscriptions.
@@ -1098,7 +1274,6 @@ EXPORT_SPEC int UpnpUnRegisterClient(
/*! [in] The handle of the control point instance to unregister. */ /*! [in] The handle of the control point instance to unregister. */
UpnpClient_Handle Hnd); UpnpClient_Handle Hnd);
/*! /*!
* \deprecated Use \b UpnpSetMaxContentLength instead. * \deprecated Use \b UpnpSetMaxContentLength instead.
* *
@@ -1110,8 +1285,7 @@ EXPORT_SPEC int UpnpSetContentLength(
* length needs to be set. */ * length needs to be set. */
UpnpClient_Handle Hnd, UpnpClient_Handle Hnd,
/*! [in] Permissible content length */ /*! [in] Permissible content length */
int contentLength); size_t contentLength);
/*! /*!
* \brief Sets the maximum content-length that the SDK will process on an * \brief Sets the maximum content-length that the SDK will process on an
@@ -1121,6 +1295,8 @@ EXPORT_SPEC int UpnpSetContentLength(
* behaviour if the size of the incoming SOAP message exceeds the memory that * behaviour if the size of the incoming SOAP message exceeds the memory that
* device can allocate. * device can allocate.
* *
* If set to 0 then checking will be disabled.
*
* The default maximum content-length is \c DEFAULT_SOAP_CONTENT_LENGTH * The default maximum content-length is \c DEFAULT_SOAP_CONTENT_LENGTH
* = 16K bytes. * = 16K bytes.
* *
@@ -1132,10 +1308,8 @@ EXPORT_SPEC int UpnpSetMaxContentLength(
* in bytes. */ * in bytes. */
size_t contentLength); size_t contentLength);
/* @} Initialization and Registration */ /* @} Initialization and Registration */
/****************************************************************************** /******************************************************************************
****************************************************************************** ******************************************************************************
* * * *
@@ -1144,14 +1318,12 @@ EXPORT_SPEC int UpnpSetMaxContentLength(
****************************************************************************** ******************************************************************************
******************************************************************************/ ******************************************************************************/
/*! /*!
* \name Discovery * \name Discovery
* *
* @{ * @{
*/ */
/*! /*!
* \brief Searches for devices matching the given search target. * \brief Searches for devices matching the given search target.
* *
@@ -1210,10 +1382,8 @@ EXPORT_SPEC int UpnpSendAdvertisement(
/*! The expiration age, in seconds, of the announcements. */ /*! The expiration age, in seconds, of the announcements. */
int Exp); int Exp);
/* @} Discovery */ /* @} Discovery */
/****************************************************************************** /******************************************************************************
****************************************************************************** ******************************************************************************
* * * *
@@ -1222,14 +1392,12 @@ EXPORT_SPEC int UpnpSendAdvertisement(
****************************************************************************** ******************************************************************************
******************************************************************************/ ******************************************************************************/
/*! /*!
* \name Control * \name Control
* *
* @{ * @{
*/ */
/*! /*!
* \brief Queries the state of a state variable of a service on another device. * \brief Queries the state of a state variable of a service on another device.
* *
@@ -1267,7 +1435,6 @@ EXPORT_SPEC int UpnpGetServiceVarStatus(
* \b ixmlFreeDOMString. */ * \b ixmlFreeDOMString. */
DOMString *StVarVal); DOMString *StVarVal);
/*! /*!
* \brief Queries the state of a variable of a service, generating a callback * \brief Queries the state of a variable of a service, generating a callback
* when the operation is complete. * when the operation is complete.
@@ -1298,7 +1465,6 @@ EXPORT_SPEC int UpnpGetServiceVarStatusAsync(
/*! [in] Pointer to user data to pass to the callback function when invoked. */ /*! [in] Pointer to user data to pass to the callback function when invoked. */
const void *Cookie); const void *Cookie);
/*! /*!
* \brief Sends a message to change a state variable in a service. * \brief Sends a message to change a state variable in a service.
* *
@@ -1337,7 +1503,6 @@ EXPORT_SPEC int UpnpSendAction(
* this document and the caller needs to free it. */ * this document and the caller needs to free it. */
IXML_Document **RespNode); IXML_Document **RespNode);
/*! /*!
* \brief Sends a message to change a state variable in a service. * \brief Sends a message to change a state variable in a service.
* *
@@ -1379,7 +1544,6 @@ EXPORT_SPEC int UpnpSendActionEx(
* this document and the caller needs to free it. */ * this document and the caller needs to free it. */
IXML_Document **RespNode); IXML_Document **RespNode);
/*! /*!
* \brief Sends a message to change a state variable in a service, generating a * \brief Sends a message to change a state variable in a service, generating a
* callback when the operation is complete. * callback when the operation is complete.
@@ -1419,7 +1583,6 @@ EXPORT_SPEC int UpnpSendActionAsync(
* invoked. */ * invoked. */
const void *Cookie); const void *Cookie);
/*! /*!
* \brief Sends a message to change a state variable in a service, generating a * \brief Sends a message to change a state variable in a service, generating a
* callback when the operation is complete. * callback when the operation is complete.
@@ -1462,10 +1625,8 @@ EXPORT_SPEC int UpnpSendActionExAsync(
* invoked. */ * invoked. */
const void *Cookie); const void *Cookie);
/*! @} Control */ /*! @} Control */
/****************************************************************************** /******************************************************************************
****************************************************************************** ******************************************************************************
* * * *
@@ -1474,14 +1635,12 @@ EXPORT_SPEC int UpnpSendActionExAsync(
****************************************************************************** ******************************************************************************
******************************************************************************/ ******************************************************************************/
/*! /*!
* \name Eventing * \name Eventing
* *
* @{ * @{
*/ */
/*! /*!
* \brief Accepts a subscription request and sends out the current state of the * \brief Accepts a subscription request and sends out the current state of the
* eventable variables for a service. * eventable variables for a service.
@@ -1523,7 +1682,6 @@ EXPORT_SPEC int UpnpAcceptSubscription(
/*! [in] The subscription ID of the newly registered control point. */ /*! [in] The subscription ID of the newly registered control point. */
const Upnp_SID SubsId); const Upnp_SID SubsId);
/*! /*!
* \brief Similar to \b UpnpAcceptSubscription() except that it takes a DOM * \brief Similar to \b UpnpAcceptSubscription() except that it takes a DOM
* document for the variables to event rather than an array of strings. * document for the variables to event rather than an array of strings.
@@ -1560,7 +1718,6 @@ EXPORT_SPEC int UpnpAcceptSubscriptionExt(
/*! [in] The subscription ID of the newly registered control point. */ /*! [in] The subscription ID of the newly registered control point. */
Upnp_SID SubsId); Upnp_SID SubsId);
/*! /*!
* \brief Sends out an event change notification to all control points * \brief Sends out an event change notification to all control points
* subscribed to a particular service. * subscribed to a particular service.
@@ -1596,7 +1753,6 @@ EXPORT_SPEC int UpnpNotify(
/*! [in] The count of variables included in this notification. */ /*! [in] The count of variables included in this notification. */
int cVariables); int cVariables);
/*! /*!
* \brief Similar to \b UpnpNotify except that it takes a DOM document for the * \brief Similar to \b UpnpNotify except that it takes a DOM document for the
* event rather than an array of strings. * event rather than an array of strings.
@@ -1630,7 +1786,6 @@ EXPORT_SPEC int UpnpNotifyExt(
* Plug and Play Device Architecture specification. */ * Plug and Play Device Architecture specification. */
IXML_Document *PropSet); IXML_Document *PropSet);
/*! /*!
* \brief Renews a subscription that is about to expire. * \brief Renews a subscription that is about to expire.
* *
@@ -1668,7 +1823,6 @@ EXPORT_SPEC int UpnpRenewSubscription(
/*! [in] The ID for the subscription to renew. */ /*! [in] The ID for the subscription to renew. */
const Upnp_SID SubsId); const Upnp_SID SubsId);
/*! /*!
* \brief Renews a subscription that is about to expire, generating a callback * \brief Renews a subscription that is about to expire, generating a callback
* when the operation is complete. * when the operation is complete.
@@ -1730,7 +1884,6 @@ EXPORT_SPEC int UpnpRenewSubscriptionAsync(
/*! [in] Pointer to user data passed to the callback function when invoked. */ /*! [in] Pointer to user data passed to the callback function when invoked. */
const void *Cookie); const void *Cookie);
/*! /*!
* \brief Sets the maximum number of subscriptions accepted per service. * \brief Sets the maximum number of subscriptions accepted per service.
* *
@@ -1751,7 +1904,6 @@ EXPORT_SPEC int UpnpSetMaxSubscriptions(
/*! The maximum number of subscriptions to be allowed per service. */ /*! The maximum number of subscriptions to be allowed per service. */
int MaxSubscriptions); int MaxSubscriptions);
/*! /*!
* \brief Sets the maximum time-out accepted for a subscription request or * \brief Sets the maximum time-out accepted for a subscription request or
* renewal. * renewal.
@@ -1773,7 +1925,6 @@ EXPORT_SPEC int UpnpSetMaxSubscriptionTimeOut(
/*! The maximum subscription time-out to be accepted. */ /*! The maximum subscription time-out to be accepted. */
int MaxSubscriptionTimeOut); int MaxSubscriptionTimeOut);
/*! /*!
* \brief Registers a control point to receive event notifications from another * \brief Registers a control point to receive event notifications from another
* device. * device.
@@ -1815,7 +1966,6 @@ EXPORT_SPEC int UpnpSubscribe(
/*! [out] Pointer to a variable to receive the subscription ID (SID). */ /*! [out] Pointer to a variable to receive the subscription ID (SID). */
Upnp_SID SubsId); Upnp_SID SubsId);
/*! /*!
* \brief Performs the same operation as \b UpnpSubscribe, but returns * \brief Performs the same operation as \b UpnpSubscribe, but returns
* immediately and calls the registered callback function when the operation * immediately and calls the registered callback function when the operation
@@ -1877,7 +2027,6 @@ EXPORT_SPEC int UpnpSubscribeAsync(
/*! A user data value passed to the callback function when invoked. */ /*! A user data value passed to the callback function when invoked. */
const void *Cookie); const void *Cookie);
/*! /*!
* \brief Removes the subscription of a control point from a service previously * \brief Removes the subscription of a control point from a service previously
* subscribed to using \b UpnpSubscribe or \b UpnpSubscribeAsync. * subscribed to using \b UpnpSubscribe or \b UpnpSubscribeAsync.
@@ -1913,7 +2062,6 @@ EXPORT_SPEC int UpnpUnSubscribe(
/*! [in] The ID returned when the control point subscribed to the service. */ /*! [in] The ID returned when the control point subscribed to the service. */
const Upnp_SID SubsId); const Upnp_SID SubsId);
/*! /*!
* \brief Removes a subscription of a control point from a service previously * \brief Removes a subscription of a control point from a service previously
* subscribed to using \b UpnpSubscribe or \b UpnpSubscribeAsync, generating * subscribed to using \b UpnpSubscribe or \b UpnpSubscribeAsync, generating
@@ -1971,11 +2119,9 @@ EXPORT_SPEC int UpnpUnSubscribeAsync(
/*! [in] Pointer to user data to pass to the callback function when invoked. */ /*! [in] Pointer to user data to pass to the callback function when invoked. */
const void *Cookie); const void *Cookie);
/*! @} Eventing */ /*! @} Eventing */
/****************************************************************************** /******************************************************************************
****************************************************************************** ******************************************************************************
* * * *
@@ -2025,7 +2171,6 @@ EXPORT_SPEC int UpnpDownloadUrlItem(
* \c LINE_SIZE bytes in size. */ * \c LINE_SIZE bytes in size. */
char *contentType); char *contentType);
/*! /*!
* \brief Gets a file specified in a URL. * \brief Gets a file specified in a URL.
* *
@@ -2070,7 +2215,6 @@ EXPORT_SPEC int UpnpOpenHttpGet(
* back to the user. */ * back to the user. */
int timeout); int timeout);
/*! /*!
* \brief Gets a file specified in a URL through the specified proxy. * \brief Gets a file specified in a URL through the specified proxy.
* *
@@ -2117,7 +2261,6 @@ EXPORT_SPEC int UpnpOpenHttpGetProxy(
* back to the user. */ * back to the user. */
int timeout); int timeout);
/*! /*!
* \brief Gets specified number of bytes from a file specified in the URL. * \brief Gets specified number of bytes from a file specified in the URL.
* *
@@ -2168,7 +2311,6 @@ EXPORT_SPEC int UpnpOpenHttpGetEx(
* to the user. */ * to the user. */
int timeout); int timeout);
/*! /*!
* \brief Gets specified number of bytes from a file specified in a URL. * \brief Gets specified number of bytes from a file specified in a URL.
* *
@@ -2192,13 +2334,12 @@ EXPORT_SPEC int UpnpReadHttpGet(
/*! [in,out] The buffer to store the read item. */ /*! [in,out] The buffer to store the read item. */
char *buf, char *buf,
/*! [in,out] The size of the buffer to be read. */ /*! [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 /*! [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 * expected from the server, failing which, an error is reported back to
* the user. */ * the user. */
int timeout); int timeout);
/*! /*!
* \brief Retrieve progress information of a http-get transfer. * \brief Retrieve progress information of a http-get transfer.
* *
@@ -2211,10 +2352,9 @@ EXPORT_SPEC int UpnpHttpGetProgress(
/*! [in] The token created by the call to \b UpnpOpenHttpGet. */ /*! [in] The token created by the call to \b UpnpOpenHttpGet. */
void *handle, void *handle,
/*! [out] The number of bytes received. */ /*! [out] The number of bytes received. */
unsigned int *length, size_t *length,
/*! [out] The content length. */ /*! [out] The content length. */
unsigned int *total); size_t *total);
/*! /*!
* \brief Set the cancel flag of the \b handle parameter. * \brief Set the cancel flag of the \b handle parameter.
@@ -2241,7 +2381,6 @@ EXPORT_SPEC int UpnpCloseHttpGet(
* \b UpnpOpenHttpGet. */ * \b UpnpOpenHttpGet. */
void *handle); void *handle);
/*! /*!
* \brief Makes an HTTP POST request message, opens a connection to the server * \brief Makes an HTTP POST request message, opens a connection to the server
* and sends the POST request to the server if the connection to the server * and sends the POST request to the server if the connection to the server
@@ -2281,7 +2420,6 @@ EXPORT_SPEC int UpnpOpenHttpPost(
* is expected from the receiver, failing which, an error is reported. */ * is expected from the receiver, failing which, an error is reported. */
int timeout); int timeout);
/*! /*!
* \brief Sends a request to a server to copy the contents of a buffer to the * \brief Sends a request to a server to copy the contents of a buffer to the
* URI specified in the \b UpnpOpenHttpPost call. * URI specified in the \b UpnpOpenHttpPost call.
@@ -2302,12 +2440,11 @@ EXPORT_SPEC int UpnpWriteHttpPost(
/*! [in] The buffer to be posted. */ /*! [in] The buffer to be posted. */
char *buf, char *buf,
/*! [in] The size, in bytes of \b 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 /*! [in] A timeout value sent with the request during which a response is
* expected from the server, failing which, an error is reported. */ * expected from the server, failing which, an error is reported. */
int timeout); int timeout);
/*! /*!
* \brief Sends and receives any pending data, closes the connection with the * \brief Sends and receives any pending data, closes the connection with the
* server, and frees memory allocated during the \b UpnpOpenHttpPost call. * server, and frees memory allocated during the \b UpnpOpenHttpPost call.
@@ -2330,7 +2467,6 @@ EXPORT_SPEC int UpnpCloseHttpPost(
/*! [in] A time out value sent with the request during which a response is /*! [in] A time out value sent with the request during which a response is
* expected from the server, failing which, an error is reported. */ * expected from the server, failing which, an error is reported. */
int timeout); int timeout);
/*! /*!
* \brief Downloads an XML document specified in a URL. * \brief Downloads an XML document specified in a URL.
@@ -2365,7 +2501,6 @@ EXPORT_SPEC int UpnpDownloadXmlDoc(
/*! [out] A pointer in which to store the XML document. */ /*! [out] A pointer in which to store the XML document. */
IXML_Document **xmlDoc); IXML_Document **xmlDoc);
/*! @} Control Point HTTP API */ /*! @} Control Point HTTP API */
/****************************************************************************** /******************************************************************************
@@ -2402,13 +2537,11 @@ EXPORT_SPEC int UpnpSetWebServerRootDir(
/*! [in] Path of the root directory of the web server. */ /*! [in] Path of the root directory of the web server. */
const char *rootDir); const char *rootDir);
/*! /*!
* \brief The type of handle returned by the web server for open requests. * \brief The type of handle returned by the web server for open requests.
*/ */
typedef void *UpnpWebFileHandle; typedef void *UpnpWebFileHandle;
/*! /*!
* \brief Get-info callback function prototype. * \brief Get-info callback function prototype.
*/ */
@@ -2416,8 +2549,12 @@ typedef int (*VDCallback_GetInfo)(
/*! [in] The name of the file to query. */ /*! [in] The name of the file to query. */
const char *filename, const char *filename,
/*! [out] Pointer to a structure to store the information on the file. */ /*! [out] Pointer to a structure to store the information on the file. */
UpnpFileInfo *info); #if UPNP_VERSION < 10800
struct File_Info *info
#else
UpnpFileInfo *info
#endif /* UPNP_VERSION < 10800 */
);
/*! /*!
* \brief Sets the get_info callback function to be used to access a virtual * \brief Sets the get_info callback function to be used to access a virtual
@@ -2429,7 +2566,6 @@ typedef int (*VDCallback_GetInfo)(
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_GetInfoCallback(VDCallback_GetInfo callback); EXPORT_SPEC int UpnpVirtualDir_set_GetInfoCallback(VDCallback_GetInfo callback);
/*! /*!
* \brief Open callback function prototype. * \brief Open callback function prototype.
*/ */
@@ -2440,7 +2576,6 @@ typedef UpnpWebFileHandle (*VDCallback_Open)(
* Valid values are \c UPNP_READ or \c UPNP_WRITE. */ * Valid values are \c UPNP_READ or \c UPNP_WRITE. */
enum UpnpOpenFileMode Mode); enum UpnpOpenFileMode Mode);
/*! /*!
* \brief Sets the open callback function to be used to access a virtual * \brief Sets the open callback function to be used to access a virtual
* directory. * directory.
@@ -2451,7 +2586,6 @@ typedef UpnpWebFileHandle (*VDCallback_Open)(
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_OpenCallback(VDCallback_Open callback); EXPORT_SPEC int UpnpVirtualDir_set_OpenCallback(VDCallback_Open callback);
/*! /*!
* \brief Read callback function prototype. * \brief Read callback function prototype.
*/ */
@@ -2463,7 +2597,6 @@ typedef int (*VDCallback_Read)(
/*! [in] The size of the buffer (i.e. the number of bytes to read). */ /*! [in] The size of the buffer (i.e. the number of bytes to read). */
size_t buflen); size_t buflen);
/*! /*!
* \brief Sets the read callback function to be used to access a virtual * \brief Sets the read callback function to be used to access a virtual
* directory. * directory.
@@ -2474,7 +2607,6 @@ typedef int (*VDCallback_Read)(
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_ReadCallback(VDCallback_Read callback); EXPORT_SPEC int UpnpVirtualDir_set_ReadCallback(VDCallback_Read callback);
/*! /*!
* \brief Write callback function prototype. * \brief Write callback function prototype.
*/ */
@@ -2486,7 +2618,6 @@ typedef int (*VDCallback_Write)(
/*! [in] The number of bytes to write. */ /*! [in] The number of bytes to write. */
size_t buflen); size_t buflen);
/*! /*!
* \brief Sets the write callback function to be used to access a virtual * \brief Sets the write callback function to be used to access a virtual
* directory. * directory.
@@ -2497,7 +2628,6 @@ typedef int (*VDCallback_Write)(
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_WriteCallback(VDCallback_Write callback); EXPORT_SPEC int UpnpVirtualDir_set_WriteCallback(VDCallback_Write callback);
/*! /*!
* \brief Seek callback function prototype. * \brief Seek callback function prototype.
*/ */
@@ -2514,7 +2644,6 @@ typedef int (*VDCallback_Seek) (
* specify an absolute offset. */ * specify an absolute offset. */
int origin); int origin);
/*! /*!
* \brief Sets the seek callback function to be used to access a virtual * \brief Sets the seek callback function to be used to access a virtual
* directory. * directory.
@@ -2525,7 +2654,6 @@ typedef int (*VDCallback_Seek) (
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_SeekCallback(VDCallback_Seek callback); EXPORT_SPEC int UpnpVirtualDir_set_SeekCallback(VDCallback_Seek callback);
/*! /*!
* \brief Close callback function prototype. * \brief Close callback function prototype.
*/ */
@@ -2533,7 +2661,6 @@ typedef int (*VDCallback_Close)(
/*! [in] The handle of the file to close. */ /*! [in] The handle of the file to close. */
UpnpWebFileHandle fileHnd); UpnpWebFileHandle fileHnd);
/*! /*!
* \brief Sets the close callback function to be used to access a virtual * \brief Sets the close callback function to be used to access a virtual
* directory. * directory.
@@ -2544,7 +2671,6 @@ typedef int (*VDCallback_Close)(
*/ */
EXPORT_SPEC int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback); EXPORT_SPEC int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback);
/*! /*!
* \brief Enables or disables the webserver. * \brief Enables or disables the webserver.
* *
@@ -2556,7 +2682,6 @@ EXPORT_SPEC int UpnpEnableWebserver(
/*! [in] \c TRUE to enable, \c FALSE to disable. */ /*! [in] \c TRUE to enable, \c FALSE to disable. */
int enable); int enable);
/*! /*!
* \brief Returns \c TRUE if the webserver is enabled, or \c FALSE if it is not. * \brief Returns \c TRUE if the webserver is enabled, or \c FALSE if it is not.
* *
@@ -2566,7 +2691,6 @@ EXPORT_SPEC int UpnpEnableWebserver(
*/ */
EXPORT_SPEC int UpnpIsWebserverEnabled(void); EXPORT_SPEC int UpnpIsWebserverEnabled(void);
/*! /*!
* \brief Adds a virtual directory mapping. * \brief Adds a virtual directory mapping.
* *
@@ -2585,7 +2709,6 @@ EXPORT_SPEC int UpnpAddVirtualDir(
/*! [in] The name of the new directory mapping to add. */ /*! [in] The name of the new directory mapping to add. */
const char *dirName); const char *dirName);
/*! /*!
* \brief Removes a virtual directory mapping made with \b UpnpAddVirtualDir. * \brief Removes a virtual directory mapping made with \b UpnpAddVirtualDir.
* *
@@ -2597,24 +2720,17 @@ EXPORT_SPEC int UpnpRemoveVirtualDir(
/*! [in] The name of the virtual directory mapping to remove. */ /*! [in] The name of the virtual directory mapping to remove. */
const char *dirName); const char *dirName);
/*! /*!
* \brief Removes all virtual directory mappings. * \brief Removes all virtual directory mappings.
*/ */
EXPORT_SPEC void UpnpRemoveAllVirtualDirs(void); EXPORT_SPEC void UpnpRemoveAllVirtualDirs(void);
/* @} Web Server API */ /* @} Web Server API */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif /* __cplusplus */ #endif /* __cplusplus */
/* @} UPnPAPI UPnP API */ /* @} UPnPAPI UPnP API */
#endif /* UPNP_H */ #endif /* UPNP_H */

View File

@@ -1,7 +1,7 @@
/* -*- C -*- */ /* -*- C -*- */
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2006 R<EFBFBD>mi Turboult <r3mi@users.sourceforge.net> * Copyright (c) 2006 Rémi Turboult <r3mi@users.sourceforge.net>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@@ -52,13 +52,26 @@
/** The library version (numeric) e.g. 10300 means version 1.3.0 */ /** The library version (numeric) e.g. 10300 means version 1.3.0 */
#define UPNP_VERSION \ #define UPNP_VERSION \
((UPNP_VERSION_MAJOR*100 + UPNP_VERSION_MINOR)*100 + UPNP_VERSION_PATCH) ((UPNP_VERSION_MAJOR * 100 + UPNP_VERSION_MINOR) * 100 + UPNP_VERSION_PATCH)
/***************************************************************************
* Large file support
***************************************************************************/
/** File Offset size */
#undef _FILE_OFFSET_BITS
/** Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */
#undef _LARGEFILE_SOURCE
/** Large files support */
#undef _LARGE_FILE_SOURCE
/*************************************************************************** /***************************************************************************
* Library optional features * Library optional features
***************************************************************************/ ***************************************************************************/
/* /*
* The following defines can be tested in order to know which * The following defines can be tested in order to know which
@@ -90,6 +103,9 @@
* (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */ * (i.e. configure --enable-tools) : <upnp/upnptools.h> file is available */
#undef UPNP_HAVE_TOOLS #undef UPNP_HAVE_TOOLS
/** Defined to 1 if the library has been compiled with ipv6 support
* (i.e. configure --enable-ipv6) */
#undef UPNP_ENABLE_IPV6
#endif /* UPNP_CONFIG_H */ #endif /* UPNP_CONFIG_H */

View File

@@ -1,64 +1,59 @@
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * 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. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions are met:
* *
* - Redistributions of source code must retain the above copyright notice, * - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. * this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice, * - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution. * and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors * - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* *
******************************************************************************/ ******************************************************************************/
#ifndef UPNP_DEBUG_H #ifndef UPNP_DEBUG_H
#define UPNP_DEBUG_H #define UPNP_DEBUG_H
/*! /*!
* \file * \file
*/ */
#include "ThreadPool.h" #include "ThreadPool.h"
#include "upnpconfig.h" #include "upnpconfig.h"
#include "UpnpGlobal.h" /* for UPNP_INLINE */ #include "UpnpGlobal.h" /* for UPNP_INLINE */
#include <stdio.h> #include <stdio.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/*! \name Other debugging features
/** \name Other debugging features
* *
* The UPnP SDK contains other features to aid in debugging. * The UPnP SDK contains other features to aid in debugging.
*/ */
/*@{*/ /*@{*/
/** \name Upnp_LogLevel /*! \name Upnp_LogLevel
* The user has the option to select 4 different types of debugging levels, * The user has the option to select 4 different types of debugging levels,
* see \c UpnpSetLogLevel. * see \c UpnpSetLogLevel.
* The critical level will show only those messages * The critical level will show only those messages
@@ -85,7 +80,6 @@ typedef enum Upnp_Module {
HTTP HTTP
} Dbg_Module; } Dbg_Module;
/*@{*/ /*@{*/
typedef enum Upnp_LogLevel_e { typedef enum Upnp_LogLevel_e {
UPNP_CRITICAL, UPNP_CRITICAL,
@@ -95,14 +89,11 @@ typedef enum Upnp_LogLevel_e {
} Upnp_LogLevel; } Upnp_LogLevel;
/*@}*/ /*@}*/
/*!
/**
* Default log level : see \c Upnp_LogLevel * Default log level : see \c Upnp_LogLevel
*/ */
#define UPNP_DEFAULT_LOG_LEVEL UPNP_ALL #define UPNP_DEFAULT_LOG_LEVEL UPNP_ALL
/*! /*!
* \brief Initialize the log files. * \brief Initialize the log files.
* *
@@ -116,8 +107,6 @@ static UPNP_INLINE int UpnpInitLog(void)
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
#endif #endif
/*! /*!
* \brief Set the log level (see \c Upnp_LogLevel). * \brief Set the log level (see \c Upnp_LogLevel).
*/ */
@@ -126,20 +115,24 @@ void UpnpSetLogLevel(
/*! [in] Log level. */ /*! [in] Log level. */
Upnp_LogLevel log_level); Upnp_LogLevel log_level);
#else #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 #endif
/*! /*!
* \brief Closes the log files. * \brief Closes the log files.
*/ */
#ifdef DEBUG #ifdef DEBUG
void UpnpCloseLog(void); void UpnpCloseLog(void);
#else #else
static UPNP_INLINE void UpnpCloseLog(void) {} static UPNP_INLINE void UpnpCloseLog(void)
{
}
#endif #endif
/*! /*!
* \brief Set the name for error and information files, respectively. * \brief Set the name for error and information files, respectively.
*/ */
@@ -150,12 +143,15 @@ void UpnpSetLogFileNames(
/*! [in] Name of the information file. */ /*! [in] Name of the information file. */
const char *InfoFileName); const char *InfoFileName);
#else #else
static UPNP_INLINE void UpnpSetLogFileNames( static UPNP_INLINE void UpnpSetLogFileNames(const char *ErrFileName,
const char *ErrFileName, const char *InfoFileName)
const char *InfoFileName) {} {
return;
ErrFileName = ErrFileName;
InfoFileName = InfoFileName;
}
#endif #endif
/*! /*!
* \brief Check if the module is turned on for debug and returns the file * \brief Check if the module is turned on for debug and returns the file
* descriptor corresponding to the debug level * descriptor corresponding to the debug level
@@ -174,10 +170,11 @@ FILE *UpnpGetDebugFile(
static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module) static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module)
{ {
return NULL; return NULL;
level = level;
module = module;
} }
#endif #endif
/*! /*!
* \brief Returns true if debug output should be done in this module. * \brief Returns true if debug output should be done in this module.
* *
@@ -191,19 +188,18 @@ int DebugAtThisLevel(
/*! [in] Debug will go in the name of this module. */ /*! [in] Debug will go in the name of this module. */
Dbg_Module Module); Dbg_Module Module);
#else #else
static UPNP_INLINE int DebugAtThisLevel( static UPNP_INLINE int DebugAtThisLevel(Upnp_LogLevel DLevel, Dbg_Module Module)
Upnp_LogLevel DLevel,
Dbg_Module Module)
{ {
return 0; return 0;
DLevel = DLevel;
Module = Module;
} }
#endif #endif
/*! /*!
* \brief Prints the debug statement either on the standard output or log file * \brief Prints the debug statement either on the standard output or log file
* along with the information from where this debug statement is coming. * along with the information from where this debug statement is coming.
*/ */
#ifdef DEBUG #ifdef DEBUG
void UpnpPrintf( void UpnpPrintf(
/*! [in] The level of the debug logging. It will decide whether debug /*! [in] The level of the debug logging. It will decide whether debug
@@ -212,98 +208,81 @@ void UpnpPrintf(
/*! [in] debug will go in the name of this module. */ /*! [in] debug will go in the name of this module. */
Dbg_Module Module, Dbg_Module Module,
/*! [in] Name of the file from where debug statement is coming. */ /*! [in] Name of the file from where debug statement is coming. */
const char* DbgFileName, const char *DbgFileName,
/*! [in] Line number of the file from where debug statement is coming. */ /*! [in] Line number of the file from where debug statement is coming. */
int DbgLineNo, int DbgLineNo,
/*! [in] Printf like format specification. */ /*! [in] Printf like format specification. */
const char* FmtStr, const char *FmtStr,
/*! [in] Printf like Variable number of arguments that will go in the debug /*! [in] Printf like Variable number of arguments that will go in the
* statement. */ * debug statement. */
...) ...)
#if (__GNUC__ >= 3) #if (__GNUC__ >= 3)
/* This enables printf like format checking by the compiler */ /* This enables printf like format checking by the compiler. */
__attribute__((format (__printf__, 5, 6))) __attribute__ ((format(__printf__, 5, 6)))
#endif #endif
; ;
#else /* DEBUG */ #else /* DEBUG */
static UPNP_INLINE void UpnpPrintf( static UPNP_INLINE void UpnpPrintf(Upnp_LogLevel DLevel, Dbg_Module Module,
Upnp_LogLevel DLevel, const char *DbgFileName, int DbgLineNo, const char *FmtStr, ...)
Dbg_Module Module,
const char* DbgFileName,
int DbgLineNo,
const char* FmtStr,
...)
{ {
return;
DLevel = DLevel;
Module = Module;
DbgFileName = DbgFileName;
DbgLineNo = DbgLineNo;
FmtStr = FmtStr;
} }
#endif /* DEBUG */ #endif /* DEBUG */
/*! /*!
* \brief Writes the file name and file number from where debug statement is * \brief Writes the file name and file number from where debug statement is
* coming to the log file. * coming to the log file.
*/ */
#ifdef DEBUG #ifdef DEBUG
void UpnpDisplayFileAndLine( void UpnpDisplayFileAndLine(
/*! [in] File descriptor where line number and file name will be written. */ /*! [in] File descriptor where line number and file name will be
FILE *fd, * written. */
FILE * fd,
/*! [in] Name of the file. */ /*! [in] Name of the file. */
const char *DbgFileName, const char *DbgFileName,
/*! [in] Line number of the file. */ /*! [in] Line number of the file. */
int DbgLineNo); int DbgLineNo);
#else #else
static UPNP_INLINE void UpnpDisplayFileAndLine( static UPNP_INLINE void UpnpDisplayFileAndLine(FILE *fd,
FILE *fd, const char *DbgFileName, int DbgLineNo)
const char *DbgFileName, {
int DbgLineNo) {} return;
fd = fd;
DbgFileName = DbgFileName;
DbgLineNo = DbgLineNo;
}
#endif #endif
/*! /*!
* \brief Writes the buffer in the file as per the requested banner * \brief Writes the buffer in the file as per the requested banner
*/ */
#ifdef DEBUG #ifdef DEBUG
void UpnpDisplayBanner( void UpnpDisplayBanner(
/*! [in] file descriptor where the banner will be written. */ /*! [in] file descriptor where the banner will be written. */
FILE *fd, FILE * fd,
/*! [in] The buffer that will be written. */ /*! [in] The buffer that will be written. */
const char **lines, const char **lines,
/*! [in] Size of the buffer. */ /*! [in] Size of the buffer. */
size_t size, size_t size,
/*! [in] This parameter provides the width of the banner. */ /*! [in] This parameter provides the width of the banner. */
int starlength); size_t starlength);
#else #else
static UPNP_INLINE void UpnpDisplayBanner( static UPNP_INLINE void UpnpDisplayBanner(FILE *fd, const char **lines,
FILE *fd, size_t size, int starlength)
const char **lines,
size_t size,
int starlength) {}
#endif
/*!
* \brief Prints thread pool statistics.
*/
#ifdef DEBUG
void PrintThreadPoolStats(
/*! [in] The thread pool. */
ThreadPool *tp,
/*! [in] The file name that called this function, use the macro __FILE__. */
const char *DbgFileName,
/*! [in] The line number that the function was called, use the macro __LINE__. */
int DbgLineNo,
/*! [in] The message. */
const char *msg);
#else
static UPNP_INLINE void PrintThreadPoolStats(
ThreadPool *tp,
const char *DbgFileName,
int DbgLineNo,
const char *msg)
{ {
return;
fd = fd;
lines = lines;
size = size;
starlength = starlength;
} }
#endif #endif
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus
@@ -311,4 +290,3 @@ static UPNP_INLINE void PrintThreadPoolStats(
#endif #endif
#endif /* UPNP_DEBUG_H */ #endif /* UPNP_DEBUG_H */

View File

@@ -96,6 +96,30 @@ EXPORT_SPEC int UpnpResolveURL(
char *AbsURL); 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 * \brief Creates an action request packet based on its input parameters
* (status variable name and value pair). * (status variable name and value pair).

View File

@@ -14,67 +14,62 @@ LDADD = \
$(top_builddir)/threadutil/libthreadutil.la \ $(top_builddir)/threadutil/libthreadutil.la \
$(top_builddir)/ixml/libixml.la $(top_builddir)/ixml/libixml.la
# samples # samples
noinst_PROGRAMS = noinst_PROGRAMS =
if ENABLE_SAMPLES if ENABLE_SAMPLES
if ENABLE_CLIENT if ENABLE_CLIENT
noinst_PROGRAMS += upnp_tv_ctrlpt noinst_PROGRAMS += tv_ctrlpt
upnp_tv_ctrlpt_CPPFLAGS = \ tv_ctrlpt_CPPFLAGS = \
$(AM_CPPFLAGS) \ $(AM_CPPFLAGS) \
-I$(srcdir)/common/ \ -I$(srcdir)/common/ \
-I$(srcdir)/tvctrlpt -I$(srcdir)/tvctrlpt
if ENABLE_DEVICE if ENABLE_DEVICE
noinst_PROGRAMS += upnp_tv_combo noinst_PROGRAMS += tv_combo
upnp_tv_combo_CPPFLAGS = $(AM_CPPFLAGS) \ tv_combo_CPPFLAGS = $(AM_CPPFLAGS) \
-I$(srcdir)/common/ \ -I$(srcdir)/common/ \
-I$(srcdir)/tvcombo -I$(srcdir)/tvcombo
endif endif
endif endif
if ENABLE_DEVICE if ENABLE_DEVICE
noinst_PROGRAMS += upnp_tv_device noinst_PROGRAMS += tv_device
upnp_tv_device_CPPFLAGS = \ tv_device_CPPFLAGS = \
$(AM_CPPFLAGS) \ $(AM_CPPFLAGS) \
-I$(srcdir)/common/ \ -I$(srcdir)/common/ \
-I$(srcdir)/tvdevice -I$(srcdir)/tvdevice
endif endif
endif endif
tv_device_SOURCES = \
upnp_tv_device_SOURCES = \
common/sample_util.c \ common/sample_util.c \
common/sample_util.h \ common/sample_util.h \
tvdevice/upnp_tv_device.c \ common/tv_device.c \
tvdevice/upnp_tv_device.h \ common/tv_device.h \
tvdevice/linux/upnp_tv_device_main.c linux/tv_device_main.c
tv_ctrlpt_SOURCES = \
upnp_tv_ctrlpt_SOURCES = \
common/sample_util.c \ common/sample_util.c \
common/sample_util.h \ common/sample_util.h \
tvctrlpt/upnp_tv_ctrlpt.c \ common/tv_ctrlpt.c \
tvctrlpt/upnp_tv_ctrlpt.h \ common/tv_ctrlpt.h \
tvctrlpt/linux/upnp_tv_ctrlpt_main.c linux/tv_ctrlpt_main.c
upnp_tv_combo_SOURCES = \ tv_combo_SOURCES = \
common/sample_util.c \ common/sample_util.c \
common/sample_util.h \ common/sample_util.h \
tvcombo/upnp_tv_ctrlpt.c \ common/tv_ctrlpt.c \
tvcombo/upnp_tv_ctrlpt.h \ common/tv_ctrlpt.h \
tvcombo/upnp_tv_device.c \ common/tv_device.c \
tvcombo/upnp_tv_device.h \ common/tv_device.h \
tvcombo/linux/upnp_tv_combo_main.c linux/tv_combo_main.c
if WITH_DOCUMENTATION if WITH_DOCUMENTATION
examplesdir = $(docdir)/examples examplesdir = $(docdir)/examples
examples_DATA = \ examples_DATA = \
$(sort \ $(sort \
$(upnp_tv_ctrlpt_SOURCES) \ $(tv_ctrlpt_SOURCES) \
$(upnp_tv_device_SOURCES)) $(tv_device_SOURCES))
endif endif
EXTRA_DIST = \ EXTRA_DIST = \
web/tvcombodesc.xml \ web/tvcombodesc.xml \
web/tvcontrolSCPD.xml \ web/tvcontrolSCPD.xml \

View File

@@ -29,21 +29,27 @@
* *
******************************************************************************/ ******************************************************************************/
/*!
* \addtogroup UpnpSamples
*
* @{
*
* \file
*/
#define SAMPLE_UTIL_C
#include "sample_util.h" #include "sample_util.h"
#include <assert.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.h> #include <stdio.h>
#if !UPNP_HAVE_TOOLS #if !UPNP_HAVE_TOOLS
# error "Need upnptools.h to compile samples ; try ./configure --enable-tools" # error "Need upnptools.h to compile samples ; try ./configure --enable-tools"
#endif #endif
static int initialize_init = 1;
int initialize = 1; static int initialize_register = 1;
/*! Function pointers to use for displaying formatted strings. /*! Function pointers to use for displaying formatted strings.
* Set on Initialization of device. */ * Set on Initialization of device. */
@@ -53,165 +59,105 @@ state_update gStateUpdateFun = NULL;
/*! mutex to control displaying of events */ /*! mutex to control displaying of events */
ithread_mutex_t display_mutex; 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) int SampleUtil_Initialize(print_string print_function)
{ {
if (initialize) { if (initialize_init) {
ithread_mutexattr_t attr; ithread_mutexattr_t attr;
ithread_mutexattr_init(&attr); ithread_mutexattr_init(&attr);
ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP); ithread_mutexattr_setkind_np(&attr, ITHREAD_MUTEX_RECURSIVE_NP);
ithread_mutex_init(&display_mutex, &attr); ithread_mutex_init(&display_mutex, &attr);
ithread_mutexattr_destroy(&attr); ithread_mutexattr_destroy(&attr);
/* To shut up valgrind mutex warning. */ /* To shut up valgrind mutex warning. */
ithread_mutex_lock(&display_mutex); ithread_mutex_lock(&display_mutex);
gPrintFun = print_function; gPrintFun = print_function;
ithread_mutex_unlock(&display_mutex); ithread_mutex_unlock(&display_mutex);
/* Finished initializing. */
initialize = 0; initialize_init = 0;
} else {
SampleUtil_Print("***** SampleUtil_Initialize was called multiple times!\n");
abort();
} }
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/*******************************************************************************
* SampleUtil_RegisterUpdateFunction
*
* Description:
*
* Parameters:
*
******************************************************************************/
int SampleUtil_RegisterUpdateFunction(state_update update_function) int SampleUtil_RegisterUpdateFunction(state_update update_function)
{ {
/* Intialize only once. */ if (initialize_register) {
static int initialize = 1;
if (initialize) {
gStateUpdateFun = update_function; gStateUpdateFun = update_function;
initialize = 0; initialize_register = 0;
} }
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/*******************************************************************************
* SampleUtil_Finish
*
* Description:
* Releases Resources held by sample util.
*
* Parameters:
*
******************************************************************************/
int SampleUtil_Finish() int SampleUtil_Finish()
{ {
ithread_mutex_destroy(&display_mutex); ithread_mutex_destroy(&display_mutex);
gPrintFun = NULL; gPrintFun = NULL;
initialize = 1; gStateUpdateFun = NULL;
initialize_init = 1;
initialize_register = 1;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/******************************************************************************* char *SampleUtil_GetElementValue(IXML_Element *element)
* 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)
{ {
IXML_Node *child = ixmlNode_getFirstChild((IXML_Node *)element); IXML_Node *child = ixmlNode_getFirstChild((IXML_Node *)element);
char *temp = NULL; char *temp = NULL;
if (child != 0 && ixmlNode_getNodeType(child) == eTEXT_NODE) { if (child != 0 && ixmlNode_getNodeType(child) == eTEXT_NODE)
temp = strdup(ixmlNode_getNodeValue(child)); temp = strdup(ixmlNode_getNodeValue(child));
}
return temp; return temp;
} }
/******************************************************************************* IXML_NodeList *SampleUtil_GetFirstServiceList(IXML_Document *doc)
* 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 *ServiceList = NULL; IXML_NodeList *ServiceList = NULL;
IXML_NodeList *servlistnodelist = NULL; IXML_NodeList *servlistnodelist = NULL;
IXML_Node *servlistnode = NULL; IXML_Node *servlistnode = NULL;
servlistnodelist = servlistnodelist =
ixmlDocument_getElementsByTagName( doc, "serviceList" ); ixmlDocument_getElementsByTagName(doc, "serviceList");
if (servlistnodelist && ixmlNodeList_length(servlistnodelist)) { if (servlistnodelist && ixmlNodeList_length(servlistnodelist)) {
/* we only care about the first service list, from the root /* we only care about the first service list, from the root
* device */ * device */
servlistnode = ixmlNodeList_item(servlistnodelist, 0); servlistnode = ixmlNodeList_item(servlistnodelist, 0);
/* create as list of DOM nodes */ /* create as list of DOM nodes */
ServiceList = ixmlElement_getElementsByTagName( ServiceList = ixmlElement_getElementsByTagName(
(IXML_Element *)servlistnode, "service"); (IXML_Element *)servlistnode, "service");
} }
if (servlistnodelist) { if (servlistnodelist)
ixmlNodeList_free(servlistnodelist); ixmlNodeList_free(servlistnodelist);
}
return ServiceList; return ServiceList;
} }
#define OLD_FIND_SERVICE_CODE
#ifdef OLD_FIND_SERVICE_CODE
#else
/* /*
* Obtain the service list * Obtain the service list
* n == 0 the first * n == 0 the first
* n == 1 the next in the device list, etc.. * 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 *ServiceList = NULL;
IXML_NodeList *servlistnodelist = NULL; IXML_NodeList *servlistnodelist = NULL;
IXML_Node *servlistnode = NULL; IXML_Node *servlistnode = NULL;
/* /* ixmlDocument_getElementsByTagName()
* ixmlDocument_getElementsByTagName()
* Returns a NodeList of all Elements that match the given * Returns a NodeList of all Elements that match the given
* tag name in the order in which they were encountered in a preorder * tag name in the order in which they were encountered in a preorder
* traversal of the Document tree. * traversal of the Document tree.
* *
* return (NodeList*) A pointer to a NodeList containing the * 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); SampleUtil_Print("SampleUtil_GetNthServiceList called : n = %d\n", n);
servlistnodelist = servlistnodelist =
ixmlDocument_getElementsByTagName(doc, "serviceList"); ixmlDocument_getElementsByTagName(doc, "serviceList");
@@ -226,38 +172,24 @@ IXML_NodeList *SampleUtil_GetNthServiceList(IN IXML_Document *doc , int n)
* numerical index. * numerical index.
* *
* return (Node*) A pointer to a Node or NULL if there was an * return (Node*) A pointer to a Node or NULL if there was an
* error. * error. */
*/
servlistnode = ixmlNodeList_item(servlistnodelist, n); servlistnode = ixmlNodeList_item(servlistnodelist, n);
if (!servlistnode) {
assert(servlistnode != 0); /* create as list of DOM nodes */
ServiceList = ixmlElement_getElementsByTagName(
/* create as list of DOM nodes */ (IXML_Element *)servlistnode, "service");
ServiceList = ixmlElement_getElementsByTagName( } else
(IXML_Element *)servlistnode, "service"); SampleUtil_Print("%s(%d): ixmlNodeList_item(nodeList, n) returned NULL\n",
__FILE__, __LINE__);
} }
if (servlistnodelist)
if (servlistnodelist) {
ixmlNodeList_free(servlistnodelist); ixmlNodeList_free(servlistnodelist);
}
return ServiceList; return ServiceList;
} }
#endif
/******************************************************************************* char *SampleUtil_GetFirstDocumentItem(IXML_Document *doc, const char *item)
* 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)
{ {
IXML_NodeList *nodeList = NULL; IXML_NodeList *nodeList = NULL;
IXML_Node *textNode = NULL; IXML_Node *textNode = NULL;
@@ -270,52 +202,32 @@ char *SampleUtil_GetFirstDocumentItem(
if (tmpNode) { if (tmpNode) {
textNode = ixmlNode_getFirstChild(tmpNode); textNode = ixmlNode_getFirstChild(tmpNode);
if (!textNode) { if (!textNode) {
SampleUtil_Print("sample_util.c: (bug) " SampleUtil_Print("%s(%d): (BUG) ixmlNode_getFirstChild(tmpNode) returned NULL\n",
"ixmlNode_getFirstChild(tmpNode) " __FILE__, __LINE__);
"returned NULL\n");
ret = strdup(""); ret = strdup("");
goto epilogue; goto epilogue;
} }
if (!ixmlNode_getNodeValue(textNode)) { ret = strdup(ixmlNode_getNodeValue(textNode));
SampleUtil_Print("ixmlNode_getNodeValue " if (!ret) {
"returned NULL\n"); SampleUtil_Print("%s(%d): ixmlNode_getNodeValue returned NULL\n",
__FILE__, __LINE__);
ret = strdup(""); ret = strdup("");
goto epilogue;
} else {
ret = strdup(ixmlNode_getNodeValue(textNode));
} }
} else { } else
SampleUtil_Print("ixmlNode_getFirstChild(tmpNode) " SampleUtil_Print("%s(%d): ixmlNodeList_item(nodeList, 0) returned NULL\n",
"returned NULL\n"); __FILE__, __LINE__);
goto epilogue; } else
} SampleUtil_Print("%s(%d): Error finding %s in XML Node\n",
} else { __FILE__, __LINE__, item);
SampleUtil_Print("Error finding %s in XML Node\n", item);
goto epilogue;
}
epilogue: epilogue:
if (nodeList) { if (nodeList)
ixmlNodeList_free(nodeList); ixmlNodeList_free(nodeList);
}
return ret; return ret;
} }
/******************************************************************************* char *SampleUtil_GetFirstElementItem(IXML_Element *element, const char *item)
* 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)
{ {
IXML_NodeList *nodeList = NULL; IXML_NodeList *nodeList = NULL;
IXML_Node *textNode = NULL; IXML_Node *textNode = NULL;
@@ -324,24 +236,23 @@ char *SampleUtil_GetFirstElementItem(
nodeList = ixmlElement_getElementsByTagName(element, (char *)item); nodeList = ixmlElement_getElementsByTagName(element, (char *)item);
if (nodeList == NULL) { if (nodeList == NULL) {
SampleUtil_Print( "Error finding %s in XML Node\n", item); SampleUtil_Print("%s(%d): Error finding %s in XML Node\n",
__FILE__, __LINE__, item);
return NULL; return NULL;
} }
tmpNode = ixmlNodeList_item(nodeList, 0); tmpNode = ixmlNodeList_item(nodeList, 0);
if (tmpNode) { if (!tmpNode) {
SampleUtil_Print("Error finding %s value in XML Node\n", item); SampleUtil_Print("%s(%d): Error finding %s value in XML Node\n",
__FILE__, __LINE__, item);
ixmlNodeList_free(nodeList); ixmlNodeList_free(nodeList);
return NULL; return NULL;
} }
textNode = ixmlNode_getFirstChild(tmpNode); textNode = ixmlNode_getFirstChild(tmpNode);
ret = strdup(ixmlNode_getNodeValue(textNode)); ret = strdup(ixmlNode_getNodeValue(textNode));
if (!ret) { if (!ret) {
SampleUtil_Print("Error allocating memory for %s in XML Node\n", SampleUtil_Print("%s(%d): Error allocating memory for %s in XML Node\n",
item); __FILE__, __LINE__, item);
ixmlNodeList_free(nodeList); ixmlNodeList_free(nodeList);
return NULL; return NULL;
} }
ixmlNodeList_free(nodeList); ixmlNodeList_free(nodeList);
@@ -349,17 +260,7 @@ char *SampleUtil_GetFirstElementItem(
return ret; return ret;
} }
/******************************************************************************* void SampleUtil_PrintEventType(Upnp_EventType S)
* SampleUtil_PrintEventType
*
* Description:
* Prints a callback event type as a string.
*
* Parameters:
* S -- The callback event
*
******************************************************************************/
void SampleUtil_PrintEventType(IN Upnp_EventType S)
{ {
switch (S) { switch (S) {
/* Discovery */ /* Discovery */
@@ -413,18 +314,7 @@ void SampleUtil_PrintEventType(IN Upnp_EventType S)
} }
} }
/******************************************************************************* int SampleUtil_PrintEvent(Upnp_EventType EventType, void *Event)
* 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)
{ {
ithread_mutex_lock(&display_mutex); ithread_mutex_lock(&display_mutex);
@@ -437,28 +327,18 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE: case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
case UPNP_DISCOVERY_SEARCH_RESULT: { case UPNP_DISCOVERY_SEARCH_RESULT: {
UpnpDiscovery *d_event = (UpnpDiscovery *)Event; struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event;
SampleUtil_Print(
"ErrCode = %d\n" SampleUtil_Print("ErrCode = %s(%d)\n",
"Expires = %d\n" UpnpGetErrorMessage(d_event->ErrCode), d_event->ErrCode);
"DeviceId = %s\n" SampleUtil_Print("Expires = %d\n", d_event->Expires);
"DeviceType = %s\n" SampleUtil_Print("DeviceId = %s\n", d_event->DeviceId);
"ServiceType = %s\n" SampleUtil_Print("DeviceType = %s\n", d_event->DeviceType);
"ServiceVer = %s\n" SampleUtil_Print("ServiceType = %s\n", d_event->ServiceType);
"Location = %s\n" SampleUtil_Print("ServiceVer = %s\n", d_event->ServiceVer);
"OS = %s\n" SampleUtil_Print("Location = %s\n", d_event->Location);
"Date = %s\n" SampleUtil_Print("OS = %s\n", d_event->Os);
"Ext = %s\n", SampleUtil_Print("Ext = %s\n", d_event->Ext);
UpnpDiscovery_get_ErrCode(d_event),
UpnpDiscovery_get_Expires(d_event),
UpnpString_get_String(UpnpDiscovery_get_DeviceID(d_event)),
UpnpString_get_String(UpnpDiscovery_get_DeviceType(d_event)),
UpnpString_get_String(UpnpDiscovery_get_ServiceType(d_event)),
UpnpString_get_String(UpnpDiscovery_get_ServiceVer(d_event)),
UpnpString_get_String(UpnpDiscovery_get_Location(d_event)),
UpnpString_get_String(UpnpDiscovery_get_Os(d_event)),
UpnpString_get_String(UpnpDiscovery_get_Date(d_event)),
UpnpString_get_String(UpnpDiscovery_get_Ext(d_event)));
break; break;
} }
case UPNP_DISCOVERY_SEARCH_TIMEOUT: case UPNP_DISCOVERY_SEARCH_TIMEOUT:
@@ -466,25 +346,18 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
break; break;
/* SOAP */ /* SOAP */
case UPNP_CONTROL_ACTION_REQUEST: { case UPNP_CONTROL_ACTION_REQUEST: {
UpnpActionRequest *a_event = (UpnpActionRequest *)Event; struct Upnp_Action_Request *a_event =
IXML_Document *actionRequestDoc = NULL; (struct Upnp_Action_Request *)Event;
IXML_Document *actionResultDoc = NULL;
char *xmlbuff = NULL; char *xmlbuff = NULL;
SampleUtil_Print( SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(a_event->ErrCode), a_event->ErrCode);
"ErrStr = %s\n" SampleUtil_Print("ErrStr = %s\n", a_event->ErrStr);
"ActionName = %s\n" SampleUtil_Print("ActionName = %s\n", a_event->ActionName);
"UDN = %s\n" SampleUtil_Print("UDN = %s\n", a_event->DevUDN);
"ServiceID = %s\n", SampleUtil_Print("ServiceID = %s\n", a_event->ServiceID);
UpnpActionRequest_get_ErrCode(a_event), if (a_event->ActionRequest) {
UpnpString_get_String(UpnpActionRequest_get_ErrStr(a_event)), xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest);
UpnpString_get_String(UpnpActionRequest_get_ActionName(a_event)),
UpnpString_get_String(UpnpActionRequest_get_DevUDN(a_event)),
UpnpString_get_String(UpnpActionRequest_get_ServiceID(a_event)));
actionRequestDoc = UpnpActionRequest_get_ActionRequest(a_event);
if (actionRequestDoc) {
xmlbuff = ixmlPrintNode((IXML_Node *)actionRequestDoc);
if (xmlbuff) { if (xmlbuff) {
SampleUtil_Print("ActRequest = %s\n", xmlbuff); SampleUtil_Print("ActRequest = %s\n", xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
@@ -493,9 +366,8 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
} else { } else {
SampleUtil_Print("ActRequest = (null)\n"); SampleUtil_Print("ActRequest = (null)\n");
} }
actionResultDoc = UpnpActionRequest_get_ActionResult(a_event); if (a_event->ActionResult) {
if (actionResultDoc) { xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionResult);
xmlbuff = ixmlPrintNode((IXML_Node *)actionResultDoc);
if (xmlbuff) { if (xmlbuff) {
SampleUtil_Print("ActResult = %s\n", xmlbuff); SampleUtil_Print("ActResult = %s\n", xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
@@ -507,22 +379,15 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
break; break;
} }
case UPNP_CONTROL_ACTION_COMPLETE: { case UPNP_CONTROL_ACTION_COMPLETE: {
UpnpActionComplete *a_event = (UpnpActionComplete *)Event; struct Upnp_Action_Complete *a_event =
(struct Upnp_Action_Complete *)Event;
char *xmlbuff = NULL; char *xmlbuff = NULL;
int errCode = UpnpActionComplete_get_ErrCode(a_event);
const char *ctrlURL = UpnpString_get_String(
UpnpActionComplete_get_CtrlUrl(a_event));
IXML_Document *actionRequest =
UpnpActionComplete_get_ActionRequest(a_event);
IXML_Document *actionResult =
UpnpActionComplete_get_ActionResult(a_event);
SampleUtil_Print( SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(a_event->ErrCode), a_event->ErrCode);
"CtrlUrl = %s\n", SampleUtil_Print("CtrlUrl = %s\n", a_event->CtrlUrl);
errCode, ctrlURL); if (a_event->ActionRequest) {
if (actionRequest) { xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest);
xmlbuff = ixmlPrintNode((IXML_Node *)actionRequest);
if (xmlbuff) { if (xmlbuff) {
SampleUtil_Print("ActRequest = %s\n", xmlbuff); SampleUtil_Print("ActRequest = %s\n", xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
@@ -531,8 +396,8 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
} else { } else {
SampleUtil_Print("ActRequest = (null)\n"); SampleUtil_Print("ActRequest = (null)\n");
} }
if (actionResult) { if (a_event->ActionResult) {
xmlbuff = ixmlPrintNode((IXML_Node *)actionResult); xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionResult);
if (xmlbuff) { if (xmlbuff) {
SampleUtil_Print("ActResult = %s\n", xmlbuff); SampleUtil_Print("ActResult = %s\n", xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
@@ -544,107 +409,83 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
break; break;
} }
case UPNP_CONTROL_GET_VAR_REQUEST: { case UPNP_CONTROL_GET_VAR_REQUEST: {
UpnpStateVarRequest *sv_event = (UpnpStateVarRequest *)Event; struct Upnp_State_Var_Request *sv_event =
(struct Upnp_State_Var_Request *)Event;
SampleUtil_Print( SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(sv_event->ErrCode), sv_event->ErrCode);
"ErrStr = %s\n" SampleUtil_Print("ErrStr = %s\n", sv_event->ErrStr);
"UDN = %s\n" SampleUtil_Print("UDN = %s\n", sv_event->DevUDN);
"ServiceID = %s\n" SampleUtil_Print("ServiceID = %s\n", sv_event->ServiceID);
"StateVarName= %s\n" SampleUtil_Print("StateVarName= %s\n", sv_event->StateVarName);
"CurrentVal = %s\n", SampleUtil_Print("CurrentVal = %s\n", sv_event->CurrentVal);
UpnpStateVarRequest_get_ErrCode(sv_event),
UpnpString_get_String(UpnpStateVarRequest_get_ErrStr(sv_event)),
UpnpString_get_String(UpnpStateVarRequest_get_DevUDN(sv_event)),
UpnpString_get_String(UpnpStateVarRequest_get_ServiceID(sv_event)),
UpnpString_get_String(UpnpStateVarRequest_get_StateVarName(sv_event)),
UpnpStateVarRequest_get_CurrentVal(sv_event));
break; break;
} }
case UPNP_CONTROL_GET_VAR_COMPLETE: { case UPNP_CONTROL_GET_VAR_COMPLETE: {
UpnpStateVarComplete *sv_event = (UpnpStateVarComplete *)Event; struct Upnp_State_Var_Complete *sv_event =
(struct Upnp_State_Var_Complete *)Event;
SampleUtil_Print( SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(sv_event->ErrCode), sv_event->ErrCode);
"CtrlUrl = %s\n" SampleUtil_Print("CtrlUrl = %s\n", sv_event->CtrlUrl);
"StateVarName= %s\n" SampleUtil_Print("StateVarName= %s\n", sv_event->StateVarName);
"CurrentVal = %s\n", SampleUtil_Print("CurrentVal = %s\n", sv_event->CurrentVal);
UpnpStateVarComplete_get_ErrCode(sv_event),
UpnpString_get_String(UpnpStateVarComplete_get_CtrlUrl(sv_event)),
UpnpString_get_String(UpnpStateVarComplete_get_StateVarName(sv_event)),
UpnpStateVarComplete_get_CurrentVal(sv_event));
break; break;
} }
/* GENA */ /* GENA */
case UPNP_EVENT_SUBSCRIPTION_REQUEST: { case UPNP_EVENT_SUBSCRIPTION_REQUEST: {
UpnpSubscriptionRequest *sr_event = (UpnpSubscriptionRequest *)Event; struct Upnp_Subscription_Request *sr_event =
(struct Upnp_Subscription_Request *)Event;
SampleUtil_Print( SampleUtil_Print("ServiceID = %s\n", sr_event->ServiceId);
"ServiceID = %s\n" SampleUtil_Print("UDN = %s\n", sr_event->UDN);
"UDN = %s\n" SampleUtil_Print("SID = %s\n", sr_event->Sid);
"SID = %s\n",
UpnpString_get_String(UpnpSubscriptionRequest_get_ServiceId(sr_event)),
UpnpString_get_String(UpnpSubscriptionRequest_get_UDN(sr_event)),
UpnpString_get_String(UpnpSubscriptionRequest_get_SID(sr_event)));
break; break;
} }
case UPNP_EVENT_RECEIVED: { case UPNP_EVENT_RECEIVED: {
UpnpEvent *e_event = (UpnpEvent *)Event; struct Upnp_Event *e_event = (struct Upnp_Event *)Event;
char *xmlbuff = NULL; char *xmlbuff = NULL;
xmlbuff = ixmlPrintNode( SampleUtil_Print("SID = %s\n", e_event->Sid);
(IXML_Node *)UpnpEvent_get_ChangedVariables(e_event)); SampleUtil_Print("EventKey = %d\n", e_event->EventKey);
SampleUtil_Print( xmlbuff = ixmlPrintNode((IXML_Node *)e_event->ChangedVariables);
"SID = %s\n" SampleUtil_Print("ChangedVars = %s\n", xmlbuff);
"EventKey = %d\n"
"ChangedVars = %s\n",
UpnpString_get_String(UpnpEvent_get_SID(e_event)),
UpnpEvent_get_EventKey(e_event),
xmlbuff);
ixmlFreeDOMString(xmlbuff); ixmlFreeDOMString(xmlbuff);
xmlbuff = NULL;
break; break;
} }
case UPNP_EVENT_RENEWAL_COMPLETE: { case UPNP_EVENT_RENEWAL_COMPLETE: {
UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; struct Upnp_Event_Subscribe *es_event =
(struct Upnp_Event_Subscribe *)Event;
SampleUtil_Print( SampleUtil_Print("SID = %s\n", es_event->Sid);
"SID = %s\n" SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
"TimeOut = %d\n", SampleUtil_Print("TimeOut = %d\n", es_event->TimeOut);
UpnpString_get_String(UpnpEventSubscribe_get_SID(es_event)),
UpnpEventSubscribe_get_ErrCode(es_event),
UpnpEventSubscribe_get_TimeOut(es_event));
break; break;
} }
case UPNP_EVENT_SUBSCRIBE_COMPLETE: case UPNP_EVENT_SUBSCRIBE_COMPLETE:
case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: { case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: {
UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; struct Upnp_Event_Subscribe *es_event =
(struct Upnp_Event_Subscribe *)Event;
SampleUtil_Print( SampleUtil_Print("SID = %s\n", es_event->Sid);
"SID = %s\n" SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
"PublisherURL= %s\n" SampleUtil_Print("PublisherURL= %s\n", es_event->PublisherUrl);
"TimeOut = %d\n", SampleUtil_Print("TimeOut = %d\n", es_event->TimeOut);
UpnpString_get_String(UpnpEventSubscribe_get_SID(es_event)),
UpnpEventSubscribe_get_ErrCode(es_event),
UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)),
UpnpEventSubscribe_get_TimeOut(es_event));
break; break;
} }
case UPNP_EVENT_AUTORENEWAL_FAILED: case UPNP_EVENT_AUTORENEWAL_FAILED:
case UPNP_EVENT_SUBSCRIPTION_EXPIRED: { case UPNP_EVENT_SUBSCRIPTION_EXPIRED: {
UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event; struct Upnp_Event_Subscribe *es_event =
(struct Upnp_Event_Subscribe *)Event;
SampleUtil_Print( SampleUtil_Print("SID = %s\n", es_event->Sid);
"SID = %s\n" SampleUtil_Print("ErrCode = %s(%d)\n",
"ErrCode = %d\n" UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
"PublisherURL= %s\n" SampleUtil_Print("PublisherURL= %s\n", es_event->PublisherUrl);
"TimeOut = %d\n", SampleUtil_Print("TimeOut = %d\n", es_event->TimeOut);
UpnpString_get_String(UpnpEventSubscribe_get_SID(es_event)),
UpnpEventSubscribe_get_ErrCode(es_event),
UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)),
UpnpEventSubscribe_get_TimeOut(es_event));
break; break;
} }
} }
@@ -658,31 +499,17 @@ int SampleUtil_PrintEvent(IN Upnp_EventType EventType, IN void *Event)
return 0; return 0;
} }
/******************************************************************************* int SampleUtil_FindAndParseService(IXML_Document *DescDoc, const char *location,
* SampleUtil_FindAndParseService const char *serviceType, char **serviceId, char **eventURL, char **controlURL)
*
* 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 i; unsigned int i;
int length; unsigned long length;
int found = 0; int found = 0;
int ret; int ret;
int sindex = 0; #ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
unsigned int sindex = 0;
#endif /* OLD_FIND_SERVICE_CODE */
char *tempServiceType = NULL; char *tempServiceType = NULL;
char *baseURL = NULL; char *baseURL = NULL;
const char *base = NULL; const char *base = NULL;
@@ -692,53 +519,45 @@ int SampleUtil_FindAndParseService(
IXML_Element *service = NULL; IXML_Element *service = NULL;
baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase"); baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase");
if (baseURL) { if (baseURL)
base = baseURL; base = baseURL;
} else { else
base = location; base = location;
} #ifdef OLD_FIND_SERVICE_CODE
serviceList = SampleUtil_GetFirstServiceList(DescDoc);
/* Top level */ #else /* OLD_FIND_SERVICE_CODE */
for (sindex = 0; for (sindex = 0;
(serviceList = SampleUtil_GetNthServiceList(DescDoc , sindex)) != NULL; (serviceList = SampleUtil_GetNthServiceList(DescDoc , sindex)) != NULL;
sindex ++) { sindex++) {
tempServiceType = NULL; tempServiceType = NULL;
relcontrolURL = NULL; relcontrolURL = NULL;
releventURL = NULL; releventURL = NULL;
service = NULL; service = NULL;
#endif /* OLD_FIND_SERVICE_CODE */
/* serviceList = SampleUtil_GetFirstServiceList( DescDoc ); */
length = ixmlNodeList_length(serviceList); length = ixmlNodeList_length(serviceList);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
service = (IXML_Element *)ixmlNodeList_item(serviceList, i); service = (IXML_Element *)ixmlNodeList_item(serviceList, i);
tempServiceType = tempServiceType = SampleUtil_GetFirstElementItem(
SampleUtil_GetFirstElementItem( (IXML_Element *)service, "serviceType");
(IXML_Element *)service, "serviceType"); if (tempServiceType && strcmp(tempServiceType, serviceType) == 0) {
if (strcmp(tempServiceType, serviceType) == 0) {
SampleUtil_Print("Found service: %s\n", serviceType); SampleUtil_Print("Found service: %s\n", serviceType);
*serviceId = *serviceId = SampleUtil_GetFirstElementItem(service, "serviceId");
SampleUtil_GetFirstElementItem(service, "serviceId");
SampleUtil_Print("serviceId: %s\n", *serviceId); SampleUtil_Print("serviceId: %s\n", *serviceId);
relcontrolURL = relcontrolURL = SampleUtil_GetFirstElementItem(service, "controlURL");
SampleUtil_GetFirstElementItem(service, "controlURL"); releventURL = SampleUtil_GetFirstElementItem(service, "eventSubURL");
releventURL = *controlURL = malloc(strlen(base) + strlen(relcontrolURL) + 1);
SampleUtil_GetFirstElementItem(service, "eventSubURL");
*controlURL =
malloc(strlen(base) + strlen(relcontrolURL)+1);
if (*controlURL) { if (*controlURL) {
ret = UpnpResolveURL(base, relcontrolURL, *controlURL); ret = UpnpResolveURL(base, relcontrolURL, *controlURL);
if (ret != UPNP_E_SUCCESS) { if (ret != UPNP_E_SUCCESS)
SampleUtil_Print("Error generating controlURL from %s + %s\n", SampleUtil_Print("Error generating controlURL from %s + %s\n",
base, relcontrolURL); base, relcontrolURL);
}
} }
*eventURL = malloc(strlen(base) + strlen(releventURL)+1); *eventURL = malloc(strlen(base) + strlen(releventURL) + 1);
if (*eventURL) { if (*eventURL) {
ret = UpnpResolveURL(base, releventURL, *eventURL); ret = UpnpResolveURL(base, releventURL, *eventURL);
if (ret != UPNP_E_SUCCESS) { if (ret != UPNP_E_SUCCESS)
SampleUtil_Print("Error generating eventURL from %s + %s\n", SampleUtil_Print("Error generating eventURL from %s + %s\n",
base, releventURL); base, releventURL);
}
} }
free(relcontrolURL); free(relcontrolURL);
free(releventURL); free(releventURL);
@@ -752,30 +571,19 @@ int SampleUtil_FindAndParseService(
} }
free(tempServiceType); free(tempServiceType);
tempServiceType = NULL; tempServiceType = NULL;
if (serviceList) { if (serviceList)
ixmlNodeList_free(serviceList); ixmlNodeList_free(serviceList);
}
serviceList = NULL; serviceList = NULL;
#ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
} }
#endif /* OLD_FIND_SERVICE_CODE */
free(baseURL); free(baseURL);
return found; return found;
} }
/******************************************************************************* int SampleUtil_Print(const char *fmt, ...)
* 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, ...)
{ {
#define MAX_BUF (8 * 1024) #define MAX_BUF (8 * 1024)
va_list ap; va_list ap;
@@ -788,30 +596,33 @@ int SampleUtil_Print(char *fmt, ...)
va_start(ap, fmt); va_start(ap, fmt);
rc = vsnprintf(buf, MAX_BUF, fmt, ap); rc = vsnprintf(buf, MAX_BUF, fmt, ap);
va_end(ap); va_end(ap);
if (gPrintFun)
if (gPrintFun) { gPrintFun("%s", buf);
gPrintFun(buf);
}
ithread_mutex_unlock(&display_mutex); ithread_mutex_unlock(&display_mutex);
return rc; return rc;
} }
/*******************************************************************************
* SampleUtil_StateUpdate
*
* Description:
*
* Parameters:
*
******************************************************************************/
void SampleUtil_StateUpdate(const char *varName, const char *varValue, void SampleUtil_StateUpdate(const char *varName, const char *varValue,
const char *UDN, eventType type) const char *UDN, eventType type)
{ {
/* TBD: Add mutex here? */ /* TBD: Add mutex here? */
if (gStateUpdateFun) { if (gStateUpdateFun)
gStateUpdateFun(varName, varValue, UDN, type); gStateUpdateFun(varName, varValue, UDN, type);
}
} }
/*!
* \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);
}
/*! @} UpnpSamples */

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,6 @@
#ifndef UPNP_TV_CTRLPT_H
#define UPNP_TV_CTRLPT_H
/************************************************************************** /**************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
@@ -29,66 +32,58 @@
* *
**************************************************************************/ **************************************************************************/
/*!
#ifndef UPNP_TV_CTRLPT_H * \addtogroup UpnpSamples
#define UPNP_TV_CTRLPT_H *
* @{
*
* \name Contro Point Sample API
*
* @{
*
* \file
*/
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "sample_util.h" #include "sample_util.h"
#include "ithread.h"
#include "upnp.h" #include "upnp.h"
#include "UpnpString.h"
#include "upnptools.h" #include "upnptools.h"
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdio.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_SERVCOUNT 2
#define TV_SERVICE_CONTROL 0 #define TV_SERVICE_CONTROL 0
#define TV_SERVICE_PICTURE 1 #define TV_SERVICE_PICTURE 1
#define TV_CONTROL_VARCOUNT 3 #define TV_CONTROL_VARCOUNT 3
#define TV_CONTROL_POWER 0 #define TV_CONTROL_POWER 0
#define TV_CONTROL_CHANNEL 1 #define TV_CONTROL_CHANNEL 1
#define TV_CONTROL_VOLUME 2 #define TV_CONTROL_VOLUME 2
#define TV_PICTURE_VARCOUNT 4 #define TV_PICTURE_VARCOUNT 4
#define TV_PICTURE_COLOR 0 #define TV_PICTURE_COLOR 0
#define TV_PICTURE_TINT 1 #define TV_PICTURE_TINT 1
#define TV_PICTURE_CONTRAST 2 #define TV_PICTURE_CONTRAST 2
#define TV_PICTURE_BRIGHTNESS 3 #define TV_PICTURE_BRIGHTNESS 3
#define TV_MAX_VAL_LEN 5 #define TV_MAX_VAL_LEN 5
#define TV_SUCCESS 0 #define TV_SUCCESS 0
#define TV_ERROR (-1) #define TV_ERROR (-1)
#define TV_WARNING 1 #define TV_WARNING 1
/* This should be the maximum VARCOUNT from above */ /* This should be the maximum VARCOUNT from above */
#define TV_MAXVARS TV_PICTURE_VARCOUNT #define TV_MAXVARS TV_PICTURE_VARCOUNT
extern char TvDeviceType[]; extern const char *TvServiceName[];
extern char *TvServiceType[]; extern const char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS];
extern char *TvServiceName[];
extern char *TvVarName[TV_SERVICE_SERVCOUNT][TV_MAXVARS];
extern char TvVarCount[]; extern char TvVarCount[];
struct tv_service { struct tv_service {
@@ -120,15 +115,14 @@ extern ithread_mutex_t DeviceListMutex;
extern UpnpClient_Handle ctrlpt_handle; extern UpnpClient_Handle ctrlpt_handle;
void TvCtrlPointPrintHelp(); void TvCtrlPointPrintHelp(void);
int TvCtrlPointDeleteNode(struct TvDeviceNode*); int TvCtrlPointDeleteNode(struct TvDeviceNode *);
int TvCtrlPointRemoveDevice(const char *); int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll(); int TvCtrlPointRemoveAll(void);
int TvCtrlPointRefresh(); int TvCtrlPointRefresh(void);
int TvCtrlPointSendAction(int, int, const char *, const char **, char **, int);
int TvCtrlPointSendAction(int, int, char *, char **, char **, int); int TvCtrlPointSendActionNumericArg(int devnum, int service, const char *actionName, const char *paramName, int paramValue);
int TvCtrlPointSendActionNumericArg(int devnum, int service, char *actionName, char *paramName, int paramValue);
int TvCtrlPointSendPowerOn(int devnum); int TvCtrlPointSendPowerOn(int devnum);
int TvCtrlPointSendPowerOff(int devnum); int TvCtrlPointSendPowerOff(int devnum);
int TvCtrlPointSendSetChannel(int, int); int TvCtrlPointSendSetChannel(int, int);
@@ -138,7 +132,7 @@ int TvCtrlPointSendSetTint(int, int);
int TvCtrlPointSendSetContrast(int, int); int TvCtrlPointSendSetContrast(int, int);
int TvCtrlPointSendSetBrightness(int, int); int TvCtrlPointSendSetBrightness(int, int);
int TvCtrlPointGetVar(int, int, char*); int TvCtrlPointGetVar(int, int, const char *);
int TvCtrlPointGetPower(int devnum); int TvCtrlPointGetPower(int devnum);
int TvCtrlPointGetChannel(int); int TvCtrlPointGetChannel(int);
int TvCtrlPointGetVolume(int); int TvCtrlPointGetVolume(int);
@@ -148,23 +142,84 @@ int TvCtrlPointGetContrast(int);
int TvCtrlPointGetBrightness(int); int TvCtrlPointGetBrightness(int);
int TvCtrlPointGetDevice(int, struct TvDeviceNode **); int TvCtrlPointGetDevice(int, struct TvDeviceNode **);
int TvCtrlPointPrintList( void ); int TvCtrlPointPrintList(void);
int TvCtrlPointPrintDevice(int); int TvCtrlPointPrintDevice(int);
void TvCtrlPointAddDevice(IXML_Document *, const char *, int); void TvCtrlPointAddDevice(IXML_Document *, const char *, int);
void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString); void TvCtrlPointHandleGetVar(const char *, const char *, const DOMString);
void TvStateUpdate(char*,int, IXML_Document * , char **);
void TvCtrlPointHandleEvent(const UpnpString *, int, IXML_Document *); /*!
* \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); void TvCtrlPointHandleSubscribeUpdate(const char *, const Upnp_SID, int);
int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *); int TvCtrlPointCallbackEventHandler(Upnp_EventType, void *, void *);
void TvCtrlPointVerifyTimeouts(int);
void TvCtrlPointPrintCommands( void ); /*!
void* TvCtrlPointCommandLoop( void* ); * \brief Checks the advertisement each device in the global device list.
int TvCtrlPointStart( print_string printFunctionPtr, state_update updateFunctionPtr ); *
int TvCtrlPointStop( void ); * If an advertisement expires, the device is removed from the list.
int TvCtrlPointProcessCommand( char *cmdline ); *
* 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 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 #ifdef __cplusplus
}; };
#endif #endif
#endif //UPNP_TV_CTRLPT_H
/*! @} Device Sample */
/*! @} UpnpSamples */
#endif /* UPNP_TV_CTRLPT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,571 @@
#ifndef UPNP_TV_DEVICE_H
#define UPNP_TV_DEVICE_H
/**************************************************************************
*
* 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.
*
**************************************************************************/
/*!
* \addtogroup UpnpSamples
*
* @{
*
* \name Device Sample API
*
* @{
*
* \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>
/*! 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
/*! @} Control Point Sample API */
/*! @} UpnpSamples */
#endif /* UPNP_TV_DEVICE_H */

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

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(const UpnpSubscriptionRequest *);
/******************************************************************************
* 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(UpnpStateVarRequest *);
/******************************************************************************
* 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(UpnpActionRequest *);
/******************************************************************************
* 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();
#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,170 +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 "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();
int TvCtrlPointDeleteNode(struct TvDeviceNode*);
int TvCtrlPointRemoveDevice(const char *);
int TvCtrlPointRemoveAll();
int TvCtrlPointRefresh();
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 UpnpString *, 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,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(const UpnpSubscriptionRequest *);
/******************************************************************************
* 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(UpnpStateVarRequest *);
/******************************************************************************
* 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(UpnpActionRequest *);
/******************************************************************************
* 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,157 +0,0 @@
/*!
* \file
*
* \brief UpnpActionComplete object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "ActionComplete.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for strlen(), strdup() */
/*!
* \brief Internal implementation of the UpnpActionComplete object.
*/
struct SUpnpActionComplete
{
/*! The result of the operation */
int m_errCode;
/*! The control URL for service. */
UpnpString *m_ctrlUrl;
/*! The DOM document describing the action. */
IXML_Document *m_actionRequest;
/*! The DOM document describing the result of the action */
IXML_Document *m_actionResult;
};
UpnpActionComplete *UpnpActionComplete_new()
{
struct SUpnpActionComplete *p = calloc(1, sizeof (struct SUpnpActionComplete));
#if 0
p->m_errCode = 0;
#endif
p->m_ctrlUrl = UpnpString_new();
#if 0
p->m_actionRequest = NULL;
p->m_actionResult = NULL;
#endif
return (UpnpActionComplete *)p;
}
void UpnpActionComplete_delete(UpnpActionComplete *p)
{
struct SUpnpActionComplete *q = (struct SUpnpActionComplete *)p;
if (!q) return;
q->m_errCode = 0;
UpnpString_delete(q->m_ctrlUrl);
q->m_ctrlUrl = NULL;
UpnpActionComplete_set_ActionRequest(p, NULL);
UpnpActionComplete_set_ActionResult(p, NULL);
free(p);
}
UpnpActionComplete *UpnpActionComplete_dup(const UpnpActionComplete *p)
{
UpnpActionComplete *q = UpnpActionComplete_new();
UpnpActionComplete_assign(q, p);
return q;
}
void UpnpActionComplete_assign(UpnpActionComplete *p, const UpnpActionComplete *q)
{
if (p != q) {
UpnpActionComplete_set_ErrCode(p, UpnpActionComplete_get_ErrCode(q));
UpnpActionComplete_set_CtrlUrl(p, UpnpActionComplete_get_CtrlUrl(q));
UpnpActionComplete_set_ActionRequest(p, UpnpActionComplete_get_ActionRequest(q));
UpnpActionComplete_set_ActionResult(p, UpnpActionComplete_get_ActionResult(q));
}
}
int UpnpActionComplete_get_ErrCode(const UpnpActionComplete *p)
{
return ((struct SUpnpActionComplete *)p)->m_errCode;
}
void UpnpActionComplete_set_ErrCode(UpnpActionComplete *p, int n)
{
((struct SUpnpActionComplete *)p)->m_errCode = n;
}
const UpnpString *UpnpActionComplete_get_CtrlUrl(const UpnpActionComplete *p)
{
return ((struct SUpnpActionComplete *)p)->m_ctrlUrl;
}
const char *UpnpActionComplete_get_CtrlUrl_cstr(const UpnpActionComplete *p)
{
return UpnpString_get_String(UpnpActionComplete_get_CtrlUrl(p));
}
void UpnpActionComplete_set_CtrlUrl(UpnpActionComplete *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpActionComplete *)p)->m_ctrlUrl);
((struct SUpnpActionComplete *)p)->m_ctrlUrl = UpnpString_dup(s);
}
void UpnpActionComplete_strcpy_CtrlUrl(UpnpActionComplete *p, const char *s)
{
UpnpString_delete(((struct SUpnpActionComplete *)p)->m_ctrlUrl);
((struct SUpnpActionComplete *)p)->m_ctrlUrl = UpnpString_new();
UpnpString_set_String(((struct SUpnpActionComplete *)p)->m_ctrlUrl, s);
}
IXML_Document *UpnpActionComplete_get_ActionRequest(const UpnpActionComplete *p)
{
return ((struct SUpnpActionComplete *)p)->m_actionRequest;
}
void UpnpActionComplete_set_ActionRequest(UpnpActionComplete *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpActionComplete *)p)->m_actionRequest);
((struct SUpnpActionComplete *)p)->m_actionRequest = d;
}
IXML_Document *UpnpActionComplete_get_ActionResult(const UpnpActionComplete *p)
{
return ((struct SUpnpActionComplete *)p)->m_actionResult;
}
void UpnpActionComplete_set_ActionResult(UpnpActionComplete *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpActionComplete *)p)->m_actionResult);
((struct SUpnpActionComplete *)p)->m_actionResult = d;
}

View File

@@ -1,283 +0,0 @@
/*!
* \file
*
* \brief UpnpActionRequest object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "ActionRequest.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for memset(), strlen(), strdup() */
struct SUpnpActionRequest
{
int m_errCode;
int m_socket;
UpnpString *m_errStr;
UpnpString *m_actionName;
UpnpString *m_devUDN;
UpnpString *m_serviceID;
IXML_Document *m_actionRequest;
IXML_Document *m_actionResult;
IXML_Document *m_soapHeader;
/* Variables should be declared with struct sockaddr_storage,
* but users must only see a struct sockaddr pointer */
struct sockaddr_storage m_ctrlPtIPAddr;
};
UpnpActionRequest *UpnpActionRequest_new()
{
struct SUpnpActionRequest *p = calloc(1, sizeof (struct SUpnpActionRequest));
#if 0
p->m_errCode = 0;
p->m_socket = 0;
#endif
p->m_errStr = UpnpString_new();
p->m_actionName = UpnpString_new();
p->m_devUDN = UpnpString_new();
p->m_serviceID = UpnpString_new();
#if 0
p->m_actionRequest = NULL;
p->m_actionResult = NULL;
p->m_soapHeader = NULL;
memset(&p->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
#endif
return (UpnpActionRequest *)p;
}
void UpnpActionRequest_delete(UpnpActionRequest *p)
{
struct SUpnpActionRequest *q = (struct SUpnpActionRequest *)p;
if (!q) return;
q->m_errCode = 0;
q->m_socket = 0;
UpnpString_delete(q->m_errStr);
q->m_errStr = NULL;
UpnpString_delete(q->m_actionName);
q->m_actionName = NULL;
UpnpString_delete(q->m_devUDN);
q->m_devUDN = NULL;
UpnpString_delete(q->m_serviceID);
q->m_serviceID = NULL;
UpnpActionRequest_set_ActionRequest(p, NULL);
UpnpActionRequest_set_ActionResult(p, NULL);
UpnpActionRequest_set_SoapHeader(p, NULL);
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
free(p);
}
UpnpActionRequest *UpnpActionRequest_dup(const UpnpActionRequest *p)
{
UpnpActionRequest *q = UpnpActionRequest_new();
UpnpActionRequest_assign(q, p);
return q;
}
void UpnpActionRequest_assign(UpnpActionRequest *p, const UpnpActionRequest *q)
{
if (p != q) {
UpnpActionRequest_set_ErrCode(p, UpnpActionRequest_get_ErrCode(q));
UpnpActionRequest_set_Socket(p, UpnpActionRequest_get_Socket(q));
UpnpActionRequest_set_ErrStr(p, UpnpActionRequest_get_ErrStr(q));
UpnpActionRequest_set_ActionName(p, UpnpActionRequest_get_ActionName(q));
UpnpActionRequest_set_DevUDN(p, UpnpActionRequest_get_DevUDN(q));
UpnpActionRequest_set_ServiceID(p, UpnpActionRequest_get_ServiceID(q));
UpnpActionRequest_set_ActionRequest(p, UpnpActionRequest_get_ActionRequest(q));
UpnpActionRequest_set_ActionResult(p, UpnpActionRequest_get_ActionResult(q));
UpnpActionRequest_set_CtrlPtIPAddr(p, UpnpActionRequest_get_CtrlPtIPAddr(q));
UpnpActionRequest_set_SoapHeader(p, UpnpActionRequest_get_SoapHeader(q));
}
}
int UpnpActionRequest_get_ErrCode(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_errCode;
}
void UpnpActionRequest_set_ErrCode(UpnpActionRequest *p, int n)
{
((struct SUpnpActionRequest *)p)->m_errCode = n;
}
int UpnpActionRequest_get_Socket(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_socket;
}
void UpnpActionRequest_set_Socket(UpnpActionRequest *p, int n)
{
((struct SUpnpActionRequest *)p)->m_socket = n;
}
const UpnpString *UpnpActionRequest_get_ErrStr(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_errStr;
}
const char *UpnpActionRequest_get_ErrStr_cstr(const UpnpActionRequest *p)
{
return UpnpString_get_String(UpnpActionRequest_get_ErrStr(p));
}
void UpnpActionRequest_set_ErrStr(UpnpActionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_errStr);
((struct SUpnpActionRequest *)p)->m_errStr = UpnpString_dup(s);
}
void UpnpActionRequest_strcpy_ErrStr(UpnpActionRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_errStr);
((struct SUpnpActionRequest *)p)->m_errStr = UpnpString_new();
UpnpString_set_String(((struct SUpnpActionRequest *)p)->m_errStr, s);
}
const UpnpString *UpnpActionRequest_get_ActionName(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_actionName;
}
const char *UpnpActionRequest_get_ActionName_cstr(const UpnpActionRequest *p)
{
return UpnpString_get_String(UpnpActionRequest_get_ActionName(p));
}
void UpnpActionRequest_set_ActionName(UpnpActionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_actionName);
((struct SUpnpActionRequest *)p)->m_actionName = UpnpString_dup(s);
}
void UpnpActionRequest_strcpy_ActionName(UpnpActionRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_actionName);
((struct SUpnpActionRequest *)p)->m_actionName = UpnpString_new();
UpnpString_set_String(((struct SUpnpActionRequest *)p)->m_actionName, s);
}
const UpnpString *UpnpActionRequest_get_DevUDN(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_devUDN;
}
const char *UpnpActionRequest_get_DevUDN_cstr(const UpnpActionRequest *p)
{
return UpnpString_get_String(UpnpActionRequest_get_DevUDN(p));
}
void UpnpActionRequest_set_DevUDN(UpnpActionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_devUDN);
((struct SUpnpActionRequest *)p)->m_devUDN = UpnpString_dup(s);
}
const UpnpString *UpnpActionRequest_get_ServiceID(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_serviceID;
}
const char *UpnpActionRequest_get_ServiceID_cstr(const UpnpActionRequest *p)
{
return UpnpString_get_String(UpnpActionRequest_get_ServiceID(p));
}
void UpnpActionRequest_set_ServiceID(UpnpActionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpActionRequest *)p)->m_serviceID);
((struct SUpnpActionRequest *)p)->m_serviceID = UpnpString_dup(s);
}
IXML_Document *UpnpActionRequest_get_ActionRequest(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_actionRequest;
}
void UpnpActionRequest_set_ActionRequest(UpnpActionRequest *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpActionRequest *)p)->m_actionRequest);
((struct SUpnpActionRequest *)p)->m_actionRequest = d;
}
IXML_Document *UpnpActionRequest_get_ActionResult(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_actionResult;
}
void UpnpActionRequest_set_ActionResult(UpnpActionRequest *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpActionRequest *)p)->m_actionResult);
((struct SUpnpActionRequest *)p)->m_actionResult = d;
}
const struct sockaddr *UpnpActionRequest_get_CtrlPtIPAddr(const UpnpActionRequest *p)
{
return (struct sockaddr *)&((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr;
}
void UpnpActionRequest_set_CtrlPtIPAddr(UpnpActionRequest *p, const struct sockaddr *ia)
{
((struct SUpnpActionRequest *)p)->m_ctrlPtIPAddr = *(struct sockaddr_storage *)ia;
}
IXML_Document *UpnpActionRequest_get_SoapHeader(const UpnpActionRequest *p)
{
return ((struct SUpnpActionRequest *)p)->m_soapHeader;
}
void UpnpActionRequest_set_SoapHeader(UpnpActionRequest *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpActionRequest *)p)->m_soapHeader);
((struct SUpnpActionRequest *)p)->m_soapHeader = d;
}

View File

@@ -1,396 +0,0 @@
/*!
* \file
*
* \brief UpnpDiscovery object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "Discovery.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for memset() */
struct SUpnpDiscovery
{
int m_errCode;
int m_expires;
UpnpString *m_deviceID;
UpnpString *m_deviceType;
UpnpString *m_serviceType;
UpnpString *m_serviceVer;
UpnpString *m_location;
UpnpString *m_os;
UpnpString *m_date;
UpnpString *m_ext;
/* Variables should be declared with struct sockaddr_storage,
* but users must only see a struct sockaddr pointer */
struct sockaddr_storage m_destAddr;
};
UpnpDiscovery *UpnpDiscovery_new()
{
struct SUpnpDiscovery *p = calloc(1, sizeof (struct SUpnpDiscovery));
#if 0
p->errCode = 0;
p->m_expires = 0;
#endif
p->m_deviceID = UpnpString_new();
p->m_deviceType = UpnpString_new();
p->m_serviceType = UpnpString_new();
p->m_serviceVer = UpnpString_new();
p->m_location = UpnpString_new();
p->m_os = UpnpString_new();
p->m_date = UpnpString_new();
p->m_ext = UpnpString_new();
memset(&p->m_destAddr, 0, sizeof(struct sockaddr_storage));
return (UpnpDiscovery *)p;
}
void UpnpDiscovery_delete(UpnpDiscovery *p)
{
struct SUpnpDiscovery *q = (struct SUpnpDiscovery *)p;
if (!q) return;
q->m_errCode = 0;
q->m_expires = 0;
UpnpString_delete(q->m_deviceID);
q->m_deviceID = NULL;
UpnpString_delete(q->m_deviceType);
q->m_deviceType = NULL;
UpnpString_delete(q->m_serviceType);
q->m_serviceType = NULL;
UpnpString_delete(q->m_serviceVer);
q->m_serviceVer = NULL;
UpnpString_delete(q->m_location);
q->m_location = NULL;
UpnpString_delete(q->m_os);
q->m_os = NULL;
UpnpString_delete(q->m_date);
q->m_date = NULL;
UpnpString_delete(q->m_ext);
q->m_ext = NULL;
memset(&q->m_destAddr, 0, sizeof(struct sockaddr_storage));
free(p);
}
UpnpDiscovery *UpnpDiscovery_dup(const UpnpDiscovery *p)
{
UpnpDiscovery *q = UpnpDiscovery_new();
UpnpDiscovery_assign(q, p);
return q;
}
void UpnpDiscovery_assign(UpnpDiscovery *p, const UpnpDiscovery *q)
{
if (p != q) {
UpnpDiscovery_set_ErrCode(p, UpnpDiscovery_get_ErrCode(q));
UpnpDiscovery_set_Expires(p, UpnpDiscovery_get_Expires(q));
UpnpDiscovery_set_DeviceID(p, UpnpDiscovery_get_DeviceID(q));
UpnpDiscovery_set_DeviceType(p, UpnpDiscovery_get_DeviceType(q));
UpnpDiscovery_set_ServiceType(p, UpnpDiscovery_get_ServiceType(q));
UpnpDiscovery_set_ServiceVer(p, UpnpDiscovery_get_ServiceVer(q));
UpnpDiscovery_set_Location(p, UpnpDiscovery_get_Location(q));
UpnpDiscovery_set_Os(p, UpnpDiscovery_get_Os(q));
UpnpDiscovery_set_Date(p, UpnpDiscovery_get_Date(q));
UpnpDiscovery_set_Ext(p, UpnpDiscovery_get_Ext(q));
UpnpDiscovery_set_DestAddr(p, UpnpDiscovery_get_DestAddr(q));
}
}
int UpnpDiscovery_get_ErrCode(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_errCode;
}
void UpnpDiscovery_set_ErrCode(UpnpDiscovery *p, int n)
{
((struct SUpnpDiscovery *)p)->m_errCode = n;
}
int UpnpDiscovery_get_Expires(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_expires;
}
void UpnpDiscovery_set_Expires(UpnpDiscovery *p, int n)
{
((struct SUpnpDiscovery *)p)->m_expires = n;
}
const UpnpString *UpnpDiscovery_get_DeviceID(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_deviceID;
}
const char *UpnpDiscovery_get_DeviceID_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_DeviceID(p));
}
void UpnpDiscovery_set_DeviceID(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_deviceID);
((struct SUpnpDiscovery *)p)->m_deviceID = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_DeviceID(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_deviceID);
((struct SUpnpDiscovery *)p)->m_deviceID = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_deviceID, s);
}
const UpnpString *UpnpDiscovery_get_DeviceType(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_deviceType;
}
const char *UpnpDiscovery_get_DeviceType_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_DeviceType(p));
}
void UpnpDiscovery_set_DeviceType(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_deviceType);
((struct SUpnpDiscovery *)p)->m_deviceType = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_DeviceType(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_deviceType);
((struct SUpnpDiscovery *)p)->m_deviceType = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_deviceType, s);
}
const UpnpString *UpnpDiscovery_get_ServiceType(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_serviceType;
}
const char *UpnpDiscovery_get_ServiceType_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_ServiceType(p));
}
void UpnpDiscovery_set_ServiceType(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_serviceType);
((struct SUpnpDiscovery *)p)->m_serviceType = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_ServiceType(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_serviceType);
((struct SUpnpDiscovery *)p)->m_serviceType = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_serviceType, s);
}
const UpnpString *UpnpDiscovery_get_ServiceVer(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_serviceVer;
}
const char *UpnpDiscovery_get_ServiceVer_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_ServiceVer(p));
}
void UpnpDiscovery_set_ServiceVer(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_serviceVer);
((struct SUpnpDiscovery *)p)->m_serviceVer = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_ServiceVer(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_serviceVer);
((struct SUpnpDiscovery *)p)->m_serviceVer = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_serviceVer, s);
}
const UpnpString *UpnpDiscovery_get_Location(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_location;
}
const char *UpnpDiscovery_get_Location_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_Location(p));
}
void UpnpDiscovery_set_Location(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_location);
((struct SUpnpDiscovery *)p)->m_location = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_Location(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_location);
((struct SUpnpDiscovery *)p)->m_location = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_location, s);
}
void UpnpDiscovery_strncpy_Location(UpnpDiscovery *p, const char *s, int n)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_location);
((struct SUpnpDiscovery *)p)->m_location = UpnpString_new();
UpnpString_set_StringN(((struct SUpnpDiscovery *)p)->m_location, s, n);
}
const UpnpString *UpnpDiscovery_get_Os(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_os;
}
const char *UpnpDiscovery_get_Os_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_Os(p));
}
void UpnpDiscovery_set_Os(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_os);
((struct SUpnpDiscovery *)p)->m_os = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_Os(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_os);
((struct SUpnpDiscovery *)p)->m_os = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_os, s);
}
void UpnpDiscovery_strncpy_Os(UpnpDiscovery *p, const char *s, int n)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_os);
((struct SUpnpDiscovery *)p)->m_os = UpnpString_new();
UpnpString_set_StringN(((struct SUpnpDiscovery *)p)->m_os, s, n);
}
const UpnpString *UpnpDiscovery_get_Date(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_date;
}
const char *UpnpDiscovery_get_Date_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_Date(p));
}
void UpnpDiscovery_set_Date(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_date);
((struct SUpnpDiscovery *)p)->m_date = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_Date(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_date);
((struct SUpnpDiscovery *)p)->m_date = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_date, s);
}
const UpnpString *UpnpDiscovery_get_Ext(const UpnpDiscovery *p)
{
return ((struct SUpnpDiscovery *)p)->m_ext;
}
const char *UpnpDiscovery_get_Ext_cstr(const UpnpDiscovery *p)
{
return UpnpString_get_String(UpnpDiscovery_get_Ext(p));
}
void UpnpDiscovery_set_Ext(UpnpDiscovery *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_ext);
((struct SUpnpDiscovery *)p)->m_ext = UpnpString_dup(s);
}
void UpnpDiscovery_strcpy_Ext(UpnpDiscovery *p, const char *s)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_ext);
((struct SUpnpDiscovery *)p)->m_ext = UpnpString_new();
UpnpString_set_String(((struct SUpnpDiscovery *)p)->m_ext, s);
}
void UpnpDiscovery_strncpy_Ext(UpnpDiscovery *p, const char *s, int n)
{
UpnpString_delete(((struct SUpnpDiscovery *)p)->m_ext);
((struct SUpnpDiscovery *)p)->m_ext = UpnpString_new();
UpnpString_set_StringN(((struct SUpnpDiscovery *)p)->m_ext, s, n);
}
const struct sockaddr *UpnpDiscovery_get_DestAddr(const UpnpDiscovery *p)
{
return (struct sockaddr *)&((struct SUpnpDiscovery *)p)->m_destAddr;
}
void UpnpDiscovery_set_DestAddr(UpnpDiscovery *p, const struct sockaddr *sa)
{
((struct SUpnpDiscovery *)p)->m_destAddr = *(struct sockaddr_storage *)sa;
}

View File

@@ -1,121 +0,0 @@
/*!
* \file
*
* \brief UpnpEvent object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "Event.h"
#include <stdlib.h> /* for calloc(), free() */
struct SUpnpEvent
{
int m_eventKey;
IXML_Document *m_changedVariables;
UpnpString *m_SID;
};
UpnpEvent *UpnpEvent_new()
{
struct SUpnpEvent *p = calloc(1, sizeof (struct SUpnpEvent));
#if 0
p->m_eventKey = 0;
p->m_changedVariables = NULL;
#endif
p->m_SID = UpnpString_new();
return (UpnpEvent *)p;
}
void UpnpEvent_delete(UpnpEvent *p)
{
struct SUpnpEvent *q = (struct SUpnpEvent *)p;
if (!q) return;
q->m_eventKey = 0;
q->m_changedVariables = NULL;
UpnpString_delete(q->m_SID);
q->m_SID = NULL;
free(p);
}
UpnpEvent *UpnpEvent_dup(const UpnpEvent *p)
{
UpnpEvent *q = UpnpEvent_new();
UpnpEvent_assign(q, p);
return q;
}
void UpnpEvent_assign(UpnpEvent *p, const UpnpEvent *q)
{
if (p != q) {
UpnpEvent_set_EventKey(p, UpnpEvent_get_EventKey(q));
UpnpEvent_set_ChangedVariables(p, UpnpEvent_get_ChangedVariables(q));
UpnpEvent_set_SID(p, UpnpEvent_get_SID(q));
}
}
int UpnpEvent_get_EventKey(const UpnpEvent *p)
{
return ((struct SUpnpEvent *)p)->m_eventKey;
}
void UpnpEvent_set_EventKey(UpnpEvent *p, int n)
{
((struct SUpnpEvent *)p)->m_eventKey = n;
}
IXML_Document *UpnpEvent_get_ChangedVariables(const UpnpEvent *p)
{
return ((struct SUpnpEvent *)p)->m_changedVariables;
}
void UpnpEvent_set_ChangedVariables(UpnpEvent *p, IXML_Document *d)
{
ixmlDocument_free(((struct SUpnpEvent *)p)->m_changedVariables);
((struct SUpnpEvent *)p)->m_changedVariables = d;
}
const UpnpString *UpnpEvent_get_SID(const UpnpEvent *p)
{
return ((struct SUpnpEvent *)p)->m_SID;
}
const char *UpnpEvent_get_SID_cstr(const UpnpEvent *p)
{
return UpnpString_get_String(UpnpEvent_get_SID(p));
}
void UpnpEvent_set_SID(UpnpEvent *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpEvent *)p)->m_SID);
((struct SUpnpEvent *)p)->m_SID = UpnpString_dup(s);
}

View File

@@ -1,159 +0,0 @@
/*!
* \file
*
* \brief UpnpEventSubscribe object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "EventSubscribe.h"
#include <stdlib.h> /* for calloc(), free() */
struct SEventSubscribe
{
int m_errCode;
int m_timeOut;
UpnpString *m_SID;
UpnpString *m_publisherUrl;
};
UpnpEventSubscribe *UpnpEventSubscribe_new()
{
struct SEventSubscribe *p = calloc(1, sizeof (struct SEventSubscribe));
#if 0
p->errCode = 0;
p->timeOut = 0;
#endif
p->m_SID = UpnpString_new();
p->m_publisherUrl = UpnpString_new();
return (UpnpEventSubscribe *)p;
}
void UpnpEventSubscribe_delete(UpnpEventSubscribe *p)
{
struct SEventSubscribe *q = (struct SEventSubscribe *)p;
if (!q) return;
q->m_errCode = 0;
q->m_timeOut = 0;
UpnpString_delete(q->m_publisherUrl);
q->m_publisherUrl = NULL;
UpnpString_delete(q->m_SID);
q->m_SID = NULL;
free(p);
}
UpnpEventSubscribe *UpnpEventSubscribe_dup(const UpnpEventSubscribe *p)
{
UpnpEventSubscribe *q = UpnpEventSubscribe_new();
UpnpEventSubscribe_assign(q, p);
return q;
}
void UpnpEventSubscribe_assign(UpnpEventSubscribe *p, const UpnpEventSubscribe *q)
{
if (p != q) {
UpnpEventSubscribe_set_ErrCode(p, UpnpEventSubscribe_get_ErrCode(q));
UpnpEventSubscribe_set_TimeOut(p, UpnpEventSubscribe_get_TimeOut(q));
UpnpEventSubscribe_set_SID(p, UpnpEventSubscribe_get_SID(q));
UpnpEventSubscribe_set_PublisherUrl(p, UpnpEventSubscribe_get_PublisherUrl(q));
}
}
int UpnpEventSubscribe_get_ErrCode(const UpnpEventSubscribe *p)
{
return ((struct SEventSubscribe *)p)->m_errCode;
}
void UpnpEventSubscribe_set_ErrCode(UpnpEventSubscribe *p, int n)
{
((struct SEventSubscribe *)p)->m_errCode = n;
}
int UpnpEventSubscribe_get_TimeOut(const UpnpEventSubscribe *p)
{
return ((struct SEventSubscribe *)p)->m_timeOut;
}
void UpnpEventSubscribe_set_TimeOut(UpnpEventSubscribe *p, int n)
{
((struct SEventSubscribe *)p)->m_timeOut = n;
}
const UpnpString *UpnpEventSubscribe_get_SID(const UpnpEventSubscribe *p)
{
return ((struct SEventSubscribe *)p)->m_SID;
}
const char *UpnpEventSubscribe_get_SID_cstr(const UpnpEventSubscribe *p)
{
return UpnpString_get_String(UpnpEventSubscribe_get_SID(p));
}
void UpnpEventSubscribe_set_SID(UpnpEventSubscribe *p, const UpnpString *s)
{
UpnpString_delete(((struct SEventSubscribe *)p)->m_SID);
((struct SEventSubscribe *)p)->m_SID = UpnpString_dup(s);
}
void UpnpEventSubscribe_strcpy_SID(UpnpEventSubscribe *p, const char *s)
{
UpnpString_delete(((struct SEventSubscribe *)p)->m_SID);
((struct SEventSubscribe *)p)->m_SID = UpnpString_new();
UpnpString_set_String(((struct SEventSubscribe *)p)->m_SID, s);
}
const UpnpString *UpnpEventSubscribe_get_PublisherUrl(const UpnpEventSubscribe *p)
{
return ((struct SEventSubscribe *)p)->m_publisherUrl;
}
const char *UpnpEventSubscribe_get_PublisherUrl_cstr(const UpnpEventSubscribe *p)
{
return UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(p));
}
void UpnpEventSubscribe_set_PublisherUrl(UpnpEventSubscribe *p, const UpnpString *s)
{
UpnpString_delete(((struct SEventSubscribe *)p)->m_publisherUrl);
((struct SEventSubscribe *)p)->m_publisherUrl = UpnpString_dup(s);
}
void UpnpEventSubscribe_strcpy_PublisherUrl(UpnpEventSubscribe *p, const char *s)
{
UpnpString_delete(((struct SEventSubscribe *)p)->m_publisherUrl);
((struct SEventSubscribe *)p)->m_publisherUrl = UpnpString_new();
UpnpString_set_String(((struct SEventSubscribe *)p)->m_publisherUrl, s);
}

View File

@@ -1,179 +0,0 @@
/*!
* \file
*
* \brief UpnpFileInfo object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "FileInfo.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for strlen(), strdup() */
struct SUpnpFileInfo
{
off_t m_fileLength;
time_t m_lastModified;
int m_isDirectory;
int m_isReadable;
DOMString m_contentType;
DOMString m_extraHeaders;
};
UpnpFileInfo *UpnpFileInfo_new()
{
struct SUpnpFileInfo *p = calloc(1, sizeof (struct SUpnpFileInfo));
#if 0
p->m_fileLength = 0;
p->m_lastModified = 0;
p->m_isDirectory = 0;
p->m_isReadable = 0;
p->m_contentType = NULL;
p->m_extraHeaders = NULL;
#endif
return (UpnpFileInfo *)p;
}
void UpnpFileInfo_delete(UpnpFileInfo *p)
{
struct SUpnpFileInfo *q = (struct SUpnpFileInfo *)p;
if (!q) return;
q->m_fileLength = 0;
q->m_lastModified = 0;
q->m_isDirectory = 0;
q->m_isReadable = 0;
ixmlFreeDOMString(q->m_contentType);
q->m_contentType = NULL;
ixmlFreeDOMString(q->m_extraHeaders);
q->m_extraHeaders = NULL;
free(p);
}
UpnpFileInfo *UpnpFileInfo_dup(const UpnpFileInfo *p)
{
UpnpFileInfo *q = UpnpFileInfo_new();
UpnpFileInfo_assign(q, p);
return q;
}
void UpnpFileInfo_assign(UpnpFileInfo *p, const UpnpFileInfo *q)
{
if (p != q) {
UpnpFileInfo_set_FileLength(p, UpnpFileInfo_get_FileLength(q));
UpnpFileInfo_set_LastModified(p, UpnpFileInfo_get_LastModified(q));
UpnpFileInfo_set_IsDirectory(p, UpnpFileInfo_get_IsDirectory(q));
UpnpFileInfo_set_IsReadable(p, UpnpFileInfo_get_IsReadable(q));
UpnpFileInfo_set_ContentType(p, UpnpFileInfo_get_ContentType(q));
UpnpFileInfo_set_ExtraHeaders(p, UpnpFileInfo_get_ExtraHeaders(q));
}
}
off_t UpnpFileInfo_get_FileLength(const UpnpFileInfo *p)
{
return ((struct SUpnpFileInfo *)p)->m_fileLength;
}
void UpnpFileInfo_set_FileLength(UpnpFileInfo *p, off_t l)
{
((struct SUpnpFileInfo *)p)->m_fileLength = l;
}
const time_t *UpnpFileInfo_get_LastModified(const UpnpFileInfo *p)
{
return &((struct SUpnpFileInfo *)p)->m_lastModified;
}
void UpnpFileInfo_set_LastModified(UpnpFileInfo *p, const time_t *t)
{
((struct SUpnpFileInfo *)p)->m_lastModified = *t;
}
int UpnpFileInfo_get_IsDirectory(const UpnpFileInfo *p)
{
return ((struct SUpnpFileInfo *)p)->m_isDirectory;
}
void UpnpFileInfo_set_IsDirectory(UpnpFileInfo *p, int b)
{
((struct SUpnpFileInfo *)p)->m_isDirectory = b;
}
int UpnpFileInfo_get_IsReadable(const UpnpFileInfo *p)
{
return ((struct SUpnpFileInfo *)p)->m_isReadable;
}
void UpnpFileInfo_set_IsReadable(UpnpFileInfo *p, int b)
{
((struct SUpnpFileInfo *)p)->m_isReadable = b;
}
const DOMString UpnpFileInfo_get_ContentType(const UpnpFileInfo *p)
{
return ((struct SUpnpFileInfo *)p)->m_contentType;
}
const char *UpnpFileInfo_get_ContentType_cstr(const UpnpFileInfo *p)
{
return (const char *)UpnpFileInfo_get_ContentType(p);
}
void UpnpFileInfo_set_ContentType(UpnpFileInfo *p, const DOMString s)
{
ixmlFreeDOMString(((struct SUpnpFileInfo *)p)->m_contentType);
((struct SUpnpFileInfo *)p)->m_contentType = ixmlCloneDOMString(s);
}
const DOMString UpnpFileInfo_get_ExtraHeaders(const UpnpFileInfo *p)
{
return ((struct SUpnpFileInfo *)p)->m_extraHeaders;
}
const char *UpnpFileInfo_get_ExtraHeaders_cstr(const UpnpFileInfo *p)
{
return (const char *)UpnpFileInfo_get_ExtraHeaders(p);
}
void UpnpFileInfo_set_ExtraHeaders(UpnpFileInfo *p, const DOMString s)
{
ixmlFreeDOMString(((struct SUpnpFileInfo *)p)->m_extraHeaders);
((struct SUpnpFileInfo *)p)->m_extraHeaders = ixmlCloneDOMString(s);
}

View File

@@ -1,170 +0,0 @@
/*!
* \file
*
* \brief UpnpStateVarComplete object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "StateVarComplete.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for strlen(), strdup() */
struct SUpnpStateVarComplete
{
int m_errCode;
UpnpString *m_ctrlUrl;
UpnpString *m_stateVarName;
DOMString m_currentVal;
};
UpnpStateVarComplete *UpnpStateVarComplete_new()
{
struct SUpnpStateVarComplete *p = calloc(1, sizeof (struct SUpnpStateVarComplete));
#if 0
p->m_errCode = 0;
#endif
p->m_ctrlUrl = UpnpString_new();
p->m_stateVarName = UpnpString_new();
#if 0
p->m_currentVal = NULL;
#endif
return (UpnpStateVarComplete *)p;
}
void UpnpStateVarComplete_delete(UpnpStateVarComplete *p)
{
struct SUpnpStateVarComplete *q = (struct SUpnpStateVarComplete *)p;
if (!q) return;
q->m_errCode = 0;
UpnpString_delete(q->m_ctrlUrl);
q->m_ctrlUrl = NULL;
UpnpString_delete(q->m_stateVarName);
q->m_stateVarName = NULL;
ixmlFreeDOMString(q->m_currentVal);
q->m_currentVal = NULL;
free(p);
}
UpnpStateVarComplete *UpnpStateVarComplete_dup(const UpnpStateVarComplete *p)
{
UpnpStateVarComplete *q = UpnpStateVarComplete_new();
UpnpStateVarComplete_assign(q, p);
return q;
}
void UpnpStateVarComplete_assign(UpnpStateVarComplete *p, const UpnpStateVarComplete *q)
{
if (p != q) {
UpnpStateVarComplete_set_ErrCode(p, UpnpStateVarComplete_get_ErrCode(q));
UpnpStateVarComplete_set_CtrlUrl(p, UpnpStateVarComplete_get_CtrlUrl(q));
UpnpStateVarComplete_set_StateVarName(p, UpnpStateVarComplete_get_StateVarName(q));
UpnpStateVarComplete_set_CurrentVal(p, UpnpStateVarComplete_get_CurrentVal(q));
}
}
int UpnpStateVarComplete_get_ErrCode(const UpnpStateVarComplete *p)
{
return ((struct SUpnpStateVarComplete *)p)->m_errCode;
}
void UpnpStateVarComplete_set_ErrCode(UpnpStateVarComplete *p, int n)
{
((struct SUpnpStateVarComplete *)p)->m_errCode = n;
}
const UpnpString *UpnpStateVarComplete_get_CtrlUrl(const UpnpStateVarComplete *p)
{
return ((struct SUpnpStateVarComplete *)p)->m_ctrlUrl;
}
const char *UpnpStateVarComplete_get_CtrlUrl_cstr(const UpnpStateVarComplete *p)
{
return UpnpString_get_String(UpnpStateVarComplete_get_CtrlUrl(p));
}
void UpnpStateVarComplete_set_CtrlUrl(UpnpStateVarComplete *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarComplete *)p)->m_ctrlUrl);
((struct SUpnpStateVarComplete *)p)->m_ctrlUrl = UpnpString_dup(s);
}
void UpnpStateVarComplete_strcpy_CtrlUrl(UpnpStateVarComplete *p, const char *s)
{
UpnpString_delete(((struct SUpnpStateVarComplete *)p)->m_ctrlUrl);
((struct SUpnpStateVarComplete *)p)->m_ctrlUrl = UpnpString_new();
UpnpString_set_String(((struct SUpnpStateVarComplete *)p)->m_ctrlUrl, s);
}
const UpnpString *UpnpStateVarComplete_get_StateVarName(const UpnpStateVarComplete *p)
{
return ((struct SUpnpStateVarComplete *)p)->m_stateVarName;
}
const char *UpnpStateVarComplete_get_StateVarName_cstr(const UpnpStateVarComplete *p)
{
return UpnpString_get_String(UpnpStateVarComplete_get_StateVarName(p));
}
void UpnpStateVarComplete_set_StateVarName(UpnpStateVarComplete *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarComplete *)p)->m_stateVarName);
((struct SUpnpStateVarComplete *)p)->m_stateVarName = UpnpString_dup(s);
}
void UpnpStateVarComplete_strcpy_StateVarName(UpnpStateVarComplete *p, const char *s)
{
UpnpString_delete(((struct SUpnpStateVarComplete *)p)->m_ctrlUrl);
((struct SUpnpStateVarComplete *)p)->m_ctrlUrl = UpnpString_new();
UpnpString_set_String(((struct SUpnpStateVarComplete *)p)->m_ctrlUrl, s);
}
const DOMString UpnpStateVarComplete_get_CurrentVal(const UpnpStateVarComplete *p)
{
return ((struct SUpnpStateVarComplete *)p)->m_currentVal;
}
const char *UpnpStateVarComplete_get_CurrentVal_cstr(const UpnpStateVarComplete *p)
{
return (const char *)UpnpStateVarComplete_get_CurrentVal(p);
}
void UpnpStateVarComplete_set_CurrentVal(UpnpStateVarComplete *p, const DOMString s)
{
ixmlFreeDOMString(((struct SUpnpStateVarComplete *)p)->m_currentVal);
((struct SUpnpStateVarComplete *)p)->m_currentVal = ixmlCloneDOMString(s);
}

View File

@@ -1,254 +0,0 @@
/*!
* \file
*
* \brief UpnpStateVarRequest object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "StateVarRequest.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for memset(), strlen(), strdup() */
struct SUpnpStateVarRequest
{
int m_errCode;
int m_socket;
UpnpString *m_errStr;
UpnpString *m_devUDN;
UpnpString *m_serviceID;
UpnpString *m_stateVarName;
/* Variables should be declared with struct sockaddr_storage,
* but users must only see a struct sockaddr pointer */
struct sockaddr_storage m_ctrlPtIPAddr;
DOMString m_currentVal;
};
UpnpStateVarRequest *UpnpStateVarRequest_new()
{
struct SUpnpStateVarRequest *p = calloc(1, sizeof (struct SUpnpStateVarRequest));
#if 0
p->m_errCode = 0;
p->m_socket = 0;
#endif
p->m_errStr = UpnpString_new();
p->m_devUDN = UpnpString_new();
p->m_serviceID = UpnpString_new();
p->m_stateVarName = UpnpString_new();
#if 0
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
p->m_currentVal = NULL;
#endif
return (UpnpStateVarRequest *)p;
}
void UpnpStateVarRequest_delete(UpnpStateVarRequest *p)
{
struct SUpnpStateVarRequest *q = (struct SUpnpStateVarRequest *)p;
if (!q) return;
q->m_errCode = 0;
q->m_socket = 0;
UpnpString_delete(q->m_errStr);
q->m_errStr = NULL;
UpnpString_delete(q->m_devUDN);
q->m_devUDN = NULL;
UpnpString_delete(q->m_serviceID);
q->m_serviceID = NULL;
UpnpString_delete(q->m_stateVarName);
q->m_stateVarName = NULL;
memset(&q->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage));
ixmlFreeDOMString(q->m_currentVal);
q->m_currentVal = NULL;
free(p);
}
UpnpStateVarRequest *UpnpStateVarRequest_dup(const UpnpStateVarRequest *p)
{
UpnpStateVarRequest *q = UpnpStateVarRequest_new();
UpnpStateVarRequest_assign(q, p);
return q;
}
void UpnpStateVarRequest_assign(UpnpStateVarRequest *p, const UpnpStateVarRequest *q)
{
if (p != q) {
UpnpStateVarRequest_set_ErrCode(p, UpnpStateVarRequest_get_ErrCode(q));
UpnpStateVarRequest_set_Socket(p, UpnpStateVarRequest_get_Socket(q));
UpnpStateVarRequest_set_ErrStr(p, UpnpStateVarRequest_get_ErrStr(q));
UpnpStateVarRequest_set_StateVarName(p, UpnpStateVarRequest_get_StateVarName(q));
UpnpStateVarRequest_set_DevUDN(p, UpnpStateVarRequest_get_DevUDN(q));
UpnpStateVarRequest_set_ServiceID(p, UpnpStateVarRequest_get_ServiceID(q));
UpnpStateVarRequest_set_CtrlPtIPAddr(p, UpnpStateVarRequest_get_CtrlPtIPAddr(q));
UpnpStateVarRequest_set_CurrentVal(p, UpnpStateVarRequest_get_CurrentVal(q));
}
}
int UpnpStateVarRequest_get_ErrCode(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_errCode;
}
void UpnpStateVarRequest_set_ErrCode(UpnpStateVarRequest *p, int n)
{
((struct SUpnpStateVarRequest *)p)->m_errCode = n;
}
int UpnpStateVarRequest_get_Socket(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_socket;
}
void UpnpStateVarRequest_set_Socket(UpnpStateVarRequest *p, int n)
{
((struct SUpnpStateVarRequest *)p)->m_socket = n;
}
const UpnpString *UpnpStateVarRequest_get_ErrStr(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_errStr;
}
const char *UpnpStateVarRequest_get_ErrStr_cstr(const UpnpStateVarRequest *p)
{
return UpnpString_get_String(UpnpStateVarRequest_get_ErrStr(p));
}
void UpnpStateVarRequest_set_ErrStr(UpnpStateVarRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_errStr);
((struct SUpnpStateVarRequest *)p)->m_errStr = UpnpString_dup(s);
}
void UpnpStateVarRequest_strcpy_ErrStr(UpnpStateVarRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_errStr);
((struct SUpnpStateVarRequest *)p)->m_errStr = UpnpString_new();
UpnpString_set_String(((struct SUpnpStateVarRequest *)p)->m_errStr, s);
}
const UpnpString *UpnpStateVarRequest_get_DevUDN(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_devUDN;
}
const char *UpnpStateVarRequest_get_DevUDN_cstr(const UpnpStateVarRequest *p)
{
return UpnpString_get_String(UpnpStateVarRequest_get_DevUDN(p));
}
void UpnpStateVarRequest_set_DevUDN(UpnpStateVarRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_devUDN);
((struct SUpnpStateVarRequest *)p)->m_devUDN = UpnpString_dup(s);
}
const UpnpString *UpnpStateVarRequest_get_ServiceID(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_serviceID;
}
const char *UpnpStateVarRequest_get_ServiceID_cstr(const UpnpStateVarRequest *p)
{
return UpnpString_get_String(UpnpStateVarRequest_get_ServiceID(p));
}
void UpnpStateVarRequest_set_ServiceID(UpnpStateVarRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_serviceID);
((struct SUpnpStateVarRequest *)p)->m_serviceID = UpnpString_dup(s);
}
const UpnpString *UpnpStateVarRequest_get_StateVarName(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_stateVarName;
}
const char *UpnpStateVarRequest_get_StateVarName_cstr(const UpnpStateVarRequest *p)
{
return UpnpString_get_String(UpnpStateVarRequest_get_StateVarName(p));
}
void UpnpStateVarRequest_set_StateVarName(UpnpStateVarRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_stateVarName);
((struct SUpnpStateVarRequest *)p)->m_stateVarName = UpnpString_dup(s);
}
void UpnpStateVarRequest_strcpy_StateVarName(UpnpStateVarRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpStateVarRequest *)p)->m_errStr);
((struct SUpnpStateVarRequest *)p)->m_errStr = UpnpString_new();
UpnpString_set_String(((struct SUpnpStateVarRequest *)p)->m_errStr, s);
}
const struct sockaddr *UpnpStateVarRequest_get_CtrlPtIPAddr(const UpnpStateVarRequest *p)
{
return (struct sockaddr *)&((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr;
}
void UpnpStateVarRequest_set_CtrlPtIPAddr(UpnpStateVarRequest *p, const struct sockaddr *sa)
{
((struct SUpnpStateVarRequest *)p)->m_ctrlPtIPAddr = *(struct sockaddr_storage *)sa;
}
const DOMString UpnpStateVarRequest_get_CurrentVal(const UpnpStateVarRequest *p)
{
return ((struct SUpnpStateVarRequest *)p)->m_currentVal;
}
const char *UpnpStateVarRequest_get_CurrentVal_cstr(const UpnpStateVarRequest *p)
{
return (const char *)UpnpStateVarRequest_get_CurrentVal(p);
}
void UpnpStateVarRequest_set_CurrentVal(UpnpStateVarRequest *p, const DOMString s)
{
ixmlFreeDOMString(((struct SUpnpStateVarRequest *)p)->m_currentVal);
((struct SUpnpStateVarRequest *)p)->m_currentVal = ixmlCloneDOMString(s);
}

View File

@@ -1,157 +0,0 @@
/*!
* \file
*
* \brief UpnpSubscriptionRequest object implementation.
*
* \author Marcelo Roberto Jimenez
*/
#include "config.h"
#include "SubscriptionRequest.h"
#include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for memset(), strlen(), strdup() */
struct SUpnpSubscriptionRequest
{
UpnpString *m_serviceId;
UpnpString *m_UDN;
UpnpString *m_SID;
};
UpnpSubscriptionRequest *UpnpSubscriptionRequest_new()
{
struct SUpnpSubscriptionRequest *p = calloc(1, sizeof (struct SUpnpSubscriptionRequest));
p->m_serviceId = UpnpString_new();
p->m_UDN = UpnpString_new();
p->m_SID = UpnpString_new();
return (UpnpSubscriptionRequest *)p;
}
void UpnpSubscriptionRequest_delete(UpnpSubscriptionRequest *p)
{
struct SUpnpSubscriptionRequest *q = (struct SUpnpSubscriptionRequest *)p;
if (!q) return;
UpnpString_delete(q->m_serviceId);
q->m_serviceId = NULL;
UpnpString_delete(q->m_UDN);
q->m_UDN = NULL;
UpnpString_delete(q->m_SID);
q->m_SID = NULL;
free(p);
}
UpnpSubscriptionRequest *UpnpSubscriptionRequest_dup(const UpnpSubscriptionRequest *p)
{
UpnpSubscriptionRequest *q = UpnpSubscriptionRequest_new();
UpnpSubscriptionRequest_assign(q, p);
return q;
}
void UpnpSubscriptionRequest_assign(UpnpSubscriptionRequest *p, const UpnpSubscriptionRequest *q)
{
if (p != q) {
UpnpSubscriptionRequest_set_ServiceId(p, UpnpSubscriptionRequest_get_ServiceId(q));
UpnpSubscriptionRequest_set_UDN(p, UpnpSubscriptionRequest_get_UDN(q));
UpnpSubscriptionRequest_set_SID(p, UpnpSubscriptionRequest_get_SID(q));
}
}
const UpnpString *UpnpSubscriptionRequest_get_ServiceId(const UpnpSubscriptionRequest *p)
{
return ((struct SUpnpSubscriptionRequest *)p)->m_serviceId;
}
const char *UpnpSubscriptionRequest_get_ServiceId_cstr(const UpnpSubscriptionRequest *p)
{
return UpnpString_get_String(UpnpSubscriptionRequest_get_ServiceId(p));
}
void UpnpSubscriptionRequest_set_ServiceId(UpnpSubscriptionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_serviceId);
((struct SUpnpSubscriptionRequest *)p)->m_serviceId = UpnpString_dup(s);
}
void UpnpSubscriptionRequest_strcpy_ServiceId(UpnpSubscriptionRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_serviceId);
((struct SUpnpSubscriptionRequest *)p)->m_serviceId = UpnpString_new();
UpnpString_set_String(((struct SUpnpSubscriptionRequest *)p)->m_serviceId, s);
}
const UpnpString *UpnpSubscriptionRequest_get_UDN(const UpnpSubscriptionRequest *p)
{
return ((struct SUpnpSubscriptionRequest *)p)->m_UDN;
}
const char *UpnpSubscriptionRequest_get_UDN_cstr(const UpnpSubscriptionRequest *p)
{
return UpnpString_get_String(UpnpSubscriptionRequest_get_UDN(p));
}
void UpnpSubscriptionRequest_set_UDN(UpnpSubscriptionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_UDN);
((struct SUpnpSubscriptionRequest *)p)->m_UDN = UpnpString_dup(s);
}
void UpnpSubscriptionRequest_strcpy_UDN(UpnpSubscriptionRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_UDN);
((struct SUpnpSubscriptionRequest *)p)->m_UDN = UpnpString_new();
UpnpString_set_String(((struct SUpnpSubscriptionRequest *)p)->m_UDN, s);
}
const UpnpString *UpnpSubscriptionRequest_get_SID(const UpnpSubscriptionRequest *p)
{
return ((struct SUpnpSubscriptionRequest *)p)->m_SID;
}
const char *UpnpSubscriptionRequest_get_SID_cstr(const UpnpSubscriptionRequest *p)
{
return UpnpString_get_String(UpnpSubscriptionRequest_get_SID(p));
}
void UpnpSubscriptionRequest_set_SID(UpnpSubscriptionRequest *p, const UpnpString *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_SID);
((struct SUpnpSubscriptionRequest *)p)->m_SID = UpnpString_dup(s);
}
void UpnpSubscriptionRequest_strcpy_SID(UpnpSubscriptionRequest *p, const char *s)
{
UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_SID);
((struct SUpnpSubscriptionRequest *)p)->m_SID = UpnpString_new();
UpnpString_set_String(((struct SUpnpSubscriptionRequest *)p)->m_SID, s);
}

View File

@@ -1,5 +1,3 @@
/*! /*!
* \addtogroup UpnpString * \addtogroup UpnpString
* *
@@ -17,16 +15,45 @@
* \brief UpnpString object implementation. * \brief UpnpString object implementation.
*/ */
#include "config.h" #include "config.h"
#include "UpnpString.h" #include "UpnpString.h"
#include <stdlib.h> /* for calloc(), free() */ #include <stdlib.h> /* for calloc(), free() */
#include <string.h> /* for strlen(), strdup() */ #include <string.h> /* for strlen(), strdup() */
#ifdef WIN32
#define strcasecmp stricmp
#else
/* Other systems have strncasecmp */
#endif
/* strnlen() is a GNU extension. */
#if HAVE_STRNLEN
extern size_t strnlen(const char *s, size_t maxlen);
#else /* HAVE_STRNLEN */
static size_t strnlen(const char *s, size_t n)
{
const char *p = (const char *)memchr(s, 0, n);
return p ? p - s : n;
}
#endif /* HAVE_STRNLEN */
/* strndup() is a GNU extension. */
#if HAVE_STRNDUP && !defined(WIN32)
extern char *strndup(__const char *__string, size_t __n);
#else /* HAVE_STRNDUP && !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, strsize);
newstr[strsize] = 0;
return newstr;
}
#endif /* HAVE_STRNDUP && !defined(WIN32) */
/*! /*!
* \brief Internal implementation of the class UpnpString. * \brief Internal implementation of the class UpnpString.
@@ -36,16 +63,15 @@
struct SUpnpString struct SUpnpString
{ {
/*! \brief Length of the string. */ /*! \brief Length of the string. */
int m_length; size_t m_length;
/*! \brief Pointer to a dynamically allocated area that holds the NULL /*! \brief Pointer to a dynamically allocated area that holds the NULL
* terminated string. */ * terminated string. */
char *m_string; char *m_string;
}; };
UpnpString *UpnpString_new() 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)); struct SUpnpString *p = calloc(1, sizeof (struct SUpnpString));
if (p == NULL) { if (p == NULL) {
goto error_handler1; goto error_handler1;
@@ -54,7 +80,7 @@ UpnpString *UpnpString_new()
p->m_length = 0; p->m_length = 0;
#endif #endif
// This byte is zero, calloc does initialize it. /* This byte is zero, calloc does initialize it. */
p->m_string = calloc(1, 1); p->m_string = calloc(1, 1);
if (p->m_string == NULL) { if (p->m_string == NULL) {
goto error_handler2; goto error_handler2;
@@ -62,14 +88,13 @@ UpnpString *UpnpString_new()
return (UpnpString *)p; return (UpnpString *)p;
//free(p->m_string); /*free(p->m_string); */
error_handler2: error_handler2:
free(p); free(p);
error_handler1: error_handler1:
return NULL; return NULL;
} }
void UpnpString_delete(UpnpString *p) void UpnpString_delete(UpnpString *p)
{ {
struct SUpnpString *q = (struct SUpnpString *)p; struct SUpnpString *q = (struct SUpnpString *)p;
@@ -84,7 +109,6 @@ void UpnpString_delete(UpnpString *p)
free(p); free(p);
} }
UpnpString *UpnpString_dup(const UpnpString *p) UpnpString *UpnpString_dup(const UpnpString *p)
{ {
struct SUpnpString *q = calloc(1, sizeof (struct SUpnpString)); struct SUpnpString *q = calloc(1, sizeof (struct SUpnpString));
@@ -99,14 +123,13 @@ UpnpString *UpnpString_dup(const UpnpString *p)
return (UpnpString *)q; return (UpnpString *)q;
//free(q->m_string); /*free(q->m_string); */
error_handler2: error_handler2:
free(q); free(q);
error_handler1: error_handler1:
return NULL; return NULL;
} }
void UpnpString_assign(UpnpString *p, const UpnpString *q) void UpnpString_assign(UpnpString *p, const UpnpString *q)
{ {
if (p != q) { if (p != q) {
@@ -114,43 +137,70 @@ void UpnpString_assign(UpnpString *p, const UpnpString *q)
} }
} }
size_t UpnpString_get_Length(const UpnpString *p)
int UpnpString_get_Length(const UpnpString *p)
{ {
return ((struct SUpnpString *)p)->m_length; return ((struct SUpnpString *)p)->m_length;
} }
void UpnpString_set_Length(UpnpString *p, size_t n)
{
if (((struct SUpnpString *)p)->m_length > n) {
((struct SUpnpString *)p)->m_length = n;
/* No need to realloc now, will do later when needed. */
((struct SUpnpString *)p)->m_string[n] = 0;
}
}
const char *UpnpString_get_String(const UpnpString *p) const char *UpnpString_get_String(const UpnpString *p)
{ {
return ((struct SUpnpString *)p)->m_string; return ((struct SUpnpString *)p)->m_string;
} }
int UpnpString_set_String(UpnpString *p, const char *s)
void UpnpString_set_String(UpnpString *p, const char *s)
{ {
char *q = strdup(s);
if (!q) goto error_handler1;
free(((struct SUpnpString *)p)->m_string); free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = strlen(s); ((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = strdup(s); ((struct SUpnpString *)p)->m_string = q;
error_handler1:
return q != NULL;
} }
int UpnpString_set_StringN(UpnpString *p, const char *s, size_t n)
void UpnpString_set_StringN(UpnpString *p, const char *s, int n)
{ {
char *q = strndup(s, n);
if (!q) goto error_handler1;
free(((struct SUpnpString *)p)->m_string); free(((struct SUpnpString *)p)->m_string);
((struct SUpnpString *)p)->m_length = n; ((struct SUpnpString *)p)->m_length = strlen(q);
((struct SUpnpString *)p)->m_string = (char *)malloc(n+1); ((struct SUpnpString *)p)->m_string = q;
strncpy(((struct SUpnpString *)p)->m_string, s, n);
((struct SUpnpString *)p)->m_string[n] = 0;
}
error_handler1:
return q != NULL;
}
void UpnpString_clear(UpnpString *p) void UpnpString_clear(UpnpString *p)
{ {
((struct SUpnpString *)p)->m_length = 0; ((struct SUpnpString *)p)->m_length = 0;
// No need to realloc now, will do later when needed /* No need to realloc now, will do later when needed. */
((struct SUpnpString *)p)->m_string[0] = 0; ((struct SUpnpString *)p)->m_string[0] = 0;
} }
/* @} UpnpString */ int UpnpString_cmp(UpnpString *p, UpnpString *q)
{
const char *cp = UpnpString_get_String(p);
const char *cq = UpnpString_get_String(q);
return strcmp(cp, cq);
}
int UpnpString_casecmp(UpnpString *p, UpnpString *q)
{
const char *cp = UpnpString_get_String(p);
const char *cq = UpnpString_get_String(q);
return strcasecmp(cp, cq);
}
/* @} UpnpString */

File diff suppressed because it is too large Load Diff

View File

@@ -29,21 +29,23 @@
* *
******************************************************************************/ ******************************************************************************/
#include "config.h" /*!
* \file
*/
#include "config.h"
#include "ithread.h" #include "ithread.h"
#include "ixml.h" #include "ixml.h"
#include "upnp.h" #include "upnp.h"
#include "upnpdebug.h" #include "upnpdebug.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef DEBUG
/*! Mutex to synchronize all the log file opeartions in the debug mode */ /*! Mutex to synchronize all the log file opeartions in the debug mode */
static ithread_mutex_t GlobalDebugMutex; static ithread_mutex_t GlobalDebugMutex;
@@ -63,31 +65,25 @@ static const char *errFileName = "IUpnpErrFile.txt";
/*! Name of the info file */ /*! Name of the info file */
static const char *infoFileName = "IUpnpInfoFile.txt"; static const char *infoFileName = "IUpnpInfoFile.txt";
#ifdef DEBUG
int UpnpInitLog(void) int UpnpInitLog(void)
{ {
ithread_mutex_init(&GlobalDebugMutex, NULL); ithread_mutex_init(&GlobalDebugMutex, NULL);
if(DEBUG_TARGET == 1) { if (DEBUG_TARGET == 1) {
if((ErrFileHnd = fopen( errFileName, "a")) == NULL) { if ((ErrFileHnd = fopen(errFileName, "a")) == NULL) {
return -1; return -1;
} }
if((InfoFileHnd = fopen( infoFileName, "a")) == NULL) { if ((InfoFileHnd = fopen(infoFileName, "a")) == NULL) {
return -1; return -1;
} }
} }
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
void UpnpSetLogLevel(Upnp_LogLevel log_level) void UpnpSetLogLevel(Upnp_LogLevel log_level)
{ {
g_log_level = log_level; g_log_level = log_level;
} }
void UpnpCloseLog(void) void UpnpCloseLog(void)
{ {
if (DEBUG_TARGET == 1) { if (DEBUG_TARGET == 1) {
@@ -99,71 +95,56 @@ void UpnpCloseLog(void)
ithread_mutex_destroy(&GlobalDebugMutex); ithread_mutex_destroy(&GlobalDebugMutex);
} }
void UpnpSetLogFileNames(const char *ErrFileName, const char *InfoFileName)
void UpnpSetLogFileNames(
const char *ErrFileName,
const char *InfoFileName)
{ {
if (ErrFileName) { if (ErrFileName) {
errFileName = ErrFileName; errFileName = ErrFileName;
} }
if (InfoFileName) { if (InfoFileName) {
infoFileName = InfoFileName; infoFileName = InfoFileName;
} }
} }
int DebugAtThisLevel(Upnp_LogLevel DLevel, Dbg_Module Module)
int DebugAtThisLevel(
Upnp_LogLevel DLevel,
Dbg_Module Module)
{ {
int ret = DLevel <= g_log_level; int ret = DLevel <= g_log_level;
ret &= ret &=
DEBUG_ALL || DEBUG_ALL ||
(Module == SSDP && DEBUG_SSDP ) || (Module == SSDP && DEBUG_SSDP) ||
(Module == SOAP && DEBUG_SOAP ) || (Module == SOAP && DEBUG_SOAP) ||
(Module == GENA && DEBUG_GENA ) || (Module == GENA && DEBUG_GENA) ||
(Module == TPOOL && DEBUG_TPOOL) || (Module == TPOOL && DEBUG_TPOOL) ||
(Module == MSERV && DEBUG_MSERV) || (Module == MSERV && DEBUG_MSERV) ||
(Module == DOM && DEBUG_DOM ) || (Module == DOM && DEBUG_DOM) || (Module == HTTP && DEBUG_HTTP);
(Module == HTTP && DEBUG_HTTP );
return ret; return ret;
} }
void UpnpPrintf(Upnp_LogLevel DLevel,
void UpnpPrintf( Dbg_Module Module,
Upnp_LogLevel DLevel, const char *DbgFileName, int DbgLineNo, const char *FmtStr, ...)
Dbg_Module Module,
const char *DbgFileName,
int DbgLineNo,
const char *FmtStr,
...)
{ {
va_list ArgList; va_list ArgList;
if (!DebugAtThisLevel(DLevel, Module)) { if (!DebugAtThisLevel(DLevel, Module))
return; return;
}
ithread_mutex_lock(&GlobalDebugMutex); ithread_mutex_lock(&GlobalDebugMutex);
va_start(ArgList, FmtStr); va_start(ArgList, FmtStr);
if (!DEBUG_TARGET) { if (!DEBUG_TARGET) {
if (DbgFileName) { if (DbgFileName)
UpnpDisplayFileAndLine(stdout, DbgFileName, DbgLineNo); UpnpDisplayFileAndLine(stdout, DbgFileName, DbgLineNo);
}
vfprintf(stdout, FmtStr, ArgList); vfprintf(stdout, FmtStr, ArgList);
fflush(stdout); fflush(stdout);
} else if (DLevel == 0) { } else if (DLevel == 0) {
if (DbgFileName) { if (DbgFileName)
UpnpDisplayFileAndLine(ErrFileHnd, DbgFileName, DbgLineNo); UpnpDisplayFileAndLine(ErrFileHnd, DbgFileName,
} DbgLineNo);
vfprintf(ErrFileHnd, FmtStr, ArgList); vfprintf(ErrFileHnd, FmtStr, ArgList);
fflush(ErrFileHnd); fflush(ErrFileHnd);
} else { } else {
if (DbgFileName) { if (DbgFileName)
UpnpDisplayFileAndLine(InfoFileHnd, DbgFileName, DbgLineNo); UpnpDisplayFileAndLine(InfoFileHnd, DbgFileName,
} DbgLineNo);
vfprintf(InfoFileHnd, FmtStr, ArgList); vfprintf(InfoFileHnd, FmtStr, ArgList);
fflush(InfoFileHnd); fflush(InfoFileHnd);
} }
@@ -171,31 +152,23 @@ void UpnpPrintf(
ithread_mutex_unlock(&GlobalDebugMutex); ithread_mutex_unlock(&GlobalDebugMutex);
} }
FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module) FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module)
{ {
FILE *ret; FILE *ret;
if (!DebugAtThisLevel(DLevel, Module)) { if (!DebugAtThisLevel(DLevel, Module))
ret = NULL; ret = NULL;
} if (!DEBUG_TARGET)
if (!DEBUG_TARGET) {
ret = stdout; ret = stdout;
} else if (DLevel == 0) { else if (DLevel == 0)
ret = ErrFileHnd; ret = ErrFileHnd;
} else { else
ret = InfoFileHnd; ret = InfoFileHnd;
}
return ret; return ret;
} }
void UpnpDisplayFileAndLine(FILE *fd, const char *DbgFileName, int DbgLineNo)
void UpnpDisplayFileAndLine(
FILE *fd,
const char *DbgFileName,
int DbgLineNo)
{ {
#define NLINES 2 #define NLINES 2
#define MAX_LINE_SIZE 512 #define MAX_LINE_SIZE 512
@@ -205,10 +178,8 @@ void UpnpDisplayFileAndLine(
int i; int i;
/* Initialize the pointer array */ /* Initialize the pointer array */
for (i = 0; i < NLINES; i++) { for (i = 0; i < NLINES; i++)
lines[i] = buf[i]; lines[i] = buf[i];
}
/* Put the debug lines in the buffer */ /* Put the debug lines in the buffer */
sprintf(buf[0], "DEBUG - THREAD ID: 0x%lX", sprintf(buf[0], "DEBUG - THREAD ID: 0x%lX",
#ifdef WIN32 #ifdef WIN32
@@ -216,64 +187,54 @@ void UpnpDisplayFileAndLine(
#else #else
(unsigned long int)ithread_self() (unsigned long int)ithread_self()
#endif #endif
); );
if (DbgFileName) { if (DbgFileName)
sprintf(buf[1], sprintf(buf[1], "FILE: %s, LINE: %d", DbgFileName, DbgLineNo);
"FILE: %s, LINE: %d",
DbgFileName,
DbgLineNo);
}
/* Show the lines centered */ /* Show the lines centered */
UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS); UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS);
fflush(fd); fflush(fd);
} }
void UpnpDisplayBanner(FILE * fd,
void UpnpDisplayBanner( const char **lines, size_t size, size_t starLength)
FILE * fd,
const char **lines,
size_t size,
int starLength)
{ {
int leftMarginLength = starLength / 2 + 1; size_t leftMarginLength = starLength / 2 + 1;
int rightMarginLength = starLength / 2 + 1; size_t rightMarginLength = starLength / 2 + 1;
int i = 0; size_t i = 0;
int LineSize = 0; size_t LineSize = 0;
int starLengthMinus2 = starLength - 2; size_t starLengthMinus2 = starLength - 2;
char *leftMargin = ( char * )malloc( leftMarginLength ); char *leftMargin = malloc(leftMarginLength);
char *rightMargin = ( char * )malloc( rightMarginLength ); char *rightMargin = malloc(rightMarginLength);
char *stars = ( char * )malloc( starLength + 1 ); char *stars = malloc(starLength + 1);
char *currentLine = ( char * )malloc( starLength + 1 ); char *currentLine = malloc(starLength + 1);
const char *line = NULL; const char *line = NULL;
memset( stars, '*', starLength ); memset(stars, '*', starLength);
stars[starLength] = 0; stars[starLength] = 0;
memset( leftMargin, 0, leftMarginLength ); memset(leftMargin, 0, leftMarginLength);
memset( rightMargin, 0, rightMarginLength ); memset(rightMargin, 0, rightMarginLength);
fprintf( fd, "\n%s\n", stars ); fprintf(fd, "\n%s\n", stars);
for( i = 0; i < size; i++ ) { for (i = 0; i < size; i++) {
LineSize = strlen( lines[i] ); LineSize = strlen(lines[i]);
line = lines[i]; line = lines[i];
while( LineSize > starLengthMinus2 ) { while (LineSize > starLengthMinus2) {
memcpy( currentLine, line, starLengthMinus2 ); memcpy(currentLine, line, starLengthMinus2);
currentLine[starLengthMinus2] = 0; currentLine[starLengthMinus2] = 0;
fprintf( fd, "*%s*\n", currentLine ); fprintf(fd, "*%s*\n", currentLine);
LineSize -= starLengthMinus2; LineSize -= starLengthMinus2;
line += starLengthMinus2; line += starLengthMinus2;
} }
leftMarginLength = (starLengthMinus2 - LineSize)/2; leftMarginLength = (starLengthMinus2 - LineSize) / 2;
if( LineSize % 2 == 0 ) { if (LineSize % 2 == 0)
rightMarginLength = leftMarginLength; rightMarginLength = leftMarginLength;
} else { else
rightMarginLength = leftMarginLength + 1; rightMarginLength = leftMarginLength + 1;
} memset(leftMargin, ' ', leftMarginLength);
memset( leftMargin, ' ', leftMarginLength ); memset(rightMargin, ' ', rightMarginLength);
memset( rightMargin, ' ', rightMarginLength );
leftMargin[leftMarginLength] = 0; leftMargin[leftMarginLength] = 0;
rightMargin[rightMarginLength] = 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); fprintf(fd, "%s\n\n", stars);
@@ -283,46 +244,4 @@ void UpnpDisplayBanner(
free(leftMargin); free(leftMargin);
} }
void PrintThreadPoolStats(
ThreadPool *tp,
const char *DbgFileName,
int DbgLineNo,
const char *msg)
{
ThreadPoolStats stats;
ThreadPoolGetStats(tp, &stats);
UpnpPrintf(UPNP_INFO, API, DbgFileName, DbgLineNo,
"%s\n"
"High Jobs pending: %d\n"
"Med Jobs Pending: %d\n"
"Low Jobs Pending: %d\n"
"Average wait in High Q in milliseconds: %lf\n"
"Average wait in Med Q in milliseconds: %lf\n"
"Average wait in Low Q in milliseconds: %lf\n"
"Max Threads Used: %d\n"
"Worker Threads: %d\n"
"Persistent Threads: %d\n"
"Idle Threads: %d\n"
"Total Threads: %d\n"
"Total Work Time: %lf\n"
"Total Idle Time: %lf\n",
msg,
stats.currentJobsHQ,
stats.currentJobsMQ,
stats.currentJobsLQ,
stats.avgWaitHQ,
stats.avgWaitMQ,
stats.avgWaitLQ,
stats.maxThreads,
stats.workerThreads,
stats.persistentThreads,
stats.idleThreads,
stats.totalThreads,
stats.totalWorkTime,
stats.totalIdleTime);
}
#endif /* DEBUG */ #endif /* DEBUG */

View File

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

View File

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

View File

@@ -42,7 +42,6 @@
#ifdef INCLUDE_CLIENT_APIS #ifdef INCLUDE_CLIENT_APIS
#include "EventSubscribe.h"
#include "gena.h" #include "gena.h"
#include "httpparser.h" #include "httpparser.h"
#include "httpreadwrite.h" #include "httpreadwrite.h"
@@ -65,7 +64,7 @@ static void GenaAutoRenewSubscription(
IN void *input) IN void *input)
{ {
upnp_timeout *event = (upnp_timeout *) input; upnp_timeout *event = (upnp_timeout *) input;
UpnpEventSubscribe *sub_struct = (UpnpEventSubscribe *)event->Event; struct Upnp_Event_Subscribe *sub_struct = (struct Upnp_Event_Subscribe *)event->Event;
void *cookie; void *cookie;
Upnp_FunPtr callback_fun; Upnp_FunPtr callback_fun;
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
@@ -73,21 +72,23 @@ static void GenaAutoRenewSubscription(
int eventType = 0; int eventType = 0;
int timeout = 0; int timeout = 0;
int errCode = 0; int errCode = 0;
UpnpString *tmpSID = UpnpString_new();
if (AUTO_RENEW_TIME == 0) { if (AUTO_RENEW_TIME == 0) {
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUB EXPIRED"); UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUB EXPIRED");
UpnpEventSubscribe_set_ErrCode(sub_struct, UPNP_E_SUCCESS); sub_struct->ErrCode = UPNP_E_SUCCESS;
send_callback = 1; send_callback = 1;
eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED; eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED;
} else { } else {
UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA AUTO RENEW"); UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA AUTO RENEW");
timeout = UpnpEventSubscribe_get_TimeOut(sub_struct); timeout = sub_struct->TimeOut;
UpnpString_set_String(tmpSID, sub_struct->Sid);
errCode = genaRenewSubscription( errCode = genaRenewSubscription(
event->handle, event->handle,
UpnpEventSubscribe_get_SID(sub_struct), tmpSID,
&timeout); &timeout);
UpnpEventSubscribe_set_ErrCode(sub_struct, errCode); sub_struct->ErrCode = errCode;
UpnpEventSubscribe_set_TimeOut(sub_struct, timeout); sub_struct->TimeOut = timeout;
if (errCode != UPNP_E_SUCCESS && if (errCode != UPNP_E_SUCCESS &&
errCode != GENA_E_BAD_SID && errCode != GENA_E_BAD_SID &&
errCode != GENA_E_BAD_HANDLE) { errCode != GENA_E_BAD_HANDLE) {
@@ -105,7 +106,7 @@ static void GenaAutoRenewSubscription(
} }
UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "HANDLE IS VALID"); UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "HANDLE IS VALID");
// make callback /* make callback */
callback_fun = handle_info->Callback; callback_fun = handle_info->Callback;
cookie = handle_info->Cookie; cookie = handle_info->Cookie;
HandleUnlock(); HandleUnlock();
@@ -115,6 +116,7 @@ static void GenaAutoRenewSubscription(
free_upnp_timeout(event); free_upnp_timeout(event);
end_function: end_function:
UpnpString_delete(tmpSID);
return; return;
} }
@@ -133,17 +135,19 @@ static int ScheduleGenaAutoRenew(
/*! [in] Subscription being renewed. */ /*! [in] Subscription being renewed. */
IN ClientSubscription *sub) IN ClientSubscription *sub)
{ {
UpnpEventSubscribe *RenewEventStruct = NULL; struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
upnp_timeout *RenewEvent = NULL; upnp_timeout *RenewEvent = NULL;
int return_code = GENA_SUCCESS; int return_code = GENA_SUCCESS;
ThreadPoolJob job; ThreadPoolJob job;
const UpnpString *tmpSID = UpnpClientSubscription_get_SID(sub);
const UpnpString *tmpEventURL = UpnpClientSubscription_get_EventURL(sub);
if (TimeOut == UPNP_INFINITE) { if (TimeOut == UPNP_INFINITE) {
return_code = GENA_SUCCESS; return_code = GENA_SUCCESS;
goto end_function; goto end_function;
} }
RenewEventStruct = UpnpEventSubscribe_new(); RenewEventStruct = (struct Upnp_Event_Subscribe *)malloc(sizeof (struct Upnp_Event_Subscribe));
if (RenewEventStruct == NULL) { if (RenewEventStruct == NULL) {
return_code = UPNP_E_OUTOF_MEMORY; return_code = UPNP_E_OUTOF_MEMORY;
goto end_function; goto end_function;
@@ -156,13 +160,14 @@ static int ScheduleGenaAutoRenew(
goto end_function; goto end_function;
} }
// schedule expire event /* schedule expire event */
UpnpEventSubscribe_set_ErrCode(RenewEventStruct, UPNP_E_SUCCESS); RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
UpnpEventSubscribe_set_TimeOut(RenewEventStruct, TimeOut); RenewEventStruct->TimeOut = TimeOut;
UpnpEventSubscribe_set_SID(RenewEventStruct, GenlibClientSubscription_get_SID(sub)); strcpy(RenewEventStruct->Sid, UpnpString_get_String(tmpSID));
UpnpEventSubscribe_set_PublisherUrl(RenewEventStruct, GenlibClientSubscription_get_EventURL(sub)); 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->handle = client_handle;
RenewEvent->Event = RenewEventStruct; RenewEvent->Event = RenewEventStruct;
@@ -170,7 +175,7 @@ static int ScheduleGenaAutoRenew(
TPJobSetFreeFunction(&job, (free_routine)free_upnp_timeout); TPJobSetFreeFunction(&job, (free_routine)free_upnp_timeout);
TPJobSetPriority(&job, MED_PRIORITY); TPJobSetPriority(&job, MED_PRIORITY);
// Schedule the job /* Schedule the job */
return_code = TimerThreadSchedule( return_code = TimerThreadSchedule(
&gTimerThread, &gTimerThread,
TimeOut - AUTO_RENEW_TIME, TimeOut - AUTO_RENEW_TIME,
@@ -183,12 +188,11 @@ static int ScheduleGenaAutoRenew(
goto end_function; goto end_function;
} }
GenlibClientSubscription_set_RenewEventId(sub, RenewEvent->eventId); UpnpClientSubscription_set_RenewEventId(sub, RenewEvent->eventId);
return_code = GENA_SUCCESS; return_code = GENA_SUCCESS;
end_function: end_function:
return return_code; return return_code;
} }
@@ -211,7 +215,7 @@ static int gena_unsubscribe(
uri_type dest_url; uri_type dest_url;
membuffer request; membuffer request;
// parse url /* parse url */
return_code = http_FixStrUrl( return_code = http_FixStrUrl(
UpnpString_get_String(url), UpnpString_get_String(url),
UpnpString_get_Length(url), UpnpString_get_Length(url),
@@ -220,7 +224,7 @@ static int gena_unsubscribe(
return return_code; return return_code;
} }
// make request msg /* make request msg */
membuffer_init(&request); membuffer_init(&request);
request.size_inc = 30; request.size_inc = 30;
return_code = http_MakeMessage( return_code = http_MakeMessage(
@@ -229,14 +233,14 @@ static int gena_unsubscribe(
HTTPMETHOD_UNSUBSCRIBE, &dest_url, HTTPMETHOD_UNSUBSCRIBE, &dest_url,
"SID: ", UpnpString_get_String(sid)); "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) { if (return_code != 0) {
membuffer_destroy(&request); membuffer_destroy(&request);
return return_code; return return_code;
} }
// send request and get reply /* send request and get reply */
return_code = http_RequestAndResponse( return_code = http_RequestAndResponse(
&dest_url, request.buf, request.length, &dest_url, request.buf, request.length,
HTTPMETHOD_UNSUBSCRIBE, HTTP_DEFAULT_TIMEOUT, response); HTTPMETHOD_UNSUBSCRIBE, HTTP_DEFAULT_TIMEOUT, response);
@@ -282,7 +286,7 @@ static int gena_subscribe(
UpnpString_clear(sid); UpnpString_clear(sid);
// request timeout to string /* request timeout to string */
if (timeout == NULL) { if (timeout == NULL) {
timeout = &local_timeout; timeout = &local_timeout;
} }
@@ -294,7 +298,7 @@ static int gena_subscribe(
sprintf(timeout_str, "%d", *timeout); sprintf(timeout_str, "%d", *timeout);
} }
// parse url /* parse url */
return_code = http_FixStrUrl( return_code = http_FixStrUrl(
UpnpString_get_String(url), UpnpString_get_String(url),
UpnpString_get_Length(url), UpnpString_get_Length(url),
@@ -303,11 +307,11 @@ static int gena_subscribe(
return return_code; return return_code;
} }
// make request msg /* make request msg */
membuffer_init(&request); membuffer_init(&request);
request.size_inc = 30; request.size_inc = 30;
if (renewal_sid) { if (renewal_sid) {
// renew subscription /* renew subscription */
return_code = http_MakeMessage( return_code = http_MakeMessage(
&request, 1, 1, &request, 1, 1,
"q" "ssc" "sscc", "q" "ssc" "sscc",
@@ -315,19 +319,19 @@ static int gena_subscribe(
"SID: ", UpnpString_get_String(renewal_sid), "SID: ", UpnpString_get_String(renewal_sid),
"TIMEOUT: Second-", timeout_str ); "TIMEOUT: Second-", timeout_str );
} else { } else {
// subscribe /* subscribe */
if( dest_url.hostport.IPaddress.ss_family == AF_INET6 ) { if (dest_url.hostport.IPaddress.ss_family == AF_INET6) {
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&dest_url.hostport.IPaddress; struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&dest_url.hostport.IPaddress;
return_code = http_MakeMessage( return_code = http_MakeMessage(
&request, 1, 1, &request, 1, 1,
"q" "sssdsc" "sc" "sscc", "q" "sssdsc" "sc" "sscc",
HTTPMETHOD_SUBSCRIBE, &dest_url, HTTPMETHOD_SUBSCRIBE, &dest_url,
"CALLBACK: <http://[", "CALLBACK: <http://[",
((IN6_IS_ADDR_LINKLOCAL(DestAddr6))||(strlen(gIF_IPV6_ULA_GUA) == 0 ))? (IN6_IS_ADDR_LINKLOCAL(&DestAddr6->sin6_addr) || strlen(gIF_IPV6_ULA_GUA) == 0) ?
gIF_IPV6 : gIF_IPV6_ULA_GUA, gIF_IPV6 : gIF_IPV6_ULA_GUA,
"]:", LOCAL_PORT_V6, "/>", "]:", LOCAL_PORT_V6, "/>",
"NT: upnp:event", "NT: upnp:event",
"TIMEOUT: Second-", timeout_str ); "TIMEOUT: Second-", timeout_str);
} else { } else {
return_code = http_MakeMessage( return_code = http_MakeMessage(
&request, 1, 1, &request, 1, 1,
@@ -342,7 +346,7 @@ static int gena_subscribe(
return return_code; return return_code;
} }
// send request and get reply /* send request and get reply */
return_code = http_RequestAndResponse(&dest_url, request.buf, return_code = http_RequestAndResponse(&dest_url, request.buf,
request.length, request.length,
HTTPMETHOD_SUBSCRIBE, HTTPMETHOD_SUBSCRIBE,
@@ -361,7 +365,7 @@ static int gena_subscribe(
return UPNP_E_SUBSCRIBE_UNACCEPTED; return UPNP_E_SUBSCRIBE_UNACCEPTED;
} }
// get SID and TIMEOUT /* get SID and TIMEOUT */
if (httpmsg_find_hdr(&response.msg, HDR_SID, &sid_hdr) == NULL || if (httpmsg_find_hdr(&response.msg, HDR_SID, &sid_hdr) == NULL ||
sid_hdr.length == 0 || sid_hdr.length == 0 ||
httpmsg_find_hdr( &response.msg, HDR_TIMEOUT, &timeout_hdr ) == NULL || httpmsg_find_hdr( &response.msg, HDR_TIMEOUT, &timeout_hdr ) == NULL ||
@@ -371,10 +375,10 @@ static int gena_subscribe(
return UPNP_E_BAD_RESPONSE; return UPNP_E_BAD_RESPONSE;
} }
// save timeout /* save timeout */
parse_ret = matchstr(timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0", timeout); parse_ret = matchstr(timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0", timeout);
if (parse_ret == PARSE_OK) { if (parse_ret == PARSE_OK) {
// nothing to do /* nothing to do */
} else if (memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) { } else if (memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
*timeout = -1; *timeout = -1;
} else { } else {
@@ -383,7 +387,7 @@ static int gena_subscribe(
return UPNP_E_BAD_RESPONSE; return UPNP_E_BAD_RESPONSE;
} }
// save SID /* save SID */
UpnpString_set_StringN(sid, sid_hdr.buf, sid_hdr.length); UpnpString_set_StringN(sid, sid_hdr.buf, sid_hdr.length);
if (UpnpString_get_String(sid) == NULL) { if (UpnpString_get_String(sid) == NULL) {
httpmsg_destroy(&response.msg); httpmsg_destroy(&response.msg);
@@ -398,7 +402,7 @@ static int gena_subscribe(
int genaUnregisterClient(UpnpClient_Handle client_handle) int genaUnregisterClient(UpnpClient_Handle client_handle)
{ {
ClientSubscription *sub_copy = GenlibClientSubscription_new(); ClientSubscription *sub_copy = UpnpClientSubscription_new();
int return_code = UPNP_E_SUCCESS; int return_code = UPNP_E_SUCCESS;
struct Handle_Info *handle_info = NULL; struct Handle_Info *handle_info = NULL;
http_parser_t response; http_parser_t response;
@@ -415,16 +419,16 @@ int genaUnregisterClient(UpnpClient_Handle client_handle)
return_code = UPNP_E_SUCCESS; return_code = UPNP_E_SUCCESS;
break; break;
} }
GenlibClientSubscription_assign(sub_copy, handle_info->ClientSubList); UpnpClientSubscription_assign(sub_copy, handle_info->ClientSubList);
RemoveClientSubClientSID( RemoveClientSubClientSID(
&handle_info->ClientSubList, &handle_info->ClientSubList,
GenlibClientSubscription_get_SID(sub_copy)); UpnpClientSubscription_get_SID(sub_copy));
HandleUnlock(); HandleUnlock();
return_code = gena_unsubscribe( return_code = gena_unsubscribe(
GenlibClientSubscription_get_EventURL(sub_copy), UpnpClientSubscription_get_EventURL(sub_copy),
GenlibClientSubscription_get_ActualSID(sub_copy), UpnpClientSubscription_get_ActualSID(sub_copy),
&response); &response);
if (return_code == 0) { if (return_code == 0) {
httpmsg_destroy(&response.msg); httpmsg_destroy(&response.msg);
@@ -436,7 +440,7 @@ int genaUnregisterClient(UpnpClient_Handle client_handle)
HandleUnlock(); HandleUnlock();
exit_function: exit_function:
GenlibClientSubscription_delete(sub_copy); UpnpClientSubscription_delete(sub_copy);
return return_code; return return_code;
} }
@@ -449,10 +453,10 @@ int genaUnSubscribe(
ClientSubscription *sub = NULL; ClientSubscription *sub = NULL;
int return_code = GENA_SUCCESS; int return_code = GENA_SUCCESS;
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
ClientSubscription *sub_copy = GenlibClientSubscription_new(); ClientSubscription *sub_copy = UpnpClientSubscription_new();
http_parser_t response; http_parser_t response;
// validate handle and sid /* validate handle and sid */
HandleLock(); HandleLock();
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock(); HandleUnlock();
@@ -465,12 +469,12 @@ int genaUnSubscribe(
return_code = GENA_E_BAD_SID; return_code = GENA_E_BAD_SID;
goto exit_function; goto exit_function;
} }
GenlibClientSubscription_assign(sub_copy, sub); UpnpClientSubscription_assign(sub_copy, sub);
HandleUnlock(); HandleUnlock();
return_code = gena_unsubscribe( return_code = gena_unsubscribe(
GenlibClientSubscription_get_EventURL(sub_copy), UpnpClientSubscription_get_EventURL(sub_copy),
GenlibClientSubscription_get_ActualSID(sub_copy), UpnpClientSubscription_get_ActualSID(sub_copy),
&response); &response);
if (return_code == 0) { if (return_code == 0) {
httpmsg_destroy(&response.msg); httpmsg_destroy(&response.msg);
@@ -487,7 +491,7 @@ int genaUnSubscribe(
HandleUnlock(); HandleUnlock();
exit_function: exit_function:
GenlibClientSubscription_delete(sub_copy); UpnpClientSubscription_delete(sub_copy);
return return_code; return return_code;
} }
#endif /* INCLUDE_CLIENT_APIS */ #endif /* INCLUDE_CLIENT_APIS */
@@ -501,7 +505,7 @@ int genaSubscribe(
UpnpString *out_sid) UpnpString *out_sid)
{ {
int return_code = GENA_SUCCESS; int return_code = GENA_SUCCESS;
ClientSubscription *newSubscription = GenlibClientSubscription_new(); ClientSubscription *newSubscription = UpnpClientSubscription_new();
uuid_upnp uid; uuid_upnp uid;
Upnp_SID temp_sid; Upnp_SID temp_sid;
Upnp_SID temp_sid2; Upnp_SID temp_sid2;
@@ -514,7 +518,7 @@ int genaSubscribe(
UpnpString_clear(out_sid); UpnpString_clear(out_sid);
HandleReadLock(); HandleReadLock();
// validate handle /* validate handle */
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock(); HandleUnlock();
@@ -522,7 +526,7 @@ int genaSubscribe(
} }
HandleUnlock(); HandleUnlock();
// subscribe /* subscribe */
SubscribeLock(); SubscribeLock();
return_code = gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID); return_code = gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID);
HandleLock(); HandleLock();
@@ -538,35 +542,35 @@ int genaSubscribe(
goto error_handler; goto error_handler;
} }
// generate client SID /* generate client SID */
uuid_create(&uid ); uuid_create(&uid );
uuid_unpack(&uid, temp_sid); uuid_unpack(&uid, temp_sid);
sprintf(temp_sid2, "uuid:%s", temp_sid); sprintf(temp_sid2, "uuid:%s", temp_sid);
UpnpString_set_String(out_sid, temp_sid2); UpnpString_set_String(out_sid, temp_sid2);
// create event url /* create event url */
UpnpString_assign(EventURL, PublisherURL); UpnpString_assign(EventURL, PublisherURL);
// fill subscription /* fill subscription */
if (newSubscription == NULL) { if (newSubscription == NULL) {
return_code = UPNP_E_OUTOF_MEMORY; return_code = UPNP_E_OUTOF_MEMORY;
goto error_handler; goto error_handler;
} }
GenlibClientSubscription_set_RenewEventId(newSubscription, -1); UpnpClientSubscription_set_RenewEventId(newSubscription, -1);
GenlibClientSubscription_set_SID(newSubscription, out_sid); UpnpClientSubscription_set_SID(newSubscription, out_sid);
GenlibClientSubscription_set_ActualSID(newSubscription, ActualSID); UpnpClientSubscription_set_ActualSID(newSubscription, ActualSID);
GenlibClientSubscription_set_EventURL(newSubscription, EventURL); UpnpClientSubscription_set_EventURL(newSubscription, EventURL);
GenlibClientSubscription_set_Next(newSubscription, handle_info->ClientSubList); UpnpClientSubscription_set_Next(newSubscription, handle_info->ClientSubList);
handle_info->ClientSubList = newSubscription; handle_info->ClientSubList = newSubscription;
// schedule expiration event /* schedule expiration event */
return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, newSubscription); return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, newSubscription);
error_handler: error_handler:
if (return_code != UPNP_E_SUCCESS) { if (return_code != UPNP_E_SUCCESS) {
UpnpString_delete(ActualSID); UpnpString_delete(ActualSID);
UpnpString_delete(EventURL); UpnpString_delete(EventURL);
GenlibClientSubscription_delete(newSubscription); UpnpClientSubscription_delete(newSubscription);
} }
HandleUnlock(); HandleUnlock();
SubscribeUnlock(); SubscribeUnlock();
@@ -583,14 +587,14 @@ int genaRenewSubscription(
{ {
int return_code = GENA_SUCCESS; int return_code = GENA_SUCCESS;
ClientSubscription *sub = NULL; ClientSubscription *sub = NULL;
ClientSubscription *sub_copy = GenlibClientSubscription_new(); ClientSubscription *sub_copy = UpnpClientSubscription_new();
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
UpnpString *ActualSID = UpnpString_new(); UpnpString *ActualSID = UpnpString_new();
ThreadPoolJob tempJob; ThreadPoolJob tempJob;
HandleLock(); HandleLock();
// validate handle and sid /* validate handle and sid */
if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
HandleUnlock(); HandleUnlock();
@@ -606,25 +610,25 @@ int genaRenewSubscription(
goto exit_function; goto exit_function;
} }
// remove old events /* remove old events */
if (TimerThreadRemove( if (TimerThreadRemove(
&gTimerThread, &gTimerThread,
GenlibClientSubscription_get_RenewEventId(sub), UpnpClientSubscription_get_RenewEventId(sub),
&tempJob) == 0 ) { &tempJob) == 0 ) {
free_upnp_timeout((upnp_timeout *)tempJob.arg); free_upnp_timeout((upnp_timeout *)tempJob.arg);
} }
UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "REMOVED AUTO RENEW EVENT"); UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "REMOVED AUTO RENEW EVENT");
GenlibClientSubscription_set_RenewEventId(sub, -1); UpnpClientSubscription_set_RenewEventId(sub, -1);
GenlibClientSubscription_assign(sub_copy, sub); UpnpClientSubscription_assign(sub_copy, sub);
HandleUnlock(); HandleUnlock();
return_code = gena_subscribe( return_code = gena_subscribe(
GenlibClientSubscription_get_EventURL(sub_copy), UpnpClientSubscription_get_EventURL(sub_copy),
TimeOut, TimeOut,
GenlibClientSubscription_get_ActualSID(sub_copy), UpnpClientSubscription_get_ActualSID(sub_copy),
ActualSID); ActualSID);
HandleLock(); HandleLock();
@@ -635,17 +639,17 @@ int genaRenewSubscription(
goto exit_function; goto exit_function;
} }
// we just called GetHandleInfo, so we don't check for return value /* we just called GetHandleInfo, so we don't check for return value */
//GetHandleInfo(client_handle, &handle_info); /*GetHandleInfo(client_handle, &handle_info); */
if (return_code != UPNP_E_SUCCESS) { if (return_code != UPNP_E_SUCCESS) {
// network failure (remove client sub) /* network failure (remove client sub) */
RemoveClientSubClientSID(&handle_info->ClientSubList, in_sid); RemoveClientSubClientSID(&handle_info->ClientSubList, in_sid);
free_client_subscription(sub_copy); free_client_subscription(sub_copy);
HandleUnlock(); HandleUnlock();
goto exit_function; goto exit_function;
} }
// get subscription /* get subscription */
sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid); sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid);
if (sub == NULL) { if (sub == NULL) {
free_client_subscription(sub_copy); free_client_subscription(sub_copy);
@@ -654,22 +658,22 @@ int genaRenewSubscription(
goto exit_function; goto exit_function;
} }
// store actual sid /* store actual sid */
GenlibClientSubscription_set_ActualSID(sub, ActualSID); UpnpClientSubscription_set_ActualSID(sub, ActualSID);
// start renew subscription timer /* start renew subscription timer */
return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, sub); return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, sub);
if (return_code != GENA_SUCCESS) { if (return_code != GENA_SUCCESS) {
RemoveClientSubClientSID( RemoveClientSubClientSID(
&handle_info->ClientSubList, &handle_info->ClientSubList,
GenlibClientSubscription_get_SID(sub)); UpnpClientSubscription_get_SID(sub));
} }
free_client_subscription(sub_copy); free_client_subscription(sub_copy);
HandleUnlock(); HandleUnlock();
exit_function: exit_function:
UpnpString_delete(ActualSID); UpnpString_delete(ActualSID);
GenlibClientSubscription_delete(sub_copy); UpnpClientSubscription_delete(sub_copy);
return return_code; return return_code;
} }
@@ -678,7 +682,7 @@ void gena_process_notification_event(
SOCKINFO *info, SOCKINFO *info,
http_message_t *event) http_message_t *event)
{ {
UpnpEvent *event_struct = UpnpEvent_new(); struct Upnp_Event event_struct;
IXML_Document *ChangedVars = NULL; IXML_Document *ChangedVars = NULL;
int eventKey; int eventKey;
token sid; token sid;
@@ -687,13 +691,14 @@ void gena_process_notification_event(
void *cookie; void *cookie;
Upnp_FunPtr callback; Upnp_FunPtr callback;
UpnpClient_Handle client_handle; UpnpClient_Handle client_handle;
const UpnpString *tmpSID = NULL;
memptr sid_hdr; memptr sid_hdr;
memptr nt_hdr, memptr nt_hdr,
nts_hdr; nts_hdr;
memptr seq_hdr; memptr seq_hdr;
// get SID /* get SID */
if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) { if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) {
error_respond(info, HTTP_PRECONDITION_FAILED, event); error_respond(info, HTTP_PRECONDITION_FAILED, event);
goto exit_function; goto exit_function;
@@ -701,28 +706,28 @@ void gena_process_notification_event(
sid.buff = sid_hdr.buf; sid.buff = sid_hdr.buf;
sid.size = sid_hdr.length; sid.size = sid_hdr.length;
// get event key /* get event key */
if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL || if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL ||
matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) { matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) {
error_respond( info, HTTP_BAD_REQUEST, event ); error_respond( info, HTTP_BAD_REQUEST, event );
goto exit_function; goto exit_function;
} }
// get NT and NTS headers /* get NT and NTS headers */
if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL || if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL ||
httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) { httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) {
error_respond( info, HTTP_BAD_REQUEST, event ); error_respond( info, HTTP_BAD_REQUEST, event );
goto exit_function; goto exit_function;
} }
// verify NT and NTS headers /* verify NT and NTS headers */
if (memptr_cmp(&nt_hdr, "upnp:event") != 0 || if (memptr_cmp(&nt_hdr, "upnp:event") != 0 ||
memptr_cmp(&nts_hdr, "upnp:propchange") != 0) { memptr_cmp(&nts_hdr, "upnp:propchange") != 0) {
error_respond(info, HTTP_PRECONDITION_FAILED, event); error_respond(info, HTTP_PRECONDITION_FAILED, event);
goto exit_function; goto exit_function;
} }
// parse the content (should be XML) /* parse the content (should be XML) */
if (!has_xml_content_type(event) || if (!has_xml_content_type(event) ||
event->msg.length == 0 || event->msg.length == 0 ||
ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) { ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) {
@@ -732,28 +737,28 @@ void gena_process_notification_event(
HandleLock(); HandleLock();
// get client info /* get client info */
if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) { if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
error_respond(info, HTTP_PRECONDITION_FAILED, event); error_respond(info, HTTP_PRECONDITION_FAILED, event);
HandleUnlock(); HandleUnlock();
goto exit_function; goto exit_function;
} }
// get subscription based on SID /* get subscription based on SID */
subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid); subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
if (subscription == NULL) { if (subscription == NULL) {
if (eventKey == 0) { if (eventKey == 0) {
// wait until we've finished processing a subscription /* wait until we've finished processing a subscription */
// (if we are in the middle) /* (if we are in the middle) */
// this is to avoid mistakenly rejecting the first event if we /* this is to avoid mistakenly rejecting the first event if we */
// receive it before the subscription response /* receive it before the subscription response */
HandleUnlock(); HandleUnlock();
// try and get Subscription Lock /* try and get Subscription Lock */
// (in case we are in the process of subscribing) /* (in case we are in the process of subscribing) */
SubscribeLock(); SubscribeLock();
// get HandleLock again /* get HandleLock again */
HandleLock(); HandleLock();
if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) { if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
@@ -779,29 +784,29 @@ void gena_process_notification_event(
} }
} }
// success /* success */
error_respond(info, HTTP_OK, event); error_respond(info, HTTP_OK, event);
// fill event struct /* fill event struct */
UpnpEvent_set_EventKey(event_struct, eventKey); tmpSID = UpnpClientSubscription_get_SID(subscription);
UpnpEvent_set_ChangedVariables(event_struct, ChangedVars); strcpy(event_struct.Sid, UpnpString_get_String(tmpSID));
UpnpEvent_set_SID(event_struct, GenlibClientSubscription_get_SID(subscription)); event_struct.EventKey = eventKey;
event_struct.ChangedVariables = ChangedVars;
// copy callback /* copy callback */
callback = handle_info->Callback; callback = handle_info->Callback;
cookie = handle_info->Cookie; cookie = handle_info->Cookie;
HandleUnlock(); HandleUnlock();
// make callback with event struct /* make callback with event struct */
// In future, should find a way of mainting /* In future, should find a way of mainting */
// that the handle is not unregistered in the middle of a /* that the handle is not unregistered in the middle of a */
// callback /* callback */
callback(UPNP_EVENT_RECEIVED, event_struct, cookie); callback(UPNP_EVENT_RECEIVED, &event_struct, cookie);
exit_function: exit_function:
ixmlDocument_free(ChangedVars); ixmlDocument_free(ChangedVars);
UpnpEvent_delete(event_struct);
} }

View File

@@ -29,19 +29,15 @@
* *
******************************************************************************/ ******************************************************************************/
/*! /*!
* \file * \file
*/ */
#include "config.h" #include "config.h"
#if EXCLUDE_GENA == 0 #if EXCLUDE_GENA == 0
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
#include "gena.h" #include "gena.h"
#include "httpparser.h" #include "httpparser.h"
#include "httpreadwrite.h" #include "httpreadwrite.h"
@@ -53,7 +49,6 @@
#include "upnpapi.h" #include "upnpapi.h"
#include "uuid.h" #include "uuid.h"
/*! /*!
* \brief Unregisters a device. * \brief Unregisters a device.
* *
@@ -81,7 +76,6 @@ int genaUnregisterDevice(
return ret; return ret;
} }
/*! /*!
* \brief Generates XML property set for notifications. * \brief Generates XML property set for notifications.
* *
@@ -102,7 +96,7 @@ static int GeneratePropertySet(
{ {
char *buffer; char *buffer;
int counter = 0; int counter = 0;
int size = 0; size_t size = 0;
int temp_counter = 0; int temp_counter = 0;
/*size += strlen(XML_VERSION);*/ /*size += strlen(XML_VERSION);*/
@@ -116,9 +110,8 @@ static int GeneratePropertySet(
} }
buffer = (char *)malloc(size + 1); buffer = (char *)malloc(size + 1);
if (buffer == NULL) { if (buffer == NULL)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
}
memset(buffer, 0, size + 1); memset(buffer, 0, size + 1);
/* /*
strcpy(buffer,XML_VERSION); strcpy(buffer,XML_VERSION);
@@ -140,7 +133,6 @@ static int GeneratePropertySet(
return XML_SUCCESS; return XML_SUCCESS;
} }
/*! /*!
* \brief Frees memory used in notify_threads if the reference count is 0, * \brief Frees memory used in notify_threads if the reference count is 0,
* otherwise decrements the refrence count. * otherwise decrements the refrence count.
@@ -160,7 +152,6 @@ static void free_notify_struct(
free(input); free(input);
} }
/*! /*!
* \brief Sends the notify message and returns a reply. * \brief Sends the notify message and returns a reply.
* *
@@ -178,73 +169,69 @@ static UPNP_INLINE int notify_send_and_recv(
/*! [out] The response from the control point. */ /*! [out] The response from the control point. */
http_parser_t *response) http_parser_t *response)
{ {
uri_type url; uri_type url;
int conn_fd; SOCKET conn_fd;
membuffer start_msg; membuffer start_msg;
int ret_code; int ret_code;
int err_code; int err_code;
int timeout; int timeout;
SOCKINFO info; SOCKINFO info;
const char *CRLF = "\r\n";
// connect /* connect */
UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__, UpnpPrintf(UPNP_ALL, GENA, __FILE__, __LINE__,
"gena notify to: %.*s\n", "gena notify to: %.*s\n",
(int)destination_url->hostport.text.size, (int)destination_url->hostport.text.size,
destination_url->hostport.text.buff ); destination_url->hostport.text.buff);
conn_fd = http_Connect( destination_url, &url ); conn_fd = http_Connect(destination_url, &url);
if( conn_fd < 0 ) { if (conn_fd < 0)
return conn_fd; // return UPNP error /* return UPNP error */
} 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 */
membuffer_init(&start_msg);
if (http_MakeMessage(
&start_msg, 1, 1,
"q" "s",
HTTPMETHOD_NOTIFY, &url,
mid_msg->buf) != 0) {
membuffer_destroy(&start_msg);
sock_destroy(&info, SD_BOTH);
return UPNP_E_OUTOF_MEMORY;
}
timeout = 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),
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);
if( ( ret_code = sock_init( &info, conn_fd ) ) != 0 ) { return UPNP_E_SUCCESS;
sock_destroy( &info, SD_BOTH );
return ret_code;
}
// make start line and HOST header
membuffer_init( &start_msg );
if (http_MakeMessage(
&start_msg, 1, 1,
"q" "s",
HTTPMETHOD_NOTIFY, &url,
mid_msg->buf ) != 0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
return UPNP_E_OUTOF_MEMORY;
}
timeout = HTTP_DEFAULT_TIMEOUT;
// send msg (note +1 for propertyset; null-terminator is also sent)
if( ( ret_code = http_SendMessage( &info, &timeout,
"bb",
start_msg.buf, start_msg.length,
propertySet,
strlen( propertySet ) + 1 ) ) !=
0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
return ret_code;
}
if( ( ret_code = http_RecvMessage( &info, response,
HTTPMETHOD_NOTIFY, &timeout,
&err_code ) ) != 0 ) {
membuffer_destroy( &start_msg );
sock_destroy( &info, SD_BOTH );
httpmsg_destroy( &response->msg );
return ret_code;
}
sock_destroy( &info, SD_BOTH ); //should shutdown completely
//when closing socket
// sock_destroy( &info,SD_RECEIVE);
membuffer_destroy( &start_msg );
return UPNP_E_SUCCESS;
} }
/*! /*!
* \brief Function to Notify a particular subscription of a particular event. * \brief Function to Notify a particular subscription of a particular event.
* *
@@ -264,55 +251,47 @@ static int genaNotify(
/*! [in] subscription to be Notified, assumes this is valid for life of function. */ /*! [in] subscription to be Notified, assumes this is valid for life of function. */
subscription *sub) subscription *sub)
{ {
int i; size_t i;
membuffer mid_msg; membuffer mid_msg;
membuffer endmsg; membuffer endmsg;
uri_type *url; uri_type *url;
http_parser_t response; http_parser_t response;
int return_code = -1; int return_code = -1;
membuffer_init( &mid_msg ); 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,
"s" "ssc" "sdcc",
headers,
"SID: ", sub->sid,
"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++) {
url = &sub->DeliveryURLs.parsedURLs[i];
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)
return_code = GENA_SUCCESS;
else {
if (response.msg.status_code == HTTP_PRECONDITION_FAILED)
/*Invalid SID gets removed */
return_code = GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;
else
return_code = GENA_E_NOTIFY_UNACCEPTED;
}
httpmsg_destroy(&response.msg);
}
// make 'end' msg (the part that won't vary with the destination) return return_code;
endmsg.size_inc = 30;
if( http_MakeMessage(
&mid_msg, 1, 1,
"s" "ssc" "sdcc",
headers,
"SID: ", sub->sid,
"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++ ) {
url = &sub->DeliveryURLs.parsedURLs[i];
if( ( return_code = notify_send_and_recv( url,
&mid_msg, propertySet,
&response ) ) ==
UPNP_E_SUCCESS ) {
break;
}
}
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
return_code = GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;
} else {
return_code = GENA_E_NOTIFY_UNACCEPTED;
}
}
httpmsg_destroy( &response.msg );
}
return return_code;
} }
@@ -328,80 +307,81 @@ static void genaNotifyThread(
/*! [in] notify thread structure containing all the headers and property set info. */ /*! [in] notify thread structure containing all the headers and property set info. */
void *input) void *input)
{ {
subscription *sub; subscription *sub;
service_info *service; service_info *service;
subscription sub_copy; subscription sub_copy;
notify_thread_struct *in = ( notify_thread_struct * ) input; notify_thread_struct *in = (notify_thread_struct *) input;
int return_code; int return_code;
struct Handle_Info *handle_info; struct Handle_Info *handle_info;
ThreadPoolJob job; ThreadPoolJob job;
HandleReadLock(); /* This should be a HandleLock and not a HandleReadLock otherwise if there
//validate context * is a lot of notifications, then multiple threads will acquire a read
* lock and the thread which sends the notification will be blocked forever
* on the HandleLock at the end of this function. */
/*HandleReadLock(); */
HandleLock();
/* validate context */
if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) { if (GetHandleInfo(in->device_handle, &handle_info) != HND_DEVICE) {
free_notify_struct( in ); free_notify_struct(in);
HandleUnlock(); HandleUnlock();
return; return;
} }
if( ( ( service = FindServiceId( &handle_info->ServiceTable, if (!(service = FindServiceId(&handle_info->ServiceTable, in->servId, in->UDN)) ||
in->servId, in->UDN ) ) == NULL ) !service->active ||
|| ( !service->active ) !(sub = GetSubscriptionSID(in->sid, service)) ||
|| ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL ) copy_subscription(sub, &sub_copy) != HTTP_SUCCESS) {
|| ( ( copy_subscription( sub, &sub_copy ) != HTTP_SUCCESS ) ) ) { free_notify_struct(in);
free_notify_struct( in ); HandleUnlock();
HandleUnlock(); return;
return; }
} #ifdef UPNP_ENABLE_NOTIFICATION_REORDERING
//If the event is out of order push it back to the job queue /*If the event is out of order push it back to the job queue */
if( in->eventKey != sub->ToSendEventKey ) { if (in->eventKey != sub->ToSendEventKey) {
TPJobInit(&job, (start_routine) genaNotifyThread, input);
TPJobSetFreeFunction(&job, (free_function) free_notify_struct);
TPJobSetPriority(&job, MED_PRIORITY);
/* Sleep a little before creating another thread otherwise if there is
* a lot of notifications to send, the device will take 100% of the CPU
* to create threads and push them back to the job queue. */
imillisleep(1);
ThreadPoolAdd(&gSendThreadPool, &job, NULL);
freeSubscription(&sub_copy);
HandleUnlock();
return;
}
#endif
TPJobInit( &job, ( start_routine ) genaNotifyThread, input ); HandleUnlock();
TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
ThreadPoolAdd( &gSendThreadPool, &job, NULL );
freeSubscription( &sub_copy ); /* send the notify */
HandleUnlock(); return_code = genaNotify(in->headers, in->propertySet, &sub_copy);
return; freeSubscription(&sub_copy);
} HandleLock();
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)) ||
!service->active ||
!(sub = GetSubscriptionSID(in->sid, service))) {
free_notify_struct(in);
HandleUnlock();
return;
}
sub->ToSendEventKey++;
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);
HandleUnlock(); HandleUnlock();
//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 );
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 );
HandleUnlock();
return;
}
sub->ToSendEventKey++;
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 );
HandleUnlock();
} }
@@ -428,7 +408,7 @@ static char *AllocGenaHeaders(
static const char *HEADER_LINE_4 = static const char *HEADER_LINE_4 =
"NTS: upnp:propchange\r\n"; "NTS: upnp:propchange\r\n";
char *headers = NULL; char *headers = NULL;
int headers_size = 0; size_t headers_size = 0;
int line = 0; int line = 0;
headers_size = headers_size =
@@ -1115,8 +1095,8 @@ static int create_url_list(
/*! [out] . */ /*! [out] . */
URL_list *out) URL_list *out)
{ {
int URLcount = 0; size_t URLcount = 0;
int i; size_t i;
int return_code = 0; int return_code = 0;
uri_type temp; uri_type temp;
token urls; token urls;
@@ -1146,12 +1126,11 @@ static int create_url_list(
} }
if( URLcount > 0 ) { if( URLcount > 0 ) {
out->URLs = ( char * )malloc( URLS->size + 1 ); out->URLs = malloc(URLS->size + 1);
out->parsedURLs = out->parsedURLs = malloc(sizeof(uri_type) * URLcount);
( uri_type * ) malloc( sizeof( uri_type ) * URLcount ); if (!out->URLs || !out->parsedURLs) {
if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) { free(out->URLs);
free( out->URLs ); free(out->parsedURLs);
free( out->parsedURLs );
out->URLs = NULL; out->URLs = NULL;
out->parsedURLs = NULL; out->parsedURLs = NULL;
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
@@ -1182,7 +1161,7 @@ static int create_url_list(
} }
out->size = URLcount; out->size = URLcount;
return URLcount; return (int)URLcount;
} }
@@ -1190,7 +1169,7 @@ void gena_process_subscription_request(
SOCKINFO *info, SOCKINFO *info,
http_message_t *request) http_message_t *request)
{ {
UpnpSubscriptionRequest *request_struct = UpnpSubscriptionRequest_new(); struct Upnp_Subscription_Request request_struct;
Upnp_SID temp_sid; Upnp_SID temp_sid;
int return_code = 1; int return_code = 1;
int time_out = 1801; int time_out = 1801;
@@ -1214,20 +1193,20 @@ void gena_process_subscription_request(
goto exit_function; goto exit_function;
} }
// check NT header /* check NT header */
// Windows Millenium Interoperability: /* Windows Millenium Interoperability: */
// we accept either upnp:event, or upnp:propchange for the NT header /* we accept either upnp:event, or upnp:propchange for the NT header */
if (memptr_cmp_nocase(&nt_hdr, "upnp:event") != 0) { if (memptr_cmp_nocase(&nt_hdr, "upnp:event") != 0) {
error_respond(info, HTTP_PRECONDITION_FAILED, request); error_respond(info, HTTP_PRECONDITION_FAILED, request);
goto exit_function; 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) { if (httpmsg_find_hdr(request, HDR_SID, NULL) != NULL) {
error_respond(info, HTTP_BAD_REQUEST, request); error_respond(info, HTTP_BAD_REQUEST, request);
goto exit_function; 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); event_url_path = str_alloc(request->uri.pathquery.buff, request->uri.pathquery.size);
if (event_url_path == NULL) { if (event_url_path == NULL) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request); error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
@@ -1240,7 +1219,7 @@ void gena_process_subscription_request(
HandleLock(); HandleLock();
// CURRENTLY, ONLY ONE DEVICE /* CURRENTLY, ONLY ONE DEVICE */
if (GetDeviceHandleInfo(info->foreign_sockaddr.ss_family , if (GetDeviceHandleInfo(info->foreign_sockaddr.ss_family ,
&device_handle, &handle_info) != HND_DEVICE) { &device_handle, &handle_info) != HND_DEVICE) {
free(event_url_path); free(event_url_path);
@@ -1263,14 +1242,14 @@ void gena_process_subscription_request(
service->TotalSubscriptions, service->TotalSubscriptions,
handle_info->MaxSubscriptions); handle_info->MaxSubscriptions);
// too many subscriptions /* too many subscriptions */
if (handle_info->MaxSubscriptions != -1 && if (handle_info->MaxSubscriptions != -1 &&
service->TotalSubscriptions >= handle_info->MaxSubscriptions) { service->TotalSubscriptions >= handle_info->MaxSubscriptions) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request); error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
HandleUnlock(); HandleUnlock();
goto exit_function; goto exit_function;
} }
// generate new subscription /* generate new subscription */
sub = (subscription *)malloc(sizeof (subscription)); sub = (subscription *)malloc(sizeof (subscription));
if (sub == NULL) { if (sub == NULL) {
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request); error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
@@ -1285,7 +1264,7 @@ void gena_process_subscription_request(
sub->DeliveryURLs.URLs = NULL; sub->DeliveryURLs.URLs = NULL;
sub->DeliveryURLs.parsedURLs = NULL; sub->DeliveryURLs.parsedURLs = NULL;
// check for valid callbacks /* check for valid callbacks */
if (httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr) == NULL) { if (httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr) == NULL) {
error_respond(info, HTTP_PRECONDITION_FAILED, request); error_respond(info, HTTP_PRECONDITION_FAILED, request);
freeSubscriptionList(sub); freeSubscriptionList(sub);
@@ -1305,20 +1284,20 @@ void gena_process_subscription_request(
HandleUnlock(); HandleUnlock();
goto exit_function; goto exit_function;
} }
// set the timeout /* set the timeout */
if (httpmsg_find_hdr(request, HDR_TIMEOUT, &timeout_hdr) != NULL) { if (httpmsg_find_hdr(request, HDR_TIMEOUT, &timeout_hdr) != NULL) {
if (matchstr(timeout_hdr.buf, timeout_hdr.length, if (matchstr(timeout_hdr.buf, timeout_hdr.length,
"%iSecond-%d%0", &time_out) == PARSE_OK) { "%iSecond-%d%0", &time_out) == PARSE_OK) {
// nothing /* nothing */
} else if(memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) { } else if(memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
// infinite timeout /* infinite timeout */
time_out = -1; time_out = -1;
} else { } else {
// default is > 1800 seconds /* default is > 1800 seconds */
time_out = DEFAULT_TIMEOUT; 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 (handle_info->MaxSubscriptionTimeOut != -1) {
if (time_out == -1 || if (time_out == -1 ||
time_out > handle_info->MaxSubscriptionTimeOut) { time_out > handle_info->MaxSubscriptionTimeOut) {
@@ -1328,44 +1307,44 @@ void gena_process_subscription_request(
if (time_out >= 0) { if (time_out >= 0) {
sub->expireTime = time(NULL) + time_out; sub->expireTime = time(NULL) + time_out;
} else { } else {
// infinite time /* infinite time */
sub->expireTime = 0; sub->expireTime = 0;
} }
// generate SID /* generate SID */
uuid_create(&uid); uuid_create(&uid);
uuid_unpack(&uid, temp_sid); uuid_unpack(&uid, temp_sid);
sprintf(sub->sid, "uuid:%s", temp_sid); sprintf(sub->sid, "uuid:%s", temp_sid);
// respond OK /* respond OK */
if (respond_ok(info, time_out, sub, request) != UPNP_E_SUCCESS) { if (respond_ok(info, time_out, sub, request) != UPNP_E_SUCCESS) {
freeSubscriptionList(sub); freeSubscriptionList(sub);
HandleUnlock(); HandleUnlock();
goto exit_function; goto exit_function;
} }
// add to subscription list /* add to subscription list */
sub->next = service->subscriptionList; sub->next = service->subscriptionList;
service->subscriptionList = sub; service->subscriptionList = sub;
service->TotalSubscriptions++; service->TotalSubscriptions++;
// finally generate callback for init table dump /* finally generate callback for init table dump */
UpnpSubscriptionRequest_strcpy_ServiceId(request_struct, service->serviceId); request_struct.ServiceId = service->serviceId;
UpnpSubscriptionRequest_strcpy_UDN(request_struct, service->UDN); request_struct.UDN = service->UDN;
UpnpSubscriptionRequest_strcpy_SID(request_struct, sub->sid); strcpy((char *)request_struct.Sid, sub->sid);
// copy callback /* copy callback */
callback_fun = handle_info->Callback; callback_fun = handle_info->Callback;
cookie = handle_info->Cookie; cookie = handle_info->Cookie;
HandleUnlock(); HandleUnlock();
// make call back with request struct /* make call back with request struct */
// in the future should find a way of mainting that the handle /* in the future should find a way of mainting that the handle */
// is not unregistered in the middle of a callback /* is not unregistered in the middle of a callback */
callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, request_struct, cookie); callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, &request_struct, cookie);
exit_function: exit_function:
UpnpSubscriptionRequest_delete(request_struct); return;
} }
@@ -1383,13 +1362,13 @@ void gena_process_subscription_renewal_request(
membuffer event_url_path; membuffer event_url_path;
memptr timeout_hdr; 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 || if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) { httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
error_respond( info, HTTP_BAD_REQUEST, request ); error_respond( info, HTTP_BAD_REQUEST, request );
return; return;
} }
// get SID /* get SID */
if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL || if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
temp_hdr.length > SID_SIZE ) { temp_hdr.length > SID_SIZE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request ); error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1398,7 +1377,7 @@ void gena_process_subscription_renewal_request(
memcpy( sid, temp_hdr.buf, temp_hdr.length ); memcpy( sid, temp_hdr.buf, temp_hdr.length );
sid[temp_hdr.length] = '\0'; sid[temp_hdr.length] = '\0';
// lookup service by eventURL /* lookup service by eventURL */
membuffer_init( &event_url_path ); membuffer_init( &event_url_path );
if( membuffer_append( &event_url_path, request->uri.pathquery.buff, if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
request->uri.pathquery.size ) != 0 ) { request->uri.pathquery.size ) != 0 ) {
@@ -1408,7 +1387,7 @@ void gena_process_subscription_renewal_request(
HandleLock(); HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE /* CURRENTLY, ONLY SUPPORT ONE DEVICE */
if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family, if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
&device_handle, &handle_info ) != HND_DEVICE ) { &device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request ); error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1420,7 +1399,7 @@ void gena_process_subscription_renewal_request(
event_url_path.buf ); event_url_path.buf );
membuffer_destroy( &event_url_path ); membuffer_destroy( &event_url_path );
// get subscription /* get subscription */
if( service == NULL || if( service == NULL ||
!service->active || !service->active ||
( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) { ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
@@ -1434,7 +1413,7 @@ void gena_process_subscription_renewal_request(
"Max Subscriptions allowed:%d\n", "Max Subscriptions allowed:%d\n",
service->TotalSubscriptions, service->TotalSubscriptions,
handle_info->MaxSubscriptions ); handle_info->MaxSubscriptions );
// too many subscriptions /* too many subscriptions */
if( handle_info->MaxSubscriptions != -1 && if( handle_info->MaxSubscriptions != -1 &&
service->TotalSubscriptions > handle_info->MaxSubscriptions ) { service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request ); error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
@@ -1442,25 +1421,25 @@ void gena_process_subscription_renewal_request(
HandleUnlock(); HandleUnlock();
return; return;
} }
// set the timeout /* set the timeout */
if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) { if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
if( matchstr( timeout_hdr.buf, timeout_hdr.length, if( matchstr( timeout_hdr.buf, timeout_hdr.length,
"%iSecond-%d%0", &time_out ) == PARSE_OK ) { "%iSecond-%d%0", &time_out ) == PARSE_OK ) {
//nothing /*nothing */
} else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) == } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
0 ) { 0 ) {
time_out = -1; // inifinite timeout time_out = -1; /* inifinite timeout */
} else { } 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( handle_info->MaxSubscriptionTimeOut != -1 ) {
if( time_out == -1 || if( time_out == -1 ||
time_out > handle_info->MaxSubscriptionTimeOut ) { time_out > handle_info->MaxSubscriptionTimeOut ) {
@@ -1494,13 +1473,13 @@ void gena_process_unsubscribe_request(
memptr temp_hdr; memptr temp_hdr;
membuffer event_url_path; 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 || if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) { httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
error_respond( info, HTTP_BAD_REQUEST, request ); error_respond( info, HTTP_BAD_REQUEST, request );
return; return;
} }
// get SID /* get SID */
if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL || if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
temp_hdr.length > SID_SIZE ) { temp_hdr.length > SID_SIZE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request ); error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1509,7 +1488,7 @@ void gena_process_unsubscribe_request(
memcpy( sid, temp_hdr.buf, temp_hdr.length ); memcpy( sid, temp_hdr.buf, temp_hdr.length );
sid[temp_hdr.length] = '\0'; sid[temp_hdr.length] = '\0';
// lookup service by eventURL /* lookup service by eventURL */
membuffer_init( &event_url_path ); membuffer_init( &event_url_path );
if( membuffer_append( &event_url_path, request->uri.pathquery.buff, if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
request->uri.pathquery.size ) != 0 ) { request->uri.pathquery.size ) != 0 ) {
@@ -1519,7 +1498,7 @@ void gena_process_unsubscribe_request(
HandleLock(); HandleLock();
// CURRENTLY, ONLY SUPPORT ONE DEVICE /* CURRENTLY, ONLY SUPPORT ONE DEVICE */
if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family, if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
&device_handle, &handle_info ) != HND_DEVICE ) { &device_handle, &handle_info ) != HND_DEVICE ) {
error_respond( info, HTTP_PRECONDITION_FAILED, request ); error_respond( info, HTTP_PRECONDITION_FAILED, request );
@@ -1531,7 +1510,7 @@ void gena_process_unsubscribe_request(
event_url_path.buf ); event_url_path.buf );
membuffer_destroy( &event_url_path ); membuffer_destroy( &event_url_path );
// validate service /* validate service */
if( service == NULL || if( service == NULL ||
!service->active || GetSubscriptionSID( sid, service ) == NULL ) !service->active || GetSubscriptionSID( sid, service ) == NULL )
{ {
@@ -1541,7 +1520,7 @@ void gena_process_unsubscribe_request(
} }
RemoveSubscriptionSID(sid, service); RemoveSubscriptionSID(sid, service);
error_respond(info, HTTP_OK, request); // success error_respond(info, HTTP_OK, request); /* success */
HandleUnlock(); HandleUnlock();
} }

View File

@@ -1,200 +0,0 @@
/************************************************************************
* Purpose: This file defines the functions for clients. It defines
* functions for adding and removing clients to and from the client table,
* adding and accessing subscription and other attributes pertaining to the
* client
************************************************************************/
#include "config.h"
#include "ClientSubscription.h"
#ifdef INCLUDE_CLIENT_APIS
#include <stdlib.h> // for calloc(), free()
struct SClientSubscription {
int m_renewEventId;
UpnpString *m_SID;
UpnpString *m_actualSID;
UpnpString *m_eventURL;
struct SClientSubscription *m_next;
};
ClientSubscription *GenlibClientSubscription_new()
{
struct SClientSubscription *p = calloc(1, sizeof (struct SClientSubscription));
#if 0
p->renewEventId = 0;
#endif
p->m_SID = UpnpString_new();
p->m_actualSID = UpnpString_new();
p->m_eventURL = UpnpString_new();
p->m_next = NULL;
return (ClientSubscription *)p;
}
void GenlibClientSubscription_delete(ClientSubscription *p)
{
struct SClientSubscription *q = (struct SClientSubscription *)p;
if (!q) return;
q->m_renewEventId = 0;
UpnpString_delete(q->m_SID);
q->m_SID = NULL;
UpnpString_delete(q->m_actualSID);
q->m_actualSID = NULL;
UpnpString_delete(q->m_eventURL);
q->m_eventURL = NULL;
q->m_next = NULL;
free(p);
}
ClientSubscription *GenlibClientSubscription_dup(const ClientSubscription *p)
{
ClientSubscription *q = GenlibClientSubscription_new();
GenlibClientSubscription_assign(q, p);
return q;
}
void GenlibClientSubscription_assign(ClientSubscription *q, const ClientSubscription *p)
{
if (q != p) {
/*struct SClientSubscription *_p = (struct SClientSubscription *)p;*/
struct SClientSubscription *_q = (struct SClientSubscription *)q;
// Do not copy RenewEventId
_q->m_renewEventId = -1;
GenlibClientSubscription_set_SID(q, GenlibClientSubscription_get_SID(p));
GenlibClientSubscription_set_ActualSID(q, GenlibClientSubscription_get_ActualSID(p));
GenlibClientSubscription_set_EventURL(q, GenlibClientSubscription_get_EventURL(p));
// Do not copy m_next
_q->m_next = NULL;
}
}
int GenlibClientSubscription_get_RenewEventId(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_renewEventId;
}
void GenlibClientSubscription_set_RenewEventId(ClientSubscription *p, int n)
{
((struct SClientSubscription *)p)->m_renewEventId = n;
}
const UpnpString *GenlibClientSubscription_get_SID(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_SID;
}
const char *GenlibClientSubscription_get_SID_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(GenlibClientSubscription_get_SID(p));
}
void GenlibClientSubscription_set_SID(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_SID);
((struct SClientSubscription *)p)->m_SID = UpnpString_dup(s);
}
void GenlibClientSubscription_strcpy_SID(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_SID);
((struct SClientSubscription *)p)->m_SID = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_SID, s);
}
const UpnpString *GenlibClientSubscription_get_ActualSID(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_actualSID;
}
const char *GenlibClientSubscription_get_ActualSID_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(GenlibClientSubscription_get_ActualSID(p));
}
void GenlibClientSubscription_set_ActualSID(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_actualSID);
((struct SClientSubscription *)p)->m_actualSID = UpnpString_dup(s);
}
void GenlibClientSubscription_strcpy_ActualSID(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_actualSID);
((struct SClientSubscription *)p)->m_actualSID = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_actualSID, s);
}
const UpnpString *GenlibClientSubscription_get_EventURL(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_eventURL;
}
const char *GenlibClientSubscription_get_EventURL_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(GenlibClientSubscription_get_EventURL(p));
}
void GenlibClientSubscription_set_EventURL(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_eventURL);
((struct SClientSubscription *)p)->m_eventURL = UpnpString_dup(s);
}
void GenlibClientSubscription_strcpy_EventURL(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_eventURL);
((struct SClientSubscription *)p)->m_eventURL = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_eventURL, s);
}
ClientSubscription *GenlibClientSubscription_get_Next(const ClientSubscription *p)
{
return (ClientSubscription *)(((struct SClientSubscription *)p)->m_next);
}
void GenlibClientSubscription_set_Next(ClientSubscription *p, ClientSubscription *q)
{
((struct SClientSubscription *)p)->m_next = (struct SClientSubscription *)q;
}
#endif /* INCLUDE_CLIENT_APIS */

View File

@@ -1,3 +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.
*
******************************************************************************/
/************************************************************************ /************************************************************************
* Purpose: This file defines the functions for clients. It defines * Purpose: This file defines the functions for clients. It defines
@@ -16,7 +46,187 @@
#ifdef INCLUDE_CLIENT_APIS #ifdef INCLUDE_CLIENT_APIS
#include <stdlib.h> // for calloc(), free() #include <stdlib.h> /* for calloc(), free() */
struct SClientSubscription {
int m_renewEventId;
UpnpString *m_SID;
UpnpString *m_actualSID;
UpnpString *m_eventURL;
struct SClientSubscription *m_next;
};
/** Constructor */
ClientSubscription *UpnpClientSubscription_new()
{
struct SClientSubscription *p = calloc(1, sizeof (struct SClientSubscription));
#if 0
p->renewEventId = 0;
#endif
p->m_SID = UpnpString_new();
p->m_actualSID = UpnpString_new();
p->m_eventURL = UpnpString_new();
p->m_next = NULL;
return (ClientSubscription *)p;
}
/** Destructor */
void UpnpClientSubscription_delete(ClientSubscription *p)
{
struct SClientSubscription *q = (struct SClientSubscription *)p;
if (!q) return;
q->m_renewEventId = 0;
UpnpString_delete(q->m_SID);
q->m_SID = NULL;
UpnpString_delete(q->m_actualSID);
q->m_actualSID = NULL;
UpnpString_delete(q->m_eventURL);
q->m_eventURL = NULL;
q->m_next = NULL;
free(p);
}
/** Copy Constructor */
ClientSubscription *UpnpClientSubscription_dup(const ClientSubscription *p)
{
ClientSubscription *q = UpnpClientSubscription_new();
UpnpClientSubscription_assign(q, p);
return q;
}
/** Assignment operator */
void UpnpClientSubscription_assign(ClientSubscription *q, const ClientSubscription *p)
{
if (q != p) {
/* 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 */
((struct SClientSubscription *)q)->m_next = NULL;
}
}
int UpnpClientSubscription_get_RenewEventId(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_renewEventId;
}
void UpnpClientSubscription_set_RenewEventId(ClientSubscription *p, int n)
{
((struct SClientSubscription *)p)->m_renewEventId = n;
}
const UpnpString *UpnpClientSubscription_get_SID(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_SID;
}
const char *UpnpClientSubscription_get_SID_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(UpnpClientSubscription_get_SID(p));
}
void UpnpClientSubscription_set_SID(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_SID);
((struct SClientSubscription *)p)->m_SID = UpnpString_dup(s);
}
void UpnpClientSubscription_strcpy_SID(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_SID);
((struct SClientSubscription *)p)->m_SID = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_SID, s);
}
const UpnpString *UpnpClientSubscription_get_ActualSID(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_actualSID;
}
const char *UpnpClientSubscription_get_ActualSID_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(UpnpClientSubscription_get_ActualSID(p));
}
void UpnpClientSubscription_set_ActualSID(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_actualSID);
((struct SClientSubscription *)p)->m_actualSID = UpnpString_dup(s);
}
void UpnpClientSubscription_strcpy_ActualSID(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_actualSID);
((struct SClientSubscription *)p)->m_actualSID = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_actualSID, s);
}
const UpnpString *UpnpClientSubscription_get_EventURL(const ClientSubscription *p)
{
return ((struct SClientSubscription *)p)->m_eventURL;
}
const char *UpnpClientSubscription_get_EventURL_cstr(const ClientSubscription *p)
{
return UpnpString_get_String(UpnpClientSubscription_get_EventURL(p));
}
void UpnpClientSubscription_set_EventURL(ClientSubscription *p, const UpnpString *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_eventURL);
((struct SClientSubscription *)p)->m_eventURL = UpnpString_dup(s);
}
void UpnpClientSubscription_strcpy_EventURL(ClientSubscription *p, const char *s)
{
UpnpString_delete(((struct SClientSubscription *)p)->m_eventURL);
((struct SClientSubscription *)p)->m_eventURL = UpnpString_new();
UpnpString_set_String(((struct SClientSubscription *)p)->m_eventURL, s);
}
ClientSubscription *UpnpClientSubscription_get_Next(const ClientSubscription *p)
{
return (ClientSubscription *)(((struct SClientSubscription *)p)->m_next);
}
void UpnpClientSubscription_set_Next(ClientSubscription *p, ClientSubscription *q)
{
((struct SClientSubscription *)p)->m_next = (struct SClientSubscription *)q;
}
void free_client_subscription(ClientSubscription *sub) void free_client_subscription(ClientSubscription *sub)
@@ -24,18 +234,18 @@ void free_client_subscription(ClientSubscription *sub)
upnp_timeout *event; upnp_timeout *event;
ThreadPoolJob tempJob; ThreadPoolJob tempJob;
if (sub) { if (sub) {
int renewEventId = GenlibClientSubscription_get_RenewEventId(sub); int renewEventId = UpnpClientSubscription_get_RenewEventId(sub);
GenlibClientSubscription_strcpy_ActualSID(sub, ""); UpnpClientSubscription_strcpy_ActualSID(sub, "");
GenlibClientSubscription_strcpy_EventURL(sub, ""); UpnpClientSubscription_strcpy_EventURL(sub, "");
if (renewEventId != -1) { if (renewEventId != -1) {
// do not remove timer event of copy /* do not remove timer event of copy */
// invalid timer event id /* invalid timer event id */
if (TimerThreadRemove(&gTimerThread, renewEventId, &tempJob) == 0) { if (TimerThreadRemove(&gTimerThread, renewEventId, &tempJob) == 0) {
event = (upnp_timeout *)tempJob.arg; event = (upnp_timeout *)tempJob.arg;
free_upnp_timeout(event); free_upnp_timeout(event);
} }
} }
GenlibClientSubscription_set_RenewEventId(sub, -1); UpnpClientSubscription_set_RenewEventId(sub, -1);
} }
} }
@@ -45,8 +255,8 @@ void freeClientSubList(ClientSubscription *list)
ClientSubscription *next; ClientSubscription *next;
while (list) { while (list) {
free_client_subscription(list); free_client_subscription(list);
next = GenlibClientSubscription_get_Next(list); next = UpnpClientSubscription_get_Next(list);
GenlibClientSubscription_delete(list); UpnpClientSubscription_delete(list);
list = next; list = next;
} }
} }
@@ -60,20 +270,20 @@ void RemoveClientSubClientSID(ClientSubscription **head, const UpnpString *sid)
while (finger) { while (finger) {
found = !strcmp( found = !strcmp(
UpnpString_get_String(sid), UpnpString_get_String(sid),
GenlibClientSubscription_get_SID_cstr(finger)); UpnpClientSubscription_get_SID_cstr(finger));
if (found) { if (found) {
if (previous) { if (previous) {
GenlibClientSubscription_set_Next(previous, UpnpClientSubscription_set_Next(previous,
GenlibClientSubscription_get_Next(finger)); UpnpClientSubscription_get_Next(finger));
} else { } else {
*head = GenlibClientSubscription_get_Next(finger); *head = UpnpClientSubscription_get_Next(finger);
} }
GenlibClientSubscription_set_Next(finger, NULL); UpnpClientSubscription_set_Next(finger, NULL);
freeClientSubList(finger); freeClientSubList(finger);
finger = NULL; finger = NULL;
} else { } else {
previous = finger; previous = finger;
finger = GenlibClientSubscription_get_Next(finger); finger = UpnpClientSubscription_get_Next(finger);
} }
} }
} }
@@ -85,12 +295,12 @@ ClientSubscription *GetClientSubClientSID(ClientSubscription *head, const UpnpSt
int found = 0; int found = 0;
while (next) { while (next) {
found = !strcmp( found = !strcmp(
GenlibClientSubscription_get_SID_cstr(next), UpnpClientSubscription_get_SID_cstr(next),
UpnpString_get_String(sid)); UpnpString_get_String(sid));
if(found) { if(found) {
break; break;
} else { } else {
next = GenlibClientSubscription_get_Next(next); next = UpnpClientSubscription_get_Next(next);
} }
} }
@@ -103,11 +313,11 @@ ClientSubscription *GetClientSubActualSID(ClientSubscription *head, token *sid)
ClientSubscription *next = head; ClientSubscription *next = head;
while (next) { while (next) {
if (!memcmp( if (!memcmp(
GenlibClientSubscription_get_ActualSID_cstr(next), UpnpClientSubscription_get_ActualSID_cstr(next),
sid->buff, sid->size)) { sid->buff, sid->size)) {
break; break;
} else { } else {
next = GenlibClientSubscription_get_Next(next); next = UpnpClientSubscription_get_Next(next);
} }
} }
@@ -115,5 +325,5 @@ ClientSubscription *GetClientSubActualSID(ClientSubscription *head, token *sid)
} }
#endif /* INCLUDE_CLIENT_APIS */ #endif /* INCLUDE_CLIENT_APIS */

File diff suppressed because it is too large Load Diff

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

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