⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 soap_ctrlpt.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 2 页
字号:
/////////////////////////////////////////////////////////////////////////////// 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_CLIENT_APIS#if EXCLUDE_SOAP == 0#include <assert.h>#include <stdlib.h>#include <ctype.h>#include <stdio.h>#include <stdarg.h>#include "config.h"#include "miniserver.h"#include "membuffer.h"#include "httpparser.h"#include "httpreadwrite.h"#include "statcodes.h"#include "parsetools.h"#include "upnpapi.h"#include "soaplib.h"#include "uri.h"#include "upnp.h"#include "unixutil.h"#define SOAP_ACTION_RESP	1#define SOAP_VAR_RESP		2//#define SOAP_ERROR_RESP       3#define SOAP_ACTION_RESP_ERROR  3#define SOAP_VAR_RESP_ERROR   4/*****************************************************************************	Function :	dom_cmp_name**	Parameters :*			IN char *name :	lookup name*			IN IXML_Node *node : xml node**	Description : This function compares 'name' and node's name	**	Return : int*		0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY**	Note :****************************************************************************/static intdom_cmp_name( IN char *name,              IN IXML_Node * node ){    const DOMString node_name = NULL;    memptr nameptr,      dummy;    int ret_code;    assert( name );    assert( node );    node_name = ixmlNode_getNodeName( node );    if( node_name == NULL ) {        return UPNP_E_OUTOF_MEMORY;    }    if( strcmp( name, node_name ) == 0 ) {        ret_code = 0;    } else if( matchstr( ( char * )node_name, strlen( node_name ),                         "%s:%s%0", &dummy, &nameptr ) == PARSE_OK &&               strcmp( nameptr.buf, name ) == 0 ) {        ret_code = 0;    } else {        ret_code = 1;           // names are not the same    }    return ret_code;}/*****************************************************************************	Function :	dom_find_node**	Parameters :*			IN char* node_name : name of the node	*			IN IXML_Node *start_node :	complete xml node*			OUT IXML_Node ** matching_node : matched node**	Description :	This function goes thru each child of 'start_node' *		looking for a node having the name 'node_name'. **	Return : int*		return UPNP_E_SUCCESS if successful else returns appropriate error**	Note :****************************************************************************/static intdom_find_node( IN char *node_name,               IN IXML_Node * start_node,               OUT IXML_Node ** matching_node ){    IXML_Node *node;    // invalid args    if( node_name == NULL || start_node == NULL ) {        return UPNP_E_NOT_FOUND;    }    node = ixmlNode_getFirstChild( start_node );    while( node != NULL ) {        // match name        if( dom_cmp_name( node_name, node ) == 0 ) {            *matching_node = node;            return UPNP_E_SUCCESS;        }        // free and next node        node = ixmlNode_getNextSibling( node ); // next node    }    return UPNP_E_NOT_FOUND;}/*****************************************************************************	Function :	dom_find_deep_node**	Parameters :*			IN char* names[] : array of names*			IN int num_names :	size of array*			IN IXML_Node *start_node : Node from where it should should be *										searched	*			OUT IXML_Node ** matching_node : Node that matches the last name*											of the array**	Description :	This function searches for the node specifed by the last *		name in the 'name' array.**	Return : int*		return UPNP_E_SUCCESS if successful else returns appropriate error*	Note :****************************************************************************/static intdom_find_deep_node( IN char *names[],                    IN int num_names,                    IN IXML_Node * start_node,                    OUT IXML_Node ** matching_node ){    int i;    IXML_Node *node;    IXML_Node *match_node;    assert( num_names > 0 );    node = start_node;    if( dom_cmp_name( names[0], start_node ) == 0 ) {        if( num_names == 1 ) {            *matching_node = start_node;            return UPNP_E_SUCCESS;        }    }    for( i = 1; i < num_names; i++ ) {        if( dom_find_node( names[i], node, &match_node ) !=            UPNP_E_SUCCESS ) {            return UPNP_E_NOT_FOUND;        }        if( i == num_names - 1 ) {            *matching_node = match_node;            return UPNP_E_SUCCESS;        }        node = match_node;      // try again    }    return UPNP_E_NOT_FOUND;    // this line not reached}/*****************************************************************************	Function :	get_node_value**	Parameters :*			IN IXML_Node *node : input node	**	Description :	This function returns the value of the text node**	Return : DOMString*		string containing the node value**	Note :The given node must have a text node as its first child****************************************************************************/static DOMStringget_node_value( IN IXML_Node * node ){    IXML_Node *text_node = NULL;    DOMString text_value = NULL;    text_node = ixmlNode_getFirstChild( node );    if( text_node == NULL ) {        return NULL;    }    text_value = ixmlNode_getNodeValue( text_node );    return text_value;}/*****************************************************************************	Function :	get_host_and_path**	Parameters :*			IN char *ctrl_url :	URL *			OUT memptr *host :	host string*			OUT memptr *path :	path string*			OUT uri_type* url :	URL type**	Description :	This function retrives the host and path from the *		control URL**	Return : int*		returns 0 on sucess; -1 on error**	Note :****************************************************************************/static XINLINE intget_host_and_path( IN char *ctrl_url,                   OUT memptr * host,                   OUT memptr * path,                   OUT uri_type * url ){    if( parse_uri( ctrl_url, strlen( ctrl_url ), url ) != HTTP_SUCCESS ) {        return -1;    }    host->buf = url->hostport.text.buff;    host->length = url->hostport.text.size;    path->buf = url->pathquery.buff;    path->length = url->pathquery.size;    return 0;}/*****************************************************************************	Function :	get_action_name**	Parameters :*			IN char* action :	string containing action name*			OUT memptr* name : name of the action	**	Description :	This functions retirves the action name in the buffer**	Return : int*		returns 0 on success; -1 on error**	Note :****************************************************************************/static XINLINE intget_action_name( IN char *action,                 OUT memptr * name ){    memptr dummy;    int ret_code;    ret_code =        matchstr( action, strlen( action ), " <%s:%s", &dummy, name );    return ret_code == PARSE_OK ? 0 : -1;}/*****************************************************************************	Function :	add_man_header**	Parameters :*			INOUT membuffer* headers :	HTTP header**	Description :	This function adds "MAN" field in the HTTP header**	Return : int*		returns 0 on success; UPNP_E_OUTOFMEMORY on error**	Note :****************************************************************************/static XINLINE intadd_man_header( INOUT membuffer * headers ){    char *soap_action_hdr;    char *man_hdr = "MAN: \"http://schemas.xmlsoap.org/soap/envelope/\"; "        "ns=01\r\n01-";    // change POST to M-POST    if( membuffer_insert( headers, "M-", 2, 0 ) != 0 ) {        return UPNP_E_OUTOF_MEMORY;    }    soap_action_hdr = strstr( headers->buf, "SOAPACTION:" );    assert( soap_action_hdr != NULL );  // can't fail    // insert MAN header    if( membuffer_insert( headers, man_hdr, strlen( man_hdr ),                          soap_action_hdr - headers->buf ) != 0 ) {        return UPNP_E_OUTOF_MEMORY;    }    return 0;}/*****************************************************************************	Function :	soap_request_and_response**	Parameters :*		IN membuffer* request :	request that will be sent to the device*		IN uri_type* destination_url :	destination address string*		OUT http_parser_t *response :	response from the device**	Description :	This function sends the control point's request to the *		device and receives a response from it.**	Return : int**	Note :****************************************************************************/static intsoap_request_and_response( IN membuffer * request,                           IN uri_type * destination_url,                           OUT http_parser_t * response ){    int ret_code;    ret_code = http_RequestAndResponse( destination_url, request->buf,                                        request->length,                                        SOAPMETHOD_POST,                                        UPNP_TIMEOUT, response );    if( ret_code != 0 ) {        httpmsg_destroy( &response->msg );        return ret_code;    }    // method-not-allowed error    if( response->msg.status_code == HTTP_METHOD_NOT_ALLOWED ) {        ret_code = add_man_header( request );   // change to M-POST msg        if( ret_code != 0 ) {            return ret_code;        }        httpmsg_destroy( &response->msg );  // about to reuse response        // try again        ret_code = http_RequestAndResponse( destination_url, request->buf,                                            HTTPMETHOD_MPOST,                                            request->length, UPNP_TIMEOUT,                                            response );        if( ret_code != 0 ) {            httpmsg_destroy( &response->msg );        }    }    return ret_code;}/*****************************************************************************	Function :	get_response_value**	Parameters :*			IN http_message_t* hmsg :	HTTP response message*			IN int code :	return code in the HTTP response*			IN char*name :	name of the action*			OUT int *upnp_error_code :	UPnP error code*			OUT IXML_Node ** action_value :	SOAP response node *			OUT DOMString * str_value : state varible value ( in the case of *							querry state variable request)	**	Description :	This function handles the response coming back from the *		device. This function parses the response and gives back the SOAP *		response node.**	Return : int*		return the type of the SOAP message if successful else returns *	appropriate error.**	Note :****************************************************************************/static intget_response_value( IN http_message_t * hmsg,                    IN int code,                    IN char *name,                    OUT int *upnp_error_code,                    OUT IXML_Node ** action_value,                    OUT DOMString * str_value ){    IXML_Node *node = NULL;    IXML_Node *root_node = NULL;    IXML_Node *error_node = NULL;    IXML_Document *doc = NULL;    char *node_str = NULL;    char *temp_str = NULL;    DOMString error_node_str = NULL;    int err_code;    xboolean done = FALSE;    char *names[5];    DOMString nodeValue;    err_code = UPNP_E_BAD_RESPONSE; // default error    // only 200 and 500 status codes are relevant    if( ( hmsg->status_code != HTTP_OK &&          hmsg->status_code != HTTP_INTERNAL_SERVER_ERROR ) ||        !has_xml_content_type( hmsg ) ) {        goto error_handler;    }    if( ixmlParseBufferEx( hmsg->entity.buf, &doc ) != IXML_SUCCESS ) {        goto error_handler;    }    root_node = ixmlNode_getFirstChild( ( IXML_Node * ) doc );    if( root_node == NULL ) {        goto error_handler;    }    if( code == SOAP_ACTION_RESP ) {        //        // try reading soap action response        //        assert( action_value != NULL );        *action_value = NULL;        names[0] = "Envelope";        names[1] = "Body";        names[2] = name;        if( dom_find_deep_node( names, 3, root_node, &node ) ==            UPNP_E_SUCCESS ) {            node_str = ixmlPrintDocument( node );            if( node_str == NULL ) {                err_code = UPNP_E_OUTOF_MEMORY;                goto error_handler;            }            if( ixmlParseBufferEx( node_str,                                   ( IXML_Document ** ) action_value ) !=                IXML_SUCCESS ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -