📄 gena_device.c
字号:
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.****************************************************************************/intgenaNotifyAll( 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; 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; 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 ); if( ( return_code = GeneratePropertySet( VarNames, VarValues, var_count, &propertySet ) ) != XML_SUCCESS ) { free( UDN_copy ); free( servId_copy ); free( reference_count ); return return_code; } 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 ) { return_code = UPNP_E_OUTOF_MEMORY; break; } ( *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 : respond_ok** Parameters :* IN SOCKINFO *info : socket connection of request* IN int time_out : accepted duration* IN subscription *sub : accepted subscription* IN http_message_t* request : http request** Description : Function to return OK message in the case * of a subscription request.** Return : static int* returns UPNP_E_SUCCESS if successful else returns appropriate error* Note :****************************************************************************/static intrespond_ok( IN SOCKINFO * info, IN int time_out, IN subscription * sub, IN http_message_t * request ){ int major, minor; membuffer response; int return_code; char timeout_str[100]; int upnp_timeout = UPNP_TIMEOUT; http_CalcResponseVersion( request->major_version, request->minor_version, &major, &minor ); if( time_out >= 0 ) { sprintf( timeout_str, "TIMEOUT: Second-%d", time_out ); } else { strcpy( timeout_str, "TIMEOUT: Second-infinite" ); } membuffer_init( &response ); response.size_inc = 30; if( http_MakeMessage( &response, major, minor, "R" "D" "S" "ssc" "sc" "c", HTTP_OK, "SID: ", sub->sid, timeout_str ) != 0 ) { membuffer_destroy( &response ); error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request ); return UPNP_E_OUTOF_MEMORY; } return_code = http_SendMessage( info, &upnp_timeout, "b", response.buf, response.length ); membuffer_destroy( &response ); return return_code;}/***************************************************************************** Function : create_url_list** Parameters :* IN memptr* url_list : * OUT URL_list *out : ** Description : Function to parse the Callback header value in * subscription requests takes in a buffer containing URLS delimited by * '<' and '>'. The entire buffer is copied into dynamic memory* and stored in the URL_list. Pointers to the individual urls within * this buffer are allocated and stored in the URL_list. Only URLs with * network addresses are considered(i.e. host:port or domain name)** Return : int* if successful returns the number of URLs parsed * else UPNP_E_OUTOF_MEMORY* Note :****************************************************************************/static intcreate_url_list( IN memptr * url_list, OUT URL_list * out ){ int URLcount = 0; int i; int return_code = 0; uri_type temp; token urls; token *URLS; urls.buff = url_list->buf; urls.size = url_list->length; URLS = &urls; out->size = 0; out->URLs = NULL; out->parsedURLs = NULL; for( i = 0; i < URLS->size; i++ ) { if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) { if( ( ( return_code = parse_uri( &URLS->buff[i + 1], URLS->size - i + 1, &temp ) ) == HTTP_SUCCESS ) && ( temp.hostport.text.size != 0 ) ) { URLcount++; } else { if( return_code == UPNP_E_OUTOF_MEMORY ) { return return_code; } } } } if( URLcount > 0 ) { out->URLs = ( char * )malloc( URLS->size + 1 ); out->parsedURLs = ( uri_type * ) malloc( sizeof( uri_type ) * URLcount ); if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) { free( out->URLs ); free( out->parsedURLs ); out->URLs = NULL; out->parsedURLs = NULL; return UPNP_E_OUTOF_MEMORY; } memcpy( out->URLs, URLS->buff, URLS->size ); out->URLs[URLS->size] = 0; URLcount = 0; for( i = 0; i < URLS->size; i++ ) { if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) { if( ( ( return_code = parse_uri( &out->URLs[i + 1], URLS->size - i + 1, &out->parsedURLs[URLcount] ) ) == HTTP_SUCCESS ) && ( out->parsedURLs[URLcount].hostport.text.size != 0 ) ) { URLcount++; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -