⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gena_device.c

📁 Upnp开发包文件
💻 C
📖 第 1 页 / 共 4 页
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2000-2003 Intel Corporation // All rights reserved. //// Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: //// * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither name of Intel Corporation nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission.// // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL OR // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE./////////////////////////////////////////////////////////////////////////////#include "config.h"#if EXCLUDE_GENA == 0#ifdef INCLUDE_DEVICE_APIS#include "gena.h"#include "sysdep.h"#include "uuid.h"#include "upnpapi.h"#include "parsetools.h"#include "statcodes.h"#include "httpparser.h"#include "httpreadwrite.h"#include "unixutil.h"/************************************************************************* Function : genaUnregisterDevice*																	* Parameters:														*	IN UpnpDevice_Handle device_handle: Handle of the root device** Description:														*	This function cleans the service table of the device. ** Returns: int*	returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE****************************************************************************/intgenaUnregisterDevice( IN UpnpDevice_Handle device_handle ){    struct Handle_Info *handle_info;    HandleLock(  );    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {        DBGONLY( UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__,                             "genaUnregisterDevice : BAD Handle : %d\n",                             device_handle ) );        HandleUnlock(  );        return GENA_E_BAD_HANDLE;    }    freeServiceTable( &handle_info->ServiceTable );    HandleUnlock(  );    return UPNP_E_SUCCESS;}/************************************************************************* Function : GeneratePropertySet*																	* Parameters:														*	IN char **names : Array of variable names (go in the event notify)*	IN char ** values : Array of variable values (go in the event notify)*   IN int count : number of variables*   OUT DOMString *out: PropertySet node in the string format** Description:														*	This function to generate XML propery Set for notifications				** Returns: int*	returns UPNP_E_SUCCESS if successful else returns GENA_E_BAD_HANDLE** Note: XML_VERSION comment is NOT sent due to interop issues with other *		UPnP vendors****************************************************************************/static intGeneratePropertySet( IN char **names,                     IN char **values,                     IN int count,                     OUT DOMString * out ){    char *buffer;    int counter = 0;    int size = 0;    int temp_counter = 0;    //size+=strlen(XML_VERSION);  the XML_VERSION is not interopeable with     //other vendors    size += strlen( XML_PROPERTYSET_HEADER );    size += strlen( "</e:propertyset>\n\n" );    for( temp_counter = 0, counter = 0; counter < count; counter++ ) {        size += strlen( "<e:property>\n</e:property>\n" );        size +=            ( 2 * strlen( names[counter] ) + strlen( values[counter] ) +              ( strlen( "<></>\n" ) ) );    }    buffer = ( char * )malloc( size + 1 );    if( buffer == NULL ) {        return UPNP_E_OUTOF_MEMORY;    }    memset( buffer, 0, size + 1 );    //strcpy(buffer,XML_VERSION);  the XML_VERSION is not interopeable with     //other vendors    strcpy( buffer, XML_PROPERTYSET_HEADER );    for( counter = 0; counter < count; counter++ ) {        strcat( buffer, "<e:property>\n" );        sprintf( &buffer[strlen( buffer )],                 "<%s>%s</%s>\n</e:property>\n", names[counter],                 values[counter], names[counter] );    }    strcat( buffer, "</e:propertyset>\n\n" );    ( *out ) = ixmlCloneDOMString( buffer );    free( buffer );    return XML_SUCCESS;}/************************************************************************* Function : free_notify_struct*																	* Parameters:														*	IN notify_thread_struct * input : Notify structure** Description:														*	This function frees memory used in notify_threads if the reference *	count is 0 otherwise decrements the refrence count** Returns: VOID*	****************************************************************************/static voidfree_notify_struct( IN notify_thread_struct * input ){    ( *input->reference_count )--;    if( ( *input->reference_count ) == 0 ) {        free( input->headers );        ixmlFreeDOMString( input->propertySet );        free( input->servId );        free( input->UDN );        free( input->reference_count );    }    free( input );}/*****************************************************************************	Function :	notify_send_and_recv**	Parameters :*		IN uri_type* destination_url : subscription callback URL *										(URL of the control point)*		IN membuffer* mid_msg :	Common HTTP headers *		IN char* propertySet :	The evented XML *		OUT http_parser_t* response : The response from the control point.**	Description :	This function sends the notify message and returns a *					reply.**	Return : int*		on success: returns UPNP_E_SUCCESS; else returns a UPNP error**	Note : called by genaNotify****************************************************************************/static XINLINE intnotify_send_and_recv( IN uri_type * destination_url,                      IN membuffer * mid_msg,                      IN char *propertySet,                      OUT http_parser_t * response ){    uri_type url;    int conn_fd;    membuffer start_msg;    int ret_code;    int err_code;    int timeout;    SOCKINFO info;    // connect    DBGONLY( UpnpPrintf( UPNP_ALL, GENA, __FILE__, __LINE__,                         "gena notify to: %.*s\n",                         destination_url->hostport.text.size,                         destination_url->hostport.text.buff ); )        conn_fd = http_Connect( destination_url, &url );    if( conn_fd < 0 ) {        return conn_fd;         // return UPNP error    }    if( ( ret_code = sock_init( &info, conn_fd ) ) != 0 ) {        sock_destroy( &info, SD_BOTH );        return ret_code;    }    // make start line and HOST header    membuffer_init( &start_msg );    if( http_MakeMessage( &start_msg, 1, 1,                          "q" "s",                          HTTPMETHOD_NOTIFY, &url, mid_msg->buf ) != 0 ) {        membuffer_destroy( &start_msg );        sock_destroy( &info, SD_BOTH );        return UPNP_E_OUTOF_MEMORY;    }    timeout = HTTP_DEFAULT_TIMEOUT;    // send msg (note +1 for propertyset; null-terminator is also sent)    if( ( ret_code = http_SendMessage( &info, &timeout,                                       "bb",                                       start_msg.buf, start_msg.length,                                       propertySet,                                       strlen( propertySet ) + 1 ) ) !=        0 ) {        membuffer_destroy( &start_msg );        sock_destroy( &info, SD_BOTH );        return ret_code;    }    if( ( ret_code = http_RecvMessage( &info, response,                                       HTTPMETHOD_NOTIFY, &timeout,                                       &err_code ) ) != 0 ) {        membuffer_destroy( &start_msg );        sock_destroy( &info, SD_BOTH );        httpmsg_destroy( &response->msg );        return ret_code;    }    sock_destroy( &info, SD_BOTH ); //should shutdown completely    //when closing socket    //  sock_destroy( &info,SD_RECEIVE);    membuffer_destroy( &start_msg );    return UPNP_E_SUCCESS;}/*****************************************************************************	Function :	genaNotify**	Parameters :*		IN char *headers :	(null terminated) (includes all headers *							(including \r\n) except SID and SEQ)*		IN char *propertySet :	The evented XML *		IN subscription* sub :	subscription to be Notified, *								Assumes this is valid for life of function)**	Description :	Function to Notify a particular subscription of a *					particular event. In general the service should NOT be *					blocked around this call. (this may cause deadlock *					with a client) NOTIFY http request is sent and the *					reply is processed.**	Return :	int*		GENA_SUCCESS  if the event was delivered else returns appropriate *		error**	Note :****************************************************************************/intgenaNotify( IN char *headers,            IN char *propertySet,            IN subscription * sub ){    int i;    membuffer mid_msg;    membuffer endmsg;    uri_type *url;    http_parser_t response;    int return_code = -1;    membuffer_init( &mid_msg );    // make 'end' msg (the part that won't vary with the destination)    endmsg.size_inc = 30;    if( http_MakeMessage( &mid_msg, 1, 1,                          "s" "ssc" "sdcc",                          headers,                          "SID: ", sub->sid,                          "SEQ: ", sub->ToSendEventKey ) != 0 ) {        membuffer_destroy( &mid_msg );        return UPNP_E_OUTOF_MEMORY;    }    // send a notify to each url until one goes thru    for( i = 0; i < sub->DeliveryURLs.size; i++ ) {        url = &sub->DeliveryURLs.parsedURLs[i];        if( ( return_code = notify_send_and_recv( url,                                                  &mid_msg, propertySet,                                                  &response ) ) ==            UPNP_E_SUCCESS ) {            break;        }    }    membuffer_destroy( &mid_msg );    if( return_code == UPNP_E_SUCCESS ) {        if( response.msg.status_code == HTTP_OK ) {            return_code = GENA_SUCCESS;        } else {            if( response.msg.status_code == HTTP_PRECONDITION_FAILED ) {                //Invalid SID gets removed                return_code = GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB;            } else {                return_code = GENA_E_NOTIFY_UNACCEPTED;            }        }        httpmsg_destroy( &response.msg );    }    return return_code;}/*****************************************************************************	Function :	genaNotifyThread**	Parameters :*			IN void * input : notify thread structure containing all the *								headers and property set info**	Description :	Thread job to Notify a control point. It validates the*		subscription and copies the subscription. Also make sure that *		events are sent in order. **	Return : void**	Note : calls the genaNotify to do the actual work****************************************************************************/static voidgenaNotifyThread( IN void *input ){    subscription *sub;    service_info *service;    subscription sub_copy;    notify_thread_struct *in = ( notify_thread_struct * ) input;    int return_code;    struct Handle_Info *handle_info;    ThreadPoolJob job;    HandleLock(  );    //validate context    if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {        free_notify_struct( in );        HandleUnlock(  );        return;    }    if( ( ( service = FindServiceId( &handle_info->ServiceTable,                                     in->servId, in->UDN ) ) == NULL )        || ( !service->active )        || ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL )        || ( ( copy_subscription( sub, &sub_copy ) != HTTP_SUCCESS ) ) ) {        free_notify_struct( in );        HandleUnlock(  );        return;    }    //If the event is out of order push it back to the job queue    if( in->eventKey != sub->ToSendEventKey ) {        TPJobInit( &job, ( start_routine ) genaNotifyThread, input );        TPJobSetFreeFunction( &job, ( free_function ) free_notify_struct );        TPJobSetPriority( &job, MED_PRIORITY );        ThreadPoolAdd( &gSendThreadPool, &job, NULL );        freeSubscription( &sub_copy );        HandleUnlock(  );        return;    }    HandleUnlock(  );    //send the notify    return_code = genaNotify( in->headers, in->propertySet, &sub_copy );    freeSubscription( &sub_copy );    HandleLock(  );    if( GetHandleInfo( in->device_handle, &handle_info ) != HND_DEVICE ) {        free_notify_struct( in );        HandleUnlock(  );        return;    }    //validate context    if( ( ( service = FindServiceId( &handle_info->ServiceTable,                                     in->servId, in->UDN ) ) == NULL )        || ( !service->active )        || ( ( sub = GetSubscriptionSID( in->sid, service ) ) == NULL ) ) {        free_notify_struct( in );        HandleUnlock(  );        return;    }    sub->ToSendEventKey++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -