soap_ctrlpt.c
来自「原来由英特尔制定的UPnP SDK的」· C语言 代码 · 共 966 行 · 第 1/2 页
C
966 行
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 = ixmlPrintNode( 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 :****************************************************************************/intSoapSendAction( 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; off_t content_length; char *xml_start = "<s:Envelope " "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" "<s:Body>"; char *xml_end = "</s:Body>\r\n" "</s:Envelope>\r\n\r\n"; size_t xml_start_len; size_t xml_end_len; size_t action_str_len; *response_node = NULL; // init err_code = UPNP_E_OUTOF_MEMORY; // default error UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Inside SoapSendAction():" ); // init membuffer_init( &request ); membuffer_init( &responsename ); // print action action_str = ixmlPrintNode( ( 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; } UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "path=%.*s, hostport=%.*s\n", (int)url.pathquery.size, url.pathquery.buff, (int)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; content_length = xml_start_len + action_str_len + xml_end_len; if (http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbsc" "Uc" "b" "b" "b", SOAPMETHOD_POST, &url, content_length, ContentTypeHeader, "SOAPACTION: \"", service_type, "#", name.buf, name.length, "\"", 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 :****************************************************************************/intSoapSendActionEx( 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/\" " "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n"; char *xml_header_start = "<s:Header>\r\n"; char *xml_header_end = "</s:Header>\r\n"; char *xml_body_start = "<s:Body>"; char *xml_end = "</s:Body>\r\n" "</s:Envelope>\r\n"; size_t xml_start_len; size_t xml_header_start_len; size_t xml_header_str_len; size_t xml_header_end_len; size_t xml_body_start_len; size_t action_str_len; size_t xml_end_len; off_t content_length; *response_node = NULL; // init err_code = UPNP_E_OUTOF_MEMORY; // default error UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Inside SoapSendActionEx():" ); // init membuffer_init( &request ); membuffer_init( &responsename ); // header string xml_header_str = ixmlPrintNode( ( IXML_Node * ) header ); if( xml_header_str == NULL ) { goto error_handler; } // print action action_str = ixmlPrintNode( ( 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; } UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "path=%.*s, hostport=%.*s\n", (int)url.pathquery.size, url.pathquery.buff, (int)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; content_length = 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; if (http_MakeMessage( &request, 1, 1, "q" "N" "s" "sssbsc" "Uc" "b" "b" "b" "b" "b" "b" "b", SOAPMETHOD_POST, &url, content_length, ContentTypeHeader, "SOAPACTION: \"", service_type, "#", name.buf, name.length, "\"", 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 :****************************************************************************/intSoapGetServiceVarStatus( IN char *action_url, IN char *var_name, OUT char **var_value ){ const memptr host; // value for HOST header const 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; off_t content_length; char *xml_start = "<s:Envelope " "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" " "s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">\r\n" "<s:Body>\r\n" "<u:QueryStateVariable xmlns:u=\"urn:schemas-upnp-org:control-1-0\">\r\n" "<u:varName>"; char *xml_end = "</u:varName>\r\n" "</u:QueryStateVariable>\r\n" "</s:Body>\r\n" "</s:Envelope>\r\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; content_length = strlen( xml_start ) + strlen( var_name ) + strlen( xml_end ); if (http_MakeMessage( &request, 1, 1, "Q" "sbc" "N" "s" "s" "Ucc" "sss", SOAPMETHOD_POST, path.buf, path.length, "HOST: ", host.buf, host.length, content_length, ContentTypeHeader, "SOAPACTION: \"urn:schemas-upnp-org:control-1-0#QueryStateVariable\"", 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 + =
减小字号Ctrl + -
显示快捷键?