📄 soap_ctrlpt.c
字号:
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 + -