📄 gena_ctrlpt.c
字号:
*sid = str_alloc( sid_hdr.buf, sid_hdr.length );
if( *sid == NULL ) {
httpmsg_destroy( &response.msg );
return UPNP_E_OUTOF_MEMORY;
}
httpmsg_destroy( &response.msg );
return UPNP_E_SUCCESS;
}
/************************************************************************
* Function : genaUnregisterClient
*
* Parameters:
* IN UpnpClient_Handle client_handle: Handle containing all the control
* point related information
*
* Description:
* This function unsubcribes all the outstanding subscriptions and cleans
* the subscription list. This function is called when control point
* unregisters.
*
* Returns: int
* return UPNP_E_SUCCESS if successful else returns appropriate error
***************************************************************************/
int
genaUnregisterClient( IN UpnpClient_Handle client_handle )
{
client_subscription sub_copy;
int return_code = UPNP_E_SUCCESS;
struct Handle_Info *handle_info = NULL;
http_parser_t response;
while( TRUE ) {
HandleLock( );
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock( );
return GENA_E_BAD_HANDLE;
}
if( handle_info->ClientSubList == NULL ) {
return_code = UPNP_E_SUCCESS;
break;
}
return_code = copy_client_subscription( handle_info->ClientSubList,
&sub_copy );
if( return_code != HTTP_SUCCESS ) {
break;
}
RemoveClientSubClientSID( &handle_info->ClientSubList,
sub_copy.sid );
HandleUnlock( );
return_code = gena_unsubscribe( sub_copy.EventURL,
sub_copy.ActualSID, &response );
if( return_code == 0 ) {
httpmsg_destroy( &response.msg );
}
free_client_subscription( &sub_copy );
}
freeClientSubList( handle_info->ClientSubList );
HandleUnlock( );
return return_code;
}
/************************************************************************
* Function : genaUnSubscribe
*
* Parameters:
* IN UpnpClient_Handle client_handle: UPnP client handle
* IN SID in_sid: The subscription ID
*
* Description:
* This function unsubscribes a SID. It first validates the SID and
* client_handle,copies the subscription, sends UNSUBSCRIBE http request
* to service processes request and finally removes the subscription
*
* Returns: int
* return UPNP_E_SUCCESS if service response is OK else
* returns appropriate error
***************************************************************************/
int
genaUnSubscribe( IN UpnpClient_Handle client_handle,
IN const Upnp_SID in_sid )
{
client_subscription *sub;
int return_code = GENA_SUCCESS;
struct Handle_Info *handle_info;
client_subscription sub_copy;
http_parser_t response;
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;
}
return_code = copy_client_subscription( sub, &sub_copy );
HandleUnlock( );
return_code = gena_unsubscribe( sub_copy.EventURL, sub_copy.ActualSID,
&response );
if( return_code == 0 ) {
httpmsg_destroy( &response.msg );
}
free_client_subscription( &sub_copy );
HandleLock( );
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock( );
return GENA_E_BAD_HANDLE;
}
RemoveClientSubClientSID( &handle_info->ClientSubList, in_sid );
HandleUnlock( );
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;
}
// BROADCAST!!!
/************************************************************************
* Function : genaRegisterMulticast
*
* Parameters:
* IN UpnpClient_Handle client_handle:
* IN char * PublisherURL: NULL Terminated, of the form :
* "http://134.134.156.80:4000/RedBulb/Event"
*
* Description:
* This function sets up a multicast socket to accept
* GENA event notifications
*
* Returns: int
* return UPNP_E_SUCCESS if service response is OK else
* returns appropriate error
***************************************************************************/
int
genaRegisterMulticast( IN UpnpClient_Handle client_handle,
IN char * addr)
{
int return_code = GENA_SUCCESS;
struct Handle_Info *handle_info;
DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA SUBSCRIBE BEGIN" ) );
HandleLock( );
// validate handle
if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
HandleUnlock( );
return GENA_E_BAD_HANDLE;
}
HandleUnlock( );
return_code = genaSetupMulticastSocket(addr);
return return_code;
}
/************************************************************************
* 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -