void gena_process_subscription_renewal_request(
	SOCKINFO *info,
	http_message_t *request)
{
    Upnp_SID sid;
    subscription *sub;
    int time_out = 1801;
    service_info *service;
    struct Handle_Info *handle_info;
    UpnpDevice_Handle device_handle;
    memptr temp_hdr;
    membuffer event_url_path;
    memptr timeout_hdr;

    /* if a CALLBACK or NT header is present, then it is an error */
    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    /* get SID */
    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
        temp_hdr.length > SID_SIZE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }
    memcpy( sid, temp_hdr.buf, temp_hdr.length );
    sid[temp_hdr.length] = '\0';

    /* lookup service by eventURL */
    membuffer_init( &event_url_path );
    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
                          request->uri.pathquery.size ) != 0 ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    HandleLock();

    /* CURRENTLY, ONLY SUPPORT ONE DEVICE */
    if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
        &device_handle, &handle_info ) != HND_DEVICE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        membuffer_destroy( &event_url_path );
        HandleUnlock();
        return;
    }
    service = FindServiceEventURLPath( &handle_info->ServiceTable,
                                       event_url_path.buf );
    membuffer_destroy( &event_url_path );

    /* get subscription */
    if( service == NULL ||
        !service->active ||
        ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        HandleUnlock();
        return;
    }

    UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
        "Renew request: Number of subscriptions already: %d\n "
        "Max Subscriptions allowed:%d\n",
        service->TotalSubscriptions,
        handle_info->MaxSubscriptions );
    /* too many subscriptions */
    if( handle_info->MaxSubscriptions != -1 &&
            service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        RemoveSubscriptionSID( sub->sid, service );
        HandleUnlock();
        return;
    }
    /* set the timeout */
    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {

            /*nothing */

        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
                   0 ) {

            time_out = -1;      /* inifinite timeout */

        } else {
            time_out = DEFAULT_TIMEOUT; /* default is > 1800 seconds */

        }
    }

    /* replace infinite timeout with max timeout, if possible */
    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
        if( time_out == -1 ||
            time_out > handle_info->MaxSubscriptionTimeOut ) {
            time_out = handle_info->MaxSubscriptionTimeOut;
        }
    }

    if( time_out == -1 ) {
        sub->expireTime = 0;
    } else {
        sub->expireTime = time( NULL ) + time_out;
    }

    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
        RemoveSubscriptionSID( sub->sid, service );
    }

    HandleUnlock();
}
Exemple #2
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 ); )
void gena_process_subscription_request(
	SOCKINFO *info,
	http_message_t *request)
{
	UpnpSubscriptionRequest *request_struct = UpnpSubscriptionRequest_new();
	Upnp_SID temp_sid;
	int return_code = 1;
	int time_out = 1801;
	service_info *service;
	subscription *sub;
	uuid_upnp uid;
	struct Handle_Info *handle_info;
	void *cookie;
	Upnp_FunPtr callback_fun;
	UpnpDevice_Handle device_handle;
	memptr nt_hdr;
	char *event_url_path = NULL;
	memptr callback_hdr;
	memptr timeout_hdr;
	int rc = 0;

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"Subscription Request Received:\n");

	if (httpmsg_find_hdr(request, HDR_NT, &nt_hdr) == NULL) {
		error_respond(info, HTTP_BAD_REQUEST, request);
		goto exit_function;
	}

	/* check NT header */
	/* Windows Millenium Interoperability: */
	/* we accept either upnp:event, or upnp:propchange for the NT header */
	if (memptr_cmp_nocase(&nt_hdr, "upnp:event") != 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		goto exit_function;
	}

	/* if a SID is present then the we have a bad request "incompatible headers" */
	if (httpmsg_find_hdr(request, HDR_SID, NULL) != NULL) {
		error_respond(info, HTTP_BAD_REQUEST, request);
		goto exit_function;
	}
	/* look up service by eventURL */
	event_url_path = str_alloc(request->uri.pathquery.buff, request->uri.pathquery.size);
	if (event_url_path == NULL) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		goto exit_function;
	}

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"SubscriptionRequest for event URL path: %s\n",
		event_url_path);

	HandleLock();

	/* CURRENTLY, ONLY ONE DEVICE */
	if (GetDeviceHandleInfo(info->foreign_sockaddr.ss_family , 
	    &device_handle, &handle_info) != HND_DEVICE) {
		free(event_url_path);
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	service = FindServiceEventURLPath(&handle_info->ServiceTable, event_url_path);
	free(event_url_path);

	if (service == NULL || !service->active) {
		error_respond(info, HTTP_NOT_FOUND, request);
		HandleUnlock();
		goto exit_function;
	}

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"Subscription Request: Number of Subscriptions already %d\n "
		"Max Subscriptions allowed: %d\n",
		service->TotalSubscriptions,
		handle_info->MaxSubscriptions);

	/* too many subscriptions */
	if (handle_info->MaxSubscriptions != -1 &&
	    service->TotalSubscriptions >= handle_info->MaxSubscriptions) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	/* generate new subscription */
	sub = (subscription *)malloc(sizeof (subscription));
	if (sub == NULL) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	sub->eventKey = 0;
	sub->ToSendEventKey = 0;
	sub->active = 0;
	sub->next = NULL;
	sub->DeliveryURLs.size = 0;
	sub->DeliveryURLs.URLs = NULL;
	sub->DeliveryURLs.parsedURLs = NULL;

	/* check for valid callbacks */
	if (httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr) == NULL) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	return_code = create_url_list(&callback_hdr, &sub->DeliveryURLs);
	if (return_code == 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	if (return_code == UPNP_E_OUTOF_MEMORY) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	/* set the timeout */
	if (httpmsg_find_hdr(request, HDR_TIMEOUT, &timeout_hdr) != NULL) {
		if (matchstr(timeout_hdr.buf, timeout_hdr.length,
		    "%iSecond-%d%0", &time_out) == PARSE_OK) {
			/* nothing */
		} else if(memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
			/* infinite timeout */
			time_out = -1;
		} else {
			/* default is > 1800 seconds */
			time_out = DEFAULT_TIMEOUT;
		}
	}
	/* replace infinite timeout with max timeout, if possible */
	if (handle_info->MaxSubscriptionTimeOut != -1) {
		if (time_out == -1 ||
		    time_out > handle_info->MaxSubscriptionTimeOut) {
			time_out = handle_info->MaxSubscriptionTimeOut;
		}
	}
	if (time_out >= 0) {
		sub->expireTime = time(NULL) + time_out;
	} else {
		/* infinite time */
		sub->expireTime = 0;
	}

	/* generate SID */
	uuid_create(&uid);
	uuid_unpack(&uid, temp_sid);
	rc = snprintf(sub->sid, sizeof(sub->sid), "uuid:%s", temp_sid);

	/* respond OK */
	if (rc < 0 || (unsigned int) rc >= sizeof(sub->sid) ||
		(respond_ok(info, time_out,
		sub, request) != UPNP_E_SUCCESS)) {
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	/* add to subscription list */
	sub->next = service->subscriptionList;
	service->subscriptionList = sub;
	service->TotalSubscriptions++;

	/* finally generate callback for init table dump */
	UpnpSubscriptionRequest_strcpy_ServiceId(request_struct, service->serviceId);
	UpnpSubscriptionRequest_strcpy_UDN(request_struct, service->UDN);
	UpnpSubscriptionRequest_strcpy_SID(request_struct, sub->sid);

	/* copy callback */
	callback_fun = handle_info->Callback;
	cookie = handle_info->Cookie;

	HandleUnlock();

	/* make call back with request struct */
	/* in the future should find a way of mainting that the handle */
	/* is not unregistered in the middle of a callback */
	callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, request_struct, cookie);

exit_function:
	UpnpSubscriptionRequest_delete(request_struct);
}
Exemple #4
0
/************************************************************************
* Function : genaSubscribe
*																	
* Parameters:														
*	IN UpnpClient_Handle client_handle: 
*	IN char * PublisherURL: NULL Terminated, of the form : 
*						"http://134.134.156.80:4000/RedBulb/Event"
*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
*						in the OUT case: actual Duration granted 
*						by Service, -1 for infinite
*	OUT Upnp_SID out_sid:sid of subscription, memory passed in by caller
*
* Description:														
*	This function subscribes to a PublisherURL ( also mentioned as EventURL
*	some places). It sends SUBSCRIBE http request to service processes 
*	request. Finally adds a Subscription to 
*	the clients subscription list, if service responds with OK
*
* Returns: int
*	return UPNP_E_SUCCESS if service response is OK else 
*	returns appropriate error
***************************************************************************/
int
genaSubscribe( IN UpnpClient_Handle client_handle,
               IN char *PublisherURL,
               INOUT int *TimeOut,
               OUT Upnp_SID out_sid )
{
    int return_code = GENA_SUCCESS;
    client_subscription *newSubscription = NULL;
    uuid_upnp uid;
    Upnp_SID temp_sid;
    char *ActualSID = NULL;
    struct Handle_Info *handle_info;
    char *EventURL = NULL;

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "GENA SUBSCRIBE BEGIN" ) );
    HandleLock(  );

    memset( out_sid, 0, sizeof( Upnp_SID ) );

    // validate handle
    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        return GENA_E_BAD_HANDLE;
    }
    HandleUnlock(  );

    // subscribe
    SubscribeLock(  );
    return_code =
        gena_subscribe( PublisherURL, TimeOut, NULL, &ActualSID );
    HandleLock(  );
    if( return_code != UPNP_E_SUCCESS ) {
        DBGONLY( UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__,
                             "SUBSCRIBE FAILED in transfer error code: %d returned\n",
                             return_code ) );
        goto error_handler;
    }

    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
        return_code = GENA_E_BAD_HANDLE;
        goto error_handler;
    }
    // generate client SID
    uuid_create( &uid );
    uuid_unpack( &uid, temp_sid );
    sprintf( out_sid, "uuid:%s", temp_sid );

    // create event url
    EventURL = ( char * )malloc( strlen( PublisherURL ) + 1 );
    if( EventURL == NULL ) {
        return_code = UPNP_E_OUTOF_MEMORY;
        goto error_handler;
    }

    strcpy( EventURL, PublisherURL );

    // fill subscription
    newSubscription =
        ( client_subscription * ) malloc( sizeof( client_subscription ) );
    if( newSubscription == NULL ) {
        return_code = UPNP_E_OUTOF_MEMORY;
        goto error_handler;
    }
    newSubscription->EventURL = EventURL;
    newSubscription->ActualSID = ActualSID;
    strcpy( newSubscription->sid, out_sid );
    newSubscription->RenewEventId = -1;
    newSubscription->next = handle_info->ClientSubList;
    handle_info->ClientSubList = newSubscription;

    // schedule expiration event
    return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut,
                                         newSubscription );

  error_handler:
    if( return_code != UPNP_E_SUCCESS ) {
        free( ActualSID );
        free( EventURL );
        free( newSubscription );
    }
    HandleUnlock(  );
    SubscribeUnlock(  );
    return return_code;
}
Exemple #5
0
/************************************************************************
* 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 ) {
#ifdef _UPNP_MM_
        upnp_free( id );
#else
        free( id );
#endif
        HandleUnlock(  );
        return;
    }

    ctrlpt_callback = ctrlpt_info->Callback;

    node = ListHead( &ctrlpt_info->SsdpSearchList );

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

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

#ifdef _UPNP_MM_
    upnp_free( id );
#else
    free( id );
#endif
}
int genaInitNotifyExt(
	UpnpDevice_Handle device_handle,
	char *UDN,
	char *servId,
	IXML_Document *PropSet,
	const Upnp_SID sid)
{
	int ret = GENA_SUCCESS;
	int line = 0;

	int *reference_count = NULL;
	char *UDN_copy = NULL;
	char *servId_copy = NULL;
	DOMString propertySet = NULL;
	char *headers = NULL;
	notify_thread_struct *thread_struct = NULL;

	subscription *sub = NULL;
	service_info *service = NULL;
	struct Handle_Info *handle_info;
	ThreadPoolJob job;

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

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"GENA BEGIN INITIAL NOTIFY EXT");
	
	reference_count = (int *)malloc(sizeof (int));
	if (reference_count == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}
	*reference_count = 0;
	
	UDN_copy = (char *)malloc(strlen(UDN) + 1);
	if (UDN_copy == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	servId_copy = (char *)malloc(strlen(servId) + 1);
	if( servId_copy == NULL ) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	memset(UDN_copy, 0, strlen(UDN) + 1);
	strncpy(UDN_copy, UDN, strlen(UDN));
	memset(servId_copy, 0, strlen(servId) + 1);
	strncpy(servId_copy, servId, strlen(servId));

	HandleLock();

	if (GetHandleInfo(device_handle, &handle_info) != HND_DEVICE) {
		line = __LINE__;
		ret = GENA_E_BAD_HANDLE;
		goto ExitFunction;
	}

	service = FindServiceId(&handle_info->ServiceTable, servId, UDN);
	if (service == NULL) {
		line = __LINE__;
		ret = GENA_E_BAD_SERVICE;
		goto ExitFunction;
	}
	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"FOUND SERVICE IN INIT NOTFY EXT: UDN %s, ServID: %s",
		UDN, servId);

	sub = GetSubscriptionSID(sid, service);
	if (sub == NULL || sub->active) {
		line = __LINE__;
		ret = GENA_E_BAD_SID;
		goto ExitFunction;
	}
	UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
		"FOUND SUBSCRIPTION IN INIT NOTIFY EXT: SID %s", sid);
	sub->active = 1;

	if (PropSet == 0) {
		line = __LINE__;
		ret = GENA_SUCCESS;
		goto ExitFunction;
	}

	propertySet = ixmlPrintNode((IXML_Node *)PropSet);
	if (propertySet == NULL) {
		line = __LINE__;
		ret = UPNP_E_INVALID_PARAM;
		goto ExitFunction;
	}
	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"GENERATED PROPERTY SET IN INIT EXT NOTIFY: %s",
		propertySet);

	headers = AllocGenaHeaders(propertySet);
	if (headers == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	/* schedule thread for initial notification */

	thread_struct = (notify_thread_struct *)malloc(sizeof (notify_thread_struct));
	if (thread_struct == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
	} else {
		*reference_count = 1;
		thread_struct->servId = servId_copy;
		thread_struct->UDN = UDN_copy;
		thread_struct->headers = headers;
		thread_struct->propertySet = propertySet;
		memset(thread_struct->sid, 0, sizeof(thread_struct->sid));
		strncpy(thread_struct->sid, sid,
			sizeof(thread_struct->sid) - 1);
		thread_struct->eventKey = sub->eventKey++;
		thread_struct->reference_count = reference_count;
		thread_struct->device_handle = device_handle;

		TPJobInit(&job, (start_routine)genaNotifyThread, thread_struct);
		TPJobSetFreeFunction(&job, (free_routine)free_notify_struct);
		TPJobSetPriority(&job, MED_PRIORITY);

		ret = ThreadPoolAdd(&gSendThreadPool, &job, NULL);
		if (ret != 0) {
			if (ret == EOUTOFMEM) {
				line = __LINE__;
				ret = UPNP_E_OUTOF_MEMORY;
			}
		} else {
			line = __LINE__;
			ret = GENA_SUCCESS;
		}
	}

ExitFunction:
	if (ret != GENA_SUCCESS || PropSet == 0) {
		free(thread_struct);
		free(headers);
		ixmlFreeDOMString(propertySet);
		free(servId_copy);
		free(UDN_copy);
		free(reference_count);
	}

	HandleUnlock();

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, line,
		"GENA END INITIAL NOTIFY EXT, ret = %d",
		ret);

	return ret;
}
Exemple #7
0
int SearchByTarget(int Mx, char *St, void *Cookie)
{
	char errorBuffer[ERROR_BUFFER_LEN];
	int *id = NULL;
	int ret = 0;
	char ReqBufv4[BUFSIZE];
#ifdef UPNP_ENABLE_IPV6
	char ReqBufv6[BUFSIZE];
	char ReqBufv6UlaGua[BUFSIZE];
#endif
	struct sockaddr_storage __ss_v4;
#ifdef UPNP_ENABLE_IPV6
	struct sockaddr_storage __ss_v6;
#endif
	struct sockaddr_in *destAddr4 = (struct sockaddr_in *)&__ss_v4;
#ifdef UPNP_ENABLE_IPV6
	struct sockaddr_in6 *destAddr6 = (struct sockaddr_in6 *)&__ss_v6;
#endif
	fd_set wrSet;
	SsdpSearchArg *newArg = NULL;
	int timeTillRead = 0;
	int handle;
	struct Handle_Info *ctrlpt_info = NULL;
	enum SsdpSearchType requestType;
	unsigned long addrv4 = inet_addr(gIF_IPV4);
	SOCKET max_fd = 0;
	int retVal;

	/*ThreadData *ThData; */
	ThreadPoolJob job;

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

	requestType = ssdp_request_type1(St);
	if (requestType == SSDP_SERROR)
		return UPNP_E_INVALID_PARAM;
	UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
		   "Inside SearchByTarget\n");
	timeTillRead = Mx;
	if (timeTillRead < MIN_SEARCH_TIME)
		timeTillRead = MIN_SEARCH_TIME;
	else if (timeTillRead > MAX_SEARCH_TIME)
		timeTillRead = MAX_SEARCH_TIME;
	retVal = CreateClientRequestPacket(ReqBufv4, sizeof(ReqBufv4), timeTillRead, St, AF_INET);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
#ifdef UPNP_ENABLE_IPV6
	retVal = CreateClientRequestPacket(ReqBufv6, sizeof(ReqBufv6), timeTillRead, St, AF_INET6);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
	retVal = CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, sizeof(ReqBufv6UlaGua), timeTillRead, St, AF_INET6);
	if (retVal != UPNP_E_SUCCESS)
		return retVal;
#endif

	memset(&__ss_v4, 0, sizeof(__ss_v4));
	destAddr4->sin_family = (sa_family_t)AF_INET;
	inet_pton(AF_INET, SSDP_IP, &destAddr4->sin_addr);
	destAddr4->sin_port = htons(SSDP_PORT);

#ifdef UPNP_ENABLE_IPV6
	memset(&__ss_v6, 0, sizeof(__ss_v6));
	destAddr6->sin6_family = (sa_family_t)AF_INET6;
	inet_pton(AF_INET6, SSDP_IPV6_SITELOCAL, &destAddr6->sin6_addr);
	destAddr6->sin6_port = htons(SSDP_PORT);
	destAddr6->sin6_scope_id = gIF_INDEX;
#endif

	/* add search criteria to list */
	HandleLock();
	if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
		HandleUnlock();
		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();
	/* End of lock */

	FD_ZERO(&wrSet);
	if (gSsdpReqSocket4 != INVALID_SOCKET) {
		setsockopt(gSsdpReqSocket4, IPPROTO_IP, IP_MULTICAST_IF,
			   (char *)&addrv4, sizeof(addrv4));
		FD_SET(gSsdpReqSocket4, &wrSet);
		max_fd = max(max_fd, gSsdpReqSocket4);
	}
#ifdef UPNP_ENABLE_IPV6
	if (gSsdpReqSocket6 != INVALID_SOCKET) {
		setsockopt(gSsdpReqSocket6, IPPROTO_IPV6, IPV6_MULTICAST_IF,
			   (char *)&gIF_INDEX, sizeof(gIF_INDEX));
		FD_SET(gSsdpReqSocket6, &wrSet);
		max_fd = max(max_fd, gSsdpReqSocket6);
	}
#endif
	ret = select(max_fd + 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(gSsdpReqSocket4, SD_BOTH);
		UpnpCloseSocket(gSsdpReqSocket4);
#ifdef UPNP_ENABLE_IPV6
		shutdown(gSsdpReqSocket6, SD_BOTH);
		UpnpCloseSocket(gSsdpReqSocket6);
#endif
		return UPNP_E_INTERNAL_ERROR;
	}
#ifdef UPNP_ENABLE_IPV6
	if (gSsdpReqSocket6 != INVALID_SOCKET &&
	    FD_ISSET(gSsdpReqSocket6, &wrSet)) {
		int NumCopy = 0;

		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv6UlaGua);
			sendto(gSsdpReqSocket6,
			       ReqBufv6UlaGua, strlen(ReqBufv6UlaGua), 0,
			       (struct sockaddr *)&__ss_v6,
			       sizeof(struct sockaddr_in6));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
		NumCopy = 0;
		inet_pton(AF_INET6, SSDP_IPV6_LINKLOCAL, &destAddr6->sin6_addr);
		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv6);
			sendto(gSsdpReqSocket6,
			       ReqBufv6, strlen(ReqBufv6), 0,
			       (struct sockaddr *)&__ss_v6,
			       sizeof(struct sockaddr_in6));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
	}
#endif /* IPv6 */
	if (gSsdpReqSocket4 != INVALID_SOCKET &&
	    FD_ISSET(gSsdpReqSocket4, &wrSet)) {
		int NumCopy = 0;
		while (NumCopy < NUM_SSDP_COPY) {
			UpnpPrintf(UPNP_INFO, SSDP, __FILE__, __LINE__,
				   ">>> SSDP SEND M-SEARCH >>>\n%s\n",
				   ReqBufv4);
			sendto(gSsdpReqSocket4,
			       ReqBufv4, strlen(ReqBufv4), 0,
			       (struct sockaddr *)&__ss_v4,
			       sizeof(struct sockaddr_in));
			NumCopy++;
			imillisleep(SSDP_PAUSE);
		}
	}

	return 1;
}
Exemple #8
0
void PageDraw(HPAGE PageHandle,HWND Window,int DrawLeft,
              int DrawTop,int DrawRight,int DrawBottom)
{
  int SaveColor;
  struct viewporttype TmpViewPort;
  #ifdef __TURBOC__
    struct linesettingstype SaveLineStyle;
  #else
    unsigned short old_style;
  #endif

  ORDINATETYPE BoxDrawLeft,BoxDrawTop,BoxDrawRight,BoxDrawBottom;
  ORDINATETYPE BoxXY[2*MAXPOLYGONNUMBER];
  HBOX HBox;
  Pages *MidPage;
  int Left,Top,Right,Bottom;
  int PageLeft,PageTop,PageRight,PageBottom;

  WindowGetRect(Window,&Left,&Top,&Right,&Bottom);
  if (!RectangleIsInRectangle(DrawLeft,DrawTop,DrawRight,DrawBottom,
          Left,Top,Right,Bottom))
     return;

  if (DrawRight>=Right-Left)
     DrawRight=Right-Left-1;
  if (DrawBottom>=Bottom-Top)
     DrawBottom=Bottom-Top-1;
  if (DrawLeft<0)
     DrawLeft=0;
  if (DrawTop<0)
     DrawTop=0;
  BoxDrawLeft=WindowXToUserX(DrawLeft);
  BoxDrawTop=WindowYToUserY(DrawTop);
  BoxDrawRight=WindowXToUserX(DrawRight);
  BoxDrawBottom=WindowYToUserY(DrawBottom);

  MidPage=HandleLock(ItemGetHandle(PageHandle));
  if (MidPage==NULL)
     return;
  PageLeft=UserXToWindowX(0);
  PageTop=UserYToWindowY(0);
  PageRight=UserXToWindowX(PageGetPageWidth(MidPage));
  PageBottom=UserYToWindowY(PageGetPageHeight(MidPage));

  if(GlobalTextBlockStart<GlobalTextBlockEnd) // must clear now block
    DisplayBlock(GlobalBoxHeadHandle,GlobalTextBlockStart,GlobalTextBlockEnd);

  SaveColor=getcolor();
  MouseHidden();
  TextCursorOff();
  getviewsettings(&TmpViewPort);

  setviewport(Left,Top,Right,Bottom,1);

  /*---- clear page -----*/
  setfillstyle(1,EGA_WHITE);
  bar(DrawLeft,DrawTop,DrawRight,DrawBottom);
  /*--- draw page border ---*/
  setcolor(PAGEBORDERCOLOR);
  rectangle(PageLeft,PageTop,PageRight,PageBottom);

  if(!IsInGlobalBrowser())
       DrawPageFootHead(PageHandle,TRUE,TRUE);

  if(!fEditor)
  {
      #ifdef __TURBOC__
        getlinesettings(&SaveLineStyle);
        setlinestyle(4,0x5555,1);
      #else
        old_style=getlinestyle();
        setlinestyle(0xffff);
      #endif

      /*--- draw page shadow ---*/
      setcolor(EGA_DARKGRAY);
      line(((PageLeft>0)?PageLeft:0)+3,PageBottom+1,PageRight+3,PageBottom+1);
      line(((PageLeft>0)?PageLeft:0)+3,PageBottom+2,PageRight+3,PageBottom+2);
      line(((PageLeft>0)?PageLeft:0)+3,PageBottom+3,PageRight+3,PageBottom+3);
      line(PageRight+1,((PageTop>0)?PageTop:0)+3,PageRight+1,PageBottom+3);
      line(PageRight+2,((PageTop>0)?PageTop:0)+3,PageRight+2,PageBottom+3);
      line(PageRight+3,((PageTop>0)?PageTop:0)+3,PageRight+3,PageBottom+3);

      /*--- draw box align line ---*/
      setcolor(EGA_LIGHTBLUE);
     /*------------  use 0x5555 --
      #ifdef __TURBOC__
        setlinestyle(4,0x5f5f,1);
      #else
        setlinestyle(0x5f5f);
      #endif
     ----------------*/
      setlinestyle(0x8888);
      PageLeft=UserXToWindowX(PageGetMarginLeft(MidPage))-1;
      PageTop=UserYToWindowY(PageGetMarginTop(MidPage))-1;
      PageRight=UserXToWindowX(PageGetPageWidth(MidPage)-
                               PageGetMarginRight(MidPage))+1;
      PageBottom=UserYToWindowY(PageGetPageHeight(MidPage)-
                                PageGetMarginBottom(MidPage))+1;
      line(UserXToWindowX(0),PageTop,
           UserXToWindowX(PageGetPageWidth(MidPage)),PageTop);
      line(UserXToWindowX(0),PageBottom,
           UserXToWindowX(PageGetPageWidth(MidPage)),PageBottom);
      line(PageLeft,UserYToWindowY(0),PageLeft,
           UserYToWindowY(PageGetPageHeight(MidPage)));
      line(PageRight,UserYToWindowY(0),PageRight,
           UserYToWindowY(PageGetPageHeight(MidPage)));

      #ifdef __TURBOC__
        setlinestyle(SaveLineStyle.linestyle,SaveLineStyle.upattern,
                     SaveLineStyle.thickness);
      #else
        setlinestyle(old_style);
      #endif
  }

  HandleUnlock(ItemGetHandle(PageHandle));

  setcolor(EGA_BLACK);

  HBox=PageGetBoxHead(PageHandle);
  while (HBox)
  {
    ORDINATETYPE BoxLeft,BoxTop,BoxRight,BoxBottom;
    TextBoxs *MidBox;
    int BoxDots;

    MidBox=HandleLock(ItemGetHandle(HBox));
    if (MidBox==NULL)
       break;
    BoxGetPolygonDrawBorder((Boxs *)MidBox,&BoxDots,BoxXY);
    PolygonGetMinRectangle(BoxDots,BoxXY,&BoxLeft,&BoxTop,&BoxRight,&BoxBottom);
    if (RectangleIsInRectangle(BoxDrawLeft,BoxDrawTop,BoxDrawRight,BoxDrawBottom,
         BoxLeft,BoxTop,BoxRight,BoxBottom)||TextBoxGetBoxType(MidBox)==TEXTBOX)
    {
       HBOX LinkBox;

       BoxDraw(HBox,
               (HBox==GlobalBoxHeadHandle)?DRAWBORDERWITHRECATNGLE:
               DRAWVIRTUALBORDOR);

       if (TextBoxGetBoxType(MidBox)==TEXTBOX &&
           (GlobalBoxTool==IDX_UNLINK||GlobalBoxTool==IDX_LINK) &&
           (LinkBox=TextBoxGetPrevLinkBox(MidBox))!=0 )
       {
          ORDINATETYPE Left2,Top2,Right2,Bottom2;

          BoxGetRect(HBox,&BoxLeft,&BoxTop,&BoxRight,&BoxBottom);
          BoxXY[0]=BoxLeft;     BoxXY[1]=BoxTop;
          BoxPolygonRotate(1,BoxXY,(PictureBoxs *)MidBox);
          BoxPolygonToWindowXY(1,BoxXY);
          BoxLeft=BoxXY[0];     BoxTop=BoxXY[1];

          if(ItemGetFather(LinkBox)==PageHandle)
          {
              BoxGetRect(LinkBox,&Left2,&Top2,&Right2,&Bottom2);
              BoxXY[0]=Right2;  BoxXY[1]=Bottom2;
              BoxPolygonRotate(1,BoxXY,HandleLock(ItemGetHandle(LinkBox)));
              HandleUnlock(ItemGetHandle(LinkBox));
              BoxPolygonToWindowXY(1,BoxXY);
          }
          else
          {
              BoxXY[0]=getmaxx();  BoxXY[1]=0;    // screen (Right,Top)
          }

          line(BoxLeft,BoxTop,BoxXY[0],BoxXY[1]);
       }
    }
    HandleUnlock(ItemGetHandle(HBox));
    HBox=ItemGetNext(HBox);
  }

  if (GlobalGroupGetSign())
     GroupDrawAllBorder(DRAWXORBORDER);
  setviewport(TmpViewPort.left,TmpViewPort.top,TmpViewPort.right,
              TmpViewPort.bottom,TmpViewPort.clip);
  setcolor(SaveColor);
  MouseShow();
  return;
}
Exemple #9
0
void DrawPageFootHead(HPAGE PageHandle,BOOL fDrawFoot,BOOL fDrawHead)
{
  Pages *MidPage;
  int   i,k,PageNum,x,y,PgFtWid,PgHdWid;
  Wchar code;
  int   width;
  int  fString=NO_NUM;
  BOOL fBothAtMid=FALSE;
  char str[PAGEHEADSTRMAXLEN+20],headstr[PAGEHEADSTRMAXLEN];

  MidPage=HandleLock(ItemGetHandle(PageHandle));
  PageNum=PageHandleToNumber(PageHandle)+PgFtStartNum;


  if(PrintingSign)
     width=UserXToWindowX(146);
  else
     width=myUserXToWindowX(146);      // /GlobalPageScale;      /* use 5' size */

  if(GetPageHeadOption()&&GetPageFootOption()&&GetPageFootTopOption()==FOOTTOP)
  {
     if((PageNum&1)==0)        // page_head_string may be at left
     {
       if((GetPageFootLeftOption()==FOOTLEFT||GetPageFootLeftOption()==FOOTLEFT_RIGHT)
       && (GetPageHeadLeftOption()==FOOTLEFT||GetPageHeadLeftOption()==FOOTLEFT_RIGHT) )
          fString=AFTER_NUM;    //- put it after PageNum string
       else
       if(GetPageFootLeftOption()==GetPageHeadLeftOption()) // middle, right
       {
          if(GetPageFootLeftOption()==FOOTMID)
             fBothAtMid=TRUE;
          fString=PREV_NUM;    //- put it prev to PageNum string
       }
     }
     else                      // page_head_string may be at right
     {
       if((GetPageFootLeftOption()==FOOTRIGHT||GetPageFootLeftOption()==FOOTLEFT_RIGHT)
       && (GetPageHeadLeftOption()==FOOTRIGHT||GetPageHeadLeftOption()==FOOTLEFT_RIGHT) )
          fString=PREV_NUM;    //- put it prev to PageNum string
       else
       if(GetPageFootLeftOption()==GetPageHeadLeftOption())
         if(GetPageFootLeftOption()==FOOTLEFT)
            fString=AFTER_NUM;    //- left, put it after PageNum string
         else
         {
            fString=PREV_NUM;    //-  middle, put it prev to PageNum string
            fBothAtMid=TRUE;
         }
     }
  }

  /*--- draw page foot (page number) ---*/
  if(GetPageFootOption() && (fDrawFoot || fString) )
  {
     // calculate page foot string's length
     itoa(PageNum,str,10);
      //-- insert prev<sp>, <sp>suff to str --
     switch(GetPageFootPrevOption())
     {
         case DOT_PREV:
              code='.';
              goto calu_prev;
         case LINE_PREV:
              code='-';
           calu_prev:
              i=strlen(str);
              memmove(str+2,str,i);
              str[0]=str[i+3]=code;
              str[1]=str[i+2]=BLANK;
              str[i+4]=0;
              break;
     }  /* end of switch */

     if(fBothAtMid)             //  ... <PageHeadStr><sp><sp><PageNum> ...
     {     // strcat(headstr,str), then build str.
         if((PageNum&1)!=0)        // page_head_string at right
             strcpy(headstr,PageHeadRightStr);
         else
             strcpy(headstr,PageHeadLeftStr);

         i=strlen(headstr);
         memmove(str+i+2,str,i);
         memmove(str,headstr,i);
         str[i+1]=str[i]=BLANK;
         fDrawFoot=TRUE;
     }
     PgFtWid=(float)CalcStrLen(str)*width/CHAR_WIDTH_IN_DOT+0.5;

     //--- calculate Y value ---
     if(GetPageFootTopOption()==FOOTTOP)
         y=UserYToWindowY(PageGetMarginTop(MidPage))-width;
     else
         y=UserYToWindowY(PageGetPageHeight(MidPage)
                         -PageGetMarginBottom(MidPage))+width*3/2;

     //--- calculate X value ---
     switch(GetPageFootLeftOption())
     {
         case FOOTLEFT:
              x=UserXToWindowX(PageGetMarginLeft(MidPage))+width;
              break;
         case FOOTRIGHT:
              PgFtWid+=width;
              x=UserXToWindowX(PageGetPageWidth(MidPage)
                            -PageGetMarginRight(MidPage))
                   -PgFtWid;
              break;
         case FOOTLEFT_RIGHT:
              if( (PageNum&1)==0)     // odd, put PageNum at left
                  x=UserXToWindowX(PageGetMarginLeft(MidPage))+width;
              else              // even, put it at right
              {
                  PgFtWid+=width;
                  x=UserXToWindowX(PageGetPageWidth(MidPage)
                                -PageGetMarginRight(MidPage))
                    -PgFtWid;
              }
              break;
         case FOOTMID:
              x=UserXToWindowX(PageGetPageWidth(MidPage)
                            -PageGetMarginRight(MidPage))
                   -PgFtWid;
              x+=UserXToWindowX(PageGetMarginLeft(MidPage));
              x/=2;
              break;
     }  /* end of switch */

     /*----- now, draw page foot string ------*/
     if(fDrawFoot)
         BuildStr(x,y,str,width);

     if(fBothAtMid)
         goto lbl_draw_page_head_line;

     x+=PgFtWid;
  }  /*-- page foot --*/

  /*--- draw page head string ----*/
  if(GetPageHeadOption() && fDrawHead)
  {
     if((PageNum&1)!=0)
         strcpy(str,PageHeadRightStr);
     else
         strcpy(str,PageHeadLeftStr);

     PgHdWid=(float)CalcStrLen(str)*width/CHAR_WIDTH_IN_DOT+0.5;

     if(fString==AFTER_NUM)
         x+=width*3/2;          // use last_modified_X, add some SPACE
     else
     switch(GetPageHeadLeftOption())
     {
       case FOOTLEFT:
       lbl_head_left:
            x=UserXToWindowX(PageGetMarginLeft(MidPage));
            break;
       case FOOTMID:
            x=UserXToWindowX(PageGetPageWidth(MidPage)
                          -PageGetMarginRight(MidPage))
                 -PgHdWid;
            x+=UserXToWindowX(PageGetMarginLeft(MidPage));
            x/=2;
            break;
       case FOOTRIGHT:
       lbl_head_right:
            x=UserXToWindowX(PageGetPageWidth(MidPage)
                          -PageGetMarginRight(MidPage))
                  - PgHdWid;

            if(fString==PREV_NUM)       // page num is at right also
                x-=PgFtWid+width*3/2;     // add some SPACE
            break;
       case FOOTLEFT_RIGHT:
            if((PageNum&1)!=0)        // page_head_string at right
               goto lbl_head_right;
            else
               goto lbl_head_left;
     } /*- end of switch -*/

     y=UserYToWindowY(PageGetMarginTop(MidPage))-width;
     BuildStr(x,y,str,width);

     // if page head string is not NULL, draw a line
     if(str[0]&&GetPageHeadLineOption())
     {
   lbl_draw_page_head_line:
         x=UserXToWindowX(PageGetMarginLeft(MidPage));
         i=UserXToWindowX(PageGetPageWidth(MidPage)
                           -PageGetMarginRight(MidPage));
         y+=width/4;
         if(PrintingSign)
         {
             printer->printScanLine(x,i,y,&SysDc);
             printer->printScanLine(x,i,y+1,&SysDc);
         }
         else
         {
             setcolor(EGA_BLACK);
             line(x,y,i,y);
         }

         if(GetPageHeadLineOption()==HEADLINE_DOUBLE)
         {
             y+=width/6;
             for(k=0;k<width/6;k++)
                 if(PrintingSign)
                     printer->printScanLine(x,i,y+k,&SysDc);
                 else
                 {
                     line(x,y+k,i,y+k);
                 }
         }
     } /*--- page head line ---*/
  } /*-- if pagehead --*/

  HandleUnlock(ItemGetHandle(PageHandle));
}
void gena_process_notification_event(
	SOCKINFO *info,
	http_message_t *event)
{
	struct Upnp_Event event_struct;
	IXML_Document *ChangedVars = NULL;
	int eventKey;
	token sid;
	ClientSubscription *subscription = NULL;
	struct Handle_Info *handle_info;
	void *cookie;
	Upnp_FunPtr callback;
	UpnpClient_Handle client_handle;
	const UpnpString *tmpSID = NULL;

	memptr sid_hdr;
	memptr nt_hdr,
	nts_hdr;
	memptr seq_hdr;

	/* get SID */
	if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}
	sid.buff = sid_hdr.buf;
	sid.size = sid_hdr.length;

	/* get event key */
	if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL ||
	    matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* get NT and NTS headers */
	if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL ||
	    httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* verify NT and NTS headers */
	if (memptr_cmp(&nt_hdr, "upnp:event") != 0 ||
	    memptr_cmp(&nts_hdr, "upnp:propchange") != 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}

	/* parse the content (should be XML) */
	if (!has_xml_content_type(event) ||
	    event->msg.length == 0 ||
	    ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) {
		error_respond(info, HTTP_BAD_REQUEST, event);
		goto exit_function;
	}

	HandleLock();

	/* get client info */
	if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		HandleUnlock();
		goto exit_function;
	}

	/* get subscription based on SID */
	subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
	if (subscription == NULL) {
		if (eventKey == 0) {
			/* wait until we've finished processing a subscription  */
			/*   (if we are in the middle) */
			/* this is to avoid mistakenly rejecting the first event if we  */
			/*   receive it before the subscription response */
			HandleUnlock();

			/* try and get Subscription Lock  */
			/*   (in case we are in the process of subscribing) */
			SubscribeLock();

			/* get HandleLock again */
			HandleLock();

			if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
				error_respond(info, HTTP_PRECONDITION_FAILED, event);
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
			if (subscription == NULL) {
				error_respond( info, HTTP_PRECONDITION_FAILED, event );
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			SubscribeUnlock();
		} else {
			error_respond( info, HTTP_PRECONDITION_FAILED, event );
			HandleUnlock();
			goto exit_function;
		}
	}

	/* success */
	error_respond(info, HTTP_OK, event);

	/* fill event struct */
	tmpSID = UpnpClientSubscription_get_SID(subscription);
	memset(event_struct.Sid, 0, sizeof(event_struct.Sid));
	strncpy(event_struct.Sid, UpnpString_get_String(tmpSID),
		sizeof(event_struct.Sid) - 1);
	event_struct.EventKey = eventKey;
	event_struct.ChangedVariables = ChangedVars;

	/* copy callback */
	callback = handle_info->Callback;
	cookie = handle_info->Cookie;

	HandleUnlock();

	/* make callback with event struct */
	/* In future, should find a way of mainting */
	/* that the handle is not unregistered in the middle of a */
	/* callback */
	callback(UPNP_EVENT_RECEIVED, &event_struct, cookie);

exit_function:
	ixmlDocument_free(ChangedVars);
}
Exemple #11
0
HPAGE PageNew(Pages *NewPage,int PageNumber)
{
  Items NewPageHandle;
  HITEM MidPageItem,MidItem,MidBoxItem;
  Pages *MidPage;
//  TextBoxs NewBox;            // ByHance
#define NewBox        (TmpBuf.TextBox)

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

  if (PageNumber>0)
     MidPageItem=PageNumberToHandle(PageNumber-1);
  else
     MidPageItem=0;

  if (!(MidPageItem=ItemInsert(&NewPageHandle,GlobalPageHeadHandle,MidPageItem)))
     return(0);

  if (!PageNumber)
  {
     if (!(MidItem=HandleAlloc(sizeof(Pages),0)))
        return(0);
     if ((MidPage=(Pages *)HandleLock(MidItem))==NULL)
     {
        HandleFree(MidItem);
        return(0);
     }
     memcpy(MidPage,NewPage,sizeof(Pages));
     HandleUnlock(MidItem);
     ItemSetHandle(MidPageItem,MidItem);
  }
  else
     ItemSetHandle(MidPageItem,ItemGetHandle(PageNumberToHandle(0)));

  if (PageHaveInitialBox(*NewPage))
  {
     HBOX NewHBox;
     int CursorX,CursorY;
     TextBoxs *BoxPointer;

     DefaultNewBox(NewPage,&NewBox);
     NewBox.BoxStatus|=4;               // TextBoxSetDependPage()
     MidBoxItem=TextBoxInsert(&NewBox,MidPageItem);
     if (!MidBoxItem)
        return(OUTOFMEMORY);

     if (TotalPage==0)
     {
        GlobalBoxHeadHandle=MidBoxItem;
        GlobalTextPosition=0;
        TextBoxSeekTextPosition(GlobalBoxHeadHandle,0,1,&GlobalTextPosition);
        TextBoxSeekTextPosition(GlobalBoxHeadHandle,GlobalTextPosition,-1,&GlobalTextPosition);
        CursorLocate(GlobalBoxHeadHandle,&NewHBox,GlobalTextPosition,&CursorX,&CursorY);
     }
     // BoxPointer=HandleLock(ItemGetHandle(GlobalBoxHeadHandle));
     BoxPointer=HandleLock(ItemGetHandle(MidBoxItem));   // ByHance, 95,12.5
     if (BoxPointer)
          BoxSetLocked(BoxPointer);
     HandleUnlock(ItemGetHandle(MidBoxItem));
     // HandleUnlock(ItemGetHandle(GlobalBoxHeadHandle));

     /* else
     {
        TextBoxs *TextBox;

        GlobalBoxHeadHandle=MidBoxItem;
        TextBox=HandleLock(ItemGetHandle(GlobalBoxHeadHandle));
        if (TextBox!=NULL)
        {
           InitRL(TextBox);
           HandleUnlock(ItemGetHandle(GlobalBoxHeadHandle));
        }
     } */
  }
  else
     if (TotalPage==0)
        GlobalBoxHeadHandle=0;
  TotalPage++;
  FileSetModified();
  return(MidPageItem);

#undef NewBox           // ByHance
}
int genaRenewSubscription(
	UpnpClient_Handle client_handle,
	const UpnpString *in_sid,
	int *TimeOut)
{
	int return_code = GENA_SUCCESS;
	ClientSubscription *sub = NULL;
	ClientSubscription *sub_copy = UpnpClientSubscription_new();
	struct Handle_Info *handle_info;
	UpnpString *ActualSID = UpnpString_new();
	ThreadPoolJob tempJob;

	HandleLock();

	/* validate handle and sid */
	if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
		HandleUnlock();

		return_code = GENA_E_BAD_HANDLE;
		goto exit_function;
	}

	sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid);
	if (sub == NULL) {
		HandleUnlock();

		return_code = GENA_E_BAD_SID;
		goto exit_function;
	}

	/* remove old events */
	if (TimerThreadRemove(
		&gTimerThread,
		UpnpClientSubscription_get_RenewEventId(sub),
		&tempJob) == 0 ) {
		free_upnp_timeout((upnp_timeout *)tempJob.arg);
	}

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "REMOVED AUTO RENEW  EVENT");

	UpnpClientSubscription_set_RenewEventId(sub, -1);
	UpnpClientSubscription_assign(sub_copy, sub);

	HandleUnlock();

	return_code = gena_subscribe(
		UpnpClientSubscription_get_EventURL(sub_copy),
		TimeOut,
		UpnpClientSubscription_get_ActualSID(sub_copy),
		ActualSID);

	HandleLock();

	if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
		HandleUnlock();
		return_code = GENA_E_BAD_HANDLE;
		goto exit_function;
	}

	/* we just called GetHandleInfo, so we don't check for return value */
	/*GetHandleInfo(client_handle, &handle_info); */
	if (return_code != UPNP_E_SUCCESS) {
		/* network failure (remove client sub) */
		RemoveClientSubClientSID(&handle_info->ClientSubList, in_sid);
		free_client_subscription(sub_copy);
		HandleUnlock();
		goto exit_function;
	}

	/* get subscription */
	sub = GetClientSubClientSID(handle_info->ClientSubList, in_sid);
	if (sub == NULL) {
		free_client_subscription(sub_copy);
		HandleUnlock();
		return_code = GENA_E_BAD_SID;
		goto exit_function;
	}

	/* store actual sid */
	UpnpClientSubscription_set_ActualSID(sub, ActualSID);

	/* start renew subscription timer */
	return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, sub);
	if (return_code != GENA_SUCCESS) {
		RemoveClientSubClientSID(
			&handle_info->ClientSubList,
			UpnpClientSubscription_get_SID(sub));
	}
	free_client_subscription(sub_copy);
	HandleUnlock();

exit_function:
	UpnpString_delete(ActualSID);
	UpnpClientSubscription_delete(sub_copy);
	return return_code;
}
int genaSubscribe(
	UpnpClient_Handle client_handle,
	const UpnpString *PublisherURL,
	int *TimeOut,
	UpnpString *out_sid)
{
	int return_code = GENA_SUCCESS;
	ClientSubscription *newSubscription = UpnpClientSubscription_new();
	uuid_upnp uid;
	Upnp_SID temp_sid;
	Upnp_SID temp_sid2;
	UpnpString *ActualSID = UpnpString_new();
	UpnpString *EventURL = UpnpString_new();
	struct Handle_Info *handle_info;
	int rc = 0;

	memset(temp_sid, 0, sizeof(temp_sid));
	memset(temp_sid2, 0, sizeof(temp_sid2));

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__, "GENA SUBSCRIBE BEGIN");

	UpnpString_clear(out_sid);

	HandleReadLock();
	/* validate handle */
	if (GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
		return_code = GENA_E_BAD_HANDLE;
		SubscribeLock();
		goto error_handler;
	}
	HandleUnlock();

	/* subscribe */
	SubscribeLock();
	return_code = gena_subscribe(PublisherURL, TimeOut, NULL, ActualSID);
	HandleLock();
	if (return_code != UPNP_E_SUCCESS) {
		UpnpPrintf( UPNP_CRITICAL, GENA, __FILE__, __LINE__,
			"SUBSCRIBE FAILED in transfer error code: %d returned\n",
			return_code );
		goto error_handler;
	}

	if(GetHandleInfo(client_handle, &handle_info) != HND_CLIENT) {
		return_code = GENA_E_BAD_HANDLE;
		goto error_handler;
	}

	/* generate client SID */
	uuid_create(&uid );
	uuid_unpack(&uid, temp_sid);
	rc = snprintf(temp_sid2, sizeof(temp_sid2), "uuid:%s", temp_sid);
	if (rc < 0 || (unsigned int) rc >= sizeof(temp_sid2)) {
		return_code = UPNP_E_OUTOF_MEMORY;
		goto error_handler;
	}
	UpnpString_set_String(out_sid, temp_sid2);

	/* create event url */
	UpnpString_assign(EventURL, PublisherURL);

	/* fill subscription */
	if (newSubscription == NULL) {
		return_code = UPNP_E_OUTOF_MEMORY;
		goto error_handler;
	}
	UpnpClientSubscription_set_RenewEventId(newSubscription, -1);
	UpnpClientSubscription_set_SID(newSubscription, out_sid);
	UpnpClientSubscription_set_ActualSID(newSubscription, ActualSID);
	UpnpClientSubscription_set_EventURL(newSubscription, EventURL);
	UpnpClientSubscription_set_Next(newSubscription, handle_info->ClientSubList);
	handle_info->ClientSubList = newSubscription;

	/* schedule expiration event */
	return_code = ScheduleGenaAutoRenew(client_handle, *TimeOut, newSubscription);

error_handler:
		UpnpString_delete(ActualSID);
		UpnpString_delete(EventURL);
	if (return_code != UPNP_E_SUCCESS)
		UpnpClientSubscription_delete(newSubscription);
	HandleUnlock();
	SubscribeUnlock();

	return return_code;
}
Exemple #14
0
/****************************************************************************
*	Function :	get_device_info
*
*	Parameters :
*		IN http_message_t* request :	HTTP request
*		IN int isQuery :	flag for a querry
*		IN IXML_Document *actionDoc :	action request document
*		OUT char device_udn[LINE_SIZE] :	Device UDN string
*		OUT char service_id[LINE_SIZE] :	Service ID string
*		OUT Upnp_FunPtr *callback :	callback function of the device
*									application
*		OUT void** cookie :	cookie stored by device application
*
*	Description :	This function retrives all the information needed to
*		process the incoming SOAP request. It finds the device and service info
*		and also the callback function to hand-over the request to the device
*		application.
*
*	Return : int
*		UPNP_E_SUCCESS if successful else returns appropriate error
*
*	Note :
****************************************************************************/
static int
get_device_info( IN http_message_t * request,
                 IN int isQuery,
                 IN IXML_Document * actionDoc,
                 OUT char device_udn[LINE_SIZE],
                 OUT char service_id[LINE_SIZE],
                 OUT Upnp_FunPtr * callback,
                 OUT void **cookie )
{
    struct Handle_Info *device_info;
    int device_hnd;
    service_info *serv_info;
    char save_char;
    int ret_code = -1;          // error by default
    const char *control_url;
    char *actionName = NULL;

    // null-terminate pathquery of url
    control_url = request->uri.pathquery.buff;
    save_char = control_url[request->uri.pathquery.size];
    ((char *)control_url)[request->uri.pathquery.size] = '\0';

    HandleLock();

    if( GetDeviceHandleInfo( &device_hnd, &device_info ) != HND_DEVICE ) {
        goto error_handler;
    }

    if( ( serv_info =
                FindServiceControlURLPath( &device_info->ServiceTable,
                                           control_url ) ) == NULL ) {
        goto error_handler;
    }

    if( isQuery ) {
        ret_code = check_soap_action_header( request, QUERY_STATE_VAR_URN,
                                             &actionName );
        if( ( ret_code != UPNP_E_SUCCESS )
                && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
            ret_code = UPNP_E_INVALID_ACTION;
            goto error_handler;
        }
        //check soap body
        ret_code =
            check_soap_body( actionDoc, QUERY_STATE_VAR_URN, actionName );
        free( actionName );
        if( ret_code != UPNP_E_SUCCESS ) {
            goto error_handler;
        }
    } else {
        ret_code = check_soap_action_header( request,
                                             serv_info->serviceType,
                                             &actionName );
        if( ( ret_code != UPNP_E_SUCCESS )
                && ( ret_code != UPNP_E_OUTOF_MEMORY ) ) {
            ret_code = UPNP_E_INVALID_SERVICE;
            goto error_handler;
        }
        //check soap body
        ret_code =
            check_soap_body( actionDoc, serv_info->serviceType,
                             actionName );
        free( actionName );
        if( ret_code != UPNP_E_SUCCESS ) {
            ret_code = UPNP_E_INVALID_SERVICE;
            goto error_handler;
        }
    }

    namecopy( service_id, serv_info->serviceId );
    namecopy( device_udn, serv_info->UDN );
    *callback = device_info->Callback;
    *cookie = device_info->Cookie;

    ret_code = 0;

error_handler:
    ((char *)control_url)[request->uri.pathquery.size] = save_char;   // restore
    HandleUnlock();
    return ret_code;
}
void gena_process_unsubscribe_request(
	SOCKINFO *info,
	http_message_t *request)
{
    Upnp_SID sid;
    service_info *service;
    struct Handle_Info *handle_info;
    UpnpDevice_Handle device_handle;

    memptr temp_hdr;
    membuffer event_url_path;

    /* if a CALLBACK or NT header is present, then it is an error */
    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    /* get SID */
    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
        temp_hdr.length > SID_SIZE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }
    memcpy( sid, temp_hdr.buf, temp_hdr.length );
    sid[temp_hdr.length] = '\0';

    /* lookup service by eventURL */
    membuffer_init( &event_url_path );
    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
                          request->uri.pathquery.size ) != 0 ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    HandleLock();

    /* CURRENTLY, ONLY SUPPORT ONE DEVICE */
    if( GetDeviceHandleInfo( info->foreign_sockaddr.ss_family,
        &device_handle, &handle_info ) != HND_DEVICE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        membuffer_destroy( &event_url_path );
        HandleUnlock();
        return;
    }
    service = FindServiceEventURLPath( &handle_info->ServiceTable,
                                       event_url_path.buf );
    membuffer_destroy( &event_url_path );

    /* validate service */
    if( service == NULL ||
        !service->active || GetSubscriptionSID( sid, service ) == NULL )
    {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        HandleUnlock();
        return;
    }

    RemoveSubscriptionSID(sid, service);
    error_respond(info, HTTP_OK, request);    /* success */

    HandleUnlock();
}
Exemple #16
0
/************************************************************************
* Function : gena_process_notification_event
*																	
* Parameters:														
*	IN SOCKINFO *info: Socket structure containing the device socket 
*					information
*	IN http_message_t* event: The http message contains the GENA 
*								notification
*
* Description:														
*	This function processes NOTIFY events that are sent by devices. 
*	called by genacallback()
*
* Returns: void
*
* Note : called by genacallback()
****************************************************************************/
void
gena_process_notification_event( IN SOCKINFO * info,
                                 IN http_message_t * event )
{
    struct Upnp_Event event_struct;
    int eventKey;
    token sid;
    client_subscription *subscription;
    IXML_Document *ChangedVars;
    struct Handle_Info *handle_info;
    void *cookie;
    Upnp_FunPtr callback;
    UpnpClient_Handle client_handle;

    memptr sid_hdr;
    memptr nt_hdr,
      nts_hdr;
    memptr seq_hdr;

    // get SID
    if( httpmsg_find_hdr( event, HDR_SID, &sid_hdr ) == NULL ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    sid.buff = sid_hdr.buf;
    sid.size = sid_hdr.length;

    // get event key
    if( httpmsg_find_hdr( event, HDR_SEQ, &seq_hdr ) == NULL ||
        matchstr( seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey )
        != PARSE_OK ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // get NT and NTS headers
    if( httpmsg_find_hdr( event, HDR_NT, &nt_hdr ) == NULL ||
        httpmsg_find_hdr( event, HDR_NTS, &nts_hdr ) == NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // verify NT and NTS headers
    if( memptr_cmp( &nt_hdr, "upnp:event" ) != 0 ||
        memptr_cmp( &nts_hdr, "upnp:propchange" ) != 0 ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    // parse the content (should be XML)
    if( !has_xml_content_type( event ) ||
        event->msg.length == 0 ||
        ( ixmlParseBufferEx( event->entity.buf, &ChangedVars ) ) !=
        IXML_SUCCESS ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }

    HandleLock(  );

    // get client info
    if( GetClientHandleInfo( &client_handle, &handle_info ) != HND_CLIENT ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );
        HandleUnlock(  );
        ixmlDocument_free( ChangedVars );

        return;
    }
    // get subscription based on SID
    if( ( subscription = GetClientSubActualSID( handle_info->ClientSubList,
                                                &sid ) ) == NULL ) {
        if( eventKey == 0 ) {
            // wait until we've finished processing a subscription 
            //   (if we are in the middle)
            // this is to avoid mistakenly rejecting the first event if we 
            //   receive it before the subscription response
            HandleUnlock(  );

            // try and get Subscription Lock 
            //   (in case we are in the process of subscribing)
            SubscribeLock(  );

            // get HandleLock again
            HandleLock(  );

            if( GetClientHandleInfo( &client_handle, &handle_info )
                != HND_CLIENT ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            if( ( subscription =
                  GetClientSubActualSID( handle_info->ClientSubList,
                                         &sid ) ) == NULL ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            SubscribeUnlock(  );
        } else {
            error_respond( info, HTTP_PRECONDITION_FAILED, event );
            HandleUnlock(  );
            ixmlDocument_free( ChangedVars );

            return;
        }
    }

    error_respond( info, HTTP_OK, event );  // success

    // fill event struct
    strcpy( event_struct.Sid, subscription->sid );
    event_struct.EventKey = eventKey;
    event_struct.ChangedVariables = ChangedVars;

    // copy callback
    callback = handle_info->Callback;
    cookie = handle_info->Cookie;

    HandleUnlock(  );

    // make callback with event struct
    // In future, should find a way of mainting
    // that the handle is not unregistered in the middle of a
    // callback
    callback( UPNP_EVENT_RECEIVED, &event_struct, cookie );

    ixmlDocument_free( ChangedVars );
}
/*!
 * \brief Thread job to Notify a control point.
 *
 * It validates the subscription and copies the subscription. Also make sure
 * that events are sent in order.
 *
 * \note calls the genaNotify to do the actual work.
 */
static void genaNotifyThread(
	/*! [in] notify thread structure containing all the headers and property set info. */
	void *input)
{
	subscription *sub;
	service_info *service;
	subscription sub_copy;
	notify_thread_struct *in = (notify_thread_struct *) input;
	int return_code;
	struct Handle_Info *handle_info;
	ThreadPoolJob job;

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

	/* This should be a HandleLock and not a HandleReadLock otherwise if there
	 * is a lot of notifications, then multiple threads will acquire a read
	 * lock and the thread which sends the notification will be blocked forever
	 * on the HandleLock at the end of this function. */
	/*HandleReadLock(); */
	HandleLock();
	/* validate context */

	if (GetHandleInfo(in->device_handle, &handle_info) != HND_DEVICE) {
		free_notify_struct(in);
		HandleUnlock();
		return;
	}

	if (!(service = FindServiceId(&handle_info->ServiceTable, in->servId, in->UDN)) ||
	    !service->active ||
	    !(sub = GetSubscriptionSID(in->sid, service)) ||
	    copy_subscription(sub, &sub_copy) != HTTP_SUCCESS) {
		free_notify_struct(in);
		HandleUnlock();
		return;
	}
#ifdef UPNP_ENABLE_NOTIFICATION_REORDERING
	/*If the event is out of order push it back to the job queue */
	if (in->eventKey != sub->ToSendEventKey) {
		TPJobInit(&job, (start_routine) genaNotifyThread, input);
		TPJobSetFreeFunction(&job, (free_function) free_notify_struct);
		TPJobSetPriority(&job, MED_PRIORITY);
		/* Sleep a little before creating another thread otherwise if there is
		 * a lot of notifications to send, the device will take 100% of the CPU
		 * to create threads and push them back to the job queue. */
		imillisleep(1);
		ThreadPoolAdd(&gSendThreadPool, &job, NULL);
		freeSubscription(&sub_copy);
		HandleUnlock();
		return;
	}
#endif

	HandleUnlock();

	/* send the notify */
	return_code = genaNotify(in->headers, in->propertySet, &sub_copy);
	freeSubscription(&sub_copy);
	HandleLock();
	if (GetHandleInfo(in->device_handle, &handle_info) != HND_DEVICE) {
		free_notify_struct(in);
		HandleUnlock();
		return;
	}
	/* validate context */
	if (!(service = FindServiceId(&handle_info->ServiceTable, in->servId, in->UDN)) ||
	    !service->active ||
	    !(sub = GetSubscriptionSID(in->sid, service))) {
		free_notify_struct(in);
		HandleUnlock();
		return;
	}
	sub->ToSendEventKey++;
	if (sub->ToSendEventKey < 0)
		/* wrap to 1 for overflow */
		sub->ToSendEventKey = 1;
	if (return_code == GENA_E_NOTIFY_UNACCEPTED_REMOVE_SUB)
		RemoveSubscriptionSID(in->sid, service);
	free_notify_struct(in);

	HandleUnlock();
}
Exemple #18
0
/*!
 * \brief Retrives all the information needed to process the incoming SOAP
 * request. It finds the device and service info and also the callback
 * function to hand-over the request to the device application.
 *
 * \return UPNP_E_SUCCESS if successful else returns appropriate error.
 */
static int get_device_info(
    int iface,
	/*! [in] HTTP request. */
	http_message_t *request,
	/*! [in] flag for a querry. */
	int isQuery,
	/*! [in] Action request document. */
	IXML_Document *actionDoc,
	/*! [in] . */
	int AddressFamily,
	/*! [out] Device UDN string. */
	OUT char device_udn[LINE_SIZE],
	/*! [out] Service ID string. */
	char service_id[LINE_SIZE],
	/*! [out] callback function of the device application. */
	Upnp_FunPtr *callback,
	/*! [out] cookie stored by device application. */
	void **cookie)
{
	struct Handle_Info *device_info;
	int device_hnd;
	service_info *serv_info;
	char save_char;
	/* error by default */
	int ret_code = -1;
	const char *control_url;
	char *actionName = NULL;

	/* null-terminate pathquery of url */
	control_url = request->uri.pathquery.buff;
	save_char = control_url[request->uri.pathquery.size];
	((char *)control_url)[request->uri.pathquery.size] = '\0';

	HandleLock();

	if (GetDeviceHandleInfo(iface, AddressFamily, &device_hnd,
				&device_info) != HND_DEVICE)
		goto error_handler;
	serv_info = FindServiceControlURLPath(
		&device_info->ServiceTable, control_url);
	if (!serv_info)
		goto error_handler;
	if (isQuery) {
		ret_code = check_soap_action_header(request,
			QUERY_STATE_VAR_URN, &actionName);
		if (ret_code != UPNP_E_SUCCESS &&
		    ret_code != UPNP_E_OUTOF_MEMORY) {
			ret_code = UPNP_E_INVALID_ACTION;
			goto error_handler;
		}
		/* check soap body */
		ret_code = check_soap_body(actionDoc, QUERY_STATE_VAR_URN,
			actionName);
		free(actionName);
		if (ret_code != UPNP_E_SUCCESS)
			goto error_handler;
	} else {
		ret_code = check_soap_action_header(request,
			serv_info->serviceType, &actionName);
		if (ret_code != UPNP_E_SUCCESS &&
		    ret_code != UPNP_E_OUTOF_MEMORY) {
			ret_code = UPNP_E_INVALID_SERVICE;
			goto error_handler;
		}
		/* check soap body */
		ret_code = check_soap_body(actionDoc, serv_info->serviceType,
			actionName);
		free(actionName);
		if (ret_code != UPNP_E_SUCCESS) {
			ret_code = UPNP_E_INVALID_SERVICE;
			goto error_handler;
		}
	}
	namecopy(service_id, serv_info->serviceId);
	namecopy(device_udn, serv_info->UDN);
	*callback = device_info->Callback;
	*cookie = device_info->Cookie;
	ret_code = 0;

 error_handler:
	/* restore */
	((char *)control_url)[request->uri.pathquery.size] = save_char;
	HandleUnlock();
	return ret_code;
}
int genaNotifyAll(
	UpnpDevice_Handle device_handle,
	char *UDN,
	char *servId,
	char **VarNames,
	char **VarValues,
	int var_count)
{
	int ret = GENA_SUCCESS;
	int line = 0;

	int *reference_count = NULL;
	char *UDN_copy = NULL;
	char *servId_copy = NULL;
	DOMString propertySet = NULL;
	char *headers = NULL;
	notify_thread_struct *thread_struct = NULL;

	subscription *finger = NULL;
	service_info *service = NULL;
	struct Handle_Info *handle_info;
	ThreadPoolJob job;

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

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"GENA BEGIN NOTIFY ALL");

	reference_count = (int *)malloc(sizeof (int));
	if (reference_count == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}
	*reference_count = 0;
	
	UDN_copy = (char *)malloc(strlen(UDN) + 1);
	if (UDN_copy == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	servId_copy = (char *)malloc(strlen(servId) + 1);
	if( servId_copy == NULL ) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	memset(UDN_copy, 0, strlen(UDN) + 1);
	strncpy(UDN_copy, UDN, strlen(UDN));
	memset(servId_copy, 0, strlen(servId) + 1);
	strncpy(servId_copy, servId, strlen(servId));

	ret = GeneratePropertySet(VarNames, VarValues, var_count, &propertySet);
	if (ret != XML_SUCCESS) {
		line = __LINE__;
		goto ExitFunction;
	}
	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"GENERATED PROPERTY SET IN EXT NOTIFY: %s",
		propertySet);

	headers = AllocGenaHeaders(propertySet);
	if (headers == NULL) {
		line = __LINE__;
		ret = UPNP_E_OUTOF_MEMORY;
		goto ExitFunction;
	}

	HandleLock();

	if (GetHandleInfo(device_handle, &handle_info) != HND_DEVICE) {
		line = __LINE__;
		ret = GENA_E_BAD_HANDLE;
	} else {
		service = FindServiceId(&handle_info->ServiceTable, servId, UDN);
		if (service != NULL) {
			finger = GetFirstSubscription(service);
			while (finger) {
				thread_struct = (notify_thread_struct *)malloc(sizeof (notify_thread_struct));
				if (thread_struct == NULL) {
					line = __LINE__;
					ret = UPNP_E_OUTOF_MEMORY;
					break;
				}

				(*reference_count)++;
				thread_struct->reference_count = reference_count;
				thread_struct->UDN = UDN_copy;
				thread_struct->servId = servId_copy;
				thread_struct->headers = headers;
				thread_struct->propertySet = propertySet;
				memset(thread_struct->sid, 0,
					sizeof(thread_struct->sid));
				strncpy(thread_struct->sid, finger->sid,
					sizeof(thread_struct->sid) - 1);
				thread_struct->eventKey = finger->eventKey++;
				thread_struct->device_handle = device_handle;
				/* if overflow, wrap to 1 */
				if (finger->eventKey < 0) {
					finger->eventKey = 1;
				}


				TPJobInit(&job, (start_routine)genaNotifyThread, thread_struct);
				TPJobSetFreeFunction(&job, (free_routine)free_notify_struct);
				TPJobSetPriority(&job, MED_PRIORITY);
				ret = ThreadPoolAdd(&gSendThreadPool, &job, NULL);
				if (ret != 0) {
					line = __LINE__;
					if (ret == EOUTOFMEM) {
						line = __LINE__;
						ret = UPNP_E_OUTOF_MEMORY;
					}
					break;
				}

				finger = GetNextSubscription(service, finger);
			}
		} else {
			line = __LINE__;
			ret = GENA_E_BAD_SERVICE;
		}
	}

ExitFunction:
	if (ret != GENA_SUCCESS || *reference_count == 0) {
		free(headers);
		ixmlFreeDOMString(propertySet);
		free(servId_copy);
		free(UDN_copy);
		free(reference_count);
	}

	HandleUnlock();

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, line,
		"GENA END NOTIFY ALL, ret = %d",
		ret);

	return ret;
}
Exemple #20
0
/************************************************************************
* Function : ssdp_handle_ctrlpt_msg											
*																	
* Parameters:														
*	IN http_message_t* hmsg: SSDP message from the device
*	IN struct sockaddr_in* dest_addr: Address of the device
*	IN xboolean timeout: timeout kept by the control point while sending 
*						search message
*	IN void* cookie: Cookie stored by the control point application. 
*					This cookie will be returned to the control point
*					in the callback 
*																	
* Description:														
*	This function handles the ssdp messages from the devices. These 
*	messages includes the search replies, advertisement of device coming 
*	alive and bye byes.
*
* Returns: void
*
***************************************************************************/
void
ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
                        IN struct sockaddr_in *dest_addr,
                        IN xboolean timeout,    // only in search reply

                        IN void *cookie )   // only in search reply
{
    int handle;
    struct Handle_Info *ctrlpt_info = NULL;
    memptr hdr_value;
    xboolean is_byebye;         // byebye or alive
    struct Upnp_Discovery param;
    SsdpEvent event;
    xboolean nt_found,
      usn_found,
      st_found;
    char save_char;
    Upnp_EventType event_type;
    Upnp_FunPtr ctrlpt_callback;
    void *ctrlpt_cookie;
    ListNode *node = NULL;
    SsdpSearchArg *searchArg = NULL;
    int matched = 0;
    ResultData *threadData;
    ThreadPoolJob job;

    // we are assuming that there can be only one client supported at a time

    HandleLock(  );

    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        return;
    }
    // copy
    ctrlpt_callback = ctrlpt_info->Callback;
    ctrlpt_cookie = ctrlpt_info->Cookie;
    HandleUnlock(  );

    // search timeout
    if( timeout ) {
        ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
        return;
    }

    param.ErrCode = UPNP_E_SUCCESS;

    // MAX-AGE
    param.Expires = -1;         // assume error
    if( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) {
        matchstr( hdr_value.buf, hdr_value.length,
                  "%imax-age = %d%0", &param.Expires );
    }

    // DATE
    param.Date[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) {
        linecopylen( param.Date, hdr_value.buf, hdr_value.length );
    }

    // dest addr
    param.DestAddr = dest_addr;

    // EXT
    param.Ext[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) {
        linecopylen( param.Ext, hdr_value.buf, hdr_value.length );
    }
    // LOCATION
    param.Location[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) {
        linecopylen( param.Location, hdr_value.buf, hdr_value.length );
    }
    // SERVER / USER-AGENT
    param.Os[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL ||
        httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) {
        linecopylen( param.Os, hdr_value.buf, hdr_value.length );
    }
    // clear everything
    param.DeviceId[0] = '\0';
    param.DeviceType[0] = '\0';
    param.ServiceType[0] = '\0';

    param.ServiceVer[0] = '\0'; // not used; version is in ServiceType

    event.UDN[0] = '\0';
    event.DeviceType[0] = '\0';
    event.ServiceType[0] = '\0';

    nt_found = FALSE;

    if( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
        save_char = hdr_value.buf[hdr_value.length];
        hdr_value.buf[hdr_value.length] = '\0';

        nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );

        hdr_value.buf[hdr_value.length] = save_char;
    }

    usn_found = FALSE;
    if( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
        save_char = hdr_value.buf[hdr_value.length];
        hdr_value.buf[hdr_value.length] = '\0';

        usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );

        hdr_value.buf[hdr_value.length] = save_char;
    }

    if( nt_found || usn_found ) {
        strcpy( param.DeviceId, event.UDN );
        strcpy( param.DeviceType, event.DeviceType );
        strcpy( param.ServiceType, event.ServiceType );
    }

    // ADVERT. OR BYEBYE
    if( hmsg->is_request ) {
        // use NTS hdr to determine advert., or byebye
        //
        if( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
            return;             // error; NTS header not found
        }
        if( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
            is_byebye = FALSE;
        } else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
            is_byebye = TRUE;
        } else {
            return;             // bad value
        }

        if( is_byebye ) {
            // check device byebye
            if( !nt_found || !usn_found ) {
                return;         // bad byebye
            }
            event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
        } else {
            // check advertisement      
            // .Expires is valid if positive. This is for testing
            //  only. Expires should be greater than 1800 (30 mins)
            if( !nt_found ||
                !usn_found ||
                strlen( param.Location ) == 0 || param.Expires <= 0 ) {
                return;         // bad advertisement
            }

            event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
        }

        // call callback
        ctrlpt_callback( event_type, &param, ctrlpt_cookie );

    } else                      // reply (to a SEARCH)
    {
        // only checking to see if there is a valid ST header
        st_found = FALSE;
        if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) {
            save_char = hdr_value.buf[hdr_value.length];
            hdr_value.buf[hdr_value.length] = '\0';
            st_found = ssdp_request_type( hdr_value.buf, &event ) == 0;
            hdr_value.buf[hdr_value.length] = save_char;
        }
        if( hmsg->status_code != HTTP_OK ||
            param.Expires <= 0 ||
            strlen( param.Location ) == 0 || !usn_found || !st_found ) {
            return;             // bad reply
        }
        //check each current search
        HandleLock(  );
        if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
            HandleUnlock(  );
            return;
        }
        node = ListHead( &ctrlpt_info->SsdpSearchList );

        //temporary add null termination
        //save_char = hdr_value.buf[ hdr_value.length ];
        //hdr_value.buf[ hdr_value.length ] = '\0';

        while( node != NULL ) {
            searchArg = node->item;
            matched = 0;
            //check for match of ST header and search target
            switch ( searchArg->requestType ) {
                case SSDP_ALL:
                    {
                        matched = 1;
                        break;
                    }
                case SSDP_ROOTDEVICE:
                    {
                        matched = ( event.RequestType == SSDP_ROOTDEVICE );
                        break;
                    }
                case SSDP_DEVICEUDN:
                    {
                        matched = !( strncmp( searchArg->searchTarget,
                                              hdr_value.buf,
                                              hdr_value.length ) );
                        break;
                    }
                case SSDP_DEVICETYPE:
                    {
                        int m = min( hdr_value.length,
                                     strlen( searchArg->searchTarget ) );

                        matched = !( strncmp( searchArg->searchTarget,
                                              hdr_value.buf, m ) );
                        break;
                    }
                case SSDP_SERVICE:
                    {
                        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, &param, cookie );
    }
}
Exemple #21
0
void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr_storage *dest_addr,
			    int timeout, void *cookie)
{
	int handle;
	struct Handle_Info *ctrlpt_info = NULL;
	memptr hdr_value;
	/* byebye or alive */
	int is_byebye;
	UpnpDiscovery *param = UpnpDiscovery_new();
	int expires;
	int ret;
	SsdpEvent event;
	int nt_found;
	int usn_found;
	int st_found;
	char save_char;
	Upnp_EventType event_type;
	Upnp_FunPtr ctrlpt_callback;
	void *ctrlpt_cookie;
	ListNode *node = NULL;
	SsdpSearchArg *searchArg = NULL;
	int matched = 0;
	SSDPResultData *threadData = NULL;
	ThreadPoolJob job;

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

	/* we are assuming that there can be only one client supported at a time */
	HandleReadLock();

	if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
		HandleUnlock();
		goto end_ssdp_handle_ctrlpt_msg;
	}
	/* copy */
	ctrlpt_callback = ctrlpt_info->Callback;
	ctrlpt_cookie = ctrlpt_info->Cookie;
	HandleUnlock();
	/* search timeout */
	if (timeout) {
		ctrlpt_callback(UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie);
		goto end_ssdp_handle_ctrlpt_msg;
	}

	UpnpDiscovery_set_ErrCode(param, UPNP_E_SUCCESS);
	/* MAX-AGE, assume error */
	expires = -1;
	UpnpDiscovery_set_Expires(param, expires);
	if (httpmsg_find_hdr(hmsg, HDR_CACHE_CONTROL, &hdr_value) != NULL) {
		ret = matchstr(hdr_value.buf, hdr_value.length,
			"%imax-age = %d%0", &expires);
		UpnpDiscovery_set_Expires(param, expires);
		if (ret != PARSE_OK)
			goto end_ssdp_handle_ctrlpt_msg;
	}
	/* DATE */
	if (httpmsg_find_hdr(hmsg, HDR_DATE, &hdr_value) != NULL) {
		UpnpDiscovery_strcpy_Date(param, hdr_value.buf);
	}
	/* dest addr */
	UpnpDiscovery_set_DestAddr(param, dest_addr);
	/* EXT */
	if (httpmsg_find_hdr(hmsg, HDR_EXT, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Ext(param, hdr_value.buf,
					  hdr_value.length);
	}
	/* LOCATION */
	if (httpmsg_find_hdr(hmsg, HDR_LOCATION, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Location(param, hdr_value.buf,
					       hdr_value.length);
	}
	/* SERVER / USER-AGENT */
	if (httpmsg_find_hdr(hmsg, HDR_SERVER, &hdr_value) != NULL ||
	    httpmsg_find_hdr(hmsg, HDR_USER_AGENT, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Os(param, hdr_value.buf,
					 hdr_value.length);
	}
	/* clear everything */
	event.UDN[0] = '\0';
	event.DeviceType[0] = '\0';
	event.ServiceType[0] = '\0';
	nt_found = FALSE;
	if (httpmsg_find_hdr(hmsg, HDR_NT, &hdr_value) != NULL) {
		save_char = hdr_value.buf[hdr_value.length];
		hdr_value.buf[hdr_value.length] = '\0';
		nt_found = (ssdp_request_type(hdr_value.buf, &event) == 0);
		hdr_value.buf[hdr_value.length] = save_char;
	}
	usn_found = FALSE;
	if (httpmsg_find_hdr(hmsg, HDR_USN, &hdr_value) != NULL) {
		save_char = hdr_value.buf[hdr_value.length];
		hdr_value.buf[hdr_value.length] = '\0';
		usn_found = (unique_service_name(hdr_value.buf, &event) == 0);
		hdr_value.buf[hdr_value.length] = save_char;
	}
	if (nt_found || usn_found) {
		UpnpDiscovery_strcpy_DeviceID(param, event.UDN);
		UpnpDiscovery_strcpy_DeviceType(param, event.DeviceType);
		UpnpDiscovery_strcpy_ServiceType(param, event.ServiceType);
	}
	/* ADVERT. OR BYEBYE */
	if (hmsg->is_request) {
		/* use NTS hdr to determine advert., or byebye */
		if (httpmsg_find_hdr(hmsg, HDR_NTS, &hdr_value) == NULL) {
			/* error; NTS header not found */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		if (memptr_cmp(&hdr_value, "ssdp:alive") == 0) {
			is_byebye = FALSE;
		} else if (memptr_cmp(&hdr_value, "ssdp:byebye") == 0) {
			is_byebye = TRUE;
		} else {
			/* bad value */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		if (is_byebye) {
			/* check device byebye */
			if (!nt_found || !usn_found) {
				/* bad byebye */
				goto end_ssdp_handle_ctrlpt_msg;
			}
			event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
		} else {
			/* check advertisement.
			 * Expires is valid if positive. This is for testing
			 * only. Expires should be greater than 1800 (30 mins) */
			if (!nt_found ||
			    !usn_found ||
			    UpnpString_get_Length(UpnpDiscovery_get_Location(param)) == 0 ||
			    UpnpDiscovery_get_Expires(param) <= 0) {
				/* bad advertisement */
				goto end_ssdp_handle_ctrlpt_msg;
			}
			event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
		}
		/* call callback */
		ctrlpt_callback(event_type, param, ctrlpt_cookie);
	} else {
		/* reply (to a SEARCH) */
		/* only checking to see if there is a valid ST header */
		st_found = FALSE;
		if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) != NULL) {
			save_char = hdr_value.buf[hdr_value.length];
			hdr_value.buf[hdr_value.length] = '\0';
			st_found =
			    ssdp_request_type(hdr_value.buf, &event) == 0;
			hdr_value.buf[hdr_value.length] = save_char;
		}
		if (hmsg->status_code != HTTP_OK ||
		    UpnpDiscovery_get_Expires(param) <= 0 ||
		    UpnpString_get_Length(UpnpDiscovery_get_Location(param)) == 0 ||
		    !usn_found || !st_found) {
			/* bad reply */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		/* check each current search */
		HandleLock();
		if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
			HandleUnlock();
			goto end_ssdp_handle_ctrlpt_msg;
		}
		node = ListHead(&ctrlpt_info->SsdpSearchList);
		/* temporary add null termination */
		/*save_char = hdr_value.buf[ hdr_value.length ]; */
		/*hdr_value.buf[ hdr_value.length ] = '\0'; */
		while (node != NULL) {
			searchArg = node->item;
			/* check for match of ST header and search target */
			switch (searchArg->requestType) {
			case SSDP_ALL:
				matched = 1;
				break;
			case SSDP_ROOTDEVICE:
				matched =
				    (event.RequestType == SSDP_ROOTDEVICE);
				break;
			case SSDP_DEVICEUDN:
				matched = !strncmp(searchArg->searchTarget,
						   hdr_value.buf,
						   hdr_value.length);
				break;
			case SSDP_DEVICETYPE:{
					size_t m = min(hdr_value.length,
						       strlen
						       (searchArg->searchTarget));
					matched =
					    !strncmp(searchArg->searchTarget,
						     hdr_value.buf, m);
					break;
				}
			case SSDP_SERVICE:{
					size_t 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 = SSDPResultData_new();
				if (threadData != NULL) {
					SSDPResultData_set_Param(threadData,
								 param);
					SSDPResultData_set_Cookie(threadData,
								  searchArg->
								  cookie);
					SSDPResultData_set_CtrlptCallback
					    (threadData, ctrlpt_callback);
					TPJobInit(&job, (start_routine)
						  send_search_result,
						  threadData);
					TPJobSetPriority(&job, MED_PRIORITY);
					TPJobSetFreeFunction(&job,
							     (free_routine)
							     SSDPResultData_delete);
					ThreadPoolAdd(&gRecvThreadPool, &job,
						      NULL);
				}
			}
			node = ListNext(&ctrlpt_info->SsdpSearchList, node);
		}

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

end_ssdp_handle_ctrlpt_msg:
	UpnpDiscovery_delete(param);
}
Exemple #22
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);
}
Exemple #23
0
/************************************************************************
* Function : genaRenewSubscription
*																	
* Parameters:														
*	IN UpnpClient_Handle client_handle: Client handle
*	IN const Upnp_SID in_sid: subscription ID
*	INOUT int * TimeOut: requested Duration, if -1, then "infinite".
*						in the OUT case: actual Duration granted 
*						by Service, -1 for infinite
*
* Description:														
*	This function renews a SID. It first validates the SID and 
*	client_handle and copies the subscription. It sends RENEW 
*	(modified SUBSCRIBE) http request to service and processes
*	the response.
*
* Returns: int
*	return UPNP_E_SUCCESS if service response is OK else 
*	returns appropriate error
***************************************************************************/
int
genaRenewSubscription( IN UpnpClient_Handle client_handle,
                       IN const Upnp_SID in_sid,
                       INOUT int *TimeOut )
{
    int return_code = GENA_SUCCESS;
    client_subscription *sub;
    client_subscription sub_copy;
    struct Handle_Info *handle_info;

    char *ActualSID;
    ThreadPoolJob tempJob;

    HandleLock(  );

    // validate handle and sid
    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        return GENA_E_BAD_HANDLE;
    }

    if( ( sub = GetClientSubClientSID( handle_info->ClientSubList,
                                       in_sid ) ) == NULL ) {
        HandleUnlock(  );
        return GENA_E_BAD_SID;
    }
    // remove old events
    if( TimerThreadRemove( &gTimerThread, sub->RenewEventId, &tempJob ) ==
        0 ) {

        free_upnp_timeout( ( upnp_timeout * ) tempJob.arg );
    }

    DBGONLY( UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
                         "REMOVED AUTO RENEW  EVENT" ) );

    sub->RenewEventId = -1;
    return_code = copy_client_subscription( sub, &sub_copy );

    HandleUnlock(  );

    if( return_code != HTTP_SUCCESS ) {
        return return_code;
    }

    return_code = gena_subscribe( sub_copy.EventURL, TimeOut,
                                  sub_copy.ActualSID, &ActualSID );
    HandleLock(  );

    if( GetHandleInfo( client_handle, &handle_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        if( return_code == UPNP_E_SUCCESS ) {
            free( ActualSID );
        }
        return GENA_E_BAD_HANDLE;
    }
    // we just called GetHandleInfo, so we don't check for return value
    //GetHandleInfo(client_handle, &handle_info);

    if( return_code != UPNP_E_SUCCESS ) {
        // network failure (remove client sub)
        RemoveClientSubClientSID( &handle_info->ClientSubList, in_sid );
        free_client_subscription( &sub_copy );
        HandleUnlock(  );
        return return_code;
    }
    // get subscription
    if( ( sub = GetClientSubClientSID( handle_info->ClientSubList,
                                       in_sid ) ) == NULL ) {
        free( ActualSID );
        free_client_subscription( &sub_copy );
        HandleUnlock(  );
        return GENA_E_BAD_SID;
    }
    // store actual sid
    free( sub->ActualSID );
    sub->ActualSID = ActualSID;

    // start renew subscription timer
    return_code = ScheduleGenaAutoRenew( client_handle, *TimeOut, sub );
    if( return_code != GENA_SUCCESS ) {
        RemoveClientSubClientSID( &handle_info->ClientSubList, sub->sid );
    }
    free_client_subscription( &sub_copy );
    HandleUnlock(  );
    return return_code;
}
Exemple #24
0
/*  PasteSign = 0:Paste to Page,  1: Paste to Text Box */
int ClipBoardGetBox(int PasteSign)
{
    ClipBoards ClipBoardDataInformation;
    HBOX InsertHBox;
//  Boxs TmpBox,*Box;
#define TmpBox        TmpBuf
    Boxs *Box;
    TextBoxs *TextBox;
    PictureBoxs *PictureBox;

    ClipBoardGetDataInfomation(&ClipBoardDataInformation);
    if( ClipBoardDataInformation.ClipBoardDataLength==0
            || ClipBoardDataInformation.ClipBoardDataType!=BOXDATA )
        return(0);

    Box=&TmpBox;
    ClipBoardGet(Box,&ClipBoardDataInformation.ClipBoardDataLength,
                 &ClipBoardDataInformation.ClipBoardDataType);
    InsertHBox=BoxInsert(Box,GlobalCurrentPage);
    if (!InsertHBox)
        return(OUTOFMEMORY);
    if (TextBoxGetBoxType((TextBoxs *)Box)==POLYGONPICTUREBOX)
    {
        int *PolygonEdges,PolygonLeft,PolygonTop,PolygonRight,PolygonBottom,i;
        ORDINATETYPE PolygonEdgeData[2*MAXPOLYGONNUMBER+1];

        ClipBoardGetDataInfomation(&ClipBoardDataInformation);
        if ((ClipBoardDataInformation.ClipBoardDataLength==0)||
                (ClipBoardDataInformation.ClipBoardDataType!=POLYGONDATA))
            return(OUTOFMEMORY);
        ClipBoardGet(PolygonEdgeData,&ClipBoardDataInformation.ClipBoardDataLength,
                     &ClipBoardDataInformation.ClipBoardDataType);
        PictureBox=HandleLock(ItemGetHandle(InsertHBox));
        if (PictureBox==NULL)
            return(OUTOFMEMORY);
        PictureBoxSetBorderPolygon(PictureBox,HandleAlloc(
                                       sizeof(int)+2*sizeof(ORDINATETYPE)*MAXPOLYGONNUMBER,0));
        if (!PictureBoxGetBorderPolygon(PictureBox))
        {
            HandleUnlock(ItemGetHandle(InsertHBox));
            return(OUTOFMEMORY);
        }
        PolygonEdges=HandleLock(PictureBoxGetBorderPolygon(PictureBox));
        if (PolygonEdges==NULL)
        {
            HandleUnlock(ItemGetHandle(InsertHBox));
            return(OUTOFMEMORY);
        }
        memcpy(PolygonEdges,PolygonEdgeData,
               ClipBoardDataInformation.ClipBoardDataLength);
        if (PasteSign==GETTOTEXTBOX)
        {
            PictureBoxSetBoxLeft(PictureBox,0);
            PictureBoxSetBoxTop(PictureBox,0);
            PolygonGetMinRectangle(*PolygonEdges,&(PolygonEdges[1]),
                                   &PolygonLeft,&PolygonTop,&PolygonRight,&PolygonBottom);
            for (i=0; i<*PolygonEdges; i++)
            {
                PolygonEdges[i*2+1]-=PolygonLeft;
                PolygonEdges[i*2+2]-=PolygonTop;
            }
        }
        HandleUnlock(PictureBoxGetBorderPolygon(PictureBox));
        HandleUnlock(ItemGetHandle(InsertHBox));
    }
    else if (TextBoxGetBoxType((TextBoxs *)Box)==TEXTBOX)
    {
        TextBox=HandleLock(ItemGetHandle(InsertHBox));
        if (TextBox==NULL)
            return(OUTOFMEMORY);

        TextBoxInitialLineTable(TextBox);
        TextBoxSetInvalidPolygons(TextBox,0);

        if ((TextBoxGetTextLength((TextBoxs *)Box)>0)&&
                !TextBoxGetPrevLinkBox((TextBoxs *)Box))
        {
            Wchar *TextBlock;

            ClipBoardGetDataInfomation(&ClipBoardDataInformation);
            if ((ClipBoardDataInformation.ClipBoardDataLength==0)||
                    (ClipBoardDataInformation.ClipBoardDataType!=TEXTDATA))
            {
                TextBoxSetTextHandle(TextBox,0);
                TextBoxSetTextLength(TextBox,0);
                TextBoxSetBlockLength(TextBox,0);
                HandleUnlock(ItemGetHandle(InsertHBox));
                return(OUTOFMEMORY);
            }
            TextBoxSetTextHandle(TextBox,HandleAlloc(TextBoxGetBlockLength(TextBox)
                                 *sizeof(Wchar),0));
            if (!TextBoxGetTextHandle(TextBox))
            {
                TextBoxSetTextLength(TextBox,0);
                TextBoxSetBlockLength(TextBox,0);
                HandleUnlock(ItemGetHandle(InsertHBox));
                return(OUTOFMEMORY);
            }
            TextBlock=HandleLock(TextBoxGetTextHandle(TextBox));
            ClipBoardGet(TextBlock,&ClipBoardDataInformation.ClipBoardDataLength,
                         &ClipBoardDataInformation.ClipBoardDataType);
            TextBlock[TextBoxGetTextLength(TextBox)]=0;
            HandleUnlock(TextBoxGetTextHandle(TextBox));
        }
        else
        {
            TextBoxSetTextHandle(TextBox,0);
            TextBoxSetTextLength(TextBox,0);
            TextBoxSetBlockLength(TextBox,0);
        }
        TextBoxSetPrevLinkBox(TextBox,0);
        TextBoxSetNextLinkBox(TextBox,0);
        InitRL(TextBox);
        FormatAll(InsertHBox);
        HandleUnlock(ItemGetHandle(InsertHBox));
    }
    else if ((TextBoxGetBoxType((TextBoxs *)Box)>=RECTANGLEPICTUREBOX)
             &&(TextBoxGetBoxType((TextBoxs *)Box)<=POLYGONPICTUREBOX))
    {
        PictureBox=HandleLock(ItemGetHandle(InsertHBox));
        if (PictureBox==NULL)
            return(OUTOFMEMORY);
        if (PictureBoxGetPictureFileName(PictureBox)[0])
        {
            ImageDescribes *TiffPresent;

            TiffPresent=&(PictureBoxGetPicturePresent(PictureBox));
            TiffPresent->ImageHandle=TiffPresent->ImageNewHandle=0;
            PictureBoxImportTiff(PictureBoxGetPictureFileName(PictureBox),
                                 InsertHBox);
        }
        HandleUnlock(ItemGetHandle(InsertHBox));
    }

    if (PasteSign==GETTOTEXTBOX)
    {
        ItemSetNext(ItemGetPrev(InsertHBox),0);
        ItemSetPrev(InsertHBox,0);
        ItemSetNext(InsertHBox,0);
        ItemSetFather(InsertHBox,0);

        TextBox=HandleLock(ItemGetHandle(InsertHBox));
        if (TextBox==NULL)
            return(OUTOFMEMORY);
        TextBoxSetEmbodyBox(TextBox);
        HandleUnlock(ItemGetHandle(InsertHBox));
    }
    return(InsertHBox);
}