예제 #1
0
/************************************************************************
* Function : ssdp_handle_device_request									
*																	
* Parameters:														
*		IN http_message_t* hmsg: SSDP search request from the control point
*		IN struct sockaddr_in* dest_addr: The address info of control point
*
* Description:														
*	This function handles the search request. It do the sanity checks of
*	the request and then schedules a thread to send a random time reply (
*	random within maximum time given by the control point to reply).
*
* Returns: void *
*	1 if successful else appropriate error
***************************************************************************/
void
ssdp_handle_device_request( IN http_message_t * hmsg,
                            IN struct sockaddr_in *dest_addr )
{
#define MX_FUDGE_FACTOR 10

    int handle;
    struct Handle_Info *dev_info = NULL;
    memptr hdr_value;
    int mx;
    char save_char;
    SsdpEvent event;
    int ret_code;
    SsdpSearchReply *threadArg = NULL;
    ThreadPoolJob job;
    int replyTime;
    int maxAge;

    // check man hdr
    if( httpmsg_find_hdr( hmsg, HDR_MAN, &hdr_value ) == NULL ||
        memptr_cmp( &hdr_value, "\"ssdp:discover\"" ) != 0 ) {
        return;                 // bad or missing hdr
    }
    // MX header
    if( httpmsg_find_hdr( hmsg, HDR_MX, &hdr_value ) == NULL ||
        ( mx = raw_to_int( &hdr_value, 10 ) ) < 0 ) {
        return;
    }
    // ST header
    if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) == NULL ) {
        return;
    }
    save_char = hdr_value.buf[hdr_value.length];
    hdr_value.buf[hdr_value.length] = '\0';
    ret_code = ssdp_request_type( hdr_value.buf, &event );
    hdr_value.buf[hdr_value.length] = save_char;    // restore
    if( ret_code == -1 ) {
        return;                 // bad ST header
    }

    HandleLock(  );
    // device info
    if( GetDeviceHandleInfo( &handle, &dev_info ) != HND_DEVICE ) {
        HandleUnlock(  );
        return;                 // no info found
    }
    maxAge = dev_info->MaxAge;
    HandleUnlock(  );

    DBGONLY( UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "ssdp_handle_device_request with Cmd %d SEARCH\n",
                         event.Cmd );
             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "MAX-AGE     =  %d\n", maxAge );
             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "MX     =  %d\n", event.Mx );
             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "DeviceType   =  %s\n", event.DeviceType );
             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "DeviceUuid   =  %s\n", event.UDN );
             UpnpPrintf( UPNP_PACKET, API, __FILE__, __LINE__,
                         "ServiceType =  %s\n", event.ServiceType ); )
예제 #2
0
void ssdp_handle_device_request(http_message_t *hmsg, struct sockaddr_storage *dest_addr)
{
#define MX_FUDGE_FACTOR 10
	int handle;
	struct Handle_Info *dev_info = NULL;
	memptr hdr_value;
	int mx;
	char save_char;
	SsdpEvent event;
	int ret_code;
	SsdpSearchReply *threadArg = NULL;
	ThreadPoolJob job;
	int replyTime;
	int maxAge;

	memset(&job, 0, sizeof(job));

	/* check man hdr. */
	if (httpmsg_find_hdr(hmsg, HDR_MAN, &hdr_value) == NULL ||
	    memptr_cmp(&hdr_value, "\"ssdp:discover\"") != 0)
		/* bad or missing hdr. */
		return;
	/* MX header. */
	if (httpmsg_find_hdr(hmsg, HDR_MX, &hdr_value) == NULL ||
	    (mx = raw_to_int(&hdr_value, 10)) < 0)
		return;
	/* ST header. */
	if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) == NULL)
		return;
	save_char = hdr_value.buf[hdr_value.length];
	hdr_value.buf[hdr_value.length] = '\0';
	ret_code = ssdp_request_type(hdr_value.buf, &event);
	/* restore. */
	hdr_value.buf[hdr_value.length] = save_char;
	if (ret_code == -1)
		/* bad ST header. */
		return;

	HandleLock();
	/* device info. */
	switch (GetDeviceHandleInfo((int)dest_addr->ss_family,
				&handle, &dev_info)) {
	case HND_DEVICE:
		break;
	default:
		HandleUnlock();
		/* no info found. */
		return;
	}
	maxAge = dev_info->MaxAge;
	HandleUnlock();

	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "MAX-AGE     =  %d\n", maxAge);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "MX     =  %d\n", event.Mx);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "DeviceType   =  %s\n", event.DeviceType);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "DeviceUuid   =  %s\n", event.UDN);
	UpnpPrintf(UPNP_PACKET, API, __FILE__, __LINE__,
		   "ServiceType =  %s\n", event.ServiceType);
	threadArg = (SsdpSearchReply *)malloc(sizeof(SsdpSearchReply));
	if (threadArg == NULL)
		return;
	threadArg->handle = handle;
	memcpy(&threadArg->dest_addr, dest_addr, sizeof(threadArg->dest_addr));
	threadArg->event = event;
	threadArg->MaxAge = maxAge;

	TPJobInit(&job, advertiseAndReplyThread, threadArg);
	TPJobSetFreeFunction(&job, (free_routine) free);

	/* Subtract a percentage from the mx to allow for network and processing
	 * delays (i.e. if search is for 30 seconds, respond
	 * within 0 - 27 seconds). */
	if (mx >= 2)
		mx -= MAXVAL(1, mx / MX_FUDGE_FACTOR);
	if (mx < 1)
		mx = 1;
	replyTime = rand() % mx;
	TimerThreadSchedule(&gTimerThread, replyTime, REL_SEC, &job,
			    SHORT_TERM, NULL);
}