/************************************************************************ * 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; }
/************************************************************************ * Function : genaSubscribe * * Parameters: * IN UpnpClient_Handle client_handle: * IN char * PublisherURL: NULL Terminated, of the form : * "http://134.134.156.80:4000/RedBulb/Event" * INOUT int * TimeOut: requested Duration, if -1, then "infinite". * in the OUT case: actual Duration granted * by Service, -1 for infinite * OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller * * Description: * This function subscribes to a PublisherURL ( also mentioned as EventURL * some places). It sends SUBSCRIBE http request to service processes * request. Finally adds a Subscription to * the clients subscription list, if service responds with OK * * Returns: int * return UPNP_E_SUCCESS if service response is OK else * returns appropriate error ***************************************************************************/ int genaSubscribe( IN UpnpClient_Handle client_handle, IN char *PublisherURL, INOUT int *TimeOut, OUT Upnp_SID out_sid ) { int return_code = GENA_SUCCESS; client_subscription *newSubscription = NULL; uuid_upnp uid; Upnp_SID temp_sid; char *ActualSID = NULL; struct Handle_Info *handle_info; char *EventURL = NULL; DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUBSCRIBE BEGIN" ) ); HandleLock( ); memset( out_sid, 0, sizeof( Upnp_SID ) ); // validate handle if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) { HandleUnlock( ); return GENA_E_BAD_HANDLE; } HandleUnlock( ); // subscribe SubscribeLock( ); return_code = gena_subscribe( PublisherURL, TimeOut, NULL, &ActualSID ); HandleLock( ); if( return_code != UPNP_E_SUCCESS ) { DBGONLY( 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 ); sprintf( out_sid, "uuid:%s", temp_sid ); // create event url EventURL = ( char * )malloc( strlen( PublisherURL ) + 1 ); if( EventURL == NULL ) { return_code = UPNP_E_OUTOF_MEMORY; goto error_handler; } strcpy( EventURL, PublisherURL ); // fill subscription newSubscription = ( client_subscription * ) malloc( sizeof( client_subscription ) ); if( newSubscription == NULL ) { return_code = UPNP_E_OUTOF_MEMORY; goto error_handler; } newSubscription->EventURL = EventURL; newSubscription->ActualSID = ActualSID; strcpy( newSubscription->sid, out_sid ); newSubscription->RenewEventId = -1; newSubscription->next = handle_info->ClientSubList; handle_info->ClientSubList = newSubscription; // schedule expiration event return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut, newSubscription ); error_handler: if( return_code != UPNP_E_SUCCESS ) { free( ActualSID ); free( EventURL ); free( newSubscription ); } HandleUnlock( ); SubscribeUnlock( ); 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; }