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
This commit is contained in:
parent
6c8a4dd361
commit
2bcbdffd89
42
ChangeLog
42
ChangeLog
@ -2,6 +2,48 @@
|
|||||||
Version 1.6.7
|
Version 1.6.7
|
||||||
*******************************************************************************
|
*******************************************************************************
|
||||||
|
|
||||||
|
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
|
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
|
||||||
|
|
||||||
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
2010-03-27 Marcelo Jimenez <mroberto(at)users.sourceforge.net>
|
||||||
* SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
|
* SF Patch Tracker [ 2836704 ] Patch for Solaris10 compilation and usage.
|
||||||
Submitted By: zephyrus ( zephyrus00jp )
|
Submitted By: zephyrus ( zephyrus00jp )
|
||||||
|
60
configure.ac
60
configure.ac
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
# Process this file with autoconf to produce a configure script.
|
# Process this file with autoconf to produce a configure script.
|
||||||
#
|
#
|
||||||
# (C) Copyright 2005-2007 Rémi Turboult <r3mi@users.sourceforge.net>
|
# (C) Copyright 2005-2007 Rémi Turboult <r3mi@users.sourceforge.net>
|
||||||
#
|
#
|
||||||
|
|
||||||
AC_PREREQ(2.60)
|
AC_PREREQ(2.60)
|
||||||
@ -147,13 +147,21 @@ dnl ############################################################################
|
|||||||
dnl # Release 1.6.7:
|
dnl # Release 1.6.7:
|
||||||
dnl # "current:revision:age"
|
dnl # "current:revision:age"
|
||||||
dnl #
|
dnl #
|
||||||
|
dnl # - Code has changed in upnp
|
||||||
|
dnl # revision: 5 -> 6
|
||||||
|
dnl # - Code has changed in threadutil
|
||||||
|
dnl # revision: 3 -> 4
|
||||||
|
dnl # - Interfaces have been changed, added and removed in upnp
|
||||||
|
dnl # current: 4 -> 5
|
||||||
|
dnl # revision: 4 -> 0
|
||||||
|
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], [4:3:2])
|
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
|
||||||
dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0])
|
dnl #AC_SUBST([LT_VERSION_UPNP], [3:5:0])
|
||||||
dnl #
|
dnl #
|
||||||
dnl ############################################################################
|
dnl ############################################################################
|
||||||
AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
AC_SUBST([LT_VERSION_IXML], [2:4:0])
|
||||||
AC_SUBST([LT_VERSION_THREADUTIL], [4:3:2])
|
AC_SUBST([LT_VERSION_THREADUTIL], [5:0:2])
|
||||||
AC_SUBST([LT_VERSION_UPNP], [3:5:0])
|
AC_SUBST([LT_VERSION_UPNP], [3:5: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:
|
||||||
@ -333,9 +341,26 @@ AC_DEFINE([_FILE_OFFSET_BITS], [64], [File Offset size])
|
|||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Checks for header files
|
# Are we targetting Win32?
|
||||||
|
#
|
||||||
|
AC_MSG_CHECKING([for Win32])
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||||
|
#ifdef WIN32
|
||||||
|
#error Yup
|
||||||
|
#endif
|
||||||
|
],[])], [ac_cv_win32="no"], [ac_cv_win32="yes"])
|
||||||
|
if test "$ac_cv_win32" = "yes"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checks for header files (which aren't needed on Win32)
|
||||||
#
|
#
|
||||||
AC_HEADER_STDC
|
AC_HEADER_STDC
|
||||||
|
if test "$ac_cv_win32" = "no"; then
|
||||||
# libupnp code doesn't use autoconf variables yet,
|
# libupnp code doesn't use autoconf variables yet,
|
||||||
# so just abort if a header file is not found.
|
# so just abort if a header file is not found.
|
||||||
AC_CHECK_HEADERS(
|
AC_CHECK_HEADERS(
|
||||||
@ -356,13 +381,38 @@ AC_CHECK_HEADERS(
|
|||||||
],
|
],
|
||||||
[],
|
[],
|
||||||
[AC_MSG_ERROR([required header file missing])])
|
[AC_MSG_ERROR([required header file missing])])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Checks for typedefs, structures, and compiler characteristics
|
# Checks for typedefs, structures, and compiler characteristics
|
||||||
#
|
#
|
||||||
AC_C_CONST
|
AC_C_CONST
|
||||||
TYPE_SOCKLEN_T
|
|
||||||
|
# The test for socklen_t was getting it wrong when it exists but is in ws2tcpip.h,
|
||||||
|
# so we use a new test.
|
||||||
|
#TYPE_SOCKLEN_T
|
||||||
|
|
||||||
|
AC_CHECK_HEADERS([sys/types.h sys/socket.h ws2tcpip.h])
|
||||||
|
AC_MSG_CHECKING(for socklen_t)
|
||||||
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
|
||||||
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
#include <sys/types.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_WS2TCPIP_H
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
#endif
|
||||||
|
],[ socklen_t t = 0; return t; ])
|
||||||
|
],[ac_cv_socklen_t="yes"],[ac_cv_socklen_t="no"])
|
||||||
|
if test "$ac_cv_socklen_t" = "yes"; then
|
||||||
|
AC_MSG_RESULT([yes])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no, using int])
|
||||||
|
AC_DEFINE(socklen_t, int, [Type for storing the length of struct sockaddr])
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -30,19 +30,21 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef ITHREADH
|
#ifndef ITHREAD_H
|
||||||
#define ITHREADH
|
#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 EXPORT_SPEC */
|
|
||||||
|
#include "UpnpGlobal.h" /* For UPNP_INLINE, EXPORT_SPEC */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -94,6 +96,7 @@ extern "C" {
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
typedef pthread_t ithread_t;
|
typedef pthread_t ithread_t;
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: ithread_attr_t
|
* Name: ithread_attr_t
|
||||||
*
|
*
|
||||||
@ -112,7 +115,7 @@ typedef pthread_attr_t ithread_attr_t;
|
|||||||
* Thread start routine
|
* Thread start routine
|
||||||
* Internal Use Only.
|
* Internal Use Only.
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
typedef void * (*start_routine) (void *arg);
|
typedef void *(*start_routine)(void *arg);
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -181,6 +184,95 @@ typedef pthread_rwlockattr_t ithread_rwlockattr_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
typedef pthread_rwlock_t ithread_rwlock_t;
|
typedef pthread_rwlock_t ithread_rwlock_t;
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_initialize_library
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes the library. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_initialize_library(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_process_attach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_cleanup_library
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Clean up library resources. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_cleanup_library(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_process_detach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_initialize_thread
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Initializes the thread. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_initialize_thread(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_thread_attach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Function: ithread_cleanup_thread
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Clean up thread resources. Does nothing in all implementations, except
|
||||||
|
* when statically linked for WIN32.
|
||||||
|
* Parameters:
|
||||||
|
* none.
|
||||||
|
* Returns:
|
||||||
|
* 0 on success, Nonzero on failure.
|
||||||
|
***************************************************************************/
|
||||||
|
static UPNP_INLINE int ithread_cleanup_thread(void) {
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(PTW32_STATIC_LIB)
|
||||||
|
ret = !pthread_win32_thread_detach_np();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_mutexattr_init
|
* Function: ithread_mutexattr_init
|
||||||
*
|
*
|
||||||
@ -420,8 +512,8 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Must be called before use.
|
* Must be called before use.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
* ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
||||||
* const ithread_rwlockattr_t * rwlock_attr
|
* const ithread_rwlockattr_t *rwlock_attr
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success, Nonzero on failure.
|
* 0 on success, Nonzero on failure.
|
||||||
* Always returns 0.
|
* Always returns 0.
|
||||||
@ -436,7 +528,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Description:
|
* Description:
|
||||||
* Locks rwlock for reading.
|
* Locks rwlock for reading.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
* ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
||||||
* rwlock must be initialized.
|
* rwlock must be initialized.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -453,7 +545,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Description:
|
* Description:
|
||||||
* Locks rwlock for writting.
|
* Locks rwlock for writting.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
* ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
||||||
* rwlock must be initialized.
|
* rwlock must be initialized.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -471,7 +563,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Unlocks rwlock.
|
* Unlocks rwlock.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
* ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
||||||
* rwlock must be initialized.
|
* rwlock must be initialized.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -491,7 +583,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* rwlock is only destroyed when there are no longer any threads waiting on it.
|
* rwlock is only destroyed when there are no longer any threads waiting on it.
|
||||||
* rwlock cannot be destroyed if it is locked.
|
* rwlock cannot be destroyed if it is locked.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_rwlock_t * rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
* ithread_rwlock_t *rwlock (must be valid non NULL pointer to pthread_rwlock_t)
|
||||||
* rwlock must be initialized.
|
* rwlock must be initialized.
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success. Nonzero on failure.
|
* 0 on success. Nonzero on failure.
|
||||||
@ -508,8 +600,8 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Initializes condition variable.
|
* Initializes condition variable.
|
||||||
* Must be called before use.
|
* Must be called before use.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to pthread_cond_t)
|
* ithread_cond_t *cond (must be valid non NULL pointer to pthread_cond_t)
|
||||||
* const ithread_condattr_t * cond_attr (ignored)
|
* const ithread_condattr_t *cond_attr (ignored)
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success, Nonzero on failure.
|
* 0 on success, Nonzero on failure.
|
||||||
* See man page for pthread_cond_init
|
* See man page for pthread_cond_init
|
||||||
@ -517,7 +609,6 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define ithread_cond_init pthread_cond_init
|
#define ithread_cond_init pthread_cond_init
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_cond_signal
|
* Function: ithread_cond_signal
|
||||||
*
|
*
|
||||||
@ -525,7 +616,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Wakes up exactly one thread waiting on condition.
|
* Wakes up exactly one thread waiting on condition.
|
||||||
* Associated mutex MUST be locked by thread before entering this call.
|
* Associated mutex MUST be locked by thread before entering this call.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to
|
||||||
* ithread_cond_t)
|
* ithread_cond_t)
|
||||||
* cond must be initialized
|
* cond must be initialized
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -542,7 +633,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Wakes up all threads waiting on condition.
|
* Wakes up all threads waiting on condition.
|
||||||
* Associated mutex MUST be locked by thread before entering this call.
|
* Associated mutex MUST be locked by thread before entering this call.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to
|
||||||
* ithread_cond_t)
|
* ithread_cond_t)
|
||||||
* cond must be initialized
|
* cond must be initialized
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -560,7 +651,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Associated mutex MUST be locked by thread before entering this call.
|
* Associated mutex MUST be locked by thread before entering this call.
|
||||||
* Mutex is reacquired when call returns.
|
* Mutex is reacquired when call returns.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to
|
||||||
* ithread_cond_t)
|
* ithread_cond_t)
|
||||||
* cond must be initialized
|
* cond must be initialized
|
||||||
* ithread_mutex_t *mutex (must be valid non NULL pointer to
|
* ithread_mutex_t *mutex (must be valid non NULL pointer to
|
||||||
@ -576,23 +667,19 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: pthread_cond_timedwait
|
* Function: pthread_cond_timedwait
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* Atomically releases the associated mutex and waits on the condition.
|
* Atomically releases the associated mutex and waits on the
|
||||||
* If the condition is not signaled in the specified time
|
* condition.
|
||||||
* than the
|
* If the condition is not signaled in the specified time than the
|
||||||
* call times out and returns.
|
* call times out and returns.
|
||||||
* Associated mutex MUST be locked by thread before entering
|
* Associated mutex MUST be locked by thread before entering this call.
|
||||||
* this call.
|
* Mutex is reacquired when call returns.
|
||||||
* Mutex is reacquired when call returns.
|
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to ithread_cond_t)
|
||||||
* ithread_cond_t)
|
* cond must be initialized
|
||||||
* cond must be initialized
|
* ithread_mutex_t *mutex (must be valid non NULL pointer to ithread_mutex_t)
|
||||||
* ithread_mutex_t *mutex (must be valid non NULL pointer to
|
* Mutex must be locked.
|
||||||
* ithread_mutex_t)
|
* const struct timespec *abstime (absolute time, measured from Jan 1, 1970)
|
||||||
* Mutex must be locked.
|
|
||||||
* const struct timespec *abstime (absolute time, measured
|
|
||||||
* from Jan 1, 1970)
|
|
||||||
* Returns:
|
* Returns:
|
||||||
* 0 on success. ETIMEDOUT on timeout. Nonzero on failure.
|
* 0 on success. ETIMEDOUT on timeout. Nonzero on failure.
|
||||||
* See man page for pthread_cond_timedwait
|
* See man page for pthread_cond_timedwait
|
||||||
@ -608,7 +695,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
* Releases any resources held by the condition variable.
|
* Releases any resources held by the condition variable.
|
||||||
* Condition variable can no longer be used after this call.
|
* Condition variable can no longer be used after this call.
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* ithread_cond_t * cond (must be valid non NULL pointer to
|
* ithread_cond_t *cond (must be valid non NULL pointer to
|
||||||
* ithread_cond_t)
|
* ithread_cond_t)
|
||||||
* cond must be initialized.
|
* cond must be initialized.
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -664,6 +751,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_exit pthread_exit
|
#define ithread_exit pthread_exit
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_get_current_thread_id
|
* Function: ithread_get_current_thread_id
|
||||||
*
|
*
|
||||||
@ -687,6 +775,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_self pthread_self
|
#define ithread_self pthread_self
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_detach
|
* Function: ithread_detach
|
||||||
*
|
*
|
||||||
@ -700,6 +789,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#define ithread_detach pthread_detach
|
#define ithread_detach pthread_detach
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: ithread_join
|
* Function: ithread_join
|
||||||
*
|
*
|
||||||
@ -719,7 +809,6 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define ithread_join pthread_join
|
#define ithread_join pthread_join
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: isleep
|
* Function: isleep
|
||||||
*
|
*
|
||||||
@ -739,6 +828,7 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
#define isleep sleep
|
#define isleep sleep
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function: isleep
|
* Function: isleep
|
||||||
*
|
*
|
||||||
@ -764,9 +854,11 @@ typedef pthread_rwlock_t ithread_rwlock_t;
|
|||||||
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
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* ITHREADH */
|
|
||||||
|
#endif /* ITHREAD_H */
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -73,6 +73,7 @@ libupnp_la_SOURCES = \
|
|||||||
src/inc/util.h \
|
src/inc/util.h \
|
||||||
src/inc/utilall.h \
|
src/inc/utilall.h \
|
||||||
src/inc/uuid.h \
|
src/inc/uuid.h \
|
||||||
|
src/inc/VirtualDir.h \
|
||||||
src/inc/webserver.h
|
src/inc/webserver.h
|
||||||
|
|
||||||
# ssdp
|
# ssdp
|
||||||
|
412
upnp/inc/upnp.h
412
upnp/inc/upnp.h
@ -644,7 +644,7 @@ struct Upnp_Action_Request
|
|||||||
IXML_Document *ActionResult;
|
IXML_Document *ActionResult;
|
||||||
|
|
||||||
/** IP address of the control point requesting this action. */
|
/** IP address of the control point requesting this action. */
|
||||||
struct in_addr CtrlPtIPAddr;
|
struct sockaddr_storage CtrlPtIPAddr;
|
||||||
|
|
||||||
/** The DOM document containing the information from the
|
/** The DOM document containing the information from the
|
||||||
the SOAP header. */
|
the SOAP header. */
|
||||||
@ -691,7 +691,7 @@ struct Upnp_State_Var_Request
|
|||||||
char StateVarName[NAME_SIZE];
|
char StateVarName[NAME_SIZE];
|
||||||
|
|
||||||
/** IP address of sender requesting the state variable. */
|
/** IP address of sender requesting the state variable. */
|
||||||
struct in_addr CtrlPtIPAddr;
|
struct sockaddr_storage CtrlPtIPAddr;
|
||||||
|
|
||||||
/** The current value of the variable. This needs to be allocated by
|
/** The current value of the variable. This needs to be allocated by
|
||||||
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
|
* the caller. When finished with it, the SDK frees this {\bf DOMString}. */
|
||||||
@ -817,132 +817,29 @@ struct Upnp_Subscription_Request
|
|||||||
|
|
||||||
struct File_Info
|
struct File_Info
|
||||||
{
|
{
|
||||||
/** The length of the file. A length less than 0 indicates the size
|
/** 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
|
* is unknown, and data will be sent until 0 bytes are returned from
|
||||||
* a read call. */
|
* a read call. */
|
||||||
off_t file_length;
|
off_t file_length;
|
||||||
|
|
||||||
/** The time at which the contents of the file was modified;
|
/** The time at which the contents of the file was modified;
|
||||||
* The time system is always local (not GMT). */
|
* The time system is always local (not GMT). */
|
||||||
time_t last_modified;
|
time_t last_modified;
|
||||||
|
|
||||||
/** If the file is a directory, {\bf is_directory} contains
|
/** If the file is a directory, {\bf is_directory} contains
|
||||||
* a non-zero value. For a regular file, it should be 0. */
|
* a non-zero value. For a regular file, it should be 0. */
|
||||||
int is_directory;
|
int is_directory;
|
||||||
|
|
||||||
/** If the file or directory is readable, this contains
|
/** If the file or directory is readable, this contains
|
||||||
* a non-zero value. If unreadable, it should be set to 0. */
|
* a non-zero value. If unreadable, it should be set to 0. */
|
||||||
int is_readable;
|
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;
|
|
||||||
|
|
||||||
|
/** 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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The type of handle returned by the web server for open requests. */
|
|
||||||
|
|
||||||
typedef void *UpnpWebFileHandle;
|
|
||||||
|
|
||||||
/** The {\bf UpnpVirtualDirCallbacks} structure contains the pointers to
|
|
||||||
* file-related callback functions a device application can register to
|
|
||||||
* virtualize URLs.
|
|
||||||
*/
|
|
||||||
struct UpnpVirtualDirCallbacks
|
|
||||||
{
|
|
||||||
/** Called by the web server to query information on a file. The callback
|
|
||||||
* should return 0 on success or -1 on an error. */
|
|
||||||
int (*get_info) (
|
|
||||||
IN const char *filename, /** The name of the file to query. */
|
|
||||||
OUT struct File_Info *info /** Pointer to a structure to store the
|
|
||||||
information on the file. */
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Called by the web server to open a file. The callback should return
|
|
||||||
* a valid handle if the file can be opened. Otherwise, it should return
|
|
||||||
* {\tt NULL} to signify an error. */
|
|
||||||
UpnpWebFileHandle (*open)(
|
|
||||||
IN const char *filename, /** The name of the file to open. */
|
|
||||||
IN enum UpnpOpenFileMode Mode /** The mode in which to open the file.
|
|
||||||
Valid values are {\tt UPNP_READ} or
|
|
||||||
{\tt UPNP_WRITE}. */
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Called by the web server to perform a sequential read from an open
|
|
||||||
* file. The callback should copy {\bf buflen} bytes from the file into
|
|
||||||
* the buffer.
|
|
||||||
* @return [int] An integer representing one of the following:
|
|
||||||
* \begin{itemize}
|
|
||||||
* \item {\tt 0}: The file contains no more data (EOF).
|
|
||||||
* \item {\tt >0}: A successful read of the number of bytes in the
|
|
||||||
* return code.
|
|
||||||
* \item {\tt <0}: An error occurred reading the file.
|
|
||||||
* \end{itemzie}
|
|
||||||
*/
|
|
||||||
int (*read) (
|
|
||||||
IN UpnpWebFileHandle fileHnd, /** The handle of the file to read. */
|
|
||||||
OUT char *buf, /** The buffer in which to place the
|
|
||||||
data. */
|
|
||||||
IN size_t buflen /** The size of the buffer (i.e. the
|
|
||||||
number of bytes to read). */
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Called by the web server to perform a sequential write to an open
|
|
||||||
* file. The callback should write {\bf buflen} bytes into the file from
|
|
||||||
* the buffer. It should return the actual number of bytes written,
|
|
||||||
* which might be less than {\bf buflen} in the case of a write error.
|
|
||||||
*/
|
|
||||||
int (*write) (
|
|
||||||
IN UpnpWebFileHandle fileHnd, /** The handle of the file to write. */
|
|
||||||
IN char *buf, /** The buffer with the bytes to write. */
|
|
||||||
IN size_t buflen /** The number of bytes to write. */
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Called by the web server to move the file pointer, or offset, into
|
|
||||||
* an open file. The {\bf origin} parameter determines where to start
|
|
||||||
* moving the file pointer. A value of {\tt SEEK_CUR} moves the
|
|
||||||
* file pointer relative to where it is. The {\bf offset} parameter can
|
|
||||||
* be either positive (move forward) or negative (move backward).
|
|
||||||
* {\tt SEEK_END} moves relative to the end of the file. A positive
|
|
||||||
* {\bf offset} extends the file. A negative {\bf offset} moves backward
|
|
||||||
* in the file. Finally, {\tt SEEK_SET} moves to an absolute position in
|
|
||||||
* the file. In this case, {\bf offset} must be positive. The callback
|
|
||||||
* should return 0 on a successful seek or a non-zero value on an error.
|
|
||||||
*/
|
|
||||||
int (*seek) (
|
|
||||||
IN UpnpWebFileHandle fileHnd, /** The handle of the file to move the
|
|
||||||
file pointer. */
|
|
||||||
IN off_t offset, /** The number of bytes to move in the
|
|
||||||
file. Positive values move foward and
|
|
||||||
negative values move backward. Note
|
|
||||||
that this must be positive if the
|
|
||||||
{\bf origin} is {\tt SEEK_SET}. */
|
|
||||||
IN int origin /** The position to move relative to. It
|
|
||||||
can be {\tt SEEK_CUR} to move relative
|
|
||||||
to the current position,
|
|
||||||
{\tt SEEK_END} to move relative to
|
|
||||||
the end of the file, or {\tt
|
|
||||||
SEEK_SET} to specify an absolute
|
|
||||||
offset. */
|
|
||||||
);
|
|
||||||
|
|
||||||
/** Called by the web server to close a file opened via the {\bf open}
|
|
||||||
* callback. It should return 0 on success, or a non-zero value on an
|
|
||||||
* error.
|
|
||||||
*/
|
|
||||||
int (*close) (
|
|
||||||
IN UpnpWebFileHandle fileHnd /** The handle of the file to close. */
|
|
||||||
);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct virtual_Dir_List
|
|
||||||
{
|
|
||||||
struct virtual_Dir_List *next;
|
|
||||||
char dirName[NAME_SIZE];
|
|
||||||
} virtualDirList;
|
|
||||||
|
|
||||||
/** All callback functions share the same prototype, documented below.
|
/** All callback functions share the same prototype, documented below.
|
||||||
* Note that any memory passed to the callback function
|
* Note that any memory passed to the callback function
|
||||||
@ -992,22 +889,22 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Initializes the Linux SDK for UPnP Devices.
|
* \brief Initializes the Linux SDK for UPnP Devices (IPv4 only).
|
||||||
*
|
*
|
||||||
* \deprecated Kept for backwards compatibility. Use UpnpInit2 for new
|
* \deprecated Kept for backwards compatibility. Use UpnpInit2 for new
|
||||||
* implementations.
|
* implementations or where IPv6 is required.
|
||||||
*
|
*
|
||||||
* This function must be called before any other API function can be called.
|
* This function must be called before any other API function can be called.
|
||||||
* It should be called only once. Subsequent calls to this API return a
|
* It should be called only once. Subsequent calls to this API return a
|
||||||
* \c UPNP_E_INIT error code.
|
* \c UPNP_E_INIT error code.
|
||||||
*
|
*
|
||||||
* Optionally, the application can specify a host IP address (in the
|
* Optionally, the application can specify a host IPv4 address (in the
|
||||||
* case of a multi-homed configuration) and a port number to use for
|
* case of a multi-homed configuration) and a port number to use for
|
||||||
* all UPnP operations. Since a port number can be used only by one
|
* all UPnP operations. Since a port number can be used only by one
|
||||||
* process, multiple processes using the SDK must specify
|
* process, multiple processes using the SDK must specify
|
||||||
* different port numbers.
|
* different port numbers.
|
||||||
*
|
*
|
||||||
* If unspecified, the SDK will use the first adapter's IP address
|
* If unspecified, the SDK will use the first IPv4-capable adapter's IP address
|
||||||
* and an arbitrary port.
|
* and an arbitrary port.
|
||||||
*
|
*
|
||||||
* This call is synchronous.
|
* This call is synchronous.
|
||||||
@ -1025,14 +922,55 @@ extern "C" {
|
|||||||
* \li \c UPNP_E_INTERNAL_ERROR: An internal error ocurred.
|
* \li \c UPNP_E_INTERNAL_ERROR: An internal error ocurred.
|
||||||
*/
|
*/
|
||||||
EXPORT_SPEC int UpnpInit(
|
EXPORT_SPEC int UpnpInit(
|
||||||
/*! The host local IP address to use, in string format, for example
|
/*! The host local IPv4 address to use, in string format, for example
|
||||||
* "192.168.0.1", or \c NULL to use the first adapter's IP address. */
|
* "192.168.0.1", or \c NULL to use the first IPv4 adapter's IP address. */
|
||||||
const char *HostIP,
|
const char *HostIP,
|
||||||
/*! 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);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initializes the Linux SDK for UPnP Devices (IPv4 or IPv6).
|
||||||
|
*
|
||||||
|
* This function must be called before any other API function can be called.
|
||||||
|
* It should be called only once. Subsequent calls to this API return a
|
||||||
|
* \c UPNP_E_INIT error code.
|
||||||
|
*
|
||||||
|
* Optionally, the application can specify an interface name (in the
|
||||||
|
* case of a multi-homed configuration) and a port number to use for
|
||||||
|
* all UPnP operations. Since a port number can be used only by one
|
||||||
|
* process, multiple processes using the SDK must specify
|
||||||
|
* different port numbers.
|
||||||
|
*
|
||||||
|
* If unspecified, the SDK will use the first suitable interface and an
|
||||||
|
* arbitrary port.
|
||||||
|
*
|
||||||
|
* This call is synchronous.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_OUTOF_MEMORY: Insufficient resources exist
|
||||||
|
* to initialize the SDK.
|
||||||
|
* \li \c UPNP_E_INIT: The SDK is already initialized.
|
||||||
|
* \li \c UPNP_E_INIT_FAILED: The SDK initialization
|
||||||
|
* failed for an unknown reason.
|
||||||
|
* \li \c UPNP_E_SOCKET_BIND: An error occurred binding a socket.
|
||||||
|
* \li \c UPNP_E_LISTEN: An error occurred listening to a socket.
|
||||||
|
* \li \c UPNP_E_OUTOF_SOCKET: An error ocurred creating a socket.
|
||||||
|
* \li \c UPNP_E_INTERNAL_ERROR: An internal error ocurred.
|
||||||
|
* \li \c UPNP_E_INVALID_INTERFACE: IfName is invalid or does not
|
||||||
|
* have a valid IPv4 or IPv6 addresss configured.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpInit2(
|
||||||
|
/*! The interface name to use by the UPnP SDK operations.
|
||||||
|
* Examples: "eth0", "xl0", "Local Area Connection", \c NULL to
|
||||||
|
* use the first suitable interface. */
|
||||||
|
const char *IfName,
|
||||||
|
/*! Local Port to listen for incoming connections.
|
||||||
|
* \c NULL will pick an arbitrary free port. */
|
||||||
|
unsigned short DestPort);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Terminates the Linux SDK for UPnP Devices.
|
* \brief Terminates the Linux SDK for UPnP Devices.
|
||||||
@ -1070,6 +1008,19 @@ 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.
|
||||||
|
*
|
||||||
|
* If '0' is used as the port number in \b UpnpInit, then this function can be
|
||||||
|
* used to retrieve the actual port allocated to the SDK.
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
* \li On success: The port on which an internal server is listening for IPv6 UPnP
|
||||||
|
* related requests.
|
||||||
|
* \li On error: 0 is returned if \b UpnpInit has not succeeded.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC unsigned short UpnpGetServerPort6(void);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Returns the local IPv4 listening ip address.
|
* \brief Returns the local IPv4 listening ip address.
|
||||||
*
|
*
|
||||||
@ -1084,6 +1035,20 @@ EXPORT_SPEC unsigned short UpnpGetServerPort(void);
|
|||||||
EXPORT_SPEC char *UpnpGetServerIpAddress(void);
|
EXPORT_SPEC char *UpnpGetServerIpAddress(void);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Returns the local IPv6 listening ip address.
|
||||||
|
*
|
||||||
|
* If \c NULL is used as the IPv6 address in \b UpnpInit, then this function can
|
||||||
|
* be used to retrieve the actual interface address on which device is running.
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
* \li On success: The IPv6 address on which an internal server is
|
||||||
|
* listening for UPnP related requests.
|
||||||
|
* \li On error: \c NULL is returned if \b UpnpInit has not succeeded.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC char *UpnpGetServerIp6Address(void);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Registers a device application with the UPnP Library.
|
* \brief Registers a device application with the UPnP Library.
|
||||||
*
|
*
|
||||||
@ -1220,6 +1185,56 @@ EXPORT_SPEC int UpnpRegisterRootDevice2(
|
|||||||
UpnpDevice_Handle* Hnd);
|
UpnpDevice_Handle* Hnd);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Registers a device application for a specific address family with
|
||||||
|
* the UPnP library.
|
||||||
|
*
|
||||||
|
* A device application cannot make any other API calls until it registers
|
||||||
|
* using this function. Device applications can also register as control
|
||||||
|
* points (see \b UpnpRegisterClient to get a control point handle to perform
|
||||||
|
* control point functionality).
|
||||||
|
*
|
||||||
|
* This is synchronous and does not generate any callbacks. Callbacks can occur
|
||||||
|
* as soon as this function returns.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_FINISH: The SDK is already terminated or
|
||||||
|
* is not initialized.
|
||||||
|
* \li \c UPNP_E_INVALID_DESC: The description document was not
|
||||||
|
* a valid device description.
|
||||||
|
* \li \c UPNP_E_INVALID_URL: The URL for the description document
|
||||||
|
* is not valid.
|
||||||
|
* \li \c UPNP_E_INVALID_PARAM: Either \b Callback or \b Hnd
|
||||||
|
* is not a valid pointer or \b DescURL is \c NULL.
|
||||||
|
* \li \c UPNP_E_NETWORK_ERROR: A network error occurred.
|
||||||
|
* \li \c UPNP_E_SOCKET_WRITE: An error or timeout occurred writing
|
||||||
|
* to a socket.
|
||||||
|
* \li \c UPNP_E_SOCKET_READ: An error or timeout occurred reading
|
||||||
|
* from a socket.
|
||||||
|
* \li \c UPNP_E_SOCKET_BIND: An error occurred binding a socket.
|
||||||
|
* \li \c UPNP_E_SOCKET_CONNECT: An error occurred connecting the
|
||||||
|
* socket.
|
||||||
|
* \li \c UPNP_E_OUTOF_SOCKET: Too many sockets are currently
|
||||||
|
* allocated.
|
||||||
|
* \li \c UPNP_E_OUTOF_MEMORY: There are insufficient resources to
|
||||||
|
* register this root device.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpRegisterRootDevice3(
|
||||||
|
/*! [in] Pointer to a string containing the description URL for this root
|
||||||
|
* device instance. */
|
||||||
|
const char *DescUrl,
|
||||||
|
/*! [in] Pointer to the callback function for receiving asynchronous events. */
|
||||||
|
Upnp_FunPtr Callback,
|
||||||
|
/*! [in] Pointer to user data returned with the callback function when invoked. */
|
||||||
|
const void *Cookie,
|
||||||
|
/*! [out] Pointer to a variable to store the new device handle. */
|
||||||
|
UpnpDevice_Handle *Hnd,
|
||||||
|
/*! [in] Address family of this device. Can be AF_INET for an IPv4 device, or
|
||||||
|
* AF_INET6 for an IPv6 device. Defaults to AF_INET. */
|
||||||
|
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.
|
||||||
@ -2592,6 +2607,147 @@ EXPORT_SPEC int UpnpSetWebServerRootDir(
|
|||||||
const char *rootDir);
|
const char *rootDir);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief The type of handle returned by the web server for open requests.
|
||||||
|
*/
|
||||||
|
typedef void *UpnpWebFileHandle;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get-info callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef int (*VDCallback_GetInfo)(
|
||||||
|
/*! [in] The name of the file to query. */
|
||||||
|
const char *filename,
|
||||||
|
/*! [out] Pointer to a structure to store the information on the file. */
|
||||||
|
struct File_Info *info);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the get_info callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_GetInfoCallback(VDCallback_GetInfo callback);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Open callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef UpnpWebFileHandle (*VDCallback_Open)(
|
||||||
|
/*! [in] The name of the file to open. */
|
||||||
|
const char *filename,
|
||||||
|
/*! [in] The mode in which to open the file.
|
||||||
|
* Valid values are \c UPNP_READ or \c UPNP_WRITE. */
|
||||||
|
enum UpnpOpenFileMode Mode);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the open callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_OpenCallback(VDCallback_Open callback);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Read callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef int (*VDCallback_Read)(
|
||||||
|
/*! [in] The handle of the file to read. */
|
||||||
|
UpnpWebFileHandle fileHnd,
|
||||||
|
/*! [out] The buffer in which to place the data. */
|
||||||
|
char *buf,
|
||||||
|
/*! [in] The size of the buffer (i.e. the number of bytes to read). */
|
||||||
|
size_t buflen);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the read callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_ReadCallback(VDCallback_Read callback);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Write callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef int (*VDCallback_Write)(
|
||||||
|
/*! [in] The handle of the file to write. */
|
||||||
|
UpnpWebFileHandle fileHnd,
|
||||||
|
/*! [in] The buffer with the bytes to write. */
|
||||||
|
char *buf,
|
||||||
|
/*! [in] The number of bytes to write. */
|
||||||
|
size_t buflen);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the write callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_WriteCallback(VDCallback_Write callback);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Seek callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef int (*VDCallback_Seek) (
|
||||||
|
/*! [in] The handle of the file to move the file pointer. */
|
||||||
|
UpnpWebFileHandle fileHnd,
|
||||||
|
/*! [in] The number of bytes to move in the file. Positive values
|
||||||
|
* move foward and negative values move backward. Note that
|
||||||
|
* this must be positive if the \b origin is \c SEEK_SET. */
|
||||||
|
off_t offset,
|
||||||
|
/*! [in] The position to move relative to. It can be \c SEEK_CUR
|
||||||
|
* to move relative to the current position, \c SEEK_END to
|
||||||
|
* move relative to the end of the file, or \c SEEK_SET to
|
||||||
|
* specify an absolute offset. */
|
||||||
|
int origin);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the seek callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_SeekCallback(VDCallback_Seek callback);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Close callback function prototype.
|
||||||
|
*/
|
||||||
|
typedef int (*VDCallback_Close)(
|
||||||
|
/*! [in] The handle of the file to close. */
|
||||||
|
UpnpWebFileHandle fileHnd);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Sets the close callback function to be used to access a virtual
|
||||||
|
* directory.
|
||||||
|
*
|
||||||
|
* \return An integer representing one of the following:
|
||||||
|
* \li \c UPNP_E_SUCCESS: The operation completed successfully.
|
||||||
|
* \li \c UPNP_E_INVALID_ARGUMENT: \b callback is not a valid pointer.
|
||||||
|
*/
|
||||||
|
EXPORT_SPEC int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Enables or disables the webserver.
|
* \brief Enables or disables the webserver.
|
||||||
*
|
*
|
||||||
|
@ -7,12 +7,12 @@
|
|||||||
* 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.
|
||||||
*
|
*
|
||||||
@ -33,25 +33,34 @@
|
|||||||
#ifndef UPNP_DEBUG_H
|
#ifndef UPNP_DEBUG_H
|
||||||
#define UPNP_DEBUG_H
|
#define UPNP_DEBUG_H
|
||||||
|
|
||||||
#include "upnp.h"
|
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "ThreadPool.h"
|
||||||
#include "upnpconfig.h"
|
#include "upnpconfig.h"
|
||||||
|
#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 {\tt UpnpSetLogLevel}.
|
* see \c UpnpSetLogLevel.
|
||||||
* The critical level will show only those messages
|
* The critical level will show only those messages
|
||||||
* which can halt the normal processing of the library, like memory
|
* which can halt the normal processing of the library, like memory
|
||||||
* allocation errors. The remaining three levels are just for debugging
|
* allocation errors. The remaining three levels are just for debugging
|
||||||
@ -60,14 +69,11 @@ extern "C" {
|
|||||||
* Info Level displays the other important operational information
|
* Info Level displays the other important operational information
|
||||||
* regarding the working of the library. If the user selects All,
|
* regarding the working of the library. If the user selects All,
|
||||||
* then the library displays all the debugging information that it has.
|
* then the library displays all the debugging information that it has.
|
||||||
* \begin{itemize}
|
* \li \c UPNP_CRITICAL [0]
|
||||||
* \item {\tt UPNP_CRITICAL [0]}
|
* \li \c UPNP_PACKET [1]
|
||||||
* \item {\tt UPNP_PACKET [1]}
|
* \li \c UPNP_INFO [2]
|
||||||
* \item {\tt UPNP_INFO [2]}
|
* \li \c UPNP_ALL [3]
|
||||||
* \item {\tt UPNP_ALL [3]}
|
|
||||||
* \end{itemize}
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum Upnp_Module {
|
typedef enum Upnp_Module {
|
||||||
SSDP,
|
SSDP,
|
||||||
SOAP,
|
SOAP,
|
||||||
@ -79,67 +85,54 @@ typedef enum Upnp_Module {
|
|||||||
HTTP
|
HTTP
|
||||||
} Dbg_Module;
|
} Dbg_Module;
|
||||||
|
|
||||||
/*! @{ */
|
|
||||||
|
/*@{*/
|
||||||
typedef enum Upnp_LogLevel_e {
|
typedef enum Upnp_LogLevel_e {
|
||||||
UPNP_CRITICAL,
|
UPNP_CRITICAL,
|
||||||
UPNP_PACKET,
|
UPNP_PACKET,
|
||||||
UPNP_INFO,
|
UPNP_INFO,
|
||||||
UPNP_ALL
|
UPNP_ALL
|
||||||
} Upnp_LogLevel;
|
} Upnp_LogLevel;
|
||||||
/*! @} */
|
/*@}*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default log level : see {\tt Upnp_LogLevel}
|
* Default log level : see \c Upnp_LogLevel
|
||||||
*/
|
*/
|
||||||
#define UPNP_DEFAULT_LOG_LEVEL UPNP_ALL
|
#define UPNP_DEFAULT_LOG_LEVEL UPNP_ALL
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpInitLog
|
* \brief Initialize the log files.
|
||||||
*
|
*
|
||||||
* Parameters: void
|
* \return -1 if fails or UPNP_E_SUCCESS if succeeds.
|
||||||
*
|
*/
|
||||||
* Description:
|
|
||||||
* This functions initializes the log files
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
* -1 : If fails
|
|
||||||
* UPNP_E_SUCCESS : if success
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int UpnpInitLog(void);
|
int UpnpInitLog(void);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE int UpnpInitLog(void) { return UPNP_E_SUCCESS; }
|
static UPNP_INLINE int UpnpInitLog(void)
|
||||||
|
{
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpSetLogLevel
|
* \brief Set the log level (see \c Upnp_LogLevel).
|
||||||
*
|
*/
|
||||||
* Parameters: Upnp_LogLevel log_level
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions set the log level (see {\tt Upnp_LogLevel}
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpnpSetLogLevel(Upnp_LogLevel log_level);
|
void UpnpSetLogLevel(
|
||||||
|
/*! [in] 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) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpCloseLog
|
* \brief Closes the log files.
|
||||||
*
|
*/
|
||||||
* Parameters: void
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions closes the log files
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpnpCloseLog(void);
|
void UpnpCloseLog(void);
|
||||||
#else
|
#else
|
||||||
@ -147,23 +140,14 @@ static UPNP_INLINE void UpnpCloseLog(void) {}
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpSetLogFileNames
|
* \brief Set the name for error and information files, respectively.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
|
||||||
* IN const char* ErrFileName: name of the error file
|
|
||||||
* IN const char *InfoFileName: name of the information file
|
|
||||||
* IN int size: Size of the buffer
|
|
||||||
* IN int starLength: This parameter provides the width of the banner
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions takes the buffer and writes the buffer in the file as
|
|
||||||
* per the requested banner
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpnpSetLogFileNames(
|
void UpnpSetLogFileNames(
|
||||||
|
/*! [in] Name of the error file. */
|
||||||
const char *ErrFileName,
|
const char *ErrFileName,
|
||||||
|
/*! [in] Name of the information file. */
|
||||||
const char *InfoFileName);
|
const char *InfoFileName);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE void UpnpSetLogFileNames(
|
static UPNP_INLINE void UpnpSetLogFileNames(
|
||||||
@ -172,24 +156,20 @@ static UPNP_INLINE void UpnpSetLogFileNames(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpGetDebugFile
|
* \brief Check if the module is turned on for debug and returns the file
|
||||||
|
* descriptor corresponding to the debug level
|
||||||
*
|
*
|
||||||
* Parameters:
|
* \return NULL if the module is turn off for debug otheriwse returns the
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
* right file descriptor.
|
||||||
* whether debug statement will go to standard output,
|
*/
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function checks if the module is turned on for debug
|
|
||||||
* and returns the file descriptor corresponding to the debug level
|
|
||||||
* Returns: FILE *
|
|
||||||
* NULL : if the module is turn off for debug
|
|
||||||
* else returns the right file descriptor
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module);
|
FILE *UpnpGetDebugFile(
|
||||||
|
/*! [in] The level of the debug logging. It will decide whether debug
|
||||||
|
* statement will go to standard output, or any of the log files. */
|
||||||
|
Upnp_LogLevel level,
|
||||||
|
/*! [in] debug will go in the name of this module. */
|
||||||
|
Dbg_Module module);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module)
|
static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module)
|
||||||
{
|
{
|
||||||
@ -198,60 +178,47 @@ static UPNP_INLINE FILE *UpnpGetDebugFile(Upnp_LogLevel level, Dbg_Module module
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : DebugAtThisLevel
|
* \brief Returns true if debug output should be done in this module.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* \return Nonzero value if true, zero if false.
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
*/
|
||||||
* whether debug statement will go to standard output,
|
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions returns true if debug output should be done in this
|
|
||||||
* module.
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
int DebugAtThisLevel(
|
int DebugAtThisLevel(
|
||||||
IN Upnp_LogLevel DLevel,
|
/*! [in] The level of the debug logging. It will decide whether debug
|
||||||
IN Dbg_Module Module);
|
* statement will go to standard output, or any of the log files. */
|
||||||
|
Upnp_LogLevel DLevel,
|
||||||
|
/*! [in] Debug will go in the name of this module. */
|
||||||
|
Dbg_Module Module);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE int DebugAtThisLevel(
|
static UPNP_INLINE int DebugAtThisLevel(
|
||||||
IN Upnp_LogLevel DLevel,
|
Upnp_LogLevel DLevel,
|
||||||
IN Dbg_Module Module) { return 0; }
|
Dbg_Module Module)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpPrintf
|
* \brief Prints the debug statement either on the standard output or log file
|
||||||
*
|
* along with the information from where this debug statement is coming.
|
||||||
* Parameters:
|
*/
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
|
||||||
* whether debug statement will go to standard output,
|
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
* IN char *DbgFileName: Name of the file from where debug statement is
|
|
||||||
* coming
|
|
||||||
* IN int DbgLineNo : Line number of the file from where debug statement
|
|
||||||
* is coming
|
|
||||||
* IN char * FmtStr, ...: Variable number of arguments that will go
|
|
||||||
* in the debug statement
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions prints the debug statement either on the startdard
|
|
||||||
* output or log file along with the information from where this
|
|
||||||
* debug statement is coming
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpnpPrintf(
|
void UpnpPrintf(
|
||||||
|
/*! [in] The level of the debug logging. It will decide whether debug
|
||||||
|
* statement will go to standard output, or any of the log files. */
|
||||||
Upnp_LogLevel DLevel,
|
Upnp_LogLevel DLevel,
|
||||||
|
/*! [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. */
|
||||||
const char* DbgFileName,
|
const char* DbgFileName,
|
||||||
|
/*! [in] Line number of the file from where debug statement is coming. */
|
||||||
int DbgLineNo,
|
int DbgLineNo,
|
||||||
|
/*! [in] Printf like format specification. */
|
||||||
const char* FmtStr,
|
const char* FmtStr,
|
||||||
|
/*! [in] Printf like Variable number of arguments that will go in the 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 */
|
||||||
@ -265,29 +232,44 @@ static UPNP_INLINE void UpnpPrintf(
|
|||||||
const char* DbgFileName,
|
const char* DbgFileName,
|
||||||
int DbgLineNo,
|
int DbgLineNo,
|
||||||
const char* FmtStr,
|
const char* FmtStr,
|
||||||
...) {}
|
...)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpDisplayBanner
|
* \brief Writes the file name and file number from where debug statement is
|
||||||
*
|
* coming to the log file.
|
||||||
* Parameters:
|
*/
|
||||||
* IN FILE *fd: file descriptor where the banner will be written
|
#ifdef DEBUG
|
||||||
* IN char **lines: The buffer that will be written
|
void UpnpDisplayFileAndLine(
|
||||||
* IN int size: Size of the buffer
|
/*! [in] File descriptor where line number and file name will be written. */
|
||||||
* IN int starLength: This parameter provides the width of the banner
|
FILE *fd,
|
||||||
*
|
/*! [in] Name of the file. */
|
||||||
* Description:
|
const char *DbgFileName,
|
||||||
* This functions takes the buffer and writes the buffer in the file as
|
/*! [in] Line number of the file. */
|
||||||
* per the requested banner
|
int DbgLineNo);
|
||||||
* Returns: void
|
#else
|
||||||
***************************************************************************/
|
static UPNP_INLINE void UpnpDisplayFileAndLine(
|
||||||
|
FILE *fd,
|
||||||
|
const char *DbgFileName,
|
||||||
|
int DbgLineNo) {}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \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. */
|
||||||
FILE *fd,
|
FILE *fd,
|
||||||
|
/*! [in] The buffer that will be written. */
|
||||||
const char **lines,
|
const char **lines,
|
||||||
|
/*! [in] Size of the buffer. */
|
||||||
size_t size,
|
size_t size,
|
||||||
|
/*! [in] This parameter provides the width of the banner. */
|
||||||
int starlength);
|
int starlength);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE void UpnpDisplayBanner(
|
static UPNP_INLINE void UpnpDisplayBanner(
|
||||||
@ -298,33 +280,49 @@ static UPNP_INLINE void UpnpDisplayBanner(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
/*!
|
||||||
* Function : UpnpDisplayFileAndLine
|
* \brief Prints thread pool statistics.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
|
||||||
* IN FILE *fd: File descriptor where line number and file name will be
|
|
||||||
* written
|
|
||||||
* IN char *DbgFileName: Name of the file
|
|
||||||
* IN int DbgLineNo : Line number of the file
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function writes the file name and file number from where
|
|
||||||
* debug statement is coming to the log file
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
void UpnpDisplayFileAndLine(
|
void PrintThreadPoolStats(
|
||||||
FILE *fd,
|
/*! [in] The thread pool. */
|
||||||
|
ThreadPool *tp,
|
||||||
|
/*! [in] The file name that called this function, use the macro __FILE__. */
|
||||||
const char *DbgFileName,
|
const char *DbgFileName,
|
||||||
int DbgLineNo);
|
/*! [in] The line number that the function was called, use the macro __LINE__. */
|
||||||
|
int DbgLineNo,
|
||||||
|
/*! [in] The message. */
|
||||||
|
const char *msg);
|
||||||
#else
|
#else
|
||||||
static UPNP_INLINE void UpnpDisplayFileAndLine(
|
static UPNP_INLINE void PrintThreadPoolStats(
|
||||||
FILE *fd,
|
ThreadPool *tp,
|
||||||
const char *DbgFileName,
|
const char *DbgFileName,
|
||||||
int DbgLineNo) {}
|
int DbgLineNo,
|
||||||
|
const char *msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*! @} */
|
|
||||||
|
/*!
|
||||||
|
* \brief Print the node names and values of a XML tree.
|
||||||
|
*/
|
||||||
|
#ifdef DEBUG
|
||||||
|
void printNodes(
|
||||||
|
/*! [in] The root of the tree to print. */
|
||||||
|
IXML_Node *tmpRoot,
|
||||||
|
/*! [in] The depth to print. */
|
||||||
|
int depth);
|
||||||
|
#else
|
||||||
|
static UPNP_INLINE void printNodes(
|
||||||
|
IXML_Node *tmpRoot,
|
||||||
|
int depth)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*@}*/
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -6,12 +6,12 @@
|
|||||||
* 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.
|
||||||
*
|
*
|
||||||
@ -30,148 +30,92 @@
|
|||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "ithread.h"
|
||||||
|
#include "ixml.h"
|
||||||
|
#include "upnp.h"
|
||||||
#include "upnpdebug.h"
|
#include "upnpdebug.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "ithread.h"
|
|
||||||
#include "upnp.h"
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//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;
|
||||||
|
|
||||||
// Global log level
|
/*! Global log level */
|
||||||
static Upnp_LogLevel g_log_level = UPNP_DEFAULT_LOG_LEVEL;
|
static Upnp_LogLevel g_log_level = UPNP_DEFAULT_LOG_LEVEL;
|
||||||
|
|
||||||
//File handle for the error log file
|
/*! File handle for the error log file */
|
||||||
static FILE *ErrFileHnd = NULL;
|
static FILE *ErrFileHnd = NULL;
|
||||||
|
|
||||||
//File handle for the information log file
|
/*! File handle for the information log file */
|
||||||
static FILE *InfoFileHnd = NULL;
|
static FILE *InfoFileHnd = NULL;
|
||||||
|
|
||||||
//Name of the error file
|
/*! Name of the error file */
|
||||||
static const char *errFileName = "IUpnpErrFile.txt";
|
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
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : UpnpSetLogFileNames
|
int UpnpInitLog(void)
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN const char* ErrFileName: name of the error file
|
|
||||||
* IN const char *InfoFileName: name of the information file
|
|
||||||
* IN int size: Size of the buffer
|
|
||||||
* IN int starLength: This parameter provides the width of the banner
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions takes the buffer and writes the buffer in the file as
|
|
||||||
* per the requested banner
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
UpnpSetLogFileNames ( IN const char *ErrFileName,
|
|
||||||
IN const char *InfoFileName )
|
|
||||||
{
|
{
|
||||||
if( ErrFileName ) {
|
ithread_mutex_init(&GlobalDebugMutex, NULL);
|
||||||
errFileName = ErrFileName;
|
if(DEBUG_TARGET == 1) {
|
||||||
}
|
if((ErrFileHnd = fopen( errFileName, "a")) == NULL) {
|
||||||
if( InfoFileName ) {
|
return -1;
|
||||||
infoFileName = InfoFileName;
|
}
|
||||||
}
|
if((InfoFileHnd = fopen( infoFileName, "a")) == NULL) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
void UpnpSetLogLevel(Upnp_LogLevel log_level)
|
||||||
* Function : UpnpInitLog
|
|
||||||
*
|
|
||||||
* Parameters: void
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions initializes the log files
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
* -1 : If fails
|
|
||||||
* UPNP_E_SUCCESS : if success
|
|
||||||
***************************************************************************/
|
|
||||||
int
|
|
||||||
UpnpInitLog(void)
|
|
||||||
{
|
|
||||||
ithread_mutex_init( &GlobalDebugMutex, NULL );
|
|
||||||
|
|
||||||
if( DEBUG_TARGET == 1 ) {
|
|
||||||
if( ( ErrFileHnd = fopen( errFileName, "a" ) ) == NULL )
|
|
||||||
return -1;
|
|
||||||
if( ( InfoFileHnd = fopen( infoFileName, "a" ) ) == NULL )
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return UPNP_E_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : UpnpSetLogLevel
|
|
||||||
*
|
|
||||||
* Parameters: Upnp_LogLevel log_level
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions set the log level (see {\tt Upnp_LogLevel}
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
UpnpSetLogLevel (Upnp_LogLevel log_level)
|
|
||||||
{
|
{
|
||||||
g_log_level = log_level;
|
g_log_level = log_level;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
void UpnpCloseLog(void)
|
||||||
* Function : UpnpCloseLog
|
|
||||||
*
|
|
||||||
* Parameters: void
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions closes the log files
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
void
|
|
||||||
UpnpCloseLog(void)
|
|
||||||
{
|
{
|
||||||
if( DEBUG_TARGET == 1 ) {
|
if (DEBUG_TARGET == 1) {
|
||||||
fflush( ErrFileHnd );
|
fflush(ErrFileHnd);
|
||||||
fflush( InfoFileHnd );
|
fflush(InfoFileHnd);
|
||||||
fclose( ErrFileHnd );
|
fclose(ErrFileHnd);
|
||||||
fclose( InfoFileHnd );
|
fclose(InfoFileHnd);
|
||||||
}
|
}
|
||||||
ithread_mutex_destroy( &GlobalDebugMutex );
|
ithread_mutex_destroy(&GlobalDebugMutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void UpnpSetLogFileNames(
|
||||||
|
const char *ErrFileName,
|
||||||
|
const char *InfoFileName)
|
||||||
|
{
|
||||||
|
if (ErrFileName) {
|
||||||
|
errFileName = ErrFileName;
|
||||||
|
}
|
||||||
|
if (InfoFileName) {
|
||||||
|
infoFileName = InfoFileName;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : DebugAtThisLevel
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
|
||||||
* whether debug statement will go to standard output,
|
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions returns true if debug output should be done in this
|
|
||||||
* module.
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
|
||||||
int DebugAtThisLevel(
|
int DebugAtThisLevel(
|
||||||
IN Upnp_LogLevel DLevel,
|
Upnp_LogLevel DLevel,
|
||||||
IN Dbg_Module Module)
|
Dbg_Module Module)
|
||||||
{
|
{
|
||||||
int ret = DLevel <= g_log_level;
|
int ret = DLevel <= g_log_level;
|
||||||
ret &=
|
ret &=
|
||||||
@ -186,38 +130,15 @@ int DebugAtThisLevel(
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : UpnpPrintf
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
|
||||||
* whether debug statement will go to standard output,
|
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
* IN char *DbgFileName: Name of the file from where debug statement is
|
|
||||||
* coming
|
|
||||||
* IN int DbgLineNo : Line number of the file from where debug statement
|
|
||||||
* is coming
|
|
||||||
* IN char * FmtStr, ...: Variable number of arguments that will go
|
|
||||||
* in the debug statement
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions prints the debug statement either on the startdard
|
|
||||||
* output or log file along with the information from where this debug
|
|
||||||
* statement is coming
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
|
||||||
void UpnpPrintf(
|
void UpnpPrintf(
|
||||||
IN Upnp_LogLevel DLevel,
|
Upnp_LogLevel DLevel,
|
||||||
IN Dbg_Module Module,
|
Dbg_Module Module,
|
||||||
IN const char *DbgFileName,
|
const char *DbgFileName,
|
||||||
IN int DbgLineNo,
|
int DbgLineNo,
|
||||||
IN const char *FmtStr,
|
const char *FmtStr,
|
||||||
... )
|
...)
|
||||||
{
|
{
|
||||||
va_list ArgList;
|
va_list ArgList;
|
||||||
|
|
||||||
@ -249,27 +170,9 @@ void UpnpPrintf(
|
|||||||
va_end(ArgList);
|
va_end(ArgList);
|
||||||
ithread_mutex_unlock(&GlobalDebugMutex);
|
ithread_mutex_unlock(&GlobalDebugMutex);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
FILE *GetDebugFile(Upnp_LogLevel DLevel, Dbg_Module Module)
|
||||||
* Function : UpnpGetDebugFile
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN Upnp_LogLevel DLevel: The level of the debug logging. It will decide
|
|
||||||
* whether debug statement will go to standard output,
|
|
||||||
* or any of the log files.
|
|
||||||
* IN Dbg_Module Module: debug will go in the name of this module
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function checks if the module is turned on for debug
|
|
||||||
* and returns the file descriptor corresponding to the debug level
|
|
||||||
* Returns: FILE *
|
|
||||||
* NULL : if the module is turn off for debug
|
|
||||||
* else returns the right file descriptor
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
|
||||||
FILE *GetDebugFile( Upnp_LogLevel DLevel, Dbg_Module Module )
|
|
||||||
{
|
{
|
||||||
FILE *ret;
|
FILE *ret;
|
||||||
|
|
||||||
@ -287,28 +190,12 @@ FILE *GetDebugFile( Upnp_LogLevel DLevel, Dbg_Module Module )
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : UpnpDisplayFileAndLine
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN FILE *fd: File descriptor where line number and file name will be
|
|
||||||
* written
|
|
||||||
* IN char *DbgFileName: Name of the file
|
|
||||||
* IN int DbgLineNo : Line number of the file
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function writes the file name and file number from where
|
|
||||||
* debug statement is coming to the log file
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
|
||||||
void UpnpDisplayFileAndLine(
|
void UpnpDisplayFileAndLine(
|
||||||
IN FILE * fd,
|
FILE *fd,
|
||||||
IN const char *DbgFileName,
|
const char *DbgFileName,
|
||||||
IN int DbgLineNo)
|
int DbgLineNo)
|
||||||
{
|
{
|
||||||
#define NLINES 2
|
#define NLINES 2
|
||||||
#define MAX_LINE_SIZE 512
|
#define MAX_LINE_SIZE 512
|
||||||
@ -324,7 +211,12 @@ void UpnpDisplayFileAndLine(
|
|||||||
|
|
||||||
/* 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",
|
||||||
(unsigned long int)ithread_self());
|
#ifdef WIN32
|
||||||
|
(unsigned long int)ithread_self().p
|
||||||
|
#else
|
||||||
|
(unsigned long int)ithread_self()
|
||||||
|
#endif
|
||||||
|
);
|
||||||
if (DbgFileName) {
|
if (DbgFileName) {
|
||||||
sprintf(buf[1],
|
sprintf(buf[1],
|
||||||
"FILE: %s, LINE: %d",
|
"FILE: %s, LINE: %d",
|
||||||
@ -336,29 +228,13 @@ void UpnpDisplayFileAndLine(
|
|||||||
UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS);
|
UpnpDisplayBanner(fd, lines, NLINES, NUMBER_OF_STARS);
|
||||||
fflush(fd);
|
fflush(fd);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* Function : UpnpDisplayBanner
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN FILE *fd: file descriptor where the banner will be written
|
|
||||||
* IN char **lines: The buffer that will be written
|
|
||||||
* IN int size: Size of the buffer
|
|
||||||
* IN int starLength: This parameter provides the width of the banner
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This functions takes the buffer and writes the buffer in the file as
|
|
||||||
* per the requested banner
|
|
||||||
* Returns: void
|
|
||||||
***************************************************************************/
|
|
||||||
#ifdef DEBUG
|
|
||||||
void UpnpDisplayBanner(
|
void UpnpDisplayBanner(
|
||||||
IN FILE * fd,
|
FILE * fd,
|
||||||
IN const char **lines,
|
const char **lines,
|
||||||
IN size_t size,
|
size_t size,
|
||||||
IN int starLength)
|
int starLength)
|
||||||
{
|
{
|
||||||
int leftMarginLength = starLength / 2 + 1;
|
int leftMarginLength = starLength / 2 + 1;
|
||||||
int rightMarginLength = starLength / 2 + 1;
|
int rightMarginLength = starLength / 2 + 1;
|
||||||
@ -399,12 +275,81 @@ void UpnpDisplayBanner(
|
|||||||
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);
|
||||||
|
|
||||||
free( currentLine );
|
free(currentLine);
|
||||||
free( stars );
|
free(stars);
|
||||||
free( rightMargin );
|
free(rightMargin);
|
||||||
free( leftMargin );
|
free(leftMargin);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void printNodes(IXML_Node *tmpRoot, int depth)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
IXML_NodeList *NodeList1;
|
||||||
|
IXML_Node *ChildNode1;
|
||||||
|
unsigned short NodeType;
|
||||||
|
const DOMString NodeValue;
|
||||||
|
const DOMString NodeName;
|
||||||
|
NodeList1 = ixmlNode_getChildNodes(tmpRoot);
|
||||||
|
for (i = 0; i < 100; ++i) {
|
||||||
|
ChildNode1 = ixmlNodeList_item(NodeList1, i);
|
||||||
|
if (ChildNode1 == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printNodes(ChildNode1, depth+1);
|
||||||
|
NodeType = ixmlNode_getNodeType(ChildNode1);
|
||||||
|
NodeValue = ixmlNode_getNodeValue(ChildNode1);
|
||||||
|
NodeName = ixmlNode_getNodeName(ChildNode1);
|
||||||
|
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
|
||||||
|
"DEPTH-%2d-IXML_Node Type %d, "
|
||||||
|
"IXML_Node Name: %s, IXML_Node Value: %s\n",
|
||||||
|
depth, NodeType, NodeName, NodeValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* DEBUG */
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ static int ScheduleGenaAutoRenew(
|
|||||||
/*! [in] The time out value of the subscription. */
|
/*! [in] The time out value of the subscription. */
|
||||||
IN int TimeOut,
|
IN int TimeOut,
|
||||||
/*! [in] Subscription being renewed. */
|
/*! [in] Subscription being renewed. */
|
||||||
IN client_subscription *sub)
|
IN ClientSubscription *sub)
|
||||||
{
|
{
|
||||||
struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
|
struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
|
||||||
upnp_timeout *RenewEvent = NULL;
|
upnp_timeout *RenewEvent = NULL;
|
||||||
@ -300,14 +300,24 @@ static int gena_subscribe(
|
|||||||
"TIMEOUT: Second-", timeout_str );
|
"TIMEOUT: Second-", timeout_str );
|
||||||
} else {
|
} else {
|
||||||
// subscribe
|
// subscribe
|
||||||
|
if( dest_url.hostport.IPaddress.ss_family == AF_INET6 ) {
|
||||||
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://", LOCAL_HOST, ":", LOCAL_PORT, "/>",
|
"CALLBACK: <http://[", gIF_IPV6, "]:", LOCAL_PORT_V6, "/>",
|
||||||
|
"NT: upnp:event",
|
||||||
|
"TIMEOUT: Second-", timeout_str );
|
||||||
|
} else {
|
||||||
|
return_code = http_MakeMessage(
|
||||||
|
&request, 1, 1,
|
||||||
|
"q" "sssdsc" "sc" "sscc",
|
||||||
|
HTTPMETHOD_SUBSCRIBE, &dest_url,
|
||||||
|
"CALLBACK: <http://", gIF_IPV4, ":", LOCAL_PORT_V4, "/>",
|
||||||
"NT: upnp:event",
|
"NT: upnp:event",
|
||||||
"TIMEOUT: Second-", timeout_str);
|
"TIMEOUT: Second-", timeout_str);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (return_code != 0) {
|
if (return_code != 0) {
|
||||||
return return_code;
|
return return_code;
|
||||||
}
|
}
|
||||||
@ -368,7 +378,7 @@ static int gena_subscribe(
|
|||||||
|
|
||||||
int genaUnregisterClient(UpnpClient_Handle client_handle)
|
int genaUnregisterClient(UpnpClient_Handle client_handle)
|
||||||
{
|
{
|
||||||
client_subscription sub_copy;
|
ClientSubscription sub_copy;
|
||||||
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;
|
||||||
@ -413,10 +423,10 @@ int genaUnSubscribe(
|
|||||||
UpnpClient_Handle client_handle,
|
UpnpClient_Handle client_handle,
|
||||||
const Upnp_SID in_sid)
|
const Upnp_SID in_sid)
|
||||||
{
|
{
|
||||||
client_subscription *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;
|
||||||
client_subscription sub_copy;
|
ClientSubscription sub_copy;
|
||||||
http_parser_t response;
|
http_parser_t response;
|
||||||
|
|
||||||
// validate handle and sid
|
// validate handle and sid
|
||||||
@ -467,7 +477,7 @@ int genaSubscribe(
|
|||||||
Upnp_SID out_sid)
|
Upnp_SID out_sid)
|
||||||
{
|
{
|
||||||
int return_code = GENA_SUCCESS;
|
int return_code = GENA_SUCCESS;
|
||||||
client_subscription *newSubscription = NULL;
|
ClientSubscription *newSubscription = NULL;
|
||||||
uuid_upnp uid;
|
uuid_upnp uid;
|
||||||
Upnp_SID temp_sid;
|
Upnp_SID temp_sid;
|
||||||
char *ActualSID = NULL;
|
char *ActualSID = NULL;
|
||||||
@ -517,7 +527,7 @@ int genaSubscribe(
|
|||||||
strcpy( EventURL, PublisherURL );
|
strcpy( EventURL, PublisherURL );
|
||||||
|
|
||||||
// fill subscription
|
// fill subscription
|
||||||
newSubscription = (client_subscription *)malloc(sizeof (client_subscription));
|
newSubscription = (ClientSubscription *)malloc(sizeof (ClientSubscription));
|
||||||
if (newSubscription == NULL) {
|
if (newSubscription == NULL) {
|
||||||
return_code = UPNP_E_OUTOF_MEMORY;
|
return_code = UPNP_E_OUTOF_MEMORY;
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
@ -552,8 +562,8 @@ int genaRenewSubscription(
|
|||||||
int *TimeOut)
|
int *TimeOut)
|
||||||
{
|
{
|
||||||
int return_code = GENA_SUCCESS;
|
int return_code = GENA_SUCCESS;
|
||||||
client_subscription *sub = NULL;
|
ClientSubscription *sub = NULL;
|
||||||
client_subscription sub_copy;
|
ClientSubscription sub_copy;
|
||||||
struct Handle_Info *handle_info;
|
struct Handle_Info *handle_info;
|
||||||
char *ActualSID;
|
char *ActualSID;
|
||||||
ThreadPoolJob tempJob;
|
ThreadPoolJob tempJob;
|
||||||
@ -657,7 +667,7 @@ void gena_process_notification_event(
|
|||||||
IXML_Document *ChangedVars = NULL;
|
IXML_Document *ChangedVars = NULL;
|
||||||
int eventKey;
|
int eventKey;
|
||||||
token sid;
|
token sid;
|
||||||
client_subscription *subscription = NULL;
|
ClientSubscription *subscription = NULL;
|
||||||
struct Handle_Info *handle_info;
|
struct Handle_Info *handle_info;
|
||||||
void *cookie;
|
void *cookie;
|
||||||
Upnp_FunPtr callback;
|
Upnp_FunPtr callback;
|
||||||
|
@ -1241,7 +1241,7 @@ void gena_process_subscription_request(
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY ONE DEVICE
|
// CURRENTLY, ONLY ONE DEVICE
|
||||||
if (GetDeviceHandleInfo(
|
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);
|
||||||
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
|
error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
|
||||||
@ -1409,7 +1409,7 @@ void gena_process_subscription_renewal_request(
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
||||||
if (GetDeviceHandleInfo(
|
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 );
|
||||||
membuffer_destroy( &event_url_path );
|
membuffer_destroy( &event_url_path );
|
||||||
@ -1520,7 +1520,7 @@ void gena_process_unsubscribe_request(
|
|||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
// CURRENTLY, ONLY SUPPORT ONE DEVICE
|
||||||
if (GetDeviceHandleInfo(
|
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 );
|
||||||
membuffer_destroy( &event_url_path );
|
membuffer_destroy( &event_url_path );
|
||||||
|
@ -43,8 +43,8 @@
|
|||||||
* Function : copy_client_subscription
|
* Function : copy_client_subscription
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * in ; - source client subscription
|
* ClientSubscription * in ; - source client subscription
|
||||||
* client_subscription * out ; - destination client subscription
|
* ClientSubscription * out ; - destination client subscription
|
||||||
*
|
*
|
||||||
* Description : Make a copy of the client subscription data
|
* Description : Make a copy of the client subscription data
|
||||||
*
|
*
|
||||||
@ -54,8 +54,8 @@
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
CLIENTONLY( int copy_client_subscription( ClientSubscription * in,
|
||||||
client_subscription * out ) {
|
ClientSubscription * out ) {
|
||||||
int len = strlen( in->ActualSID ) + 1;
|
int len = strlen( in->ActualSID ) + 1;
|
||||||
int len1 = strlen( in->EventURL ) + 1;
|
int len1 = strlen( in->EventURL ) + 1;
|
||||||
memcpy( out->sid, in->sid, SID_SIZE );
|
memcpy( out->sid, in->sid, SID_SIZE );
|
||||||
@ -77,7 +77,7 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
* Function : free_client_subscription
|
* Function : free_client_subscription
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * sub ; - Client subscription to be freed
|
* ClientSubscription * sub ; - Client subscription to be freed
|
||||||
*
|
*
|
||||||
* Description : Free memory allocated for client subscription data.
|
* Description : Free memory allocated for client subscription data.
|
||||||
* Remove timer thread associated with this subscription event.
|
* Remove timer thread associated with this subscription event.
|
||||||
@ -86,7 +86,7 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void free_client_subscription( client_subscription * sub ) {
|
void free_client_subscription( ClientSubscription * sub ) {
|
||||||
upnp_timeout * event; ThreadPoolJob tempJob; if( sub ) {
|
upnp_timeout * event; ThreadPoolJob tempJob; if( sub ) {
|
||||||
if( sub->ActualSID )
|
if( sub->ActualSID )
|
||||||
free( sub->ActualSID ); if( sub->EventURL )
|
free( sub->ActualSID ); if( sub->EventURL )
|
||||||
@ -106,7 +106,7 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
* Function : freeClientSubList
|
* Function : freeClientSubList
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * list ; Client subscription
|
* ClientSubscription * list ; Client subscription
|
||||||
*
|
*
|
||||||
* Description : Free the client subscription table.
|
* Description : Free the client subscription table.
|
||||||
*
|
*
|
||||||
@ -114,8 +114,8 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void freeClientSubList( client_subscription * list ) {
|
void freeClientSubList( ClientSubscription * list ) {
|
||||||
client_subscription * next; while( list ) {
|
ClientSubscription * next; while( list ) {
|
||||||
free_client_subscription( list );
|
free_client_subscription( list );
|
||||||
next = list->next; free( list ); list = next;}
|
next = list->next; free( list ); list = next;}
|
||||||
}
|
}
|
||||||
@ -124,7 +124,7 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
* Function : RemoveClientSubClientSID
|
* Function : RemoveClientSubClientSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription **head ; Head of the subscription list
|
* ClientSubscription **head ; Head of the subscription list
|
||||||
* const Upnp_SID sid ; Subscription ID to be mactched
|
* const Upnp_SID sid ; Subscription ID to be mactched
|
||||||
*
|
*
|
||||||
* Description : Remove the client subscription matching the
|
* Description : Remove the client subscription matching the
|
||||||
@ -135,10 +135,10 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void RemoveClientSubClientSID( client_subscription ** head,
|
void RemoveClientSubClientSID( ClientSubscription ** head,
|
||||||
const Upnp_SID sid ) {
|
const Upnp_SID sid ) {
|
||||||
client_subscription * finger = ( *head );
|
ClientSubscription * finger = ( *head );
|
||||||
client_subscription * previous = NULL; while( finger ) {
|
ClientSubscription * previous = NULL; while( finger ) {
|
||||||
if( !( strcmp( sid, finger->sid ) ) ) {
|
if( !( strcmp( sid, finger->sid ) ) ) {
|
||||||
if( previous )
|
if( previous )
|
||||||
previous->next = finger->next;
|
previous->next = finger->next;
|
||||||
@ -156,20 +156,20 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
* Function : GetClientSubClientSID
|
* Function : GetClientSubClientSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription *head ; Head of the subscription list
|
* ClientSubscription *head ; Head of the subscription list
|
||||||
* const Upnp_SID sid ; Subscription ID to be matched
|
* const Upnp_SID sid ; Subscription ID to be matched
|
||||||
*
|
*
|
||||||
* Description : Return the client subscription from the client table
|
* Description : Return the client subscription from the client table
|
||||||
* that matches const Upnp_SID sid subscrition id value.
|
* that matches const Upnp_SID sid subscrition id value.
|
||||||
*
|
*
|
||||||
* Return : client_subscription * ; The matching subscription
|
* Return : ClientSubscription * ; The matching subscription
|
||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
client_subscription *
|
ClientSubscription *
|
||||||
GetClientSubClientSID( client_subscription * head,
|
GetClientSubClientSID( ClientSubscription * head,
|
||||||
const Upnp_SID sid ) {
|
const Upnp_SID sid ) {
|
||||||
client_subscription * next = head; while( next ) {
|
ClientSubscription * next = head; while( next ) {
|
||||||
if( !strcmp( next->sid, sid ) )
|
if( !strcmp( next->sid, sid ) )
|
||||||
break;
|
break;
|
||||||
else
|
else
|
||||||
@ -182,21 +182,21 @@ CLIENTONLY( int copy_client_subscription( client_subscription * in,
|
|||||||
* Function : GetClientSubActualSID
|
* Function : GetClientSubActualSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription *head ; Head of the subscription list
|
* ClientSubscription *head ; Head of the subscription list
|
||||||
* token * sid ; Subscription ID to be matched
|
* token * sid ; Subscription ID to be matched
|
||||||
*
|
*
|
||||||
* Description : Returns the client subscription from the client
|
* Description : Returns the client subscription from the client
|
||||||
* subscription table that has the matching token * sid buffer
|
* subscription table that has the matching token * sid buffer
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* Return : client_subscription * ; The matching subscription
|
* Return : ClientSubscription * ; The matching subscription
|
||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
client_subscription *
|
ClientSubscription *
|
||||||
GetClientSubActualSID( client_subscription * head,
|
GetClientSubActualSID( ClientSubscription * head,
|
||||||
token * sid ) {
|
token * sid ) {
|
||||||
client_subscription * next = head; while( next ) {
|
ClientSubscription * next = head; while( next ) {
|
||||||
|
|
||||||
if( !memcmp( next->ActualSID, sid->buff, sid->size ) )
|
if( !memcmp( next->ActualSID, sid->buff, sid->size ) )
|
||||||
break;
|
break;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,33 +1,34 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// 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 defines the Web Server and has functions to carry out
|
* Purpose: This file defines the Web Server and has functions to carry out
|
||||||
@ -52,18 +53,28 @@
|
|||||||
#include "upnp.h"
|
#include "upnp.h"
|
||||||
#include "upnpapi.h"
|
#include "upnpapi.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "VirtualDir.h"
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#ifndef UPNP_USE_BCBPP
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef UPNP_USE_BCBPP
|
||||||
|
/* Do not #include <inttypes.h> */
|
||||||
|
/* Do not #include <stdint.h> */
|
||||||
|
#else
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif /* !UPNP_USE_BCBPP */
|
||||||
#ifndef WIN32
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Do not #include <unistd.h> */
|
||||||
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -301,8 +312,8 @@ get_content_type( IN const char *filename,
|
|||||||
OUT DOMString * content_type )
|
OUT DOMString * content_type )
|
||||||
{
|
{
|
||||||
const char *extension;
|
const char *extension;
|
||||||
const char *type,
|
const char *type;
|
||||||
*subtype;
|
const char *subtype;
|
||||||
xboolean ctype_found = FALSE;
|
xboolean ctype_found = FALSE;
|
||||||
char *temp = NULL;
|
char *temp = NULL;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
@ -311,13 +322,13 @@ get_content_type( IN const char *filename,
|
|||||||
|
|
||||||
// get ext
|
// get ext
|
||||||
extension = strrchr( filename, '.' );
|
extension = strrchr( filename, '.' );
|
||||||
if( extension != NULL ) {
|
if (extension != NULL) {
|
||||||
if( search_extension( extension + 1, &type, &subtype ) == 0 ) {
|
if( search_extension( extension + 1, &type, &subtype ) == 0 ) {
|
||||||
ctype_found = TRUE;
|
ctype_found = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !ctype_found ) {
|
if (!ctype_found) {
|
||||||
// unknown content type
|
// unknown content type
|
||||||
type = gMediaTypes[APPLICATION_INDEX];
|
type = gMediaTypes[APPLICATION_INDEX];
|
||||||
subtype = "octet-stream";
|
subtype = "octet-stream";
|
||||||
@ -325,15 +336,13 @@ get_content_type( IN const char *filename,
|
|||||||
|
|
||||||
length = strlen( type ) + strlen( "/" ) + strlen( subtype ) + 1;
|
length = strlen( type ) + strlen( "/" ) + strlen( subtype ) + 1;
|
||||||
temp = ( char * )malloc( length );
|
temp = ( char * )malloc( length );
|
||||||
|
if (!temp) {
|
||||||
if( !temp ) {
|
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf( temp, "%s/%s", type, subtype );
|
sprintf( temp, "%s/%s", type, subtype );
|
||||||
( *content_type ) = ixmlCloneDOMString( temp );
|
( *content_type ) = ixmlCloneDOMString( temp );
|
||||||
|
|
||||||
free( temp );
|
free(temp);
|
||||||
|
|
||||||
if( !content_type ) {
|
if( !content_type ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
@ -521,40 +530,33 @@ web_server_set_alias( IN const char *alias_name,
|
|||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function: web_server_init
|
int web_server_init()
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* none
|
|
||||||
*
|
|
||||||
* Description: Initilialize the different documents. Initialize the
|
|
||||||
* memory for root directory for web server. Call to initialize global
|
|
||||||
* XML document. Sets bWebServerState to WEB_SERVER_ENABLED
|
|
||||||
*
|
|
||||||
* Returns:
|
|
||||||
* 0 - OK
|
|
||||||
* UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here
|
|
||||||
************************************************************************/
|
|
||||||
int
|
|
||||||
web_server_init( void )
|
|
||||||
{
|
{
|
||||||
int ret_code;
|
int ret = 0;
|
||||||
|
if (bWebServerState == WEB_SERVER_DISABLED) {
|
||||||
|
// decode media list
|
||||||
|
media_list_init();
|
||||||
|
membuffer_init(&gDocumentRootDir);
|
||||||
|
glob_alias_init();
|
||||||
|
pVirtualDirList = NULL;
|
||||||
|
|
||||||
if( bWebServerState == WEB_SERVER_DISABLED ) {
|
// Initialize callbacks
|
||||||
media_list_init(); // decode media list
|
virtualDirCallback.get_info = NULL;
|
||||||
membuffer_init( &gDocumentRootDir );
|
virtualDirCallback.open = NULL;
|
||||||
glob_alias_init();
|
virtualDirCallback.read = NULL;
|
||||||
|
virtualDirCallback.write = NULL;
|
||||||
|
virtualDirCallback.seek = NULL;
|
||||||
|
virtualDirCallback.close = NULL;
|
||||||
|
|
||||||
pVirtualDirList = NULL;
|
if (ithread_mutex_init(&gWebMutex, NULL) == -1) {
|
||||||
|
ret = UPNP_E_OUTOF_MEMORY;
|
||||||
|
} else {
|
||||||
|
bWebServerState = WEB_SERVER_ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ret_code = ithread_mutex_init( &gWebMutex, NULL );
|
return ret;
|
||||||
if( ret_code == -1 ) {
|
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
|
||||||
}
|
|
||||||
bWebServerState = WEB_SERVER_ENABLED;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -593,7 +595,7 @@ web_server_destroy( void )
|
|||||||
* Function: get_file_info
|
* Function: get_file_info
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN const char* filename ; Filename having the description document
|
* IN const char *filename; Filename having the description document
|
||||||
* OUT struct File_Info * info ; File information object having file
|
* OUT struct File_Info * info ; File information object having file
|
||||||
* attributes such as filelength, when was the file last
|
* attributes such as filelength, when was the file last
|
||||||
* modified, whether a file or a directory and whether the
|
* modified, whether a file or a directory and whether the
|
||||||
@ -610,45 +612,45 @@ static int
|
|||||||
get_file_info( IN const char *filename,
|
get_file_info( IN const char *filename,
|
||||||
OUT struct File_Info *info )
|
OUT struct File_Info *info )
|
||||||
{
|
{
|
||||||
int code;
|
int code;
|
||||||
struct stat s;
|
struct stat s;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
info->content_type = NULL;
|
info->content_type = NULL;
|
||||||
|
|
||||||
code = stat( filename, &s );
|
code = stat(filename, &s);
|
||||||
if( code == -1 ) {
|
if (code == -1) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( S_ISDIR( s.st_mode ) ) {
|
if (S_ISDIR(s.st_mode)) {
|
||||||
info->is_directory = TRUE;
|
info->is_directory = TRUE;
|
||||||
} else if( S_ISREG( s.st_mode ) ) {
|
} else if (S_ISREG(s.st_mode)) {
|
||||||
info->is_directory = FALSE;
|
info->is_directory = FALSE;
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check readable
|
// check readable
|
||||||
fp = fopen( filename, "r" );
|
fp = fopen(filename, "r");
|
||||||
info->is_readable = ( fp != NULL );
|
info->is_readable = ( fp != NULL );
|
||||||
if( fp ) {
|
if (fp) {
|
||||||
fclose( fp );
|
fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
info->file_length = s.st_size;
|
info->file_length = s.st_size;
|
||||||
info->last_modified = s.st_mtime;
|
info->last_modified = s.st_mtime;
|
||||||
|
|
||||||
rc = get_content_type( filename, &info->content_type );
|
rc = get_content_type( filename, &info->content_type );
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
|
||||||
"file info: %s, length: %lld, last_mod=%s readable=%d\n",
|
"file info: %s, length: %lld, last_mod=%s readable=%d\n",
|
||||||
filename, (long long)info->file_length,
|
filename, (long long)info->file_length,
|
||||||
asctime( gmtime( &info->last_modified ) ),
|
asctime( gmtime( &info->last_modified ) ),
|
||||||
info->is_readable );
|
info->is_readable );
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -690,7 +692,7 @@ web_server_set_root_dir( IN const char *root_dir )
|
|||||||
* Function: get_alias
|
* Function: get_alias
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN const char* request_file ; request file passed in to be compared with
|
* IN const char *request_file; request file passed in to be compared with
|
||||||
* OUT struct xml_alias_t* alias ; xml alias object which has a file name
|
* OUT struct xml_alias_t* alias ; xml alias object which has a file name
|
||||||
* stored
|
* stored
|
||||||
* OUT struct File_Info * info ; File information object which will be
|
* OUT struct File_Info * info ; File information object which will be
|
||||||
@ -706,21 +708,19 @@ web_server_set_root_dir( IN const char *root_dir )
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
static UPNP_INLINE xboolean
|
static UPNP_INLINE xboolean
|
||||||
get_alias( IN const char *request_file,
|
get_alias( IN const char *request_file,
|
||||||
OUT struct xml_alias_t *alias,
|
OUT struct xml_alias_t *alias,
|
||||||
OUT struct File_Info *info )
|
OUT struct File_Info *info )
|
||||||
{
|
{
|
||||||
int cmp;
|
int cmp = strcmp(alias->name.buf, request_file);
|
||||||
|
if (cmp == 0) {
|
||||||
cmp = strcmp( alias->name.buf, request_file );
|
// fill up info
|
||||||
if( cmp == 0 ) {
|
|
||||||
// fill up info
|
|
||||||
info->file_length = alias->doc.length;
|
info->file_length = alias->doc.length;
|
||||||
info->is_readable = TRUE;
|
info->is_readable = TRUE;
|
||||||
info->is_directory = FALSE;
|
info->is_directory = FALSE;
|
||||||
info->last_modified = alias->last_modified;
|
info->last_modified = alias->last_modified;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmp == 0;
|
return cmp == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -1209,11 +1209,11 @@ process_request( IN http_message_t * req,
|
|||||||
xboolean using_virtual_dir;
|
xboolean using_virtual_dir;
|
||||||
uri_type *url;
|
uri_type *url;
|
||||||
char *temp_str;
|
char *temp_str;
|
||||||
int resp_major,
|
int resp_major;
|
||||||
resp_minor;
|
int resp_minor;
|
||||||
xboolean alias_grabbed;
|
xboolean alias_grabbed;
|
||||||
size_t dummy;
|
size_t dummy;
|
||||||
struct UpnpVirtualDirCallbacks *pVirtualDirCallback;
|
const char *extra_headers = NULL;
|
||||||
|
|
||||||
print_http_headers( req );
|
print_http_headers( req );
|
||||||
|
|
||||||
@ -1265,15 +1265,13 @@ process_request( IN http_message_t * req,
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//
|
/* try using alias */
|
||||||
// try using alias
|
if (is_valid_alias(&gAliasDoc)) {
|
||||||
//
|
alias_grab(alias);
|
||||||
if( is_valid_alias( &gAliasDoc ) ) {
|
|
||||||
alias_grab( alias );
|
|
||||||
alias_grabbed = TRUE;
|
alias_grabbed = TRUE;
|
||||||
|
|
||||||
using_alias = get_alias( request_doc, alias, &finfo );
|
using_alias = get_alias( request_doc, alias, &finfo );
|
||||||
if( using_alias == TRUE ) {
|
if (using_alias == TRUE) {
|
||||||
finfo.content_type = ixmlCloneDOMString( "text/xml" );
|
finfo.content_type = ixmlCloneDOMString( "text/xml" );
|
||||||
|
|
||||||
if( finfo.content_type == NULL ) {
|
if( finfo.content_type == NULL ) {
|
||||||
@ -1283,29 +1281,26 @@ process_request( IN http_message_t * req,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( using_virtual_dir ) {
|
if (using_virtual_dir) {
|
||||||
if( req->method != HTTPMETHOD_POST ) {
|
if (req->method != HTTPMETHOD_POST) {
|
||||||
// get file info
|
// get file info
|
||||||
pVirtualDirCallback = &virtualDirCallback;
|
if (virtualDirCallback.get_info(filename->buf, &finfo) != 0) {
|
||||||
if( pVirtualDirCallback->get_info( filename->buf, &finfo ) !=
|
|
||||||
0 ) {
|
|
||||||
err_code = HTTP_NOT_FOUND;
|
err_code = HTTP_NOT_FOUND;
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
// try index.html if req is a dir
|
// try index.html if req is a dir
|
||||||
if( finfo.is_directory ) {
|
if( finfo.is_directory ) {
|
||||||
if( filename->buf[filename->length - 1] == '/' ) {
|
if (filename->buf[filename->length - 1] == '/') {
|
||||||
temp_str = "index.html";
|
temp_str = "index.html";
|
||||||
} else {
|
} else {
|
||||||
temp_str = "/index.html";
|
temp_str = "/index.html";
|
||||||
}
|
}
|
||||||
if( membuffer_append_str( filename, temp_str ) != 0 ) {
|
if ( membuffer_append_str(filename, temp_str) != 0) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
// get info
|
// get info
|
||||||
if( ( pVirtualDirCallback->
|
if( (virtualDirCallback.get_info(filename->buf, &finfo ) != UPNP_E_SUCCESS ) ||
|
||||||
get_info( filename->buf, &finfo ) != UPNP_E_SUCCESS )
|
finfo.is_directory) {
|
||||||
|| finfo.is_directory ) {
|
|
||||||
err_code = HTTP_NOT_FOUND;
|
err_code = HTTP_NOT_FOUND;
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
@ -1321,7 +1316,7 @@ process_request( IN http_message_t * req,
|
|||||||
// goto error_handler;
|
// goto error_handler;
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
} else if( !using_alias ) {
|
} else if (!using_alias) {
|
||||||
if( gDocumentRootDir.length == 0 ) {
|
if( gDocumentRootDir.length == 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
@ -1392,34 +1387,40 @@ process_request( IN http_message_t * req,
|
|||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*extra_headers = UpnpFileInfo_get_ExtraHeaders(finfo);*/
|
||||||
|
if (!extra_headers) {
|
||||||
|
extra_headers = "";
|
||||||
|
}
|
||||||
|
|
||||||
if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
|
if( RespInstr->IsRangeActive && RespInstr->IsChunkActive ) {
|
||||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||||
// Transfer-Encoding: chunked
|
// Transfer-Encoding: chunked
|
||||||
if (http_MakeMessage(
|
if (http_MakeMessage(
|
||||||
headers, resp_major, resp_minor,
|
headers, resp_major, resp_minor,
|
||||||
"R" "T" "GKD" "s" "tcS" "XcCc",
|
"R" "T" "GKD" "s" "tcS" "Xc" "sCc",
|
||||||
HTTP_PARTIAL_CONTENT, // status code
|
HTTP_PARTIAL_CONTENT, // status code
|
||||||
finfo.content_type, // content type
|
finfo.content_type, // content type
|
||||||
RespInstr, // range info
|
RespInstr, // range info
|
||||||
"LAST-MODIFIED: ",
|
"LAST-MODIFIED: ",
|
||||||
&finfo.last_modified,
|
&finfo.last_modified,
|
||||||
X_USER_AGENT) != 0 ) {
|
X_USER_AGENT,
|
||||||
|
extra_headers) != 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
} else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
|
} else if( RespInstr->IsRangeActive && !RespInstr->IsChunkActive ) {
|
||||||
|
|
||||||
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
// Content-Range: bytes 222-3333/4000 HTTP_PARTIAL_CONTENT
|
||||||
// Transfer-Encoding: chunked
|
// Transfer-Encoding: chunked
|
||||||
if (http_MakeMessage(
|
if (http_MakeMessage(
|
||||||
headers, resp_major, resp_minor,
|
headers, resp_major, resp_minor,
|
||||||
"R" "N" "T" "GD" "s" "tcS" "XcCc",
|
"R" "N" "T" "GD" "s" "tcS" "Xc" "sCc",
|
||||||
HTTP_PARTIAL_CONTENT, // status code
|
HTTP_PARTIAL_CONTENT, // status code
|
||||||
RespInstr->ReadSendSize, // content length
|
RespInstr->ReadSendSize, // content length
|
||||||
finfo.content_type, // content type
|
finfo.content_type, // content type
|
||||||
RespInstr, // range info
|
RespInstr, // range info
|
||||||
"LAST-MODIFIED: ",
|
"LAST-MODIFIED: ",
|
||||||
&finfo.last_modified,
|
&finfo.last_modified,
|
||||||
X_USER_AGENT) != 0 ) {
|
X_USER_AGENT,
|
||||||
|
extra_headers) != 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1428,12 +1429,13 @@ process_request( IN http_message_t * req,
|
|||||||
// Transfer-Encoding: chunked
|
// Transfer-Encoding: chunked
|
||||||
if (http_MakeMessage(
|
if (http_MakeMessage(
|
||||||
headers, resp_major, resp_minor,
|
headers, resp_major, resp_minor,
|
||||||
"RK" "TD" "s" "tcS" "XcCc",
|
"RK" "TD" "s" "tcS" "Xc" "sCc",
|
||||||
HTTP_OK, // status code
|
HTTP_OK, // status code
|
||||||
finfo.content_type, // content type
|
finfo.content_type, // content type
|
||||||
"LAST-MODIFIED: ",
|
"LAST-MODIFIED: ",
|
||||||
&finfo.last_modified,
|
&finfo.last_modified,
|
||||||
X_USER_AGENT) != 0 ) {
|
X_USER_AGENT,
|
||||||
|
extra_headers) != 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1443,13 +1445,14 @@ process_request( IN http_message_t * req,
|
|||||||
// Transfer-Encoding: chunked
|
// Transfer-Encoding: chunked
|
||||||
if (http_MakeMessage(
|
if (http_MakeMessage(
|
||||||
headers, resp_major, resp_minor,
|
headers, resp_major, resp_minor,
|
||||||
"R" "N" "TD" "s" "tcS" "XcCc",
|
"R" "N" "TD" "s" "tcS" "Xc" "sCc",
|
||||||
HTTP_OK, // status code
|
HTTP_OK, // status code
|
||||||
RespInstr->ReadSendSize, // content length
|
RespInstr->ReadSendSize, // content length
|
||||||
finfo.content_type, // content type
|
finfo.content_type, // content type
|
||||||
"LAST-MODIFIED: ",
|
"LAST-MODIFIED: ",
|
||||||
&finfo.last_modified,
|
&finfo.last_modified,
|
||||||
X_USER_AGENT) != 0 ) {
|
X_USER_AGENT,
|
||||||
|
extra_headers) != 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -1457,12 +1460,13 @@ process_request( IN http_message_t * req,
|
|||||||
// Transfer-Encoding: chunked
|
// Transfer-Encoding: chunked
|
||||||
if (http_MakeMessage(
|
if (http_MakeMessage(
|
||||||
headers, resp_major, resp_minor,
|
headers, resp_major, resp_minor,
|
||||||
"R" "TD" "s" "tcS" "XcCc",
|
"R" "TD" "s" "tcS" "b" "Xc" "sCc",
|
||||||
HTTP_OK, // status code
|
HTTP_OK, // status code
|
||||||
finfo.content_type, // content type
|
finfo.content_type, // content type
|
||||||
"LAST-MODIFIED: ",
|
"LAST-MODIFIED: ",
|
||||||
&finfo.last_modified,
|
&finfo.last_modified,
|
||||||
X_USER_AGENT) != 0 ) {
|
X_USER_AGENT,
|
||||||
|
extra_headers) != 0 ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1488,11 +1492,11 @@ process_request( IN http_message_t * req,
|
|||||||
|
|
||||||
err_code = UPNP_E_SUCCESS;
|
err_code = UPNP_E_SUCCESS;
|
||||||
|
|
||||||
error_handler:
|
error_handler:
|
||||||
free( request_doc );
|
free(request_doc);
|
||||||
ixmlFreeDOMString( finfo.content_type );
|
ixmlFreeDOMString( finfo.content_type );
|
||||||
if( err_code != UPNP_E_SUCCESS && alias_grabbed ) {
|
if (err_code != UPNP_E_SUCCESS && alias_grabbed) {
|
||||||
alias_release( alias );
|
alias_release(alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
return err_code;
|
return err_code;
|
||||||
@ -1517,8 +1521,8 @@ process_request( IN http_message_t * req,
|
|||||||
* HTTP_OK
|
* HTTP_OK
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
http_RecvPostMessage( http_parser_t * parser,
|
http_RecvPostMessage( http_parser_t *parser,
|
||||||
IN SOCKINFO * info,
|
IN SOCKINFO *info,
|
||||||
char *filename,
|
char *filename,
|
||||||
struct SendInstruction *Instr )
|
struct SendInstruction *Instr )
|
||||||
{
|
{
|
||||||
@ -1535,12 +1539,10 @@ http_RecvPostMessage( http_parser_t * parser,
|
|||||||
int ret_code = 0;
|
int ret_code = 0;
|
||||||
|
|
||||||
if( Instr && Instr->IsVirtualFile ) {
|
if( Instr && Instr->IsVirtualFile ) {
|
||||||
|
|
||||||
Fp = (virtualDirCallback.open)( filename, UPNP_WRITE );
|
Fp = (virtualDirCallback.open)( filename, UPNP_WRITE );
|
||||||
if( Fp == NULL ) {
|
if( Fp == NULL ) {
|
||||||
return HTTP_INTERNAL_SERVER_ERROR;
|
return HTTP_INTERNAL_SERVER_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Fp = fopen( filename, "wb" );
|
Fp = fopen( filename, "wb" );
|
||||||
if( Fp == NULL ) {
|
if( Fp == NULL ) {
|
||||||
|
@ -1,60 +1,58 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// 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 implements the sockets functionality
|
* Purpose: This file implements the sockets functionality
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "sock.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
|
||||||
|
#include "upnp.h"
|
||||||
|
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "sock.h"
|
|
||||||
#include "upnp.h"
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#else
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
#include "unixutil.h"
|
|
||||||
|
|
||||||
#ifndef MSG_NOSIGNAL
|
#ifndef MSG_NOSIGNAL
|
||||||
#define MSG_NOSIGNAL 0
|
#define MSG_NOSIGNAL 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -62,7 +60,7 @@
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
*
|
*
|
||||||
* Description : Assign the passed in socket descriptor to socket
|
* Description : Assign the passed in socket descriptor to socket
|
||||||
* descriptor in the SOCKINFO structure.
|
* descriptor in the SOCKINFO structure.
|
||||||
@ -76,7 +74,7 @@
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
sock_init( OUT SOCKINFO * info,
|
sock_init( OUT SOCKINFO * info,
|
||||||
IN int sockfd )
|
IN SOCKET sockfd )
|
||||||
{
|
{
|
||||||
assert( info );
|
assert( info );
|
||||||
|
|
||||||
@ -91,10 +89,9 @@ sock_init( OUT SOCKINFO * info,
|
|||||||
* Function : sock_init_with_ip
|
* Function : sock_init_with_ip
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
* IN struct in_addr foreign_ip_addr ; Remote IP Address
|
* IN struct sockaddr* foreign_sockaddr; remote socket address.
|
||||||
* IN unsigned short foreign_ip_port ; Remote Port number
|
|
||||||
*
|
*
|
||||||
* Description : Calls the sock_init function and assigns the passed in
|
* Description : Calls the sock_init function and assigns the passed in
|
||||||
* IP address and port to the IP address and port in the SOCKINFO
|
* IP address and port to the IP address and port in the SOCKINFO
|
||||||
@ -109,9 +106,8 @@ sock_init( OUT SOCKINFO * info,
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
sock_init_with_ip( OUT SOCKINFO * info,
|
sock_init_with_ip( OUT SOCKINFO * info,
|
||||||
IN int sockfd,
|
IN SOCKET sockfd,
|
||||||
IN struct in_addr foreign_ip_addr,
|
IN struct sockaddr* foreign_sockaddr )
|
||||||
IN unsigned short foreign_ip_port )
|
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@ -120,8 +116,8 @@ sock_init_with_ip( OUT SOCKINFO * info,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->foreign_ip_addr = foreign_ip_addr;
|
memcpy( &info->foreign_sockaddr, foreign_sockaddr,
|
||||||
info->foreign_ip_port = foreign_ip_port;
|
sizeof( info->foreign_sockaddr) );
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -149,9 +145,11 @@ int
|
|||||||
sock_destroy( INOUT SOCKINFO * info,
|
sock_destroy( INOUT SOCKINFO * info,
|
||||||
int ShutdownMethod )
|
int ShutdownMethod )
|
||||||
{
|
{
|
||||||
shutdown( info->socket, ShutdownMethod );
|
if( info->socket != INVALID_SOCKET ) {
|
||||||
if( UpnpCloseSocket( info->socket ) == -1 ) {
|
shutdown( info->socket, ShutdownMethod );
|
||||||
return UPNP_E_SOCKET_ERROR;
|
if( UpnpCloseSocket( info->socket ) == -1 ) {
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
@ -190,7 +188,7 @@ sock_read_write( IN SOCKINFO * info,
|
|||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
int numBytes;
|
int numBytes;
|
||||||
time_t start_time = time( NULL );
|
time_t start_time = time( NULL );
|
||||||
int sockfd = info->socket;
|
SOCKET sockfd = info->socket;
|
||||||
long bytes_sent = 0,
|
long bytes_sent = 0,
|
||||||
byte_left = 0,
|
byte_left = 0,
|
||||||
num_written;
|
num_written;
|
||||||
@ -202,9 +200,9 @@ sock_read_write( IN SOCKINFO * info,
|
|||||||
FD_ZERO( &readSet );
|
FD_ZERO( &readSet );
|
||||||
FD_ZERO( &writeSet );
|
FD_ZERO( &writeSet );
|
||||||
if( bRead ) {
|
if( bRead ) {
|
||||||
FD_SET( ( unsigned )sockfd, &readSet );
|
FD_SET( sockfd, &readSet );
|
||||||
} else {
|
} else {
|
||||||
FD_SET( ( unsigned )sockfd, &writeSet );
|
FD_SET( sockfd, &writeSet );
|
||||||
}
|
}
|
||||||
|
|
||||||
timeout.tv_sec = *timeoutSecs;
|
timeout.tv_sec = *timeoutSecs;
|
||||||
|
69
upnp/src/inc/VirtualDir.h
Normal file
69
upnp/src/inc/VirtualDir.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#ifndef VIRTUALDIR_H
|
||||||
|
#define VIRTUALDIR_H
|
||||||
|
|
||||||
|
|
||||||
|
/** The \b VirtualDirCallbacks structure contains the pointers to
|
||||||
|
* file-related callback functions a device application can register to
|
||||||
|
* virtualize URLs.
|
||||||
|
*/
|
||||||
|
struct VirtualDirCallbacks
|
||||||
|
{
|
||||||
|
/** Called by the web server to query information on a file. The callback
|
||||||
|
* should return 0 on success or -1 on an error. */
|
||||||
|
VDCallback_GetInfo get_info;
|
||||||
|
|
||||||
|
/** Called by the web server to open a file. The callback should return
|
||||||
|
* a valid handle if the file can be opened. Otherwise, it should return
|
||||||
|
* \c NULL to signify an error. */
|
||||||
|
VDCallback_Open open;
|
||||||
|
|
||||||
|
/** Called by the web server to perform a sequential read from an open
|
||||||
|
* file. The callback should copy \b buflen bytes from the file into
|
||||||
|
* the buffer.
|
||||||
|
* @return An integer representing one of the following:
|
||||||
|
* \li <tt> 0</tt>: The file contains no more data (EOF).
|
||||||
|
* \li <tt> > 0</tt>: A successful read of the number of bytes in the
|
||||||
|
* return code.
|
||||||
|
* \li <tt> < 0</tt>: An error occurred reading the file.
|
||||||
|
*/
|
||||||
|
VDCallback_Read read;
|
||||||
|
|
||||||
|
/** Called by the web server to perform a sequential write to an open
|
||||||
|
* file. The callback should write \b buflen bytes into the file from
|
||||||
|
* the buffer. It should return the actual number of bytes written,
|
||||||
|
* which might be less than \b buflen in the case of a write error.
|
||||||
|
*/
|
||||||
|
VDCallback_Write write;
|
||||||
|
|
||||||
|
/** Called by the web server to move the file pointer, or offset, into
|
||||||
|
* an open file. The \b origin parameter determines where to start
|
||||||
|
* moving the file pointer. A value of \c SEEK_CUR moves the
|
||||||
|
* file pointer relative to where it is. The \b offset parameter can
|
||||||
|
* be either positive (move forward) or negative (move backward).
|
||||||
|
* \c SEEK_END moves relative to the end of the file. A positive
|
||||||
|
* \b offset extends the file. A negative \b offset moves backward
|
||||||
|
* in the file. Finally, \c SEEK_SET moves to an absolute position in
|
||||||
|
* the file. In this case, \b offset must be positive. The callback
|
||||||
|
* should return 0 on a successful seek or a non-zero value on an error.
|
||||||
|
*/
|
||||||
|
VDCallback_Seek seek;
|
||||||
|
|
||||||
|
/** Called by the web server to close a file opened via the \b open
|
||||||
|
* callback. It should return 0 on success, or a non-zero value on an
|
||||||
|
* error.
|
||||||
|
*/
|
||||||
|
VDCallback_Close close;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct virtual_Dir_List
|
||||||
|
{
|
||||||
|
struct virtual_Dir_List *next;
|
||||||
|
char dirName[NAME_SIZE];
|
||||||
|
} virtualDirList;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* VIRTUALDIR_H */
|
||||||
|
|
@ -56,15 +56,15 @@ typedef struct CLIENT_SUBSCRIPTION {
|
|||||||
char * ActualSID;
|
char * ActualSID;
|
||||||
char * EventURL;
|
char * EventURL;
|
||||||
int RenewEventId;
|
int RenewEventId;
|
||||||
struct CLIENT_SUBSCRIPTION * next;
|
struct CLIENT_SUBSCRIPTION *next;
|
||||||
} client_subscription;
|
} ClientSubscription;
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : copy_client_subscription
|
* Function : copy_client_subscription
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * in ; - source client subscription
|
* ClientSubscription * in ; - source client subscription
|
||||||
* client_subscription * out ; - destination client subscription
|
* ClientSubscription * out ; - destination client subscription
|
||||||
*
|
*
|
||||||
* Description : Make a copy of the client subscription data
|
* Description : Make a copy of the client subscription data
|
||||||
*
|
*
|
||||||
@ -74,13 +74,13 @@ typedef struct CLIENT_SUBSCRIPTION {
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int copy_client_subscription(client_subscription * in, client_subscription * out);
|
int copy_client_subscription(ClientSubscription * in, ClientSubscription * out);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : free_client_subscription
|
* Function : free_client_subscription
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * sub ; - Client subscription to be freed
|
* ClientSubscription * sub ; - Client subscription to be freed
|
||||||
*
|
*
|
||||||
* Description : Free memory allocated for client subscription data.
|
* Description : Free memory allocated for client subscription data.
|
||||||
* Remove timer thread associated with this subscription event.
|
* Remove timer thread associated with this subscription event.
|
||||||
@ -89,14 +89,14 @@ int copy_client_subscription(client_subscription * in, client_subscription * out
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void free_client_subscription(client_subscription * sub);
|
void free_client_subscription(ClientSubscription * sub);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : freeClientSubList
|
* Function : freeClientSubList
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription * list ; Client subscription
|
* ClientSubscription * list ; Client subscription
|
||||||
*
|
*
|
||||||
* Description : Free the client subscription table.
|
* Description : Free the client subscription table.
|
||||||
*
|
*
|
||||||
@ -104,13 +104,13 @@ void free_client_subscription(client_subscription * sub);
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void freeClientSubList(client_subscription * list);
|
void freeClientSubList(ClientSubscription * list);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : RemoveClientSubClientSID
|
* Function : RemoveClientSubClientSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription **head ; Head of the subscription list
|
* ClientSubscription **head ; Head of the subscription list
|
||||||
* const Upnp_SID sid ; Subscription ID to be mactched
|
* const Upnp_SID sid ; Subscription ID to be mactched
|
||||||
*
|
*
|
||||||
* Description : Remove the client subscription matching the
|
* Description : Remove the client subscription matching the
|
||||||
@ -121,43 +121,42 @@ void freeClientSubList(client_subscription * list);
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
void RemoveClientSubClientSID(client_subscription **head,
|
void RemoveClientSubClientSID(ClientSubscription **head,
|
||||||
const Upnp_SID sid);
|
const Upnp_SID sid);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : GetClientSubClientSID
|
* Function : GetClientSubClientSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription *head ; Head of the subscription list
|
* ClientSubscription *head ; Head of the subscription list
|
||||||
* const Upnp_SID sid ; Subscription ID to be matched
|
* const Upnp_SID sid ; Subscription ID to be matched
|
||||||
*
|
*
|
||||||
* Description : Return the client subscription from the client table
|
* Description : Return the client subscription from the client table
|
||||||
* that matches const Upnp_SID sid subscrition id value.
|
* that matches const Upnp_SID sid subscrition id value.
|
||||||
*
|
*
|
||||||
* Return : client_subscription * ; The matching subscription
|
* Return : ClientSubscription * ; The matching subscription
|
||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
client_subscription * GetClientSubClientSID(client_subscription *head
|
ClientSubscription * GetClientSubClientSID(ClientSubscription *head
|
||||||
, const Upnp_SID sid);
|
, const Upnp_SID sid);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : GetClientSubActualSID
|
* Function : GetClientSubActualSID
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* client_subscription *head ; Head of the subscription list
|
* ClientSubscription *head ; Head of the subscription list
|
||||||
* token * sid ; Subscription ID to be matched
|
* token * sid ; Subscription ID to be matched
|
||||||
*
|
*
|
||||||
* Description : Returns the client subscription from the client
|
* Description : Returns the client subscription from the client
|
||||||
* subscription table that has the matching token * sid buffer
|
* subscription table that has the matching token * sid buffer
|
||||||
* value.
|
* value.
|
||||||
*
|
*
|
||||||
* Return : client_subscription * ; The matching subscription
|
* Return : ClientSubscription * ; The matching subscription
|
||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
client_subscription * GetClientSubActualSID(client_subscription *head
|
ClientSubscription * GetClientSubActualSID(ClientSubscription *head, token * sid);
|
||||||
, token * sid);
|
|
||||||
)
|
)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -1,33 +1,38 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* - Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GLOBAL_H
|
||||||
|
#define GLOBAL_H
|
||||||
|
|
||||||
|
|
||||||
/* GLOBAL.H - RSAREF types and constants */
|
/* GLOBAL.H - RSAREF types and constants */
|
||||||
/* PROTOTYPES should be set to one if and only if the compiler supports
|
/* PROTOTYPES should be set to one if and only if the compiler supports
|
||||||
@ -37,8 +42,9 @@
|
|||||||
been defined with C compiler flags.
|
been defined with C compiler flags.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef PROTOTYPES
|
#ifndef PROTOTYPES
|
||||||
#define PROTOTYPES 0
|
#define PROTOTYPES 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* POINTER defines a generic pointer type */
|
/* POINTER defines a generic pointer type */
|
||||||
@ -50,13 +56,17 @@ typedef unsigned short int UINT2;
|
|||||||
/* UINT4 defines a four byte word */
|
/* UINT4 defines a four byte word */
|
||||||
typedef unsigned long int UINT4;
|
typedef unsigned long int UINT4;
|
||||||
|
|
||||||
/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
/*
|
||||||
If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
|
||||||
returns an empty list.
|
* If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
|
||||||
|
* returns an empty list.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PROTOTYPES
|
#if PROTOTYPES
|
||||||
#define PROTO_LIST(list) list
|
#define PROTO_LIST(list) list
|
||||||
#else
|
#else
|
||||||
#define PROTO_LIST(list) ()
|
#define PROTO_LIST(list) ()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* GLOBAL_H */
|
||||||
|
|
||||||
|
@ -42,17 +42,21 @@ extern SOCKET gMiniServerStopSock;
|
|||||||
|
|
||||||
typedef struct MServerSockArray {
|
typedef struct MServerSockArray {
|
||||||
/* socket for listening for miniserver requests */
|
/* socket for listening for miniserver requests */
|
||||||
int miniServerSock;
|
SOCKET miniServerSock4;
|
||||||
|
SOCKET miniServerSock6;
|
||||||
/* socket for stopping miniserver */
|
/* socket for stopping miniserver */
|
||||||
int miniServerStopSock;
|
SOCKET miniServerStopSock;
|
||||||
/* socket for incoming advertisments and search requests */
|
/* socket for incoming advertisments and search requests */
|
||||||
int ssdpSock;
|
SOCKET ssdpSock4;
|
||||||
|
SOCKET ssdpSock6;
|
||||||
|
|
||||||
int stopPort;
|
SOCKET stopPort;
|
||||||
int miniServerPort;
|
SOCKET miniServerPort4;
|
||||||
|
SOCKET miniServerPort6;
|
||||||
|
|
||||||
/* socket for sending search requests and receiving search replies */
|
/* socket for sending search requests and receiving search replies */
|
||||||
CLIENTONLY(int ssdpReqSock;)
|
CLIENTONLY(SOCKET ssdpReqSock4;)
|
||||||
|
CLIENTONLY(SOCKET ssdpReqSock6;)
|
||||||
} MiniServerSockArray;
|
} MiniServerSockArray;
|
||||||
|
|
||||||
|
|
||||||
@ -66,78 +70,62 @@ typedef void (*MiniServerCallback)(
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function: SetHTTPGetCallback
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* MiniServerCallback callback; - HTTP Callback to be invoked
|
|
||||||
*
|
|
||||||
* Description: Set HTTP Get Callback
|
|
||||||
*
|
|
||||||
* Return: void
|
|
||||||
************************************************************************/
|
|
||||||
void SetHTTPGetCallback( MiniServerCallback callback );
|
|
||||||
|
|
||||||
/************************************************************************
|
/*!
|
||||||
* Function: SetSoapCallback
|
* \brief Set HTTP Get Callback.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
void SetHTTPGetCallback(
|
||||||
* MiniServerCallback callback; - SOAP Callback to be invoked
|
/*! [in] HTTP Callback to be invoked . */
|
||||||
*
|
MiniServerCallback callback);
|
||||||
* Description: Set SOAP Callback
|
|
||||||
*
|
|
||||||
* Return: void
|
/*!
|
||||||
************************************************************************/
|
* \brief Set SOAP Callback.
|
||||||
|
*/
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
void SetSoapCallback( MiniServerCallback callback );
|
void SetSoapCallback(
|
||||||
|
/*! [in] SOAP Callback to be invoked . */
|
||||||
|
MiniServerCallback callback);
|
||||||
#else /* INCLUDE_DEVICE_APIS */
|
#else /* INCLUDE_DEVICE_APIS */
|
||||||
static inline void SetSoapCallback( MiniServerCallback callback ) {}
|
static inline void SetSoapCallback(MiniServerCallback callback) {}
|
||||||
#endif /* INCLUDE_DEVICE_APIS */
|
#endif /* INCLUDE_DEVICE_APIS */
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function: SetGenaCallback
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* MiniServerCallback callback; - GENA Callback to be invoked
|
|
||||||
*
|
|
||||||
* D6escription: Set GENA Callback
|
|
||||||
*
|
|
||||||
* Return: void
|
|
||||||
************************************************************************/
|
|
||||||
void SetGenaCallback( MiniServerCallback callback );
|
|
||||||
|
|
||||||
/************************************************************************
|
/*!
|
||||||
* Function: StartMiniServer
|
* \brief Set GENA Callback.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
void SetGenaCallback(
|
||||||
* unsigned short listen_port ; Port on which the server listens for
|
/*! [in] GENA Callback to be invoked. */
|
||||||
* incoming connections
|
MiniServerCallback callback);
|
||||||
*
|
|
||||||
* Description: Initialize the sockets functionality for the
|
|
||||||
* Miniserver. Initialize a thread pool job to run the MiniServer
|
|
||||||
* and the job to the thread pool. If listen port is 0, port is
|
|
||||||
* dynamically picked
|
|
||||||
*
|
|
||||||
* Use timer mechanism to start the MiniServer, failure to meet the
|
|
||||||
* allowed delay aborts the attempt to launch the MiniServer.
|
|
||||||
*
|
|
||||||
* Return: int;
|
|
||||||
* Actual port socket is bound to - On Success:
|
|
||||||
* A negative number UPNP_E_XXX - On Error
|
|
||||||
************************************************************************/
|
|
||||||
int StartMiniServer( unsigned short listen_port );
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function: StopMiniServer
|
/*!
|
||||||
|
* \brief Initialize the sockets functionality for the Miniserver.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Initialize a thread pool job to run the MiniServer and the job to the
|
||||||
* void;
|
* thread pool.
|
||||||
*
|
*
|
||||||
* Description: Stop and Shutdown the MiniServer and free socket resources.
|
* If listen port is 0, port is dynamically picked.
|
||||||
*
|
*
|
||||||
* Return : int;
|
* Use timer mechanism to start the MiniServer, failure to meet the
|
||||||
* Always returns 0
|
* allowed delay aborts the attempt to launch the MiniServer.
|
||||||
************************************************************************/
|
*
|
||||||
|
* \return
|
||||||
|
* \li On success: UPNP_E_SUCCESS.
|
||||||
|
* \li On error: UPNP_E_XXX.
|
||||||
|
*/
|
||||||
|
int StartMiniServer(
|
||||||
|
/*! [in,out] Port on which the server listens for incoming IPv4 connections. */
|
||||||
|
unsigned short *listen_port4,
|
||||||
|
/*! [in,out] Port on which the server listens for incoming IPv6 connections. */
|
||||||
|
unsigned short *listen_port6);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Stop and Shutdown the MiniServer and free socket resources.
|
||||||
|
*
|
||||||
|
* \return Always returns 0.
|
||||||
|
*/
|
||||||
int StopMiniServer();
|
int StopMiniServer();
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,44 +1,50 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* - Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef GENLIB_NET_SOCK_H
|
#ifndef GENLIB_NET_SOCK_H
|
||||||
#define GENLIB_NET_SOCK_H
|
#define GENLIB_NET_SOCK_H
|
||||||
|
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <netinet/in.h>
|
#ifdef WIN32
|
||||||
|
/* Do not #include <netinet/in.h> */
|
||||||
|
#else
|
||||||
|
#include <netinet/in.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Following variable is not defined under winsock.h
|
|
||||||
|
/* Following variable is not defined under winsock.h */
|
||||||
#ifndef SD_RECEIVE
|
#ifndef SD_RECEIVE
|
||||||
#define SD_RECEIVE 0x00
|
#define SD_RECEIVE 0x00
|
||||||
#define SD_SEND 0x01
|
#define SD_SEND 0x01
|
||||||
@ -48,24 +54,25 @@
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int socket; // handle/descriptor to a socket
|
/* handle/descriptor to a socket */
|
||||||
|
SOCKET socket;
|
||||||
// the following two fields are filled only in incoming requests;
|
|
||||||
struct in_addr foreign_ip_addr;
|
|
||||||
unsigned short foreign_ip_port;
|
|
||||||
|
|
||||||
|
/* the following two fields are filled only in incoming requests; */
|
||||||
|
struct sockaddr_storage foreign_sockaddr;
|
||||||
} SOCKINFO;
|
} SOCKINFO;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
#extern "C" {
|
#extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : sock_init
|
* Function : sock_init
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
*
|
*
|
||||||
* Description : Assign the passed in socket descriptor to socket
|
* Description : Assign the passed in socket descriptor to socket
|
||||||
* descriptor in the SOCKINFO structure.
|
* descriptor in the SOCKINFO structure.
|
||||||
@ -76,16 +83,15 @@ typedef struct
|
|||||||
* UPNP_E_SOCKET_ERROR
|
* UPNP_E_SOCKET_ERROR
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_init( OUT SOCKINFO* info, IN int sockfd );
|
int sock_init(OUT SOCKINFO* info, IN SOCKET sockfd);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : sock_init_with_ip
|
* Function : sock_init_with_ip
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* OUT SOCKINFO* info ; Socket Information Object
|
* OUT SOCKINFO* info ; Socket Information Object
|
||||||
* IN int sockfd ; Socket Descriptor
|
* IN SOCKET sockfd ; Socket Descriptor
|
||||||
* IN struct in_addr foreign_ip_addr ; Remote IP Address
|
* IN struct sockaddr* foreign_sockaddr; Remote socket address
|
||||||
* IN unsigned short foreign_ip_port ; Remote Port number
|
|
||||||
*
|
*
|
||||||
* Description : Calls the sock_init function and assigns the passed in
|
* Description : Calls the sock_init function and assigns the passed in
|
||||||
* IP address and port to the IP address and port in the SOCKINFO
|
* IP address and port to the IP address and port in the SOCKINFO
|
||||||
@ -98,8 +104,10 @@ int sock_init( OUT SOCKINFO* info, IN int sockfd );
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_init_with_ip( OUT SOCKINFO* info, IN int sockfd,
|
int sock_init_with_ip(
|
||||||
IN struct in_addr foreign_ip_addr, IN unsigned short foreign_ip_port );
|
OUT SOCKINFO* info,
|
||||||
|
IN SOCKET sockfd,
|
||||||
|
IN struct sockaddr *foreign_sockaddr);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : sock_read
|
* Function : sock_read
|
||||||
@ -162,11 +170,13 @@ int sock_write( IN SOCKINFO *info, IN char* buffer, IN size_t bufsize,
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
int sock_destroy( INOUT SOCKINFO* info,int );
|
int sock_destroy(INOUT SOCKINFO* info, int);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // #extern "C"
|
} /* #extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif // GENLIB_NET_SOCK_H
|
#endif /* GENLIB_NET_SOCK_H */
|
||||||
|
|
||||||
|
@ -1,59 +1,64 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* - Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef SSDPLIB_H
|
#ifndef SSDPLIB_H
|
||||||
#define SSDPLIB_H
|
#define SSDPLIB_H
|
||||||
|
|
||||||
|
#include "httpparser.h"
|
||||||
|
#include "httpreadwrite.h"
|
||||||
|
#include "miniserver.h"
|
||||||
|
#include "UpnpInet.h"
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include "httpparser.h"
|
|
||||||
#include "httpreadwrite.h"
|
|
||||||
#include "miniserver.h"
|
#ifdef WIN32
|
||||||
#ifndef WIN32
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#include <netinet/in_systm.h>
|
|
||||||
#include <netinet/ip.h>
|
|
||||||
#include <netinet/ip_icmp.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include <arpa/inet.h>
|
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <syslog.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in_systm.h>
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/ip_icmp.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Enumeration to define all different types of ssdp searches
|
|
||||||
|
/* Enumeration to define all different types of ssdp searches */
|
||||||
typedef enum SsdpSearchType{
|
typedef enum SsdpSearchType{
|
||||||
SSDP_SERROR=-1,
|
SSDP_SERROR=-1,
|
||||||
SSDP_ALL,SSDP_ROOTDEVICE,
|
SSDP_ALL,SSDP_ROOTDEVICE,
|
||||||
@ -63,8 +68,9 @@ typedef enum SsdpSearchType{
|
|||||||
} SType;
|
} SType;
|
||||||
|
|
||||||
|
|
||||||
//Enumeration to define all different type of ssdp messages
|
/* Enumeration to define all different type of ssdp messages */
|
||||||
typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
typedef enum SsdpCmdType{
|
||||||
|
SSDP_ERROR=-1,
|
||||||
SSDP_OK,
|
SSDP_OK,
|
||||||
SSDP_ALIVE,
|
SSDP_ALIVE,
|
||||||
SSDP_BYEBYE,
|
SSDP_BYEBYE,
|
||||||
@ -75,16 +81,18 @@ typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Constant
|
/* Constant */
|
||||||
#define BUFSIZE 2500
|
#define BUFSIZE 2500
|
||||||
#define SSDP_IP "239.255.255.250"
|
#define SSDP_IP "239.255.255.250"
|
||||||
|
#define SSDP_IPV6_LINKLOCAL "FF02::C"
|
||||||
#define SSDP_PORT 1900
|
#define SSDP_PORT 1900
|
||||||
#define NUM_TRY 3
|
#define NUM_TRY 3
|
||||||
#define NUM_COPY 1
|
#define NUM_COPY 1
|
||||||
#define THREAD_LIMIT 50
|
#define THREAD_LIMIT 50
|
||||||
#define COMMAND_LEN 300
|
#define COMMAND_LEN 300
|
||||||
|
|
||||||
#ifndef X_USER_AGENT // can be overwritten by configure CFLAGS argument
|
/* can be overwritten by configure CFLAGS argument */
|
||||||
|
#ifndef X_USER_AGENT
|
||||||
/** @name X_USER_AGENT
|
/** @name X_USER_AGENT
|
||||||
* The {\tt X_USER_AGENT} constant specifies the value of the X-User-Agent:
|
* The {\tt X_USER_AGENT} constant specifies the value of the X-User-Agent:
|
||||||
* HTTP header. The value "redsonic" is needed for the DSM-320. See
|
* HTTP header. The value "redsonic" is needed for the DSM-320. See
|
||||||
@ -94,7 +102,7 @@ typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
|||||||
#define X_USER_AGENT "redsonic"
|
#define X_USER_AGENT "redsonic"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Error code
|
/* Error code */
|
||||||
#define NO_ERROR_FOUND 0
|
#define NO_ERROR_FOUND 0
|
||||||
#define E_REQUEST_INVALID -3
|
#define E_REQUEST_INVALID -3
|
||||||
#define E_RES_EXPIRED -4
|
#define E_RES_EXPIRED -4
|
||||||
@ -105,7 +113,7 @@ typedef enum SsdpCmdType{SSDP_ERROR=-1,
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
//Structure to store the SSDP information
|
/* Structure to store the SSDP information */
|
||||||
typedef struct SsdpEventStruct
|
typedef struct SsdpEventStruct
|
||||||
{
|
{
|
||||||
enum SsdpCmdType Cmd;
|
enum SsdpCmdType Cmd;
|
||||||
@ -121,7 +129,7 @@ typedef struct SsdpEventStruct
|
|||||||
char Os[LINE_SIZE];
|
char Os[LINE_SIZE];
|
||||||
char Ext[LINE_SIZE];
|
char Ext[LINE_SIZE];
|
||||||
char Date[LINE_SIZE];
|
char Date[LINE_SIZE];
|
||||||
struct sockaddr_in * DestAddr;
|
struct sockaddr *DestAddr;
|
||||||
void * Cookie;
|
void * Cookie;
|
||||||
} Event;
|
} Event;
|
||||||
|
|
||||||
@ -143,7 +151,7 @@ typedef struct TData
|
|||||||
int Mx;
|
int Mx;
|
||||||
void * Cookie;
|
void * Cookie;
|
||||||
char * Data;
|
char * Data;
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage DestAddr;
|
||||||
|
|
||||||
}ThreadData;
|
}ThreadData;
|
||||||
|
|
||||||
@ -151,7 +159,7 @@ typedef struct ssdpsearchreply
|
|||||||
{
|
{
|
||||||
int MaxAge;
|
int MaxAge;
|
||||||
UpnpDevice_Handle handle;
|
UpnpDevice_Handle handle;
|
||||||
struct sockaddr_in dest_addr;
|
struct sockaddr_storage dest_addr;
|
||||||
SsdpEvent event;
|
SsdpEvent event;
|
||||||
|
|
||||||
}SsdpSearchReply;
|
}SsdpSearchReply;
|
||||||
@ -168,21 +176,18 @@ typedef struct ssdpsearcharg
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
http_parser_t parser;
|
http_parser_t parser;
|
||||||
struct sockaddr_in dest_addr;
|
struct sockaddr_storage dest_addr;
|
||||||
} ssdp_thread_data;
|
} ssdp_thread_data;
|
||||||
|
|
||||||
|
|
||||||
/* globals */
|
/* globals */
|
||||||
|
|
||||||
CLIENTONLY(extern SOCKET gSsdpReqSocket;);
|
CLIENTONLY(extern SOCKET gSsdpReqSocket4;);
|
||||||
|
CLIENTONLY(extern SOCKET gSsdpReqSocket6;);
|
||||||
|
|
||||||
typedef int (*ParserFun)(char *, Event *);
|
typedef int (*ParserFun)(char *, Event *);
|
||||||
|
|
||||||
|
|
||||||
//void InitParser();
|
|
||||||
|
|
||||||
//int AnalyzeCommand(char * szCommand, Event * Evt);
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : Make_Socket_NoBlocking
|
* Function : Make_Socket_NoBlocking
|
||||||
*
|
*
|
||||||
@ -214,11 +219,11 @@ int Make_Socket_NoBlocking (int sock);
|
|||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
void ssdp_handle_device_request(
|
void ssdp_handle_device_request(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr );
|
IN struct sockaddr* dest_addr );
|
||||||
#else
|
#else
|
||||||
static inline void ssdp_handle_device_request(
|
static inline void ssdp_handle_device_request(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr ) {}
|
IN struct sockaddr* dest_addr ) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -226,7 +231,7 @@ static inline void ssdp_handle_device_request(
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t* hmsg: SSDP message from the device
|
* IN http_message_t* hmsg: SSDP message from the device
|
||||||
* IN struct sockaddr_in* dest_addr: Address of the device
|
* IN struct sockaddr* dest_addr: Address of the device
|
||||||
* IN xboolean timeout: timeout kept by the control point while sending
|
* IN xboolean timeout: timeout kept by the control point while sending
|
||||||
* search message
|
* search message
|
||||||
* IN void* cookie: Cookie stored by the control point application.
|
* IN void* cookie: Cookie stored by the control point application.
|
||||||
@ -243,7 +248,7 @@ static inline void ssdp_handle_device_request(
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void ssdp_handle_ctrlpt_msg(
|
void ssdp_handle_ctrlpt_msg(
|
||||||
IN http_message_t* hmsg,
|
IN http_message_t* hmsg,
|
||||||
IN struct sockaddr_in* dest_addr,
|
IN struct sockaddr* dest_addr,
|
||||||
IN xboolean timeout,
|
IN xboolean timeout,
|
||||||
IN void* cookie );
|
IN void* cookie );
|
||||||
|
|
||||||
@ -356,6 +361,7 @@ int SearchByTarget(IN int Mx, IN char *St, IN void *Cookie);
|
|||||||
* IN char *Udn :
|
* IN char *Udn :
|
||||||
* IN char *Location: Location URL.
|
* IN char *Location: Location URL.
|
||||||
* IN int Duration : Service duration in sec.
|
* IN int Duration : Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the device advertisement request based on
|
* This function creates the device advertisement request based on
|
||||||
@ -369,7 +375,8 @@ int DeviceAdvertisement(
|
|||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -382,6 +389,7 @@ int DeviceAdvertisement(
|
|||||||
* IN char *_Server:
|
* IN char *_Server:
|
||||||
* IN char *Location: Location URL
|
* IN char *Location: Location URL
|
||||||
* IN int Duration :Device duration in sec.
|
* IN int Duration :Device duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP device shutdown request packet
|
* This function creates a HTTP device shutdown request packet
|
||||||
@ -396,13 +404,14 @@ int DeviceShutdown(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *_Server,
|
IN char *_Server,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : DeviceReply
|
* Function : DeviceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr: destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char *Udn: Device UDN
|
* IN char *Udn: Device UDN
|
||||||
@ -417,17 +426,18 @@ int DeviceShutdown(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int DeviceReply(
|
int DeviceReply(
|
||||||
IN struct sockaddr_in * DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location, IN int Duration);
|
IN char *Location,
|
||||||
|
IN int Duration);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : SendReply
|
* Function : SendReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr: destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -444,7 +454,7 @@ int DeviceReply(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int SendReply(
|
int SendReply(
|
||||||
IN struct sockaddr_in * DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
@ -459,7 +469,8 @@ int SendReply(
|
|||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Life time of this device.
|
* IN int Duration: Life time of this device.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the advertisement packet based
|
* This function creates the advertisement packet based
|
||||||
@ -472,13 +483,14 @@ int ServiceAdvertisement(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : ServiceReply
|
* Function : ServiceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in *DestAddr:
|
* IN struct sockaddr *DestAddr:
|
||||||
* IN char *Udn: Device UDN
|
* IN char *Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char *Server: Not used
|
* IN char *Server: Not used
|
||||||
@ -493,7 +505,7 @@ int ServiceAdvertisement(
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int ServiceReply(
|
int ServiceReply(
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
@ -507,6 +519,7 @@ int ServiceReply(
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char *Location: Location of Device description document.
|
* IN char *Location: Location of Device description document.
|
||||||
* IN int Duration :Service duration in sec.
|
* IN int Duration :Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP service shutdown request packet
|
* This function creates a HTTP service shutdown request packet
|
||||||
@ -519,7 +532,8 @@ int ServiceShutdown(
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration);
|
IN int Duration,
|
||||||
|
IN int AddressFamily);
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -546,7 +560,7 @@ void *advertiseAndReplyThread(IN void * data);
|
|||||||
* 1 = Send Advertisement
|
* 1 = Send Advertisement
|
||||||
* IN UpnpDevice_Handle Hnd: Device handle
|
* IN UpnpDevice_Handle Hnd: Device handle
|
||||||
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
||||||
* IN struct sockaddr_in *DestAddr:Destination address
|
* IN struct sockaddr *DestAddr:Destination address
|
||||||
* IN char *DeviceType:Device type
|
* IN char *DeviceType:Device type
|
||||||
* IN char *DeviceUDN:Device UDN
|
* IN char *DeviceUDN:Device UDN
|
||||||
* IN char *ServiceType:Service type
|
* IN char *ServiceType:Service type
|
||||||
@ -562,10 +576,10 @@ int AdvertiseAndReply(
|
|||||||
IN int AdFlag,
|
IN int AdFlag,
|
||||||
IN UpnpDevice_Handle Hnd,
|
IN UpnpDevice_Handle Hnd,
|
||||||
IN enum SsdpSearchType SearchType,
|
IN enum SsdpSearchType SearchType,
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DeviceType,
|
IN char *DeviceType,
|
||||||
IN char *DeviceUDN,
|
IN char *DeviceUDN,
|
||||||
IN char *ServiceType, int Exp);
|
IN char *ServiceType, int Exp);
|
||||||
|
|
||||||
#endif
|
#endif /* SSDPLIB_H */
|
||||||
|
|
||||||
|
@ -1,65 +1,90 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
* Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||||
** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
* Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
||||||
** Digital Equipment Corporation, Maynard, Mass.
|
* Digital Equipment Corporation, Maynard, Mass.
|
||||||
** Copyright (c) 1998 Microsoft.
|
* Copyright (c) 1998 Microsoft.
|
||||||
** To anyone who acknowledges that this file is provided "AS IS"
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
** without any express or implied warranty: permission to use, copy,
|
* without any express or implied warranty: permission to use, copy,
|
||||||
** modify, and distribute this file for any purpose is hereby
|
* modify, and distribute this file for any purpose is hereby
|
||||||
** granted without fee, provided that the above copyright notices and
|
* granted without fee, provided that the above copyright notices and
|
||||||
** this notice appears in all source code copies, and that none of
|
* this notice appears in all source code copies, and that none of
|
||||||
** the names of Open Software Foundation, Inc., Hewlett-Packard
|
* the names of Open Software Foundation, Inc., Hewlett-Packard
|
||||||
** Company, or Digital Equipment Corporation be used in advertising
|
* Company, or Digital Equipment Corporation be used in advertising
|
||||||
** or publicity pertaining to distribution of the software without
|
* or publicity pertaining to distribution of the software without
|
||||||
** specific, written prior permission. Neither Open Software
|
* specific, written prior permission. Neither Open Software
|
||||||
** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
* Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
||||||
** Corporation makes any representations about the suitability of
|
* Corporation makes any representations about the suitability of
|
||||||
** this software for any purpose.
|
* this software for any purpose.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SYSDEP_H
|
||||||
|
#define SYSDEP_H
|
||||||
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifndef WIN32
|
|
||||||
#include <sys/time.h>
|
|
||||||
#endif
|
|
||||||
//#include <sys/sysinfo.h>
|
|
||||||
#include "ithread.h"
|
#include "ithread.h"
|
||||||
|
|
||||||
|
|
||||||
/* change to point to where MD5 .h's live */
|
/* change to point to where MD5 .h's live */
|
||||||
/* get MD5 sample implementation from RFC 1321 */
|
/* get MD5 sample implementation from RFC 1321 */
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Do not #include <sys/time.h> */
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* set the following to the number of 100ns ticks of the actual
|
/* set the following to the number of 100ns ticks of the actual
|
||||||
resolution of
|
resolution of
|
||||||
your system's clock */
|
your system's clock */
|
||||||
#define UUIDS_PER_TICK 1024
|
#define UUIDS_PER_TICK 1024
|
||||||
|
|
||||||
|
|
||||||
/* Set the following to a call to acquire a system wide global lock
|
/* Set the following to a call to acquire a system wide global lock
|
||||||
*/
|
*/
|
||||||
extern ithread_mutex_t gUUIDMutex;
|
extern ithread_mutex_t gUUIDMutex;
|
||||||
|
|
||||||
|
|
||||||
#define UUIDLock() ithread_mutex_lock(&gUUIDMutex)
|
#define UUIDLock() ithread_mutex_lock(&gUUIDMutex)
|
||||||
#define UUIDUnlock() ithread_mutex_unlock(&gUUIDMutex)
|
#define UUIDUnlock() ithread_mutex_unlock(&gUUIDMutex)
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned long unsigned32;
|
typedef unsigned long unsigned32;
|
||||||
typedef unsigned short unsigned16;
|
typedef unsigned short unsigned16;
|
||||||
typedef unsigned char unsigned8;
|
typedef unsigned char unsigned8;
|
||||||
typedef unsigned char byte;
|
typedef unsigned char byte;
|
||||||
|
|
||||||
|
|
||||||
/* Set this to what your compiler uses for 64 bit data type */
|
/* Set this to what your compiler uses for 64 bit data type */
|
||||||
#ifndef WIN32
|
#ifdef WIN32
|
||||||
#define unsigned64_t unsigned long long
|
#define unsigned64_t __int64
|
||||||
#else
|
#else
|
||||||
#define unsigned64_t __int64
|
#define unsigned64_t unsigned long long
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define I64(C) C##LL
|
#define I64(C) C##LL
|
||||||
|
|
||||||
|
|
||||||
typedef unsigned64_t uuid_time_t;
|
typedef unsigned64_t uuid_time_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char nodeID[6];
|
char nodeID[6];
|
||||||
} uuid_node_t;
|
} uuid_node_t;
|
||||||
|
|
||||||
|
|
||||||
void get_ieee_node_identifier(uuid_node_t *node);
|
void get_ieee_node_identifier(uuid_node_t *node);
|
||||||
void get_system_time(uuid_time_t *uuid_time);
|
void get_system_time(uuid_time_t *uuid_time);
|
||||||
void get_random_info(char seed[16]);
|
void get_random_info(char seed[16]);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* SYSDEP_H */
|
||||||
|
|
||||||
|
@ -1,46 +1,56 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
//
|
*
|
||||||
// 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.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/* Unix-specific network utilities */
|
||||||
|
|
||||||
// Unix-specific network utilities
|
|
||||||
|
|
||||||
#ifndef GENLIB_NET_UNIXUTIL_H
|
#ifndef GENLIB_NET_UNIXUTIL_H
|
||||||
#define GENLIB_NET_UNIXUTIL_H
|
#define GENLIB_NET_UNIXUTIL_H
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#ifndef WIN32
|
#include "UpnpInet.h"
|
||||||
#include <sys/socket.h>
|
|
||||||
#else
|
|
||||||
|
#ifdef WIN32
|
||||||
typedef int socklen_t;
|
typedef int socklen_t;
|
||||||
#define EAFNOSUPPORT 97
|
#define EAFNOSUPPORT 97
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // GENLIB_NET_UNIXUTIL_H
|
|
||||||
|
#endif /* GENLIB_NET_UNIXUTIL_H */
|
||||||
|
|
||||||
|
@ -1,42 +1,48 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* * Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* * Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
******************************************************************************/
|
||||||
|
|
||||||
// File : upnpapi.h
|
|
||||||
|
|
||||||
#ifndef UPNPDK_H
|
#ifndef UPNPAPI_H
|
||||||
#define UPNPDK_H
|
#define UPNPAPI_H
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "upnp.h"
|
|
||||||
#include "client_table.h"
|
#include "client_table.h"
|
||||||
//#include "../ssdp/ssdplib.h"
|
#include "upnp.h"
|
||||||
|
#include "VirtualDir.h" /* for struct VirtualDirCallbacks */
|
||||||
|
|
||||||
|
|
||||||
#define MAX_INTERFACES 256
|
#define MAX_INTERFACES 256
|
||||||
|
|
||||||
@ -55,134 +61,277 @@
|
|||||||
|
|
||||||
extern size_t g_maxContentLength;
|
extern size_t g_maxContentLength;
|
||||||
|
|
||||||
// 30-second timeout
|
/* 30-second timeout */
|
||||||
#define UPNP_TIMEOUT 30
|
#define UPNP_TIMEOUT 30
|
||||||
|
|
||||||
typedef enum {HND_INVALID=-1,HND_CLIENT,HND_DEVICE} Upnp_Handle_Type;
|
typedef enum {HND_INVALID=-1,HND_CLIENT,HND_DEVICE} Upnp_Handle_Type;
|
||||||
|
|
||||||
// Data to be stored in handle table for
|
/* Data to be stored in handle table for */
|
||||||
struct Handle_Info
|
struct Handle_Info
|
||||||
{
|
{
|
||||||
Upnp_Handle_Type HType;
|
/*! . */
|
||||||
Upnp_FunPtr Callback; // Callback function pointer.
|
Upnp_Handle_Type HType;
|
||||||
char * Cookie;
|
/*! Callback function pointer. */
|
||||||
|
Upnp_FunPtr Callback;
|
||||||
|
/*! . */
|
||||||
|
char *Cookie;
|
||||||
|
/*! 0 = not installed; otherwise installed. */
|
||||||
|
int aliasInstalled;
|
||||||
|
|
||||||
// Device Only
|
/* Device Only */
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
char DescURL[LINE_SIZE]; // URL for the use of SSDP
|
/*! URL for the use of SSDP. */
|
||||||
char DescXML[LINE_SIZE]; // XML file path for device
|
char DescURL[LINE_SIZE];
|
||||||
//description
|
/*! XML file path for device description. */
|
||||||
|
char DescXML[LINE_SIZE];
|
||||||
int MaxAge; // Advertisement timeout
|
/* Advertisement timeout */
|
||||||
IXML_Document *DescDocument;// Description parsed in
|
int MaxAge;
|
||||||
//terms of DOM document
|
/*! Description parsed in terms of DOM document. */
|
||||||
IXML_NodeList *DeviceList; // List of devices in the
|
IXML_Document *DescDocument;
|
||||||
//description document
|
/*! List of devices in the description document. */
|
||||||
IXML_NodeList *ServiceList; // List of services in the
|
IXML_NodeList *DeviceList;
|
||||||
// description document
|
/*! List of services in the description document. */
|
||||||
service_table ServiceTable; //table holding subscriptions and
|
IXML_NodeList *ServiceList;
|
||||||
//URL information
|
/*! Table holding subscriptions and URL information. */
|
||||||
int MaxSubscriptions;
|
service_table ServiceTable;
|
||||||
int MaxSubscriptionTimeOut;
|
/*! . */
|
||||||
|
int MaxSubscriptions;
|
||||||
|
/*! . */
|
||||||
|
int MaxSubscriptionTimeOut;
|
||||||
|
/*! Address family: AF_INET or AF_INET6. */
|
||||||
|
int DeviceAf;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Client only
|
/* Client only */
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
client_subscription *ClientSubList; //client subscription list
|
/*! Client subscription list. */
|
||||||
LinkedList SsdpSearchList; // active ssdp searches
|
ClientSubscription *ClientSubList;
|
||||||
|
/*! Active SSDP searches. */
|
||||||
|
LinkedList SsdpSearchList;
|
||||||
#endif
|
#endif
|
||||||
int aliasInstalled; // 0 = not installed; otherwise installed
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern ithread_rwlock_t GlobalHndRWLock;
|
extern ithread_rwlock_t GlobalHndRWLock;
|
||||||
Upnp_Handle_Type GetHandleInfo(int Hnd, struct Handle_Info **HndInfo);
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get handle information.
|
||||||
|
*
|
||||||
|
* \return HND_DEVICE, UPNP_E_INVALID_HANDLE
|
||||||
|
*/
|
||||||
|
Upnp_Handle_Type GetHandleInfo(
|
||||||
|
/*! handle pointer (key for the client handle structure). */
|
||||||
|
int Hnd,
|
||||||
|
/*! handle structure passed by this function. */
|
||||||
|
struct Handle_Info **HndInfo);
|
||||||
|
|
||||||
|
|
||||||
#define HandleLock() HandleWriteLock()
|
#define HandleLock() HandleWriteLock()
|
||||||
|
|
||||||
|
|
||||||
#define HandleWriteLock() \
|
#define HandleWriteLock() \
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a write lock"); \
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a write lock"); \
|
||||||
ithread_rwlock_wrlock(&GlobalHndRWLock); \
|
ithread_rwlock_wrlock(&GlobalHndRWLock); \
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Write lock acquired");
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Write lock acquired");
|
||||||
|
|
||||||
|
|
||||||
#define HandleReadLock() \
|
#define HandleReadLock() \
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a read lock"); \
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Trying a read lock"); \
|
||||||
ithread_rwlock_rdlock(&GlobalHndRWLock); \
|
ithread_rwlock_rdlock(&GlobalHndRWLock); \
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Read lock acquired");
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Read lock acquired");
|
||||||
|
|
||||||
|
|
||||||
#define HandleUnlock() \
|
#define HandleUnlock() \
|
||||||
UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \
|
UpnpPrintf(UPNP_INFO, API,__FILE__, __LINE__, "Trying Unlock"); \
|
||||||
ithread_rwlock_unlock(&GlobalHndRWLock); \
|
ithread_rwlock_unlock(&GlobalHndRWLock); \
|
||||||
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlocked rwlock");
|
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__, "Unlocked rwlock");
|
||||||
|
|
||||||
Upnp_Handle_Type GetClientHandleInfo(int *client_handle_out,
|
|
||||||
struct Handle_Info **HndInfo);
|
/*!
|
||||||
Upnp_Handle_Type GetDeviceHandleInfo(int *device_handle_out,
|
* \brief Get client handle info.
|
||||||
struct Handle_Info **HndInfo);
|
*
|
||||||
|
* \note The logic around the use of this function should be revised.
|
||||||
|
*
|
||||||
|
* \return HND_CLIENT, HND_INVALID
|
||||||
|
*/
|
||||||
|
Upnp_Handle_Type GetClientHandleInfo(
|
||||||
|
/*! [in] client handle pointer (key for the client handle structure). */
|
||||||
|
int *client_handle_out,
|
||||||
|
/*! [out] Client handle structure passed by this function. */
|
||||||
|
struct Handle_Info **HndInfo);
|
||||||
|
/*!
|
||||||
|
* \brief Retrieves the device handle and information of the first device of
|
||||||
|
* the address family spcified.
|
||||||
|
*
|
||||||
|
* \return HND_DEVICE or HND_INVALID
|
||||||
|
*/
|
||||||
|
Upnp_Handle_Type GetDeviceHandleInfo(
|
||||||
|
/*! [in] Address family. */
|
||||||
|
const int AddressFamily,
|
||||||
|
/*! [out] Device handle pointer. */
|
||||||
|
int *device_handle_out,
|
||||||
|
/*! [out] Device handle structure passed by this function. */
|
||||||
|
struct Handle_Info **HndInfo);
|
||||||
|
|
||||||
|
|
||||||
extern char LOCAL_HOST[LINE_SIZE];
|
extern char gIF_NAME[LINE_SIZE];
|
||||||
|
/*! INET_ADDRSTRLEN. */
|
||||||
|
extern char gIF_IPV4[22];
|
||||||
|
/*! INET6_ADDRSTRLEN. */
|
||||||
|
extern char gIF_IPV6[65];
|
||||||
|
extern int gIF_INDEX;
|
||||||
|
|
||||||
|
|
||||||
|
extern unsigned short LOCAL_PORT_V4;
|
||||||
|
extern unsigned short LOCAL_PORT_V6;
|
||||||
|
|
||||||
|
|
||||||
|
/*! NLS uuid. */
|
||||||
|
extern Upnp_SID gUpnpSdkNLSuuid;
|
||||||
|
|
||||||
extern unsigned short LOCAL_PORT;
|
|
||||||
|
|
||||||
extern TimerThread gTimerThread;
|
extern TimerThread gTimerThread;
|
||||||
extern ThreadPool gRecvThreadPool;
|
extern ThreadPool gRecvThreadPool;
|
||||||
extern ThreadPool gSendThreadPool;
|
extern ThreadPool gSendThreadPool;
|
||||||
extern ThreadPool gMiniServerThreadPool;
|
extern ThreadPool gMiniServerThreadPool;
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SUBSCRIBE,
|
SUBSCRIBE,
|
||||||
UNSUBSCRIBE,
|
UNSUBSCRIBE,
|
||||||
DK_NOTIFY,
|
DK_NOTIFY,
|
||||||
QUERY,
|
QUERY,
|
||||||
ACTION,
|
ACTION,
|
||||||
STATUS,
|
STATUS,
|
||||||
DEVDESCRIPTION,
|
DEVDESCRIPTION,
|
||||||
SERVDESCRIPTION,
|
SERVDESCRIPTION,
|
||||||
MINI,
|
MINI,
|
||||||
RENEW} UpnpFunName;
|
RENEW
|
||||||
|
} UpnpFunName;
|
||||||
|
|
||||||
|
|
||||||
struct UpnpNonblockParam
|
struct UpnpNonblockParam
|
||||||
{
|
{
|
||||||
UpnpFunName FunName;
|
UpnpFunName FunName;
|
||||||
int Handle;
|
int Handle;
|
||||||
int TimeOut;
|
int TimeOut;
|
||||||
char VarName[NAME_SIZE];
|
char VarName[NAME_SIZE];
|
||||||
char NewVal[NAME_SIZE];
|
char NewVal[NAME_SIZE];
|
||||||
char DevType[NAME_SIZE];
|
char DevType[NAME_SIZE];
|
||||||
char DevId[NAME_SIZE];
|
char DevId[NAME_SIZE];
|
||||||
char ServiceType[NAME_SIZE];
|
char ServiceType[NAME_SIZE];
|
||||||
char ServiceVer[NAME_SIZE];
|
char ServiceVer[NAME_SIZE];
|
||||||
char Url[NAME_SIZE];
|
char Url[NAME_SIZE];
|
||||||
Upnp_SID SubsId;
|
Upnp_SID SubsId;
|
||||||
char *Cookie;
|
char *Cookie;
|
||||||
Upnp_FunPtr Fun;
|
Upnp_FunPtr Fun;
|
||||||
IXML_Document *Header;
|
IXML_Document *Header;
|
||||||
IXML_Document *Act;
|
IXML_Document *Act;
|
||||||
struct DevDesc *Devdesc;
|
struct DevDesc *Devdesc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern virtualDirList *pVirtualDirList;
|
extern virtualDirList *pVirtualDirList;
|
||||||
extern struct UpnpVirtualDirCallbacks virtualDirCallback;
|
extern struct VirtualDirCallbacks virtualDirCallback;
|
||||||
|
|
||||||
|
|
||||||
typedef enum { WEB_SERVER_DISABLED, WEB_SERVER_ENABLED } WebServerState;
|
typedef enum {
|
||||||
|
WEB_SERVER_DISABLED,
|
||||||
|
WEB_SERVER_ENABLED
|
||||||
|
} WebServerState;
|
||||||
|
|
||||||
|
|
||||||
#define E_HTTP_SYNTAX -6
|
#define E_HTTP_SYNTAX -6
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Retrieve interface information and keep it in global variables.
|
||||||
|
* If NULL, we'll find the first suitable interface for operation.
|
||||||
|
*
|
||||||
|
* The interface must fulfill these requirements:
|
||||||
|
* \li Be UP.
|
||||||
|
* \li Not be LOOPBACK.
|
||||||
|
* \li Support MULTICAST.
|
||||||
|
* \li Have a valid IPv4 or IPv6 address.
|
||||||
|
*
|
||||||
|
* We'll retrieve the following information from the interface:
|
||||||
|
* \li gIF_NAME -> Interface name (by input or found).
|
||||||
|
* \li gIF_IPV4 -> IPv4 address (if any).
|
||||||
|
* \li gIF_IPV6 -> IPv6 address (if any).
|
||||||
|
* \li gIF_INDEX -> Interface index number.
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS on success.
|
||||||
|
*/
|
||||||
|
int UpnpGetIfInfo(
|
||||||
|
/*! [in] Interface name (can be NULL). */
|
||||||
|
const char *IfName);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Initialize handle table.
|
||||||
|
*/
|
||||||
void InitHandleList();
|
void InitHandleList();
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get a free handle.
|
||||||
|
*
|
||||||
|
* \return On success, an integer greater than zero or UPNP_E_OUTOF_HANDLE on
|
||||||
|
* failure.
|
||||||
|
*/
|
||||||
int GetFreeHandle();
|
int GetFreeHandle();
|
||||||
int FreeHandle(int Handle);
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Free handle.
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS if successful or UPNP_E_INVALID_HANDLE if not
|
||||||
|
*/
|
||||||
|
int FreeHandle(
|
||||||
|
/*! [in] Handle index. */
|
||||||
|
int Handle);
|
||||||
|
|
||||||
|
|
||||||
void UpnpThreadDistribution(struct UpnpNonblockParam * Param);
|
void UpnpThreadDistribution(struct UpnpNonblockParam * Param);
|
||||||
|
|
||||||
|
|
||||||
void AutoAdvertise(void *input);
|
/*!
|
||||||
int getlocalhostname(char *out);
|
* \brief This function is a timer thread scheduled by UpnpSendAdvertisement
|
||||||
|
* to the send advetisement again.
|
||||||
|
*/
|
||||||
|
void AutoAdvertise(
|
||||||
|
/*! [in] Information provided to the thread. */
|
||||||
|
void *input);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get local IP address.
|
||||||
|
*
|
||||||
|
* Gets the ip address for the DEFAULT_INTERFACE interface which is up and not
|
||||||
|
* a loopback. Assumes at most MAX_INTERFACES interfaces
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS if successful or UPNP_E_INIT.
|
||||||
|
*/
|
||||||
|
int getlocalhostname(
|
||||||
|
/*! [out] IP address of the interface. */
|
||||||
|
char *out,
|
||||||
|
/*! [in] Length of the output buffer. */
|
||||||
|
const int out_len);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Print handle info.
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS if successful, otherwise returns appropriate error.
|
||||||
|
*/
|
||||||
|
int PrintHandleInfo(
|
||||||
|
/*! [in] Handle index. */
|
||||||
|
UpnpClient_Handle Hnd);
|
||||||
|
|
||||||
|
|
||||||
extern WebServerState bWebServerState;
|
extern WebServerState bWebServerState;
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#endif /* UPNPAPI_H */
|
||||||
|
|
||||||
|
|
||||||
/************************ END OF upnpapi.h **********************/
|
|
||||||
|
@ -1,84 +1,90 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* - Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef URLCONFIG_H
|
#ifndef URLCONFIG_H
|
||||||
#define URLCONFIG_H
|
#define URLCONFIG_H
|
||||||
#ifndef WIN32
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netinet/in.h>
|
#include "UpnpInet.h"
|
||||||
#include <arpa/inet.h>
|
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
#else
|
#else
|
||||||
#include <winsock2.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// functions available only if the web server is included
|
|
||||||
|
/* functions available only if the web server is included */
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : configure_urlbase
|
* Function: configure_urlbase
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* INOUT IXML_Document *doc ; IXML Description document
|
* INOUT IXML_Document *doc ; IXML Description document
|
||||||
* IN const struct sockaddr_in* serverAddr ; socket address object
|
* IN const struct sockaddr *serverAddr; socket address object
|
||||||
* providing the IP address and port information
|
* providing the IP address and port information
|
||||||
* IN const char* alias ; string containing the alias
|
* IN const char* alias ; string containing the alias
|
||||||
* IN time_t last_modified ; time when the XML document was
|
* IN time_t last_modified ; time when the XML document was
|
||||||
* downloaded
|
* downloaded
|
||||||
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
||||||
* document.
|
* document.
|
||||||
*
|
*
|
||||||
* Description : Configure the full URL for the description document.
|
* Description : Configure the full URL for the description document.
|
||||||
* Create the URL document and add alias, description information.
|
* Create the URL document and add alias, description information.
|
||||||
* The doc is added to the web server to be served using the given
|
* The doc is added to the web server to be served using the given
|
||||||
* alias.
|
* alias.
|
||||||
*
|
*
|
||||||
* Return : int ;
|
* Return : int ;
|
||||||
* UPNP_E_SUCCESS - On Success
|
* UPNP_E_SUCCESS - On Success
|
||||||
* UPNP_E_OUTOF_MEMORY - Default Error
|
* UPNP_E_OUTOF_MEMORY - Default Error
|
||||||
*
|
****************************************************************************/
|
||||||
* Note :
|
|
||||||
****************************************************************************/
|
|
||||||
int configure_urlbase( INOUT IXML_Document *doc,
|
int configure_urlbase( INOUT IXML_Document *doc,
|
||||||
IN const struct sockaddr_in* serverAddr,
|
IN const struct sockaddr* serverAddr,
|
||||||
IN const char* alias,
|
IN const char* alias,
|
||||||
IN time_t last_modified,
|
IN time_t last_modified,
|
||||||
OUT char docURL[LINE_SIZE] );
|
OUT char docURL[LINE_SIZE]);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern C
|
} /* extern C */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif /* URLCONFIG_H */
|
#endif /* URLCONFIG_H */
|
||||||
|
|
||||||
|
@ -1,50 +1,90 @@
|
|||||||
/*
|
/*
|
||||||
** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
* Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||||
** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
* Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
||||||
** Digital Equipment Corporation, Maynard, Mass.
|
* Digital Equipment Corporation, Maynard, Mass.
|
||||||
** Copyright (c) 1998 Microsoft.
|
* Copyright (c) 1998 Microsoft.
|
||||||
** To anyone who acknowledges that this file is provided "AS IS"
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
** without any express or implied warranty: permission to use, copy,
|
* without any express or implied warranty: permission to use, copy,
|
||||||
** modify, and distribute this file for any purpose is hereby
|
* modify, and distribute this file for any purpose is hereby
|
||||||
** granted without fee, provided that the above copyright notices and
|
* granted without fee, provided that the above copyright notices and
|
||||||
** this notice appears in all source code copies, and that none of
|
* this notice appears in all source code copies, and that none of
|
||||||
** the names of Open Software Foundation, Inc., Hewlett-Packard
|
* the names of Open Software Foundation, Inc., Hewlett-Packard
|
||||||
** Company, or Digital Equipment Corporation be used in advertising
|
* Company, or Digital Equipment Corporation be used in advertising
|
||||||
** or publicity pertaining to distribution of the software without
|
* or publicity pertaining to distribution of the software without
|
||||||
** specific, written prior permission. Neither Open Software
|
* specific, written prior permission. Neither Open Software
|
||||||
** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
* Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
||||||
** Corporation makes any representations about the suitability of
|
* Corporation makes any representations about the suitability of
|
||||||
** this software for any purpose.
|
* this software for any purpose.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct _uuid_upnp {
|
|
||||||
unsigned32 time_low;
|
|
||||||
unsigned16 time_mid;
|
|
||||||
unsigned16 time_hi_and_version;
|
|
||||||
unsigned8 clock_seq_hi_and_reserved;
|
|
||||||
unsigned8 clock_seq_low;
|
|
||||||
byte node[6];
|
|
||||||
} uuid_upnp;
|
|
||||||
|
|
||||||
/* uuid_create -- generate a UUID */
|
#include "sysdep.h"
|
||||||
int uuid_create(uuid_upnp * id);
|
|
||||||
void uuid_unpack(uuid_upnp *u, char *out); // out will be xxxx-xx-xx-xx-xxxxxx format
|
|
||||||
|
|
||||||
/* uuid_create_from_name -- create a UUID using a "name"
|
|
||||||
from a "name space" */
|
|
||||||
void uuid_create_from_name(
|
|
||||||
uuid_upnp * uid, /* resulting UUID */
|
|
||||||
uuid_upnp nsid, /* UUID to serve as context, so identical
|
|
||||||
names from different name spaces generate
|
|
||||||
different UUIDs */
|
|
||||||
void * name, /* the name from which to generate a UUID */
|
|
||||||
int namelen /* the length of the name */
|
|
||||||
);
|
|
||||||
|
|
||||||
/* uuid_compare -- Compare two UUID's "lexically" and return
|
/*! . */
|
||||||
-1 u1 is lexically before u2
|
typedef struct _uuid_upnp {
|
||||||
0 u1 is equal to u2
|
/*! . */
|
||||||
1 u1 is lexically after u2
|
unsigned32 time_low;
|
||||||
Note: lexical ordering is not temporal ordering!
|
/*! . */
|
||||||
*/
|
unsigned16 time_mid;
|
||||||
int uuid_compare(uuid_upnp *u1, uuid_upnp *u2);
|
/*! . */
|
||||||
|
unsigned16 time_hi_and_version;
|
||||||
|
/*! . */
|
||||||
|
unsigned8 clock_seq_hi_and_reserved;
|
||||||
|
/*! . */
|
||||||
|
unsigned8 clock_seq_low;
|
||||||
|
/*! . */
|
||||||
|
byte node[6];
|
||||||
|
} uuid_upnp;
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Generate a UUID.
|
||||||
|
*/
|
||||||
|
int uuid_create(
|
||||||
|
/*! . */
|
||||||
|
uuid_upnp * id);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Out will be xxxx-xx-xx-xx-xxxxxx format.
|
||||||
|
*/
|
||||||
|
void uuid_unpack(
|
||||||
|
/*! . */
|
||||||
|
uuid_upnp *u,
|
||||||
|
/*! . */
|
||||||
|
char *out);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Create a UUID using a "name" from a "name space"
|
||||||
|
*/
|
||||||
|
void uuid_create_from_name(
|
||||||
|
/*! Resulting UUID. */
|
||||||
|
uuid_upnp *uid,
|
||||||
|
/*! UUID to serve as context, so identical names from different name
|
||||||
|
* spaces generate different UUIDs. */
|
||||||
|
uuid_upnp nsid,
|
||||||
|
/*! The name from which to generate a UUID. */
|
||||||
|
void *name,
|
||||||
|
/*! The length of the name. */
|
||||||
|
int namelen
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Compare two UUID's "lexically".
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
* -1 u1 is lexically before u2
|
||||||
|
* 0 u1 is equal to u2
|
||||||
|
* 1 u1 is lexically after u2
|
||||||
|
*
|
||||||
|
* \note Lexical ordering is not temporal ordering!
|
||||||
|
*/
|
||||||
|
int uuid_compare(
|
||||||
|
/*! . */
|
||||||
|
uuid_upnp *u1,
|
||||||
|
/*! . */
|
||||||
|
uuid_upnp *u2);
|
||||||
|
|
||||||
|
@ -1,57 +1,68 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/*******************************************************************************
|
||||||
//
|
*
|
||||||
// Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
// All rights reserved.
|
* All rights reserved.
|
||||||
//
|
*
|
||||||
// Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
// modification, are permitted provided that the following conditions are met:
|
* modification, are permitted provided that the following conditions are met:
|
||||||
//
|
*
|
||||||
// * Redistributions of source code must retain the above copyright notice,
|
* - Redistributions of source code must retain the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer.
|
* this list of conditions and the following disclaimer.
|
||||||
// * Redistributions in binary form must reproduce the above copyright notice,
|
* - Redistributions in binary form must reproduce the above copyright notice,
|
||||||
// this list of conditions and the following disclaimer in the documentation
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
// and/or other materials provided with the distribution.
|
* and/or other materials provided with the distribution.
|
||||||
// * Neither name of Intel Corporation nor the names of its contributors
|
* - Neither name of Intel Corporation nor the names of its contributors
|
||||||
// may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
// without specific prior written permission.
|
* without specific prior written permission.
|
||||||
//
|
*
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
|
||||||
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||||
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
//
|
*
|
||||||
///////////////////////////////////////////////////////////////////////////
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \file
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
#if EXCLUDE_SOAP == 0
|
#if EXCLUDE_SOAP == 0
|
||||||
|
|
||||||
|
|
||||||
#define SOAP_BODY "Body"
|
#define SOAP_BODY "Body"
|
||||||
#define SOAP_URN "http:/""/schemas.xmlsoap.org/soap/envelope/"
|
#define SOAP_URN "http:/""/schemas.xmlsoap.org/soap/envelope/"
|
||||||
|
|
||||||
#define QUERY_STATE_VAR_URN "urn:schemas-upnp-org:control-1-0"
|
#define QUERY_STATE_VAR_URN "urn:schemas-upnp-org:control-1-0"
|
||||||
|
|
||||||
#include "upnpapi.h"
|
|
||||||
#include "parsetools.h"
|
|
||||||
#include "statcodes.h"
|
|
||||||
#include "httpparser.h"
|
#include "httpparser.h"
|
||||||
#include "httpreadwrite.h"
|
#include "httpreadwrite.h"
|
||||||
#include "unixutil.h"
|
#include "parsetools.h"
|
||||||
#include "soaplib.h"
|
#include "soaplib.h"
|
||||||
#include "ssdplib.h"
|
#include "ssdplib.h"
|
||||||
|
#include "statcodes.h"
|
||||||
|
#include "unixutil.h"
|
||||||
|
#include "upnpapi.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// timeout duration in secs for transmission/reception
|
|
||||||
|
/*! timeout duration in secs for transmission/reception */
|
||||||
#define SOAP_TIMEOUT UPNP_TIMEOUT
|
#define SOAP_TIMEOUT UPNP_TIMEOUT
|
||||||
|
|
||||||
#define SREQ_HDR_NOT_FOUND -1
|
#define SREQ_HDR_NOT_FOUND -1
|
||||||
@ -65,13 +76,14 @@
|
|||||||
|
|
||||||
static const char *Soap_Invalid_Action = "Invalid Action";
|
static const char *Soap_Invalid_Action = "Invalid Action";
|
||||||
|
|
||||||
//static const char* Soap_Invalid_Args = "Invalid Args";
|
/*static const char* Soap_Invalid_Args = "Invalid Args"; */
|
||||||
static const char *Soap_Action_Failed = "Action Failed";
|
static const char *Soap_Action_Failed = "Action Failed";
|
||||||
static const char *Soap_Invalid_Var = "Invalid Var";
|
static const char *Soap_Invalid_Var = "Invalid Var";
|
||||||
|
|
||||||
const char *ContentTypeHeader =
|
const char *ContentTypeHeader =
|
||||||
"CONTENT-TYPE: text/xml; charset=\"utf-8\"\r\n";
|
"CONTENT-TYPE: text/xml; charset=\"utf-8\"\r\n";
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Function : get_request_type
|
* Function : get_request_type
|
||||||
*
|
*
|
||||||
@ -572,7 +584,7 @@ check_soap_action_header( IN http_message_t * request,
|
|||||||
* OUT char device_udn[LINE_SIZE] : Device UDN string
|
* OUT char device_udn[LINE_SIZE] : Device UDN string
|
||||||
* OUT char service_id[LINE_SIZE] : Service ID string
|
* OUT char service_id[LINE_SIZE] : Service ID string
|
||||||
* OUT Upnp_FunPtr *callback : callback function of the device
|
* OUT Upnp_FunPtr *callback : callback function of the device
|
||||||
* application
|
* application
|
||||||
* OUT void** cookie : cookie stored by device application
|
* OUT void** cookie : cookie stored by device application
|
||||||
*
|
*
|
||||||
* Description : This function retrives all the information needed to
|
* Description : This function retrives all the information needed to
|
||||||
@ -586,12 +598,13 @@ check_soap_action_header( IN http_message_t * request,
|
|||||||
* Note :
|
* Note :
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static int
|
static int
|
||||||
get_device_info( IN http_message_t * request,
|
get_device_info( IN http_message_t *request,
|
||||||
IN int isQuery,
|
IN int isQuery,
|
||||||
IN IXML_Document * actionDoc,
|
IN IXML_Document *actionDoc,
|
||||||
|
IN int AddressFamily,
|
||||||
OUT char device_udn[LINE_SIZE],
|
OUT char device_udn[LINE_SIZE],
|
||||||
OUT char service_id[LINE_SIZE],
|
OUT char service_id[LINE_SIZE],
|
||||||
OUT Upnp_FunPtr * callback,
|
OUT Upnp_FunPtr *callback,
|
||||||
OUT void **cookie )
|
OUT void **cookie )
|
||||||
{
|
{
|
||||||
struct Handle_Info *device_info;
|
struct Handle_Info *device_info;
|
||||||
@ -609,7 +622,8 @@ get_device_info( IN http_message_t * request,
|
|||||||
|
|
||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) {
|
if( GetDeviceHandleInfo( AddressFamily,
|
||||||
|
&device_hnd, &device_info ) != HND_DEVICE ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -840,10 +854,10 @@ error_handler:
|
|||||||
*
|
*
|
||||||
* Note :
|
* Note :
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
static UPNP_INLINE void
|
static UPNP_INLINE void handle_query_variable(
|
||||||
handle_query_variable( IN SOCKINFO * info,
|
IN SOCKINFO *info,
|
||||||
IN http_message_t * request,
|
IN http_message_t *request,
|
||||||
IN IXML_Document * xml_doc )
|
IN IXML_Document *xml_doc )
|
||||||
{
|
{
|
||||||
Upnp_FunPtr soap_event_callback;
|
Upnp_FunPtr soap_event_callback;
|
||||||
void *cookie;
|
void *cookie;
|
||||||
@ -859,9 +873,14 @@ handle_query_variable( IN SOCKINFO * info,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// get info for event
|
// get info for event
|
||||||
if( get_device_info( request, 1, xml_doc, variable.DevUDN,
|
err_code = get_device_info(
|
||||||
variable.ServiceID,
|
request, 1, xml_doc,
|
||||||
&soap_event_callback, &cookie ) != 0 ) {
|
info->foreign_sockaddr.ss_family,
|
||||||
|
variable.DevUDN,
|
||||||
|
variable.ServiceID,
|
||||||
|
&soap_event_callback,
|
||||||
|
&cookie);
|
||||||
|
if( err_code != 0 ) {
|
||||||
send_error_response( info, SOAP_INVALID_VAR,
|
send_error_response( info, SOAP_INVALID_VAR,
|
||||||
Soap_Invalid_Var, request );
|
Soap_Invalid_Var, request );
|
||||||
return;
|
return;
|
||||||
@ -871,7 +890,7 @@ handle_query_variable( IN SOCKINFO * info,
|
|||||||
variable.ErrCode = UPNP_E_SUCCESS;
|
variable.ErrCode = UPNP_E_SUCCESS;
|
||||||
namecopy( variable.StateVarName, var_name );
|
namecopy( variable.StateVarName, var_name );
|
||||||
variable.CurrentVal = NULL;
|
variable.CurrentVal = NULL;
|
||||||
variable.CtrlPtIPAddr = info->foreign_ip_addr;
|
variable.CtrlPtIPAddr = info->foreign_sockaddr;
|
||||||
|
|
||||||
// send event
|
// send event
|
||||||
soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie );
|
soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie );
|
||||||
@ -883,8 +902,8 @@ handle_query_variable( IN SOCKINFO * info,
|
|||||||
if( variable.CurrentVal == NULL ) {
|
if( variable.CurrentVal == NULL ) {
|
||||||
err_code = SOAP_ACTION_FAILED;
|
err_code = SOAP_ACTION_FAILED;
|
||||||
err_str = Soap_Action_Failed;
|
err_str = Soap_Action_Failed;
|
||||||
send_error_response( info, SOAP_INVALID_VAR,
|
send_error_response( info, SOAP_INVALID_VAR, Soap_Invalid_Var, request );
|
||||||
Soap_Invalid_Var, request );
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if( variable.ErrCode != UPNP_E_SUCCESS ) {
|
if( variable.ErrCode != UPNP_E_SUCCESS ) {
|
||||||
@ -951,9 +970,15 @@ handle_invoke_action( IN SOCKINFO * info,
|
|||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
// get device info for action event
|
// get device info for action event
|
||||||
err_code = get_device_info( request, 0, xml_doc, action.DevUDN,
|
err_code = get_device_info(
|
||||||
action.ServiceID, &soap_event_callback,
|
request,
|
||||||
&cookie );
|
0,
|
||||||
|
xml_doc,
|
||||||
|
info->foreign_sockaddr.ss_family,
|
||||||
|
action.DevUDN,
|
||||||
|
action.ServiceID,
|
||||||
|
&soap_event_callback,
|
||||||
|
&cookie );
|
||||||
|
|
||||||
if( err_code != UPNP_E_SUCCESS ) {
|
if( err_code != UPNP_E_SUCCESS ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
@ -964,10 +989,9 @@ handle_invoke_action( IN SOCKINFO * info,
|
|||||||
action.ActionRequest = resp_node;
|
action.ActionRequest = resp_node;
|
||||||
action.ActionResult = NULL;
|
action.ActionResult = NULL;
|
||||||
action.ErrCode = UPNP_E_SUCCESS;
|
action.ErrCode = UPNP_E_SUCCESS;
|
||||||
action.CtrlPtIPAddr = info->foreign_ip_addr;
|
action.CtrlPtIPAddr = info->foreign_sockaddr;
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
|
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n");
|
||||||
"Calling Callback\n" );
|
|
||||||
|
|
||||||
soap_event_callback( UPNP_CONTROL_ACTION_REQUEST, &action, cookie );
|
soap_event_callback( UPNP_CONTROL_ACTION_REQUEST, &action, cookie );
|
||||||
|
|
||||||
@ -993,7 +1017,7 @@ handle_invoke_action( IN SOCKINFO * info,
|
|||||||
err_code = 0;
|
err_code = 0;
|
||||||
|
|
||||||
// error handling and cleanup
|
// error handling and cleanup
|
||||||
error_handler:
|
error_handler:
|
||||||
ixmlDocument_free( action.ActionResult );
|
ixmlDocument_free( action.ActionResult );
|
||||||
ixmlDocument_free( resp_node );
|
ixmlDocument_free( resp_node );
|
||||||
action_name.buf[action_name.length] = save_char; // restore
|
action_name.buf[action_name.length] = save_char; // restore
|
||||||
|
@ -1,72 +1,78 @@
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
/**************************************************************************
|
||||||
//
|
*
|
||||||
// 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"
|
||||||
|
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
#if EXCLUDE_SSDP == 0
|
#if EXCLUDE_SSDP == 0
|
||||||
|
|
||||||
#include "ssdplib.h"
|
|
||||||
#include "upnpapi.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "ThreadPool.h"
|
|
||||||
|
|
||||||
#include "httpparser.h"
|
#include "httpparser.h"
|
||||||
#include "httpreadwrite.h"
|
#include "httpreadwrite.h"
|
||||||
|
/*#include "ssdp_ResultData.h"*/
|
||||||
|
#include "ssdplib.h"
|
||||||
#include "statcodes.h"
|
#include "statcodes.h"
|
||||||
|
|
||||||
#include "unixutil.h"
|
#include "unixutil.h"
|
||||||
|
#include "upnpapi.h"
|
||||||
|
#include "UpnpInet.h"
|
||||||
|
#include "ThreadPool.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <ws2tcpip.h>
|
|
||||||
#include <winsock2.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : send_search_result
|
* Function: send_search_result
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN void *data: Search reply from the device
|
* IN void *data: Search reply from the device
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function sends a callback to the control point application with
|
* This function sends a callback to the control point application with
|
||||||
* a SEARCH result
|
* a SEARCH result
|
||||||
*
|
*
|
||||||
* Returns: void
|
* Returns: void
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
void
|
void send_search_result(IN void *data)
|
||||||
send_search_result( IN void *data )
|
|
||||||
{
|
{
|
||||||
ResultData *temp = ( ResultData * ) data;
|
ResultData *temp = ( ResultData * ) data;
|
||||||
|
|
||||||
@ -76,31 +82,34 @@ send_search_result( IN void *data )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : ssdp_handle_ctrlpt_msg
|
* Function: ssdp_handle_ctrlpt_msg
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t* hmsg: SSDP message from the device
|
* IN http_message_t *hmsg:
|
||||||
* IN struct sockaddr_in* dest_addr: Address of the device
|
* SSDP message from the device
|
||||||
* IN xboolean timeout: timeout kept by the control point while
|
* IN struct sockaddr *dest_addr:
|
||||||
* sending search message
|
* Address of the device
|
||||||
* IN void* cookie: Cookie stored by the control point application.
|
* IN xboolean timeout:
|
||||||
* This cookie will be returned to the control point
|
* timeout kept by the control point while
|
||||||
* in the callback
|
* sending search message
|
||||||
*
|
* IN void* cookie:
|
||||||
* Description:
|
* Cookie stored by the control point application.
|
||||||
* This function handles the ssdp messages from the devices. These
|
* This cookie will be returned to the control point
|
||||||
* messages includes the search replies, advertisement of device coming
|
* in the callback
|
||||||
* alive and bye byes.
|
*
|
||||||
*
|
* Description:
|
||||||
* Returns: void
|
* This function handles the ssdp messages from the devices. These
|
||||||
*
|
* messages includes the search replies, advertisement of device coming
|
||||||
***************************************************************************/
|
* alive and bye byes.
|
||||||
void
|
*
|
||||||
ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
* Returns: void
|
||||||
IN struct sockaddr_in *dest_addr,
|
*
|
||||||
IN xboolean timeout, // only in search reply
|
***************************************************************************/
|
||||||
|
void ssdp_handle_ctrlpt_msg(
|
||||||
IN void *cookie ) // only in search reply
|
IN http_message_t *hmsg,
|
||||||
|
IN struct sockaddr *dest_addr,
|
||||||
|
IN xboolean timeout, // only in search reply
|
||||||
|
IN void *cookie) // only in search reply
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
@ -108,9 +117,9 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
xboolean is_byebye; // byebye or alive
|
xboolean is_byebye; // byebye or alive
|
||||||
struct Upnp_Discovery param;
|
struct Upnp_Discovery param;
|
||||||
SsdpEvent event;
|
SsdpEvent event;
|
||||||
xboolean nt_found,
|
xboolean nt_found;
|
||||||
usn_found,
|
xboolean usn_found;
|
||||||
st_found;
|
xboolean st_found;
|
||||||
char save_char;
|
char save_char;
|
||||||
Upnp_EventType event_type;
|
Upnp_EventType event_type;
|
||||||
Upnp_FunPtr ctrlpt_callback;
|
Upnp_FunPtr ctrlpt_callback;
|
||||||
@ -125,7 +134,7 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
|
|
||||||
HandleReadLock();
|
HandleReadLock();
|
||||||
|
|
||||||
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -135,7 +144,7 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
|
|
||||||
// search timeout
|
// search timeout
|
||||||
if( timeout ) {
|
if ( timeout ) {
|
||||||
ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
|
ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -188,26 +197,22 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
|
|
||||||
nt_found = FALSE;
|
nt_found = FALSE;
|
||||||
|
|
||||||
if( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
|
if ( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
|
||||||
save_char = hdr_value.buf[hdr_value.length];
|
save_char = hdr_value.buf[hdr_value.length];
|
||||||
hdr_value.buf[hdr_value.length] = '\0';
|
hdr_value.buf[hdr_value.length] = '\0';
|
||||||
|
|
||||||
nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );
|
nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );
|
||||||
|
|
||||||
hdr_value.buf[hdr_value.length] = save_char;
|
hdr_value.buf[hdr_value.length] = save_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
usn_found = FALSE;
|
usn_found = FALSE;
|
||||||
if( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
|
if ( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
|
||||||
save_char = hdr_value.buf[hdr_value.length];
|
save_char = hdr_value.buf[hdr_value.length];
|
||||||
hdr_value.buf[hdr_value.length] = '\0';
|
hdr_value.buf[hdr_value.length] = '\0';
|
||||||
|
|
||||||
usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );
|
usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );
|
||||||
|
|
||||||
hdr_value.buf[hdr_value.length] = save_char;
|
hdr_value.buf[hdr_value.length] = save_char;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( nt_found || usn_found ) {
|
if ( nt_found || usn_found ) {
|
||||||
strcpy( param.DeviceId, event.UDN );
|
strcpy( param.DeviceId, event.UDN );
|
||||||
strcpy( param.DeviceType, event.DeviceType );
|
strcpy( param.DeviceType, event.DeviceType );
|
||||||
strcpy( param.ServiceType, event.ServiceType );
|
strcpy( param.ServiceType, event.ServiceType );
|
||||||
@ -216,11 +221,10 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
// ADVERT. OR BYEBYE
|
// ADVERT. OR BYEBYE
|
||||||
if( hmsg->is_request ) {
|
if( hmsg->is_request ) {
|
||||||
// use NTS hdr to determine advert., or byebye
|
// use NTS hdr to determine advert., or byebye
|
||||||
//
|
if ( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
|
||||||
if( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
|
|
||||||
return; // error; NTS header not found
|
return; // error; NTS header not found
|
||||||
}
|
}
|
||||||
if( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
|
if ( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
|
||||||
is_byebye = FALSE;
|
is_byebye = FALSE;
|
||||||
} else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
|
} else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
|
||||||
is_byebye = TRUE;
|
is_byebye = TRUE;
|
||||||
@ -228,7 +232,7 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
return; // bad value
|
return; // bad value
|
||||||
}
|
}
|
||||||
|
|
||||||
if( is_byebye ) {
|
if ( is_byebye ) {
|
||||||
// check device byebye
|
// check device byebye
|
||||||
if( !nt_found || !usn_found ) {
|
if( !nt_found || !usn_found ) {
|
||||||
return; // bad byebye
|
return; // bad byebye
|
||||||
@ -243,7 +247,6 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
strlen( param.Location ) == 0 || param.Expires <= 0 ) {
|
strlen( param.Location ) == 0 || param.Expires <= 0 ) {
|
||||||
return; // bad advertisement
|
return; // bad advertisement
|
||||||
}
|
}
|
||||||
|
|
||||||
event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
|
event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,61 +285,50 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
matched = 0;
|
matched = 0;
|
||||||
// check for match of ST header and search target
|
// check for match of ST header and search target
|
||||||
switch ( searchArg->requestType ) {
|
switch ( searchArg->requestType ) {
|
||||||
case SSDP_ALL:
|
case SSDP_ALL:
|
||||||
{
|
|
||||||
matched = 1;
|
matched = 1;
|
||||||
break;
|
break;
|
||||||
}
|
case SSDP_ROOTDEVICE:
|
||||||
case SSDP_ROOTDEVICE:
|
|
||||||
{
|
|
||||||
matched = ( event.RequestType == SSDP_ROOTDEVICE );
|
matched = ( event.RequestType == SSDP_ROOTDEVICE );
|
||||||
break;
|
break;
|
||||||
}
|
case SSDP_DEVICEUDN:
|
||||||
case SSDP_DEVICEUDN:
|
|
||||||
{
|
|
||||||
matched = !( strncmp( searchArg->searchTarget,
|
matched = !( strncmp( searchArg->searchTarget,
|
||||||
hdr_value.buf,
|
hdr_value.buf,
|
||||||
hdr_value.length ) );
|
hdr_value.length ) );
|
||||||
break;
|
break;
|
||||||
}
|
case SSDP_DEVICETYPE: {
|
||||||
case SSDP_DEVICETYPE:
|
int m = min( hdr_value.length,
|
||||||
{
|
strlen( searchArg->searchTarget ) );
|
||||||
|
matched = !( strncmp( searchArg->searchTarget,
|
||||||
|
hdr_value.buf, m ) );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SSDP_SERVICE: {
|
||||||
int m = min( hdr_value.length,
|
int m = min( hdr_value.length,
|
||||||
strlen( searchArg->searchTarget ) );
|
strlen( searchArg->searchTarget ) );
|
||||||
|
|
||||||
matched = !( strncmp( searchArg->searchTarget,
|
matched = !( strncmp( searchArg->searchTarget,
|
||||||
hdr_value.buf, m ) );
|
hdr_value.buf, m ) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SSDP_SERVICE:
|
default:
|
||||||
{
|
|
||||||
int m = min( hdr_value.length,
|
|
||||||
strlen( searchArg->searchTarget ) );
|
|
||||||
|
|
||||||
matched = !( strncmp( searchArg->searchTarget,
|
|
||||||
hdr_value.buf, m ) );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
matched = 0;
|
matched = 0;
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( matched ) {
|
if (matched) {
|
||||||
// schedule call back
|
// schedule call back
|
||||||
threadData =
|
threadData =
|
||||||
( ResultData * ) malloc( sizeof( ResultData ) );
|
( ResultData * ) malloc( sizeof( ResultData ) );
|
||||||
if( threadData != NULL ) {
|
if (threadData != NULL) {
|
||||||
threadData->param = param;
|
threadData->param = param;
|
||||||
threadData->cookie = searchArg->cookie;
|
threadData->cookie = searchArg->cookie;
|
||||||
threadData->ctrlpt_callback = ctrlpt_callback;
|
threadData->ctrlpt_callback = ctrlpt_callback;
|
||||||
TPJobInit( &job, ( start_routine ) send_search_result,
|
TPJobInit( &job, ( start_routine ) send_search_result,
|
||||||
threadData );
|
threadData );
|
||||||
TPJobSetPriority( &job, MED_PRIORITY );
|
TPJobSetPriority(&job, MED_PRIORITY);
|
||||||
TPJobSetFreeFunction( &job, ( free_routine ) free );
|
TPJobSetFreeFunction( &job, ( free_routine ) free );
|
||||||
ThreadPoolAdd( &gRecvThreadPool, &job, NULL );
|
ThreadPoolAdd(&gRecvThreadPool, &job, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node = ListNext( &ctrlpt_info->SsdpSearchList, node );
|
node = ListNext( &ctrlpt_info->SsdpSearchList, node );
|
||||||
@ -347,50 +339,6 @@ ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function : process_reply
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN char* request_buf: the response came from the device
|
|
||||||
* IN int buf_len: The length of the response buffer
|
|
||||||
* IN struct sockaddr_in* dest_addr: The address of the device
|
|
||||||
* IN void *cookie : cookie passed by the control point application
|
|
||||||
* at the time of sending search message
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function processes reply recevied from a search
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
#ifndef WIN32
|
|
||||||
#warning There are currently no uses of the function 'process_reply()' in the code.
|
|
||||||
#warning 'process_reply()' is a candidate for removal.
|
|
||||||
#else
|
|
||||||
#pragma message("There are currently no uses of the function 'process_reply()' in the code.")
|
|
||||||
#pragma message("'process_reply()' is a candidate for removal.")
|
|
||||||
#endif
|
|
||||||
static UPNP_INLINE void
|
|
||||||
process_reply( IN char *request_buf,
|
|
||||||
IN int buf_len,
|
|
||||||
IN struct sockaddr_in *dest_addr,
|
|
||||||
IN void *cookie )
|
|
||||||
{
|
|
||||||
http_parser_t parser;
|
|
||||||
|
|
||||||
parser_response_init( &parser, HTTPMETHOD_MSEARCH );
|
|
||||||
|
|
||||||
// parse
|
|
||||||
if( parser_append( &parser, request_buf, buf_len ) != PARSE_SUCCESS ) {
|
|
||||||
httpmsg_destroy( &parser.msg );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// handle reply
|
|
||||||
ssdp_handle_ctrlpt_msg( &parser.msg, dest_addr, FALSE, cookie );
|
|
||||||
|
|
||||||
// done
|
|
||||||
httpmsg_destroy( &parser.msg );
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : CreateClientRequestPacket
|
* Function : CreateClientRequestPacket
|
||||||
@ -400,6 +348,7 @@ process_reply( IN char *request_buf,
|
|||||||
* IN char *SearchTarget:Search Target
|
* IN char *SearchTarget:Search Target
|
||||||
* IN int Mx dest_addr: Number of seconds to wait to
|
* IN int Mx dest_addr: Number of seconds to wait to
|
||||||
* collect all the responses
|
* collect all the responses
|
||||||
|
* IN int AddressFamily: search address family
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP search request packet
|
* This function creates a HTTP search request packet
|
||||||
@ -411,13 +360,18 @@ process_reply( IN char *request_buf,
|
|||||||
static void
|
static void
|
||||||
CreateClientRequestPacket( IN char *RqstBuf,
|
CreateClientRequestPacket( IN char *RqstBuf,
|
||||||
IN int Mx,
|
IN int Mx,
|
||||||
IN char *SearchTarget )
|
IN char *SearchTarget,
|
||||||
|
IN int AddressFamily )
|
||||||
{
|
{
|
||||||
char TempBuf[COMMAND_LEN];
|
char TempBuf[COMMAND_LEN];
|
||||||
|
|
||||||
strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );
|
strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );
|
||||||
|
|
||||||
sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
|
if (AddressFamily == AF_INET) {
|
||||||
|
sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
|
||||||
|
} else if (AddressFamily == AF_INET6) {
|
||||||
|
sprintf( TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_LINKLOCAL, SSDP_PORT );
|
||||||
|
}
|
||||||
strcat( RqstBuf, TempBuf );
|
strcat( RqstBuf, TempBuf );
|
||||||
strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
|
strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
|
||||||
|
|
||||||
@ -431,7 +385,6 @@ CreateClientRequestPacket( IN char *RqstBuf,
|
|||||||
strcat( RqstBuf, TempBuf );
|
strcat( RqstBuf, TempBuf );
|
||||||
}
|
}
|
||||||
strcat( RqstBuf, "\r\n" );
|
strcat( RqstBuf, "\r\n" );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -507,7 +460,17 @@ searchExpired( void *arg )
|
|||||||
* This cokie will be returned to application in the callback.
|
* This cokie will be returned to application in the callback.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates and send the search request for a specific URL.
|
* This function implements the search request of the discovery phase.
|
||||||
|
* A M-SEARCH request is sent on the SSDP channel for both IPv4 and
|
||||||
|
* IPv6 addresses. The search target(ST) is required and must be one of
|
||||||
|
* the following:
|
||||||
|
* - "ssdp:all" : Search for all devices and services.
|
||||||
|
* - "ssdp:rootdevice" : Search for root devices only.
|
||||||
|
* - "uuid:<device-uuid>" : Search for a particular device.
|
||||||
|
* - "urn:schemas-upnp-org:device:<deviceType:v>"
|
||||||
|
* - "urn:schemas-upnp-org:service:<serviceType:v>"
|
||||||
|
* - "urn:<domain-name>:device:<deviceType:v>"
|
||||||
|
* - "urn:<domain-name>:service:<serviceType:v>"
|
||||||
*
|
*
|
||||||
* Returns: int
|
* Returns: int
|
||||||
* 1 if successful else appropriate error
|
* 1 if successful else appropriate error
|
||||||
@ -518,18 +481,23 @@ SearchByTarget( IN int Mx,
|
|||||||
IN void *Cookie )
|
IN void *Cookie )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int socklen = sizeof( struct sockaddr_in );
|
int socklen = sizeof( struct sockaddr_storage );
|
||||||
int *id = NULL;
|
int *id = NULL;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *ReqBuf;
|
char ReqBufv4[BUFSIZE];
|
||||||
struct sockaddr_in destAddr;
|
char ReqBufv6[BUFSIZE];
|
||||||
|
struct sockaddr_storage __ss_v4;
|
||||||
|
struct sockaddr_storage __ss_v6;
|
||||||
|
struct sockaddr_in* destAddr4 = (struct sockaddr_in*)&__ss_v4;
|
||||||
|
struct sockaddr_in6* destAddr6 = (struct sockaddr_in6*)&__ss_v6;
|
||||||
fd_set wrSet;
|
fd_set wrSet;
|
||||||
SsdpSearchArg *newArg = NULL;
|
SsdpSearchArg *newArg = NULL;
|
||||||
int timeTillRead = 0;
|
int timeTillRead = 0;
|
||||||
int handle;
|
int handle;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
enum SsdpSearchType requestType;
|
enum SsdpSearchType requestType;
|
||||||
unsigned long addr = inet_addr( LOCAL_HOST );
|
unsigned long addrv4 = inet_addr( gIF_IPV4 );
|
||||||
|
int max_fd = 0;
|
||||||
|
|
||||||
//ThreadData *ThData;
|
//ThreadData *ThData;
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
@ -539,12 +507,7 @@ SearchByTarget( IN int Mx,
|
|||||||
return UPNP_E_INVALID_PARAM;
|
return UPNP_E_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReqBuf = (char *)malloc( BUFSIZE );
|
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "Inside SearchByTarget\n");
|
||||||
if( ReqBuf == NULL ) {
|
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
|
||||||
}
|
|
||||||
|
|
||||||
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n");
|
|
||||||
|
|
||||||
timeTillRead = Mx;
|
timeTillRead = Mx;
|
||||||
|
|
||||||
@ -554,21 +517,24 @@ SearchByTarget( IN int Mx,
|
|||||||
timeTillRead = MAX_SEARCH_TIME;
|
timeTillRead = MAX_SEARCH_TIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateClientRequestPacket( ReqBuf, timeTillRead, St );
|
CreateClientRequestPacket( ReqBufv4, timeTillRead, St, AF_INET );
|
||||||
memset( ( char * )&destAddr, 0, sizeof( struct sockaddr_in ) );
|
CreateClientRequestPacket( ReqBufv6, timeTillRead, St, AF_INET6 );
|
||||||
|
|
||||||
destAddr.sin_family = AF_INET;
|
memset( &__ss_v4, 0, sizeof( __ss_v4 ) );
|
||||||
destAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
destAddr4->sin_family = AF_INET;
|
||||||
destAddr.sin_port = htons( SSDP_PORT );
|
inet_pton( AF_INET, SSDP_IP, &destAddr4->sin_addr );
|
||||||
|
destAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
|
||||||
FD_ZERO( &wrSet );
|
memset( &__ss_v6, 0, sizeof( __ss_v6 ) );
|
||||||
FD_SET( gSsdpReqSocket, &wrSet );
|
destAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr );
|
||||||
|
destAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
destAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
|
||||||
// add search criteria to list
|
// add search criteria to list
|
||||||
HandleLock();
|
HandleLock();
|
||||||
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
free( ReqBuf );
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -590,34 +556,56 @@ SearchByTarget( IN int Mx,
|
|||||||
ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
|
ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
|
|
||||||
ret = setsockopt( gSsdpReqSocket, IPPROTO_IP, IP_MULTICAST_IF,
|
FD_ZERO( &wrSet );
|
||||||
(char *)&addr, sizeof (addr) );
|
if( gSsdpReqSocket4 != INVALID_SOCKET ) {
|
||||||
|
setsockopt( gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
(char *)&addrv4, sizeof (addrv4) );
|
||||||
|
FD_SET( gSsdpReqSocket4, &wrSet );
|
||||||
|
max_fd = max(max_fd, gSsdpReqSocket4);
|
||||||
|
}
|
||||||
|
if( gSsdpReqSocket6 != INVALID_SOCKET ) {
|
||||||
|
setsockopt( gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
|
(char *)&gIF_INDEX, sizeof(gIF_INDEX) );
|
||||||
|
FD_SET( gSsdpReqSocket6, &wrSet );
|
||||||
|
max_fd = max(max_fd, gSsdpReqSocket6);
|
||||||
|
}
|
||||||
|
|
||||||
ret = select( gSsdpReqSocket + 1, NULL, &wrSet, NULL, NULL );
|
ret = select( max_fd + 1, NULL, &wrSet, NULL, NULL );
|
||||||
if( ret == -1 ) {
|
if( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"SSDP_LIB: Error in select(): %s\n",
|
"SSDP_LIB: Error in select(): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( gSsdpReqSocket, SD_BOTH );
|
shutdown( gSsdpReqSocket4, SD_BOTH );
|
||||||
UpnpCloseSocket( gSsdpReqSocket );
|
UpnpCloseSocket( gSsdpReqSocket4 );
|
||||||
free( ReqBuf );
|
shutdown( gSsdpReqSocket6, SD_BOTH );
|
||||||
|
UpnpCloseSocket( gSsdpReqSocket6 );
|
||||||
|
|
||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
} else if( FD_ISSET( gSsdpReqSocket, &wrSet ) ) {
|
}
|
||||||
|
if( gSsdpReqSocket6 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( gSsdpReqSocket6, &wrSet ) ) {
|
||||||
int NumCopy = 0;
|
int NumCopy = 0;
|
||||||
while( NumCopy < NUM_SSDP_COPY ) {
|
while( NumCopy < NUM_SSDP_COPY ) {
|
||||||
sendto( gSsdpReqSocket, ReqBuf, strlen( ReqBuf ), 0,
|
sendto( gSsdpReqSocket6, ReqBufv6, strlen( ReqBufv6 ), 0,
|
||||||
(struct sockaddr *)&destAddr, socklen );
|
(struct sockaddr *)&__ss_v6, socklen );
|
||||||
|
NumCopy++;
|
||||||
|
imillisleep( SSDP_PAUSE );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( gSsdpReqSocket4 != INVALID_SOCKET &&
|
||||||
|
FD_ISSET( gSsdpReqSocket4, &wrSet ) ) {
|
||||||
|
int NumCopy = 0;
|
||||||
|
while( NumCopy < NUM_SSDP_COPY ) {
|
||||||
|
sendto( gSsdpReqSocket4, ReqBufv4, strlen( ReqBufv4 ), 0,
|
||||||
|
(struct sockaddr *)&__ss_v4, socklen );
|
||||||
NumCopy++;
|
NumCopy++;
|
||||||
imillisleep( SSDP_PAUSE );
|
imillisleep( SSDP_PAUSE );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free( ReqBuf );
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EXCLUDE_SSDP
|
#endif // EXCLUDE_SSDP
|
||||||
#endif // INCLUDE_CLIENT_APIS
|
#endif // INCLUDE_CLIENT_APIS
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
|
|
||||||
AdvertiseAndReply( 0, arg->handle,
|
AdvertiseAndReply( 0, arg->handle,
|
||||||
arg->event.RequestType,
|
arg->event.RequestType,
|
||||||
&arg->dest_addr,
|
(struct sockaddr*)&arg->dest_addr,
|
||||||
arg->event.DeviceType,
|
arg->event.DeviceType,
|
||||||
arg->event.UDN,
|
arg->event.UDN,
|
||||||
arg->event.ServiceType, arg->MaxAge );
|
arg->event.ServiceType, arg->MaxAge );
|
||||||
@ -91,7 +91,7 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN http_message_t *hmsg: SSDP search request from the control point
|
* IN http_message_t *hmsg: SSDP search request from the control point
|
||||||
* IN struct sockaddr_in* dest_addr: The address info of control point
|
* IN struct sockaddr *dest_addr: The address info of control point
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function handles the search request. It do the sanity checks of
|
* This function handles the search request. It do the sanity checks of
|
||||||
@ -104,7 +104,7 @@ advertiseAndReplyThread( IN void *data )
|
|||||||
#ifdef INCLUDE_DEVICE_APIS
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
void
|
void
|
||||||
ssdp_handle_device_request( IN http_message_t *hmsg,
|
ssdp_handle_device_request( IN http_message_t *hmsg,
|
||||||
IN struct sockaddr_in *dest_addr )
|
IN struct sockaddr *dest_addr )
|
||||||
{
|
{
|
||||||
#define MX_FUDGE_FACTOR 10
|
#define MX_FUDGE_FACTOR 10
|
||||||
|
|
||||||
@ -144,7 +144,8 @@ ssdp_handle_device_request( IN http_message_t *hmsg,
|
|||||||
|
|
||||||
HandleLock();
|
HandleLock();
|
||||||
// device info
|
// device info
|
||||||
if( GetDeviceHandleInfo( &handle, &dev_info ) != HND_DEVICE ) {
|
if( GetDeviceHandleInfo( dest_addr->sa_family,
|
||||||
|
&handle, &dev_info ) != HND_DEVICE ) {
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
return; // no info found
|
return; // no info found
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ ssdp_handle_device_request( IN http_message_t *hmsg,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
threadArg->handle = handle;
|
threadArg->handle = handle;
|
||||||
threadArg->dest_addr = ( *dest_addr );
|
memcpy( &threadArg->dest_addr, dest_addr, sizeof(threadArg->dest_addr) );
|
||||||
threadArg->event = event;
|
threadArg->event = event;
|
||||||
threadArg->MaxAge = maxAge;
|
threadArg->MaxAge = maxAge;
|
||||||
|
|
||||||
@ -203,7 +204,7 @@ ssdp_handle_device_request( IN http_message_t *hmsg,
|
|||||||
* Function : NewRequestHandler
|
* Function : NewRequestHandler
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr: Ip address, to send the reply.
|
* IN struct sockaddr *DestAddr: Ip address, to send the reply.
|
||||||
* IN int NumPacket: Number of packet to be sent.
|
* IN int NumPacket: Number of packet to be sent.
|
||||||
* IN char **RqPacket:Number of packet to be sent.
|
* IN char **RqPacket:Number of packet to be sent.
|
||||||
*
|
*
|
||||||
@ -215,19 +216,21 @@ ssdp_handle_device_request( IN http_message_t *hmsg,
|
|||||||
* 1 if successful else appropriate error
|
* 1 if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
static int
|
static int
|
||||||
NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
NewRequestHandler( IN struct sockaddr *DestAddr,
|
||||||
IN int NumPacket,
|
IN int NumPacket,
|
||||||
IN char **RqPacket )
|
IN char **RqPacket )
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int ReplySock;
|
SOCKET ReplySock;
|
||||||
int socklen = sizeof( struct sockaddr_in );
|
int socklen = sizeof( struct sockaddr_storage );
|
||||||
int NumCopy;
|
int NumCopy;
|
||||||
int Index;
|
int Index;
|
||||||
unsigned long replyAddr = inet_addr( LOCAL_HOST );
|
unsigned long replyAddr = inet_addr( gIF_IPV4 );
|
||||||
int ttl = 4; // a/c to UPNP Spec
|
int ttl = 4; // a/c to UPNP Spec
|
||||||
|
int hops = 1;
|
||||||
|
char buf_ntop[64];
|
||||||
|
|
||||||
ReplySock = socket( AF_INET, SOCK_DGRAM, 0 );
|
ReplySock = socket( DestAddr->sa_family, SOCK_DGRAM, 0 );
|
||||||
if ( ReplySock == -1 ) {
|
if ( ReplySock == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
@ -237,10 +240,24 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
|
if( DestAddr->sa_family == AF_INET ) {
|
||||||
(char *)&replyAddr, sizeof (replyAddr) );
|
inet_ntop(AF_INET, &((struct sockaddr_in*)DestAddr)->sin_addr,
|
||||||
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
|
buf_ntop, sizeof(buf_ntop));
|
||||||
(char *)&ttl, sizeof (int) );
|
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
|
(char *)&replyAddr, sizeof (replyAddr) );
|
||||||
|
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||||
|
(char *)&ttl, sizeof (int) );
|
||||||
|
} else if( DestAddr->sa_family == AF_INET6 ) {
|
||||||
|
inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr,
|
||||||
|
buf_ntop, sizeof(buf_ntop));
|
||||||
|
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
|
(char *)&gIF_INDEX, sizeof(gIF_INDEX) );
|
||||||
|
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
|
||||||
|
(char *)&hops, sizeof(hops) );
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid destination address specified." );
|
||||||
|
}
|
||||||
|
|
||||||
for( Index = 0; Index < NumPacket; Index++ ) {
|
for( Index = 0; Index < NumPacket; Index++ ) {
|
||||||
int rc;
|
int rc;
|
||||||
@ -258,11 +275,11 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
NumCopy = 0;
|
NumCopy = 0;
|
||||||
while( NumCopy < NUM_COPY ) {
|
while( NumCopy < NUM_COPY ) {
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
">>> SSDP SEND >>>\n%s\n",
|
">>> SSDP SEND to %s >>>\n%s\n",
|
||||||
*( RqPacket + Index ) );
|
buf_ntop, *( RqPacket + Index ) );
|
||||||
rc = sendto( ReplySock, *( RqPacket + Index ),
|
rc = sendto( ReplySock, *( RqPacket + Index ),
|
||||||
strlen( *( RqPacket + Index ) ),
|
strlen( *( RqPacket + Index ) ),
|
||||||
0, ( struct sockaddr * )DestAddr, socklen );
|
0, DestAddr, socklen );
|
||||||
imillisleep( SSDP_PAUSE );
|
imillisleep( SSDP_PAUSE );
|
||||||
++NumCopy;
|
++NumCopy;
|
||||||
}
|
}
|
||||||
@ -285,6 +302,7 @@ NewRequestHandler( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char * location :Location URL.
|
* IN char * location :Location URL.
|
||||||
* IN int duration :Service duration in sec.
|
* IN int duration :Service duration in sec.
|
||||||
* OUT char** packet :Output buffer filled with HTTP statement.
|
* OUT char** packet :Output buffer filled with HTTP statement.
|
||||||
|
* IN int AddressFamily: Address family of the HTTP request.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP request packet. Depending
|
* This function creates a HTTP request packet. Depending
|
||||||
@ -300,7 +318,8 @@ CreateServicePacket( IN int msg_type,
|
|||||||
IN char *usn,
|
IN char *usn,
|
||||||
IN char *location,
|
IN char *location,
|
||||||
IN int duration,
|
IN int duration,
|
||||||
OUT char **packet )
|
OUT char **packet,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
int ret_code;
|
int ret_code;
|
||||||
char *nts;
|
char *nts;
|
||||||
@ -317,11 +336,13 @@ CreateServicePacket( IN int msg_type,
|
|||||||
if( msg_type == MSGTYPE_REPLY ) {
|
if( msg_type == MSGTYPE_REPLY ) {
|
||||||
ret_code = http_MakeMessage(
|
ret_code = http_MakeMessage(
|
||||||
&buf, 1, 1,
|
&buf, 1, 1,
|
||||||
"R" "sdc" "D" "sc" "ssc" "S" "Xc" "ssc" "sscc",
|
"R" "sdc" "D" "sc" "ssc" "ssc" "ssc" "S" "Xc" "ssc" "sscc",
|
||||||
HTTP_OK,
|
HTTP_OK,
|
||||||
"CACHE-CONTROL: max-age=", duration,
|
"CACHE-CONTROL: max-age=", duration,
|
||||||
"EXT:",
|
"EXT:",
|
||||||
"LOCATION: ", location,
|
"LOCATION: ", location,
|
||||||
|
"OPT: ", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
|
||||||
|
"01-NLS: ", gUpnpSdkNLSuuid,
|
||||||
X_USER_AGENT,
|
X_USER_AGENT,
|
||||||
"ST: ", nt,
|
"ST: ", nt,
|
||||||
"USN: ", usn);
|
"USN: ", usn);
|
||||||
@ -342,11 +363,15 @@ CreateServicePacket( IN int msg_type,
|
|||||||
|
|
||||||
ret_code = http_MakeMessage(
|
ret_code = http_MakeMessage(
|
||||||
&buf, 1, 1,
|
&buf, 1, 1,
|
||||||
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
|
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
|
||||||
HTTPMETHOD_NOTIFY, "*", (size_t)1,
|
HTTPMETHOD_NOTIFY, "*", (size_t)1,
|
||||||
"HOST: ", SSDP_IP, ":", SSDP_PORT,
|
"HOST: ",
|
||||||
|
(AddressFamily==AF_INET) ? SSDP_IP : "[" SSDP_IPV6_LINKLOCAL "]",
|
||||||
|
":", SSDP_PORT,
|
||||||
"CACHE-CONTROL: max-age=", duration,
|
"CACHE-CONTROL: max-age=", duration,
|
||||||
"LOCATION: ", location,
|
"LOCATION: ", location,
|
||||||
|
"OPT: ", "\"http://schemas.upnp.org/upnp/1/0/\"; ns=01",
|
||||||
|
"01-NLS: ", gUpnpSdkNLSuuid,
|
||||||
"NT: ", nt,
|
"NT: ", nt,
|
||||||
"NTS: ", nts,
|
"NTS: ", nts,
|
||||||
X_USER_AGENT,
|
X_USER_AGENT,
|
||||||
@ -389,9 +414,12 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
int RootDev,
|
int RootDev,
|
||||||
char *Udn,
|
char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration )
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
|
|
||||||
//char Mil_Nt[LINE_SIZE]
|
//char Mil_Nt[LINE_SIZE]
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
@ -401,9 +429,20 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"In function DeviceAdvertisement\n" );
|
"In function DeviceAdvertisement\n" );
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
msgs[0] = NULL;
|
msgs[0] = NULL;
|
||||||
msgs[1] = NULL;
|
msgs[1] = NULL;
|
||||||
@ -414,17 +453,17 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
|
||||||
}
|
}
|
||||||
// both root and sub-devices need to send these two messages
|
// both root and sub-devices need to send these two messages
|
||||||
//
|
//
|
||||||
|
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, Udn, Udn,
|
||||||
Location, Duration, &msgs[1] );
|
Location, Duration, &msgs[1], AddressFamily );
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[2] );
|
Location, Duration, &msgs[2], AddressFamily );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
if( ( RootDev && msgs[0] == NULL ) ||
|
if( ( RootDev && msgs[0] == NULL ) ||
|
||||||
@ -437,11 +476,11 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
// send packets
|
// send packets
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
// send 3 msg types
|
// send 3 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
|
||||||
} else // sub-device
|
} else // sub-device
|
||||||
{
|
{
|
||||||
// send 2 msg types
|
// send 2 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free msgs
|
// free msgs
|
||||||
@ -456,7 +495,7 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
* Function : SendReply
|
* Function : SendReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr * DestAddr:destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -472,7 +511,7 @@ DeviceAdvertisement( IN char *DevType,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
SendReply( IN struct sockaddr_in *DestAddr,
|
SendReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
@ -495,7 +534,7 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
|
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_REPLY, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], DestAddr->sa_family );
|
||||||
} else {
|
} else {
|
||||||
// two msgs for embedded devices
|
// two msgs for embedded devices
|
||||||
num_msgs = 1;
|
num_msgs = 1;
|
||||||
@ -503,11 +542,11 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
//NK: FIX for extra response when someone searches by udn
|
//NK: FIX for extra response when someone searches by udn
|
||||||
if( !ByType ) {
|
if( !ByType ) {
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
|
CreateServicePacket( MSGTYPE_REPLY, Udn, Udn, Location,
|
||||||
Duration, &msgs[0] );
|
Duration, &msgs[0], DestAddr->sa_family );
|
||||||
} else {
|
} else {
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[0] );
|
Location, Duration, &msgs[0], DestAddr->sa_family );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -533,7 +572,7 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* Function : DeviceReply
|
* Function : DeviceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in * DestAddr:destination IP address.
|
* IN struct sockaddr *DestAddr:destination IP address.
|
||||||
* IN char *DevType: Device type
|
* IN char *DevType: Device type
|
||||||
* IN int RootDev: 1 means root device 0 means embedded device.
|
* IN int RootDev: 1 means root device 0 means embedded device.
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
@ -547,7 +586,7 @@ SendReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
DeviceReply( IN struct sockaddr_in *DestAddr,
|
DeviceReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *DevType,
|
IN char *DevType,
|
||||||
IN int RootDev,
|
IN int RootDev,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
@ -570,18 +609,18 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
strcpy( Mil_Nt, "upnp:rootdevice" );
|
strcpy( Mil_Nt, "upnp:rootdevice" );
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], DestAddr->sa_family );
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf( Mil_Nt, "%s", Udn );
|
sprintf( Mil_Nt, "%s", Udn );
|
||||||
sprintf( Mil_Usn, "%s", Udn );
|
sprintf( Mil_Usn, "%s", Udn );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[1] );
|
Location, Duration, &szReq[1], DestAddr->sa_family );
|
||||||
|
|
||||||
sprintf( Mil_Nt, "%s", DevType );
|
sprintf( Mil_Nt, "%s", DevType );
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, Mil_Nt, Mil_Usn,
|
||||||
Location, Duration, &szReq[2] );
|
Location, Duration, &szReq[2], DestAddr->sa_family );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
|
|
||||||
@ -615,6 +654,7 @@ DeviceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Life time of this device.
|
* IN int Duration :Life time of this device.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the advertisement packet based
|
* This function creates the advertisement packet based
|
||||||
* on the input parameter, and send it to the multicast channel.
|
* on the input parameter, and send it to the multicast channel.
|
||||||
@ -626,28 +666,42 @@ int
|
|||||||
ServiceAdvertisement( IN char *Udn,
|
ServiceAdvertisement( IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration)
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
char *szReq[1];
|
char *szReq[1];
|
||||||
struct sockaddr_in DestAddr;
|
|
||||||
int RetVal;
|
int RetVal;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
|
|
||||||
//CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
|
//CreateServiceRequestPacket(1,szReq[0],Mil_Nt,Mil_Usn,
|
||||||
//Server,Location,Duration);
|
//Server,Location,Duration);
|
||||||
CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_ADVERTISEMENT, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], AddressFamily );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
RetVal = NewRequestHandler( &DestAddr, 1, szReq );
|
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
|
||||||
|
|
||||||
free( szReq[0] );
|
free( szReq[0] );
|
||||||
return RetVal;
|
return RetVal;
|
||||||
@ -657,7 +711,7 @@ ServiceAdvertisement( IN char *Udn,
|
|||||||
* Function : ServiceReply
|
* Function : ServiceReply
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN struct sockaddr_in *DestAddr:
|
* IN struct sockaddr *DestAddr:
|
||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
@ -670,7 +724,7 @@ ServiceAdvertisement( IN char *Udn,
|
|||||||
* UPNP_E_SUCCESS if successful else appropriate error
|
* UPNP_E_SUCCESS if successful else appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
ServiceReply( IN struct sockaddr_in *DestAddr,
|
ServiceReply( IN struct sockaddr *DestAddr,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
@ -685,7 +739,7 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
|
|
||||||
CreateServicePacket( MSGTYPE_REPLY, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_REPLY, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], DestAddr->sa_family );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
@ -704,6 +758,7 @@ ServiceReply( IN struct sockaddr_in *DestAddr,
|
|||||||
* IN char *ServType: Service Type.
|
* IN char *ServType: Service Type.
|
||||||
* IN char * Location: Location of Device description document.
|
* IN char * Location: Location of Device description document.
|
||||||
* IN int Duration :Service duration in sec.
|
* IN int Duration :Service duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP service shutdown request packet
|
* This function creates a HTTP service shutdown request packet
|
||||||
* and sent it to the multicast channel through RequestHandler.
|
* and sent it to the multicast channel through RequestHandler.
|
||||||
@ -715,27 +770,41 @@ int
|
|||||||
ServiceShutdown( IN char *Udn,
|
ServiceShutdown( IN char *Udn,
|
||||||
IN char *ServType,
|
IN char *ServType,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration)
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
char *szReq[1];
|
char *szReq[1];
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
int RetVal;
|
int RetVal;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
//sprintf(Mil_Nt,"%s",ServType);
|
//sprintf(Mil_Nt,"%s",ServType);
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
sprintf( Mil_Usn, "%s::%s", Udn, ServType );
|
||||||
//CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
|
//CreateServiceRequestPacket(0,szReq[0],Mil_Nt,Mil_Usn,
|
||||||
//Server,Location,Duration);
|
//Server,Location,Duration);
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, ServType, Mil_Usn,
|
||||||
Location, Duration, &szReq[0] );
|
Location, Duration, &szReq[0], AddressFamily );
|
||||||
if( szReq[0] == NULL ) {
|
if( szReq[0] == NULL ) {
|
||||||
return UPNP_E_OUTOF_MEMORY;
|
return UPNP_E_OUTOF_MEMORY;
|
||||||
}
|
}
|
||||||
RetVal = NewRequestHandler( &DestAddr, 1, szReq );
|
RetVal = NewRequestHandler( (struct sockaddr*)&__ss, 1, szReq );
|
||||||
|
|
||||||
free( szReq[0] );
|
free( szReq[0] );
|
||||||
return RetVal;
|
return RetVal;
|
||||||
@ -750,6 +819,7 @@ ServiceShutdown( IN char *Udn,
|
|||||||
* IN char * Udn: Device UDN
|
* IN char * Udn: Device UDN
|
||||||
* IN char * Location: Location URL
|
* IN char * Location: Location URL
|
||||||
* IN int Duration :Device duration in sec.
|
* IN int Duration :Device duration in sec.
|
||||||
|
* IN int AddressFamily: Device address family.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates a HTTP device shutdown request packet
|
* This function creates a HTTP device shutdown request packet
|
||||||
@ -764,9 +834,12 @@ DeviceShutdown( IN char *DevType,
|
|||||||
IN char *Udn,
|
IN char *Udn,
|
||||||
IN char *_Server,
|
IN char *_Server,
|
||||||
IN char *Location,
|
IN char *Location,
|
||||||
IN int Duration)
|
IN int Duration,
|
||||||
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
struct sockaddr_in DestAddr;
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in* DestAddr4 = (struct sockaddr_in*)&__ss;
|
||||||
|
struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&__ss;
|
||||||
char *msgs[3];
|
char *msgs[3];
|
||||||
char Mil_Usn[LINE_SIZE];
|
char Mil_Usn[LINE_SIZE];
|
||||||
int ret_code;
|
int ret_code;
|
||||||
@ -775,26 +848,37 @@ DeviceShutdown( IN char *DevType,
|
|||||||
msgs[1] = NULL;
|
msgs[1] = NULL;
|
||||||
msgs[2] = NULL;
|
msgs[2] = NULL;
|
||||||
|
|
||||||
DestAddr.sin_family = AF_INET;
|
memset( &__ss, 0, sizeof(__ss) );
|
||||||
DestAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
|
if( AddressFamily == AF_INET ) {
|
||||||
DestAddr.sin_port = htons( SSDP_PORT );
|
DestAddr4->sin_family = AF_INET;
|
||||||
|
inet_pton( AF_INET, SSDP_IP, &DestAddr4->sin_addr );
|
||||||
|
DestAddr4->sin_port = htons( SSDP_PORT );
|
||||||
|
} else if( AddressFamily == AF_INET6 ) {
|
||||||
|
DestAddr6->sin6_family = AF_INET6;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &DestAddr6->sin6_addr );
|
||||||
|
DestAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
DestAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
} else {
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid device address family.\n" );
|
||||||
|
}
|
||||||
|
|
||||||
// root device has one extra msg
|
// root device has one extra msg
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
sprintf( Mil_Usn, "%s::upnp:rootdevice", Udn );
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
|
CreateServicePacket( MSGTYPE_SHUTDOWN, "upnp:rootdevice",
|
||||||
Mil_Usn, Location, Duration, &msgs[0] );
|
Mil_Usn, Location, Duration, &msgs[0], AddressFamily );
|
||||||
}
|
}
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
"In function DeviceShutdown\n" );
|
"In function DeviceShutdown\n" );
|
||||||
// both root and sub-devices need to send these two messages
|
// both root and sub-devices need to send these two messages
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, Udn, Udn,
|
||||||
Location, Duration, &msgs[1] );
|
Location, Duration, &msgs[1], AddressFamily );
|
||||||
|
|
||||||
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
sprintf( Mil_Usn, "%s::%s", Udn, DevType );
|
||||||
CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
|
CreateServicePacket( MSGTYPE_SHUTDOWN, DevType, Mil_Usn,
|
||||||
Location, Duration, &msgs[2] );
|
Location, Duration, &msgs[2], AddressFamily );
|
||||||
|
|
||||||
// check error
|
// check error
|
||||||
if( ( RootDev && msgs[0] == NULL ) ||
|
if( ( RootDev && msgs[0] == NULL ) ||
|
||||||
@ -807,11 +891,11 @@ DeviceShutdown( IN char *DevType,
|
|||||||
// send packets
|
// send packets
|
||||||
if( RootDev ) {
|
if( RootDev ) {
|
||||||
// send 3 msg types
|
// send 3 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 3, &msgs[0] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 3, &msgs[0] );
|
||||||
} else // sub-device
|
} else // sub-device
|
||||||
{
|
{
|
||||||
// send 2 msg types
|
// send 2 msg types
|
||||||
ret_code = NewRequestHandler( &DestAddr, 2, &msgs[1] );
|
ret_code = NewRequestHandler( (struct sockaddr*)&__ss, 2, &msgs[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free msgs
|
// free msgs
|
||||||
|
@ -50,18 +50,23 @@
|
|||||||
|
|
||||||
#define MAX_TIME_TOREAD 45
|
#define MAX_TIME_TOREAD 45
|
||||||
|
|
||||||
CLIENTONLY( SOCKET gSsdpReqSocket = 0; )
|
CLIENTONLY( SOCKET gSsdpReqSocket4 = INVALID_SOCKET; )
|
||||||
|
CLIENTONLY( SOCKET gSsdpReqSocket6 = INVALID_SOCKET; )
|
||||||
|
|
||||||
void RequestHandler();
|
void RequestHandler();
|
||||||
|
int create_ssdp_sock_v4( SOCKET* ssdpSock );
|
||||||
|
int create_ssdp_sock_v6( SOCKET* ssdpSock );
|
||||||
|
#if INCLUDE_CLIENT_APIS
|
||||||
|
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock );
|
||||||
|
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock );
|
||||||
|
#endif
|
||||||
Event ErrotEvt;
|
Event ErrotEvt;
|
||||||
|
|
||||||
enum Listener { Idle, Stopping, Running };
|
enum Listener { Idle, Stopping, Running };
|
||||||
|
|
||||||
unsigned short ssdpStopPort;
|
|
||||||
|
|
||||||
struct SSDPSockArray {
|
struct SSDPSockArray {
|
||||||
// socket for incoming advertisments and search requests
|
// socket for incoming advertisments and search requests
|
||||||
int ssdpSock;
|
SOCKET ssdpSock;
|
||||||
// socket for sending search requests and receiving search replies
|
// socket for sending search requests and receiving search replies
|
||||||
CLIENTONLY( int ssdpReqSock; )
|
CLIENTONLY( int ssdpReqSock; )
|
||||||
};
|
};
|
||||||
@ -79,10 +84,10 @@ struct SSDPSockArray {
|
|||||||
* 1 = Send Advertisement
|
* 1 = Send Advertisement
|
||||||
* IN UpnpDevice_Handle Hnd: Device handle
|
* IN UpnpDevice_Handle Hnd: Device handle
|
||||||
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
* IN enum SsdpSearchType SearchType:Search type for sending replies
|
||||||
* IN struct sockaddr_in *DestAddr:Destination address
|
* IN struct sockaddr *DestAddr:Destination address
|
||||||
* IN char *DeviceType:Device type
|
* IN char *DeviceType:Device type
|
||||||
* IN char *DeviceUDN:Device UDN
|
* IN char *DeviceUDN:Device UDN
|
||||||
* IN char *ServiceType:Service type
|
* IN char *ServiceType:Service type
|
||||||
* IN int Exp:Advertisement age
|
* IN int Exp:Advertisement age
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@ -95,7 +100,7 @@ int AdvertiseAndReply(
|
|||||||
IN int AdFlag,
|
IN int AdFlag,
|
||||||
IN UpnpDevice_Handle Hnd,
|
IN UpnpDevice_Handle Hnd,
|
||||||
IN enum SsdpSearchType SearchType,
|
IN enum SsdpSearchType SearchType,
|
||||||
IN struct sockaddr_in *DestAddr,
|
IN struct sockaddr *DestAddr,
|
||||||
IN char *DeviceType,
|
IN char *DeviceType,
|
||||||
IN char *DeviceUDN,
|
IN char *DeviceUDN,
|
||||||
IN char *ServiceType,
|
IN char *ServiceType,
|
||||||
@ -213,11 +218,11 @@ int AdvertiseAndReply(
|
|||||||
/* send the device advertisement */
|
/* send the device advertisement */
|
||||||
if (AdFlag == 1) {
|
if (AdFlag == 1) {
|
||||||
DeviceAdvertisement(devType, i == 0,
|
DeviceAdvertisement(devType, i == 0,
|
||||||
UDNstr, SInfo->DescURL, Exp);
|
UDNstr, SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
} else {
|
} else {
|
||||||
/* AdFlag == -1 */
|
/* AdFlag == -1 */
|
||||||
DeviceShutdown(devType, i == 0, UDNstr,
|
DeviceShutdown(devType, i == 0, UDNstr,
|
||||||
SERVER, SInfo->DescURL, Exp);
|
SERVER, SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (SearchType) {
|
switch (SearchType) {
|
||||||
@ -311,11 +316,11 @@ int AdvertiseAndReply(
|
|||||||
if (AdFlag) {
|
if (AdFlag) {
|
||||||
if (AdFlag == 1) {
|
if (AdFlag == 1) {
|
||||||
ServiceAdvertisement(UDNstr, servType,
|
ServiceAdvertisement(UDNstr, servType,
|
||||||
SInfo->DescURL, Exp);
|
SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
} else {
|
} else {
|
||||||
/* AdFlag == -1 */
|
/* AdFlag == -1 */
|
||||||
ServiceShutdown(UDNstr, servType,
|
ServiceShutdown(UDNstr, servType,
|
||||||
SInfo->DescURL, Exp);
|
SInfo->DescURL, Exp, SInfo->DeviceAf );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (SearchType) {
|
switch (SearchType) {
|
||||||
@ -362,7 +367,7 @@ end_function:
|
|||||||
* Function : Make_Socket_NoBlocking
|
* Function : Make_Socket_NoBlocking
|
||||||
*
|
*
|
||||||
* Parameters:
|
* Parameters:
|
||||||
* IN int sock: socket
|
* IN SOCKET sock: socket
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function makes socket non-blocking.
|
* This function makes socket non-blocking.
|
||||||
@ -371,7 +376,7 @@ end_function:
|
|||||||
* 0 if successful else -1
|
* 0 if successful else -1
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int
|
||||||
Make_Socket_NoBlocking( int sock )
|
Make_Socket_NoBlocking( SOCKET sock )
|
||||||
{
|
{
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
u_long val=1;
|
u_long val=1;
|
||||||
@ -614,8 +619,11 @@ valid_ssdp_msg( IN http_message_t * hmsg )
|
|||||||
}
|
}
|
||||||
// check HOST header
|
// check HOST header
|
||||||
if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||
|
if( ( httpmsg_find_hdr( hmsg, HDR_HOST, &hdr_value ) == NULL ) ||
|
||||||
( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 )
|
( ( memptr_cmp( &hdr_value, "239.255.255.250:1900" ) != 0 ) &&
|
||||||
|
( memptr_cmp( &hdr_value, "[FF02::C]:1900" ) != 0 ) )
|
||||||
) {
|
) {
|
||||||
|
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
|
"Invalid HOST header from SSDP message\n" );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -664,7 +672,7 @@ start_event_handler( void *Data )
|
|||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
// check msg
|
// check msg
|
||||||
if( !valid_ssdp_msg( &parser->msg ) ) {
|
if( valid_ssdp_msg( &parser->msg ) != TRUE ) {
|
||||||
goto error_handler;
|
goto error_handler;
|
||||||
}
|
}
|
||||||
return 0; //////// done; thread will free 'data'
|
return 0; //////// done; thread will free 'data'
|
||||||
@ -699,9 +707,10 @@ ssdp_event_handler_thread( void *the_data )
|
|||||||
// send msg to device or ctrlpt
|
// send msg to device or ctrlpt
|
||||||
if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
|
if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||
|
||||||
( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
|
( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {
|
||||||
CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg, &data->dest_addr, FALSE, NULL );)
|
CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg,
|
||||||
|
(struct sockaddr*)&data->dest_addr, FALSE, NULL );)
|
||||||
} else {
|
} else {
|
||||||
ssdp_handle_device_request( hmsg, &data->dest_addr );
|
ssdp_handle_device_request( hmsg, (struct sockaddr*)&data->dest_addr );
|
||||||
}
|
}
|
||||||
|
|
||||||
// free data
|
// free data
|
||||||
@ -725,11 +734,12 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
{
|
{
|
||||||
char *requestBuf = NULL;
|
char *requestBuf = NULL;
|
||||||
char staticBuf[BUFSIZE];
|
char staticBuf[BUFSIZE];
|
||||||
struct sockaddr_in clientAddr;
|
struct sockaddr_storage __ss;
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
ssdp_thread_data *data = NULL;
|
ssdp_thread_data *data = NULL;
|
||||||
socklen_t socklen = 0;
|
socklen_t socklen = sizeof( __ss );
|
||||||
int byteReceived = 0;
|
int byteReceived = 0;
|
||||||
|
char ntop_buf[64];
|
||||||
|
|
||||||
requestBuf = staticBuf;
|
requestBuf = staticBuf;
|
||||||
|
|
||||||
@ -737,8 +747,6 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
//can't be allocated, still drain the
|
//can't be allocated, still drain the
|
||||||
//socket using a static buffer
|
//socket using a static buffer
|
||||||
|
|
||||||
socklen = sizeof( struct sockaddr_in );
|
|
||||||
|
|
||||||
data = ( ssdp_thread_data * )
|
data = ( ssdp_thread_data * )
|
||||||
malloc( sizeof( ssdp_thread_data ) );
|
malloc( sizeof( ssdp_thread_data ) );
|
||||||
|
|
||||||
@ -746,7 +754,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
//initialize parser
|
//initialize parser
|
||||||
|
|
||||||
#ifdef INCLUDE_CLIENT_APIS
|
#ifdef INCLUDE_CLIENT_APIS
|
||||||
if( socket == gSsdpReqSocket ) {
|
if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) {
|
||||||
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
|
parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );
|
||||||
} else {
|
} else {
|
||||||
parser_request_init( &data->parser );
|
parser_request_init( &data->parser );
|
||||||
@ -768,10 +776,18 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
}
|
}
|
||||||
byteReceived = recvfrom( socket, requestBuf,
|
byteReceived = recvfrom( socket, requestBuf,
|
||||||
BUFSIZE - 1, 0,
|
BUFSIZE - 1, 0,
|
||||||
( struct sockaddr * )&clientAddr, &socklen );
|
(struct sockaddr *)&__ss, &socklen );
|
||||||
|
|
||||||
if( byteReceived > 0 ) {
|
if( byteReceived > 0 ) {
|
||||||
requestBuf[byteReceived] = '\0';
|
requestBuf[byteReceived] = '\0';
|
||||||
|
|
||||||
|
if( __ss.ss_family == AF_INET )
|
||||||
|
inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) );
|
||||||
|
else if( __ss.ss_family == AF_INET6 )
|
||||||
|
inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) );
|
||||||
|
else
|
||||||
|
strncpy( ntop_buf, "<Invalid address family>", sizeof(ntop_buf) );
|
||||||
|
|
||||||
UpnpPrintf( UPNP_INFO, SSDP,
|
UpnpPrintf( UPNP_INFO, SSDP,
|
||||||
__FILE__, __LINE__,
|
__FILE__, __LINE__,
|
||||||
"Start of received response ----------------------------------------------------\n"
|
"Start of received response ----------------------------------------------------\n"
|
||||||
@ -779,7 +795,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
"End of received response ------------------------------------------------------\n"
|
"End of received response ------------------------------------------------------\n"
|
||||||
"From host %s\n",
|
"From host %s\n",
|
||||||
requestBuf,
|
requestBuf,
|
||||||
inet_ntoa( clientAddr.sin_addr ) );
|
ntop_buf );
|
||||||
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
|
||||||
"Start of received multicast packet --------------------------------------------\n"
|
"Start of received multicast packet --------------------------------------------\n"
|
||||||
"%s\n"
|
"%s\n"
|
||||||
@ -790,7 +806,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
data->parser.msg.msg.length += byteReceived;
|
data->parser.msg.msg.length += byteReceived;
|
||||||
// null-terminate
|
// null-terminate
|
||||||
data->parser.msg.msg.buf[byteReceived] = 0;
|
data->parser.msg.msg.buf[byteReceived] = 0;
|
||||||
data->dest_addr = clientAddr;
|
memcpy( &data->dest_addr, &__ss, sizeof(__ss) );
|
||||||
TPJobInit( &job, ( start_routine )
|
TPJobInit( &job, ( start_routine )
|
||||||
ssdp_event_handler_thread, data );
|
ssdp_event_handler_thread, data );
|
||||||
TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
|
TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );
|
||||||
@ -805,6 +821,7 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Function : get_ssdp_sockets
|
* Function : get_ssdp_sockets
|
||||||
*
|
*
|
||||||
@ -812,125 +829,252 @@ readFromSSDPSocket( SOCKET socket )
|
|||||||
* OUT MiniServerSockArray *out: Array of SSDP sockets
|
* OUT MiniServerSockArray *out: Array of SSDP sockets
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This function creates the ssdp sockets. It set their option to listen
|
* This function creates the IPv4 and IPv6 ssdp sockets required by the
|
||||||
* for multicast traffic.
|
* control point and device operation.
|
||||||
*
|
*
|
||||||
* Returns: int
|
* Returns: int
|
||||||
* return UPNP_E_SUCCESS if successful else returns appropriate error
|
* return UPNP_E_SUCCESS if successful else returns appropriate error
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
int
|
int get_ssdp_sockets( MiniServerSockArray * out )
|
||||||
get_ssdp_sockets( MiniServerSockArray * out )
|
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
int retVal;
|
||||||
int onOff = 1;
|
|
||||||
u_char ttl = 4;
|
|
||||||
struct ip_mreq ssdpMcastAddr;
|
|
||||||
struct sockaddr_in ssdpAddr;
|
|
||||||
int option = 1;
|
|
||||||
int ret = 0;
|
|
||||||
struct in_addr addr;
|
|
||||||
SOCKET ssdpSock;
|
|
||||||
#if INCLUDE_CLIENT_APIS
|
#if INCLUDE_CLIENT_APIS
|
||||||
SOCKET ssdpReqSock;
|
// Create the IPv4 socket for SSDP REQUESTS
|
||||||
|
if( strlen( gIF_IPV4 ) > 0 ) {
|
||||||
ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
retVal = create_ssdp_sock_reqv4( &out->ssdpReqSock4 );
|
||||||
if ( ssdpReqSock == -1 ) {
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
return retVal;
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
}
|
||||||
"Error in socket(): %s\n", errorBuffer );
|
// For use by ssdp control point.
|
||||||
|
gSsdpReqSocket4 = out->ssdpReqSock4;
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
} else {
|
||||||
|
out->ssdpReqSock4 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the IPv6 socket for SSDP REQUESTS
|
||||||
|
if( strlen( gIF_IPV6 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_reqv6( &out->ssdpReqSock6 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
// For use by ssdp control point.
|
||||||
|
gSsdpReqSocket6 = out->ssdpReqSock6;
|
||||||
|
} else {
|
||||||
|
out->ssdpReqSock6 = INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
ret = setsockopt( ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
|
|
||||||
&ttl, sizeof (ttl) );
|
|
||||||
// just do it, regardless if fails or not.
|
|
||||||
Make_Socket_NoBlocking( ssdpReqSock );
|
|
||||||
gSsdpReqSocket = ssdpReqSock;
|
|
||||||
#endif /* INCLUDE_CLIENT_APIS */
|
#endif /* INCLUDE_CLIENT_APIS */
|
||||||
|
|
||||||
ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
// Create the IPv4 socket for SSDP
|
||||||
if ( ssdpSock == -1 ) {
|
if( strlen( gIF_IPV4 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_v4( &out->ssdpSock4 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock6, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock6 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out->ssdpSock4 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the IPv6 socket for SSDP
|
||||||
|
if( strlen( gIF_IPV6 ) > 0 ) {
|
||||||
|
retVal = create_ssdp_sock_v6( &out->ssdpSock6 );
|
||||||
|
if( retVal != UPNP_E_SUCCESS ) {
|
||||||
|
shutdown( out->ssdpSock4, SD_BOTH );
|
||||||
|
UpnpCloseSocket( out->ssdpSock4 );
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock4, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock4 ); )
|
||||||
|
CLIENTONLY( shutdown( out->ssdpReqSock6, SD_BOTH ); )
|
||||||
|
CLIENTONLY( UpnpCloseSocket( out->ssdpReqSock6 ); )
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out->ssdpSock6 = INVALID_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if INCLUDE_CLIENT_APIS
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_reqv4
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpReqSock: SSDP IPv4 request socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function creates the SSDP IPv4 socket to be used by the control
|
||||||
|
* point.
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* UPNP_E_SUCCESS on successful socket creation.
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
u_char ttl = 4;
|
||||||
|
|
||||||
|
*ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpReqSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
setsockopt( *ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
|
||||||
|
&ttl, sizeof (ttl) );
|
||||||
|
|
||||||
|
// just do it, regardless if fails or not.
|
||||||
|
Make_Socket_NoBlocking( *ssdpReqSock );
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_reqv6
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpReqSock: SSDP IPv6 request socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function creates the SSDP IPv6 socket to be used by the control
|
||||||
|
* point.
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_reqv6( SOCKET* ssdpReqSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
char hops = 1;
|
||||||
|
|
||||||
|
*ssdpReqSock = socket( AF_INET6, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpReqSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST use scoping of IPv6 addresses to control the propagation os SSDP
|
||||||
|
// messages instead of relying on the Hop Limit (Equivalent to the TTL
|
||||||
|
// limit in IPv4).
|
||||||
|
setsockopt( *ssdpReqSock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
|
||||||
|
&hops, sizeof(hops) );
|
||||||
|
|
||||||
|
// just do it, regardless if fails or not.
|
||||||
|
Make_Socket_NoBlocking( *ssdpReqSock );
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif /* INCLUDE_CLIENT_APIS */
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_v4
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpSock: SSDP IPv4 socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function ...
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_v4( SOCKET* ssdpSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
int onOff;
|
||||||
|
u_char ttl = 4;
|
||||||
|
struct ip_mreq ssdpMcastAddr;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in *ssdpAddr4 = (struct sockaddr_in *)&__ss;
|
||||||
|
int ret = 0;
|
||||||
|
struct in_addr addr;
|
||||||
|
|
||||||
|
|
||||||
|
*ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpSock == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in socket(): %s\n", errorBuffer );
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_OUTOF_SOCKET;
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
onOff = 1;
|
onOff = 1;
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
(char *)&onOff, sizeof(onOff) );
|
(char*)&onOff, sizeof(onOff) );
|
||||||
if ( ret == -1) {
|
if ( ret == -1) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(BSD) || defined(__OSX__) || defined(__APPLE__)
|
#if defined(BSD) || defined(__OSX__) || defined(__APPLE__)
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
onOff = 1;
|
||||||
(char *)&onOff, sizeof (onOff) );
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char *)&onOff, sizeof(onOff) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
#endif /* BSD */
|
#endif /* BSD */
|
||||||
|
|
||||||
memset( (void *)&ssdpAddr, 0, sizeof( struct sockaddr_in ) );
|
memset( &__ss, 0, sizeof( __ss ) );
|
||||||
ssdpAddr.sin_family = AF_INET;
|
ssdpAddr4->sin_family = AF_INET;
|
||||||
// ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);
|
ssdpAddr4->sin_addr.s_addr = htonl( INADDR_ANY );
|
||||||
ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );
|
ssdpAddr4->sin_port = htons( SSDP_PORT );
|
||||||
ssdpAddr.sin_port = htons( SSDP_PORT );
|
ret = bind( *ssdpSock, (struct sockaddr *)ssdpAddr4, sizeof(*ssdpAddr4) );
|
||||||
ret = bind( ssdpSock, (struct sockaddr *)&ssdpAddr, sizeof (ssdpAddr) );
|
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in bind(), addr=0x%08X, port=%d: %s\n",
|
"Error in bind(), addr=0x%08X, port=%d: %s\n",
|
||||||
INADDR_ANY, SSDP_PORT, errorBuffer );
|
INADDR_ANY, SSDP_PORT, errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
UpnpCloseSocket( ssdpSock );
|
UpnpCloseSocket( *ssdpSock );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_BIND;
|
return UPNP_E_SOCKET_BIND;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset( (void *)&ssdpMcastAddr, 0, sizeof (struct ip_mreq) );
|
memset( (void *)&ssdpMcastAddr, 0, sizeof (struct ip_mreq) );
|
||||||
ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );
|
ssdpMcastAddr.imr_interface.s_addr = inet_addr( gIF_IPV4 );
|
||||||
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
|
ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );
|
||||||
ret = setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
ret = setsockopt( *ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||||
(char *)&ssdpMcastAddr, sizeof (struct ip_mreq) );
|
(char *)&ssdpMcastAddr, sizeof(struct ip_mreq) );
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() IP_ADD_MEMBERSHIP (join multicast group): %s\n",
|
"Error in setsockopt() IP_ADD_MEMBERSHIP (join multicast group): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_SOCKET_ERROR;
|
return UPNP_E_SOCKET_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set multicast interface. */
|
/* Set multicast interface. */
|
||||||
memset( (void *)&addr, 0, sizeof (struct in_addr) );
|
memset( (void *)&addr, 0, sizeof (struct in_addr) );
|
||||||
addr.s_addr = inet_addr(LOCAL_HOST);
|
addr.s_addr = inet_addr(gIF_IPV4);
|
||||||
ret = setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
|
ret = setsockopt(*ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
(char *)&addr, sizeof addr);
|
(char *)&addr, sizeof addr);
|
||||||
if ( ret == -1 ) {
|
if ( ret == -1 ) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
@ -941,26 +1085,131 @@ get_ssdp_sockets( MiniServerSockArray * out )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* result is not checked becuase it will fail in WinMe and Win9x. */
|
/* result is not checked becuase it will fail in WinMe and Win9x. */
|
||||||
ret = setsockopt( ssdpSock, IPPROTO_IP,
|
ret = setsockopt( *ssdpSock, IPPROTO_IP,
|
||||||
IP_MULTICAST_TTL, &ttl, sizeof (ttl) );
|
IP_MULTICAST_TTL, &ttl, sizeof (ttl) );
|
||||||
|
|
||||||
ret = setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
onOff = 1;
|
||||||
(char *)&option, sizeof (option) );
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
if( ret == -1) {
|
if( ret == -1) {
|
||||||
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
||||||
errorBuffer );
|
errorBuffer );
|
||||||
shutdown( ssdpSock, SD_BOTH );
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )
|
UpnpCloseSocket( *ssdpSock );
|
||||||
UpnpCloseSocket( ssdpSock );
|
|
||||||
CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )
|
|
||||||
|
|
||||||
return UPNP_E_NETWORK_ERROR;
|
return UPNP_E_NETWORK_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLIENTONLY( out->ssdpReqSock = ssdpReqSock; )
|
return UPNP_E_SUCCESS;
|
||||||
out->ssdpSock = ssdpSock;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************
|
||||||
|
* Function : create_ssdp_sock_v6
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* IN SOCKET* ssdpSock: SSDP IPv6 socket to be created
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* This function ...
|
||||||
|
*
|
||||||
|
* Returns: void
|
||||||
|
*
|
||||||
|
***************************************************************************/
|
||||||
|
int create_ssdp_sock_v6( SOCKET* ssdpSock )
|
||||||
|
{
|
||||||
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
|
struct ipv6_mreq ssdpMcastAddr;
|
||||||
|
struct sockaddr_storage __ss;
|
||||||
|
struct sockaddr_in6 *ssdpAddr6 = (struct sockaddr_in6 *)&__ss;
|
||||||
|
int onOff;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
*ssdpSock = socket( AF_INET6, SOCK_DGRAM, 0 );
|
||||||
|
if ( *ssdpSock == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in socket(): %s\n", errorBuffer );
|
||||||
|
|
||||||
|
return UPNP_E_OUTOF_SOCKET;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEADDR,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
|
if ( ret == -1) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(BSD) || defined(__OSX__) || defined(__APPLE__)
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_REUSEPORT,
|
||||||
|
(char*)&onOff, sizeof (onOff) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
#endif /* BSD */
|
||||||
|
|
||||||
|
memset( &__ss, 0, sizeof( __ss ) );
|
||||||
|
ssdpAddr6->sin6_family = AF_INET6;
|
||||||
|
ssdpAddr6->sin6_addr = in6addr_any;
|
||||||
|
ssdpAddr6->sin6_scope_id = gIF_INDEX;
|
||||||
|
ssdpAddr6->sin6_port = htons( SSDP_PORT );
|
||||||
|
ret = bind( *ssdpSock, (struct sockaddr *)ssdpAddr6, sizeof(*ssdpAddr6) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in bind(), addr=0x%032lX, port=%d: %s\n",
|
||||||
|
0lu, SSDP_PORT, errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_BIND;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset( (void *)&ssdpMcastAddr, 0, sizeof(ssdpMcastAddr) );
|
||||||
|
ssdpMcastAddr.ipv6mr_interface = gIF_INDEX;
|
||||||
|
inet_pton( AF_INET6, SSDP_IPV6_LINKLOCAL, &ssdpMcastAddr.ipv6mr_multiaddr );
|
||||||
|
ret = setsockopt( *ssdpSock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
|
||||||
|
(char *)&ssdpMcastAddr, sizeof(ssdpMcastAddr) );
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() IPV6_JOIN_GROUP (join multicast group): %s\n",
|
||||||
|
errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_SOCKET_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
onOff = 1;
|
||||||
|
ret = setsockopt( *ssdpSock, SOL_SOCKET, SO_BROADCAST,
|
||||||
|
(char*)&onOff, sizeof(onOff) );
|
||||||
|
if( ret == -1) {
|
||||||
|
strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);
|
||||||
|
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
|
||||||
|
"Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",
|
||||||
|
errorBuffer );
|
||||||
|
shutdown( *ssdpSock, SD_BOTH );
|
||||||
|
UpnpCloseSocket( *ssdpSock );
|
||||||
|
|
||||||
|
return UPNP_E_NETWORK_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
return UPNP_E_SUCCESS;
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@
|
|||||||
* Function : addrToString
|
* Function : addrToString
|
||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* IN const struct sockaddr_in* addr ; socket address object with
|
* IN const struct sockaddr* addr ; socket address object with
|
||||||
* the IP Address and port information
|
* the IP Address and port information
|
||||||
* OUT char ipaddr_port[] ; character array which will hold the
|
* OUT char ipaddr_port[] ; character array which will hold the
|
||||||
* IP Address in a string format.
|
* IP Address in a string format.
|
||||||
@ -73,11 +73,20 @@
|
|||||||
* Note :
|
* Note :
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
static UPNP_INLINE void
|
static UPNP_INLINE void
|
||||||
addrToString( IN const struct sockaddr_in *addr,
|
addrToString( IN const struct sockaddr *addr,
|
||||||
OUT char ipaddr_port[] )
|
OUT char ipaddr_port[] )
|
||||||
{
|
{
|
||||||
sprintf( ipaddr_port, "%s:%d", inet_ntoa( addr->sin_addr ),
|
char buf_ntop[64];
|
||||||
ntohs( addr->sin_port ) );
|
|
||||||
|
if( addr->sa_family == AF_INET ) {
|
||||||
|
struct sockaddr_in* sa4 = (struct sockaddr_in*)addr;
|
||||||
|
inet_ntop(AF_INET, &sa4->sin_addr, buf_ntop, sizeof(buf_ntop) );
|
||||||
|
sprintf( ipaddr_port, "%s:%d", buf_ntop, ntohs( sa4->sin_port ) );
|
||||||
|
} else if( addr->sa_family == AF_INET6 ) {
|
||||||
|
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)addr;
|
||||||
|
inet_ntop(AF_INET6, &sa6->sin6_addr, buf_ntop, sizeof(buf_ntop) );
|
||||||
|
sprintf( ipaddr_port, "[%s]:%d", buf_ntop, ntohs( sa6->sin6_port ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
@ -353,7 +362,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
*
|
*
|
||||||
* Parameters :
|
* Parameters :
|
||||||
* INOUT IXML_Document *doc ; IXML Description document
|
* INOUT IXML_Document *doc ; IXML Description document
|
||||||
* IN const struct sockaddr_in* serverAddr ; socket address object
|
* IN const struct sockaddr* serverAddr ; socket address object
|
||||||
* providing the IP address and port information
|
* providing the IP address and port information
|
||||||
* IN const char* alias ; string containing the alias
|
* IN const char* alias ; string containing the alias
|
||||||
* IN time_t last_modified ; time when the XML document was
|
* IN time_t last_modified ; time when the XML document was
|
||||||
@ -361,7 +370,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
* OUT char docURL[LINE_SIZE] ; buffer to hold the URL of the
|
||||||
* document.
|
* document.
|
||||||
* INOUT IXML_Document *doc:dom document whose urlbase is to be modified
|
* INOUT IXML_Document *doc:dom document whose urlbase is to be modified
|
||||||
* IN const struct sockaddr_in* serverAddr : ip address and port of
|
* IN const struct sockaddr* serverAddr : ip address and port of
|
||||||
* the miniserver
|
* the miniserver
|
||||||
* IN const char* alias : a name to be used for the temp; e.g.:"foo.xml"
|
* IN const char* alias : a name to be used for the temp; e.g.:"foo.xml"
|
||||||
* IN time_t last_modified : time
|
* IN time_t last_modified : time
|
||||||
@ -380,7 +389,7 @@ config_description_doc( INOUT IXML_Document * doc,
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
int
|
int
|
||||||
configure_urlbase( INOUT IXML_Document * doc,
|
configure_urlbase( INOUT IXML_Document * doc,
|
||||||
IN const struct sockaddr_in *serverAddr,
|
IN const struct sockaddr *serverAddr,
|
||||||
IN const char *alias,
|
IN const char *alias,
|
||||||
IN time_t last_modified,
|
IN time_t last_modified,
|
||||||
OUT char docURL[LINE_SIZE] )
|
OUT char docURL[LINE_SIZE] )
|
||||||
|
@ -1,34 +1,39 @@
|
|||||||
/*
|
/**************************************************************************
|
||||||
** Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
*
|
||||||
** Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
* Copyright (c) 1990- 1993, 1996 Open Software Foundation, Inc.
|
||||||
** Digital Equipment Corporation, Maynard, Mass.
|
* Copyright (c) 1989 by Hewlett-Packard Company, Palo Alto, Ca. &
|
||||||
** Copyright (c) 1998 Microsoft.
|
* Digital Equipment Corporation, Maynard, Mass.
|
||||||
** To anyone who acknowledges that this file is provided "AS IS"
|
* Copyright (c) 1998 Microsoft.
|
||||||
** without any express or implied warranty: permission to use, copy,
|
* To anyone who acknowledges that this file is provided "AS IS"
|
||||||
** modify, and distribute this file for any purpose is hereby
|
* without any express or implied warranty: permission to use, copy,
|
||||||
** granted without fee, provided that the above copyright notices and
|
* modify, and distribute this file for any purpose is hereby
|
||||||
** this notice appears in all source code copies, and that none of
|
* granted without fee, provided that the above copyright notices and
|
||||||
** the names of Open Software Foundation, Inc., Hewlett-Packard
|
* this notice appears in all source code copies, and that none of
|
||||||
** Company, or Digital Equipment Corporation be used in advertising
|
* the names of Open Software Foundation, Inc., Hewlett-Packard
|
||||||
** or publicity pertaining to distribution of the software without
|
* Company, or Digital Equipment Corporation be used in advertising
|
||||||
** specific, written prior permission. Neither Open Software
|
* or publicity pertaining to distribution of the software without
|
||||||
** Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
* specific, written prior permission. Neither Open Software
|
||||||
** Corporation makes any representations about the suitability of
|
* Foundation, Inc., Hewlett-Packard Company, Microsoft, nor Digital Equipment
|
||||||
** this software for any purpose.
|
* Corporation makes any representations about the suitability of
|
||||||
*/
|
* this software for any purpose.
|
||||||
|
*
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "uuid.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "UpnpInet.h"
|
||||||
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#ifndef WIN32
|
|
||||||
#include <netinet/in.h>
|
|
||||||
#else
|
|
||||||
#include <winsock2.h>
|
|
||||||
#endif
|
|
||||||
#include "sysdep.h"
|
|
||||||
#include "uuid.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
various forward declarations
|
various forward declarations
|
||||||
@ -386,3 +391,4 @@ uuid_compare( uuid_upnp * u1,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user