Ejemplo n.º 1
0
/************************************************************************
*	Function :	freeServiceList
*
*	Parameters :
*		service_info * head ;	Head of the service list to be freed
*
*	Description :	Free's memory allocated for the various components 
*		of each service entry in the service table.
*
*	Return : void ;
*
*	Note :
************************************************************************/
void
freeServiceList( service_info * head )
{
    service_info *next = NULL;

    while( head ) {
        if( head->serviceType )
            ixmlFreeDOMString( head->serviceType );
        if( head->serviceId )
            ixmlFreeDOMString( head->serviceId );
        if( head->SCPDURL )
            free( head->SCPDURL );
        if( head->controlURL )
            free( head->controlURL );
        if( head->eventURL )
            free( head->eventURL );
        if( head->UDN )
            ixmlFreeDOMString( head->UDN );
        if( head->subscriptionList )
            freeSubscriptionList( head->subscriptionList );

        head->TotalSubscriptions = 0;
        next = head->next;
        free( head );
        head = next;
    }
}
Ejemplo n.º 2
0
/************************************************************************
*	Function :	freeService
*
*	Parameters :
*		service_info *in ;	service information that is to be freed
*
*	Description :	Free's memory allocated for the various components 
*		of the service entry in the service table.
*
*	Return : void ;
*
*	Note :
************************************************************************/
void freeService( service_info * in )
{
    if( in ) {
        if( in->serviceType )
            ixmlFreeDOMString( in->serviceType );

        if( in->serviceId )
            ixmlFreeDOMString( in->serviceId );

        if( in->SCPDURL )
            free( in->SCPDURL );

        if( in->controlURL )
            free( in->controlURL );

        if( in->eventURL )
            free( in->eventURL );

        if( in->UDN )
            ixmlFreeDOMString( in->UDN );

        if( in->subscriptionList )
            freeSubscriptionList( in->subscriptionList );

        in->TotalSubscriptions = 0;
        free( in );
    }
}
Ejemplo n.º 3
0
/************************************************************************
*	Function :	GetNextSubscription
*
*	Parameters :
*		service_info * service ; service object providing the list of
*						subscriptions
*		subscription *current ;	current subscription object
*
*	Description :	Get current and valid subscription from the service 
*		table.
*
*	Return : subscription * - Pointer to the next subscription node;
*
*	Note :
************************************************************************/
subscription *
GetNextSubscription( service_info * service,
                     subscription * current )
{
    time_t current_time;
    subscription *next = NULL;
    subscription *previous = NULL;
    int notDone = 1;

    //get the current_time
    time( &current_time );
    while( ( notDone ) && ( current ) ) {
        previous = current;
        current = current->next;

        if( current == NULL ) {
            notDone = 0;
            next = current;
        } else
            if( ( current->expireTime != 0 )
                && ( current->expireTime < current_time ) ) {
            previous->next = current->next;
            current->next = NULL;
            freeSubscriptionList( current );
            current = previous;
            service->TotalSubscriptions--;
        } else if( current->active ) {
            notDone = 0;
            next = current;
        }
    }
    return next;
}
Ejemplo n.º 4
0
subscription *GetSubscriptionSID(const Upnp_SID sid, service_info *service)
{
    subscription *next = service->subscriptionList;
    subscription *previous = NULL;
    subscription *found = NULL;

    time_t current_time;

    while( ( next ) && ( found == NULL ) ) {
        if( !strcmp( next->sid, sid ) )
            found = next;
        else {
            previous = next;
            next = next->next;
        }
    }
    if( found ) {
        /*get the current_time */
        time( &current_time );
        if( ( found->expireTime != 0 )
            && ( found->expireTime < current_time ) ) {
            if( previous )
                previous->next = found->next;
            else
                service->subscriptionList = found->next;
            found->next = NULL;
            freeSubscriptionList( found );
            found = NULL;
            service->TotalSubscriptions--;
        }
    }
    return found;

}
Ejemplo n.º 5
0
/************************************************************************
*	Function :	RemoveSubscriptionSID
*
*	Parameters :
*		Upnp_SID sid ;	subscription ID
*		service_info * service ;	service object providing the list of
*						subscriptions
*
*	Description :	Remove the subscription represented by the
*		const Upnp_SID sid parameter from the service table and update 
*		the service table.
*
*	Return : void ;
*
*	Note :
************************************************************************/
void
RemoveSubscriptionSID( Upnp_SID sid,
                       service_info * service )
{
    subscription *finger = service->subscriptionList;
    subscription *previous = NULL;

    while( finger ) {
        if( !( strcmp( sid, finger->sid ) ) ) {
            if( previous )
                previous->next = finger->next;
            else
                service->subscriptionList = finger->next;
            finger->next = NULL;
            freeSubscriptionList( finger );
            finger = NULL;
            service->TotalSubscriptions--;
        } else {
            previous = finger;
            finger = finger->next;
        }
    }

}
Ejemplo n.º 6
0
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();

	if (GetDeviceHandleInfoForPath(event_url_path, info->foreign_sockaddr.ss_family,
								   &device_handle, &handle_info, &service) != HND_DEVICE) {
		free(event_url_path);
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	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->ToSendEventKey = 0;
	sub->active = 0;
	sub->next = NULL;
	sub->DeliveryURLs.size = 0;
	sub->DeliveryURLs.URLs = NULL;
	sub->DeliveryURLs.parsedURLs = NULL;
	if (ListInit(&sub->outgoing, 0, free) != 0) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}

	/* 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);
	upnp_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);
}