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

📄 soap_ctrlpt.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 2 页
字号:
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;
                goto error_handler;
            }

            err_code = SOAP_ACTION_RESP;
            done = TRUE;
        }
    } else if( code == SOAP_VAR_RESP ) {
        // try reading var response
        assert( str_value != NULL );
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "QueryStateVariableResponse";
        names[3] = "return";
        if( dom_find_deep_node( names, 4, root_node, &node )
            == UPNP_E_SUCCESS ) {
            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }

            *str_value = ixmlCloneDOMString( nodeValue );
            err_code = SOAP_VAR_RESP;
            done = TRUE;
        }
    }

    if( !done ) {
        // not action or var resp; read error code and description
        *str_value = NULL;

        names[0] = "Envelope";
        names[1] = "Body";
        names[2] = "Fault";
        names[3] = "detail";
        names[4] = "UPnPError";
        if( dom_find_deep_node( names, 5, root_node, &error_node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        if( dom_find_node( "errorCode", error_node, &node )
            != UPNP_E_SUCCESS ) {
            goto error_handler;
        }

        temp_str = get_node_value( node );
        if( temp_str == NULL ) {
            goto error_handler;
        }

        *upnp_error_code = atoi( temp_str );
        if( *upnp_error_code < 400 ) {
            err_code = *upnp_error_code;
            goto error_handler; // bad SOAP error code
        }

        if( code == SOAP_VAR_RESP ) {
            if( dom_find_node( "errorDescription", error_node, &node )
                != UPNP_E_SUCCESS ) {
                goto error_handler;
            }

            nodeValue = get_node_value( node );
            if( nodeValue == NULL ) {
                goto error_handler;
            }
            *str_value = ixmlCloneDOMString( nodeValue );
            if( *str_value == NULL ) {
                goto error_handler;
            }
            err_code = SOAP_VAR_RESP_ERROR;
        }

        else if( code == SOAP_ACTION_RESP ) {
            error_node_str = ixmlPrintDocument( error_node );
            if( error_node_str == NULL ) {
                err_code = UPNP_E_OUTOF_MEMORY;
                goto error_handler;
            }

            if( ixmlParseBufferEx( error_node_str,
                                   ( IXML_Document ** ) action_value ) !=
                IXML_SUCCESS ) {
                err_code = UPNP_E_BAD_RESPONSE;

                goto error_handler;
            }
            err_code = SOAP_ACTION_RESP_ERROR;
        }
    }

  error_handler:

    ixmlDocument_free( doc );
    ixmlFreeDOMString( node_str );
    ixmlFreeDOMString( error_node_str );
    return err_code;
}

/****************************************************************************
*	Function :	SoapSendAction
*
*	Parameters :
*		IN char* action_url :	device contrl URL 
*		IN char *service_type :	device service type
*		IN IXML_Document *action_node : SOAP action node	
*		OUT IXML_Document **response_node :	SOAP response node
*
*	Description :	This function is called by UPnP API to send the SOAP 
*		action request and waits till it gets the response from the device
*		pass the response to the API layer
*
*	Return :	int
*		returns UPNP_E_SUCCESS if successful else returns appropriate error
*	Note :
****************************************************************************/
int
SoapSendAction( IN char *action_url,
                IN char *service_type,
                IN IXML_Document * action_node,
                OUT IXML_Document ** response_node )
{
    char *action_str = NULL;
    memptr name;
    membuffer request;
    membuffer responsename;
    int err_code;
    int ret_code;
    http_parser_t response;
    uri_type url;
    int upnp_error_code;
    char *upnp_error_str;
    xboolean got_response = FALSE;

    char *xml_start =
        "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
        "<s:Body>";
    char *xml_end = "</s:Body>\n" "</s:Envelope>\n";
    int xml_start_len;
    int xml_end_len;
    int action_str_len;

    *response_node = NULL;      // init

    err_code = UPNP_E_OUTOF_MEMORY; // default error

    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
                         "Inside SoapSendAction():" );
         )
        // init
        membuffer_init( &request );
    membuffer_init( &responsename );

    // print action
    action_str = ixmlPrintDocument( ( IXML_Node * ) action_node );
    if( action_str == NULL ) {
        goto error_handler;
    }
    // get action name
    if( get_action_name( action_str, &name ) != 0 ) {
        err_code = UPNP_E_INVALID_ACTION;
        goto error_handler;
    }
    // parse url
    if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
        err_code = UPNP_E_INVALID_URL;
        goto error_handler;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
                         "path=%.*s, hostport=%.*s\n",
                         url.pathquery.size, url.pathquery.buff,
                         url.hostport.text.size,
                         url.hostport.text.buff ); )

        xml_start_len = strlen( xml_start );
    xml_end_len = strlen( xml_end );
    action_str_len = strlen( action_str );

    // make request msg
    request.size_inc = 50;
    if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "U" "c" "bbb", SOAPMETHOD_POST, &url, xml_start_len + action_str_len + xml_end_len,   // content-length
                          ContentTypeHeader,
                          "SOAPACTION: \"", service_type, "#", name.buf,
                          name.length, "\"\r\n", xml_start, xml_start_len,
                          action_str, action_str_len, xml_end,
                          xml_end_len ) != 0 ) {
        goto error_handler;
    }

    ret_code = soap_request_and_response( &request, &url, &response );
    got_response = TRUE;
    if( ret_code != UPNP_E_SUCCESS ) {
        err_code = ret_code;
        goto error_handler;
    }

    if( membuffer_append( &responsename, name.buf, name.length ) != 0 ||
        membuffer_append_str( &responsename, "Response" ) != 0 ) {
        goto error_handler;
    }
    // get action node from the response
    ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
                                   responsename.buf, &upnp_error_code,
                                   ( IXML_Node ** ) response_node,
                                   &upnp_error_str );

    if( ret_code == SOAP_ACTION_RESP ) {
        err_code = UPNP_E_SUCCESS;
    } else if( ret_code == SOAP_ACTION_RESP_ERROR ) {
        err_code = upnp_error_code;
    } else {
        err_code = ret_code;
    }

  error_handler:
    ixmlFreeDOMString( action_str );
    membuffer_destroy( &request );
    membuffer_destroy( &responsename );
    if( got_response ) {
        httpmsg_destroy( &response.msg );
    }

    return err_code;
}

/****************************************************************************
*	Function :	SoapSendActionEx
*
*	Parameters :
*		IN char* action_url :	device contrl URL 
*		IN char *service_type :	device service type
		IN IXML_Document *Header: Soap header
*		IN IXML_Document *action_node : SOAP action node ( SOAP body)	
*		OUT IXML_Document **response_node :	SOAP response node
*
*	Description :	This function is called by UPnP API to send the SOAP 
*		action request and waits till it gets the response from the device
*		pass the response to the API layer. This action is similar to the 
*		the SoapSendAction with only difference that it allows users to 
*		pass the SOAP header along the SOAP body ( soap action request)
*
*	Return :	int
*		returns UPNP_E_SUCCESS if successful else returns appropriate error
*	Note :
****************************************************************************/
int
SoapSendActionEx( IN char *action_url,
                  IN char *service_type,
                  IN IXML_Document * header,
                  IN IXML_Document * action_node,
                  OUT IXML_Document ** response_node )
{
    char *xml_header_str = NULL;
    char *action_str = NULL;
    memptr name;
    membuffer request;
    membuffer responsename;
    int err_code;
    int ret_code;
    http_parser_t response;
    uri_type url;
    int upnp_error_code;
    char *upnp_error_str;
    xboolean got_response = FALSE;

    char *xml_start =
        "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n";
    char *xml_body_start = "<s:Body>";
    char *xml_end = "</s:Body>\n" "</s:Envelope>\n";
    int xml_start_len;
    int xml_end_len;
    char *xml_header_start = "<s:Header>\n";
    char *xml_header_end = "</s:Header>\n";
    int xml_header_start_len;
    int xml_header_end_len;
    int xml_header_str_len;
    int action_str_len;
    int xml_body_start_len;

    *response_node = NULL;      // init

    err_code = UPNP_E_OUTOF_MEMORY; // default error

    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
                         "Inside SoapSendActionEx():" );
         )
        // init
        membuffer_init( &request );
    membuffer_init( &responsename );

    // header string
    xml_header_str = ixmlPrintDocument( ( IXML_Node * ) header );
    if( xml_header_str == NULL ) {
        goto error_handler;
    }
    // print action
    action_str = ixmlPrintDocument( ( IXML_Node * ) action_node );
    if( action_str == NULL ) {
        goto error_handler;
    }
    // get action name
    if( get_action_name( action_str, &name ) != 0 ) {
        err_code = UPNP_E_INVALID_ACTION;
        goto error_handler;
    }
    // parse url
    if( http_FixStrUrl( action_url, strlen( action_url ), &url ) != 0 ) {
        err_code = UPNP_E_INVALID_URL;
        goto error_handler;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__,
                         "path=%.*s, hostport=%.*s\n",
                         url.pathquery.size, url.pathquery.buff,
                         url.hostport.text.size,
                         url.hostport.text.buff ); )

        xml_start_len = strlen( xml_start );
    xml_body_start_len = strlen( xml_body_start );
    xml_end_len = strlen( xml_end );
    action_str_len = strlen( action_str );

    xml_header_start_len = strlen( xml_header_start );
    xml_header_end_len = strlen( xml_header_end );
    xml_header_str_len = strlen( xml_header_str );

    // make request msg
    request.size_inc = 50;
    if( http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbs" "U" "c" "bbbbbbb", SOAPMETHOD_POST, &url, xml_start_len + xml_header_start_len + xml_header_str_len + xml_header_end_len + xml_body_start_len + action_str_len + xml_end_len, // content-length
                          ContentTypeHeader,
                          "SOAPACTION: \"", service_type, "#", name.buf,
                          name.length, "\"\r\n",
                          xml_start, xml_start_len,
                          xml_header_start, xml_header_start_len,
                          xml_header_str, xml_header_str_len,
                          xml_header_end, xml_header_end_len,
                          xml_body_start, xml_body_start_len,
                          action_str, action_str_len,
                          xml_end, xml_end_len ) != 0 ) {
        goto error_handler;
    }

    ret_code = soap_request_and_response( &request, &url, &response );
    got_response = TRUE;
    if( ret_code != UPNP_E_SUCCESS ) {
        err_code = ret_code;
        goto error_handler;
    }

    if( membuffer_append( &responsename, name.buf, name.length ) != 0 ||
        membuffer_append_str( &responsename, "Response" ) != 0 ) {
        goto error_handler;
    }
    // get action node from the response
    ret_code = get_response_value( &response.msg, SOAP_ACTION_RESP,
                                   responsename.buf, &upnp_error_code,
                                   ( IXML_Node ** ) response_node,
                                   &upnp_error_str );

    if( ret_code == SOAP_ACTION_RESP ) {
        err_code = UPNP_E_SUCCESS;
    } else if( ret_code == SOAP_ACTION_RESP_ERROR ) {
        err_code = upnp_error_code;
    } else {
        err_code = ret_code;
    }

  error_handler:

    ixmlFreeDOMString( action_str );
    ixmlFreeDOMString( xml_header_str );
    membuffer_destroy( &request );
    membuffer_destroy( &responsename );
    if( got_response ) {
        httpmsg_destroy( &response.msg );
    }

    return err_code;
}

/****************************************************************************
*	Function :	SoapGetServiceVarStatus
*
*	Parameters :
*			IN  char * action_url :	Address to send this variable 
*									query message.
*			IN  char *var_name : Name of the variable.
*			OUT char **var_value :	Output value.
*
*	Description :	This function creates a status variable query message 
*		send it to the specified URL. It also collect the response.
*
*	Return :	int
*
*	Note :
****************************************************************************/
int
SoapGetServiceVarStatus( IN char *action_url,
                         IN char *var_name,
                         OUT char **var_value )
{
    memptr host;                // value for HOST header
    memptr path;                // ctrl path in first line in msg
    uri_type url;
    membuffer request;
    int ret_code;
    http_parser_t response;
    int upnp_error_code;

    char *xml_start =
        "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"\n"
        "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\n"
        "<s:Body>\n"
        "<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\n"
        "<u:varName>";

    char *xml_end = "</u:varName>\n"
        "</u:QueryStateVariable>\n" "</s:Body>\n" "</s:Envelope>\n";

    *var_value = NULL;          // return NULL in case of an error

    membuffer_init( &request );

    // get host hdr and url path
    if( get_host_and_path( action_url, &host, &path, &url ) == -1 ) {
        return UPNP_E_INVALID_URL;
    }
    // make headers
    request.size_inc = 50;
    if( http_MakeMessage( &request, 1, 1, "Q" "sbc" "N" "s" "s" "U" "c" "sss", SOAPMETHOD_POST, path.buf, path.length, "HOST: ", host.buf, host.length, strlen( xml_start ) + strlen( var_name ) + strlen( xml_end ),   // content-length
                          ContentTypeHeader,
                          "SOAPACTION: \"urn:schemas"
                          "-upnp-org:control-1-0#QueryStateVariable\"\r\n",
                          xml_start, var_name, xml_end ) != 0 ) {
        return UPNP_E_OUTOF_MEMORY;
    }
    // send msg and get reply
    ret_code = soap_request_and_response( &request, &url, &response );
    membuffer_destroy( &request );
    if( ret_code != UPNP_E_SUCCESS ) {
        return ret_code;
    }
    // get variable value from the response
    ret_code = get_response_value( &response.msg, SOAP_VAR_RESP, NULL,
                                   &upnp_error_code, NULL, var_value );

    httpmsg_destroy( &response.msg );

    if( ret_code == SOAP_VAR_RESP ) {
        return UPNP_E_SUCCESS;
    } else if( ret_code == SOAP_VAR_RESP_ERROR ) {
        return upnp_error_code;
    } else {
        return ret_code;
    }
}

#endif // EXCLUDE_SOAP
#endif // INCLUDE_CLIENT_APIS

⌨️ 快捷键说明

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