Files
libupnp/upnp/src/genlib/service_table/service_table.c
Fabrice Fontaine c67187ac94 Remove some of the implicit cast in upnp part
Remove some of the "implicit integer or enum conversions" as well as
some access to NULL reference in upnp part.
2012-03-10 20:44:49 +01:00

1075 lines
32 KiB
C

/*******************************************************************************
*
* Copyright (c) 2000-2003 Intel Corporation
* All rights reserved.
* Copyright (c) 2012 France Telecom All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither name of Intel Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************/
/************************************************************************
* Purpose: This file defines the functions for services. It defines
* functions for adding and removing services to and from the service table,
* adding and accessing subscription and other attributes pertaining to the
* service
************************************************************************/
#include "config.h"
#include "service_table.h"
#ifdef INCLUDE_DEVICE_APIS
#if EXCLUDE_GENA == 0
/************************************************************************
* Function : copy_subscription
*
* Parameters :
* subscription *in ; Source subscription
* subscription *out ; Destination subscription
*
* Description : Makes a copy of the subscription
*
* Return : int ;
* HTTP_SUCCESS - On success
*
* Note :
************************************************************************/
int
copy_subscription( subscription * in,
subscription * out )
{
int return_code = HTTP_SUCCESS;
memcpy( out->sid, in->sid, SID_SIZE );
out->sid[SID_SIZE] = 0;
out->eventKey = in->eventKey;
out->ToSendEventKey = in->ToSendEventKey;
out->expireTime = in->expireTime;
out->active = in->active;
if( ( return_code =
copy_URL_list( &in->DeliveryURLs, &out->DeliveryURLs ) )
!= HTTP_SUCCESS )
return return_code;
out->next = NULL;
return HTTP_SUCCESS;
}
/************************************************************************
* Function : RemoveSubscriptionSID
*
* Parameters :
* Upnp_SID sid ; subscription ID
* service_info * service ; service object providing the list of
* subscriptions
*
* Description : Remove the subscription represented by the
* const Upnp_SID sid parameter from the service table and update
* the service table.
*
* Return : void ;
*
* Note :
************************************************************************/
void
RemoveSubscriptionSID( Upnp_SID sid,
service_info * service )
{
subscription *finger = service->subscriptionList;
subscription *previous = NULL;
while( finger ) {
if( !( strcmp( sid, finger->sid ) ) ) {
if( previous )
previous->next = finger->next;
else
service->subscriptionList = finger->next;
finger->next = NULL;
freeSubscriptionList( finger );
finger = NULL;
service->TotalSubscriptions--;
} else {
previous = finger;
finger = finger->next;
}
}
}
subscription *GetSubscriptionSID(const Upnp_SID sid, service_info *service)
{
subscription *next = service->subscriptionList;
subscription *previous = NULL;
subscription *found = NULL;
time_t current_time;
while( ( next ) && ( found == NULL ) ) {
if( !strcmp( next->sid, sid ) )
found = next;
else {
previous = next;
next = next->next;
}
}
if( found ) {
/*get the current_time */
time( &current_time );
if( ( found->expireTime != 0 )
&& ( found->expireTime < current_time ) ) {
if( previous )
previous->next = found->next;
else
service->subscriptionList = found->next;
found->next = NULL;
freeSubscriptionList( found );
found = NULL;
service->TotalSubscriptions--;
}
}
return found;
}
subscription *GetNextSubscription(service_info *service, subscription *current)
{
time_t current_time;
subscription *next = NULL;
subscription *previous = NULL;
int notDone = 1;
/* get the current_time */
time( &current_time );
while( ( notDone ) && ( current ) ) {
previous = current;
current = current->next;
if( current == NULL ) {
notDone = 0;
next = current;
} else
if( ( current->expireTime != 0 )
&& ( current->expireTime < current_time ) ) {
previous->next = current->next;
current->next = NULL;
freeSubscriptionList( current );
current = previous;
service->TotalSubscriptions--;
} else if( current->active ) {
notDone = 0;
next = current;
}
}
return next;
}
subscription *GetFirstSubscription(service_info *service)
{
subscription temp;
subscription *next = NULL;
temp.next = service->subscriptionList;
next = GetNextSubscription(service, &temp);
service->subscriptionList = temp.next;
/* service->subscriptionList = next; */
return next;
}
void freeSubscription(subscription *sub)
{
if (sub) {
free_URL_list(&sub->DeliveryURLs);
}
}
/************************************************************************
* Function : freeSubscriptionList
*
* Parameters :
* subscription * head ; head of the subscription list
*
* Description : Free's memory allocated for all the subscriptions
* in the service table.
*
* Return : void ;
*
* Note :
************************************************************************/
void
freeSubscriptionList( subscription * head )
{
subscription *next = NULL;
while( head ) {
next = head->next;
freeSubscription( head );
free( head );
head = next;
}
}
/************************************************************************
* Function : FindServiceId
*
* Parameters :
* service_table *table ; service table
* const char * serviceId ;string representing the service id
* to be found among those in the table
* const char * UDN ; string representing the UDN
* to be found among those in the table
*
* Description : Traverses through the service table and returns a
* pointer to the service node that matches a known service id
* and a known UDN
*
* Return : service_info * - pointer to the matching service_info node;
*
* Note :
************************************************************************/
service_info *
FindServiceId( service_table * table,
const char *serviceId,
const char *UDN )
{
service_info *finger = NULL;
if( table ) {
finger = table->serviceList;
while( finger ) {
if( ( !strcmp( serviceId, finger->serviceId ) ) &&
( !strcmp( UDN, finger->UDN ) ) ) {
return finger;
}
finger = finger->next;
}
}
return NULL;
}
/************************************************************************
* Function : FindServiceEventURLPath
*
* Parameters :
* service_table *table ; service table
* char * eventURLPath ; event URL path used to find a service
* from the table
*
* Description : Traverses the service table and finds the node whose
* event URL Path matches a know value
*
* Return : service_info * - pointer to the service list node from the
* service table whose event URL matches a known event URL;
*
* Note :
************************************************************************/
service_info *
FindServiceEventURLPath( service_table * table,
char *eventURLPath )
{
service_info *finger = NULL;
uri_type parsed_url;
uri_type parsed_url_in;
if( ( table )
&&
( parse_uri
( eventURLPath, strlen( eventURLPath ), &parsed_url_in ) ) ) {
finger = table->serviceList;
while( finger ) {
if( finger->eventURL )
if( ( parse_uri
( finger->eventURL, strlen( finger->eventURL ),
&parsed_url ) ) ) {
if( !token_cmp
( &parsed_url.pathquery,
&parsed_url_in.pathquery ) )
return finger;
}
finger = finger->next;
}
}
return NULL;
}
#endif /* EXCLUDE_GENA */
/************************************************************************
* Function : FindServiceControlURLPath
*
* Parameters :
* service_table * table ; service table
* char * controlURLPath ; control URL path used to find a service
* from the table
*
* Description : Traverses the service table and finds the node whose
* control URL Path matches a know value
*
* Return : service_info * - pointer to the service list node from the
* service table whose control URL Path matches a known value;
*
* Note :
************************************************************************/
#if EXCLUDE_SOAP == 0
service_info *
FindServiceControlURLPath( service_table * table,
const char *controlURLPath )
{
service_info *finger = NULL;
uri_type parsed_url;
uri_type parsed_url_in;
if( ( table )
&&
( parse_uri
( controlURLPath, strlen( controlURLPath ),
&parsed_url_in ) ) ) {
finger = table->serviceList;
while( finger ) {
if( finger->controlURL )
if( ( parse_uri
( finger->controlURL, strlen( finger->controlURL ),
&parsed_url ) ) ) {
if( !token_cmp
( &parsed_url.pathquery,
&parsed_url_in.pathquery ) )
return finger;
}
finger = finger->next;
}
}
return NULL;
}
#endif /* EXCLUDE_SOAP */
/************************************************************************
* Function : printService
*
* Parameters :
* service_info *service ;Service whose information is to be printed
* Upnp_LogLevel level ; Debug level specified to the print function
* Dbg_Module module ; Debug module specified to the print function
*
* Description : For debugging purposes prints information from the
* service passed into the function.
*
* Return : void ;
*
* Note :
************************************************************************/
#ifdef DEBUG
void printService(
service_info *service,
Upnp_LogLevel level,
Dbg_Module module )
{
if( service ) {
if( service->serviceType ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"serviceType: %s\n", service->serviceType );
}
if( service->serviceId ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"serviceId: %s\n", service->serviceId );
}
if( service->SCPDURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"SCPDURL: %s\n", service->SCPDURL );
}
if( service->controlURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"controlURL: %s\n", service->controlURL );
}
if( service->eventURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"eventURL: %s\n", service->eventURL );
}
if( service->UDN ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"UDN: %s\n\n", service->UDN );
}
if( service->active ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"Service is active\n" );
} else {
UpnpPrintf( level, module, __FILE__, __LINE__,
"Service is inactive\n" );
}
}
}
#endif
/************************************************************************
* Function : printServiceList
*
* Parameters :
* service_info *service ; Service whose information is to be printed
* Upnp_LogLevel level ; Debug level specified to the print function
* Dbg_Module module ; Debug module specified to the print function
*
* Description : For debugging purposes prints information of each
* service from the service table passed into the function.
*
* Return : void ;
*
* Note :
************************************************************************/
#ifdef DEBUG
void printServiceList(
service_info * service,
Upnp_LogLevel level,
Dbg_Module module )
{
while( service ) {
if( service->serviceType ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"serviceType: %s\n", service->serviceType );
}
if( service->serviceId ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"serviceId: %s\n", service->serviceId );
}
if( service->SCPDURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"SCPDURL: %s\n", service->SCPDURL );
}
if( service->controlURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"controlURL: %s\n", service->controlURL );
}
if( service->eventURL ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"eventURL: %s\n", service->eventURL );
}
if( service->UDN ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"UDN: %s\n\n", service->UDN );
}
if( service->active ) {
UpnpPrintf( level, module, __FILE__, __LINE__,
"Service is active\n" );
} else {
UpnpPrintf( level, module, __FILE__, __LINE__,
"Service is inactive\n" );
}
service = service->next;
}
}
#endif
/************************************************************************
* Function : printServiceTable
*
* Parameters :
* service_table * table ; Service table to be printed
* Upnp_LogLevel level ; Debug level specified to the print function
* Dbg_Module module ; Debug module specified to the print function
*
* Description : For debugging purposes prints the URL base of the table
* and information of each service from the service table passed into
* the function.
*
* Return : void ;
*
* Note :
************************************************************************/
#ifdef DEBUG
void printServiceTable(
service_table * table,
Upnp_LogLevel level,
Dbg_Module module )
{
UpnpPrintf( level, module, __FILE__, __LINE__,
"URL_BASE: %s\n", table->URLBase );
UpnpPrintf( level, module, __FILE__, __LINE__,
"Services: \n" );
printServiceList( table->serviceList, level, module );}
#endif
#if EXCLUDE_GENA == 0
/************************************************************************
* Function : freeService
*
* Parameters :
* service_info *in ; service information that is to be freed
*
* Description : Free's memory allocated for the various components
* of the service entry in the service table.
*
* Return : void ;
*
* Note :
************************************************************************/
void freeService( service_info * in )
{
if( in ) {
if( in->serviceType )
ixmlFreeDOMString( in->serviceType );
if( in->serviceId )
ixmlFreeDOMString( in->serviceId );
if( in->SCPDURL )
free( in->SCPDURL );
if( in->controlURL )
free( in->controlURL );
if( in->eventURL )
free( in->eventURL );
if( in->UDN )
ixmlFreeDOMString( in->UDN );
if( in->subscriptionList )
freeSubscriptionList( in->subscriptionList );
in->TotalSubscriptions = 0;
free( in );
}
}
/************************************************************************
* Function : freeServiceList
*
* Parameters :
* service_info * head ; Head of the service list to be freed
*
* Description : Free's memory allocated for the various components
* of each service entry in the service table.
*
* Return : void ;
*
* Note :
************************************************************************/
void
freeServiceList( service_info * head )
{
service_info *next = NULL;
while( head ) {
if( head->serviceType )
ixmlFreeDOMString( head->serviceType );
if( head->serviceId )
ixmlFreeDOMString( head->serviceId );
if( head->SCPDURL )
free( head->SCPDURL );
if( head->controlURL )
free( head->controlURL );
if( head->eventURL )
free( head->eventURL );
if( head->UDN )
ixmlFreeDOMString( head->UDN );
if( head->subscriptionList )
freeSubscriptionList( head->subscriptionList );
head->TotalSubscriptions = 0;
next = head->next;
free( head );
head = next;
}
}
/************************************************************************
* Function : freeServiceTable
*
* Parameters :
* service_table * table ; Service table whose memory needs to be
* freed
*
* Description : Free's dynamic memory in table.
* (does not free table, only memory within the structure)
*
* Return : void ;
*
* Note :
************************************************************************/
void
freeServiceTable( service_table * table )
{
ixmlFreeDOMString( table->URLBase );
freeServiceList( table->serviceList );
table->serviceList = NULL;
table->endServiceList = NULL;
}
/************************************************************************
* Function : getElementValue
*
* Parameters :
* IXML_Node *node ; Input node which provides the list of child
* nodes
*
* Description : Returns the clone of the element value
*
* Return : DOMString ;
*
* Note : value must be freed with DOMString_free
************************************************************************/
DOMString
getElementValue( IXML_Node * node )
{
IXML_Node *child = ( IXML_Node * ) ixmlNode_getFirstChild( node );
const DOMString temp = NULL;
if( ( child != 0 ) && ( ixmlNode_getNodeType( child ) == eTEXT_NODE ) ) {
temp = ixmlNode_getNodeValue( child );
return ixmlCloneDOMString( temp );
} else {
return NULL;
}
}
/************************************************************************
* Function : getSubElement
*
* Parameters :
* const char *element_name ; sub element name to be searched for
* IXML_Node *node ; Input node which provides the list of child
* nodes
* IXML_Node **out ; Ouput node to which the matched child node is
* returned.
*
* Description : Traverses through a list of XML nodes to find the
* node with the known element name.
*
* Return : int ;
* 1 - On Success
* 0 - On Failure
*
* Note :
************************************************************************/
int
getSubElement( const char *element_name,
IXML_Node * node,
IXML_Node ** out )
{
const DOMString NodeName = NULL;
int found = 0;
IXML_Node *child = ( IXML_Node * ) ixmlNode_getFirstChild( node );
( *out ) = NULL;
while( ( child != NULL ) && ( !found ) ) {
switch ( ixmlNode_getNodeType( child ) ) {
case eELEMENT_NODE:
NodeName = ixmlNode_getNodeName( child );
if( !strcmp( NodeName, element_name ) ) {
( *out ) = child;
found = 1;
return found;
}
break;
default:
break;
}
child = ( IXML_Node * ) ixmlNode_getNextSibling( child );
}
return found;
}
/************************************************************************
* Function : getServiceList
*
* Parameters :
* IXML_Node *node ; XML node information
* service_info **end ; service added is returned to the output
* parameter
* char * URLBase ; provides Base URL to resolve relative URL
*
* Description : Returns pointer to service info after getting the
* sub-elements of the service info.
*
* Return : service_info * - pointer to the service info node ;
*
* Note :
************************************************************************/
service_info *getServiceList(
IXML_Node *node,
service_info **end,
char *URLBase)
{
IXML_Node *serviceList = NULL;
IXML_Node *current_service = NULL;
IXML_Node *UDN = NULL;
IXML_Node *serviceType = NULL;
IXML_Node *serviceId = NULL;
IXML_Node *SCPDURL = NULL;
IXML_Node *controlURL = NULL;
IXML_Node *eventURL = NULL;
DOMString tempDOMString = NULL;
service_info *head = NULL;
service_info *current = NULL;
service_info *previous = NULL;
IXML_NodeList *serviceNodeList = NULL;
long unsigned int NumOfServices = 0lu;
long unsigned int i = 0lu;
int fail = 0;
if (getSubElement("UDN", node, &UDN) &&
getSubElement("serviceList", node, &serviceList)) {
serviceNodeList = ixmlElement_getElementsByTagName(
(IXML_Element *)serviceList, "service");
if (serviceNodeList != NULL) {
NumOfServices = ixmlNodeList_length(serviceNodeList);
for (i = 0lu; i < NumOfServices; i++) {
current_service =
ixmlNodeList_item(serviceNodeList, i);
fail = 0;
if (current) {
current->next = malloc(sizeof(service_info));
previous = current;
current = current->next;
} else {
head = malloc(sizeof(service_info));
current = head;
}
if (!current) {
freeServiceList(head);
ixmlNodeList_free(serviceNodeList);
return NULL;
}
current->next = NULL;
current->controlURL = NULL;
current->eventURL = NULL;
current->serviceType = NULL;
current->serviceId = NULL;
current->SCPDURL = NULL;
current->active = 1;
current->subscriptionList = NULL;
current->TotalSubscriptions = 0;
if (!(current->UDN = getElementValue(UDN)))
fail = 1;
if (!getSubElement("serviceType", current_service, &serviceType) ||
!(current->serviceType = getElementValue(serviceType)))
fail = 1;
if (!getSubElement("serviceId", current_service, &serviceId) ||
!(current->serviceId = getElementValue(serviceId)))
fail = 1;
if (!getSubElement("SCPDURL", current_service, &SCPDURL) ||
!(tempDOMString = getElementValue(SCPDURL)) ||
!(current->SCPDURL = resolve_rel_url(URLBase, tempDOMString)))
fail = 1;
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if (!(getSubElement("controlURL", current_service, &controlURL)) ||
!(tempDOMString = getElementValue(controlURL)) ||
!(current->controlURL = 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;
fail = 0;
}
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if (!getSubElement("eventSubURL", current_service, &eventURL) ||
!(tempDOMString = getElementValue(eventURL)) ||
!(current->eventURL = resolve_rel_url(URLBase, tempDOMString))) {
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;
fail = 0;
}
ixmlFreeDOMString(tempDOMString);
tempDOMString = NULL;
if (fail) {
freeServiceList(current);
if (previous)
previous->next = NULL;
else
head = NULL;
current = previous;
}
}
ixmlNodeList_free(serviceNodeList);
}
(*end) = current;
return head;
} else {
(*end) = NULL;
return NULL;
}
}
/************************************************************************
* Function : getAllServiceList
*
* Parameters :
* IXML_Node *node ; XML node information
* char * URLBase ; provides Base URL to resolve relative URL
* service_info **out_end ; service added is returned to the output
* parameter
*
* Description : Returns pointer to service info after getting the
* sub-elements of the service info.
*
* Return : service_info * ;
*
* Note :
************************************************************************/
service_info *
getAllServiceList( IXML_Node * node,
char *URLBase,
service_info ** out_end )
{
service_info *head = NULL;
service_info *end = NULL;
service_info *next_end = NULL;
IXML_NodeList *deviceList = NULL;
IXML_Node *currentDevice = NULL;
long unsigned int NumOfDevices = 0lu;
long unsigned int i = 0lu;
(*out_end) = NULL;
deviceList = ixmlElement_getElementsByTagName(
(IXML_Element *)node, "device");
if (deviceList) {
NumOfDevices = ixmlNodeList_length(deviceList);
for (i = 0lu; i < NumOfDevices; i++) {
currentDevice = ixmlNodeList_item(deviceList, i);
if (head) {
end->next = getServiceList(currentDevice,
&next_end, URLBase);
if (next_end)
end = next_end;
} else
head = getServiceList(currentDevice, &end,
URLBase);
}
ixmlNodeList_free(deviceList);
}
(*out_end) = end;
return head;
}
/************************************************************************
* Function : removeServiceTable
*
* Parameters :
* IXML_Node *node ; XML node information
* service_table *in ; service table from which services will be
* removed
*
* Description : This function assumes that services for a particular
* root device are placed linearly in the service table, and in the
* order in which they are found in the description document
* all services for this root device are removed from the list
*
* Return : int ;
*
* Note :
************************************************************************/
int
removeServiceTable( IXML_Node * node,
service_table * in )
{
IXML_Node *root = NULL;
IXML_Node *currentUDN = NULL;
DOMString UDN = NULL;
IXML_NodeList *deviceList = NULL;
service_info *current_service = NULL;
service_info *start_search = NULL;
service_info *prev_service = NULL;
long unsigned int NumOfDevices = 0lu;
long unsigned int i = 0lu;
if( getSubElement( "root", node, &root ) ) {
current_service = in->serviceList;
start_search = in->serviceList;
deviceList =
ixmlElement_getElementsByTagName( ( IXML_Element * ) root,
"device" );
if( deviceList != NULL ) {
NumOfDevices = ixmlNodeList_length( deviceList );
for( i = 0lu; i < NumOfDevices; i++ ) {
if( ( start_search )
&& ( ( getSubElement( "UDN", node, &currentUDN ) )
&& ( UDN = getElementValue( currentUDN ) ) ) ) {
current_service = start_search;
/*Services are put in the service table in the order in which they appear in the */
/*description document, therefore we go through the list only once to remove a particular */
/*root device */
while( ( current_service )
&& ( strcmp( current_service->UDN, UDN ) ) ) {
current_service = current_service->next;
if( current_service != NULL)
prev_service = current_service->next;
}
while( ( current_service )
&& ( !strcmp( current_service->UDN, UDN ) ) ) {
if( prev_service ) {
prev_service->next = current_service->next;
} else {
in->serviceList = current_service->next;
}
if( current_service == in->endServiceList )
in->endServiceList = prev_service;
start_search = current_service->next;
freeService( current_service );
current_service = start_search;
}
ixmlFreeDOMString( UDN );
UDN = NULL;
}
}
ixmlNodeList_free( deviceList );
}
}
return 1;
}
/************************************************************************
* Function : addServiceTable
*
* Parameters :
* IXML_Node *node ; XML node information
* service_table *in ; service table that will be initialized with
* services
* const char *DefaultURLBase ; Default base URL on which the URL
* will be returned to the service list.
*
* Description : Add Service to the table.
*
* Return : int ;
*
* Note :
************************************************************************/
int
addServiceTable( IXML_Node * node,
service_table * in,
const char *DefaultURLBase )
{
IXML_Node *root = NULL;
IXML_Node *URLBase = NULL;
service_info *tempEnd = NULL;
if( in->URLBase ) {
free( in->URLBase );
in->URLBase = NULL;
}
if( getSubElement( "root", node, &root ) ) {
if( getSubElement( "URLBase", root, &URLBase ) ) {
in->URLBase = getElementValue( URLBase );
} else {
if( DefaultURLBase ) {
in->URLBase = ixmlCloneDOMString( DefaultURLBase );
} else {
in->URLBase = ixmlCloneDOMString( "" );
}
}
if( ( in->endServiceList->next =
getAllServiceList( root, in->URLBase, &tempEnd ) ) ) {
in->endServiceList = tempEnd;
return 1;
}
}
return 0;
}
/************************************************************************
* Function : getServiceTable
*
* Parameters :
* IXML_Node *node ; XML node information
* service_table *out ; output parameter which will contain the
* service list and URL
* const char *DefaultURLBase ; Default base URL on which the URL
* will be returned.
*
* Description : Retrieve service from the table
*
* Return : int ;
*
* Note :
************************************************************************/
int
getServiceTable( IXML_Node * node,
service_table * out,
const char *DefaultURLBase )
{
IXML_Node *root = NULL;
IXML_Node *URLBase = NULL;
if( getSubElement( "root", node, &root ) ) {
if( getSubElement( "URLBase", root, &URLBase ) ) {
out->URLBase = getElementValue( URLBase );
} else {
if( DefaultURLBase ) {
out->URLBase = ixmlCloneDOMString( DefaultURLBase );
} else {
out->URLBase = ixmlCloneDOMString( "" );
}
}
if( ( out->serviceList = getAllServiceList(
root, out->URLBase, &out->endServiceList ) ) ) {
return 1;
}
}
return 0;
}
#endif /* EXCLUDE_GENA */
#endif /* INCLUDE_DEVICE_APIS */