libupnp/upnp/src/genlib/service_table/service_table.c
Fabrice Fontaine 81f10bcffb SF Bug Tracker id 3498439 - Memory leak in removeServiceTable
Submitted: Fabrice Fontaine ( ffontaine ) - 2012-03-07 02:35:46 PST

UDN is not freed.
(cherry picked from commit 0469388b73f133e839ebe9689b433a84c638b68e)
2012-03-07 16:03:13 -03:00

1068 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
/************************************************************************
* 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;
}
/************************************************************************
* 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 :
************************************************************************/
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;
}
/************************************************************************
* 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
/************************************************************************
* 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 = 0;
long unsigned int i = 0;
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 = 0; 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 = 0;
long unsigned int i = 0;
(*out_end) = NULL;
deviceList = ixmlElement_getElementsByTagName(
(IXML_Element *)node, "device");
if (deviceList) {
NumOfDevices = ixmlNodeList_length(deviceList);
for (i = 0; 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 = 0;
long unsigned int i = 0;
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 = 0; 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;
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 /* INCLUDE_DEVICE_APIS */