コード例 #1
0
ファイル: ccontrolpoint.c プロジェクト: RbBtSn0w/CyberLink4C
BOOL cg_upnp_controlpoint_parseservicesfordevice(CgUpnpDevice *dev, CgUpnpSSDPPacket *ssdpPkt)
{
	CgUpnpService *service;
	CgUpnpDevice *childDev;
	
	cg_log_debug_l4("Entering...\n");

	for (service=cg_upnp_device_getservices(dev); service != NULL; service = cg_upnp_service_next(service)) {
		if (cg_upnp_controlpoint_parsescservicescpd(service) == FALSE) {
			return FALSE;
		}
	}
	
	/* Now only root SCPDs for root services are parsed, but also child 
	   devices' services have to be parsed, so parse them */
	for (childDev=cg_upnp_device_getdevices(dev); childDev != NULL; childDev = cg_upnp_device_next(childDev)) {
		if (cg_upnp_controlpoint_parseservicesfordevice(childDev, ssdpPkt) == FALSE)
		{
			return FALSE;
		}
	}
	
	cg_log_debug_l4("Leaving...\n");

	return TRUE;
}
コード例 #2
0
ファイル: ccontrolpoint.c プロジェクト: RbBtSn0w/CyberLink4C
/**
 * Find a device from the controlpoint by the UDN of the device.
 *
 * \param ctrlPoint Controlpoint in question
 * \param udn Type of the device
 *
 */
CgUpnpDevice *cg_upnp_controlpoint_getdevicebyudn(CgUpnpControlPoint *ctrlPoint,
						  char *udn)
{
	CgUpnpDevice *dev = NULL;
	CgUpnpDevice *childDev = NULL;
	
	cg_log_debug_l4("Entering...\n");

	if (cg_strlen(udn) <= 0 || ctrlPoint == NULL)
	{
		return NULL;
	}
	
	for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint); 
	     dev != NULL;
	     dev = cg_upnp_device_next(dev))
	{
		if (cg_strcmp(cg_upnp_device_getudn(dev), udn) == 0)
		{
			return dev;
		}
		childDev = cg_upnp_device_getdevicebyudn(dev, udn);
		if (childDev != NULL)
		{
			return childDev;
		}
	}

	cg_log_debug_l4("Leaving...\n");

	return NULL;
}
コード例 #3
0
void PrintIGDInfos(CgUpnpControlPoint *ctrlPoint)
{
	CgUpnpDevice *dev;
	int igdNum;
		
	igdNum = 0;
	for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint); dev != NULL; dev = cg_upnp_device_next(dev)) {
		if (cg_upnp_device_isdevicetype(dev, UPNPAVDUMP_IGD_DEVICETYPE))
			PrintIGDInfo(dev, ++igdNum);
	}

	if (igdNum <= 0)
		printf("IGD is not found !!\n");
}
コード例 #4
0
ファイル: ccontrolpoint.c プロジェクト: RbBtSn0w/CyberLink4C
/**
 * Find a device from the controlpoint by the type of the device.
 * This function searches for devices, whose *type part* (i.e. not including
 * the version) of the device type string matches the given string.
 * For example: "urn:schemas-upnp-org:device:FooDevice". If you need
 * to know the version of a device, use \ref cg_upnp_devicetype_getversion
 *
 * \param ctrlPoint Controlpoint in question
 * \param type Type of the device
 *
 */
CgUpnpDevice *cg_upnp_controlpoint_getdevicebytype(CgUpnpControlPoint *ctrlPoint,
						   char *type)
{
	CgUpnpDevice *dev = NULL;
	CgUpnpDevice *childDev = NULL;
	const char* typeString = NULL;
	char* part = NULL;
	
	cg_log_debug_l4("Entering...\n");

	if (cg_strlen(type) <= 0 || ctrlPoint == NULL)
	{
		return NULL;
	}

	for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint);
	     dev != NULL;
	     dev = cg_upnp_device_next(dev))
	{
		typeString = cg_upnp_device_getdevicetype(dev);
		if (typeString != NULL)
		{
			part = cg_upnp_devicetype_getschematype(typeString);
			if (cg_strcmp(part, type) == 0)
			{
				free(part);
				
				return dev;
			}
			else
			{
				free(part);
			}
		}
				
		childDev = cg_upnp_device_getdevicebytype(dev, type);
		if (childDev != NULL)
		{
			return childDev;
		}
	}
	
	cg_log_debug_l4("Leaving...\n");

	return NULL;
}
コード例 #5
0
void cg_upnp_device_ssdpmessagereceived(CgUpnpDevice *dev, CgUpnpSSDPPacket *ssdpPkt, int filter)
{
    BOOL isRootDev;
    char *ssdpST;
    char *devUDN, *devType;
    char ssdpMsg[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE];
    char deviceUSN[CG_UPNP_SSDP_HEADER_LINE_MAXSIZE];
#if defined WINCE
    size_t n;
#else
    int n;
#endif
    CgUpnpService *service;
    CgUpnpDevice *childDev;
    char *ssdpMXString;
    int ssdpMX;

    cg_log_debug_l4("Entering...\n");

    ssdpMXString = cg_http_headerlist_getvalue(ssdpPkt->headerList, CG_HTTP_MX);
    ssdpST = cg_upnp_ssdp_packet_getst(ssdpPkt);

    /* Check if this ssdp packet has already been checked + filtered */
    if (filter)
    {

        /****************************************
         * Request line
         * Check the request line for errors, this is not ideal as it currently only
         * checks for the presence of the strings and not the order.
         ***************************************/
        /**** check for M-SEARCH and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), CG_HTTP_MSEARCH) < 0)
            return;
        /**** check for * and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data), "*") < 0)
            return;
        /**** check HTTP version and return if not found ****/
        if (cg_strstr(cg_string_getvalue(ssdpPkt->dgmPkt->data),  CG_HTTP_VER11) < 0)
            return;

        /****************************************
         * check HOST header, should always be 239.255.255.250:1900, return if incorrect
         ***************************************/
        if (cg_strcmp(cg_upnp_ssdp_packet_gethost(ssdpPkt), CG_UPNP_SSDP_MULTICAST_ADDRESS) != 0)
            return;

        /****************************************
         * check MAN header, return if incorrect
         ***************************************/
        if (cg_upnp_ssdp_packet_isdiscover(ssdpPkt) == FALSE)
            return;

        /****************************************
         * check MX header, return if incorrect
         ***************************************/
        if (ssdpMXString == NULL || cg_strlen(ssdpMXString)==0)
            /* return if the MX value does not exist or is empty */
            return;
        /* check if MX value is not an integer */
        for (n=0; n<strlen(ssdpMXString); n++) {
            if (isdigit(ssdpMXString[n]) == 0)
                /* MX value contains a non-digit so is invalid */
                return;
        }

        /****************************************
         * check ST header and if empty return
         ***************************************/
        if (cg_strlen(ssdpST) <= 0)
            return;

        /* Check if we have received this search recently
         * and ignore duplicates. */
        if ( filter_duplicate_m_search(ssdpPkt) )
            return;

        ssdpMX = cg_upnp_ssdp_packet_getmx(ssdpPkt);
        cg_log_debug("Sleeping for a while... (MX:%d)\n", ssdpMX);
        cg_waitrandom((ssdpMX*1000)/4);
    }

    isRootDev = cg_upnp_device_isrootdevice(dev);

    if (cg_upnp_st_isalldevice(ssdpST) == TRUE) {
        /* for root device only */
        if (isRootDev == TRUE) {
            cg_upnp_device_getnotifydevicent(dev, ssdpMsg, sizeof(ssdpMsg));
            cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
        }
        /* for all devices send */
        /* device type : device version */
        cg_upnp_device_getnotifydevicetypent(dev, ssdpMsg, sizeof(ssdpMsg));
        cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
        cg_upnp_device_postsearchresponse(dev, ssdpPkt, ssdpMsg, deviceUSN);
        /* device UUID */
        cg_upnp_device_postsearchresponse(dev, ssdpPkt, cg_upnp_device_getudn(dev), cg_upnp_device_getudn(dev));
    }
    else if (cg_upnp_st_isrootdevice(ssdpST)  == TRUE) {
        if (isRootDev == TRUE) {
            cg_upnp_device_getnotifydeviceusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, CG_UPNP_ST_ROOT_DEVICE, deviceUSN);
        }
    }
    else if (cg_upnp_st_isuuiddevice(ssdpST)  == TRUE) {
        devUDN = cg_upnp_device_getudn(dev);
        if (cg_streq(ssdpST, devUDN) == TRUE)
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, devUDN, devUDN);
    }
    else if (cg_upnp_st_isurn(ssdpST)  == TRUE) {
        devType = cg_upnp_device_getdevicetype(dev);
        if (cg_streq(ssdpST, devType) == TRUE) {
            cg_upnp_device_getnotifydevicetypeusn(dev, deviceUSN, sizeof(deviceUSN));
            cg_upnp_device_postsearchresponse(dev, ssdpPkt, devType, deviceUSN);
        }
    }

    for (service=cg_upnp_device_getservices(dev); service != NULL; service = cg_upnp_service_next(service))
        cg_upnp_service_ssdpmessagereceived(service, ssdpPkt);

    for (childDev = cg_upnp_device_getdevices(dev); childDev != NULL; childDev = cg_upnp_device_next(childDev))
        cg_upnp_device_ssdpmessagereceived(childDev, ssdpPkt, FALSE);


    cg_log_debug_l4("Leaving...\n");
}
コード例 #6
0
/**
 * The function that calls all HTTP listener callback functions. Do not call
 * this from applications.
 *
 * @param httpReq The received HTTP request
 */
void cg_upnp_controlpoint_httprequestreceived(CgHttpRequest *httpReq)
{
	CgUpnpControlPoint *ctrlPoint = NULL;
	CgUpnpNotifyRequest *notifyReq = NULL;
	CgUpnpPropertyList *propList = NULL;
	CgUpnpProperty *prop = NULL;
	CgUpnpEventListenerList *eventListeners = NULL;
	const char *sid = NULL;
	long seq = 0;
	long timeout = 0;
	CgUpnpDevice *dev = NULL;
	CgUpnpService *service = NULL;
	int notifyListeners = 0;
	
	cg_log_debug_l4("Entering...\n");

	ctrlPoint = (CgUpnpControlPoint *)cg_http_request_getuserdata(httpReq);

	cg_upnp_controlpoint_lock(ctrlPoint);

#if !defined(CG_UPNP_NOUSE_SUBSCRIPTION)
	if (cg_http_request_isnotifyrequest(httpReq) == TRUE) {	
		notifyReq = cg_upnp_event_notify_request_new();
		cg_upnp_event_notify_request_sethttprequest(notifyReq, httpReq);

		/* Get service according to SID */
		sid = cg_upnp_event_notify_request_getsid(notifyReq);
		
		for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint); 
		     dev != NULL;
		     dev = cg_upnp_device_next(dev))
		{
			service = cg_upnp_device_getservicebysid(dev, sid);
			if (service != NULL) break;
		}

		if (service != NULL) {
			/* We found a service */
			seq = cg_upnp_event_notify_request_getseq(notifyReq);
			
			/* Check that event key = previous + 1 */
			if (seq != 0 && seq != cg_upnp_service_geteventkey(service) + 1)
			{
				/* The sequence does not match, unsubscribe and subscribe */
				timeout = cg_upnp_service_getsubscriptiontimeout(service);
				cg_upnp_controlpoint_unsubscribe(ctrlPoint, service);
				cg_upnp_controlpoint_subscribe(ctrlPoint, service, timeout);
			} else {
				/* Wrap seq, so that assertion is true next time */
				if (seq == CG_UPNP_EVENT_MAX_SEQ) seq = 0;
				
				/* Set event key */
				cg_upnp_service_seteventkey(service, seq);
				
				notifyListeners = 1;
				propList = cg_upnp_event_notify_request_getpropertylist(notifyReq); 
				for (prop=cg_upnp_propertylist_gets(propList); 
				     prop != NULL; 
				     prop = cg_upnp_property_next(prop)) 
				{
					/* Update the service's state table from the event */
					cg_upnp_controlpoint_updatestatetablefromproperty(service, prop);
				}
			}
		}
		eventListeners = cg_upnp_controlpoint_geteventlisteners(ctrlPoint);
		cg_upnp_controlpoint_unlock(ctrlPoint);

		if (notifyListeners && propList != NULL) 
		{
			/* Notify listeners out of control point lock */
			for (prop=cg_upnp_propertylist_gets(propList); 
			     prop != NULL; 
			     prop = cg_upnp_property_next(prop)) 
			{
				cg_upnp_eventlistenerlist_notify(eventListeners, prop);
			}
		}

		cg_upnp_event_notify_request_delete(notifyReq);
		cg_http_request_postokrequest(httpReq);
		
		return;
	}
#endif
	
	cg_upnp_controlpoint_unlock(ctrlPoint);
	cg_http_request_postbadrequest(httpReq);

	cg_log_debug_l4("Leaving...\n");
}
コード例 #7
0
ファイル: ccontrolpoint.c プロジェクト: RbBtSn0w/CyberLink4C
BOOL cg_upnp_controlpoint_ipchanged(CgUpnpControlPoint *ctrlPoint)
{
	CgNetworkInterfaceList *current, *added, *removed;
	CgNetworkInterface *netIf;
	CgUpnpDevice *dev, *tmp;
	CgUpnpSSDPPacket *ssdpPkt;
	char *address;
	
	cg_log_debug_l4("Entering...\n");

	current = cg_net_interfacelist_new();
	added = cg_net_interfacelist_new();
	removed = cg_net_interfacelist_new();

	if (current == NULL || added == NULL || removed == NULL)
	{
		if (current != NULL) cg_net_interfacelist_delete(current);
		if (added != NULL) cg_net_interfacelist_delete(added);
		if (removed != NULL) cg_net_interfacelist_delete(removed);
		return FALSE;
	}
	
	/* Get Interface changes */
	cg_net_gethostinterfaces(current);
	cg_net_interfacelist_getchanges(ctrlPoint->ifCache, current, 
					added, removed);
	
	/* Remove all devices registered through old interface */
	for (netIf = cg_net_interfacelist_gets(removed);
	     netIf != NULL; netIf = cg_net_interface_next(netIf))
	{
		cg_upnp_controlpoint_lock(ctrlPoint);
		tmp = cg_upnp_controlpoint_getdevices(ctrlPoint);
		while (tmp != NULL)
		{
			dev = tmp; tmp = cg_upnp_device_next(dev);
			ssdpPkt = cg_upnp_device_getssdppacket(dev);
			address = cg_upnp_ssdp_packet_getlocaladdress(ssdpPkt);
			
			if (address != NULL && 
			    cg_strcmp(address, cg_net_interface_getaddress(netIf)) == 0)
			{
				/* This device has been received from the 
				   removed interface, so it does not exist */
				cg_upnp_controlpoint_unlock(ctrlPoint);
				cg_upnp_controlpoint_removedevicebyssdppacket(ctrlPoint, 
									      ssdpPkt);
				cg_upnp_controlpoint_lock(ctrlPoint);
				address = NULL; dev = NULL; ssdpPkt = NULL;
			}
		}
		cg_upnp_controlpoint_unlock(ctrlPoint);
	}

	/* Launch new M-SEARCH */
	cg_upnp_controlpoint_search(ctrlPoint, CG_UPNP_ST_ROOT_DEVICE);
	
	/**** Cache current interfaces ****/
	cg_net_gethostinterfaces(ctrlPoint->ifCache);
	
	cg_net_interfacelist_delete(current);
	cg_net_interfacelist_delete(added);
	cg_net_interfacelist_delete(removed);

	cg_log_debug_l4("Leaving...\n");

	return TRUE;
}
コード例 #8
0
ファイル: ccontrolpoint.c プロジェクト: RbBtSn0w/CyberLink4C
/**
 * Stop the control point. Stops sending/receiveing/responding to any messages.
 *
 * @param ctrlPoint The control point to stop
 *
 * @return TRUE if successful; otherwise FALSE
 *
 */
BOOL cg_upnp_controlpoint_stop(CgUpnpControlPoint *ctrlPoint)
{
	CgUpnpDevice *dev = NULL;
	CgUpnpSSDPServerList *ssdpServerList;
	CgUpnpSSDPResponseServerList *ssdpResServerList;
	CgHttpServerList *httpServerList;
	const char *udn = NULL;
	CG_UPNP_DEVICE_LISTENER listener = cg_upnp_controlpoint_getdevicelistener(ctrlPoint);
	
	cg_log_debug_l4("Entering...\n");

	/* Stop expiration handling */
	cg_thread_stop_with_cond(ctrlPoint->expThread, ctrlPoint->expCond);
	cg_log_debug_s("Expiration thread stopped.\n");
	
	/**** SSDP Server ****/
	ssdpServerList = cg_upnp_controlpoint_getssdpserverlist(ctrlPoint);
	cg_log_debug_s("Stopping ssdp servers.\n");
	cg_upnp_ssdp_serverlist_stop(ssdpServerList);
	cg_log_debug_s("Done\n");
	cg_upnp_ssdp_serverlist_close(ssdpServerList);
	cg_upnp_ssdp_serverlist_clear(ssdpServerList);
	
	/**** SSDP Response Server ****/
	ssdpResServerList = cg_upnp_controlpoint_getssdpresponseserverlist(ctrlPoint);
	cg_log_debug_s("Stopping ssdp response servers.\n");
	cg_upnp_ssdpresponse_serverlist_stop(ssdpResServerList);
	cg_log_debug_s("Done\n");
	cg_upnp_ssdpresponse_serverlist_close(ssdpResServerList);
	cg_upnp_ssdpresponse_serverlist_clear(ssdpResServerList);
	
	/**** HTTP Server ****/
	httpServerList = cg_upnp_controlpoint_gethttpserverlist(ctrlPoint);
	cg_log_debug_s("Stopping http servers.\n");
	cg_http_serverlist_stop(httpServerList);
	cg_log_debug_s("Done\n");
	cg_http_serverlist_close(httpServerList);
	cg_http_serverlist_clear(httpServerList);

	cg_upnp_controlpoint_lock(ctrlPoint);

	cg_log_debug_s("Got controlpoint lock.\n");
	
	/* Unsubscribe from all services */

	for (dev = cg_upnp_controlpoint_getdevices(ctrlPoint); 
	     dev != NULL;
	     dev = cg_upnp_device_next(dev))
	{
		udn = cg_upnp_device_getudn(dev);
		
		/* Call device listener for each device */
		if (udn != NULL && listener != NULL)
		{
			cg_upnp_controlpoint_unlock(ctrlPoint);
			listener(ctrlPoint, udn, CgUpnpDeviceStatusRemoved);
			cg_upnp_controlpoint_lock(ctrlPoint);
		}
	}
	/* Empty device cache */
	cg_upnp_devicelist_clear(ctrlPoint->deviceList);
	cg_log_debug_s("Device list cleared.\n");

	cg_upnp_controlpoint_unlock(ctrlPoint);
		
	cg_log_debug_l4("Leaving...\n");

	return TRUE;
}