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

📄 gena_device.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 5 页
字号:
///////////////////////////////////////////////////////////////////////////
//
// 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"
#ifdef _WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#endif

#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
****************************************************************************/
int
genaUnregisterDevice( 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 int
GeneratePropertySet( 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 void
free_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 );
}

static void
free_notifyMulticast_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 int
notify_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 : GenaBroadcastNotifyHandler
*																	
* Parameters:														
*		IN struct sockaddr_in * DestAddr: Ip address, to send the reply.
*		IN int NumPacket: Number of packet to be sent.
*		IN char **RqPacket:Number of packet to be sent.
*
* Description:														
*	This function works as a request handler which passes the HTTP 
*	request string to multicast channel
*
* 
*
* Returns: void *
*	1 if successful else appropriate error
***************************************************************************/
#define  GENA_IP   "239.255.255.250"
#define GENA_PORT 1901
int
GenaBroadcastNotifyHandler( IN char *RqPacket )
{
    // need to know destination address
    // need to have the packet to send out

/*#ifdef _WIN32
    struct ip_mreq genaMcastAddr;
    int option = 1;
#endif*/
    struct sockaddr_in DestAddr;
    SOCKET ReplySock;
    int socklen = sizeof( struct sockaddr_in );
    unsigned long replyAddr = inet_addr( LOCAL_HOST );
    int ttl = 4;                //a/c to UPNP Spec
    int rc;
    int retVal = UPNP_E_SUCCESS;

    DestAddr.sin_family = AF_INET;
    DestAddr.sin_addr.s_addr = inet_addr( GENA_IP );
    DestAddr.sin_port = htons( GENA_PORT );

    ReplySock = socket( AF_INET, SOCK_DGRAM, 0 );
    if( ReplySock == UPNP_INVALID_SOCKET ) {
        return UPNP_E_OUTOF_SOCKET;
    }

//#ifndef _WIN32
    setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_IF,
                ( char * )&replyAddr, sizeof( replyAddr ) );
    setsockopt( ReplySock, IPPROTO_IP, IP_MULTICAST_TTL,
                ( char * )&ttl, sizeof( int ) );
/*#else
	memset( ( void * )&genaMcastAddr, 0, sizeof( struct ip_mreq ) );
    genaMcastAddr.imr_interface.s_addr = htonl( INADDR_ANY );
    genaMcastAddr.imr_multiaddr.s_addr = inet_addr( LOCAL_HOST );
    if( setsockopt( ReplySock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
                    ( char * )&genaMcastAddr,
                    sizeof( struct ip_mreq ) ) != 0 ) {
		    shutdown( ReplySock, SD_BOTH );
		    UpnpCloseSocket( ReplySock );
			printf("Socket Error\n");
		    return UPNP_E_SOCKET_ERROR;
    }
    // result is not checked becuase it will fail in WinMe and Win9x.
    setsockopt( ReplySock, IPPROTO_IP,
                IP_MULTICAST_TTL, &ttl, sizeof( ttl ) );
    if( setsockopt( ReplySock, SOL_SOCKET, SO_BROADCAST,
                    ( const char * )&option, sizeof( option ) ) != 0 ) {
		    shutdown( ReplySock, SD_BOTH );
		    UpnpCloseSocket( ReplySock );
		    return UPNP_E_NETWORK_ERROR;
    }
#endif*/


    rc = sendto( ReplySock, RqPacket ,
		 strlen( RqPacket ),
		 0, ( struct sockaddr * )&DestAddr, socklen );

    if (rc < strlen(RqPacket)) {
	printf("sendto failed, rc = %d\n", rc);
	retVal = UPNP_E_SUCCESS;
    }
	
    shutdown( ReplySock, SD_BOTH );
    UpnpCloseSocket( ReplySock );
    return retVal;
}

/****************************************************************************
*	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 :
****************************************************************************/
int
genaNotify( IN char *headers,
            IN char *propertySet,
            IN subscription * sub )
{
    int i;
    membuffer mid_msg;
    membuffer endmsg;
    uri_type * url;

⌨️ 快捷键说明

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