void UpnpActionRequest_assign(UpnpActionRequest *p, const UpnpActionRequest *q) { if (p != q) { UpnpActionRequest_set_ErrCode(p, UpnpActionRequest_get_ErrCode(q)); UpnpActionRequest_set_Socket(p, UpnpActionRequest_get_Socket(q)); UpnpActionRequest_set_ErrStr(p, UpnpActionRequest_get_ErrStr(q)); UpnpActionRequest_set_ActionName(p, UpnpActionRequest_get_ActionName(q)); UpnpActionRequest_set_DevUDN(p, UpnpActionRequest_get_DevUDN(q)); UpnpActionRequest_set_ServiceID(p, UpnpActionRequest_get_ServiceID(q)); UpnpActionRequest_set_ActionRequest(p, UpnpActionRequest_get_ActionRequest(q)); UpnpActionRequest_set_ActionResult(p, UpnpActionRequest_get_ActionResult(q)); UpnpActionRequest_set_CtrlPtIPAddr(p, UpnpActionRequest_get_CtrlPtIPAddr(q)); UpnpActionRequest_set_SoapHeader(p, UpnpActionRequest_get_SoapHeader(q)); } }
int TvDeviceHandleActionRequest(UpnpActionRequest *ca_event) { /* Defaults if action not found. */ int action_found = 0; int i = 0; int service = -1; int retCode = 0; const char *errorString = NULL; const char *devUDN = NULL; const char *serviceID = NULL; const char *actionName = NULL; IXML_Document *actionResult = NULL; UpnpActionRequest_set_ErrCode(ca_event, 0); UpnpActionRequest_set_ActionResult(ca_event, NULL); devUDN = UpnpString_get_String(UpnpActionRequest_get_DevUDN( ca_event)); serviceID = UpnpString_get_String(UpnpActionRequest_get_ServiceID( ca_event)); actionName = UpnpString_get_String(UpnpActionRequest_get_ActionName(ca_event)); if (strcmp(devUDN, tv_service_table[TV_SERVICE_CONTROL].UDN) == 0 && strcmp(serviceID, tv_service_table[TV_SERVICE_CONTROL].ServiceId) == 0) { /* Request for action in the TvDevice Control Service. */ service = TV_SERVICE_CONTROL; } else if (strcmp(devUDN, tv_service_table[TV_SERVICE_PICTURE].UDN) == 0 && strcmp(serviceID, tv_service_table[TV_SERVICE_PICTURE].ServiceId) == 0) { /* Request for action in the TvDevice Picture Service. */ service = TV_SERVICE_PICTURE; } /* Find and call appropriate procedure based on action name. * Each action name has an associated procedure stored in the * service table. These are set at initialization. */ for (i = 0; i < TV_MAXACTIONS && tv_service_table[service].ActionNames[i] != NULL; i++) { if (!strcmp(actionName, tv_service_table[service].ActionNames[i])) { if (!strcmp(tv_service_table[TV_SERVICE_CONTROL]. VariableStrVal[TV_CONTROL_POWER], "1") || !strcmp(actionName, "PowerOn")) { retCode = tv_service_table[service].actions[i]( UpnpActionRequest_get_ActionRequest(ca_event), &actionResult, &errorString); UpnpActionRequest_set_ActionResult(ca_event, actionResult); } else { errorString = "Power is Off"; retCode = UPNP_E_INTERNAL_ERROR; } action_found = 1; break; } } if (!action_found) { UpnpActionRequest_set_ActionResult(ca_event, NULL); UpnpActionRequest_strcpy_ErrStr(ca_event, "Invalid Action"); UpnpActionRequest_set_ErrCode(ca_event, 401); } else { if (retCode == UPNP_E_SUCCESS) { UpnpActionRequest_set_ErrCode(ca_event, UPNP_E_SUCCESS); } else { /* copy the error string */ UpnpActionRequest_strcpy_ErrStr(ca_event, errorString); switch (retCode) { case UPNP_E_INVALID_PARAM: UpnpActionRequest_set_ErrCode(ca_event, 402); break; case UPNP_E_INTERNAL_ERROR: default: UpnpActionRequest_set_ErrCode(ca_event, 501); break; } } } return UpnpActionRequest_get_ErrCode(ca_event); }
/*! * \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( /*! [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; UpnpActionRequest *action = UpnpActionRequest_new(); UpnpString *devUDN = UpnpString_new(); UpnpString *serviceID = UpnpString_new(); IXML_Document *actionRequestDoc = NULL; IXML_Document *actionResultDoc = NULL; Upnp_FunPtr soap_event_callback; void *cookie = NULL; int err_code; const char *err_str; /* 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, &actionRequestDoc) == -1) goto error_handler; /* get device info for action event */ err_code = get_device_info(request, 0, xml_doc, info->foreign_sockaddr.ss_family, devUDN, serviceID, &soap_event_callback, &cookie); if (err_code != UPNP_E_SUCCESS) goto error_handler; UpnpActionRequest_set_ErrCode(action, UPNP_E_SUCCESS); UpnpActionRequest_strcpy_ErrStr(action, ""); UpnpActionRequest_strcpy_ActionName(action, action_name.buf); UpnpActionRequest_set_DevUDN(action, devUDN); UpnpActionRequest_set_ServiceID(action, serviceID); UpnpActionRequest_set_ActionRequest(action, actionRequestDoc); UpnpActionRequest_set_CtrlPtIPAddr(action, &info->foreign_sockaddr); UpnpPrintf(UPNP_INFO, SOAP, __FILE__, __LINE__, "Calling Callback\n"); soap_event_callback(UPNP_CONTROL_ACTION_REQUEST, action, cookie); err_code = UpnpActionRequest_get_ErrCode(action); if (err_code != UPNP_E_SUCCESS) { err_str = UpnpActionRequest_get_ErrStr_cstr(action); if (strlen(err_str) <= 0) { err_code = SOAP_ACTION_FAILED; err_str = Soap_Action_Failed; } goto error_handler; } /* validate, and handle action error */ actionResultDoc = UpnpActionRequest_get_ActionResult(action); if (actionResultDoc == NULL) { err_code = SOAP_ACTION_FAILED; err_str = Soap_Action_Failed; goto error_handler; } /* send response */ send_action_response(info, actionResultDoc, request); err_code = 0; /* error handling and cleanup */ error_handler: /* restore */ action_name.buf[action_name.length] = save_char; if (err_code != 0) send_error_response(info, err_code, err_str, request); UpnpString_delete(serviceID); UpnpString_delete(devUDN); UpnpActionRequest_delete(action); }