/*! * \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; }
/************************************************************************ * Function : GenaAutoRenewSubscription * * Parameters: * IN void *input: Thread data(upnp_timeout *) needed to send the renewal * * Description: * This is a thread function to send the renewal just before the * subscription times out. * * Returns: VOID * ***************************************************************************/ static void GenaAutoRenewSubscription( IN void *input ) { upnp_timeout *event = ( upnp_timeout * ) input; void *cookie; Upnp_FunPtr callback_fun; struct Handle_Info *handle_info; struct Upnp_Event_Subscribe *sub_struct = ( struct Upnp_Event_Subscribe * ) event->Event; int send_callback = 0; int eventType = 0; if( AUTO_RENEW_TIME == 0 ) { DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUB EXPIRED" ) ); sub_struct->ErrCode = UPNP_E_SUCCESS; send_callback = 1; eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED; } else { DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA AUTO RENEW" ) ); if( ( ( sub_struct->ErrCode = genaRenewSubscription( event->handle, sub_struct-> Sid, &sub_struct-> TimeOut ) ) != UPNP_E_SUCCESS ) && ( sub_struct->ErrCode != GENA_E_BAD_SID ) && ( sub_struct->ErrCode != GENA_E_BAD_HANDLE ) ) { send_callback = 1; eventType = UPNP_EVENT_AUTORENEWAL_FAILED; } } if( send_callback ) { HandleLock( ); if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) { HandleUnlock( ); free_upnp_timeout( event ); return; } DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "HANDLE IS VALID" ) ); callback_fun = handle_info->Callback; cookie = handle_info->Cookie; HandleUnlock( ); //make callback callback_fun( eventType, event->Event, cookie ); } free_upnp_timeout( event ); }
void free_client_subscription(GenlibClientSubscription *sub) { upnp_timeout *event; ThreadPoolJob tempJob; if (sub) { int renewEventId = GenlibClientSubscription_get_RenewEventId(sub); GenlibClientSubscription_strcpy_ActualSID(sub, ""); GenlibClientSubscription_strcpy_EventURL(sub, ""); if (renewEventId != -1) { /* do not remove timer event of copy */ /* invalid timer event id */ if (TimerThreadRemove(&gTimerThread, renewEventId, &tempJob) == 0) { event = (upnp_timeout *)tempJob.arg; free_upnp_timeout(event); } } GenlibClientSubscription_set_RenewEventId(sub, -1); } }
/************************************************************************ * Function : genaRenewSubscription * * Parameters: * IN UpnpClient_Handle client_handle: Client handle * IN const Upnp_SID in_sid: subscription ID * INOUT int * TimeOut: requested Duration, if -1, then "infinite". * in the OUT case: actual Duration granted * by Service, -1 for infinite * * Description: * This function renews a SID. It first validates the SID and * client_handle and copies the subscription. It sends RENEW * (modified SUBSCRIBE) http request to service and processes * the response. * * Returns: int * return UPNP_E_SUCCESS if service response is OK else * returns appropriate error ***************************************************************************/ int genaRenewSubscription( IN UpnpClient_Handle client_handle, IN const Upnp_SID in_sid, INOUT int *TimeOut ) { int return_code = GENA_SUCCESS; client_subscription *sub; client_subscription sub_copy; struct Handle_Info *handle_info; char *ActualSID; ThreadPoolJob tempJob; HandleLock( ); // validate handle and sid if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) { HandleUnlock( ); return GENA_E_BAD_HANDLE; } if( ( sub = GetClientSubClientSID( handle_info->ClientSubList, in_sid ) ) == NULL ) { HandleUnlock( ); return GENA_E_BAD_SID; } // remove old events if( TimerThreadRemove( &gTimerThread, sub->RenewEventId, &tempJob ) == 0 ) { free_upnp_timeout( ( upnp_timeout * ) tempJob.arg ); } DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "REMOVED AUTO RENEW EVENT" ) ); sub->RenewEventId = -1; return_code = copy_client_subscription( sub, &sub_copy ); HandleUnlock( ); if( return_code != HTTP_SUCCESS ) { return return_code; } return_code = gena_subscribe( sub_copy.EventURL, TimeOut, sub_copy.ActualSID, &ActualSID ); HandleLock( ); if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) { HandleUnlock( ); if( return_code == UPNP_E_SUCCESS ) { free( ActualSID ); } return GENA_E_BAD_HANDLE; } // 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( ); return return_code; } // get subscription if( ( sub = GetClientSubClientSID( handle_info->ClientSubList, in_sid ) ) == NULL ) { free( ActualSID ); free_client_subscription( &sub_copy ); HandleUnlock( ); return GENA_E_BAD_SID; } // store actual sid free( sub->ActualSID ); sub->ActualSID = ActualSID; // start renew subscription timer return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut, sub ); if( return_code != GENA_SUCCESS ) { RemoveClientSubClientSID( &handle_info->ClientSubList, sub->sid ); } free_client_subscription( &sub_copy ); HandleUnlock( ); return return_code; }
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; }