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

📄 gena_ctrlpt.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 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_CLIENT_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 "gena_ctrlpt.h"
#ifdef _WIN32
#include <winsock2.h>
#include <Ws2tcpip.h>
#endif


SOCKET gGenaSock = UPNP_INVALID_SOCKET;

extern ithread_mutex_t GlobalClientSubscribeMutex;

/************************************************************************
* Function : GenaAutoRenewSubscription									
*																	
* Parameters:														
*	IN void *input: Thread data(upnp_timeout *) needed to send the renewal
*
* Description:														
*	This is a thread function to send the renewal just before the 
*	subscription times out.
*
* Returns: VOID
*	
***************************************************************************/
static void
GenaAutoRenewSubscription( IN void *input )
{
    upnp_timeout *event = ( upnp_timeout * ) input;
    void *cookie;
    Upnp_FunPtr callback_fun;
    struct Handle_Info *handle_info;
    struct Upnp_Event_Subscribe *sub_struct =
        ( struct Upnp_Event_Subscribe * )
        event->Event;

    int send_callback = 0;
    int eventType = 0;

    if( AUTO_RENEW_TIME == 0 ) {
        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                             "GENA SUB EXPIRED" ) );
        sub_struct->ErrCode = UPNP_E_SUCCESS;
        send_callback = 1;
        eventType = UPNP_EVENT_SUBSCRIPTION_EXPIRED;
    } else {
        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                             "GENA AUTO RENEW" ) );
        if( ( ( sub_struct->ErrCode = genaRenewSubscription( event->handle,
                                                             sub_struct->
                                                             Sid,
                                                             &sub_struct->
                                                             TimeOut ) ) !=
              UPNP_E_SUCCESS )
            && ( sub_struct->ErrCode != GENA_E_BAD_SID )
            && ( sub_struct->ErrCode != GENA_E_BAD_HANDLE ) ) {
            send_callback = 1;
            eventType = UPNP_EVENT_AUTORENEWAL_FAILED;
        }
    }
    if( send_callback ) {
        HandleLock(  );
        if( GetHandleInfo( event->handle, &handle_info ) != HND_CLIENT ) {
            HandleUnlock(  );
            free_upnp_timeout( event );
            return;
        }
        DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                             "HANDLE IS VALID" ) );
        callback_fun = handle_info->Callback;
        cookie = handle_info->Cookie;
        HandleUnlock(  );
        //make callback

        callback_fun( eventType, event->Event, cookie );
    }

    free_upnp_timeout( event );
}

/************************************************************************
* Function : ScheduleGenaAutoRenew									
*																	
* Parameters:														
*	IN int client_handle: Handle that also contains the subscription list
*	IN int TimeOut: The time out value of the subscription
*	IN client_subscription * sub: Subscription being renewed
*
* Description:														
*	This function schedules a job to renew the subscription just before
*	time out.
*
* Returns: int
*	return GENA_E_SUCCESS if successful else returns appropriate error
***************************************************************************/
static int
ScheduleGenaAutoRenew( IN int client_handle,
                       IN int TimeOut,
                       IN client_subscription * sub )
{
    struct Upnp_Event_Subscribe *RenewEventStruct = NULL;
    upnp_timeout *RenewEvent = NULL;
    int return_code = GENA_SUCCESS;
    ThreadPoolJob job;

    if( TimeOut == UPNP_INFINITE ) {
        return GENA_SUCCESS;
    }

    RenewEventStruct = ( struct Upnp_Event_Subscribe * )malloc( sizeof
                                                                ( struct
                                                                  Upnp_Event_Subscribe ) );

    if( RenewEventStruct == NULL ) {
        return UPNP_E_OUTOF_MEMORY;
    }

    RenewEvent = ( upnp_timeout * ) malloc( sizeof( upnp_timeout ) );

    if( RenewEvent == NULL ) {
        free( RenewEventStruct );
        return UPNP_E_OUTOF_MEMORY;
    }
    //schedule expire event
    strcpy( RenewEventStruct->Sid, sub->sid );
    RenewEventStruct->ErrCode = UPNP_E_SUCCESS;
    strncpy( RenewEventStruct->PublisherUrl, sub->EventURL,
             UPNP_NAME_SIZE - 1 );
    RenewEventStruct->TimeOut = TimeOut;

    //RenewEvent->EventType=UPNP_EVENT_SUBSCRIPTION_EXPIRE;
    RenewEvent->handle = client_handle;
    RenewEvent->Event = RenewEventStruct;

    TPJobInit( &job, ( start_routine ) GenaAutoRenewSubscription,
               RenewEvent );
    TPJobSetFreeFunction( &job, ( free_routine ) free_upnp_timeout );
    TPJobSetPriority( &job, MED_PRIORITY );

    //Schedule the job
    if( ( return_code = TimerThreadSchedule( &gTimerThread,
                                             TimeOut - AUTO_RENEW_TIME,
                                             REL_SEC, &job, SHORT_TERM,
                                             &( RenewEvent->
                                                eventId ) ) ) !=
        UPNP_E_SUCCESS ) {
        free( RenewEvent );
        free( RenewEventStruct );
        return return_code;
    }

    sub->RenewEventId = RenewEvent->eventId;
    return GENA_SUCCESS;
}

/************************************************************************
* Function : gena_unsubscribe									
*																	
* Parameters:														
*	IN char *url: Event URL of the service
*	IN char *sid: The subcription ID.
*	OUT http_parser_t* response: The UNSUBCRIBE response from the device
*
* Description:														
*	This function sends the UNSUBCRIBE gena request and recieves the 
*	response from the device and returns it as a parameter
*
* Returns: int
*	return 0 if successful else returns appropriate error
***************************************************************************/
static int
gena_unsubscribe( IN char *url,
                  IN char *sid,
                  OUT http_parser_t * response )
{
    int return_code;
    uri_type dest_url;
    membuffer request;

    // parse url
    return_code = http_FixStrUrl( url, strlen( url ), &dest_url );
    if( return_code != 0 ) {
        return return_code;
    }
    // make request msg
    membuffer_init( &request );
    request.size_inc = 30;
    return_code = http_MakeMessage( &request, 1, 1,
                                    "q" "ssc" "U" "c",
                                    HTTPMETHOD_UNSUBSCRIBE, &dest_url,
                                    "SID: ", sid );

    //Not able to make the message so destroy the existing buffer
    if( return_code != 0 ) {
        membuffer_destroy( &request );
        return return_code;
    }
    // send request and get reply
    return_code = http_RequestAndResponse( &dest_url, request.buf,
                                           request.length,
                                           HTTPMETHOD_UNSUBSCRIBE,
                                           HTTP_DEFAULT_TIMEOUT,
                                           response );

    membuffer_destroy( &request );

    if( return_code != 0 )
        httpmsg_destroy( &response->msg );

    if( return_code == 0 && response->msg.status_code != HTTP_OK ) {
        return_code = UPNP_E_UNSUBSCRIBE_UNACCEPTED;
        httpmsg_destroy( &response->msg );
    }

    return return_code;
}

/************************************************************************
* Function : gena_subscribe									
*																	
* Parameters:														
*	IN char *url: url of service to subscribe
*	INOUT int* timeout:subscription time desired (in secs)
*	IN char* renewal_sid:for renewal, this contains a currently h
*						 held subscription SID. For first time 
*						 subscription, this must be NULL
*	OUT char** sid: SID returned by the subscription or renew msg
*
* Description:														
*	This function subscribes or renew subscription
*
* Returns: int
*	return 0 if successful else returns appropriate error
***************************************************************************/
static int
gena_subscribe( IN char *url,
                INOUT int *timeout,
                IN char *renewal_sid,
                OUT char **sid )
{
    int return_code;
    memptr sid_hdr,
      timeout_hdr;
    char timeout_str[25];
    membuffer request;
    uri_type dest_url;
    http_parser_t response;

    *sid = NULL;                // init

    // request timeout to string
    if( ( timeout == NULL ) ||
        ( ( *timeout > 0 )
          && ( *timeout < CP_MINIMUM_SUBSCRIPTION_TIME ) ) ) {
        sprintf( timeout_str, "%d", CP_MINIMUM_SUBSCRIPTION_TIME );
    } else if( *timeout >= 0 ) {
        sprintf( timeout_str, "%d", *timeout );
    } else {
        strcpy( timeout_str, "infinite" );
    }

    // parse url
    return_code = http_FixStrUrl( url, strlen( url ), &dest_url );
    if( return_code != 0 ) {
        return return_code;
    }
    // make request msg
    membuffer_init( &request );
    request.size_inc = 30;
    if( renewal_sid ) {
        // renew subscription
        return_code = http_MakeMessage( &request, 1, 1,
                                        "q" "ssc" "ssc" "c",
                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
                                        "SID: ", renewal_sid,
                                        "TIMEOUT: Second-", timeout_str );
    } else {
        // subscribe
        return_code = http_MakeMessage( &request, 1, 1,
                                        "q" "sssdsscc",
                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
                                        "CALLBACK: <http://", LOCAL_HOST,
                                        ":", LOCAL_PORT,
                                        "/>\r\n" "NT: upnp:event\r\n"
                                        "TIMEOUT: Second-", timeout_str );
    }
    if( return_code != 0 ) {
        return return_code;
    }
    // send request and get reply
    return_code = http_RequestAndResponse( &dest_url, request.buf,
                                           request.length,
                                           HTTPMETHOD_SUBSCRIBE,
                                           HTTP_DEFAULT_TIMEOUT,
                                           &response );

    membuffer_destroy( &request );

    if( return_code != 0 ) {
        httpmsg_destroy( &response.msg );
        return return_code;
    }
    if( response.msg.status_code != HTTP_OK ) {
        httpmsg_destroy( &response.msg );
        return UPNP_E_SUBSCRIBE_UNACCEPTED;
    }
    // get SID and TIMEOUT
    if( httpmsg_find_hdr( &response.msg, HDR_SID, &sid_hdr ) == NULL ||
        sid_hdr.length == 0 ||
        httpmsg_find_hdr( &response.msg,
                          HDR_TIMEOUT, &timeout_hdr ) == NULL ||
        timeout_hdr.length == 0 ) {
        httpmsg_destroy( &response.msg );
        return UPNP_E_BAD_RESPONSE;
    }
    // save timeout
    if( matchstr( timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0",
                  timeout ) == PARSE_OK ) {
        // nothing  
    } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) == 0 ) {
        *timeout = -1;
    } else {
        httpmsg_destroy( &response.msg );
        return UPNP_E_BAD_RESPONSE;
    }

    // save SID

⌨️ 快捷键说明

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