📄 gena_ctrlpt.c
字号:
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;
}
typedef struct
{
http_parser_t parser;
struct sockaddr_in dest_addr;
} gena_thread_data;
#define GENABUFSIZE 5000
/************************************************************************
* Function : gena_process_notification_broadcast
*
* Parameters:
* IN http_message_t* event: The http message contains the GENA
* notification
*
* Description:
* This function processes NOTIFY events that are sent by devices.
* called by genacallback()
*
* Returns: void
*
* Note : called by genacallback()
****************************************************************************/
void
gena_process_notification_broadcast( IN http_message_t * event )
{
struct Upnp_BroadcastEvent event_struct;
int eventKey;
token sid;
// client_subscription *subscription;
IXML_Document *ChangedVars;
struct Handle_Info *handle_info;
void *cookie;
Upnp_FunPtr callback;
UpnpClient_Handle client_handle;
char * eventURL;
#ifdef _WIN32
FILE * outFile = 0;
#endif
memptr sid_hdr;
memptr nt_hdr,
nts_hdr;
memptr seq_hdr;
// get SID
if( httpmsg_find_hdr( event, HDR_SID, &sid_hdr ) == NULL ) {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
#ifdef _WIN32
outFile = fopen("genaDebug.txt", "a");
if (outFile) {
fprintf(outFile, "httpmsg_find failed\n");
fclose(outFile);
}
#endif
return;
}
sid.buff = sid_hdr.buf;
sid.size = sid_hdr.length;
// get event key
if( httpmsg_find_hdr( event, HDR_SEQ, &seq_hdr ) == NULL ||
matchstr( seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey )
!= PARSE_OK ) {
// error_respond( info, HTTP_BAD_REQUEST, event );
#ifdef _WIN32
outFile = fopen("genaDebug.txt", "a");
if (outFile) {
fprintf(outFile, "httpmsg_find_hdr HDR_SEQ failed\n");
fclose(outFile);
}
#endif
return;
}
// get NT and NTS headers
if( httpmsg_find_hdr( event, HDR_NT, &nt_hdr ) == NULL ||
httpmsg_find_hdr( event, HDR_NTS, &nts_hdr ) == NULL ) {
// error_respond( info, HTTP_BAD_REQUEST, event );
#ifdef _WIN32
outFile = fopen("genaDebug.txt", "a");
if (outFile) {
fprintf(outFile, "httpmsg_find_hdr HDR_NT failed\n");
fclose(outFile);
}
#endif
return;
}
// verify NT and NTS headers
/*
if( memptr_cmp( &nt_hdr, "upnp:event" ) != 0 ||
memptr_cmp( &nts_hdr, "upnp:propchange" ) != 0 ) {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
return;
}
*/
// parse the content (should be XML)
if( !has_xml_content_type( event ) ||
event->msg.length == 0 ||
( ixmlParseBufferEx( event->entity.buf, &ChangedVars ) ) !=
IXML_SUCCESS ) {
// error_respond( info, HTTP_BAD_REQUEST, event );
#ifdef _WIN32
outFile = fopen("genaDebug.txt", "a");
if (outFile) {
fprintf(outFile, "ixmlParseBufferEx failed\n");
fclose(outFile);
}
#endif
return;
}
HandleLock( );
// get client info
if( GetClientHandleInfo( &client_handle, &handle_info ) != HND_CLIENT ) {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
HandleUnlock( );
ixmlDocument_free( ChangedVars );
#ifdef _WIN32
outFile = fopen("genaDebug.txt", "a");
if (outFile) {
fprintf(outFile,"GetClientHandleInfo failed\n");
fclose(outFile);
}
#endif
return;
}
if (memptr_cmp( &nts_hdr, "urn:upnp-org:serviceId:LLLogging1" ) == 0 ) {
eventURL = "http://192.168.1.203:49152/upnp/event1";
} else {
eventURL = "http://192.168.1.203:49152/upnp/event2";
}
#ifdef _WIN32
/*
outFile = fopen("ntntsFile.txt", "a");
fprintf(outFile, "just checked event url\n");
fclose(outFile);
*/
#endif
/*
// get subscription based on SID
if( ( subscription = GetClientSubEventURL( handle_info->ClientSubList,
eventURL ) ) == NULL ) {
if( eventKey == 0 ) {
// wait until we've finished processing a subscription
// (if we are in the middle)
// this is to avoid mistakenly rejecting the first event if we
// receive it before the subscription response
HandleUnlock( );
// try and get Subscription Lock
// (in case we are in the process of subscribing)
SubscribeLock( );
// get HandleLock again
HandleLock( );
if( GetClientHandleInfo( &client_handle, &handle_info )
!= HND_CLIENT ) {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
SubscribeUnlock( );
HandleUnlock( );
ixmlDocument_free( ChangedVars );
return;
}
if( ( subscription =
GetClientSubEventURL( handle_info->ClientSubList,
eventURL ) ) == NULL ) {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
SubscribeUnlock( );
HandleUnlock( );
ixmlDocument_free( ChangedVars );
return;
}
SubscribeUnlock( );
} else {
// error_respond( info, HTTP_PRECONDITION_FAILED, event );
HandleUnlock( );
ixmlDocument_free( ChangedVars );
return;
}
}
*/
// error_respond( info, HTTP_OK, event ); // success
// fill event struct
strncpy(event_struct.NotificationType, nt_hdr.buf, nt_hdr.length);
event_struct.NotificationType[nt_hdr.length] = 0;
strncpy(event_struct.NotificationSubtype, nts_hdr.buf, nts_hdr.length);
event_struct.NotificationSubtype[nts_hdr.length] = 0;
#ifdef _WIN32
/*
outFile = fopen("ntntsFile.txt", "a");
fprintf(outFile, "nt = %s\nnts = %s\n", event_struct.NotificationType,
event_struct.NotificationSubtype);
fclose(outFile);
*/
#endif
event_struct.ChangedVariables = ChangedVars;
// copy callback
callback = handle_info->Callback;
cookie = handle_info->Cookie;
HandleUnlock( );
// make callback with event struct
// In future, should find a way of mainting
// that the handle is not unregistered in the middle of a
// callback
callback( UPNP_EVENT_BROADCAST_RECEIVED, &event_struct, cookie );
ixmlDocument_free( ChangedVars );
}
/************************************************************************
* Function : free_gena_event_handler_data
*
* Parameters:
* IN void *the_data: gena_thread_data structure. This structure contains
* GENA request message.
*
* Description:
* This function frees the gena request
*
* Returns: VOID
*
***************************************************************************/
static void
free_gena_event_handler_data( void *the_data )
{
gena_thread_data *data = ( gena_thread_data * ) the_data;
if( data != NULL ) {
http_message_t *hmsg = &data->parser.msg;
// free data
httpmsg_destroy( hmsg );
free( data );
}
}
/************************************************************************
* Function : valid_gena_msg
*
* Parameters:
* IN void *the_data: gena_thread_data structure. This structure contains
* GENA request message.
*
* Description:
* This function do some quick checking of the gena msg
*
* Returns: xboolean
* returns TRUE if msg is valid else FALSE
***************************************************************************/
static XINLINE xboolean
valid_gena_msg( IN http_message_t * hmsg )
{
// memptr hdr_value;
// check for valid methods - NOTIFY or M-SEARCH
if( hmsg->method != HTTPMETHOD_NOTIFY ) {
return FALSE;
}
return TRUE; // passed quick check
}
/************************************************************************
* Function : start_event_handler
*
* Parameters:
* IN void *the_data: gena_thread_data structure. This structure contains
* GENA request message.
*
* Description:
* This function parses the message and dispatches it to a handler
* which handles the GENA notification msg
*
* Returns: int
* 0 if successful -1 if error
***************************************************************************/
static XINLINE int
start_event_handler( void *Data )
{
http_parser_t *parser = NULL;
parse_status_t status;
gena_thread_data *data = ( gena_thread_data * ) Data;
parser = &data->parser;
status = parser_parse( parser );
if( status == PARSE_FAILURE ) {
// MTY!!!
if( parser->msg.method != HTTPMETHOD_NOTIFY ) {
// ignore bad msg, or not enuf mem
goto error_handler;
}
// valid notify msg
} else if( status != PARSE_SUCCESS ) {
goto error_handler;
}
// check msg
if( !valid_gena_msg( &parser->msg ) ) {
goto error_handler;
}
return 0; //////// done; thread will free 'data'
error_handler:
free_gena_event_handler_data( data );
return -1;
}
/************************************************************************
* Function : gena_event_handler_thread
*
* Parameters:
* IN void *the_data: gena_thread_data structure. This structure contains
* GENA request message.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -