📄 ssdp_ctrlpt.c
字号:
int m = min( hdr_value.length, strlen( searchArg->searchTarget ) ); matched = !( strncmp( searchArg->searchTarget, hdr_value.buf, m ) ); break; } default: { 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, ¶m, 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****************************************************************************/#ifndef WIN32#warning There are currently no uses of the function 'process_reply()' in the code.#warning 'process_reply()' is a candidate for removal.#else#pragma message("There are currently no uses of the function 'process_reply()' in the code.")#pragma message("'process_reply()' is a candidate for removal.")#endifstatic UPNP_INLINE voidprocess_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 voidCreateClientRequestPacket( IN char *RqstBuf, IN int Mx, IN char *SearchTarget ){ char TempBuf[COMMAND_LEN]; strcpy( RqstBuf, "M-SEARCH * HTTP/1.1\r\n" ); sprintf( TempBuf, "HOST: %s:%d\r\n", SSDP_IP, SSDP_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****************************************************************************/voidsearchExpired( 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.* IN char *St: Search target.* IN 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***************************************************************************/intSearchByTarget( IN int Mx, IN char *St, IN void *Cookie ){ char errorBuffer[ERROR_BUFFER_LEN]; int socklen = sizeof( struct sockaddr_in ); int *id = NULL; int ret = 0; 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; } UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__, ">>> SSDP SEND >>>\n"); 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 ); // Schedule 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(); ret = setsockopt( gSsdpReqSocket, IPPROTO_IP, IP_MULTICAST_IF, (char *)&addr, sizeof (addr) ); ret = select( gSsdpReqSocket + 1, NULL, &wrSet, NULL, NULL ); if( ret == -1 ) { strerror_r(errno, errorBuffer, ERROR_BUFFER_LEN); UpnpPrintf( UPNP_INFO, SSDP, __FILE__, __LINE__, "SSDP_LIB: Error in select(): %s\n", errorBuffer ); 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 + -