UpnpSubscriptionRequest *UpnpSubscriptionRequest_new() { struct SUpnpSubscriptionRequest *p = calloc(1, sizeof (struct SUpnpSubscriptionRequest)); p->m_serviceId = UpnpString_new(); p->m_UDN = UpnpString_new(); p->m_SID = UpnpString_new(); return (UpnpSubscriptionRequest *)p; }
/*! * \brief This is a thread function to send the renewal just before the * subscription times out. */ static void GenaAutoRenewSubscription( /*! [in] Thread data(upnp_timeout *) needed to send the renewal. */ IN void *input) { upnp_timeout *event = (upnp_timeout *) input; struct Upnp_Event_Subscribe *sub_struct = (struct Upnp_Event_Subscribe *)event->Event; void *cookie; Upnp_FunPtr callback_fun; struct Handle_Info *handle_info; int send_callback = 0; int eventType = 0; int timeout = 0; int errCode = 0; UpnpString *tmpSID = UpnpString_new(); if (AUTO_RENEW_TIME == 0) { UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUB EXPIRED"); sub_struct->ErrCode = UPNP_E_SUCCESS; send_callback = 1; eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED; } else { UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA AUTO RENEW"); timeout = sub_struct->TimeOut; UpnpString_set_String(tmpSID, sub_struct->Sid); errCode = genaRenewSubscription( event->handle, tmpSID, &timeout); sub_struct->ErrCode = errCode; sub_struct->TimeOut = timeout; if (errCode != UPNP_E_SUCCESS && errCode != GENA_E_BAD_SID && errCode != GENA_E_BAD_HANDLE) { send_callback = 1; eventType = UPNP_EVENT_AUTORENEWAL_FAILED; } } if (send_callback) { HandleReadLock(); if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) { HandleUnlock(); free_upnp_timeout(event); goto end_function; } UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "HANDLE IS VALID"); /* make callback */ callback_fun = handle_info->Callback; cookie = handle_info->Cookie; HandleUnlock(); callback_fun(eventType, event->Event, cookie); } free_upnp_timeout(event); end_function: UpnpString_delete(tmpSID); return; }
UpnpActionRequest *UpnpActionRequest_new() { struct SUpnpActionRequest *p = calloc(1, sizeof (struct SUpnpActionRequest)); #if 0 p->m_errCode = 0; p->m_socket = 0; #endif p->m_errStr = UpnpString_new(); p->m_actionName = UpnpString_new(); p->m_devUDN = UpnpString_new(); p->m_serviceID = UpnpString_new(); #if 0 p->m_actionRequest = NULL; p->m_actionResult = NULL; p->m_soapHeader = NULL; memset(&p->m_ctrlPtIPAddr, 0, sizeof (struct sockaddr_storage)); #endif return (UpnpActionRequest *)p; }
/*! * \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); }
int genaRenewSubscription( UpnpClient_Handle client_handle, const UpnpString *in_sid, int *TimeOut) { int return_code = GENA_SUCCESS; ClientSubscription *sub = NULL; ClientSubscription *sub_copy = UpnpClientSubscription_new(); struct Handle_Info *handle_info; UpnpString *ActualSID = UpnpString_new(); ThreadPoolJob tempJob; HandleLock(); /* validate handle and sid */ if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { HandleUnlock(); return_code = GENA_E_BAD_HANDLE; goto exit_function; } sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid); if (sub == NULL) { HandleUnlock(); return_code = GENA_E_BAD_SID; goto exit_function; } /* remove old events */ if (TimerThreadRemove( &gTimerThread, UpnpClientSubscription_get_RenewEventId(sub), &tempJob) == 0 ) { free_upnp_timeout((upnp_timeout *)tempJob.arg); } UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "REMOVED AUTO RENEW EVENT"); UpnpClientSubscription_set_RenewEventId(sub, -1); UpnpClientSubscription_assign(sub_copy, sub); HandleUnlock(); return_code = gena_subscribe( UpnpClientSubscription_get_EventURL(sub_copy), TimeOut, UpnpClientSubscription_get_ActualSID(sub_copy), ActualSID); HandleLock(); if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { HandleUnlock(); return_code = GENA_E_BAD_HANDLE; goto exit_function; } /* we just called GetHandleInfo, so we don't check for return value */ /*GetHandleInfo(client_handle, &handle_info); */ if (return_code != UPNP_E_SUCCESS) { /* network failure (remove client sub) */ RemoveClientSubClientSID(&handle_info->ClientSubList, in_sid); free_client_subscription(sub_copy); HandleUnlock(); goto exit_function; } /* get subscription */ sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid); if (sub == NULL) { free_client_subscription(sub_copy); HandleUnlock(); return_code = GENA_E_BAD_SID; goto exit_function; } /* store actual sid */ UpnpClientSubscription_set_ActualSID(sub, ActualSID); /* start renew subscription timer */ return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, sub); if (return_code != GENA_SUCCESS) { RemoveClientSubClientSID( &handle_info->ClientSubList, UpnpClientSubscription_get_SID(sub)); } free_client_subscription(sub_copy); HandleUnlock(); exit_function: UpnpString_delete(ActualSID); UpnpClientSubscription_delete(sub_copy); return return_code; }
int genaSubscribe( UpnpClient_Handle client_handle, const UpnpString *PublisherURL, int *TimeOut, UpnpString *out_sid) { int return_code = GENA_SUCCESS; ClientSubscription *newSubscription = UpnpClientSubscription_new(); uuid_upnp uid; Upnp_SID temp_sid; Upnp_SID temp_sid2; UpnpString *ActualSID = UpnpString_new(); UpnpString *EventURL = UpnpString_new(); struct Handle_Info *handle_info; int rc = 0; memset(temp_sid, 0, sizeof(temp_sid)); memset(temp_sid2, 0, sizeof(temp_sid2)); UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUBSCRIBE BEGIN"); UpnpString_clear(out_sid); HandleReadLock(); /* validate handle */ if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { return_code = GENA_E_BAD_HANDLE; SubscribeLock(); goto error_handler; } HandleUnlock(); /* subscribe */ SubscribeLock(); return_code = gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID); HandleLock(); if (return_code != UPNP_E_SUCCESS) { UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__, "SUBSCRIBE FAILED in transfer error code: %d returned\n", return_code ); goto error_handler; } if(GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) { return_code = GENA_E_BAD_HANDLE; goto error_handler; } /* generate client SID */ uuid_create(&uid ); uuid_unpack(&uid, temp_sid); rc = snprintf(temp_sid2, sizeof(temp_sid2), "uuid:%s", temp_sid); if (rc < 0 || (unsigned int) rc >= sizeof(temp_sid2)) { return_code = UPNP_E_OUTOF_MEMORY; goto error_handler; } UpnpString_set_String(out_sid, temp_sid2); /* create event url */ UpnpString_assign(EventURL, PublisherURL); /* fill subscription */ if (newSubscription == NULL) { return_code = UPNP_E_OUTOF_MEMORY; goto error_handler; } UpnpClientSubscription_set_RenewEventId(newSubscription, -1); UpnpClientSubscription_set_SID(newSubscription, out_sid); UpnpClientSubscription_set_ActualSID(newSubscription, ActualSID); UpnpClientSubscription_set_EventURL(newSubscription, EventURL); UpnpClientSubscription_set_Next(newSubscription, handle_info->ClientSubList); handle_info->ClientSubList = newSubscription; /* schedule expiration event */ return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, newSubscription); error_handler: UpnpString_delete(ActualSID); UpnpString_delete(EventURL); if (return_code != UPNP_E_SUCCESS) UpnpClientSubscription_delete(newSubscription); HandleUnlock(); SubscribeUnlock(); return return_code; }
void UpnpSubscriptionRequest_strcpy_ServiceId(UpnpSubscriptionRequest *p, const char *s) { UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_serviceId); ((struct SUpnpSubscriptionRequest *)p)->m_serviceId = UpnpString_new(); UpnpString_set_String(((struct SUpnpSubscriptionRequest *)p)->m_serviceId, s); }
void UpnpSubscriptionRequest_strcpy_SID(UpnpSubscriptionRequest *p, const char *s) { UpnpString_delete(((struct SUpnpSubscriptionRequest *)p)->m_SID); ((struct SUpnpSubscriptionRequest *)p)->m_SID = UpnpString_new(); UpnpString_set_String(((struct SUpnpSubscriptionRequest *)p)->m_SID, s); }
void UpnpActionRequest_strcpy_ActionName(UpnpActionRequest *p, const char *s) { UpnpString_delete(((struct SUpnpActionRequest *)p)->m_actionName); ((struct SUpnpActionRequest *)p)->m_actionName = UpnpString_new(); UpnpString_set_String(((struct SUpnpActionRequest *)p)->m_actionName, s); }
void UpnpActionRequest_strcpy_ErrStr(UpnpActionRequest *p, const char *s) { UpnpString_delete(((struct SUpnpActionRequest *)p)->m_errStr); ((struct SUpnpActionRequest *)p)->m_errStr = UpnpString_new(); UpnpString_set_String(((struct SUpnpActionRequest *)p)->m_errStr, s); }