📄 ssdp_ctrlpt.c
字号:
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
*
***************************************************************************/
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 + -