ssdp, soap, genlib: fix compiler warnings.

This commit is contained in:
Marcelo Roberto Jimenez 2010-11-20 19:08:20 -02:00
parent 594c611a33
commit c449fd1521
11 changed files with 1089 additions and 1349 deletions

View File

@ -117,7 +117,7 @@ static int sock_read_write(
fd_set readSet; fd_set readSet;
fd_set writeSet; fd_set writeSet;
struct timeval timeout; struct timeval timeout;
int numBytes; long numBytes;
time_t start_time = time(NULL); time_t start_time = time(NULL);
SOCKET sockfd = info->socket; SOCKET sockfd = info->socket;
long bytes_sent = 0, byte_left = 0, num_written; long bytes_sent = 0, byte_left = 0, num_written;
@ -164,7 +164,7 @@ static int sock_read_write(
#endif #endif
if (bRead) { if (bRead) {
/* read data. */ /* read data. */
numBytes = recv(sockfd, buffer, bufsize, MSG_NOSIGNAL); numBytes = (long)recv(sockfd, buffer, bufsize, MSG_NOSIGNAL);
} else { } else {
byte_left = bufsize; byte_left = bufsize;
bytes_sent = 0; bytes_sent = 0;

View File

@ -718,10 +718,10 @@ getSubElement( const char *element_name,
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
service_info * service_info *getServiceList(
getServiceList( IXML_Node * node, IXML_Node *node,
service_info ** end, service_info **end,
char *URLBase ) char *URLBase)
{ {
IXML_Node *serviceList = NULL; IXML_Node *serviceList = NULL;
IXML_Node *current_service = NULL; IXML_Node *current_service = NULL;
@ -737,43 +737,32 @@ getServiceList( IXML_Node * node,
service_info *current = NULL; service_info *current = NULL;
service_info *previous = NULL; service_info *previous = NULL;
IXML_NodeList *serviceNodeList = NULL; IXML_NodeList *serviceNodeList = NULL;
int NumOfServices = 0; long unsigned int NumOfServices = 0;
int i = 0; long unsigned int i = 0;
int fail = 0; int fail = 0;
if( getSubElement( "UDN", node, &UDN ) && if (getSubElement("UDN", node, &UDN) &&
getSubElement( "serviceList", node, &serviceList ) ) { getSubElement("serviceList", node, &serviceList)) {
serviceNodeList = ixmlElement_getElementsByTagName(
serviceNodeList = ixmlElement_getElementsByTagName( ( IXML_Element (IXML_Element *)serviceList, "service");
* ) if (serviceNodeList != NULL) {
serviceList, NumOfServices = ixmlNodeList_length(serviceNodeList);
"service" ); for (i = 0; i < NumOfServices; i++) {
current_service =
if( serviceNodeList != NULL ) { ixmlNodeList_item(serviceNodeList, i);
NumOfServices = ixmlNodeList_length( serviceNodeList );
for( i = 0; i < NumOfServices; i++ ) {
current_service = ixmlNodeList_item( serviceNodeList, i );
fail = 0; fail = 0;
if (current) {
if( current ) { current->next = malloc(sizeof(service_info));
current->next =
( service_info * )
malloc( sizeof( service_info ) );
previous = current; previous = current;
current = current->next; current = current->next;
} else { } else {
head = head = malloc(sizeof(service_info));
( service_info * )
malloc( sizeof( service_info ) );
current = head; current = head;
} }
if (!current) {
if( !current ) { freeServiceList(head);
freeServiceList( head );
return NULL; return NULL;
} }
current->next = NULL; current->next = NULL;
current->controlURL = NULL; current->controlURL = NULL;
current->eventURL = NULL; current->eventURL = NULL;
@ -783,99 +772,65 @@ getServiceList( IXML_Node * node,
current->active = 1; current->active = 1;
current->subscriptionList = NULL; current->subscriptionList = NULL;
current->TotalSubscriptions = 0; current->TotalSubscriptions = 0;
if (!(current->UDN = getElementValue(UDN)))
if( !( current->UDN = getElementValue( UDN ) ) )
fail = 1; fail = 1;
if (!getSubElement("serviceType", current_service, &serviceType) ||
if( ( !getSubElement( "serviceType", current_service, !(current->serviceType = getElementValue(serviceType)))
&serviceType ) ) ||
( !( current->serviceType =
getElementValue( serviceType ) ) ) )
fail = 1; fail = 1;
if (!getSubElement("serviceId", current_service, &serviceId) ||
if( ( !getSubElement( "serviceId", current_service, !(current->serviceId = getElementValue(serviceId)))
&serviceId ) ) ||
( !
( current->serviceId =
getElementValue( serviceId ) ) ) )
fail = 1; fail = 1;
if (!getSubElement("SCPDURL", current_service, &SCPDURL) ||
if( ( ! !(tempDOMString = getElementValue(SCPDURL)) ||
( getSubElement !(current->SCPDURL = resolve_rel_url(URLBase, tempDOMString)))
( "SCPDURL", current_service, &SCPDURL ) ) )
|| ( !( tempDOMString = getElementValue( SCPDURL ) ) )
||
( !
( current->SCPDURL =
resolve_rel_url( URLBase, tempDOMString ) ) ) )
fail = 1; fail = 1;
ixmlFreeDOMString(tempDOMString);
ixmlFreeDOMString( tempDOMString );
tempDOMString = NULL; tempDOMString = NULL;
if (!(getSubElement("controlURL", current_service, &controlURL)) ||
if( ( ! !(tempDOMString = getElementValue(controlURL)) ||
( getSubElement !(current->controlURL = resolve_rel_url(URLBase, tempDOMString))) {
( "controlURL", current_service, &controlURL ) ) ) UpnpPrintf(UPNP_INFO, GENA, __FILE__,
|| __LINE__,
( !( tempDOMString = getElementValue( controlURL ) ) ) "BAD OR MISSING CONTROL URL");
|| UpnpPrintf(UPNP_INFO, GENA, __FILE__,
( ! __LINE__,
( current->controlURL = "CONTROL URL SET TO NULL IN SERVICE INFO");
resolve_rel_url( URLBase, tempDOMString ) ) ) ) {
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"BAD OR MISSING CONTROL URL" );
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"CONTROL URL SET TO NULL IN SERVICE INFO" );
current->controlURL = NULL; current->controlURL = NULL;
fail = 0; fail = 0;
} }
ixmlFreeDOMString(tempDOMString);
ixmlFreeDOMString( tempDOMString );
tempDOMString = NULL; tempDOMString = NULL;
if (!getSubElement("eventSubURL", current_service, &eventURL) ||
if( ( ! !(tempDOMString = getElementValue(eventURL)) ||
( getSubElement !(current->eventURL = resolve_rel_url(URLBase, tempDOMString))) {
( "eventSubURL", current_service, &eventURL ) ) ) UpnpPrintf(UPNP_INFO, GENA, __FILE__,
|| ( !( tempDOMString = getElementValue( eventURL ) ) ) __LINE__,
|| "BAD OR MISSING EVENT URL");
( ! UpnpPrintf(UPNP_INFO, GENA, __FILE__,
( current->eventURL = __LINE__,
resolve_rel_url( URLBase, tempDOMString ) ) ) ) { "EVENT URL SET TO NULL IN SERVICE INFO");
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"BAD OR MISSING EVENT URL" );
UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"EVENT URL SET TO NULL IN SERVICE INFO" );
current->eventURL = NULL; current->eventURL = NULL;
fail = 0; fail = 0;
} }
ixmlFreeDOMString(tempDOMString);
ixmlFreeDOMString( tempDOMString );
tempDOMString = NULL; tempDOMString = NULL;
if (fail) {
if( fail ) { freeServiceList(current);
freeServiceList( current ); if (previous)
if( previous )
previous->next = NULL; previous->next = NULL;
else else
head = NULL; head = NULL;
current = previous; current = previous;
} }
} }
ixmlNodeList_free(serviceNodeList);
ixmlNodeList_free( serviceNodeList );
} }
(*end) = current;
( *end ) = current;
return head; return head;
} else { } else {
( *end ) = NULL; (*end) = NULL;
return NULL; return NULL;
} }
} }
/************************************************************************ /************************************************************************
@ -905,32 +860,30 @@ getAllServiceList( IXML_Node * node,
IXML_NodeList *deviceList = NULL; IXML_NodeList *deviceList = NULL;
IXML_Node *currentDevice = NULL; IXML_Node *currentDevice = NULL;
int NumOfDevices = 0; long unsigned int NumOfDevices = 0;
int i = 0; long unsigned int i = 0;
( *out_end ) = NULL; (*out_end) = NULL;
deviceList = deviceList = ixmlElement_getElementsByTagName(
ixmlElement_getElementsByTagName( ( IXML_Element * ) node, (IXML_Element *)node, "device");
"device" ); if (deviceList) {
if( deviceList != NULL ) { NumOfDevices = ixmlNodeList_length(deviceList);
NumOfDevices = ixmlNodeList_length( deviceList ); for (i = 0; i < NumOfDevices; i++) {
for( i = 0; i < NumOfDevices; i++ ) { currentDevice = ixmlNodeList_item(deviceList, i);
currentDevice = ixmlNodeList_item( deviceList, i ); if (head) {
if( head ) { end->next = getServiceList(currentDevice,
end->next = &next_end, URLBase);
getServiceList( currentDevice, &next_end, URLBase ); if (next_end)
if ( next_end )
end = next_end; end = next_end;
} else } else
head = getServiceList( currentDevice, &end, URLBase ); head = getServiceList(currentDevice, &end,
URLBase);
}
ixmlNodeList_free(deviceList);
} }
ixmlNodeList_free( deviceList ); (*out_end) = end;
}
( *out_end ) = end;
return head; return head;
} }
@ -963,8 +916,8 @@ removeServiceTable( IXML_Node * node,
service_info *current_service = NULL; service_info *current_service = NULL;
service_info *start_search = NULL; service_info *start_search = NULL;
service_info *prev_service = NULL; service_info *prev_service = NULL;
int NumOfDevices = 0; long unsigned int NumOfDevices = 0;
int i = 0; long unsigned int i = 0;
if( getSubElement( "root", node, &root ) ) { if( getSubElement( "root", node, &root ) ) {
current_service = in->serviceList; current_service = in->serviceList;

View File

@ -311,28 +311,26 @@ membuffer_destroy( INOUT membuffer * m )
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
int int membuffer_assign( INOUT membuffer * m,
membuffer_assign( INOUT membuffer * m,
IN const void *buf, IN const void *buf,
IN size_t buf_len ) IN size_t buf_len )
{ {
int return_code; int return_code;
assert( m != NULL ); assert(m != NULL);
/* set value to null */ /* set value to null */
if( buf == NULL ) { if (buf == NULL) {
membuffer_destroy( m ); membuffer_destroy(m);
return 0; return 0;
} }
/* alloc mem */ /* alloc mem */
return_code = membuffer_set_size( m, buf_len ); return_code = membuffer_set_size(m, buf_len);
if( return_code != 0 ) { if (return_code != 0)
return return_code; return return_code;
}
/* copy */ /* copy */
if( buf_len ) { if (buf_len) {
memcpy( m->buf, buf, buf_len ); memcpy(m->buf, buf, buf_len);
m->buf[buf_len] = 0; /* null-terminate */ m->buf[buf_len] = 0; /* null-terminate */
} }
m->length = buf_len; m->length = buf_len;
@ -411,53 +409,29 @@ membuffer_append_str( INOUT membuffer * m,
return membuffer_insert( m, c_str, strlen( c_str ), m->length ); return membuffer_insert( m, c_str, strlen( c_str ), m->length );
} }
/************************************************************************ int membuffer_insert(membuffer *m, const void *buf, size_t buf_len, size_t index)
* Function : membuffer_insert
*
* Parameters :
* INOUT membuffer* m ; buffer whose memory size is to be increased
* and appended.
* IN const void* buf ; source buffer whose contents will be
* copied
* IN size_t buf_len ; size of the source buffer
* int index ; index to determine the bounds while movinf the data
*
* Description : Allocates memory for the new data to be inserted. Does
* memory management by moving the data from the existing memory to
* the newly allocated memory and then appending the new data.
*
* Return : int ;
*
* Note :
************************************************************************/
int
membuffer_insert( INOUT membuffer * m,
IN const void *buf,
IN size_t buf_len,
int index )
{ {
int return_code; int return_code;
assert( m != NULL ); assert(m != NULL);
if( index < 0 || index > ( int )m->length ) if (index > m->length)
return UPNP_E_OUTOF_BOUNDS; return UPNP_E_OUTOF_BOUNDS;
if (!buf || !buf_len) {
if( buf == NULL || buf_len == 0 ) {
return 0; return 0;
} }
/* alloc mem */ /* alloc mem */
return_code = membuffer_set_size( m, m->length + buf_len ); return_code = membuffer_set_size(m, m->length + buf_len);
if( return_code != 0 ) { if (return_code) {
return return_code; return return_code;
} }
/* insert data */ /* insert data */
/* move data to right of insertion point */ /* move data to right of insertion point */
memmove( m->buf + index + buf_len, m->buf + index, m->length - index ); memmove(m->buf + index + buf_len, m->buf + index, m->length - index);
memcpy( m->buf + index, buf, buf_len ); memcpy(m->buf + index, buf, buf_len);
m->length += buf_len; m->length += buf_len;
m->buf[m->length] = 0; /* null-terminate */ /* null-terminate */
m->buf[m->length] = 0;
return 0; return 0;
} }
@ -465,7 +439,7 @@ membuffer_insert( INOUT membuffer * m,
void membuffer_delete(membuffer *m, size_t index, size_t num_bytes) void membuffer_delete(membuffer *m, size_t index, size_t num_bytes)
{ {
int return_value; int return_value;
int new_length; size_t new_length;
size_t copy_len; size_t copy_len;
assert(m != NULL); assert(m != NULL);

View File

@ -58,7 +58,7 @@ void namecopy(char dest[NAME_SIZE], const char *src)
void linecopylen(char dest[LINE_SIZE], const char *src, size_t srclen) void linecopylen(char dest[LINE_SIZE], const char *src, size_t srclen)
{ {
int len; size_t len;
len = srclen < (LINE_SIZE - 1) ? srclen : (LINE_SIZE - 1); len = srclen < (LINE_SIZE - 1) ? srclen : (LINE_SIZE - 1);
strncpy(dest, src, len); strncpy(dest, src, len);

View File

@ -257,26 +257,22 @@ int membuffer_append( INOUT membuffer* m, IN const void* buf, IN size_t buf_len
************************************************************************/ ************************************************************************/
int membuffer_append_str( INOUT membuffer* m, IN const char* c_str ); int membuffer_append_str( INOUT membuffer* m, IN const char* c_str );
/************************************************************************ /*!
* Function : membuffer_insert * \brief Allocates memory for the new data to be inserted. Does
* * memory management by moving the data from the existing memory to
* Parameters : * the newly allocated memory and then appending the new data.
* INOUT membuffer* m ; buffer whose memory size is to be increased *
* and appended. * \return 0 if successful, error code if error.
* IN const void* buf ; source buffer whose contents will be */
* copied int membuffer_insert(
* IN size_t buf_len ; size of the source buffer /* [in,out] Buffer whose memory size is to be increased and appended. */
* int index ; index to determine the bounds while movinf the data membuffer *m,
* /* [in] source buffer whose contents will be copied. */
* Description : Allocates memory for the new data to be inserted. Does const void *buf,
* memory management by moving the data from the existing memory to /* [in] size of the source buffer. */
* the newly allocated memory and then appending the new data. size_t buf_len,
* /* [in] index to determine the bounds while movinf the data. */
* Return : int ; size_t index);
*
* Note :
************************************************************************/
int membuffer_insert( INOUT membuffer* m, IN const void* buf, IN size_t buf_len, int index );
/*! /*!

View File

@ -234,7 +234,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* 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 int 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.
* This cookie will be returned to the control point * This cookie will be returned to the control point
@ -251,7 +251,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 *dest_addr, IN struct sockaddr *dest_addr,
IN xboolean timeout, IN int timeout,
IN void *cookie); IN void *cookie);
/************************************************************************ /************************************************************************

View File

@ -58,145 +58,115 @@
#define SOAP_ACTION_RESP_ERROR 3 #define SOAP_ACTION_RESP_ERROR 3
#define SOAP_VAR_RESP_ERROR 4 #define SOAP_VAR_RESP_ERROR 4
/**************************************************************************** /*!
* Function : dom_cmp_name * \brief Compares 'name' and node's name.
* *
* Parameters : * \return 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY.
* IN char *name : lookup name */
* IN IXML_Node *node : xml node static int dom_cmp_name(
* /* [in] lookup name. */
* Description : This function compares 'name' and node's name const char *name,
* /* [in] xml node. */
* Return : int IXML_Node *node)
* 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY
*
* Note :
****************************************************************************/
static int
dom_cmp_name( IN char *name,
IN IXML_Node * node )
{ {
const DOMString node_name = NULL; const DOMString node_name = NULL;
memptr nameptr, memptr nameptr;
dummy; memptr dummy;
int ret_code; int ret_code;
assert( name ); assert(name);
assert( node ); assert(node);
node_name = ixmlNode_getNodeName( node ); node_name = ixmlNode_getNodeName(node);
if( node_name == NULL ) { if (node_name == NULL)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} if (strcmp(name, node_name) == 0)
if( strcmp( name, node_name ) == 0 ) {
ret_code = 0; ret_code = 0;
} else if( matchstr( ( char * )node_name, strlen( node_name ), else if (matchstr((char *)node_name, strlen(node_name),
"%s:%s%0", &dummy, &nameptr ) == PARSE_OK && "%s:%s%0", &dummy, &nameptr) == PARSE_OK &&
strcmp( nameptr.buf, name ) == 0 ) { strcmp(nameptr.buf, name) == 0)
ret_code = 0; ret_code = 0;
} else { else
ret_code = 1; /* names are not the same */ /* names are not the same */
} ret_code = 1;
return ret_code; return ret_code;
} }
/**************************************************************************** /*!
* Function : dom_find_node * \brief Goes thru each child of 'start_node' looking for a node having
* * the name 'node_name'.
* Parameters : *
* IN char* node_name : name of the node * \return UPNP_E_SUCCESS if successful else returns appropriate error.
* IN IXML_Node *start_node : complete xml node */
* OUT IXML_Node ** matching_node : matched node static int dom_find_node(
* /* [in] name of the node. */
* Description : This function goes thru each child of 'start_node' const char *node_name,
* looking for a node having the name 'node_name'. /* [in] complete xml node. */
* IXML_Node *start_node,
* Return : int /* [out] matched node. */
* return UPNP_E_SUCCESS if successful else returns appropriate error IXML_Node **matching_node)
*
* Note :
****************************************************************************/
static int
dom_find_node( IN char *node_name,
IN IXML_Node * start_node,
OUT IXML_Node ** matching_node )
{ {
IXML_Node *node; IXML_Node *node;
/* invalid args */ /* invalid args */
if( node_name == NULL || start_node == NULL ) { if (!node_name || !start_node)
return UPNP_E_NOT_FOUND; return UPNP_E_NOT_FOUND;
} node = ixmlNode_getFirstChild(start_node);
while (node != NULL) {
node = ixmlNode_getFirstChild( start_node );
while( node != NULL ) {
/* match name */ /* match name */
if( dom_cmp_name( node_name, node ) == 0 ) { if (dom_cmp_name(node_name, node) == 0) {
*matching_node = node; *matching_node = node;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/* free and next node */ /* free and next node */
node = ixmlNode_getNextSibling( node ); /* next node */ node = ixmlNode_getNextSibling(node);
} }
return UPNP_E_NOT_FOUND; return UPNP_E_NOT_FOUND;
} }
/**************************************************************************** /*!
* Function : dom_find_deep_node * \brief Searches for the node specifed by the last name in the 'name' array.
* *
* Parameters : * \return UPNP_E_SUCCESS if successful, else returns appropriate error.
* IN char* names[] : array of names */
* IN int num_names : size of array static int dom_find_deep_node(
* IN IXML_Node *start_node : Node from where it should should be /* [in] array of names. */
* searched const char *names[],
* OUT IXML_Node ** matching_node : Node that matches the last name /* [in] size of array. */
* of the array int num_names,
* /* [in] Node from where it should should be searched. */
* Description : This function searches for the node specifed by the last IXML_Node *start_node,
* name in the 'name' array. /* [out] Node that matches the last name of the array. */
* IXML_Node **matching_node)
* Return : int
* return UPNP_E_SUCCESS if successful else returns appropriate error
* Note :
****************************************************************************/
static int
dom_find_deep_node( IN char *names[],
IN int num_names,
IN IXML_Node * start_node,
OUT IXML_Node ** matching_node )
{ {
int i; int i;
IXML_Node *node; IXML_Node *node;
IXML_Node *match_node; IXML_Node *match_node;
assert( num_names > 0 ); assert(num_names > 0);
node = start_node; node = start_node;
if( dom_cmp_name( names[0], start_node ) == 0 ) { if (dom_cmp_name(names[0], start_node) == 0) {
if( num_names == 1 ) { if (num_names == 1) {
*matching_node = start_node; *matching_node = start_node;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
} }
for (i = 1; i < num_names; i++) {
for( i = 1; i < num_names; i++ ) { if (dom_find_node(names[i], node, &match_node) != UPNP_E_SUCCESS)
if( dom_find_node( names[i], node, &match_node ) !=
UPNP_E_SUCCESS ) {
return UPNP_E_NOT_FOUND; return UPNP_E_NOT_FOUND;
} if (i == num_names - 1) {
if( i == num_names - 1 ) {
*matching_node = match_node; *matching_node = match_node;
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
/* try again */
node = match_node; /* try again */ node = match_node;
} }
return UPNP_E_NOT_FOUND; /* this line not reached */ /* this line not reached */
return UPNP_E_NOT_FOUND;
} }
/**************************************************************************** /****************************************************************************
@ -290,39 +260,30 @@ get_action_name( IN char *action,
return ret_code == PARSE_OK ? 0 : -1; return ret_code == PARSE_OK ? 0 : -1;
} }
/**************************************************************************** /*!
* Function : add_man_header * \brief Adds "MAN" field in the HTTP header.
* *
* Parameters : * \return 0 on success, UPNP_E_OUTOFMEMORY on error.
* INOUT membuffer* headers : HTTP header */
* static UPNP_INLINE int add_man_header(
* Description : This function adds "MAN" field in the HTTP header /* [in,out] HTTP header. */
* membuffer *headers)
* Return : int
* returns 0 on success; UPNP_E_OUTOFMEMORY on error
*
* Note :
****************************************************************************/
static UPNP_INLINE int
add_man_header( INOUT membuffer * headers )
{ {
size_t n;
char *soap_action_hdr; char *soap_action_hdr;
char *man_hdr = "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; " const char *man_hdr =
"ns=01\r\n01-"; "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; ns=01\r\n01-";
/* change POST to M-POST */ /* change POST to M-POST */
if( membuffer_insert( headers, "M-", 2, 0 ) != 0 ) { if (membuffer_insert(headers, "M-", 2, 0) != 0)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} soap_action_hdr = strstr(headers->buf, "SOAPACTION:");
/* can't fail */
soap_action_hdr = strstr( headers->buf, "SOAPACTION:" ); assert(soap_action_hdr != NULL);
assert( soap_action_hdr != NULL ); /* can't fail */
/* insert MAN header */ /* insert MAN header */
if( membuffer_insert( headers, man_hdr, strlen( man_hdr ), n = (size_t)(soap_action_hdr - headers->buf);
soap_action_hdr - headers->buf ) != 0 ) { if (membuffer_insert(headers, man_hdr, strlen(man_hdr), n))
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
}
return 0; return 0;
} }
@ -418,140 +379,109 @@ get_response_value( IN http_message_t * hmsg,
char *node_str = NULL; char *node_str = NULL;
const char *temp_str = NULL; const char *temp_str = NULL;
DOMString error_node_str = NULL; DOMString error_node_str = NULL;
int err_code; int err_code = UPNP_E_BAD_RESPONSE; /* default error */ ;
xboolean done = FALSE; int done = FALSE;
char *names[5]; const char *names[5];
const DOMString nodeValue; const DOMString nodeValue;
err_code = UPNP_E_BAD_RESPONSE; /* default error */
/* only 200 and 500 status codes are relevant */ /* only 200 and 500 status codes are relevant */
if( ( hmsg->status_code != HTTP_OK && if ((hmsg->status_code != HTTP_OK &&
hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) || hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR) ||
!has_xml_content_type( hmsg ) ) { !has_xml_content_type(hmsg))
goto error_handler; goto error_handler;
} if (ixmlParseBufferEx(hmsg->entity.buf, &doc) != IXML_SUCCESS)
if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {
goto error_handler; goto error_handler;
} root_node = ixmlNode_getFirstChild((IXML_Node *) doc);
if (root_node == NULL)
root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );
if( root_node == NULL ) {
goto error_handler; goto error_handler;
} if (code == SOAP_ACTION_RESP) {
if( code == SOAP_ACTION_RESP ) {
/* */
/* try reading soap action response */ /* try reading soap action response */
/* */ assert(action_value != NULL);
assert( action_value != NULL );
*action_value = NULL; *action_value = NULL;
names[0] = "Envelope"; names[0] = "Envelope";
names[1] = "Body"; names[1] = "Body";
names[2] = name; names[2] = name;
if( dom_find_deep_node( names, 3, root_node, &node ) == if (dom_find_deep_node(names, 3, root_node, &node) ==
UPNP_E_SUCCESS ) { UPNP_E_SUCCESS) {
node_str = ixmlPrintNode( node ); node_str = ixmlPrintNode(node);
if( node_str == NULL ) { if (node_str == NULL) {
err_code = UPNP_E_OUTOF_MEMORY; err_code = UPNP_E_OUTOF_MEMORY;
goto error_handler; goto error_handler;
} }
if (ixmlParseBufferEx(node_str,
if( ixmlParseBufferEx( node_str, (IXML_Document **) action_value)
( IXML_Document ** ) action_value ) != != IXML_SUCCESS) {
IXML_SUCCESS ) {
err_code = UPNP_E_BAD_RESPONSE; err_code = UPNP_E_BAD_RESPONSE;
goto error_handler; goto error_handler;
} }
err_code = SOAP_ACTION_RESP; err_code = SOAP_ACTION_RESP;
done = TRUE; done = TRUE;
} }
} else if( code == SOAP_VAR_RESP ) { } else if (code == SOAP_VAR_RESP) {
/* try reading var response */ /* try reading var response */
assert( str_value != NULL ); assert(str_value != NULL);
*str_value = NULL;
*str_value = NULL;
names[0] = "Envelope"; names[0] = "Envelope";
names[1] = "Body"; names[1] = "Body";
names[2] = "QueryStateVariableResponse"; names[2] = "QueryStateVariableResponse";
names[3] = "return"; names[3] = "return";
if( dom_find_deep_node( names, 4, root_node, &node ) if (dom_find_deep_node(names, 4, root_node, &node)
== UPNP_E_SUCCESS ) { == UPNP_E_SUCCESS) {
nodeValue = get_node_value( node ); nodeValue = get_node_value(node);
if( nodeValue == NULL ) { if (nodeValue == NULL)
goto error_handler; goto error_handler;
} *str_value = ixmlCloneDOMString(nodeValue);
*str_value = ixmlCloneDOMString( nodeValue );
err_code = SOAP_VAR_RESP; err_code = SOAP_VAR_RESP;
done = TRUE; done = TRUE;
} }
} }
if (!done) {
if( !done ) {
/* not action or var resp; read error code and description */ /* not action or var resp; read error code and description */
*str_value = NULL; *str_value = NULL;
names[0] = "Envelope"; names[0] = "Envelope";
names[1] = "Body"; names[1] = "Body";
names[2] = "Fault"; names[2] = "Fault";
names[3] = "detail"; names[3] = "detail";
names[4] = "UPnPError"; names[4] = "UPnPError";
if( dom_find_deep_node( names, 5, root_node, &error_node ) if (dom_find_deep_node(names, 5, root_node, &error_node) !=
!= UPNP_E_SUCCESS ) { UPNP_E_SUCCESS)
goto error_handler; goto error_handler;
} if (dom_find_node("errorCode", error_node, &node) !=
UPNP_E_SUCCESS)
if( dom_find_node( "errorCode", error_node, &node )
!= UPNP_E_SUCCESS ) {
goto error_handler; goto error_handler;
} temp_str = get_node_value(node);
if (!temp_str)
temp_str = get_node_value( node );
if( temp_str == NULL ) {
goto error_handler; goto error_handler;
} *upnp_error_code = atoi(temp_str);
if (*upnp_error_code < 400) {
*upnp_error_code = atoi( temp_str );
if( *upnp_error_code < 400 ) {
err_code = *upnp_error_code; err_code = *upnp_error_code;
goto error_handler; /* bad SOAP error code */ goto error_handler; /* bad SOAP error code */
} }
if (code == SOAP_VAR_RESP) {
if( code == SOAP_VAR_RESP ) { if (dom_find_node("errorDescription", error_node, &node)
if( dom_find_node( "errorDescription", error_node, &node ) != UPNP_E_SUCCESS) {
!= UPNP_E_SUCCESS ) {
goto error_handler; goto error_handler;
} }
nodeValue = get_node_value(node);
nodeValue = get_node_value( node ); if (nodeValue == NULL) {
if( nodeValue == NULL ) {
goto error_handler; goto error_handler;
} }
*str_value = ixmlCloneDOMString( nodeValue ); *str_value = ixmlCloneDOMString(nodeValue);
if( *str_value == NULL ) { if (*str_value == NULL) {
goto error_handler; goto error_handler;
} }
err_code = SOAP_VAR_RESP_ERROR; err_code = SOAP_VAR_RESP_ERROR;
} } else if (code == SOAP_ACTION_RESP) {
error_node_str = ixmlPrintNode(error_node);
else if( code == SOAP_ACTION_RESP ) { if (error_node_str == NULL) {
error_node_str = ixmlPrintNode( error_node );
if( error_node_str == NULL ) {
err_code = UPNP_E_OUTOF_MEMORY; err_code = UPNP_E_OUTOF_MEMORY;
goto error_handler; goto error_handler;
} }
if (ixmlParseBufferEx(error_node_str,
if( ixmlParseBufferEx( error_node_str, (IXML_Document **) action_value)
( IXML_Document ** ) action_value ) != != IXML_SUCCESS) {
IXML_SUCCESS ) {
err_code = UPNP_E_BAD_RESPONSE; err_code = UPNP_E_BAD_RESPONSE;
goto error_handler; goto error_handler;
@ -561,10 +491,9 @@ get_response_value( IN http_message_t * hmsg,
} }
error_handler: error_handler:
ixmlDocument_free(doc);
ixmlDocument_free( doc ); ixmlFreeDOMString(node_str);
ixmlFreeDOMString( node_str ); ixmlFreeDOMString(error_node_str);
ixmlFreeDOMString( error_node_str );
return err_code; return err_code;
} }
@ -601,15 +530,15 @@ SoapSendAction( IN char *action_url,
uri_type url; uri_type url;
int upnp_error_code; int upnp_error_code;
char *upnp_error_str; char *upnp_error_str;
xboolean got_response = FALSE; int got_response = FALSE;
off_t content_length; off_t content_length;
char *xml_start = const char *xml_start =
"<s:Envelope " "<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
"<s:Body>"; "<s:Body>";
char *xml_end = const char *xml_end =
"</s:Body>\r\n" "</s:Body>\r\n"
"</s:Envelope>\r\n\r\n"; "</s:Envelope>\r\n\r\n";
size_t xml_start_len; size_t xml_start_len;
@ -655,7 +584,7 @@ SoapSendAction( IN char *action_url,
/* make request msg */ /* make request msg */
request.size_inc = 50; request.size_inc = 50;
content_length = xml_start_len + action_str_len + xml_end_len; content_length = (off_t)(xml_start_len + action_str_len + xml_end_len);
if (http_MakeMessage( if (http_MakeMessage(
&request, 1, 1, &request, 1, 1,
"q" "N" "s" "sssbsc" "Uc" "b" "b" "b", "q" "N" "s" "sssbsc" "Uc" "b" "b" "b",
@ -725,8 +654,8 @@ error_handler:
* returns UPNP_E_SUCCESS if successful else returns appropriate error * returns UPNP_E_SUCCESS if successful else returns appropriate error
* Note : * Note :
****************************************************************************/ ****************************************************************************/
int int SoapSendActionEx(
SoapSendActionEx( IN char *action_url, IN char *action_url,
IN char *service_type, IN char *service_type,
IN IXML_Document * header, IN IXML_Document * header,
IN IXML_Document * action_node, IN IXML_Document * action_node,
@ -743,19 +672,18 @@ SoapSendActionEx( IN char *action_url,
uri_type url; uri_type url;
int upnp_error_code; int upnp_error_code;
char *upnp_error_str; char *upnp_error_str;
xboolean got_response = FALSE; int got_response = FALSE;
const char *xml_start =
char *xml_start =
"<s:Envelope " "<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"; "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n";
char *xml_header_start = const char *xml_header_start =
"<s:Header>\r\n"; "<s:Header>\r\n";
char *xml_header_end = const char *xml_header_end =
"</s:Header>\r\n"; "</s:Header>\r\n";
char *xml_body_start = const char *xml_body_start =
"<s:Body>"; "<s:Body>";
char *xml_end = const char *xml_end =
"</s:Body>\r\n" "</s:Body>\r\n"
"</s:Envelope>\r\n"; "</s:Envelope>\r\n";
size_t xml_start_len; size_t xml_start_len;
@ -816,10 +744,9 @@ SoapSendActionEx( IN char *action_url,
/* make request msg */ /* make request msg */
request.size_inc = 50; request.size_inc = 50;
content_length = content_length = (off_t)(xml_start_len + xml_header_start_len +
xml_start_len + xml_header_str_len + xml_header_end_len +
xml_header_start_len + xml_header_str_len + xml_header_end_len + xml_body_start_len + action_str_len + xml_end_len);
xml_body_start_len + action_str_len + xml_end_len;
if (http_MakeMessage( if (http_MakeMessage(
&request, 1, 1, &request, 1, 1,
"q" "N" "s" "sssbsc" "Uc" "b" "b" "b" "b" "b" "b" "b", "q" "N" "s" "sssbsc" "Uc" "b" "b" "b" "b" "b" "b" "b",
@ -903,33 +830,30 @@ SoapGetServiceVarStatus( IN char *action_url,
int ret_code; int ret_code;
http_parser_t response; http_parser_t response;
int upnp_error_code; int upnp_error_code;
off_t content_length; off_t content_length;
char *xml_start = const char *xml_start =
"<s:Envelope " "<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"
"<s:Body>\r\n" "<s:Body>\r\n"
"<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n" "<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n"
"<u:varName>"; "<u:varName>";
const char *xml_end =
char *xml_end =
"</u:varName>\r\n" "</u:varName>\r\n"
"</u:QueryStateVariable>\r\n" "</u:QueryStateVariable>\r\n"
"</s:Body>\r\n" "</s:Body>\r\n"
"</s:Envelope>\r\n"; "</s:Envelope>\r\n";
*var_value = NULL; /* return NULL in case of an error */ *var_value = NULL; /* return NULL in case of an error */
membuffer_init( &request ); membuffer_init( &request );
/* get host hdr and url path */ /* get host hdr and url path */
if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) { if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) {
return UPNP_E_INVALID_URL; return UPNP_E_INVALID_URL;
} }
/* make headers */ /* make headers */
request.size_inc = 50; request.size_inc = 50;
content_length = strlen( xml_start ) + strlen( var_name ) + strlen( xml_end ); content_length = (off_t)(strlen(xml_start) + strlen(var_name) +
strlen(xml_end));
if (http_MakeMessage( if (http_MakeMessage(
&request, 1, 1, &request, 1, 1,
"Q" "sbc" "N" "s" "sc" "Ucc" "sss", "Q" "sbc" "N" "s" "sc" "Ucc" "sss",
@ -950,9 +874,7 @@ SoapGetServiceVarStatus( IN char *action_url,
/* get variable value from the response */ /* get variable value from the response */
ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL, ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL,
&upnp_error_code, NULL, var_value ); &upnp_error_code, NULL, var_value );
httpmsg_destroy( &response.msg ); httpmsg_destroy( &response.msg );
if( ret_code == SOAP_VAR_RESP ) { if( ret_code == SOAP_VAR_RESP ) {
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} else if( ret_code == SOAP_VAR_RESP_ERROR ) { } else if( ret_code == SOAP_VAR_RESP_ERROR ) {

View File

@ -89,80 +89,66 @@ static UPNP_INLINE int get_request_type(
memptr *action_name) memptr *action_name)
{ {
memptr value; memptr value;
memptr ns_value, memptr ns_value, dummy_quote;
dummy_quote;
http_header_t *hdr; http_header_t *hdr;
char save_char; char save_char;
char *s; char *s;
membuffer soap_action_name; membuffer soap_action_name;
size_t n;
/* find soapaction header */ /* find soapaction header */
if( request->method == SOAPMETHOD_POST ) { if (request->method == SOAPMETHOD_POST) {
if( httpmsg_find_hdr( request, HDR_SOAPACTION, &value ) if (!httpmsg_find_hdr(request, HDR_SOAPACTION, &value))
== NULL ) {
return SREQ_HDR_NOT_FOUND; return SREQ_HDR_NOT_FOUND;
}
} else { } else {
/* M-POST */ /* M-POST */
/* get NS value from MAN header */ /* get NS value from MAN header */
hdr = httpmsg_find_hdr( request, HDR_MAN, &value ); hdr = httpmsg_find_hdr(request, HDR_MAN, &value);
if( hdr == NULL ) { if (hdr == NULL)
return SREQ_HDR_NOT_FOUND; return SREQ_HDR_NOT_FOUND;
} if (matchstr(value.buf, value.length, "%q%i ; ns = %s",
&dummy_quote, &ns_value) != 0)
if( matchstr( value.buf, value.length, "%q%i ; ns = %s",
&dummy_quote, &ns_value ) != 0 ) {
return SREQ_BAD_HDR_FORMAT; return SREQ_BAD_HDR_FORMAT;
}
/* create soapaction name header */ /* create soapaction name header */
membuffer_init( &soap_action_name ); membuffer_init(&soap_action_name);
if( ( membuffer_assign( &soap_action_name, if (membuffer_assign(&soap_action_name,
ns_value.buf, ns_value.length ) ns_value.buf, ns_value.length) == UPNP_E_OUTOF_MEMORY ||
== UPNP_E_OUTOF_MEMORY ) || membuffer_append_str(&soap_action_name,
( membuffer_append_str( &soap_action_name, "-SOAPACTION") == UPNP_E_OUTOF_MEMORY) {
"-SOAPACTION" ) == membuffer_destroy(&soap_action_name);
UPNP_E_OUTOF_MEMORY )
) {
membuffer_destroy( &soap_action_name );
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
hdr = httpmsg_find_hdr_str(request, soap_action_name.buf);
hdr = httpmsg_find_hdr_str( request, soap_action_name.buf ); membuffer_destroy(&soap_action_name);
membuffer_destroy( &soap_action_name ); if (!hdr)
if( hdr == NULL ) {
return SREQ_HDR_NOT_FOUND; return SREQ_HDR_NOT_FOUND;
}
value.buf = hdr->value.buf; value.buf = hdr->value.buf;
value.length = hdr->value.length; value.length = hdr->value.length;
} }
/* determine type */ /* determine type */
save_char = value.buf[value.length]; save_char = value.buf[value.length];
value.buf[value.length] = '\0'; value.buf[value.length] = '\0';
s = strchr(value.buf, '#');
s = strchr( value.buf, '#' ); if (s == NULL) {
if( s == NULL ) {
value.buf[value.length] = save_char; value.buf[value.length] = save_char;
return SREQ_BAD_HDR_FORMAT; return SREQ_BAD_HDR_FORMAT;
} }
/* move to value */ /* move to value */
s++; s++;
n = value.length - (size_t)(s - value.buf);
if( matchstr( s, value.length - ( s - value.buf ), "%s", if (matchstr(s, n, "%s", action_name) != PARSE_OK) {
action_name ) != PARSE_OK ) {
value.buf[value.length] = save_char; value.buf[value.length] = save_char;
return SREQ_BAD_HDR_FORMAT; return SREQ_BAD_HDR_FORMAT;
} }
/* action name or variable ? */ /* action name or variable ? */
if( memptr_cmp( action_name, "QueryStateVariable" ) == 0 ) { if (memptr_cmp(action_name, "QueryStateVariable") == 0) {
/* query variable */ /* query variable */
action_name->buf = NULL; action_name->buf = NULL;
action_name->length = 0; action_name->length = 0;
} }
/* restore */ /* restore */
value.buf[value.length] = save_char; value.buf[value.length] = save_char;
return 0; return 0;
} }
@ -189,8 +175,8 @@ send_error_response( IN SOCKINFO * info,
{ {
off_t content_length; off_t content_length;
int timeout_secs = SOAP_TIMEOUT; int timeout_secs = SOAP_TIMEOUT;
int major, int major;
minor; int minor;
const char *start_body = const char *start_body =
/* "<?xml version=\"1.0\"?>\n" required?? */ /* "<?xml version=\"1.0\"?>\n" required?? */
"<s:Envelope " "<s:Envelope "
@ -203,27 +189,20 @@ send_error_response( IN SOCKINFO * info,
"<detail>\n" "<detail>\n"
"<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n" "<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n"
"<errorCode>"; "<errorCode>";
const char *mid_body = "</errorCode>\n" "<errorDescription>"; const char *mid_body = "</errorCode>\n" "<errorDescription>";
const char *end_body = const char *end_body =
"</errorDescription>\n" "</errorDescription>\n"
"</UPnPError>\n" "</UPnPError>\n"
"</detail>\n" "</s:Fault>\n" "</s:Body>\n" "</s:Envelope>\n"; "</detail>\n" "</s:Fault>\n" "</s:Body>\n" "</s:Envelope>\n";
char err_code_str[30]; char err_code_str[30];
membuffer headers; membuffer headers;
sprintf( err_code_str, "%d", error_code ); sprintf( err_code_str, "%d", error_code );
/* calc body len */ /* calc body len */
content_length = strlen( start_body ) + strlen( err_code_str ) + content_length = (off_t)(strlen(start_body) + strlen(err_code_str) +
strlen( mid_body ) + strlen( err_msg ) + strlen( end_body ); strlen(mid_body) + strlen(err_msg) + strlen(end_body));
http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version,
&major, &minor ); &major, &minor );
/* make headers */ /* make headers */
membuffer_init( &headers ); membuffer_init( &headers );
if (http_MakeMessage( if (http_MakeMessage(
@ -242,7 +221,6 @@ send_error_response( IN SOCKINFO * info,
/* send err msg */ /* send err msg */
http_SendMessage( info, &timeout_secs, "b", http_SendMessage( info, &timeout_secs, "b",
headers.buf, headers.length ); headers.buf, headers.length );
membuffer_destroy( &headers ); membuffer_destroy( &headers );
} }
@ -276,23 +254,18 @@ send_var_query_response( IN SOCKINFO * info,
"<s:Body>\n" "<s:Body>\n"
"<u:QueryStateVariableResponse " "<u:QueryStateVariableResponse "
"xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n" "<return>"; "xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n" "<return>";
const char *end_body = const char *end_body =
"</return>\n" "</return>\n"
"</u:QueryStateVariableResponse>\n" "</u:QueryStateVariableResponse>\n"
"</s:Body>\n" "</s:Envelope>\n"; "</s:Body>\n" "</s:Envelope>\n";
membuffer response; membuffer response;
http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version,
&major, &minor ); &major, &minor );
content_length = (off_t)(strlen(start_body) + strlen(var_value) +
content_length = strlen( start_body ) + strlen( var_value ) + strlen(end_body));
strlen( end_body );
/* make headers */ /* make headers */
membuffer_init( &response ); membuffer_init(&response);
if (http_MakeMessage( if (http_MakeMessage(
&response, major, minor, &response, major, minor,
"RNsDsSXcc" "sss", "RNsDsSXcc" "sss",
@ -302,15 +275,13 @@ send_var_query_response( IN SOCKINFO * info,
"EXT:\r\n", "EXT:\r\n",
X_USER_AGENT, X_USER_AGENT,
start_body, var_value, end_body ) != 0 ) { start_body, var_value, end_body ) != 0 ) {
membuffer_destroy( &response ); membuffer_destroy(&response);
return; /* out of mem */ return; /* out of mem */
} }
/* send msg */ /* send msg */
http_SendMessage( info, &timeout_secs, "b", http_SendMessage(info, &timeout_secs, "b",
response.buf, response.length ); response.buf, response.length);
membuffer_destroy(&response);
membuffer_destroy( &response );
} }
/**************************************************************************** /****************************************************************************
@ -478,77 +449,68 @@ check_soap_action_header( IN http_message_t * request,
memptr header_name; memptr header_name;
http_header_t *soap_action_header = NULL; http_header_t *soap_action_header = NULL;
char *ns_compare = NULL; char *ns_compare = NULL;
int tempSize = 0; size_t tempSize = 0;
int ret_code = UPNP_E_SUCCESS; int ret_code = UPNP_E_SUCCESS;
char *temp_header_value = NULL; char *temp_header_value = NULL;
char *temp = NULL; char *temp = NULL;
char *temp2 = NULL; char *temp2 = NULL;
/* check soap action header */ /* check soap action header */
soap_action_header = httpmsg_find_hdr( request, HDR_SOAPACTION, soap_action_header = httpmsg_find_hdr(request, HDR_SOAPACTION,
&header_name ); &header_name);
if (!soap_action_header) {
if( !soap_action_header ) {
ret_code = UPNP_E_INVALID_ACTION; ret_code = UPNP_E_INVALID_ACTION;
return ret_code; return ret_code;
} }
if (soap_action_header->value.length <= 0) {
if( soap_action_header->value.length <= 0 ) {
ret_code = UPNP_E_INVALID_ACTION; ret_code = UPNP_E_INVALID_ACTION;
return ret_code; return ret_code;
} }
temp_header_value = malloc(soap_action_header->value.length + 1);
temp_header_value = if (!temp_header_value) {
( char * )malloc( soap_action_header->value.length + 1 );
if( !temp_header_value ) {
ret_code = UPNP_E_OUTOF_MEMORY; ret_code = UPNP_E_OUTOF_MEMORY;
free( temp_header_value ); free(temp_header_value);
return ret_code; return ret_code;
} }
strncpy(temp_header_value, soap_action_header->value.buf,
strncpy( temp_header_value, soap_action_header->value.buf, soap_action_header->value.length);
soap_action_header->value.length );
temp_header_value[soap_action_header->value.length] = 0; temp_header_value[soap_action_header->value.length] = 0;
temp = strchr(temp_header_value, '#');
temp = strchr( temp_header_value, '#' ); if (!temp) {
if( !temp ) { free(temp_header_value);
free( temp_header_value );
ret_code = UPNP_E_INVALID_ACTION; ret_code = UPNP_E_INVALID_ACTION;
return ret_code; return ret_code;
} }
( *temp ) = 0; /* temp make string */ (*temp) = 0; /* temp make string */
/* check to see if it is Query State Variable or /* check to see if it is Query State Variable or
* Service Action */ * Service Action */
tempSize = strlen( urn ) + 2; tempSize = strlen(urn) + 2;
ns_compare = ( char * )malloc( tempSize ); ns_compare = malloc(tempSize);
if( !ns_compare ) { if (!ns_compare) {
ret_code = UPNP_E_OUTOF_MEMORY; ret_code = UPNP_E_OUTOF_MEMORY;
free( temp_header_value ); free(temp_header_value);
return ret_code; return ret_code;
} }
snprintf( ns_compare, tempSize, "\"%s", urn ); snprintf(ns_compare, tempSize, "\"%s", urn);
if( strcmp( temp_header_value, ns_compare ) ) { if (strcmp(temp_header_value, ns_compare))
ret_code = UPNP_E_INVALID_ACTION; ret_code = UPNP_E_INVALID_ACTION;
} else { else {
ret_code = UPNP_E_SUCCESS; ret_code = UPNP_E_SUCCESS;
temp++; temp++;
temp2 = strchr( temp, '\"' ); temp2 = strchr(temp, '\"');
if( temp2 ) /* remove ending " if present */ /* remove ending " if present */
{ if (temp2)
( *temp2 ) = 0; (*temp2) = 0;
} if (*temp)
if( *temp ) (*actionName) = strdup(temp);
( *actionName ) = strdup( temp ); if (!*actionName)
if( !*actionName ) {
ret_code = UPNP_E_OUTOF_MEMORY; ret_code = UPNP_E_OUTOF_MEMORY;
} }
}
free( temp_header_value ); free(temp_header_value);
free( ns_compare ); free(ns_compare);
return ret_code; return ret_code;
} }
@ -686,12 +648,12 @@ send_action_response( IN SOCKINFO * info,
off_t content_length; off_t content_length;
int ret_code; int ret_code;
int timeout_secs = SOAP_TIMEOUT; int timeout_secs = SOAP_TIMEOUT;
static char *start_body = static const char *start_body =
/*"<?xml version=\"1.0\"?>" required?? */ /*"<?xml version=\"1.0\"?>" required?? */
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap." "<s:Envelope xmlns:s=\"http://schemas.xmlsoap."
"org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap." "org/soap/envelope/\" s:encodingStyle=\"http://schemas.xmlsoap."
"org/soap/encoding/\"><s:Body>\n"; "org/soap/encoding/\"><s:Body>\n";
static char *end_body = "</s:Body> </s:Envelope>"; static const char *end_body = "</s:Body> </s:Envelope>";
/* init */ /* init */
http_CalcResponseVersion( request->major_version, http_CalcResponseVersion( request->major_version,
@ -700,14 +662,10 @@ send_action_response( IN SOCKINFO * info,
err_code = UPNP_E_OUTOF_MEMORY; /* one error only */ err_code = UPNP_E_OUTOF_MEMORY; /* one error only */
/* get xml */ /* get xml */
xml_response = ixmlPrintNode( ( IXML_Node * ) action_resp ); xml_response = ixmlPrintNode( ( IXML_Node * ) action_resp );
if( xml_response == NULL ) { if (!xml_response)
goto error_handler; goto error_handler;
} content_length = (off_t)(strlen(start_body) + strlen(xml_response) +
strlen(end_body));
content_length =
strlen( start_body ) +
strlen( xml_response ) +
strlen( end_body );
/* make headers */ /* make headers */
if (http_MakeMessage( if (http_MakeMessage(
&headers, major, minor, &headers, major, minor,
@ -725,13 +683,11 @@ send_action_response( IN SOCKINFO * info,
start_body, strlen( start_body ), start_body, strlen( start_body ),
xml_response, strlen( xml_response ), xml_response, strlen( xml_response ),
end_body, strlen( end_body ) ); end_body, strlen( end_body ) );
if( ret_code != 0 ) { if( ret_code != 0 ) {
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
"Failed to send response: err code = %d\n", "Failed to send response: err code = %d\n",
ret_code ); ret_code );
} }
err_code = 0; err_code = 0;
error_handler: error_handler:
@ -996,9 +952,8 @@ 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 */
if( err_code != 0 ) { if( err_code != 0 )
send_error_response( info, err_code, err_str, request ); send_error_response( info, err_code, err_str, request );
}
} }
/**************************************************************************** /****************************************************************************
@ -1018,10 +973,8 @@ error_handler:
* *
* Note : * Note :
****************************************************************************/ ****************************************************************************/
void void soap_device_callback(IN http_parser_t *parser, IN http_message_t *request,
soap_device_callback( IN http_parser_t * parser, INOUT SOCKINFO *info)
IN http_message_t * request,
INOUT SOCKINFO * info )
{ {
int err_code; int err_code;
const char *err_str; const char *err_str;
@ -1033,41 +986,36 @@ soap_device_callback( IN http_parser_t * parser,
err_str = Soap_Invalid_Action; err_str = Soap_Invalid_Action;
/* validate: content-type == text/xml */ /* validate: content-type == text/xml */
if( !has_xml_content_type( request ) ) { if (!has_xml_content_type(request))
goto error_handler; goto error_handler;
}
/* type of request */ /* type of request */
if( get_request_type( request, &action_name ) != 0 ) { if (get_request_type(request, &action_name) != 0)
goto error_handler; goto error_handler;
}
/* parse XML */ /* parse XML */
err_code = ixmlParseBufferEx( request->entity.buf, &xml_doc ); err_code = ixmlParseBufferEx(request->entity.buf, &xml_doc);
if( err_code != IXML_SUCCESS ) { if (err_code != IXML_SUCCESS) {
if( err_code == IXML_INSUFFICIENT_MEMORY ) { if (err_code == IXML_INSUFFICIENT_MEMORY)
err_code = UPNP_E_OUTOF_MEMORY; err_code = UPNP_E_OUTOF_MEMORY;
} else { else
err_code = SOAP_ACTION_FAILED; err_code = SOAP_ACTION_FAILED;
}
err_str = "XML error"; err_str = "XML error";
goto error_handler; goto error_handler;
} }
if (action_name.length == 0)
if( action_name.length == 0 ) {
/* query var */ /* query var */
handle_query_variable( info, request, xml_doc ); handle_query_variable(info, request, xml_doc);
} else { else
/* invoke action */ /* invoke action */
handle_invoke_action( info, request, action_name, xml_doc ); handle_invoke_action(info, request, action_name, xml_doc);
} /* no error */
err_code = 0;
err_code = 0; /* no error */
error_handler: error_handler:
ixmlDocument_free( xml_doc ); ixmlDocument_free(xml_doc);
if( err_code != 0 ) { if (err_code != 0)
send_error_response( info, err_code, err_str, request ); send_error_response(info, err_code, err_str, request);
} return;
parser = parser;
} }
#endif /* EXCLUDE_SOAP */ #endif /* EXCLUDE_SOAP */

View File

@ -81,7 +81,7 @@ void send_search_result(IN void *data)
* SSDP message from the device * SSDP message from the device
* IN struct sockaddr *dest_addr: * IN struct sockaddr *dest_addr:
* Address of the device * Address of the device
* IN xboolean timeout: * IN int timeout:
* timeout kept by the control point while * timeout kept by the control point while
* sending search message * sending search message
* IN void* cookie: * IN void* cookie:
@ -101,7 +101,7 @@ void ssdp_handle_ctrlpt_msg(
IN http_message_t *hmsg, IN http_message_t *hmsg,
IN struct sockaddr *dest_addr, IN struct sockaddr *dest_addr,
/* only in search reply */ /* only in search reply */
IN xboolean timeout, IN int timeout,
/* only in search reply */ /* only in search reply */
IN void *cookie) IN void *cookie)
{ {
@ -109,12 +109,12 @@ void ssdp_handle_ctrlpt_msg(
struct Handle_Info *ctrlpt_info = NULL; struct Handle_Info *ctrlpt_info = NULL;
memptr hdr_value; memptr hdr_value;
/* byebye or alive */ /* byebye or alive */
xboolean is_byebye; int is_byebye;
struct Upnp_Discovery param; struct Upnp_Discovery param;
SsdpEvent event; SsdpEvent event;
xboolean nt_found; int nt_found;
xboolean usn_found; int usn_found;
xboolean st_found; int st_found;
char save_char; char save_char;
Upnp_EventType event_type; Upnp_EventType event_type;
Upnp_FunPtr ctrlpt_callback; Upnp_FunPtr ctrlpt_callback;
@ -128,7 +128,7 @@ void ssdp_handle_ctrlpt_msg(
/* we are assuming that there can be only one client supported at a time */ /* we are assuming that there can be only one client supported at a time */
HandleReadLock(); HandleReadLock();
if ( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
HandleUnlock(); HandleUnlock();
return; return;
} }
@ -137,40 +137,40 @@ void ssdp_handle_ctrlpt_msg(
ctrlpt_cookie = ctrlpt_info->Cookie; ctrlpt_cookie = ctrlpt_info->Cookie;
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;
} }
param.ErrCode = UPNP_E_SUCCESS; param.ErrCode = UPNP_E_SUCCESS;
/* MAX-AGE, assume error */ /* MAX-AGE, assume error */
param.Expires = -1; param.Expires = -1;
if ( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) { if (httpmsg_find_hdr(hmsg, HDR_CACHE_CONTROL, &hdr_value) != NULL) {
if( matchstr( hdr_value.buf, hdr_value.length, if (matchstr(hdr_value.buf, hdr_value.length,
"%imax-age = %d%0", &param.Expires ) != PARSE_OK ) "%imax-age = %d%0", &param.Expires) != PARSE_OK)
return; return;
} }
/* DATE */ /* DATE */
param.Date[0] = '\0'; param.Date[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) { if (httpmsg_find_hdr(hmsg, HDR_DATE, &hdr_value) != NULL) {
linecopylen( param.Date, hdr_value.buf, hdr_value.length ); linecopylen(param.Date, hdr_value.buf, hdr_value.length);
} }
/* dest addr */ /* dest addr */
memcpy(&param.DestAddr, dest_addr, sizeof(struct sockaddr_in) ); memcpy(&param.DestAddr, dest_addr, sizeof(struct sockaddr_in));
/* EXT */ /* EXT */
param.Ext[0] = '\0'; param.Ext[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) { if (httpmsg_find_hdr(hmsg, HDR_EXT, &hdr_value) != NULL) {
linecopylen( param.Ext, hdr_value.buf, hdr_value.length ); linecopylen(param.Ext, hdr_value.buf, hdr_value.length);
} }
/* LOCATION */ /* LOCATION */
param.Location[0] = '\0'; param.Location[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) { if (httpmsg_find_hdr(hmsg, HDR_LOCATION, &hdr_value) != NULL) {
linecopylen( param.Location, hdr_value.buf, hdr_value.length ); linecopylen(param.Location, hdr_value.buf, hdr_value.length);
} }
/* SERVER / USER-AGENT */ /* SERVER / USER-AGENT */
param.Os[0] = '\0'; param.Os[0] = '\0';
if ( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL || if (httpmsg_find_hdr(hmsg, HDR_SERVER, &hdr_value) != NULL ||
httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) { httpmsg_find_hdr(hmsg, HDR_USER_AGENT, &hdr_value) != NULL) {
linecopylen( param.Os, hdr_value.buf, hdr_value.length ); linecopylen(param.Os, hdr_value.buf, hdr_value.length);
} }
/* clear everything */ /* clear everything */
param.DeviceId[0] = '\0'; param.DeviceId[0] = '\0';
@ -178,51 +178,44 @@ void ssdp_handle_ctrlpt_msg(
param.ServiceType[0] = '\0'; param.ServiceType[0] = '\0';
/* not used; version is in ServiceType */ /* not used; version is in ServiceType */
param.ServiceVer[0] = '\0'; param.ServiceVer[0] = '\0';
event.UDN[0] = '\0'; event.UDN[0] = '\0';
event.DeviceType[0] = '\0'; event.DeviceType[0] = '\0';
event.ServiceType[0] = '\0'; event.ServiceType[0] = '\0';
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 );
} }
/* 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;
} else { } else {
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 */
} }
event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE; event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
@ -230,100 +223,104 @@ void ssdp_handle_ctrlpt_msg(
/* check advertisement. /* check advertisement.
* Expires is valid if positive. This is for testing * Expires is valid if positive. This is for testing
* only. Expires should be greater than 1800 (30 mins) */ * only. Expires should be greater than 1800 (30 mins) */
if( !nt_found || if (!nt_found ||
!usn_found || !usn_found ||
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;
} }
/* call callback */ /* call callback */
ctrlpt_callback( event_type, &param, ctrlpt_cookie ); ctrlpt_callback(event_type, &param, ctrlpt_cookie);
} else { } else {
/* reply (to a SEARCH) */ /* reply (to a SEARCH) */
/* only checking to see if there is a valid ST header */ /* only checking to see if there is a valid ST header */
st_found = FALSE; st_found = FALSE;
if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) { if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) != NULL) {
save_char = hdr_value.buf[hdr_value.length]; save_char = hdr_value.buf[hdr_value.length];
hdr_value.buf[hdr_value.length] = '\0'; hdr_value.buf[hdr_value.length] = '\0';
st_found = ssdp_request_type( hdr_value.buf, &event ) == 0; st_found =
ssdp_request_type(hdr_value.buf, &event) == 0;
hdr_value.buf[hdr_value.length] = save_char; hdr_value.buf[hdr_value.length] = save_char;
} }
if( hmsg->status_code != HTTP_OK || if (hmsg->status_code != HTTP_OK ||
param.Expires <= 0 || param.Expires <= 0 ||
strlen( param.Location ) == 0 || !usn_found || !st_found ) { strlen(param.Location) == 0 || !usn_found || !st_found) {
return; /* bad reply */ return; /* bad reply */
} }
/* check each current search */ /* check each current search */
HandleLock(); HandleLock();
if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) { if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
HandleUnlock(); HandleUnlock();
return; return;
} }
node = ListHead( &ctrlpt_info->SsdpSearchList ); node = ListHead(&ctrlpt_info->SsdpSearchList);
/* temporary add null termination */ /* temporary add null termination */
/*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'; */
while (node != NULL) {
while( node != NULL ) {
searchArg = node->item; searchArg = node->item;
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, size_t m = min(hdr_value.length,
strlen( searchArg->searchTarget ) ); strlen(searchArg->
matched = !( strncmp( searchArg->searchTarget, searchTarget));
hdr_value.buf, m ) ); matched = !strncmp(searchArg->searchTarget,
hdr_value.buf, m);
break; break;
} }
case SSDP_SERVICE: { case SSDP_SERVICE:{
int m = min( hdr_value.length, size_t 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;
} }
default: 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 =
TPJobInit( &job, ( start_routine ) send_search_result, ctrlpt_callback;
threadData ); TPJobInit(&job,
(start_routine)
send_search_result,
threadData);
TPJobSetPriority(&job, MED_PRIORITY); TPJobSetPriority(&job, MED_PRIORITY);
TPJobSetFreeFunction(&job, (free_routine)free); TPJobSetFreeFunction(&job,
ThreadPoolAdd(&gRecvThreadPool, &job, NULL); (free_routine)
free);
ThreadPoolAdd(&gRecvThreadPool, &job,
NULL);
} }
} }
node = ListNext( &ctrlpt_info->SsdpSearchList, node ); node = ListNext(&ctrlpt_info->SsdpSearchList, node);
} }
HandleUnlock(); HandleUnlock();
/*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie );*/ /*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie ); */
} }
} }

View File

@ -217,76 +217,73 @@ void ssdp_handle_device_request(
* Returns: void * * Returns: void *
* 1 if successful else appropriate error * 1 if successful else appropriate error
***************************************************************************/ ***************************************************************************/
static int static int NewRequestHandler(IN struct sockaddr *DestAddr, IN int NumPacket,
NewRequestHandler( IN struct sockaddr *DestAddr, IN char **RqPacket)
IN int NumPacket,
IN char **RqPacket )
{ {
char errorBuffer[ERROR_BUFFER_LEN]; char errorBuffer[ERROR_BUFFER_LEN];
SOCKET ReplySock; SOCKET ReplySock;
int socklen = sizeof( struct sockaddr_storage ); socklen_t socklen = sizeof(struct sockaddr_storage);
int Index; int Index;
unsigned long replyAddr = inet_addr( gIF_IPV4 ); unsigned long replyAddr = inet_addr(gIF_IPV4);
/* a/c to UPNP Spec */ /* a/c to UPNP Spec */
int ttl = 4; int ttl = 4;
int hops = 1; int hops = 1;
char buf_ntop[64]; char buf_ntop[64];
int ret = UPNP_E_SUCCESS; int ret = UPNP_E_SUCCESS;
ReplySock = socket( DestAddr->sa_family, 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__,
"SSDP_LIB: New Request Handler:" "SSDP_LIB: New Request Handler:"
"Error in socket(): %s\n", errorBuffer ); "Error in socket(): %s\n", errorBuffer);
return UPNP_E_OUTOF_SOCKET; return UPNP_E_OUTOF_SOCKET;
} }
if( DestAddr->sa_family == AF_INET ) { if (DestAddr->sa_family == AF_INET) {
inet_ntop(AF_INET, &((struct sockaddr_in*)DestAddr)->sin_addr, inet_ntop(AF_INET, &((struct sockaddr_in *)DestAddr)->sin_addr,
buf_ntop, sizeof(buf_ntop)); buf_ntop, sizeof(buf_ntop));
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF, setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
(char *)&replyAddr, sizeof (replyAddr) ); (char *)&replyAddr, sizeof(replyAddr));
setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL, setsockopt(ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
(char *)&ttl, sizeof (int) ); (char *)&ttl, sizeof(int));
socklen = sizeof(struct sockaddr_in); socklen = sizeof(struct sockaddr_in);
} else if( DestAddr->sa_family == AF_INET6 ) { } else if (DestAddr->sa_family == AF_INET6) {
inet_ntop(AF_INET6, &((struct sockaddr_in6*)DestAddr)->sin6_addr, inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)DestAddr)->sin6_addr,
buf_ntop, sizeof(buf_ntop)); buf_ntop, sizeof(buf_ntop));
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF, setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_IF,
(char *)&gIF_INDEX, sizeof(gIF_INDEX) ); (char *)&gIF_INDEX, sizeof(gIF_INDEX));
setsockopt( ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, setsockopt(ReplySock, IPPROTO_IPV6, IPV6_MULTICAST_HOPS,
(char *)&hops, sizeof(hops) ); (char *)&hops, sizeof(hops));
} else { } else {
UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__, UpnpPrintf(UPNP_CRITICAL, SSDP, __FILE__, __LINE__,
"Invalid destination address specified." ); "Invalid destination address specified.");
ret = UPNP_E_NETWORK_ERROR; ret = UPNP_E_NETWORK_ERROR;
goto end_NewRequestHandler; goto end_NewRequestHandler;
} }
for( Index = 0; Index < NumPacket; Index++ ) { for (Index = 0; Index < NumPacket; Index++) {
int rc; ssize_t rc;
UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
">>> SSDP SEND to %s >>>\n%s\n", ">>> SSDP SEND to %s >>>\n%s\n",
buf_ntop, *( RqPacket + Index ) ); buf_ntop, *(RqPacket + Index));
rc = sendto( ReplySock, *( RqPacket + Index ), rc = sendto(ReplySock, *(RqPacket + Index),
strlen( *( RqPacket + Index ) ), strlen(*(RqPacket + Index)), 0, DestAddr, socklen);
0, DestAddr, socklen );
if (rc == -1) { if (rc == -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: New Request Handler:" "SSDP_LIB: New Request Handler:"
"Error in socket(): %s\n", errorBuffer ); "Error in socket(): %s\n", errorBuffer);
ret = UPNP_E_SOCKET_WRITE; ret = UPNP_E_SOCKET_WRITE;
goto end_NewRequestHandler; goto end_NewRequestHandler;
} }
} }
end_NewRequestHandler: end_NewRequestHandler:
shutdown( ReplySock, SD_BOTH ); shutdown(ReplySock, SD_BOTH);
UpnpCloseSocket( ReplySock ); UpnpCloseSocket(ReplySock);
return ret; return ret;
} }
@ -367,9 +364,9 @@ int isUrlV6UlaGua(char *descdocUrl)
* Returns: void * Returns: void
* *
***************************************************************************/ ***************************************************************************/
void CreateServicePacket( static void CreateServicePacket(
IN int msg_type, IN int msg_type,
IN char *nt, const IN char *nt,
IN char *usn, IN char *usn,
IN char *location, IN char *location,
IN int duration, IN int duration,
@ -377,7 +374,7 @@ void CreateServicePacket(
IN int AddressFamily) IN int AddressFamily)
{ {
int ret_code; int ret_code;
char *nts; const char *nts;
membuffer buf; membuffer buf;
/* Notf == 0 means service shutdown, /* Notf == 0 means service shutdown,
@ -405,24 +402,23 @@ void CreateServicePacket(
} }
} else if (msg_type == MSGTYPE_ADVERTISEMENT || } else if (msg_type == MSGTYPE_ADVERTISEMENT ||
msg_type == MSGTYPE_SHUTDOWN) { msg_type == MSGTYPE_SHUTDOWN) {
char *host = NULL; const char *host = NULL;
if (msg_type == MSGTYPE_ADVERTISEMENT) {
if (msg_type == MSGTYPE_ADVERTISEMENT)
nts = "ssdp:alive"; nts = "ssdp:alive";
} else { else
/* shutdown */ /* shutdown */
nts = "ssdp:byebye"; nts = "ssdp:byebye";
}
/* NOTE: The CACHE-CONTROL and LOCATION headers are not present in /* NOTE: The CACHE-CONTROL and LOCATION headers are not present in
* a shutdown msg, but are present here for MS WinMe interop. */ * a shutdown msg, but are present here for MS WinMe interop. */
if (AddressFamily == AF_INET) { if (AddressFamily == AF_INET)
host = SSDP_IP; host = SSDP_IP;
} else { else {
if (isUrlV6UlaGua(location)) { if (isUrlV6UlaGua(location))
host = "[" SSDP_IPV6_SITELOCAL "]"; host = "[" SSDP_IPV6_SITELOCAL "]";
} else { else
host = "[" SSDP_IPV6_LINKLOCAL "]"; host = "[" SSDP_IPV6_LINKLOCAL "]";
} }
}
ret_code = http_MakeMessage( ret_code = http_MakeMessage(
&buf, 1, 1, &buf, 1, 1,
"Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "ssc" "ssc" "S" "Xc" "sscc", "Q" "sssdc" "sdc" "ssc" "ssc" "ssc" "ssc" "ssc" "S" "Xc" "sscc",
@ -437,14 +433,11 @@ void CreateServicePacket(
"NTS: ", nts, "NTS: ", nts,
X_USER_AGENT, X_USER_AGENT,
"USN: ", usn ); "USN: ", usn );
if (ret_code != 0) { if (ret_code)
return; return;
} } else
} else {
/* unknown msg */ /* unknown msg */
assert(0); assert(0);
}
/* return msg */ /* return msg */
*packet = membuffer_detach(&buf); *packet = membuffer_detach(&buf);
membuffer_destroy(&buf); membuffer_destroy(&buf);
@ -959,6 +952,7 @@ DeviceShutdown( IN char *DevType,
free( msgs[2] ); free( msgs[2] );
return ret_code; return ret_code;
_Server = _Server;
} }
#endif /* EXCLUDE_SSDP */ #endif /* EXCLUDE_SSDP */

View File

@ -120,8 +120,8 @@ int AdvertiseAndReply(
int Exp) int Exp)
{ {
int retVal = UPNP_E_SUCCESS; int retVal = UPNP_E_SUCCESS;
int i; long unsigned int i;
int j; long unsigned int j;
int defaultExp = DEFAULT_MAXAGE; int defaultExp = DEFAULT_MAXAGE;
struct Handle_Info *SInfo = NULL; struct Handle_Info *SInfo = NULL;
char UDNstr[100]; char UDNstr[100];
@ -468,78 +468,64 @@ int unique_service_name(IN char *cmd, IN SsdpEvent *Evt)
char *ptr2 = NULL; char *ptr2 = NULL;
char *ptr3 = NULL; char *ptr3 = NULL;
int CommandFound = 0; int CommandFound = 0;
int length = 0; size_t n = 0;
if( ( TempPtr = strstr( cmd, "uuid:schemas" ) ) != NULL ) { if ((TempPtr = strstr(cmd, "uuid:schemas")) != NULL) {
ptr1 = strstr( cmd, ":device" ); ptr1 = strstr(cmd, ":device");
if( ptr1 != NULL ) { if (ptr1 != NULL)
ptr2 = strstr( ptr1 + 1, ":" ); ptr2 = strstr(ptr1 + 1, ":");
} else { else
return -1; return -1;
} if (ptr2 != NULL)
ptr3 = strstr(ptr2 + 1, ":");
if( ptr2 != NULL ) { else
ptr3 = strstr( ptr2 + 1, ":" );
} else {
return -1; return -1;
} if (ptr3 != NULL)
sprintf(Evt->UDN, "uuid:%s", ptr3 + 1);
if( ptr3 != NULL ) { else
sprintf( Evt->UDN, "uuid:%s", ptr3 + 1 );
} else {
return -1; return -1;
} ptr1 = strstr(cmd, ":");
if (ptr1 != NULL) {
ptr1 = strstr( cmd, ":" ); n = (size_t)(ptr3 - ptr1);
if( ptr1 != NULL ) { strncpy(TempBuf, ptr1, n);
strncpy( TempBuf, ptr1, ptr3 - ptr1 ); TempBuf[n] = '\0';
TempBuf[ptr3 - ptr1] = '\0'; sprintf(Evt->DeviceType, "urn%s", TempBuf);
sprintf( Evt->DeviceType, "urn%s", TempBuf ); } else
} else {
return -1; return -1;
}
return 0; return 0;
} }
if ((TempPtr = strstr(cmd, "uuid")) != NULL) {
if( ( TempPtr = strstr( cmd, "uuid" ) ) != NULL ) { if ((Ptr = strstr(cmd, "::")) != NULL) {
if( ( Ptr = strstr( cmd, "::" ) ) != NULL ) { n = (size_t)(Ptr - TempPtr);
strncpy( Evt->UDN, TempPtr, Ptr - TempPtr ); strncpy(Evt->UDN, TempPtr, n);
Evt->UDN[Ptr - TempPtr] = '\0'; Evt->UDN[n] = '\0';
} else { } else
strcpy( Evt->UDN, TempPtr ); strcpy(Evt->UDN, TempPtr);
}
CommandFound = 1; CommandFound = 1;
} }
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":service:") != NULL) {
if( strstr( cmd, "urn:" ) != NULL if ((TempPtr = strstr(cmd, "urn")) != NULL) {
&& strstr( cmd, ":service:" ) != NULL ) { strcpy(Evt->ServiceType, TempPtr);
if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
strcpy( Evt->ServiceType, TempPtr );
CommandFound = 1; CommandFound = 1;
} }
} }
if (strstr(cmd, "urn:") != NULL && strstr(cmd, ":device:") != NULL) {
if( strstr( cmd, "urn:" ) != NULL if ((TempPtr = strstr(cmd, "urn")) != NULL) {
&& strstr( cmd, ":device:" ) != NULL ) { strcpy(Evt->DeviceType, TempPtr);
if( ( TempPtr = strstr( cmd, "urn" ) ) != NULL ) {
strcpy( Evt->DeviceType, TempPtr );
CommandFound = 1; CommandFound = 1;
} }
} }
if ((TempPtr = strstr(cmd, "::upnp:rootdevice")) != NULL) {
if( ( TempPtr = strstr( cmd, "::upnp:rootdevice" ) ) != NULL ) {
/* Everything before "::upnp::rootdevice" is the UDN. */ /* Everything before "::upnp::rootdevice" is the UDN. */
if( TempPtr != cmd ) { if (TempPtr != cmd) {
length = TempPtr - cmd; n = (size_t)(TempPtr - cmd);
strncpy(Evt->UDN, cmd, length); strncpy(Evt->UDN, cmd, n);
Evt->UDN[length] = 0; Evt->UDN[n] = 0;
CommandFound = 1; CommandFound = 1;
} }
} }
if (CommandFound == 0)
if( CommandFound == 0 ) {
return -1; return -1;
}
return 0; return 0;
} }
@ -779,102 +765,85 @@ static void ssdp_event_handler_thread(void *the_data)
* Returns: void * Returns: void
* *
***************************************************************************/ ***************************************************************************/
void void readFromSSDPSocket(SOCKET socket)
readFromSSDPSocket( SOCKET socket )
{ {
char *requestBuf = NULL; char *requestBuf = NULL;
char staticBuf[BUFSIZE]; char staticBuf[BUFSIZE];
struct sockaddr_storage __ss; struct sockaddr_storage __ss;
ThreadPoolJob job; ThreadPoolJob job;
ssdp_thread_data *data = NULL; ssdp_thread_data *data = NULL;
socklen_t socklen = sizeof( __ss ); socklen_t socklen = sizeof(__ss);
int byteReceived = 0; ssize_t byteReceived = 0;
char ntop_buf[64]; char ntop_buf[64];
requestBuf = staticBuf; requestBuf = staticBuf;
/* in case memory can't be allocated, still drain the socket using a /* in case memory can't be allocated, still drain the socket using a
* static buffer. */ * static buffer. */
data = ( ssdp_thread_data * ) data = malloc(sizeof(ssdp_thread_data));
malloc( sizeof( ssdp_thread_data ) ); if (data) {
if( data != NULL ) {
/* initialize parser */ /* initialize parser */
#ifdef INCLUDE_CLIENT_APIS #ifdef INCLUDE_CLIENT_APIS
#ifdef UPNP_ENABLE_IPV6 #ifdef UPNP_ENABLE_IPV6
if( socket == gSsdpReqSocket4 || socket == gSsdpReqSocket6 ) { 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);
} #else /* UPNP_ENABLE_IPV6 */
#else if (socket == gSsdpReqSocket4)
if( socket == gSsdpReqSocket4 ) { 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 ); #endif /* UPNP_ENABLE_IPV6 */
} #else /* INCLUDE_CLIENT_APIS */
parser_request_init(&data->parser);
#endif #endif /* INCLUDE_CLIENT_APIS */
#else
parser_request_init( &data->parser );
#endif
/* set size of parser buffer */ /* set size of parser buffer */
if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) { if (membuffer_set_size(&data->parser.msg.msg, BUFSIZE) == 0)
/* use this as the buffer for recv */ /* use this as the buffer for recv */
requestBuf = data->parser.msg.msg.buf; requestBuf = data->parser.msg.msg.buf;
else {
} else { free(data);
free( data );
data = NULL; data = NULL;
} }
} }
byteReceived = recvfrom( socket, requestBuf, byteReceived = recvfrom(socket, requestBuf, BUFSIZE - 1, 0,
BUFSIZE - 1, 0, (struct sockaddr *)&__ss, &socklen);
(struct sockaddr *)&__ss, &socklen ); if (byteReceived > 0) {
if( byteReceived > 0 ) {
requestBuf[byteReceived] = '\0'; requestBuf[byteReceived] = '\0';
if (__ss.ss_family == AF_INET)
if( __ss.ss_family == AF_INET ) inet_ntop(AF_INET,
inet_ntop( AF_INET, &((struct sockaddr_in*)&__ss)->sin_addr, ntop_buf, sizeof(ntop_buf) ); &((struct sockaddr_in *)&__ss)->sin_addr,
ntop_buf, sizeof(ntop_buf));
#ifdef UPNP_ENABLE_IPV6 #ifdef UPNP_ENABLE_IPV6
else if( __ss.ss_family == AF_INET6 ) else if (__ss.ss_family == AF_INET6)
inet_ntop( AF_INET6, &((struct sockaddr_in6*)&__ss)->sin6_addr, ntop_buf, sizeof(ntop_buf) ); inet_ntop(AF_INET6,
&((struct sockaddr_in6 *)&__ss)->sin6_addr,
ntop_buf, sizeof(ntop_buf));
#endif #endif
else else
strncpy( ntop_buf, "<Invalid address family>", sizeof(ntop_buf) ); 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"
"%s\n" "%s\n"
"End of received response ------------------------------------------------------\n" "End of received response ------------------------------------------------------\n"
"From host %s\n", "From host %s\n", requestBuf, ntop_buf);
requestBuf,
ntop_buf );
UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,
"Start of received multicast packet --------------------------------------------\n"
"%s\n"
"End of received multicast packet ----------------------------------------------\n",
requestBuf );
/* add thread pool job to handle request */ /* add thread pool job to handle request */
if( data != NULL ) { if (data != NULL) {
data->parser.msg.msg.length += byteReceived; data->parser.msg.msg.length += (size_t)byteReceived;
/* null-terminate */ /* null-terminate */
data->parser.msg.msg.buf[byteReceived] = 0; data->parser.msg.msg.buf[byteReceived] = 0;
memcpy( &data->dest_addr, &__ss, sizeof(__ss) ); 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,
TPJobSetPriority( &job, MED_PRIORITY ); free_ssdp_event_handler_data);
TPJobSetPriority(&job, MED_PRIORITY);
if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) { if (ThreadPoolAdd(&gRecvThreadPool, &job, NULL) != 0)
free_ssdp_event_handler_data( data ); free_ssdp_event_handler_data(data);
}
}
} else {
free_ssdp_event_handler_data( data );
} }
} else
free_ssdp_event_handler_data(data);
} }
@ -907,10 +876,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
} }
/* For use by ssdp control point. */ /* For use by ssdp control point. */
gSsdpReqSocket4 = out->ssdpReqSock4; gSsdpReqSocket4 = out->ssdpReqSock4;
} else { } else
out->ssdpReqSock4 = INVALID_SOCKET; out->ssdpReqSock4 = INVALID_SOCKET;
}
/* Create the IPv6 socket for SSDP REQUESTS */ /* Create the IPv6 socket for SSDP REQUESTS */
#ifdef UPNP_ENABLE_IPV6 #ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) { if (strlen(gIF_IPV6) > 0) {
@ -922,14 +889,10 @@ int get_ssdp_sockets(MiniServerSockArray *out)
} }
/* For use by ssdp control point. */ /* For use by ssdp control point. */
gSsdpReqSocket6 = out->ssdpReqSock6; gSsdpReqSocket6 = out->ssdpReqSock6;
} else { } else
out->ssdpReqSock6 = INVALID_SOCKET; out->ssdpReqSock6 = INVALID_SOCKET;
}
#endif /* IPv6 */ #endif /* IPv6 */
#endif /* INCLUDE_CLIENT_APIS */ #endif /* INCLUDE_CLIENT_APIS */
/* Create the IPv4 socket for SSDP */ /* Create the IPv4 socket for SSDP */
if (strlen(gIF_IPV4) > 0) { if (strlen(gIF_IPV4) > 0) {
retVal = create_ssdp_sock_v4(&out->ssdpSock4); retVal = create_ssdp_sock_v4(&out->ssdpSock4);
@ -942,10 +905,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif #endif
return retVal; return retVal;
} }
} else { } else
out->ssdpSock4 = INVALID_SOCKET; out->ssdpSock4 = INVALID_SOCKET;
}
/* Create the IPv6 socket for SSDP */ /* Create the IPv6 socket for SSDP */
#ifdef UPNP_ENABLE_IPV6 #ifdef UPNP_ENABLE_IPV6
if (strlen(gIF_IPV6) > 0) { if (strlen(gIF_IPV6) > 0) {
@ -961,10 +922,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif #endif
return retVal; return retVal;
} }
} else { } else
out->ssdpSock6 = INVALID_SOCKET; out->ssdpSock6 = INVALID_SOCKET;
}
if (strlen(gIF_IPV6_ULA_GUA) > 0) { if (strlen(gIF_IPV6_ULA_GUA) > 0) {
retVal = create_ssdp_sock_v6_ula_gua(&out->ssdpSock6UlaGua); retVal = create_ssdp_sock_v6_ula_gua(&out->ssdpSock6UlaGua);
if (retVal != UPNP_E_SUCCESS) { if (retVal != UPNP_E_SUCCESS) {
@ -980,9 +939,8 @@ int get_ssdp_sockets(MiniServerSockArray *out)
#endif #endif
return retVal; return retVal;
} }
} else { } else
out->ssdpSock6UlaGua = INVALID_SOCKET; out->ssdpSock6UlaGua = INVALID_SOCKET;
}
#endif /* IPv6 */ #endif /* IPv6 */
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
@ -1003,24 +961,22 @@ int get_ssdp_sockets(MiniServerSockArray *out)
* Returns: * Returns:
* UPNP_E_SUCCESS on successful socket creation. * UPNP_E_SUCCESS on successful socket creation.
***************************************************************************/ ***************************************************************************/
int create_ssdp_sock_reqv4( SOCKET* ssdpReqSock ) int create_ssdp_sock_reqv4(SOCKET *ssdpReqSock)
{ {
char errorBuffer[ERROR_BUFFER_LEN]; char errorBuffer[ERROR_BUFFER_LEN];
u_char ttl = 4; u_char ttl = 4;
*ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 ); *ssdpReqSock = socket(AF_INET, SOCK_DGRAM, 0);
if ( *ssdpReqSock == -1 ) { if (*ssdpReqSock == -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);
return UPNP_E_OUTOF_SOCKET; return UPNP_E_OUTOF_SOCKET;
} }
setsockopt(*ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,
setsockopt( *ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl));
&ttl, sizeof (ttl) );
/* just do it, regardless if fails or not. */ /* just do it, regardless if fails or not. */
Make_Socket_NoBlocking( *ssdpReqSock ); Make_Socket_NoBlocking(*ssdpReqSock);
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }