/*! * \brief Handles the SOAP action request. It checks the integrity of the SOAP * action request and gives the call back to the device application. */ static void handle_invoke_action( int iface, /*! [in] Socket info. */ IN SOCKINFO *info, /*! [in] HTTP Request. */ IN http_message_t *request, /*! [in] Name of the SOAP Action. */ IN memptr action_name, /*! [in] Document containing the SOAP action request. */ 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(iface, request, 0, xml_doc, info->foreign_sockaddr.ss_family, 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_sockaddr; 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); /* restore */ action_name.buf[action_name.length] = save_char; if (err_code != 0) send_error_response(info, err_code, err_str, request); }
int hamming_search_test(const char* filename) { long result = errors_counter(); typedef containers::ternary_tree<std::string, const char*> Tst; Tst names; names["ABCD"] = "ABCD"; names["Abcd"] = "Abcd"; names["ABcd"] = "ABcd"; names["aBCd"] = "aBCd"; names["abc"] = "abc"; names["abcde"] = "abcde"; names["bcd"] = "bcd"; names["abCD"] = "abCD"; names["abCd"] = "abCd"; names["AbcD"] = "AbcD"; names["ABcD"] = "ABcD"; names["aBCD"] = "aBCD"; names["abCDE"] = "abCDE"; names["abCDd"] = "abCDd"; names["abCcd"] = "abCcd"; names["bcdc"] = "bcdc"; names["aab"] = "aab"; // hamming_search(2): ABcd, AbcD, Abcd, aBCd, abCD, abCd, abc, abcde // levenshtein_search(2): hamming + abCDd, abCcd bcd, bcdc Tst::search_results_list matches = names.create_search_results(); typedef Tst::search_results_list::iterator ResultIter; //names.levenshtein_search_count = 0; names.levenshtein_search("abcd", std::back_inserter(matches), 2); //std::cout << "l-count: " << names.levenshtein_search_count << "\n"; //names.levenshtein_search_count = 0; BOOST_CHECK(matches.size() == 12); if (matches.size() != 12) { // compare with DDJ { Tptr root = 0; for (Tst::iterator it = names.begin(); it != names.end(); ++it) { insertstr = (char*)*it; root = insert2(root, insertstr); } nearsearch(root, "abcd", 2); std::cout << "DDJ nearsearch abcd:\n"; for (int i = 0; i != srchtop; i++) std::cout << srcharr[i] << "\n"; std::cout << "\n"; cleanup2(root); } int i = 0; for (ResultIter rit = matches.begin(); rit != matches.end(); ++rit, ++i) { std::cout << **rit << " = " << (*rit).key(); std::cout /*<< " = " << matches[i].key()*/ << "\n"; } } typedef std::vector<std::string> Dictionary; extern size_t fill_dictionary(const char*, Dictionary&, size_t, size_t = 0); Dictionary dictionary; size_t longest_in_file = fill_dictionary(filename, dictionary, 300); std::random_shuffle(dictionary.begin(), dictionary.end()); names.clear(); Dictionary wildnames; // Add names with mini-variations long zeroes = 0; Dictionary::iterator dit; for (dit = dictionary.begin(); dit != dictionary.end(); ++dit) { const std::string& name(*dit); std::string namecopy(*dit); names[namecopy] = name.c_str(); std::string searchstr(name); for (int i = 0; i < 5; ++i) { int where = rand() % name.size(); // make string with ? at place of changed char if (searchstr[where] == '?') continue; searchstr[where] = '?'; wildnames.push_back(searchstr); char c = (char)rand(); if (!c) zeroes++; namecopy[where] = c; names[namecopy] = name.c_str(); } } for(dit = wildnames.begin(); dit != wildnames.end(); ++dit) { const std::string& name(*dit); for (int diff = 1; diff != 3; ++diff) { Tst::search_results_list matchresults = names.create_search_results(); names.hamming_search(name, std::back_inserter(matchresults), diff); //if (matchresults.size() == 0) // std::cout << "couldn't find " << name << '\n'; //BOOST_CHECK(found == matchresults.size()); for (size_t i = 0; i != matchresults.size(); ++i) BOOST_CHECK(check_hamming_match(matchresults[i].key(), name, diff)); } } return errors_counter() - result; }
/*! * \brief Handles the SOAP requests to querry the state variables. * This functionality has been deprecated in the UPnP V1.0 architecture. */ static UPNP_INLINE void handle_query_variable( int iface, /*! [in] Socket info. */ SOCKINFO *info, /*! [in] HTTP request. */ http_message_t *request, /*! [in] Document containing the variable request SOAP message. */ 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 */ err_code = get_device_info(iface, request, 1, xml_doc, info->foreign_sockaddr.ss_family, variable.DevUDN, variable.ServiceID, &soap_event_callback, &cookie); if (err_code != 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_sockaddr; /* send event */ soap_event_callback(UPNP_CONTROL_GET_VAR_REQUEST, &variable, cookie); UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Return from callback for var request\n"); /* validate, and handle result */ if (variable.CurrentVal == NULL) { 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); }
/*! * \brief Retrives all the information needed to process the incoming SOAP * request. It finds the device and service info and also the callback * function to hand-over the request to the device application. * * \return UPNP_E_SUCCESS if successful else returns appropriate error. */ static int get_device_info( int iface, /*! [in] HTTP request. */ http_message_t *request, /*! [in] flag for a querry. */ int isQuery, /*! [in] Action request document. */ IXML_Document *actionDoc, /*! [in] . */ int AddressFamily, /*! [out] Device UDN string. */ OUT char device_udn[LINE_SIZE], /*! [out] Service ID string. */ char service_id[LINE_SIZE], /*! [out] callback function of the device application. */ Upnp_FunPtr *callback, /*! [out] cookie stored by device application. */ void **cookie) { struct Handle_Info *device_info; int device_hnd; service_info *serv_info; char save_char; /* error by default */ int ret_code = -1; const char *control_url; char *actionName = NULL; /* null-terminate pathquery of url */ control_url = request->uri.pathquery.buff; save_char = control_url[request->uri.pathquery.size]; ((char *)control_url)[request->uri.pathquery.size] = '\0'; HandleLock(); if (GetDeviceHandleInfo(iface, AddressFamily, &device_hnd, &device_info) != HND_DEVICE) goto error_handler; serv_info = FindServiceControlURLPath( &device_info->ServiceTable, control_url); if (!serv_info) goto error_handler; if (isQuery) { ret_code = check_soap_action_header(request, QUERY_STATE_VAR_URN, &actionName); if (ret_code != UPNP_E_SUCCESS && ret_code != UPNP_E_OUTOF_MEMORY) { ret_code = UPNP_E_INVALID_ACTION; goto error_handler; } /* check soap body */ ret_code = check_soap_body(actionDoc, QUERY_STATE_VAR_URN, actionName); free(actionName); if (ret_code != UPNP_E_SUCCESS) goto error_handler; } else { ret_code = check_soap_action_header(request, serv_info->serviceType, &actionName); if (ret_code != UPNP_E_SUCCESS && ret_code != UPNP_E_OUTOF_MEMORY) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } /* check soap body */ ret_code = check_soap_body(actionDoc, serv_info->serviceType, actionName); free(actionName); if (ret_code != UPNP_E_SUCCESS) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } } namecopy(service_id, serv_info->serviceId); namecopy(device_udn, serv_info->UDN); *callback = device_info->Callback; *cookie = device_info->Cookie; ret_code = 0; error_handler: /* restore */ ((char *)control_url)[request->uri.pathquery.size] = save_char; HandleUnlock(); return ret_code; }
/**************************************************************************** * 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 UPNP_INLINE void handle_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 ); 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 : get_device_info * * Parameters : * IN http_message_t* request : HTTP request * IN int isQuery : flag for a querry * IN IXML_Document *actionDoc : action request document * OUT char device_udn[LINE_SIZE] : Device UDN string * OUT char service_id[LINE_SIZE] : Service ID string * OUT Upnp_FunPtr *callback : callback function of the device * application * OUT void** cookie : cookie stored by device application * * Description : This function retrives all the information needed to * process the incoming SOAP request. It finds the device and service info * and also the callback function to hand-over the request to the device * application. * * Return : int * UPNP_E_SUCCESS if successful else returns appropriate error * * Note : ****************************************************************************/ static int get_device_info( IN http_message_t * request, IN int isQuery, IN IXML_Document * actionDoc, OUT char device_udn[LINE_SIZE], OUT char service_id[LINE_SIZE], OUT Upnp_FunPtr * callback, OUT void **cookie ) { struct Handle_Info *device_info; int device_hnd; service_info *serv_info; char save_char; int ret_code = -1; // error by default const char *control_url; char *actionName = NULL; // null-terminate pathquery of url control_url = request->uri.pathquery.buff; save_char = control_url[request->uri.pathquery.size]; ((char *)control_url)[request->uri.pathquery.size] = '\0'; HandleLock(); if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) { goto error_handler; } if( ( serv_info = FindServiceControlURLPath( &device_info->ServiceTable, control_url ) ) == NULL ) { goto error_handler; } if( isQuery ) { ret_code = check_soap_action_header( request, QUERY_STATE_VAR_URN, &actionName ); if( ( ret_code != UPNP_E_SUCCESS ) && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) { ret_code = UPNP_E_INVALID_ACTION; goto error_handler; } //check soap body ret_code = check_soap_body( actionDoc, QUERY_STATE_VAR_URN, actionName ); free( actionName ); if( ret_code != UPNP_E_SUCCESS ) { goto error_handler; } } else { ret_code = check_soap_action_header( request, serv_info->serviceType, &actionName ); if( ( ret_code != UPNP_E_SUCCESS ) && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } //check soap body ret_code = check_soap_body( actionDoc, serv_info->serviceType, actionName ); free( actionName ); if( ret_code != UPNP_E_SUCCESS ) { ret_code = UPNP_E_INVALID_SERVICE; goto error_handler; } } namecopy( service_id, serv_info->serviceId ); namecopy( device_udn, serv_info->UDN ); *callback = device_info->Callback; *cookie = device_info->Cookie; ret_code = 0; error_handler: ((char *)control_url)[request->uri.pathquery.size] = save_char; // restore HandleUnlock(); return ret_code; }
/**************************************************************************** * 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 void handle_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; } /* for user agent probe support! by HouXB, 22Oct10 */ ListNode *node; http_header_t *header; node = ListHead(&request->headers); while( node != NULL ) { header = ( http_header_t * ) node->item; if (!strncmp(USER_AGENT, header->name.buf, strlen(USER_AGENT))) { int aLen = (int)header->value.length; sprintf(action.UserAgent, "%.*s", aLen, header->value.buf ); if(aLen <NAME_SIZE) { action.UserAgent[aLen] = '\0'; } else { action.UserAgent[NAME_SIZE-1] = '\0'; } /* printf("\n####\nuser Agent found!\nallow len is:%d\nlen is: %d\nagent is:%s\n####\n", NAME_SIZE, aLen, action.UserAgent); */ break; } node = ListNext( &request->headers , node ); } /*end for user agent probe support! by HouXB, 22Oct10 */ 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; 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 ); } }