📄 soap_device.c
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000-2003 Intel Corporation // 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./////////////////////////////////////////////////////////////////////////////#ifdef INCLUDE_DEVICE_APIS#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 "config.h"#include "upnpapi.h"#include "parsetools.h"#include "statcodes.h"#include "httpparser.h"#include "httpreadwrite.h"#include "unixutil.h"// timeout duration in secs for transmission/reception#define SOAP_TIMEOUT UPNP_TIMEOUT#define SREQ_HDR_NOT_FOUND -1#define SREQ_BAD_HDR_FORMAT -2#define SOAP_INVALID_ACTION 401#define SOAP_INVALID_ARGS 402#define SOAP_OUT_OF_SYNC 403#define SOAP_INVALID_VAR 404#define SOAP_ACTION_FAILED 501static const char *Soap_Invalid_Action = "Invalid Action";//static const char* Soap_Invalid_Args = "Invalid Args";static const char *Soap_Action_Failed = "Action Failed";static const char *Soap_Invalid_Var = "Invalid Var";const char *ContentTypeHeader = "CONTENT-TYPE: text/xml; charset=\"utf-8\"\r\n";/***************************************************************************** Function : get_request_type** Parameters :* IN http_message_t* request : HTTP request* OUT memptr* action_name : SOAP action name** Description : This function retrives the name of the SOAP action** Return : int* 0 if successful else returns appropriate error.* Note :****************************************************************************/static XINLINE intget_request_type( IN http_message_t * request, OUT memptr * action_name ){ memptr value; memptr ns_value, dummy_quote; http_header_t *hdr; char save_char; char *s; membuffer soap_action_name; // find soapaction header // if( request->method == SOAPMETHOD_POST ) { if( httpmsg_find_hdr( request, HDR_SOAPACTION, &value ) == NULL ) { return SREQ_HDR_NOT_FOUND; } } else // M-POST { // get NS value from MAN header hdr = httpmsg_find_hdr( request, HDR_MAN, &value ); if( hdr == NULL ) { return SREQ_HDR_NOT_FOUND; } if( matchstr( value.buf, value.length, "%q%i ; ns = %s", &dummy_quote, &ns_value ) != 0 ) { return SREQ_BAD_HDR_FORMAT; } // create soapaction name header membuffer_init( &soap_action_name ); if( ( membuffer_assign( &soap_action_name, ns_value.buf, ns_value.length ) == UPNP_E_OUTOF_MEMORY ) || ( membuffer_append_str( &soap_action_name, "-SOAPACTION" ) == UPNP_E_OUTOF_MEMORY ) ) { membuffer_destroy( &soap_action_name ); return UPNP_E_OUTOF_MEMORY; } hdr = httpmsg_find_hdr_str( request, soap_action_name.buf ); membuffer_destroy( &soap_action_name ); if( hdr == NULL ) { return SREQ_HDR_NOT_FOUND; } value.buf = hdr->value.buf; value.length = hdr->value.length; } // determine type // save_char = value.buf[value.length]; value.buf[value.length] = '\0'; s = strchr( value.buf, '#' ); if( s == NULL ) { value.buf[value.length] = save_char; return SREQ_BAD_HDR_FORMAT; } s++; // move to value if( matchstr( s, value.length - ( s - value.buf ), "%s", action_name ) != PARSE_OK ) { value.buf[value.length] = save_char; return SREQ_BAD_HDR_FORMAT; } // action name or variable ? if( memptr_cmp( action_name, "QueryStateVariable" ) == 0 ) { // query variable action_name->buf = NULL; action_name->length = 0; } value.buf[value.length] = save_char; // restore return 0;}/***************************************************************************** Function : send_error_response** Parameters :* IN SOCKINFO *info : socket info* IN int error_code : error code* IN const char* err_msg : error message* IN http_message_t* hmsg : HTTP request** Description : This function sends SOAP error response** Return : void** Note :****************************************************************************/static voidsend_error_response( IN SOCKINFO * info, IN int error_code, IN const char *err_msg, IN http_message_t * hmsg ){ int content_length; int timeout_secs = SOAP_TIMEOUT; int major, minor; const char *start_body = "<s:Envelope\n" "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" "<s:Body>\n" "<s:Fault>\n" "<faultcode>s:Client</faultcode>\n" "<faultstring>UPnPError</faultstring>\n" "<detail>\n" "<UPnPError xmlns=\"urn:schemas-upnp-org:control-1-0\">\n" "<errorCode>"; const char *mid_body = "</errorCode>\n" "<errorDescription>"; const char *end_body = "</errorDescription>\n" "</UPnPError>\n" "</detail>\n" "</s:Fault>\n" "</s:Body>\n" "</s:Envelope>\n"; char err_code_str[30]; membuffer headers; sprintf( err_code_str, "%d", error_code ); // calc body len content_length = strlen( start_body ) + strlen( err_code_str ) + strlen( mid_body ) + strlen( err_msg ) + strlen( end_body ); http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, &major, &minor ); // make headers membuffer_init( &headers ); if( http_MakeMessage( &headers, major, minor, "RNsDsSc" "sssss", 500, content_length, ContentTypeHeader, "EXT:\r\n", start_body, err_code_str, mid_body, err_msg, end_body ) != 0 ) { membuffer_destroy( &headers ); return; // out of mem } // send err msg http_SendMessage( info, &timeout_secs, "b", headers.buf, headers.length ); membuffer_destroy( &headers );}/***************************************************************************** Function : send_var_query_response** Parameters :* IN SOCKINFO *info : socket info* IN const char* var_value : value of the state variable* IN http_message_t* hmsg : HTTP request** Description : This function sends response of get var status** Return : void** Note :****************************************************************************/static XINLINE voidsend_var_query_response( IN SOCKINFO * info, IN const char *var_value, IN http_message_t * hmsg ){ int content_length; int timeout_secs = SOAP_TIMEOUT; int major, minor; const char *start_body = "<s:Envelope\n" "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n" "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n" "<s:Body>\n" "<u:QueryStateVariableResponse " "xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n" "<return>"; const char *end_body = "</return>\n" "</u:QueryStateVariableResponse>\n" "</s:Body>\n" "</s:Envelope>\n"; membuffer response; http_CalcResponseVersion( hmsg->major_version, hmsg->minor_version, &major, &minor ); content_length = strlen( start_body ) + strlen( var_value ) + strlen( end_body ); // make headers membuffer_init( &response ); if( http_MakeMessage( &response, major, minor, "RNsDsSc" "sss", HTTP_OK, content_length, ContentTypeHeader, "EXT:\r\n", start_body, var_value, end_body ) != 0 ) { membuffer_destroy( &response ); return; // out of mem } // send msg http_SendMessage( info, &timeout_secs, "b", response.buf, response.length ); membuffer_destroy( &response );}/***************************************************************************** Function : get_action_node** Parameters :* IN IXML_Document *TempDoc : The root DOM node.* IN char *NodeName : IXML_Node name to be searched.* OUT IXML_Document ** RespNode : Response/Output node.** Description : This function separates the action node from * the root DOM node.** Return : static XINLINE int* 0 if successful, or -1 if fails.** Note :****************************************************************************/static XINLINE intget_action_node( IN IXML_Document * TempDoc, IN char *NodeName, OUT IXML_Document ** RespNode ){ IXML_Node *EnvpNode = NULL; IXML_Node *BodyNode = NULL; IXML_Node *ActNode = NULL; DOMString ActNodeName = NULL; const DOMString nodeName; int ret_code = -1; // error, by default IXML_NodeList *nl = NULL; DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "get_action_node(): node name =%s\n ", NodeName ); ) * RespNode = NULL; // Got the Envelope node here EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc ); if( EnvpNode == NULL ) { goto error_handler; } nl = ixmlElement_getElementsByTagNameNS( ( IXML_Element * ) EnvpNode, "*", "Body" ); if( nl == NULL ) { goto error_handler; } BodyNode = ixmlNodeList_item( nl, 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -