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

📄 ssdp_server.c

📁 原来由英特尔制定的UPnP SDK的
💻 C
📖 第 1 页 / 共 3 页
字号:
 *	which handles the ssdp request msg * * Returns: int *	0 if successful -1 if error ***************************************************************************/static UPNP_INLINE intstart_event_handler( void *Data ){    http_parser_t *parser = NULL;    parse_status_t status;    ssdp_thread_data *data = ( ssdp_thread_data * ) Data;    parser = &data->parser;    status = parser_parse( parser );    if( status == PARSE_FAILURE ) {        if( parser->msg.method != HTTPMETHOD_NOTIFY ||            !parser->valid_ssdp_notify_hack ) {            UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,                "SSDP recvd bad msg code = %d\n",                status );            // ignore bad msg, or not enuf mem            goto error_handler;        }        // valid notify msg    } else if( status != PARSE_SUCCESS ) {        UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,            "SSDP recvd bad msg code = %d\n", status );        goto error_handler;    }    // check msg    if( !valid_ssdp_msg( &parser->msg ) ) {        goto error_handler;    }    return 0;                   //////// done; thread will free 'data'  error_handler:    free_ssdp_event_handler_data( data );    return -1;}/************************************************************************ * Function : ssdp_event_handler_thread * * Parameters: *	IN void *the_data: ssdp_thread_data structure. This structure contains *			SSDP request message. * * Description: *	This function is a thread that handles SSDP requests. * * Returns: void * ***************************************************************************/static voidssdp_event_handler_thread( void *the_data ){    ssdp_thread_data *data = ( ssdp_thread_data * ) the_data;    http_message_t *hmsg = &data->parser.msg;    if( start_event_handler( the_data ) != 0 ) {        return;    }    // send msg to device or ctrlpt    if( ( hmsg->method == HTTPMETHOD_NOTIFY ) ||        ( hmsg->request_method == HTTPMETHOD_MSEARCH ) ) {        CLIENTONLY( ssdp_handle_ctrlpt_msg( hmsg, &data->dest_addr, FALSE, NULL );)    } else {        ssdp_handle_device_request( hmsg, &data->dest_addr );    }    // free data    free_ssdp_event_handler_data( data );}/************************************************************************ * Function : readFromSSDPSocket * * Parameters: *	IN SOCKET socket: SSDP socket * * Description: *	This function reads the data from the ssdp socket. * * Returns: void * ***************************************************************************/voidreadFromSSDPSocket( SOCKET socket ){    char *requestBuf = NULL;    char staticBuf[BUFSIZE];    struct sockaddr_in clientAddr;    ThreadPoolJob job;    ssdp_thread_data *data = NULL;    socklen_t socklen = 0;    int byteReceived = 0;    requestBuf = staticBuf;    //in case memory    //can't be allocated, still drain the     //socket using a static buffer    socklen = sizeof( struct sockaddr_in );    data = ( ssdp_thread_data * )        malloc( sizeof( ssdp_thread_data ) );    if( data != NULL ) {        //initialize parser#ifdef INCLUDE_CLIENT_APIS        if( socket == gSsdpReqSocket ) {            parser_response_init( &data->parser, HTTPMETHOD_MSEARCH );        } else {            parser_request_init( &data->parser );        }#else        parser_request_init( &data->parser );#endif        //set size of parser buffer        if( membuffer_set_size( &data->parser.msg.msg, BUFSIZE ) == 0 ) {            //use this as the buffer for recv            requestBuf = data->parser.msg.msg.buf;        } else {            free( data );            data = NULL;        }    }    byteReceived = recvfrom( socket, requestBuf,                             BUFSIZE - 1, 0,                             ( struct sockaddr * )&clientAddr, &socklen );    if( byteReceived > 0 ) {        requestBuf[byteReceived] = '\0';        UpnpPrintf( UPNP_INFO, SSDP,            __FILE__, __LINE__,            "Start of received response ----------------------------------------------------\n"            "%s\n"            "End of received response ------------------------------------------------------\n"            "From host %s\n",            requestBuf,            inet_ntoa( clientAddr.sin_addr ) );        UpnpPrintf( UPNP_PACKET, SSDP, __FILE__, __LINE__,            "Start of received multicast packet --------------------------------------------\n"            "%s\n"            "End of received multicast packet ----------------------------------------------\n",            requestBuf );        //add thread pool job to handle request        if( data != NULL ) {            data->parser.msg.msg.length += byteReceived;            // null-terminate            data->parser.msg.msg.buf[byteReceived] = 0;            data->dest_addr = clientAddr;            TPJobInit( &job, ( start_routine )                       ssdp_event_handler_thread, data );            TPJobSetFreeFunction( &job, free_ssdp_event_handler_data );            TPJobSetPriority( &job, MED_PRIORITY );            if( ThreadPoolAdd( &gRecvThreadPool, &job, NULL ) != 0 ) {                free_ssdp_event_handler_data( data );            }        }    } else {        free_ssdp_event_handler_data( data );    }}/************************************************************************ * Function : get_ssdp_sockets								 * * Parameters: *	OUT MiniServerSockArray *out: Arrays of SSDP sockets * * Description: *	This function creates the ssdp sockets. It set their option to listen *	for multicast traffic. * * Returns: int *	return UPNP_E_SUCCESS if successful else returns appropriate error ***************************************************************************/intget_ssdp_sockets( MiniServerSockArray * out ){    char errorBuffer[ERROR_BUFFER_LEN];    int onOff = 1;    u_char ttl = 4;    struct ip_mreq ssdpMcastAddr;    struct sockaddr_in ssdpAddr;    int option = 1;    int ret = 0;    struct in_addr addr;    SOCKET ssdpSock;#if INCLUDE_CLIENT_APIS    SOCKET ssdpReqSock;    ssdpReqSock = socket( AF_INET, SOCK_DGRAM, 0 );    if ( ssdpReqSock == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in socket(): %s\n", errorBuffer );            return UPNP_E_OUTOF_SOCKET;    }    ret = setsockopt( ssdpReqSock, IPPROTO_IP, IP_MULTICAST_TTL,        &ttl, sizeof (ttl) );    // just do it, regardless if fails or not.    Make_Socket_NoBlocking( ssdpReqSock );    gSsdpReqSocket = ssdpReqSock;#endif /* INCLUDE_CLIENT_APIS */    ssdpSock = socket( AF_INET, SOCK_DGRAM, 0 );    if ( ssdpSock == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in socket(): %s\n", errorBuffer );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        return UPNP_E_OUTOF_SOCKET;    }    onOff = 1;    ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEADDR,        (char *)&onOff, sizeof(onOff) );    if ( ret == -1) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in setsockopt() SO_REUSEADDR: %s\n", errorBuffer );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        shutdown( ssdpSock, SD_BOTH );        UpnpCloseSocket( ssdpSock );        return UPNP_E_SOCKET_ERROR;    }    #if defined(__FreeBSD__) || defined(__OSX__) || defined(__APPLE__)    ret = setsockopt( ssdpSock, SOL_SOCKET, SO_REUSEPORT,        (char *)&onOff, sizeof (onOff) );    if ( ret == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in setsockopt() SO_REUSEPORT: %s\n", errorBuffer );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        shutdown( ssdpSock, SD_BOTH );        UpnpCloseSocket( ssdpSock );        return UPNP_E_SOCKET_ERROR;    }#endif /* __FreeBSD__ */    memset( (void *)&ssdpAddr, 0, sizeof( struct sockaddr_in ) );    ssdpAddr.sin_family = AF_INET;    //  ssdpAddr.sin_addr.s_addr = inet_addr(LOCAL_HOST);    ssdpAddr.sin_addr.s_addr = htonl( INADDR_ANY );    ssdpAddr.sin_port = htons( SSDP_PORT );    ret = bind( ssdpSock, (struct sockaddr *)&ssdpAddr, sizeof (ssdpAddr) );    if ( ret == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in bind(), addr=0x%08X, port=%d: %s\n",            INADDR_ANY, SSDP_PORT, errorBuffer );            shutdown( ssdpSock, SD_BOTH );        UpnpCloseSocket( ssdpSock );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        return UPNP_E_SOCKET_BIND;    }    memset( (void *)&ssdpMcastAddr, 0, sizeof (struct ip_mreq) );    ssdpMcastAddr.imr_interface.s_addr = inet_addr( LOCAL_HOST );    ssdpMcastAddr.imr_multiaddr.s_addr = inet_addr( SSDP_IP );    ret = setsockopt( ssdpSock, IPPROTO_IP, IP_ADD_MEMBERSHIP,        (char *)&ssdpMcastAddr, sizeof (struct ip_mreq) );    if ( ret == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in setsockopt() IP_ADD_MEMBERSHIP (join multicast group): %s\n",            errorBuffer );        shutdown( ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        UpnpCloseSocket( ssdpSock );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        return UPNP_E_SOCKET_ERROR;    }    /* Set multicast interface. */    memset( (void *)&addr, 0, sizeof (struct in_addr) );    addr.s_addr = inet_addr(LOCAL_HOST);    ret = setsockopt(ssdpSock, IPPROTO_IP, IP_MULTICAST_IF,        (char *)&addr, sizeof addr);    if ( ret == -1 ) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__,            "Error in setsockopt() IP_MULTICAST_IF (set multicast interface): %s\n",            errorBuffer );        /* This is probably not a critical error, so let's continue. */    }    /* result is not checked becuase it will fail in WinMe and Win9x. */    ret = setsockopt( ssdpSock, IPPROTO_IP,        IP_MULTICAST_TTL, &ttl, sizeof (ttl) );    ret = setsockopt( ssdpSock, SOL_SOCKET, SO_BROADCAST,        (char *)&option, sizeof (option) );    if( ret == -1) {        strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN);        UpnpPrintf( UPNP_CRITICAL, SSDP, __FILE__, __LINE__,            "Error in setsockopt() SO_BROADCAST (set broadcast): %s\n",            errorBuffer );        shutdown( ssdpSock, SD_BOTH );        CLIENTONLY( shutdown( ssdpReqSock, SD_BOTH ); )        UpnpCloseSocket( ssdpSock );        CLIENTONLY( UpnpCloseSocket( ssdpReqSock ); )        return UPNP_E_NETWORK_ERROR;    }    CLIENTONLY( out->ssdpReqSock = ssdpReqSock; )    out->ssdpSock = ssdpSock;    return UPNP_E_SUCCESS;}#endif /* EXCLUDE_SSDP */

⌨️ 快捷键说明

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