📄 gena_device.c
字号:
TPJobInit( &job, ( start_routine ) genaNotifyThread,
thread_struct );
TPJobSetFreeFunction( &job, ( free_routine ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
if( ( return_code =
ThreadPoolAdd( &gSendThreadPool, &job, NULL ) ) != 0 ) {
if( return_code == EOUTOFMEM ) {
return_code = UPNP_E_OUTOF_MEMORY;
}
} else {
return_code = GENA_SUCCESS;
}
}
if( return_code != GENA_SUCCESS ) {
free( reference_count );
free( UDN_copy );
free( servId_copy );
free( thread_struct );
ixmlFreeDOMString( propertySet );
free( headers );
}
HandleUnlock( );
return return_code;
}
/****************************************************************************
* Function : genaInitNotifyExt
*
* Parameters :
* IN UpnpDevice_Handle device_handle : Device handle
* IN char *UDN : Device udn
* IN char *servId : Service ID
* IN IXML_Document *PropSet : Document of the state table
* IN Upnp_SID sid : subscription ID
*
* Description : This function is similar to the genaInitNofity. The only
* difference is that it takes the xml document for the state table and
* sends the intial state table dump to newly subscribed control point.
*
* Return : int
* returns GENA_E_SUCCESS if successful else returns appropriate error
*
* Note : No other event will be sent to this control point before the
* intial state table dump.
****************************************************************************/
int
genaInitNotifyExt( IN UpnpDevice_Handle device_handle,
IN char *UDN,
IN char *servId,
IN IXML_Document * PropSet,
IN Upnp_SID sid )
{
char *UDN_copy = NULL;
char *servId_copy = NULL;
char *headers = NULL;
subscription *sub = NULL;
service_info *service = NULL;
int return_code = GENA_SUCCESS;
int headers_size;
int *reference_count = NULL;
struct Handle_Info *handle_info;
DOMString propertySet = NULL;
ThreadPoolJob job;
notify_thread_struct *thread_struct = NULL;
DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENA BEGIN INITIAL NOTIFY EXT" ) );
reference_count = ( int * )malloc( sizeof( int ) );
if( reference_count == NULL ) {
return UPNP_E_OUTOF_MEMORY;
}
( *reference_count ) = 0;
UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
if( UDN_copy == NULL ) {
free( reference_count );
return UPNP_E_OUTOF_MEMORY;
}
servId_copy = ( char * )malloc( strlen( servId ) + 1 );
if( servId_copy == NULL ) {
free( UDN_copy );
free( reference_count );
return UPNP_E_OUTOF_MEMORY;
}
strcpy( UDN_copy, UDN );
strcpy( servId_copy, servId );
HandleLock( );
if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
free( UDN_copy );
free( reference_count );
free( servId_copy );
HandleUnlock( );
return GENA_E_BAD_HANDLE;
}
if( ( service = FindServiceId( &handle_info->ServiceTable,
servId, UDN ) ) == NULL ) {
free( UDN_copy );
free( reference_count );
free( servId_copy );
HandleUnlock( );
return GENA_E_BAD_SERVICE;
}
DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"FOUND SERVICE IN INIT NOTFY EXT: UDN %s, ServID: %d\n",
UDN, servId ) );
if( ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ||
( sub->active ) ) {
free( UDN_copy );
free( reference_count );
free( servId_copy );
HandleUnlock( );
return GENA_E_BAD_SID;
}
DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"FOUND SUBSCRIPTION IN INIT NOTIFY EXT: SID %s",
sid ) );
sub->active = 1;
propertySet = ixmlPrintDocument( PropSet );
if( propertySet == NULL ) {
free( UDN_copy );
free( reference_count );
free( servId_copy );
HandleUnlock( );
return UPNP_E_INVALID_PARAM;
}
DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
"GENERATED PROPERY SET IN INIT EXT NOTIFY: %s",
propertySet ) );
headers_size = strlen( "CONTENT-TYPE text/xml\r\n" ) +
strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
strlen( "NT: upnp:event\r\n" ) +
strlen( "NTS: upnp:propchange\r\n" ) + 1;
headers = ( char * )malloc( headers_size );
if( headers == NULL ) {
free( UDN_copy );
free( servId_copy );
free( reference_count );
ixmlFreeDOMString( propertySet );
HandleUnlock( );
return UPNP_E_OUTOF_MEMORY;
}
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
"%d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
strlen( propertySet ) + 1 );
//schedule thread for initial notification
thread_struct =
( notify_thread_struct * )
malloc( sizeof( notify_thread_struct ) );
if( thread_struct == NULL ) {
return_code = UPNP_E_OUTOF_MEMORY;
} else {
( *reference_count ) = 1;
thread_struct->servId = servId_copy;
thread_struct->UDN = UDN_copy;
thread_struct->headers = headers;
thread_struct->propertySet = propertySet;
strcpy( thread_struct->sid, sid );
thread_struct->eventKey = sub->eventKey++;
thread_struct->reference_count = reference_count;
thread_struct->device_handle = device_handle;
TPJobInit( &job, ( start_routine ) genaNotifyThread,
thread_struct );
TPJobSetFreeFunction( &job, ( free_routine ) free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
if( ( return_code =
ThreadPoolAdd( &gSendThreadPool, &job, NULL ) ) != 0 ) {
if( return_code == EOUTOFMEM ) {
return_code = UPNP_E_OUTOF_MEMORY;
}
} else {
return_code = GENA_SUCCESS;
}
}
if( return_code != GENA_SUCCESS ) {
ixmlFreeDOMString( propertySet );
free( reference_count );
free( UDN_copy );
free( servId_copy );
free( thread_struct );
free( headers );
}
HandleUnlock( );
return return_code;
}
/****************************************************************************
* Function : genaNotifyAllExt
*
* Parameters :
* IN UpnpDevice_Handle device_handle : Device handle
* IN char *UDN : Device udn
* IN char *servId : Service ID
* IN IXML_Document *PropSet : XML document Event varible property set
*
* Description : This function sends a notification to all the subscribed
* control points
*
* Return : int
*
* Note : This function is similar to the genaNotifyAll. the only difference
* is it takes the document instead of event variable array
****************************************************************************/
int
genaNotifyAllExt( IN UpnpDevice_Handle device_handle,
IN char *UDN,
IN char *servId,
IN IXML_Document * PropSet )
{
char *headers = NULL;
int headers_size;
int return_code = GENA_SUCCESS;
char *UDN_copy = NULL;
char *servId_copy = NULL;
int *reference_count = NULL;
struct Handle_Info *handle_info;
DOMString propertySet = NULL;
ThreadPoolJob job;
subscription *finger = NULL;
notify_thread_struct *thread_struct = NULL;
service_info *service = NULL;
reference_count = ( int * )malloc( sizeof( int ) );
if( reference_count == NULL )
return UPNP_E_OUTOF_MEMORY;
( *reference_count = 0 );
UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );
if( UDN_copy == NULL ) {
free( reference_count );
return UPNP_E_OUTOF_MEMORY;
}
servId_copy = ( char * )malloc( strlen( servId ) + 1 );
if( servId_copy == NULL ) {
free( UDN_copy );
free( reference_count );
return UPNP_E_OUTOF_MEMORY;
}
strcpy( UDN_copy, UDN );
strcpy( servId_copy, servId );
propertySet = ixmlPrintDocument( PropSet );
if( propertySet == NULL ) {
free( UDN_copy );
free( servId_copy );
free( reference_count );
return UPNP_E_INVALID_PARAM;
}
headers_size = strlen( "CONTENT-TYPE text/xml\r\n" ) +
strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
strlen( "NT: upnp:event\r\n" ) +
strlen( "NTS: upnp:propchange\r\n" ) + 1;
headers = ( char * )malloc( headers_size );
if( headers == NULL ) {
free( UDN_copy );
free( servId_copy );
ixmlFreeDOMString( propertySet );
free( reference_count );
return UPNP_E_OUTOF_MEMORY;
}
//changed to add null terminator at end of content
//content length = (length in bytes of property set) + null char
sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
"%d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
strlen( propertySet ) + 1 );
HandleLock( );
if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE )
return_code = GENA_E_BAD_HANDLE;
else {
if( ( service = FindServiceId( &handle_info->ServiceTable,
servId, UDN ) ) != NULL ) {
finger = GetFirstSubscription( service );
while( finger ) {
thread_struct =
( notify_thread_struct * )
malloc( sizeof( notify_thread_struct ) );
if( thread_struct == NULL ) {
break;
return_code = UPNP_E_OUTOF_MEMORY;
}
( *reference_count )++;
thread_struct->reference_count = reference_count;
thread_struct->UDN = UDN_copy;
thread_struct->servId = servId_copy;
thread_struct->headers = headers;
thread_struct->propertySet = propertySet;
strcpy( thread_struct->sid, finger->sid );
thread_struct->eventKey = finger->eventKey++;
thread_struct->device_handle = device_handle;
//if overflow, wrap to 1
if( finger->eventKey < 0 ) {
finger->eventKey = 1;
}
TPJobInit( &job, ( start_routine ) genaNotifyThread,
thread_struct );
TPJobSetFreeFunction( &job,
( free_routine )
free_notify_struct );
TPJobSetPriority( &job, MED_PRIORITY );
if( ( return_code = ThreadPoolAdd( &gSendThreadPool,
&job, NULL ) ) != 0 ) {
if( return_code == EOUTOFMEM ) {
return_code = UPNP_E_OUTOF_MEMORY;
}
break;
}
finger = GetNextSubscription( service, finger );
}
} else
return_code = GENA_E_BAD_SERVICE;
}
if( ( *reference_count ) == 0 ) {
free( reference_count );
free( headers );
ixmlFreeDOMString( propertySet );
free( UDN_copy );
free( servId_copy );
}
HandleUnlock( );
return return_code;
}
/****************************************************************************
* Function : genaNotifyAll
*
* Parameters :
* IN UpnpDevice_Handle device_handle : Device handle
* IN char *UDN : Device udn
* IN char *servId : Service ID
* IN char **VarNames : array of varible names
* IN char **VarValues : array of variable values
* IN int var_count : number of variables
*
* Description : This function sends a notification to all the subscribed
* control points
*
* Return : int
*
* Note : This function is similar to the genaNotifyAllExt. The only difference
* is it takes event variable array instead of xml document.
****************************************************************************/
int
genaNotifyAll( IN UpnpDevice_Handle device_handle,
IN char *UDN,
IN char *servId,
IN char **VarNames,
IN char **VarValues,
IN int var_count )
{
char *headers = NULL;
char *propertySet = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -