/*! * \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; }
void UpnpString_assign(UpnpString *p, const UpnpString *q) { if (p != q) { UpnpString_set_String(p, UpnpString_get_String(q)); } }
/*! * \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( /*! [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 UpnpString *device_udn, /*! [out] Service ID string. */ UpnpString *service_id, /*! [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(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; } } UpnpString_set_String(device_udn, serv_info->UDN); UpnpString_set_String(service_id, serv_info->serviceId); *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; }
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); }