Doxygenation of SSDP library.
This commit is contained in:
parent
704dca3df1
commit
04d64a893b
@ -1,3 +1,6 @@
|
|||||||
|
#ifndef UPNP_H
|
||||||
|
#define UPNP_H
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2000-2003 Intel Corporation
|
* Copyright (c) 2000-2003 Intel Corporation
|
||||||
@ -29,11 +32,6 @@
|
|||||||
*
|
*
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
#ifndef UPNP_H
|
|
||||||
#define UPNP_H
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \file
|
* \file
|
||||||
*
|
*
|
||||||
@ -42,13 +40,11 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "ixml.h"
|
#include "ixml.h"
|
||||||
#include "upnpconfig.h"
|
#include "upnpconfig.h"
|
||||||
#include "UpnpGlobal.h"
|
#include "UpnpGlobal.h"
|
||||||
#include "UpnpInet.h"
|
#include "UpnpInet.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* \todo Document the exact reason of these include files and solve this
|
* \todo Document the exact reason of these include files and solve this
|
||||||
* include mess in an include file like UpnpTime.h
|
* include mess in an include file like UpnpTime.h
|
||||||
@ -61,14 +57,12 @@
|
|||||||
/* Other systems ??? */
|
/* Other systems ??? */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
/* Do not #include <sys/param.h> */
|
/* Do not #include <sys/param.h> */
|
||||||
#else
|
#else
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define LINE_SIZE 180
|
#define LINE_SIZE 180
|
||||||
#define NAME_SIZE 256
|
#define NAME_SIZE 256
|
||||||
#define MNFT_NAME_SIZE 64
|
#define MNFT_NAME_SIZE 64
|
||||||
@ -79,7 +73,6 @@
|
|||||||
#define UPNP_USING_CHUNKED -3
|
#define UPNP_USING_CHUNKED -3
|
||||||
#define UPNP_UNTIL_CLOSE -4
|
#define UPNP_UNTIL_CLOSE -4
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \name Error codes
|
* \name Error codes
|
||||||
*
|
*
|
||||||
@ -423,7 +416,6 @@
|
|||||||
#include "SubscriptionRequest.h"
|
#include "SubscriptionRequest.h"
|
||||||
#endif /* UPNP_VERSION >= 10800 */
|
#endif /* UPNP_VERSION >= 10800 */
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \name Constants and Types
|
* \name Constants and Types
|
||||||
*
|
*
|
||||||
|
@ -60,7 +60,6 @@
|
|||||||
#define fseeko fseek
|
#define fseeko fseek
|
||||||
#else
|
#else
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -84,78 +83,17 @@ const int CHUNK_TAIL_SIZE = 10;
|
|||||||
/* in seconds */
|
/* in seconds */
|
||||||
#define DEFAULT_TCP_CONNECT_TIMEOUT 5
|
#define DEFAULT_TCP_CONNECT_TIMEOUT 5
|
||||||
|
|
||||||
/************************************************************************
|
/*!
|
||||||
* Function : Make_Socket_NoBlocking
|
* \brief Checks socket connection and wait if it is not connected.
|
||||||
|
* It should be called just after connect.
|
||||||
*
|
*
|
||||||
* Parameters:
|
* \return 0 if successful, else -1.
|
||||||
* IN int sock: socket
|
*/
|
||||||
*
|
static int Check_Connect_And_Wait_Connection(
|
||||||
* Description:
|
/*! [in] socket. */
|
||||||
* This function makes socket non-blocking.
|
SOCKET sock,
|
||||||
*
|
/*! [in] result of connect. */
|
||||||
* Returns: int
|
int connect_res)
|
||||||
* 0 if successful else -1
|
|
||||||
***************************************************************************/
|
|
||||||
static int Make_Socket_NoBlocking(SOCKET sock)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
u_long val = 1;
|
|
||||||
return ioctlsocket(sock, FIONBIO, &val);
|
|
||||||
#else
|
|
||||||
int val;
|
|
||||||
|
|
||||||
val = fcntl(sock, F_GETFL, 0);
|
|
||||||
if (fcntl(sock, F_SETFL, val | O_NONBLOCK) == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function : Make_Socket_Blocking
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN int sock: socket
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function makes socket blocking.
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
* 0 if successful else -1
|
|
||||||
***************************************************************************/
|
|
||||||
static int Make_Socket_Blocking(int sock)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
|
||||||
u_long val = 0;
|
|
||||||
return ioctlsocket(sock, FIONBIO, &val);
|
|
||||||
#else
|
|
||||||
int val;
|
|
||||||
|
|
||||||
val = fcntl(sock, F_GETFL, 0);
|
|
||||||
if (fcntl(sock, F_SETFL, val & ~O_NONBLOCK) == -1) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************
|
|
||||||
* Function : Check_Connect_And_Wait_Connection
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN int sock: socket
|
|
||||||
* IN int connect_res: result of connect
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function checks socket connection and wait if it is not connected
|
|
||||||
* It should be called just after connect
|
|
||||||
*
|
|
||||||
* Returns: int
|
|
||||||
* 0 if successful else -1
|
|
||||||
***************************************************************************/
|
|
||||||
static int Check_Connect_And_Wait_Connection(int sock, int connect_res)
|
|
||||||
{
|
{
|
||||||
struct timeval tmvTimeout = {DEFAULT_TCP_CONNECT_TIMEOUT, 0};
|
struct timeval tmvTimeout = {DEFAULT_TCP_CONNECT_TIMEOUT, 0};
|
||||||
int result;
|
int result;
|
||||||
@ -210,12 +148,12 @@ static int private_connect(
|
|||||||
socklen_t addrlen)
|
socklen_t addrlen)
|
||||||
{
|
{
|
||||||
#ifndef UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS
|
#ifndef UPNP_ENABLE_BLOCKING_TCP_CONNECTIONS
|
||||||
int ret = Make_Socket_NoBlocking(sockfd);
|
int ret = sock_make_no_blocking(sockfd);
|
||||||
if (ret != - 1) {
|
if (ret != - 1) {
|
||||||
ret = connect(sockfd, serv_addr, addrlen);
|
ret = connect(sockfd, serv_addr, addrlen);
|
||||||
ret = Check_Connect_And_Wait_Connection(sockfd, ret);
|
ret = Check_Connect_And_Wait_Connection(sockfd, ret);
|
||||||
if (ret != - 1) {
|
if (ret != - 1) {
|
||||||
ret = Make_Socket_Blocking(sockfd);
|
ret = sock_make_blocking(sockfd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +39,12 @@
|
|||||||
|
|
||||||
#include "sock.h"
|
#include "sock.h"
|
||||||
|
|
||||||
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
|
#include "unixutil.h" /* for socklen_t, EAFNOSUPPORT */
|
||||||
#include "upnp.h"
|
#include "upnp.h"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h> /* for F_GETFL, F_SETFL, O_NONBLOCK */
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@ -207,3 +208,35 @@ int sock_write(IN SOCKINFO *info, IN const char *buffer, IN int bufsize,
|
|||||||
return sock_read_write(info, (char *)buffer, bufsize, timeoutSecs, FALSE);
|
return sock_read_write(info, (char *)buffer, bufsize, timeoutSecs, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sock_make_blocking(SOCKET sock)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long val = 0;
|
||||||
|
return ioctlsocket(sock, FIONBIO, &val);
|
||||||
|
#else
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = fcntl(sock, F_GETFL, 0);
|
||||||
|
if (fcntl(sock, F_SETFL, val & ~O_NONBLOCK) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sock_make_no_blocking(SOCKET sock)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
u_long val = 1;
|
||||||
|
return ioctlsocket(sock, FIONBIO, &val);
|
||||||
|
#else /* WIN32 */
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = fcntl(sock, F_GETFL, 0);
|
||||||
|
if (fcntl(sock, F_SETFL, val | O_NONBLOCK) == -1) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
#endif /* WIN32 */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -34,6 +34,10 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \file
|
* \file
|
||||||
|
*
|
||||||
|
* \defgroup Sock Network Socket Library
|
||||||
|
*
|
||||||
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "upnputil.h"
|
#include "upnputil.h"
|
||||||
@ -64,6 +68,23 @@ typedef struct
|
|||||||
#extern "C" {
|
#extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Closes the socket if it is different from -1.
|
||||||
|
*
|
||||||
|
* \return -1 if an error occurred or if the socket is -1.
|
||||||
|
*/
|
||||||
|
static UPNP_INLINE int sock_close(
|
||||||
|
/*! Socket descriptor. */
|
||||||
|
SOCKET sock)
|
||||||
|
{
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (sock != -1)
|
||||||
|
ret = UpnpCloseSocket(sock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Assign the passed in socket descriptor to socket descriptor in the
|
* \brief Assign the passed in socket descriptor to socket descriptor in the
|
||||||
* SOCKINFO structure.
|
* SOCKINFO structure.
|
||||||
@ -96,6 +117,23 @@ int sock_init_with_ip(
|
|||||||
/*! Remote socket address. */
|
/*! Remote socket address. */
|
||||||
IN struct sockaddr *foreign_sockaddr);
|
IN struct sockaddr *foreign_sockaddr);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Shutsdown the socket using the ShutdownMethod to indicate whether
|
||||||
|
* sends and receives on the socket will be dis-allowed.
|
||||||
|
*
|
||||||
|
* After shutting down the socket, closesocket is called to release system
|
||||||
|
* resources used by the socket calls.
|
||||||
|
*
|
||||||
|
* \return Integer:
|
||||||
|
* \li \c UPNP_E_SOCKET_ERROR on failure.
|
||||||
|
* \li \c UPNP_E_SUCCESS on success.
|
||||||
|
*/
|
||||||
|
int sock_destroy(
|
||||||
|
/*! Socket Information Object. */
|
||||||
|
INOUT SOCKINFO* info,
|
||||||
|
/*! How to shutdown the socket. Used by sockets's shutdown(). */
|
||||||
|
int ShutdownMethod);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Reads data on socket in sockinfo.
|
* \brief Reads data on socket in sockinfo.
|
||||||
*
|
*
|
||||||
@ -133,42 +171,27 @@ int sock_write(
|
|||||||
INOUT int *timeoutSecs);
|
INOUT int *timeoutSecs);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Shutsdown the socket using the ShutdownMethod to indicate whether
|
* \brief Make socket blocking.
|
||||||
* sends and receives on the socket will be dis-allowed.
|
|
||||||
*
|
*
|
||||||
* After shutting down the socket, closesocket is called to release system
|
* \return 0 if successful, -1 otherwise.
|
||||||
* resources used by the socket calls.
|
|
||||||
*
|
|
||||||
* \return Integer:
|
|
||||||
* \li \c UPNP_E_SOCKET_ERROR on failure.
|
|
||||||
* \li \c UPNP_E_SUCCESS on success.
|
|
||||||
*/
|
*/
|
||||||
int sock_destroy(
|
int sock_make_blocking(
|
||||||
/*! Socket Information Object. */
|
/* [in] socket. */
|
||||||
INOUT SOCKINFO* info,
|
SOCKET sock);
|
||||||
/*! How to shutdown the socket. Used by sockets's shutdown(). */
|
|
||||||
int ShutdownMethod);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Closes the socket if it is different from -1.
|
* \brief Make socket non-blocking.
|
||||||
*
|
*
|
||||||
* \return -1 if an error occurred or if the socket is -1.
|
* \return 0 if successful, -1 otherwise.
|
||||||
*/
|
*/
|
||||||
static UPNP_INLINE int sock_close(
|
int sock_make_no_blocking(
|
||||||
/*! Socket descriptor. */
|
/* [in] socket. */
|
||||||
SOCKET sock)
|
SOCKET sock);
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
if (sock != -1) {
|
|
||||||
ret = UpnpCloseSocket(sock);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} /* #extern "C" */
|
} /* #extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* @} Sock Network Socket Library */
|
||||||
|
|
||||||
#endif /* GENLIB_NET_SOCK_H */
|
#endif /* GENLIB_NET_SOCK_H */
|
||||||
|
@ -33,6 +33,10 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
* \defgroup SSDPlib SSDP Library
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
* \file
|
* \file
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -44,7 +48,6 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@ -184,48 +187,33 @@ typedef struct
|
|||||||
typedef int (*ParserFun)(char *, Event *);
|
typedef int (*ParserFun)(char *, Event *);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Make ssdp socket non-blocking.
|
* \name SSDP Server Functions
|
||||||
*
|
*
|
||||||
* \return 0 if successful, -1 otherwise.
|
* @{
|
||||||
*/
|
*/
|
||||||
int Make_Socket_NoBlocking(
|
|
||||||
/* [in] socket. */
|
|
||||||
SOCKET sock);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Handles the search request. It does the sanity checks of the
|
* \brief Sends SSDP advertisements, replies and shutdown messages.
|
||||||
* request and then schedules a thread to send a random time reply
|
*
|
||||||
* (random within maximum time given by the control point to reply).
|
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
||||||
*/
|
*/
|
||||||
#ifdef INCLUDE_DEVICE_APIS
|
int AdvertiseAndReply(
|
||||||
void ssdp_handle_device_request(
|
/* [in] -1 = Send shutdown, 0 = send reply, 1 = Send Advertisement. */
|
||||||
/* [in] . */
|
int AdFlag,
|
||||||
http_message_t *hmsg,
|
/* [in] Device handle. */
|
||||||
/* [in] . */
|
UpnpDevice_Handle Hnd,
|
||||||
struct sockaddr *dest_addr);
|
/* [in] Search type for sending replies. */
|
||||||
#else
|
enum SsdpSearchType SearchType,
|
||||||
static inline void ssdp_handle_device_request(
|
/* [in] Destination address. */
|
||||||
/* [in] . */
|
struct sockaddr *DestAddr,
|
||||||
http_message_t *hmsg,
|
/* [in] Device type. */
|
||||||
/* [in] . */
|
char *DeviceType,
|
||||||
struct sockaddr* dest_addr) {}
|
/* [in] Device UDN. */
|
||||||
#endif
|
char *DeviceUDN,
|
||||||
|
/* [in] Service type. */
|
||||||
/*!
|
char *ServiceType,
|
||||||
* \brief This function handles the ssdp messages from the devices. These
|
/* [in] Advertisement age. */
|
||||||
* messages includes the search replies, advertisement of device coming alive
|
int Exp);
|
||||||
* and bye byes.
|
|
||||||
*/
|
|
||||||
void ssdp_handle_ctrlpt_msg(
|
|
||||||
/* [in] SSDP message from the device. */
|
|
||||||
http_message_t *hmsg,
|
|
||||||
/* [in] Address of the device. */
|
|
||||||
struct sockaddr *dest_addr,
|
|
||||||
/* [in] timeout kept by the control point while sending search message. */
|
|
||||||
int timeout,
|
|
||||||
/* [in] Cookie stored by the control point application. This cookie will
|
|
||||||
* be returned to the control point in the callback. */
|
|
||||||
void *cookie);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Fills the fields of the event structure like DeviceType, Device UDN
|
* \brief Fills the fields of the event structure like DeviceType, Device UDN
|
||||||
@ -240,24 +228,6 @@ int unique_service_name(
|
|||||||
* function. */
|
* function. */
|
||||||
SsdpEvent *Evt);
|
SsdpEvent *Evt);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Creates the ssdp sockets. It set their option to listen for
|
|
||||||
* multicast traffic.
|
|
||||||
*
|
|
||||||
* \return UPNP_E_SUCCESS if successful else returns appropriate error.
|
|
||||||
*/
|
|
||||||
int get_ssdp_sockets(
|
|
||||||
/* [out] Array of SSDP sockets. */
|
|
||||||
MiniServerSockArray *out);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief This function reads the data from the ssdp socket.
|
|
||||||
*/
|
|
||||||
void readFromSSDPSocket(
|
|
||||||
/* [in] SSDP socket. */
|
|
||||||
SOCKET socket);
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief This function figures out the type of the SSDP search in the in the
|
* \brief This function figures out the type of the SSDP search in the in the
|
||||||
* request.
|
* request.
|
||||||
@ -269,7 +239,6 @@ enum SsdpSearchType ssdp_request_type1(
|
|||||||
/* [in] command came in the ssdp request. */
|
/* [in] command came in the ssdp request. */
|
||||||
char *cmd);
|
char *cmd);
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Starts filling the SSDP event structure based upon the
|
* \brief Starts filling the SSDP event structure based upon the
|
||||||
* request received.
|
* request received.
|
||||||
@ -282,9 +251,64 @@ int ssdp_request_type(
|
|||||||
/* [out] The event structure partially filled by this function. */
|
/* [out] The event structure partially filled by this function. */
|
||||||
SsdpEvent *Evt);
|
SsdpEvent *Evt);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief This function reads the data from the ssdp socket.
|
||||||
|
*/
|
||||||
|
void readFromSSDPSocket(
|
||||||
|
/* [in] SSDP socket. */
|
||||||
|
SOCKET socket);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates the IPv4 and IPv6 ssdp sockets required by the
|
||||||
|
* control point and device operation.
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS if successful else returns appropriate error.
|
||||||
|
*/
|
||||||
|
int get_ssdp_sockets(
|
||||||
|
/* [out] Array of SSDP sockets. */
|
||||||
|
MiniServerSockArray *out);
|
||||||
|
|
||||||
|
/* @} SSDP Server Functions */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name SSDP Control Point Functions
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief 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] SSDP message from the device. */
|
||||||
|
http_message_t *hmsg,
|
||||||
|
/* [in] Address of the device. */
|
||||||
|
struct sockaddr *dest_addr,
|
||||||
|
/* [in] timeout kept by the control point while sending search message.
|
||||||
|
* Only in search reply. */
|
||||||
|
int timeout,
|
||||||
|
/* [in] Cookie stored by the control point application. This cookie will
|
||||||
|
* be returned to the control point in the callback.
|
||||||
|
* Only in search reply. */
|
||||||
|
void *cookie);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates and send the search request for a specific URL.
|
* \brief 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:
|
||||||
|
* \li "ssdp:all" : Search for all devices and services.
|
||||||
|
* \li "ssdp:rootdevice" : Search for root devices only.
|
||||||
|
* \li "uuid:<device-uuid>" : Search for a particular device.
|
||||||
|
* \li "urn:schemas-upnp-org:device:<deviceType:v>"
|
||||||
|
* \li "urn:schemas-upnp-org:service:<serviceType:v>"
|
||||||
|
* \li "urn:<domain-name>:device:<deviceType:v>"
|
||||||
|
* \li "urn:<domain-name>:service:<serviceType:v>"
|
||||||
|
*
|
||||||
* \return 1 if successful else appropriate error.
|
* \return 1 if successful else appropriate error.
|
||||||
*/
|
*/
|
||||||
int SearchByTarget(
|
int SearchByTarget(
|
||||||
@ -296,6 +320,43 @@ int SearchByTarget(
|
|||||||
* be returned to application in the callback. */
|
* be returned to application in the callback. */
|
||||||
void *Cookie);
|
void *Cookie);
|
||||||
|
|
||||||
|
/* @} SSDP Control Point Functions */
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \name SSDP Device Functions
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Wrapper function to reply the search request coming from the
|
||||||
|
* control point.
|
||||||
|
*
|
||||||
|
* \return always return NULL
|
||||||
|
*/
|
||||||
|
void *advertiseAndReplyThread(
|
||||||
|
/* [in] Structure containing the search request. */
|
||||||
|
void *data);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Handles the search request. It does the sanity checks of the
|
||||||
|
* request and then schedules a thread to send a random time reply
|
||||||
|
* (random within maximum time given by the control point to reply).
|
||||||
|
*/
|
||||||
|
#ifdef INCLUDE_DEVICE_APIS
|
||||||
|
void ssdp_handle_device_request(
|
||||||
|
/* [in] . */
|
||||||
|
http_message_t *hmsg,
|
||||||
|
/* [in] . */
|
||||||
|
struct sockaddr *dest_addr);
|
||||||
|
#else /* INCLUDE_DEVICE_APIS */
|
||||||
|
static inline void ssdp_handle_device_request(
|
||||||
|
/* [in] . */
|
||||||
|
http_message_t *hmsg,
|
||||||
|
/* [in] . */
|
||||||
|
struct sockaddr* dest_addr) {}
|
||||||
|
#endif /* INCLUDE_DEVICE_APIS */
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates the device advertisement request based on the input
|
* \brief Creates the device advertisement request based on the input
|
||||||
* parameter, and send it to the multicast channel.
|
* parameter, and send it to the multicast channel.
|
||||||
@ -316,48 +377,6 @@ int DeviceAdvertisement(
|
|||||||
/* [in] Device address family. */
|
/* [in] Device address family. */
|
||||||
int AddressFamily);
|
int AddressFamily);
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Creates a HTTP device shutdown request packet and send it to the
|
|
||||||
* multicast channel through RequestHandler.
|
|
||||||
*
|
|
||||||
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
|
||||||
*/
|
|
||||||
int DeviceShutdown(
|
|
||||||
/* [in] Device Type. */
|
|
||||||
char *DevType,
|
|
||||||
/* [in] 1 means root device. */
|
|
||||||
int RootDev,
|
|
||||||
/* [in] Device UDN. */
|
|
||||||
char *Udn,
|
|
||||||
/* [in] . */
|
|
||||||
char *_Server,
|
|
||||||
/* [in] Location URL. */
|
|
||||||
char *Location,
|
|
||||||
/* [in] Device duration in sec. */
|
|
||||||
int Duration,
|
|
||||||
/* [in] Device address family. */
|
|
||||||
int AddressFamily);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Creates the reply packet based on the input parameter, and send it
|
|
||||||
* to the client address given in its input parameter DestAddr.
|
|
||||||
*
|
|
||||||
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
|
||||||
*/
|
|
||||||
int DeviceReply(
|
|
||||||
/* [in] destination IP address. */
|
|
||||||
struct sockaddr *DestAddr,
|
|
||||||
/* [in] Device type. */
|
|
||||||
char *DevType,
|
|
||||||
/* [in] 1 means root device 0 means embedded device. */
|
|
||||||
int RootDev,
|
|
||||||
/* [in] Device UDN. */
|
|
||||||
char *Udn,
|
|
||||||
/* [in] Location of Device description document. */
|
|
||||||
char *Location,
|
|
||||||
/* [in] Life time of this device. */
|
|
||||||
int Duration);
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates the reply packet based on the input parameter, and send it
|
* \brief Creates the reply packet based on the input parameter, and send it
|
||||||
* to the client addesss given in its input parameter DestAddr.
|
* to the client addesss given in its input parameter DestAddr.
|
||||||
@ -380,6 +399,26 @@ int SendReply(
|
|||||||
/* [in] . */
|
/* [in] . */
|
||||||
int ByType );
|
int ByType );
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Creates the reply packet based on the input parameter, and send it
|
||||||
|
* to the client address given in its input parameter DestAddr.
|
||||||
|
*
|
||||||
|
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
||||||
|
*/
|
||||||
|
int DeviceReply(
|
||||||
|
/* [in] destination IP address. */
|
||||||
|
struct sockaddr *DestAddr,
|
||||||
|
/* [in] Device type. */
|
||||||
|
char *DevType,
|
||||||
|
/* [in] 1 means root device 0 means embedded device. */
|
||||||
|
int RootDev,
|
||||||
|
/* [in] Device UDN. */
|
||||||
|
char *Udn,
|
||||||
|
/* [in] Location of Device description document. */
|
||||||
|
char *Location,
|
||||||
|
/* [in] Life time of this device. */
|
||||||
|
int Duration);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Creates the advertisement packet based on the input parameter,
|
* \brief Creates the advertisement packet based on the input parameter,
|
||||||
* and send it to the multicast channel.
|
* and send it to the multicast channel.
|
||||||
@ -435,36 +474,29 @@ int ServiceShutdown(
|
|||||||
int AddressFamily);
|
int AddressFamily);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Wrapper function to reply the search request coming from the
|
* \brief Creates a HTTP device shutdown request packet and send it to the
|
||||||
* control point.
|
* multicast channel through RequestHandler.
|
||||||
*
|
|
||||||
* \return always return NULL
|
|
||||||
*/
|
|
||||||
void *advertiseAndReplyThread(
|
|
||||||
/* [in] Structure containing the search request. */
|
|
||||||
void *data);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Sends SSDP advertisements, replies and shutdown messages.
|
|
||||||
*
|
*
|
||||||
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
* \return UPNP_E_SUCCESS if successful else appropriate error.
|
||||||
*/
|
*/
|
||||||
int AdvertiseAndReply(
|
int DeviceShutdown(
|
||||||
/* [in] -1 = Send shutdown, 0 = send reply, 1 = Send Advertisement. */
|
/* [in] Device Type. */
|
||||||
int AdFlag,
|
char *DevType,
|
||||||
/* [in] Device handle. */
|
/* [in] 1 means root device. */
|
||||||
UpnpDevice_Handle Hnd,
|
int RootDev,
|
||||||
/* [in] Search type for sending replies. */
|
|
||||||
enum SsdpSearchType SearchType,
|
|
||||||
/* [in] Destination address. */
|
|
||||||
struct sockaddr *DestAddr,
|
|
||||||
/* [in] Device type. */
|
|
||||||
char *DeviceType,
|
|
||||||
/* [in] Device UDN. */
|
/* [in] Device UDN. */
|
||||||
char *DeviceUDN,
|
char *Udn,
|
||||||
/* [in] Service type. */
|
/* [in] . */
|
||||||
char *ServiceType,
|
char *_Server,
|
||||||
/* [in] Advertisement age. */
|
/* [in] Location URL. */
|
||||||
int Exp);
|
char *Location,
|
||||||
|
/* [in] Device duration in sec. */
|
||||||
|
int Duration,
|
||||||
|
/* [in] Device address family. */
|
||||||
|
int AddressFamily);
|
||||||
|
|
||||||
|
/* @} SSDP Device Functions */
|
||||||
|
|
||||||
|
/* @} SSDPlib SSDP Library */
|
||||||
|
|
||||||
#endif /* SSDPLIB_H */
|
#endif /* SSDPLIB_H */
|
||||||
|
@ -29,6 +29,14 @@
|
|||||||
*
|
*
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \addtogroup SSDPlib
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* \file
|
||||||
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "upnputil.h"
|
#include "upnputil.h"
|
||||||
@ -49,61 +57,26 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#endif /* WIN32 */
|
#endif /* WIN32 */
|
||||||
|
|
||||||
/************************************************************************
|
/*!
|
||||||
* Function: send_search_result
|
* \brief Sends a callback to the control point application with a SEARCH
|
||||||
*
|
* result.
|
||||||
* Parameters:
|
*/
|
||||||
* IN void *data: Search reply from the device
|
static void send_search_result(
|
||||||
*
|
/* [in] Search reply from the device. */
|
||||||
* Description:
|
IN void *data)
|
||||||
* This function sends a callback to the control point application with
|
|
||||||
* a SEARCH result
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
void send_search_result(IN void *data)
|
|
||||||
{
|
{
|
||||||
ResultData *temp = ( ResultData * ) data;
|
ResultData *temp = (ResultData *) data;
|
||||||
|
|
||||||
temp->ctrlpt_callback(UPNP_DISCOVERY_SEARCH_RESULT, &temp->param, temp->cookie);
|
temp->ctrlpt_callback(UPNP_DISCOVERY_SEARCH_RESULT, &temp->param,
|
||||||
|
temp->cookie);
|
||||||
free(temp);
|
free(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr *dest_addr,
|
||||||
* Function: ssdp_handle_ctrlpt_msg
|
int timeout, void *cookie)
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN http_message_t *hmsg:
|
|
||||||
* SSDP message from the device
|
|
||||||
* IN struct sockaddr *dest_addr:
|
|
||||||
* Address of the device
|
|
||||||
* IN int timeout:
|
|
||||||
* timeout kept by the control point while
|
|
||||||
* sending search message
|
|
||||||
* IN void* cookie:
|
|
||||||
* Cookie stored by the control point application.
|
|
||||||
* This cookie will be returned to the control point
|
|
||||||
* in the callback
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function handles the ssdp messages from the devices. These
|
|
||||||
* messages includes the search replies, advertisement of device coming
|
|
||||||
* alive and bye byes.
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
void ssdp_handle_ctrlpt_msg(
|
|
||||||
IN http_message_t *hmsg,
|
|
||||||
IN struct sockaddr *dest_addr,
|
|
||||||
/* only in search reply */
|
|
||||||
IN int timeout,
|
|
||||||
/* only in search reply */
|
|
||||||
IN void *cookie)
|
|
||||||
{
|
{
|
||||||
int handle;
|
int handle;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
@ -272,25 +245,27 @@ void ssdp_handle_ctrlpt_msg(
|
|||||||
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:{
|
||||||
size_t m = min(hdr_value.length,
|
size_t m = min(hdr_value.length,
|
||||||
strlen(searchArg->
|
strlen
|
||||||
searchTarget));
|
(searchArg->searchTarget));
|
||||||
matched = !strncmp(searchArg->searchTarget,
|
matched =
|
||||||
hdr_value.buf, m);
|
!strncmp(searchArg->searchTarget,
|
||||||
break;
|
hdr_value.buf, m);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
case SSDP_SERVICE:{
|
case SSDP_SERVICE:{
|
||||||
size_t m = min(hdr_value.length,
|
size_t m = min(hdr_value.length,
|
||||||
strlen(searchArg->
|
strlen
|
||||||
searchTarget));
|
(searchArg->searchTarget));
|
||||||
matched = !strncmp(searchArg->searchTarget,
|
matched =
|
||||||
hdr_value.buf, m);
|
!strncmp(searchArg->searchTarget,
|
||||||
break;
|
hdr_value.buf, m);
|
||||||
}
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
matched = 0;
|
matched = 0;
|
||||||
break;
|
break;
|
||||||
@ -304,8 +279,7 @@ void ssdp_handle_ctrlpt_msg(
|
|||||||
threadData->cookie = searchArg->cookie;
|
threadData->cookie = searchArg->cookie;
|
||||||
threadData->ctrlpt_callback =
|
threadData->ctrlpt_callback =
|
||||||
ctrlpt_callback;
|
ctrlpt_callback;
|
||||||
TPJobInit(&job,
|
TPJobInit(&job, (start_routine)
|
||||||
(start_routine)
|
|
||||||
send_search_result,
|
send_search_result,
|
||||||
threadData);
|
threadData);
|
||||||
TPJobSetPriority(&job, MED_PRIORITY);
|
TPJobSetPriority(&job, MED_PRIORITY);
|
||||||
@ -324,60 +298,57 @@ void ssdp_handle_ctrlpt_msg(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
/************************************************************************
|
* \brief Creates a HTTP search request packet depending on the input
|
||||||
* Function : CreateClientRequestPacket
|
* parameter.
|
||||||
*
|
*/
|
||||||
* Parameters:
|
static void CreateClientRequestPacket(
|
||||||
* IN char * RqstBuf:Output string in HTTP format.
|
/*! [in] Output string in HTTP format. */
|
||||||
* IN char *SearchTarget:Search Target
|
IN char *RqstBuf,
|
||||||
* IN int Mx dest_addr: Number of seconds to wait to
|
/*! [in] Search Target. */
|
||||||
* collect all the responses
|
IN int Mx,
|
||||||
* IN int AddressFamily: search address family
|
/*! [in] Number of seconds to wait to collect all the responses. */
|
||||||
*
|
IN char *SearchTarget,
|
||||||
* Description:
|
/*! [in] search address family. */
|
||||||
* This function creates a HTTP search request packet
|
IN int AddressFamily)
|
||||||
* depending on the input parameter.
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
static void
|
|
||||||
CreateClientRequestPacket( IN char *RqstBuf,
|
|
||||||
IN int Mx,
|
|
||||||
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");
|
||||||
|
|
||||||
if (AddressFamily == AF_INET) {
|
if (AddressFamily == AF_INET) {
|
||||||
sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT );
|
sprintf(TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT);
|
||||||
} else if (AddressFamily == AF_INET6) {
|
} else if (AddressFamily == AF_INET6) {
|
||||||
sprintf( TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_LINKLOCAL, SSDP_PORT );
|
sprintf(TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_LINKLOCAL,
|
||||||
}
|
SSDP_PORT);
|
||||||
strcat( RqstBuf, TempBuf );
|
}
|
||||||
strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );
|
strcat(RqstBuf, TempBuf);
|
||||||
|
strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n");
|
||||||
|
|
||||||
if( Mx > 0 ) {
|
if (Mx > 0) {
|
||||||
sprintf( TempBuf, "MX: %d\r\n", Mx );
|
sprintf(TempBuf, "MX: %d\r\n", Mx);
|
||||||
strcat( RqstBuf, TempBuf );
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if( SearchTarget != NULL ) {
|
if (SearchTarget != NULL) {
|
||||||
sprintf( TempBuf, "ST: %s\r\n", SearchTarget );
|
sprintf(TempBuf, "ST: %s\r\n", SearchTarget);
|
||||||
strcat( RqstBuf, TempBuf );
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
strcat( RqstBuf, "\r\n" );
|
strcat(RqstBuf, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief
|
||||||
|
*/
|
||||||
static void CreateClientRequestPacketUlaGua(
|
static void CreateClientRequestPacketUlaGua(
|
||||||
IN char *RqstBuf,
|
/*! [in] . */
|
||||||
IN int Mx,
|
char *RqstBuf,
|
||||||
IN char *SearchTarget,
|
/*! [in] . */
|
||||||
IN int AddressFamily)
|
int Mx,
|
||||||
|
/*! [in] . */
|
||||||
|
char *SearchTarget,
|
||||||
|
/*! [in] . */
|
||||||
|
int AddressFamily)
|
||||||
{
|
{
|
||||||
char TempBuf[COMMAND_LEN];
|
char TempBuf[COMMAND_LEN];
|
||||||
|
|
||||||
@ -385,7 +356,8 @@ static void CreateClientRequestPacketUlaGua(
|
|||||||
if (AddressFamily == AF_INET) {
|
if (AddressFamily == AF_INET) {
|
||||||
sprintf(TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT);
|
sprintf(TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_PORT);
|
||||||
} else if (AddressFamily == AF_INET6) {
|
} else if (AddressFamily == AF_INET6) {
|
||||||
sprintf(TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_SITELOCAL, SSDP_PORT);
|
sprintf(TempBuf, "HOST: [%s]:%d\r\n", SSDP_IPV6_SITELOCAL,
|
||||||
|
SSDP_PORT);
|
||||||
}
|
}
|
||||||
strcat(RqstBuf, TempBuf);
|
strcat(RqstBuf, TempBuf);
|
||||||
strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n");
|
strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n");
|
||||||
@ -400,94 +372,58 @@ static void CreateClientRequestPacketUlaGua(
|
|||||||
strcat(RqstBuf, "\r\n");
|
strcat(RqstBuf, "\r\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
/************************************************************************
|
* \brief
|
||||||
* Function : searchExpired
|
*/
|
||||||
*
|
static void searchExpired(
|
||||||
* Parameters:
|
/* [in] . */
|
||||||
* IN void * arg:
|
void *arg)
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* This function
|
|
||||||
*
|
|
||||||
* Returns: void
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
void searchExpired(void *arg)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
int *id = (int *)arg;
|
int *id = (int *)arg;
|
||||||
int handle = -1;
|
int handle = -1;
|
||||||
struct Handle_Info *ctrlpt_info = NULL;
|
struct Handle_Info *ctrlpt_info = NULL;
|
||||||
|
|
||||||
/* remove search Target from list and call client back */
|
/* remove search Target from list and call client back */
|
||||||
ListNode *node = NULL;
|
ListNode *node = NULL;
|
||||||
SsdpSearchArg *item;
|
SsdpSearchArg *item;
|
||||||
Upnp_FunPtr ctrlpt_callback;
|
Upnp_FunPtr ctrlpt_callback;
|
||||||
void *cookie = NULL;
|
void *cookie = NULL;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
HandleLock();
|
HandleLock();
|
||||||
|
|
||||||
/* remove search target from search list */
|
/* remove search target from search list */
|
||||||
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
|
if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
|
||||||
free( id );
|
free(id);
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ctrlpt_callback = ctrlpt_info->Callback;
|
ctrlpt_callback = ctrlpt_info->Callback;
|
||||||
node = ListHead( &ctrlpt_info->SsdpSearchList );
|
node = ListHead(&ctrlpt_info->SsdpSearchList);
|
||||||
while( node != NULL ) {
|
while (node != NULL) {
|
||||||
item = ( SsdpSearchArg * ) node->item;
|
item = (SsdpSearchArg *) node->item;
|
||||||
if( item->timeoutEventId == ( *id ) ) {
|
if (item->timeoutEventId == (*id)) {
|
||||||
free( item->searchTarget );
|
free(item->searchTarget);
|
||||||
cookie = item->cookie;
|
cookie = item->cookie;
|
||||||
found = 1;
|
found = 1;
|
||||||
item->searchTarget = NULL;
|
item->searchTarget = NULL;
|
||||||
free( item );
|
free(item);
|
||||||
ListDelNode( &ctrlpt_info->SsdpSearchList, node, 0 );
|
ListDelNode(&ctrlpt_info->SsdpSearchList, node, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
node = ListNext( &ctrlpt_info->SsdpSearchList, node );
|
node = ListNext(&ctrlpt_info->SsdpSearchList, node);
|
||||||
}
|
}
|
||||||
HandleUnlock();
|
HandleUnlock();
|
||||||
|
|
||||||
if( found ) {
|
if (found) {
|
||||||
ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
|
ctrlpt_callback(UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie);
|
||||||
}
|
}
|
||||||
|
|
||||||
free( id );
|
free(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
int SearchByTarget(int Mx, char *St, void *Cookie)
|
||||||
* Function : SearchByTarget
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* IN int Mx:Number of seconds to wait, to collect all the responses.
|
|
||||||
* IN char *St: Search target.
|
|
||||||
* IN void *Cookie: cookie provided by control point application.
|
|
||||||
* This cokie will be returned to application in the callback.
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* 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
|
|
||||||
* 1 if successful else appropriate error
|
|
||||||
***************************************************************************/
|
|
||||||
int SearchByTarget(
|
|
||||||
IN int Mx,
|
|
||||||
IN char *St,
|
|
||||||
IN void *Cookie)
|
|
||||||
{
|
{
|
||||||
char errorBuffer[ERROR_BUFFER_LEN];
|
char errorBuffer[ERROR_BUFFER_LEN];
|
||||||
int *id = NULL;
|
int *id = NULL;
|
||||||
@ -497,8 +433,8 @@ int SearchByTarget(
|
|||||||
char ReqBufv6UlaGua[BUFSIZE];
|
char ReqBufv6UlaGua[BUFSIZE];
|
||||||
struct sockaddr_storage __ss_v4;
|
struct sockaddr_storage __ss_v4;
|
||||||
struct sockaddr_storage __ss_v6;
|
struct sockaddr_storage __ss_v6;
|
||||||
struct sockaddr_in* destAddr4 = (struct sockaddr_in*)&__ss_v4;
|
struct sockaddr_in *destAddr4 = (struct sockaddr_in *)&__ss_v4;
|
||||||
struct sockaddr_in6* destAddr6 = (struct sockaddr_in6*)&__ss_v6;
|
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;
|
||||||
@ -508,7 +444,7 @@ int SearchByTarget(
|
|||||||
unsigned long addrv4 = inet_addr(gIF_IPV4);
|
unsigned long addrv4 = inet_addr(gIF_IPV4);
|
||||||
int max_fd = 0;
|
int max_fd = 0;
|
||||||
|
|
||||||
/*ThreadData *ThData;*/
|
/*ThreadData *ThData; */
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
|
|
||||||
requestType = ssdp_request_type1(St);
|
requestType = ssdp_request_type1(St);
|
||||||
@ -516,7 +452,8 @@ int SearchByTarget(
|
|||||||
return UPNP_E_INVALID_PARAM;
|
return UPNP_E_INVALID_PARAM;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, "Inside SearchByTarget\n");
|
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
|
"Inside SearchByTarget\n");
|
||||||
|
|
||||||
timeTillRead = Mx;
|
timeTillRead = Mx;
|
||||||
if (timeTillRead < MIN_SEARCH_TIME) {
|
if (timeTillRead < MIN_SEARCH_TIME) {
|
||||||
@ -527,7 +464,8 @@ int SearchByTarget(
|
|||||||
|
|
||||||
CreateClientRequestPacket(ReqBufv4, timeTillRead, St, AF_INET);
|
CreateClientRequestPacket(ReqBufv4, timeTillRead, St, AF_INET);
|
||||||
CreateClientRequestPacket(ReqBufv6, timeTillRead, St, AF_INET6);
|
CreateClientRequestPacket(ReqBufv6, timeTillRead, St, AF_INET6);
|
||||||
CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, timeTillRead, St, AF_INET6);
|
CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, timeTillRead, St,
|
||||||
|
AF_INET6);
|
||||||
|
|
||||||
memset(&__ss_v4, 0, sizeof(__ss_v4));
|
memset(&__ss_v4, 0, sizeof(__ss_v4));
|
||||||
destAddr4->sin_family = AF_INET;
|
destAddr4->sin_family = AF_INET;
|
||||||
@ -548,19 +486,19 @@ int SearchByTarget(
|
|||||||
return UPNP_E_INTERNAL_ERROR;
|
return UPNP_E_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
newArg = (SsdpSearchArg *)malloc(sizeof(SsdpSearchArg));
|
newArg = (SsdpSearchArg *) malloc(sizeof(SsdpSearchArg));
|
||||||
newArg->searchTarget = strdup(St);
|
newArg->searchTarget = strdup(St);
|
||||||
newArg->cookie = Cookie;
|
newArg->cookie = Cookie;
|
||||||
newArg->requestType = requestType;
|
newArg->requestType = requestType;
|
||||||
|
|
||||||
id = (int *)malloc(sizeof(int));
|
id = (int *)malloc(sizeof(int));
|
||||||
TPJobInit(&job, (start_routine)searchExpired, id);
|
TPJobInit(&job, (start_routine) searchExpired, id);
|
||||||
TPJobSetPriority(&job, MED_PRIORITY);
|
TPJobSetPriority(&job, MED_PRIORITY);
|
||||||
TPJobSetFreeFunction(&job, (free_routine)free);
|
TPJobSetFreeFunction(&job, (free_routine) free);
|
||||||
|
|
||||||
/* Schedule a timeout event to remove search Arg */
|
/* Schedule a timeout event to remove search Arg */
|
||||||
TimerThreadSchedule(&gTimerThread, timeTillRead,
|
TimerThreadSchedule(&gTimerThread, timeTillRead,
|
||||||
REL_SEC, &job, SHORT_TERM, id);
|
REL_SEC, &job, SHORT_TERM, id);
|
||||||
newArg->timeoutEventId = *id;
|
newArg->timeoutEventId = *id;
|
||||||
|
|
||||||
ListAddTail(&ctrlpt_info->SsdpSearchList, newArg);
|
ListAddTail(&ctrlpt_info->SsdpSearchList, newArg);
|
||||||
@ -570,14 +508,14 @@ int SearchByTarget(
|
|||||||
FD_ZERO(&wrSet);
|
FD_ZERO(&wrSet);
|
||||||
if (gSsdpReqSocket4 != INVALID_SOCKET) {
|
if (gSsdpReqSocket4 != INVALID_SOCKET) {
|
||||||
setsockopt(gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF,
|
setsockopt(gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF,
|
||||||
(char *)&addrv4, sizeof (addrv4));
|
(char *)&addrv4, sizeof(addrv4));
|
||||||
FD_SET(gSsdpReqSocket4, &wrSet);
|
FD_SET(gSsdpReqSocket4, &wrSet);
|
||||||
max_fd = max(max_fd, gSsdpReqSocket4);
|
max_fd = max(max_fd, gSsdpReqSocket4);
|
||||||
}
|
}
|
||||||
#ifdef UPNP_ENABLE_IPV6
|
#ifdef UPNP_ENABLE_IPV6
|
||||||
if (gSsdpReqSocket6 != INVALID_SOCKET) {
|
if (gSsdpReqSocket6 != INVALID_SOCKET) {
|
||||||
setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
|
||||||
(char *)&gIF_INDEX, sizeof (gIF_INDEX));
|
(char *)&gIF_INDEX, sizeof(gIF_INDEX));
|
||||||
FD_SET(gSsdpReqSocket6, &wrSet);
|
FD_SET(gSsdpReqSocket6, &wrSet);
|
||||||
max_fd = max(max_fd, gSsdpReqSocket6);
|
max_fd = max(max_fd, gSsdpReqSocket6);
|
||||||
}
|
}
|
||||||
@ -587,8 +525,7 @@ int SearchByTarget(
|
|||||||
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(gSsdpReqSocket4, SD_BOTH);
|
shutdown(gSsdpReqSocket4, SD_BOTH);
|
||||||
UpnpCloseSocket(gSsdpReqSocket4);
|
UpnpCloseSocket(gSsdpReqSocket4);
|
||||||
#ifdef UPNP_ENABLE_IPV6
|
#ifdef UPNP_ENABLE_IPV6
|
||||||
@ -604,39 +541,39 @@ int SearchByTarget(
|
|||||||
|
|
||||||
while (NumCopy < NUM_SSDP_COPY) {
|
while (NumCopy < NUM_SSDP_COPY) {
|
||||||
sendto(gSsdpReqSocket6,
|
sendto(gSsdpReqSocket6,
|
||||||
ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
|
ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
|
||||||
(struct sockaddr *)&__ss_v6,
|
(struct sockaddr *)&__ss_v6,
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
NumCopy++;
|
NumCopy++;
|
||||||
imillisleep(SSDP_PAUSE);
|
imillisleep(SSDP_PAUSE);
|
||||||
}
|
}
|
||||||
NumCopy = 0;
|
NumCopy = 0;
|
||||||
inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
|
inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
|
||||||
while (NumCopy < NUM_SSDP_COPY) {
|
while (NumCopy < NUM_SSDP_COPY) {
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
">>> SSDP SEND M-SEARCH >>>\n%s\n",
|
">>> SSDP SEND M-SEARCH >>>\n%s\n",
|
||||||
ReqBufv6);
|
ReqBufv6);
|
||||||
sendto(gSsdpReqSocket6,
|
sendto(gSsdpReqSocket6,
|
||||||
ReqBufv6, strlen(ReqBufv6), 0,
|
ReqBufv6, strlen(ReqBufv6), 0,
|
||||||
(struct sockaddr *)&__ss_v6,
|
(struct sockaddr *)&__ss_v6,
|
||||||
sizeof(struct sockaddr_in6));
|
sizeof(struct sockaddr_in6));
|
||||||
NumCopy++;
|
NumCopy++;
|
||||||
imillisleep(SSDP_PAUSE);
|
imillisleep(SSDP_PAUSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* IPv6 */
|
#endif /* IPv6 */
|
||||||
|
|
||||||
if (gSsdpReqSocket4 != INVALID_SOCKET &&
|
if (gSsdpReqSocket4 != INVALID_SOCKET &&
|
||||||
FD_ISSET(gSsdpReqSocket4, &wrSet)) {
|
FD_ISSET(gSsdpReqSocket4, &wrSet)) {
|
||||||
int NumCopy = 0;
|
int NumCopy = 0;
|
||||||
while (NumCopy < NUM_SSDP_COPY) {
|
while (NumCopy < NUM_SSDP_COPY) {
|
||||||
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
|
UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
|
||||||
">>> SSDP SEND M-SEARCH >>>\n%s\n",
|
">>> SSDP SEND M-SEARCH >>>\n%s\n",
|
||||||
ReqBufv4);
|
ReqBufv4);
|
||||||
sendto(gSsdpReqSocket4,
|
sendto(gSsdpReqSocket4,
|
||||||
ReqBufv4, strlen(ReqBufv4), 0,
|
ReqBufv4, strlen(ReqBufv4), 0,
|
||||||
(struct sockaddr *)&__ss_v4,
|
(struct sockaddr *)&__ss_v4,
|
||||||
sizeof(struct sockaddr_in));
|
sizeof(struct sockaddr_in));
|
||||||
NumCopy++;
|
NumCopy++;
|
||||||
imillisleep(SSDP_PAUSE);
|
imillisleep(SSDP_PAUSE);
|
||||||
}
|
}
|
||||||
@ -644,7 +581,7 @@ int SearchByTarget(
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* EXCLUDE_SSDP */
|
#endif /* EXCLUDE_SSDP */
|
||||||
#endif /* INCLUDE_CLIENT_APIS */
|
#endif /* INCLUDE_CLIENT_APIS */
|
||||||
|
|
||||||
|
/* @} SSDPlib */
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user