Doxygenation of SSDP library.

This commit is contained in:
Marcelo Roberto Jimenez 2010-12-19 13:30:32 -02:00
parent 704dca3df1
commit 04d64a893b
8 changed files with 1503 additions and 1986 deletions

View File

@ -1,3 +1,6 @@
#ifndef UPNP_H
#define UPNP_H
/******************************************************************************* /*******************************************************************************
* *
* Copyright (c) 2000-2003 Intel Corporation * Copyright (c) 2000-2003 Intel Corporation
@ -29,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
* *

View File

@ -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);
} }
} }

View File

@ -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;
}

View File

@ -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. *
* * \return 0 if successful, -1 otherwise.
* 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( 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 */

View File

@ -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 */

View File

@ -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
@ -598,53 +535,53 @@ int SearchByTarget(
return UPNP_E_INTERNAL_ERROR; return UPNP_E_INTERNAL_ERROR;
} }
#ifdef UPNP_ENABLE_IPV6 #ifdef UPNP_ENABLE_IPV6
if (gSsdpReqSocket6 != INVALID_SOCKET && if (gSsdpReqSocket6 != INVALID_SOCKET &&
FD_ISSET(gSsdpReqSocket6, &wrSet)) { FD_ISSET(gSsdpReqSocket6, &wrSet)) {
int NumCopy = 0; int NumCopy = 0;
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);
} }
} }
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