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

📄 gena_device.c

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

	// MTY !!!
/*
	printf("a URL:\n\t%d\n\t%s\n\t%d\n\t%s\n\t%s\n\t%d\n", url->type, 
	       url->scheme, url->path_type,
	       url->pathquery, url->fragment,
	       url->hostport.IPv4address);
*/

        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 void
genaNotifyThread( 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++;

    if( sub->ToSendEventKey < 0 )   //wrap to 1 for overflow
        sub->ToSendEventKey = 1;

    if( return_code == GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB ) {
        RemoveSubscriptionSID( in->sid, service );
    }

    free_notify_struct( in );
    HandleUnlock(  );
}

/****************************************************************************
*	Function :	genaNotifyBroadcastThread
*
*	Parameters :
*			IN void * input : notify thread structure containing all the 
*								headers and property set info
*
*	Description :	Thread job to broadcast Notifies to all control points.
*
*	Return : void
*
*	Note : calls the genaNotify to do the actual work
****************************************************************************/
static void
genaNotifyBroadcastThread( IN void *input )
{


    notify_thread_struct *in = ( notify_thread_struct * ) input;
    int return_code;
//    ThreadPoolJob job;
    char msgBuf[2000];
    uri_type url;
    membuffer mid_msg;
    membuffer start_msg;
    membuffer endmsg;

	//printf("genaNotifyBroadcastThread\n");

	membuffer_init( &mid_msg );
    membuffer_init( &start_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",
                          in->headers,
                          "SID: ", "0",
                          "SEQ: ", "0" ) != 0 ) {
        membuffer_destroy( &mid_msg );
        return UPNP_E_OUTOF_MEMORY;
    }


    url.type = 0;
    url.scheme.buff = "http";
    url.scheme.size = strlen(url.scheme.buff);
    url.path_type = 4;
    url.pathquery.buff = 0;
    url.pathquery.size = 0;
    url.fragment.buff = 0;
    url.fragment.size = 0;
    url.hostport.text.buff = "192.168.1.204:49152";
    url.hostport.text.size = strlen(url.hostport.text.buff);
    

    if( http_MakeMessage( &start_msg, 1, 1,
                          "q" "s",
                          HTTPMETHOD_NOTIFY, &url, mid_msg.buf ) != 0 ) {
	membuffer_destroy( &start_msg );
	membuffer_destroy( &mid_msg );
	return UPNP_E_OUTOF_MEMORY;
    }


    msgBuf[0] = 0;
    strcat(msgBuf, start_msg.buf);

    membuffer_destroy( &mid_msg );
    membuffer_destroy( &start_msg );

//    strcat(msgBuf, in->headers);
    strcat(msgBuf, "\n");
    strcat(msgBuf, in->propertySet);



    //send the notify
    return_code = GenaBroadcastNotifyHandler( msgBuf );


    free_notifyMulticast_struct( in );

}

/****************************************************************************
*	Function :	genaInitNotify
*
*	Parameters :
*		   IN UpnpDevice_Handle device_handle :	Device handle
*		   IN char *UDN :	Device udn
*		   IN char *servId :	Service ID
*		   IN char **VarNames :	Array of variable names
*		   IN char **VarValues :	Array of variable values
*		   IN int var_count :	array size
*		   IN Upnp_SID sid :	subscription ID
*
*	Description :	This function sends the intial state table dump to 
*		newly subscribed control point. 
*
*	Return :	int
*		returns GENA_E_SUCCESS if successful else returns appropriate error
* 
*	Note : No other event will be sent to this control point before the 
*			intial state table dump.
****************************************************************************/
int
genaInitNotify( IN UpnpDevice_Handle device_handle,
                IN char *UDN,
                IN char *servId,
                IN char **VarNames,
                IN char **VarValues,
                IN int var_count,
                IN Upnp_SID sid )
{
    char *UDN_copy = NULL;
    char *servId_copy = NULL;
    char *propertySet = NULL;
    char *headers = NULL;
    subscription *sub = NULL;
    service_info *service = NULL;
    int return_code = GENA_SUCCESS;
    int headers_size;
    int *reference_count = NULL;
    struct Handle_Info *handle_info;
    ThreadPoolJob job;

    notify_thread_struct *thread_struct = NULL;

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "GENA BEGIN INITIAL NOTIFY " ) );

    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 );

    HandleLock(  );

    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
        free( UDN_copy );
        free( reference_count );
        free( servId_copy );
        HandleUnlock(  );
        return GENA_E_BAD_HANDLE;
    }

    if( ( service = FindServiceId( &handle_info->ServiceTable,
                                   servId, UDN ) ) == NULL ) {
        free( UDN_copy );
        free( reference_count );
        free( servId_copy );
        HandleUnlock(  );
        return GENA_E_BAD_SERVICE;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "FOUND SERVICE IN INIT NOTFY: UDN %s, ServID: %d ",
                         UDN, servId ) );

    if( ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ||
        ( sub->active ) ) {
        free( UDN_copy );
        free( reference_count );
        free( servId_copy );
        HandleUnlock(  );
        return GENA_E_BAD_SID;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "FOUND SUBSCRIPTION IN INIT NOTIFY: SID %s ",
                         sid ) );

    sub->active = 1;

    if( ( return_code = GeneratePropertySet( VarNames, VarValues,
                                             var_count,
                                             &propertySet ) ) !=
        XML_SUCCESS ) {
        free( UDN_copy );
        free( reference_count );
        free( servId_copy );
        HandleUnlock(  );
        return return_code;
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "GENERATED PROPERY SET IN INIT NOTIFY: \n'%s'\n",
                         propertySet ) );

    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 ) {
        ixmlFreeDOMString( propertySet );
        free( UDN_copy );
        free( servId_copy );
        free( reference_count );
        HandleUnlock(  );
        return UPNP_E_OUTOF_MEMORY;
    }

    sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: "
             "%d\r\nNT: upnp:event\r\nNTS: upnp:propchange\r\n",
             strlen( propertySet ) + 1 );

    //schedule thread for initial notification

    thread_struct =
        ( notify_thread_struct * )
        malloc( sizeof( notify_thread_struct ) );

    if( thread_struct == NULL ) {
        return_code = UPNP_E_OUTOF_MEMORY;
    } else {
        ( *reference_count ) = 1;
        thread_struct->servId = servId_copy;
        thread_struct->UDN = UDN_copy;
        thread_struct->headers = headers;
        thread_struct->propertySet = propertySet;
        strcpy( thread_struct->sid, sid );
        thread_struct->eventKey = sub->eventKey++;
        thread_struct->reference_count = reference_count;
        thread_struct->device_handle = device_handle;

⌨️ 快捷键说明

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