📄 soap_device.c
字号:
if( http_MakeMessage( &headers, major, minor, "RNsDsSc", HTTP_OK, // status code content_length, ContentTypeHeader, "EXT:\r\n" // EXT header ) != 0 ) { goto error_handler; } // send whole msg ret_code = http_SendMessage( info, &timeout_secs, "bbbb", headers.buf, headers.length, start_body, strlen( start_body ), xml_response, strlen( xml_response ), end_body, strlen( end_body ) ); DBGONLY( if( ret_code != 0 ) { UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Failed to send response: err code = %d\n", ret_code );} ) err_code = 0; error_handler: ixmlFreeDOMString( xml_response ); membuffer_destroy( &headers ); if( err_code != 0 ) { // only one type of error to worry about - out of mem send_error_response( info, SOAP_ACTION_FAILED, "Out of memory", request ); }}/***************************************************************************** Function : get_var_name** Parameters :* IN IXML_Document *TempDoc : Document containing variable request* OUT char* VarName : Name of the state varible** Description : This function finds the name of the state variable * asked in the SOAP request.** Return : int* returns 0 if successful else returns -1.* Note :****************************************************************************/static XINLINE intget_var_name( IN IXML_Document * TempDoc, OUT char *VarName ){ IXML_Node *EnvpNode = NULL; IXML_Node *BodyNode = NULL; IXML_Node *StNode = NULL; IXML_Node *VarNameNode = NULL; IXML_Node *VarNode = NULL; const DOMString StNodeName = NULL; DOMString Temp = NULL; int ret_val = -1; // Got the Envelop node here EnvpNode = ixmlNode_getFirstChild( ( IXML_Node * ) TempDoc ); if( EnvpNode == NULL ) { goto error_handler; } // Got Body here BodyNode = ixmlNode_getFirstChild( EnvpNode ); if( BodyNode == NULL ) { goto error_handler; } // Got action node here StNode = ixmlNode_getFirstChild( BodyNode ); if( StNode == NULL ) { goto error_handler; } //Test whether this is the action node StNodeName = ixmlNode_getNodeName( StNode ); if( StNodeName == NULL || strstr( StNodeName, "QueryStateVariable" ) == NULL ) { goto error_handler; } VarNameNode = ixmlNode_getFirstChild( StNode ); if( VarNameNode == NULL ) { goto error_handler; } VarNode = ixmlNode_getFirstChild( VarNameNode ); Temp = ixmlNode_getNodeValue( VarNode ); linecopy( VarName, Temp ); DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Received query for variable name %s\n", VarName ); ) ret_val = 0; // success error_handler: return ret_val;}/***************************************************************************** Function : handle_query_variable** Parameters :* IN SOCKINFO *info : Socket info* IN http_message_t* request : HTTP request * IN IXML_Document *xml_doc : Document containing the variable request * SOAP message** Description : This action handles the SOAP requests to querry the * state variables. This functionality has been deprecated in * the UPnP V1.0 architecture** Return : void** Note :****************************************************************************/static XINLINE voidhandle_query_variable( IN SOCKINFO * info, IN http_message_t * request, IN IXML_Document * xml_doc ){ Upnp_FunPtr soap_event_callback; void *cookie; char var_name[LINE_SIZE]; struct Upnp_State_Var_Request variable; const char *err_str; int err_code; // get var name if( get_var_name( xml_doc, var_name ) != 0 ) { send_error_response( info, SOAP_INVALID_VAR, Soap_Invalid_Var, request ); return; } // get info for event if( get_device_info( request, 1, xml_doc, variable.DevUDN, variable.ServiceID, &soap_event_callback, &cookie ) != 0 ) { send_error_response( info, SOAP_INVALID_VAR, Soap_Invalid_Var, request ); return; } linecopy( variable.ErrStr, "" ); variable.ErrCode = UPNP_E_SUCCESS; namecopy( variable.StateVarName, var_name ); variable.CurrentVal = NULL; variable.CtrlPtIPAddr = info->foreign_ip_addr; // send event soap_event_callback( UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie ); DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Return from callback for var request\n" ) ); // validate, and handle result if( variable.CurrentVal == NULL ) { err_code = SOAP_ACTION_FAILED; err_str = Soap_Action_Failed; send_error_response( info, SOAP_INVALID_VAR, Soap_Invalid_Var, request ); return; } if( variable.ErrCode != UPNP_E_SUCCESS ) { if( strlen( variable.ErrStr ) > 0 ) { err_code = SOAP_INVALID_VAR; err_str = Soap_Invalid_Var; } else { err_code = variable.ErrCode; err_str = variable.ErrStr; } send_error_response( info, err_code, err_str, request ); return; } // send response send_var_query_response( info, variable.CurrentVal, request ); ixmlFreeDOMString( variable.CurrentVal );}/***************************************************************************** Function : handle_invoke_action** Parameters :* IN SOCKINFO *info : Socket info* IN http_message_t* request : HTTP Request * IN memptr action_name : Name of the SOAP Action* IN IXML_Document *xml_doc : document containing the SOAP action * request** Description : This functions handle the SOAP action request. It checks * the integrity of the SOAP action request and gives the call back to * the device application.** Return : void** Note :****************************************************************************/static voidhandle_invoke_action( IN SOCKINFO * info, IN http_message_t * request, IN memptr action_name, IN IXML_Document * xml_doc ){ char save_char; IXML_Document *resp_node = NULL; struct Upnp_Action_Request action; Upnp_FunPtr soap_event_callback; void *cookie = NULL; int err_code; const char *err_str; action.ActionResult = NULL; // null-terminate save_char = action_name.buf[action_name.length]; action_name.buf[action_name.length] = '\0'; // set default error err_code = SOAP_INVALID_ACTION; err_str = Soap_Invalid_Action; // get action node if( get_action_node( xml_doc, action_name.buf, &resp_node ) == -1 ) { goto error_handler; } // get device info for action event err_code = get_device_info( request, 0, xml_doc, action.DevUDN, action.ServiceID, &soap_event_callback, &cookie ); if( err_code != UPNP_E_SUCCESS ) { goto error_handler; } namecopy( action.ActionName, action_name.buf ); linecopy( action.ErrStr, "" ); action.ActionRequest = resp_node; action.ActionResult = NULL; action.ErrCode = UPNP_E_SUCCESS; action.CtrlPtIPAddr = info->foreign_ip_addr; DBGONLY( UpnpPrintf( UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n" ) ); soap_event_callback( UPNP_CONTROL_ACTION_REQUEST, &action, cookie ); if( action.ErrCode != UPNP_E_SUCCESS ) { if( strlen( action.ErrStr ) <= 0 ) { err_code = SOAP_ACTION_FAILED; err_str = Soap_Action_Failed; } else { err_code = action.ErrCode; err_str = action.ErrStr; } goto error_handler; } // validate, and handle action error if( action.ActionResult == NULL ) { err_code = SOAP_ACTION_FAILED; err_str = Soap_Action_Failed; goto error_handler; } // send response send_action_response( info, action.ActionResult, request ); err_code = 0; // error handling and cleanup error_handler: ixmlDocument_free( action.ActionResult ); ixmlDocument_free( resp_node ); action_name.buf[action_name.length] = save_char; // restore if( err_code != 0 ) { send_error_response( info, err_code, err_str, request ); }}/***************************************************************************** Function : soap_device_callback** Parameters :* IN http_parser_t *parser : Parsed request received by the device* IN http_message_t* request : HTTP request * INOUT SOCKINFO *info : socket info** Description : This is a callback called by minisever after receiving * the request from the control point. This function will start * processing the request. It calls handle_invoke_action to handle the* SOAP action** Return : void** Note :****************************************************************************/voidsoap_device_callback( IN http_parser_t * parser, IN http_message_t * request, INOUT SOCKINFO * info ){ int err_code; const char *err_str; memptr action_name; IXML_Document *xml_doc = NULL; // set default error err_code = SOAP_INVALID_ACTION; err_str = Soap_Invalid_Action; // validate: content-type == text/xml if( !has_xml_content_type( request ) ) { goto error_handler; } // type of request if( get_request_type( request, &action_name ) != 0 ) { goto error_handler; } // parse XML err_code = ixmlParseBufferEx( request->entity.buf, &xml_doc ); if( err_code != IXML_SUCCESS ) { if( err_code == IXML_INSUFFICIENT_MEMORY ) { err_code = UPNP_E_OUTOF_MEMORY; } else { err_code = SOAP_ACTION_FAILED; } err_str = "XML error"; goto error_handler; } if( action_name.length == 0 ) { // query var handle_query_variable( info, request, xml_doc ); } else { // invoke action handle_invoke_action( info, request, action_name, xml_doc ); } err_code = 0; // no error error_handler: ixmlDocument_free( xml_doc ); if( err_code != 0 ) { send_error_response( info, err_code, err_str, request ); }}#endif // EXCLUDE_SOAP#endif // INCLUDE_DEVICE_APIS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -