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

📄 ssdp_ctrlpt.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 2 页
字号:
                        matched = 0;
                        break;
                    }
            }

            if( matched ) {
                //schedule call back
                threadData =
                    ( ResultData * ) malloc( sizeof( ResultData ) );
                if( threadData != NULL ) {
                    threadData->param = param;
                    threadData->cookie = searchArg->cookie;
                    threadData->ctrlpt_callback = ctrlpt_callback;
                    TPJobInit( &job, ( start_routine ) send_search_result,
                               threadData );
                    TPJobSetPriority( &job, MED_PRIORITY );
                    TPJobSetFreeFunction( &job, ( free_routine ) free );
                    ThreadPoolAdd( &gRecvThreadPool, &job, NULL );
                }
            }
            node = ListNext( &ctrlpt_info->SsdpSearchList, node );
        }

        HandleUnlock(  );
        //ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie );
    }
}

/************************************************************************
* Function : process_reply											
*																	
* Parameters:														
*		IN char* request_buf: the response came from the device
*		IN int buf_len: The length of the response buffer
*	    IN struct sockaddr_in* dest_addr: The address of the device
*		IN void *cookie : cookie passed by the control point application
*							at the time of sending search message
*
* Description:														
*	This function processes reply recevied from a search
*
* Returns: void
*
***************************************************************************/
static XINLINE void
process_reply( IN char *request_buf,
               IN int buf_len,
               IN struct sockaddr_in *dest_addr,
               IN void *cookie )
{
    http_parser_t parser;

    parser_response_init( &parser, HTTPMETHOD_MSEARCH );

    // parse
    if( parser_append( &parser, request_buf, buf_len ) != PARSE_SUCCESS ) {
        httpmsg_destroy( &parser.msg );
        return;
    }
    // handle reply
    ssdp_handle_ctrlpt_msg( &parser.msg, dest_addr, FALSE, cookie );

    // done
    httpmsg_destroy( &parser.msg );
}

/************************************************************************
* Function : CreateClientRequestPacket											
*																	
* Parameters:														
*		IN char * RqstBuf:Output string in HTTP format.
*		IN char *SearchTarget:Search Target
*	    IN int Mx dest_addr: Number of seconds to wait to 
*							collect all the responses
*
* Description:														
*	This function creates a HTTP search request packet 
* depending on the input parameter.
*
* Returns: void
*
***************************************************************************/
static void
CreateClientRequestPacket( IN char *RqstBuf,
                           IN int Mx,
                           IN char *SearchTarget )
{
    char TempBuf[COMMAND_LEN];
    int Port;

    strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" );

    Port = SSDP_PORT;
    strcpy( TempBuf, "HOST: " );    //Added space NK.
    strcat( TempBuf, SSDP_IP );
    sprintf( TempBuf, "%s:%d\r\n", TempBuf, Port );
    strcat( RqstBuf, TempBuf );

    strcat( RqstBuf, "MAN: \"ssdp:discover\"\r\n" );

    if( Mx > 0 ) {
        sprintf( TempBuf, "MX: %d\r\n", Mx );
        strcat( RqstBuf, TempBuf );
    }

    if( SearchTarget != NULL ) {
        sprintf( TempBuf, "ST: %s\r\n", SearchTarget );
        strcat( RqstBuf, TempBuf );
    }
    strcat( RqstBuf, "\r\n" );

}

/************************************************************************
* Function : searchExpired											
*																	
* Parameters:														
*		IN void * arg:
*
* Description:														
*	This function 
*
* Returns: void
*
***************************************************************************/
void
searchExpired( void *arg )
{

    int *id = ( int * )arg;
    int handle = -1;
    struct Handle_Info *ctrlpt_info = NULL;

    //remove search Target from list and call client back
    ListNode *node = NULL;
    SsdpSearchArg *item;
    Upnp_FunPtr ctrlpt_callback;
    void *cookie = NULL;
    int found = 0;

    HandleLock(  );

    //remove search target from search list

    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
        free( id );
        HandleUnlock(  );
        return;
    }

    ctrlpt_callback = ctrlpt_info->Callback;

    node = ListHead( &ctrlpt_info->SsdpSearchList );

    while( node != NULL ) {
        item = ( SsdpSearchArg * ) node->item;
        if( item->timeoutEventId == ( *id ) ) {
            free( item->searchTarget );
            cookie = item->cookie;
            found = 1;
            item->searchTarget = NULL;
            free( item );
            ListDelNode( &ctrlpt_info->SsdpSearchList, node, 0 );
            break;
        }
        node = ListNext( &ctrlpt_info->SsdpSearchList, node );
    }
    HandleUnlock(  );

    if( found ) {
        ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
    }

    free( id );
}

/************************************************************************
* Function : SearchByTarget											
*																	
* Parameters:														
*		IN int Mx:Number of seconds to wait, to collect all the 
*					responses.
*		char *St: Search target.
*		void *Cookie: cookie provided by control point application. This
*						cokie will be returned to application in the 
*						callback.
*
* Description:														
*	This function creates and send the search request for a specific URL.
*
* Returns: int
*	1 if successful else appropriate error
***************************************************************************/
int
SearchByTarget( IN int Mx,
                IN char *St,
                IN void *Cookie )
{
    int socklen = sizeof( struct sockaddr_in );
    int *id = NULL;
    char *ReqBuf;
    struct sockaddr_in destAddr;
    fd_set wrSet;
    SsdpSearchArg *newArg = NULL;
    int timeTillRead = 0;
    int handle;
    struct Handle_Info *ctrlpt_info = NULL;
    enum SsdpSearchType requestType;
    unsigned long addr = inet_addr( LOCAL_HOST );

    //ThreadData *ThData;
    ThreadPoolJob job;

    requestType = ssdp_request_type1( St );
    if( requestType == SSDP_SERROR ) {
        return UPNP_E_INVALID_PARAM;
    }

    ReqBuf = ( char * )malloc( BUFSIZE );
    if( ReqBuf == NULL )
        return UPNP_E_OUTOF_MEMORY;

    DBGONLY( UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
                         ">>> SSDP SEND >>>\n%s\n", ReqBuf );
         )

        timeTillRead = Mx;

    if( timeTillRead < MIN_SEARCH_TIME ) {
        timeTillRead = MIN_SEARCH_TIME;
    } else if( timeTillRead > MAX_SEARCH_TIME ) {
        timeTillRead = MAX_SEARCH_TIME;
    }

    CreateClientRequestPacket( ReqBuf, timeTillRead, St );
    memset( ( char * )&destAddr, 0, sizeof( struct sockaddr_in ) );

    destAddr.sin_family = AF_INET;
    destAddr.sin_addr.s_addr = inet_addr( SSDP_IP );
    destAddr.sin_port = htons( SSDP_PORT );

    FD_ZERO( &wrSet );
    FD_SET( gSsdpReqSocket, &wrSet );

    //add search criteria to list
    HandleLock(  );
    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        free( ReqBuf );
        return UPNP_E_INTERNAL_ERROR;
    }

    newArg = ( SsdpSearchArg * ) malloc( sizeof( SsdpSearchArg ) );
    newArg->searchTarget = strdup( St );
    newArg->cookie = Cookie;
    newArg->requestType = requestType;

    id = ( int * )malloc( sizeof( int ) );
    TPJobInit( &job, ( start_routine ) searchExpired, id );
    TPJobSetPriority( &job, MED_PRIORITY );
    TPJobSetFreeFunction( &job, ( free_routine ) free );

    //Schdule a timeout event to remove search Arg
    TimerThreadSchedule( &gTimerThread, timeTillRead,
                         REL_SEC, &job, SHORT_TERM, id );
    newArg->timeoutEventId = ( *id );

    ListAddTail( &ctrlpt_info->SsdpSearchList, newArg );
    HandleUnlock(  );

    setsockopt( gSsdpReqSocket, IPPROTO_IP, IP_MULTICAST_IF,
                ( char * )&addr, sizeof( addr ) );

    if( select( gSsdpReqSocket + 1, NULL, &wrSet, NULL, NULL )
        == UPNP_SOCKETERROR ) {
        DBGONLY( if( errno == EBADF ) {
                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
                             "SSDP_LIB :RequestHandler:An invalid file descriptor"
                             " was givenin one of the sets. \n" );}
                 else
                 if( errno == EINTR ) {
                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
                             "SSDP_LIB :RequestHandler:  A non blocked "
                             "signal was caught.    \n" );}
                 else
                 if( errno == EINVAL ) {
                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
                             "SSDP_LIB :RequestHandler: n is negative.  \n" );}
                 else
                 if( errno == ENOMEM ) {
                 UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,
                             "SSDP_LIB : RequestHandler:select was unable to "
                             "allocate memory for internal tables.\n" );}
        )
        shutdown( gSsdpReqSocket, SD_BOTH );
        UpnpCloseSocket( gSsdpReqSocket );
        free( ReqBuf );
        return UPNP_E_INTERNAL_ERROR;
    } else if( FD_ISSET( gSsdpReqSocket, &wrSet ) ) {
        int NumCopy = 0;

        while( NumCopy < NUM_SSDP_COPY ) {
            sendto( gSsdpReqSocket, ReqBuf, strlen( ReqBuf ), 0,
                    ( struct sockaddr * )&destAddr, socklen );
            NumCopy++;
            imillisleep( SSDP_PAUSE );
        }
    }

    free( ReqBuf );
    return 1;
}

#endif // EXCLUDE_SSDP
#endif // INCLUDE_CLIENT_APIS

⌨️ 快捷键说明

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