soap_device: Doxygen and code reformat.

This commit is contained in:
Marcelo Roberto Jimenez 2010-11-24 12:33:13 -02:00
parent 57e9584f4e
commit 0977f8864d
2 changed files with 479 additions and 625 deletions

View File

@ -32,31 +32,25 @@
#ifndef SOAPLIB_H #ifndef SOAPLIB_H
#define SOAPLIB_H #define SOAPLIB_H
/*!
* \file
*/
/* SOAP module API to be called in Upnp-Dk API */ /* SOAP module API to be called in Upnp-Dk API */
/**************************************************************************** /*!
* Function: soap_device_callback * \brief This is a callback called by minisever after receiving the request
* * from the control point. This function will start processing the request.
* Parameters: * It calls handle_invoke_action to handle the SOAP action.
* IN http_parser_t *parser: Parsed request received by the device */
* IN http_message_t* request: HTTP request
* INOUT SOCKINFO *info: socket info
*
* Description: This is a callback called by minisever after receiving
* the request from the control point. This function will start
* processing the request. It calls handle_invoke_action to handle the
* SOAP action
*
* Return: void
*
* Note:
****************************************************************************/
void soap_device_callback( void soap_device_callback(
IN http_parser_t *parser, /*! [in] Parsed request received by the device. */
IN http_message_t* request, http_parser_t *parser,
INOUT SOCKINFO *info); /*! [in] HTTP request. */
http_message_t *request,
/*! [in,out] Socket info. */
SOCKINFO *info);
/**************************************************************************** /****************************************************************************

View File

@ -38,12 +38,6 @@
#ifdef INCLUDE_DEVICE_APIS #ifdef INCLUDE_DEVICE_APIS
#if EXCLUDE_SOAP == 0 #if EXCLUDE_SOAP == 0
#define SOAP_BODY "Body"
#define SOAP_URN "http:/""/schemas.xmlsoap.org/soap/envelope/"
#define QUERY_STATE_VAR_URN "urn:schemas-upnp-org:control-1-0"
#include "ActionRequest.h" #include "ActionRequest.h"
#include "httpparser.h" #include "httpparser.h"
#include "httpreadwrite.h" #include "httpreadwrite.h"
@ -70,8 +64,11 @@
#define SOAP_INVALID_VAR 404 #define SOAP_INVALID_VAR 404
#define SOAP_ACTION_FAILED 501 #define SOAP_ACTION_FAILED 501
static const char *Soap_Invalid_Action = "Invalid Action"; static const char *SOAP_BODY = "Body";
static const char *SOAP_URN = "http:/""/schemas.xmlsoap.org/soap/envelope/";
static const char *QUERY_STATE_VAR_URN = "urn:schemas-upnp-org:control-1-0";
static const char *Soap_Invalid_Action = "Invalid Action";
/*static const char* Soap_Invalid_Args = "Invalid Args"; */ /*static const char* Soap_Invalid_Args = "Invalid Args"; */
static const char *Soap_Action_Failed = "Action Failed"; static const char *Soap_Action_Failed = "Action Failed";
static const char *Soap_Invalid_Var = "Invalid Var"; static const char *Soap_Invalid_Var = "Invalid Var";
@ -154,26 +151,18 @@ static UPNP_INLINE int get_request_type(
return 0; return 0;
} }
/**************************************************************************** /*!
* Function : send_error_response * \brief Sends SOAP error response.
* */
* Parameters : static void send_error_response(
* IN SOCKINFO *info : socket info /*! [in] Socket info. */
* IN int error_code : error code IN SOCKINFO *info,
* IN const char* err_msg : error message /*! [in] Error code. */
* IN http_message_t* hmsg : HTTP request
*
* Description : This function sends SOAP error response
*
* Return : void
*
* Note :
****************************************************************************/
static void
send_error_response( IN SOCKINFO * info,
IN int error_code, IN int error_code,
/*! [in] Error message. */
IN const char *err_msg, IN const char *err_msg,
IN http_message_t * hmsg ) /*! [in] HTTP request. */
IN http_message_t *hmsg)
{ {
off_t content_length; off_t content_length;
int timeout_secs = SOAP_TIMEOUT; int timeout_secs = SOAP_TIMEOUT;
@ -191,24 +180,29 @@ 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 = (off_t)(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) +
http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, strlen(end_body));
&major, &minor ); http_CalcResponseVersion(hmsg->major_version, hmsg->minor_version,
&major, &minor);
/* make headers */ /* make headers */
membuffer_init( &headers ); membuffer_init(&headers);
if (http_MakeMessage( if (http_MakeMessage(&headers, major, minor,
&headers, major, minor,
"RNsDsSXcc" "sssss", "RNsDsSXcc" "sssss",
500, 500,
content_length, content_length,
@ -216,34 +210,27 @@ send_error_response( IN SOCKINFO * info,
"EXT:\r\n", "EXT:\r\n",
X_USER_AGENT, X_USER_AGENT,
start_body, err_code_str, mid_body, err_msg, start_body, err_code_str, mid_body, err_msg,
end_body ) != 0 ) { end_body) != 0) {
membuffer_destroy( &headers ); membuffer_destroy(&headers);
return; /* out of mem */ /* out of mem */
return;
} }
/* 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);
} }
/**************************************************************************** /*!
* Function : send_var_query_response * \brief Sends response of get var status.
* */
* Parameters : static UPNP_INLINE void send_var_query_response(
* IN SOCKINFO *info : socket info /*! [in] Socket info. */
* IN const char* var_value : value of the state variable SOCKINFO *info,
* IN http_message_t* hmsg : HTTP request /*! [in] Value of the state variable. */
* const char *var_value,
* Description : This function sends response of get var status /*! [in] HTTP request. */
* http_message_t *hmsg)
* Return : void
*
* Note :
****************************************************************************/
static UPNP_INLINE void
send_var_query_response( IN SOCKINFO * info,
IN const char *var_value,
IN http_message_t * hmsg )
{ {
off_t content_length; off_t content_length;
int timeout_secs = SOAP_TIMEOUT; int timeout_secs = SOAP_TIMEOUT;
@ -258,27 +245,26 @@ send_var_query_response( IN SOCKINFO * info,
"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 = (off_t) (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",
HTTP_OK, HTTP_OK,
content_length, content_length,
ContentTypeHeader, ContentTypeHeader,
"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 */ /* out of mem */
return;
} }
/* send msg */ /* send msg */
http_SendMessage(info, &timeout_secs, "b", http_SendMessage(info, &timeout_secs, "b",
@ -286,26 +272,18 @@ send_var_query_response( IN SOCKINFO * info,
membuffer_destroy(&response); membuffer_destroy(&response);
} }
/**************************************************************************** /*!
* Function : get_action_node * \brief Separates the action node from the root DOM node.
* *
* Parameters : * \return 0 if successful, or -1 if fails.
* IN IXML_Document *TempDoc : The root DOM node. */
* IN char *NodeName : IXML_Node name to be searched. static UPNP_INLINE int get_action_node(
* OUT IXML_Document ** RespNode : Response/Output node. /*! [in] The root DOM node. */
* IXML_Document *TempDoc,
* Description : This function separates the action node from /*! [in] IXML_Node name to be searched. */
* the root DOM node. char *NodeName,
* /*! [out] Response/Output node. */
* Return : static UPNP_INLINE int IXML_Document **RespNode)
* 0 if successful, or -1 if fails.
*
* Note :
****************************************************************************/
static UPNP_INLINE int
get_action_node( IN IXML_Document * TempDoc,
IN char *NodeName,
OUT IXML_Document ** RespNode )
{ {
IXML_Node *EnvpNode = NULL; IXML_Node *EnvpNode = NULL;
IXML_Node *BodyNode = NULL; IXML_Node *BodyNode = NULL;
@ -315,138 +293,104 @@ get_action_node( IN IXML_Document * TempDoc,
int ret_code = -1; /* error, by default */ int ret_code = -1; /* error, by default */
IXML_NodeList *nl = NULL; IXML_NodeList *nl = NULL;
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
"get_action_node(): node name =%s\n ", NodeName ); "get_action_node(): node name =%s\n ", NodeName);
*RespNode = NULL; *RespNode = NULL;
/* Got the Envelope node here */ /* Got the Envelope node here */
EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc ); EnvpNode = ixmlNode_getFirstChild((IXML_Node *) TempDoc);
if( EnvpNode == NULL ) { if (!EnvpNode)
goto error_handler; goto error_handler;
} nl = ixmlElement_getElementsByTagNameNS((IXML_Element *)EnvpNode,
"*", "Body");
nl = ixmlElement_getElementsByTagNameNS( ( IXML_Element * ) EnvpNode, if (!nl)
"*", "Body" );
if( nl == NULL ) {
goto error_handler; goto error_handler;
} BodyNode = ixmlNodeList_item(nl, 0);
if (!BodyNode)
BodyNode = ixmlNodeList_item( nl, 0 );
if( BodyNode == NULL ) {
goto error_handler; goto error_handler;
}
/* Got action node here */ /* Got action node here */
ActNode = ixmlNode_getFirstChild( BodyNode ); ActNode = ixmlNode_getFirstChild(BodyNode);
if( ActNode == NULL ) { if (!ActNode)
goto error_handler; goto error_handler;
}
/* Test whether this is the action node */ /* Test whether this is the action node */
nodeName = ixmlNode_getNodeName( ActNode ); nodeName = ixmlNode_getNodeName(ActNode);
if( nodeName == NULL ) { if (!nodeName)
goto error_handler; goto error_handler;
} if (!strstr(nodeName, NodeName))
if( strstr( nodeName, NodeName ) == NULL ) {
goto error_handler; goto error_handler;
} else { else {
ActNodeName = ixmlPrintNode( ActNode ); ActNodeName = ixmlPrintNode(ActNode);
if( ActNodeName == NULL ) { if (!ActNodeName)
goto error_handler; goto error_handler;
} ret_code = ixmlParseBufferEx(ActNodeName, RespNode);
if (ret_code != IXML_SUCCESS) {
ret_code = ixmlParseBufferEx( ActNodeName, RespNode ); ixmlFreeDOMString(ActNodeName);
if( ret_code != IXML_SUCCESS ) {
ixmlFreeDOMString( ActNodeName );
ret_code = -1; ret_code = -1;
goto error_handler; goto error_handler;
} }
} }
/* success */
ret_code = 0;
ret_code = 0; /* success */ error_handler:
ixmlFreeDOMString(ActNodeName);
error_handler: if (nl)
ixmlNodeList_free(nl);
ixmlFreeDOMString( ActNodeName );
if( nl )
ixmlNodeList_free( nl );
return ret_code; return ret_code;
} }
/**************************************************************************** /*!
* Function : check_soap_body * \brief Checks the soap body xml came in the SOAP request.
* *
* Parameters : * \return UPNP_E_SUCCESS if successful else returns appropriate error.
* IN IXML_Document *doc : soap body xml document */
* IN const char *urn : static int check_soap_body(
* IN const char *actionName : Name of the requested action /* [in] soap body xml document. */
* IN IXML_Document *doc,
* Description : This function checks the soap body xml came in the /* [in] URN. */
* SOAP request.
*
* Return : int
* UPNP_E_SUCCESS if successful else returns appropriate error
*
* Note :
****************************************************************************/
static int
check_soap_body( IN IXML_Document * doc,
IN const char *urn, IN const char *urn,
IN const char *actionName ) /* [in] Name of the requested action. */
IN const char *actionName)
{ {
IXML_NodeList *nl = NULL; IXML_NodeList *nl = NULL;
IXML_Node *bodyNode = NULL; IXML_Node *bodyNode = NULL;
IXML_Node *actionNode = NULL; IXML_Node *actionNode = NULL;
const DOMString ns = NULL; const DOMString ns = NULL;
const DOMString name = NULL; const DOMString name = NULL;
int ret_code = UPNP_E_INVALID_ACTION; int ret_code = UPNP_E_INVALID_ACTION;
nl = ixmlDocument_getElementsByTagNameNS( doc, SOAP_URN, SOAP_BODY ); nl = ixmlDocument_getElementsByTagNameNS(doc, SOAP_URN, SOAP_BODY);
if (nl) {
if( nl ) { bodyNode = ixmlNodeList_item(nl, 0);
bodyNode = ixmlNodeList_item( nl, 0 ); if (bodyNode) {
if( bodyNode ) { actionNode = ixmlNode_getFirstChild(bodyNode);
actionNode = ixmlNode_getFirstChild( bodyNode ); if (actionNode) {
if( actionNode ) { ns = ixmlNode_getNamespaceURI(actionNode);
ns = ixmlNode_getNamespaceURI( actionNode ); name = ixmlNode_getLocalName(actionNode);
name = ixmlNode_getLocalName( actionNode ); if (name &&
if (name && ns && ns &&
!strcmp( actionName, name ) && !strcmp(actionName, name) &&
!strcmp( urn, ns ) ) { !strcmp(urn, ns))
ret_code = UPNP_E_SUCCESS; ret_code = UPNP_E_SUCCESS;
} }
} }
} ixmlNodeList_free(nl);
ixmlNodeList_free( nl );
} }
return ret_code; return ret_code;
} }
/**************************************************************************** /*!
* Function : check_soap_action_header * \brief Checks the HTTP header of the SOAP request coming from the
* * control point.
* Parameters : *
* IN http_message_t *request : HTTP request * \return UPNP_E_SUCCESS if successful else returns appropriate error.
* IN const char *urn : */
* OUT char **actionName : name of the SOAP action static int check_soap_action_header(
* /*! [in] HTTP request. */
* Description : This function checks the HTTP header of the SOAP request http_message_t * request,
* coming from the control point /*! [in] URN. */
* const char *urn,
* Return : static int /*! [out] Name of the SOAP action. */
* UPNP_E_SUCCESS if successful else returns appropriate error char **actionName)
*
* Note :
****************************************************************************/
static int
check_soap_action_header( IN http_message_t * request,
IN const char *urn,
OUT char **actionName )
{ {
memptr header_name; memptr header_name;
http_header_t *soap_action_header = NULL; http_header_t *soap_action_header = NULL;
@ -516,44 +460,37 @@ check_soap_action_header( IN http_message_t * request,
return ret_code; return ret_code;
} }
/**************************************************************************** /*!
* Function : get_device_info * \brief Retrives all the information needed to process the incoming SOAP
* * request. It finds the device and service info and also the callback
* Parameters : * function to hand-over the request to the device application.
* IN http_message_t* request : HTTP request *
* IN int isQuery : flag for a querry * \return UPNP_E_SUCCESS if successful else returns appropriate error.
* IN IXML_Document *actionDoc : action request document */
* OUT UpnpString *device_udn : Device UDN string static int get_device_info(
* OUT UpnpString *service_id : Service ID string /*! [in] HTTP request. */
* OUT Upnp_FunPtr *callback : callback function of the device http_message_t *request,
* application /*! [in] flag for a querry. */
* OUT void** cookie : cookie stored by device application int isQuery,
* /*! [in] Action request document. */
* Description : This function retrives all the information needed to IXML_Document *actionDoc,
* process the incoming SOAP request. It finds the device and service info /*! [in] . */
* and also the callback function to hand-over the request to the device int AddressFamily,
* application. /*! [out] Device UDN string. */
*
* Return : int
* UPNP_E_SUCCESS if successful else returns appropriate error
*
* Note :
****************************************************************************/
static int
get_device_info( IN http_message_t *request,
IN int isQuery,
IN IXML_Document *actionDoc,
IN int AddressFamily,
OUT UpnpString *device_udn, OUT UpnpString *device_udn,
OUT UpnpString *service_id, /*! [out] Service ID string. */
OUT Upnp_FunPtr *callback, UpnpString *service_id,
OUT void **cookie ) /*! [out] callback function of the device application. */
Upnp_FunPtr *callback,
/*! [out] cookie stored by device application. */
void **cookie)
{ {
struct Handle_Info *device_info; struct Handle_Info *device_info;
int device_hnd; int device_hnd;
service_info *serv_info; service_info *serv_info;
char save_char; char save_char;
int ret_code = -1; /* error by default */ /* error by default */
int ret_code = -1;
const char *control_url; const char *control_url;
char *actionName = NULL; char *actionName = NULL;
@ -564,88 +501,71 @@ get_device_info( IN http_message_t *request,
HandleLock(); HandleLock();
if( GetDeviceHandleInfo( AddressFamily, if (GetDeviceHandleInfo(AddressFamily, &device_hnd,
&device_hnd, &device_info ) != HND_DEVICE ) { &device_info) != HND_DEVICE)
goto error_handler; goto error_handler;
} serv_info = FindServiceControlURLPath(
&device_info->ServiceTable, control_url);
if( ( serv_info = if (!serv_info)
FindServiceControlURLPath( &device_info->ServiceTable,
control_url ) ) == NULL ) {
goto error_handler; goto error_handler;
} if (isQuery) {
ret_code = check_soap_action_header(request,
if( isQuery ) { QUERY_STATE_VAR_URN, &actionName);
ret_code = check_soap_action_header( request, QUERY_STATE_VAR_URN, if (ret_code != UPNP_E_SUCCESS &&
&actionName ); ret_code != UPNP_E_OUTOF_MEMORY) {
if( ( ret_code != UPNP_E_SUCCESS )
&& ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
ret_code = UPNP_E_INVALID_ACTION; ret_code = UPNP_E_INVALID_ACTION;
goto error_handler; goto error_handler;
} }
/* check soap body */ /* check soap body */
ret_code = ret_code = check_soap_body(actionDoc, QUERY_STATE_VAR_URN,
check_soap_body( actionDoc, QUERY_STATE_VAR_URN, actionName ); actionName);
free( actionName ); free(actionName);
if( ret_code != UPNP_E_SUCCESS ) { if (ret_code != UPNP_E_SUCCESS)
goto error_handler; goto error_handler;
}
} else { } else {
ret_code = check_soap_action_header( request, ret_code = check_soap_action_header(request,
serv_info->serviceType, serv_info->serviceType, &actionName);
&actionName ); if (ret_code != UPNP_E_SUCCESS &&
if( ( ret_code != UPNP_E_SUCCESS ) ret_code != UPNP_E_OUTOF_MEMORY) {
&& ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
ret_code = UPNP_E_INVALID_SERVICE; ret_code = UPNP_E_INVALID_SERVICE;
goto error_handler; goto error_handler;
} }
/* check soap body */ /* check soap body */
ret_code = ret_code = check_soap_body(actionDoc, serv_info->serviceType,
check_soap_body( actionDoc, serv_info->serviceType, actionName);
actionName ); free(actionName);
free( actionName ); if (ret_code != UPNP_E_SUCCESS) {
if( ret_code != UPNP_E_SUCCESS ) {
ret_code = UPNP_E_INVALID_SERVICE; ret_code = UPNP_E_INVALID_SERVICE;
goto error_handler; goto error_handler;
} }
} }
UpnpString_set_String(device_udn, serv_info->UDN);
UpnpString_set_String( device_udn, serv_info->UDN ); UpnpString_set_String(service_id, serv_info->serviceId);
UpnpString_set_String( service_id, serv_info->serviceId );
*callback = device_info->Callback; *callback = device_info->Callback;
*cookie = device_info->Cookie; *cookie = device_info->Cookie;
ret_code = 0; ret_code = 0;
error_handler: error_handler:
((char *)control_url)[request->uri.pathquery.size] = save_char; /* restore */ /* restore */
((char *)control_url)[request->uri.pathquery.size] = save_char;
HandleUnlock(); HandleUnlock();
return ret_code; return ret_code;
} }
/**************************************************************************** /*!
* Function : send_action_response * \brief Sends the SOAP action response.
* */
* Parameters : static UPNP_INLINE void send_action_response(
* IN SOCKINFO *info : socket info /*! [in] Socket info. */
* IN IXML_Document *action_resp : The response document SOCKINFO *info,
* IN http_message_t* request : action request document /*! [in] The response document. */
* IXML_Document *action_resp,
* Description : This function sends the SOAP response /*! [in] Action request document. */
* http_message_t *request)
* Return : void
*
* Note :
****************************************************************************/
static UPNP_INLINE void
send_action_response( IN SOCKINFO * info,
IN IXML_Document * action_resp,
IN http_message_t * request )
{ {
char *xml_response = NULL; char *xml_response = NULL;
membuffer headers; membuffer headers;
int major, int major, minor;
minor;
int err_code; int err_code;
off_t content_length; off_t content_length;
int ret_code; int ret_code;
@ -658,67 +578,59 @@ send_action_response( IN SOCKINFO * info,
static const 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, request->minor_version,
request->minor_version, &major, &minor ); &major, &minor);
membuffer_init( &headers ); membuffer_init(&headers);
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) if (!xml_response)
goto error_handler; goto error_handler;
content_length = (off_t)(strlen(start_body) + strlen(xml_response) + content_length = (off_t)(strlen(start_body) + strlen(xml_response) +
strlen(end_body)); strlen(end_body));
/* make headers */ /* make headers */
if (http_MakeMessage( if (http_MakeMessage(&headers, major, minor,
&headers, major, minor,
"RNsDsSXcc", "RNsDsSXcc",
HTTP_OK, /* status code */ HTTP_OK, /* status code */
content_length, content_length,
ContentTypeHeader, ContentTypeHeader,
"EXT:\r\n", "EXT:\r\n", X_USER_AGENT) != 0) {
X_USER_AGENT) != 0 ) {
goto error_handler; goto error_handler;
} }
/* send whole msg */ /* send whole msg */
ret_code = http_SendMessage( info, &timeout_secs, "bbbb", ret_code = http_SendMessage(
info, &timeout_secs, "bbbb",
headers.buf, headers.length, headers.buf, headers.length,
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:
ixmlFreeDOMString( xml_response ); ixmlFreeDOMString(xml_response);
membuffer_destroy( &headers ); membuffer_destroy(&headers);
if( err_code != 0 ) { if (err_code != 0) {
/* only one type of error to worry about - out of mem */ /* only one type of error to worry about - out of mem */
send_error_response( info, SOAP_ACTION_FAILED, "Out of memory", send_error_response(info, SOAP_ACTION_FAILED, "Out of memory",
request ); request);
} }
} }
/**************************************************************************** /*!
* Function : get_var_name * \brief Finds the name of the state variable asked in the SOAP request.
* *
* Parameters : * \return 0 if successful else returns -1.
* IN IXML_Document *TempDoc : Document containing variable request */
* OUT char* VarName : Name of the state varible static UPNP_INLINE int get_var_name(
* /*! [in] Document containing variable request. */
* Description : This function finds the name of the state variable IXML_Document *TempDoc,
* asked in the SOAP request. /*! [out] Name of the state varible. */
* char *VarName)
* Return : int
* returns 0 if successful else returns -1.
* Note :
****************************************************************************/
static UPNP_INLINE int
get_var_name( IN IXML_Document * TempDoc,
OUT char *VarName )
{ {
IXML_Node *EnvpNode = NULL; IXML_Node *EnvpNode = NULL;
IXML_Node *BodyNode = NULL; IXML_Node *BodyNode = NULL;
@ -730,63 +642,42 @@ get_var_name( IN IXML_Document * TempDoc,
int ret_val = -1; int ret_val = -1;
/* Got the Envelop node here */ /* Got the Envelop node here */
EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc ); EnvpNode = ixmlNode_getFirstChild((IXML_Node *) TempDoc);
if( EnvpNode == NULL ) { if (EnvpNode == NULL)
goto error_handler; goto error_handler;
}
/* Got Body here */ /* Got Body here */
BodyNode = ixmlNode_getFirstChild( EnvpNode ); BodyNode = ixmlNode_getFirstChild(EnvpNode);
if( BodyNode == NULL ) { if (BodyNode == NULL)
goto error_handler; goto error_handler;
}
/* Got action node here */ /* Got action node here */
StNode = ixmlNode_getFirstChild( BodyNode ); StNode = ixmlNode_getFirstChild(BodyNode);
if( StNode == NULL ) { if (StNode == NULL)
goto error_handler; goto error_handler;
}
/* Test whether this is the action node */ /* Test whether this is the action node */
StNodeName = ixmlNode_getNodeName( StNode ); StNodeName = ixmlNode_getNodeName(StNode);
if( StNodeName == NULL || strstr( StNodeName, if (StNodeName == NULL ||
"QueryStateVariable" ) == NULL ) { strstr(StNodeName, "QueryStateVariable") == NULL)
goto error_handler; goto error_handler;
} VarNameNode = ixmlNode_getFirstChild(StNode);
if (VarNameNode == NULL)
VarNameNode = ixmlNode_getFirstChild( StNode );
if( VarNameNode == NULL ) {
goto error_handler; goto error_handler;
} VarNode = ixmlNode_getFirstChild(VarNameNode);
Temp = ixmlNode_getNodeValue(VarNode);
linecopy(VarName, Temp);
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
"Received query for variable name %s\n", VarName);
VarNode = ixmlNode_getFirstChild( VarNameNode ); /* success */
Temp = ixmlNode_getNodeValue( VarNode ); ret_val = 0;
linecopy( VarName, Temp );
UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
"Received query for variable name %s\n",
VarName );
ret_val = 0; /* success */
error_handler: error_handler:
return ret_val; return ret_val;
} }
/**************************************************************************** /*!
* Function : handle_query_variable * \brief Handles the SOAP requests to querry the state variables.
* * This functionality has been deprecated in the UPnP V1.0 architecture.
* Parameters : */
* IN SOCKINFO *info : Socket info
* IN http_message_t* request : HTTP request
* IN IXML_Document *xml_doc : Document containing the variable request
* SOAP message
*
* Description : This action handles the SOAP requests to querry the
* state variables. This functionality has been deprecated in
* the UPnP V1.0 architecture
*
* Return : void
*
* Note :
****************************************************************************/
static UPNP_INLINE void handle_query_variable( static UPNP_INLINE void handle_query_variable(
IN SOCKINFO *info, IN SOCKINFO *info,
IN http_message_t *request, IN http_message_t *request,
@ -800,40 +691,34 @@ static UPNP_INLINE void handle_query_variable(
int err_code; int err_code;
if (get_var_name(xml_doc, var_name) != 0) { if (get_var_name(xml_doc, var_name) != 0) {
send_error_response(info, SOAP_INVALID_VAR, Soap_Invalid_Var, request); send_error_response(info, SOAP_INVALID_VAR,
Soap_Invalid_Var, request);
return; return;
} }
/* get info for event */ /* get info for event */
err_code = get_device_info( err_code = get_device_info(request, 1, xml_doc,
request, 1, xml_doc,
info->foreign_sockaddr.ss_family, info->foreign_sockaddr.ss_family,
(UpnpString *)UpnpStateVarRequest_get_DevUDN(variable), (UpnpString *)UpnpStateVarRequest_get_DevUDN(variable),
(UpnpString *)UpnpStateVarRequest_get_ServiceID(variable), (UpnpString *)UpnpStateVarRequest_get_ServiceID(variable),
&soap_event_callback, &soap_event_callback, &cookie);
&cookie);
if (err_code != 0) { if (err_code != 0) {
send_error_response(info, SOAP_INVALID_VAR, Soap_Invalid_Var, request); send_error_response(info, SOAP_INVALID_VAR,
Soap_Invalid_Var, request);
return; return;
} }
UpnpStateVarRequest_set_ErrCode(variable, UPNP_E_SUCCESS); UpnpStateVarRequest_set_ErrCode(variable, UPNP_E_SUCCESS);
UpnpStateVarRequest_strcpy_StateVarName(variable, var_name); UpnpStateVarRequest_strcpy_StateVarName(variable, var_name);
UpnpStateVarRequest_set_CtrlPtIPAddr(variable, &info->foreign_sockaddr); UpnpStateVarRequest_set_CtrlPtIPAddr(variable, &info->foreign_sockaddr);
/* send event */ /* send event */
soap_event_callback(UPNP_CONTROL_GET_VAR_REQUEST, variable, cookie); soap_event_callback(UPNP_CONTROL_GET_VAR_REQUEST, variable, cookie);
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__,
"Return from callback for var request\n"); "Return from callback for var request\n");
/* validate, and handle result */ /* validate, and handle result */
if (UpnpStateVarRequest_get_CurrentVal(variable) == NULL) { if (UpnpStateVarRequest_get_CurrentVal(variable) == NULL) {
err_code = SOAP_ACTION_FAILED; err_code = SOAP_ACTION_FAILED;
err_str = Soap_Action_Failed; err_str = Soap_Action_Failed;
send_error_response(info, SOAP_INVALID_VAR, Soap_Invalid_Var, request); send_error_response(info, SOAP_INVALID_VAR, Soap_Invalid_Var,
request);
return; return;
} }
if (UpnpStateVarRequest_get_ErrCode(variable) != UPNP_E_SUCCESS) { if (UpnpStateVarRequest_get_ErrCode(variable) != UPNP_E_SUCCESS) {
@ -853,29 +738,19 @@ static UPNP_INLINE void handle_query_variable(
UpnpStateVarRequest_delete(variable); UpnpStateVarRequest_delete(variable);
} }
/**************************************************************************** /*!
* Function : handle_invoke_action * \brief Handles the SOAP action request. It checks the integrity of the SOAP
* * action request and gives the call back to the device application.
* Parameters : */
* IN SOCKINFO *info : Socket info static void handle_invoke_action(
* IN http_message_t* request : HTTP Request /*! [in] Socket info. */
* IN memptr action_name : Name of the SOAP Action IN SOCKINFO *info,
* IN IXML_Document *xml_doc : document containing the SOAP action /*! [in] HTTP Request. */
* request IN http_message_t *request,
* /*! [in] Name of the SOAP Action. */
* Description : This functions handle the SOAP action request. It checks
* the integrity of the SOAP action request and gives the call back to
* the device application.
*
* Return : void
*
* Note :
****************************************************************************/
static void
handle_invoke_action( IN SOCKINFO * info,
IN http_message_t * request,
IN memptr action_name, IN memptr action_name,
IN IXML_Document * xml_doc ) /*! [in] Document containing the SOAP action request. */
IN IXML_Document *xml_doc)
{ {
char save_char; char save_char;
UpnpActionRequest *action = UpnpActionRequest_new(); UpnpActionRequest *action = UpnpActionRequest_new();
@ -891,27 +766,23 @@ handle_invoke_action( IN SOCKINFO * info,
/* null-terminate */ /* null-terminate */
save_char = action_name.buf[action_name.length]; save_char = action_name.buf[action_name.length];
action_name.buf[action_name.length] = '\0'; action_name.buf[action_name.length] = '\0';
/* set default error */ /* set default error */
err_code = SOAP_INVALID_ACTION; err_code = SOAP_INVALID_ACTION;
err_str = Soap_Invalid_Action; err_str = Soap_Invalid_Action;
/* get action node */ /* get action node */
if (get_action_node(xml_doc, action_name.buf, &actionRequestDoc) == -1) { if (get_action_node(xml_doc, action_name.buf, &actionRequestDoc) == -1)
goto error_handler; goto error_handler;
}
/* get device info for action event */ /* get device info for action event */
err_code = get_device_info(request, err_code = get_device_info(request,
0, 0,
xml_doc, xml_doc,
info->foreign_sockaddr.ss_family, info->foreign_sockaddr.ss_family,
devUDN, devUDN,
serviceID, &soap_event_callback, &cookie); serviceID,
&soap_event_callback, &cookie);
if (err_code != UPNP_E_SUCCESS) { if (err_code != UPNP_E_SUCCESS)
goto error_handler; goto error_handler;
}
UpnpActionRequest_set_ErrCode(action, UPNP_E_SUCCESS); UpnpActionRequest_set_ErrCode(action, UPNP_E_SUCCESS);
UpnpActionRequest_strcpy_ErrStr(action, ""); UpnpActionRequest_strcpy_ErrStr(action, "");
UpnpActionRequest_strcpy_ActionName(action, action_name.buf); UpnpActionRequest_strcpy_ActionName(action, action_name.buf);
@ -919,11 +790,8 @@ handle_invoke_action( IN SOCKINFO * info,
UpnpActionRequest_set_ServiceID(action, serviceID); UpnpActionRequest_set_ServiceID(action, serviceID);
UpnpActionRequest_set_ActionRequest(action, actionRequestDoc); UpnpActionRequest_set_ActionRequest(action, actionRequestDoc);
UpnpActionRequest_set_CtrlPtIPAddr(action, &info->foreign_sockaddr); UpnpActionRequest_set_CtrlPtIPAddr(action, &info->foreign_sockaddr);
UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n"); UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n");
soap_event_callback(UPNP_CONTROL_ACTION_REQUEST, action, cookie); soap_event_callback(UPNP_CONTROL_ACTION_REQUEST, action, cookie);
err_code = UpnpActionRequest_get_ErrCode(action); err_code = UpnpActionRequest_get_ErrCode(action);
if (err_code != UPNP_E_SUCCESS) { if (err_code != UPNP_E_SUCCESS) {
err_str = UpnpActionRequest_get_ErrStr_cstr(action); err_str = UpnpActionRequest_get_ErrStr_cstr(action);
@ -942,39 +810,31 @@ handle_invoke_action( IN SOCKINFO * info,
} }
/* send response */ /* send response */
send_action_response(info, actionResultDoc, request); send_action_response(info, actionResultDoc, request);
err_code = 0; err_code = 0;
/* error handling and cleanup */ /* error handling and cleanup */
error_handler: error_handler:
action_name.buf[action_name.length] = save_char; /* restore */ /* restore */
action_name.buf[action_name.length] = save_char;
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);
UpnpString_delete(serviceID); UpnpString_delete(serviceID);
UpnpString_delete(devUDN); UpnpString_delete(devUDN);
UpnpActionRequest_delete(action); UpnpActionRequest_delete(action);
} }
/**************************************************************************** /*!
* Function : soap_device_callback * \brief This is a callback called by minisever after receiving the request
* * from the control point. This function will start processing the request.
* Parameters : * It calls handle_invoke_action to handle the SOAP action.
* IN http_parser_t *parser : Parsed request received by the device */
* IN http_message_t* request : HTTP request void soap_device_callback(
* INOUT SOCKINFO *info : socket info /*! [in] Parsed request received by the device. */
* http_parser_t *parser,
* Description : This is a callback called by minisever after receiving /*! [in] HTTP request. */
* the request from the control point. This function will start http_message_t *request,
* processing the request. It calls handle_invoke_action to handle the /*! [in,out] Socket info. */
* SOAP action SOCKINFO *info)
*
* Return : void
*
* Note :
****************************************************************************/
void soap_device_callback(IN http_parser_t *parser, IN http_message_t *request,
INOUT SOCKINFO *info)
{ {
int err_code; int err_code;
const char *err_str; const char *err_str;