Example #1
0
/********************************************************************************
 * TvCtrlPointAddDevice
 *
 * Description: 
 *       If the device is not already included in the global device list,
 *       add it.  Otherwise, update its advertisement expiration timeout.
 *
 * Parameters:
 *   DescDoc -- The description document for the device
 *   location -- The location of the description document URL
 *   expires -- The expiration time for this advertisement
 *
 ********************************************************************************/
void TvCtrlPointAddDevice(
	IXML_Document *DescDoc,
	const char *location,
	int expires)
{
	char *deviceType = NULL;
	char *friendlyName = NULL;
	char presURL[200];
	char *baseURL = NULL;
	char *relURL = NULL;
	char *UDN = NULL;
	char *serviceId[TV_SERVICE_SERVCOUNT] = { NULL, NULL };
	char *eventURL[TV_SERVICE_SERVCOUNT] = { NULL, NULL };
	char *controlURL[TV_SERVICE_SERVCOUNT] = { NULL, NULL };
	Upnp_SID eventSID[TV_SERVICE_SERVCOUNT];
	int TimeOut[TV_SERVICE_SERVCOUNT] = {
		default_timeout,
		default_timeout
	};
	struct TvDeviceNode *deviceNode;
	struct TvDeviceNode *tmpdevnode;
	int ret = 1;
	int found = 0;
	int service;
	int var;

	ithread_mutex_lock(&DeviceListMutex);

	/* Read key elements from description document */
	UDN = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN");
	deviceType = SampleUtil_GetFirstDocumentItem(DescDoc, "deviceType");
	friendlyName = SampleUtil_GetFirstDocumentItem(DescDoc, "friendlyName");
	baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase");
	relURL = SampleUtil_GetFirstDocumentItem(DescDoc, "presentationURL");

	ret = UpnpResolveURL((baseURL ? baseURL : location), relURL, presURL);

	if (UPNP_E_SUCCESS != ret)
		SampleUtil_Print("Error generating presURL from %s + %s\n",
				 baseURL, relURL);

	if (strcmp(deviceType, TvDeviceType) == 0) {
		SampleUtil_Print("Found Tv device\n");

		/* Check if this device is already in the list */
		tmpdevnode = GlobalDeviceList;
		while (tmpdevnode) {
			if (strcmp(tmpdevnode->device.UDN, UDN) == 0) {
				found = 1;
				break;
			}
			tmpdevnode = tmpdevnode->next;
		}

		if (found) {
			/* The device is already there, so just update  */
			/* the advertisement timeout field */
			tmpdevnode->device.AdvrTimeOut = expires;
		} else {
			for (service = 0; service < TV_SERVICE_SERVCOUNT;
			     service++) {
				if (SampleUtil_FindAndParseService
				    (DescDoc, location, TvServiceType[service],
				     &serviceId[service], &eventURL[service],
				     &controlURL[service])) {
					SampleUtil_Print
					    ("Subscribing to EventURL %s...\n",
					     eventURL[service]);
					ret =
					    UpnpSubscribe(ctrlpt_handle,
							  eventURL[service],
							  &TimeOut[service],
							  eventSID[service]);
					if (ret == UPNP_E_SUCCESS) {
						SampleUtil_Print
						    ("Subscribed to EventURL with SID=%s\n",
						     eventSID[service]);
					} else {
						SampleUtil_Print
						    ("Error Subscribing to EventURL -- %d\n",
						     ret);
						strcpy(eventSID[service], "");
					}
				} else {
					SampleUtil_Print
					    ("Error: Could not find Service: %s\n",
					     TvServiceType[service]);
				}
			}
			/* Create a new device node */
			deviceNode =
			    (struct TvDeviceNode *)
			    malloc(sizeof(struct TvDeviceNode));
			strcpy(deviceNode->device.UDN, UDN);
			strcpy(deviceNode->device.DescDocURL, location);
			strcpy(deviceNode->device.FriendlyName, friendlyName);
			strcpy(deviceNode->device.PresURL, presURL);
			deviceNode->device.AdvrTimeOut = expires;
			for (service = 0; service < TV_SERVICE_SERVCOUNT;
			     service++) {
				strcpy(deviceNode->device.TvService[service].
				       ServiceId, serviceId[service]);
				strcpy(deviceNode->device.TvService[service].
				       ServiceType, TvServiceType[service]);
				strcpy(deviceNode->device.TvService[service].
				       ControlURL, controlURL[service]);
				strcpy(deviceNode->device.TvService[service].
				       EventURL, eventURL[service]);
				strcpy(deviceNode->device.TvService[service].
				       SID, eventSID[service]);
				for (var = 0; var < TvVarCount[service]; var++) {
					deviceNode->device.
					    TvService[service].VariableStrVal
					    [var] =
					    (char *)malloc(TV_MAX_VAL_LEN);
					strcpy(deviceNode->device.
					       TvService[service].VariableStrVal
					       [var], "");
				}
			}
			deviceNode->next = NULL;
			/* Insert the new device node in the list */
			if ((tmpdevnode = GlobalDeviceList)) {
				while (tmpdevnode) {
					if (tmpdevnode->next) {
						tmpdevnode = tmpdevnode->next;
					} else {
						tmpdevnode->next = deviceNode;
						break;
					}
				}
			} else {
				GlobalDeviceList = deviceNode;
			}
			/*Notify New Device Added */
			SampleUtil_StateUpdate(NULL, NULL,
					       deviceNode->device.UDN,
					       DEVICE_ADDED);
		}
	}

	ithread_mutex_unlock(&DeviceListMutex);

	if (deviceType)
		free(deviceType);
	if (friendlyName)
		free(friendlyName);
	if (UDN)
		free(UDN);
	if (baseURL)
		free(baseURL);
	if (relURL)
		free(relURL);
	for (service = 0; service < TV_SERVICE_SERVCOUNT; service++) {
		if (serviceId[service])
			free(serviceId[service]);
		if (controlURL[service])
			free(controlURL[service]);
		if (eventURL[service])
			free(eventURL[service]);
	}
}
Example #2
0
int TvDeviceStateTableInit(char *DescDocURL)
{
	IXML_Document *DescDoc = NULL;
	int ret = UPNP_E_SUCCESS;
	char *servid_ctrl = NULL;
	char *evnturl_ctrl = NULL;
	char *ctrlurl_ctrl = NULL;
	char *servid_pict = NULL;
	char *evnturl_pict = NULL;
	char *ctrlurl_pict = NULL;
	char *udn = NULL;

	/*Download description document */
	if (UpnpDownloadXmlDoc(DescDocURL, &DescDoc) != UPNP_E_SUCCESS) {
		SampleUtil_Print("TvDeviceStateTableInit -- Error Parsing %s\n",
				 DescDocURL);
		ret = UPNP_E_INVALID_DESC;
		goto error_handler;
	}
	udn = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN");
	/* Find the Tv Control Service identifiers */
	if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL,
					    TvServiceType[TV_SERVICE_CONTROL],
					    &servid_ctrl, &evnturl_ctrl,
					    &ctrlurl_ctrl)) {
		SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n",
				 TvServiceType[TV_SERVICE_CONTROL]);
		ret = UPNP_E_INVALID_DESC;
		goto error_handler;
	}
	/* set control service table */
	SetServiceTable(TV_SERVICE_CONTROL, udn, servid_ctrl,
			TvServiceType[TV_SERVICE_CONTROL],
			&tv_service_table[TV_SERVICE_CONTROL]);

	/* Find the Tv Picture Service identifiers */
	if (!SampleUtil_FindAndParseService(DescDoc, DescDocURL,
					    TvServiceType[TV_SERVICE_PICTURE],
					    &servid_pict, &evnturl_pict,
					    &ctrlurl_pict)) {
		SampleUtil_Print("TvDeviceStateTableInit -- Error: Could not find Service: %s\n",
				 TvServiceType[TV_SERVICE_PICTURE]);
		ret = UPNP_E_INVALID_DESC;
		goto error_handler;
	}
	/* set picture service table */
	SetServiceTable(TV_SERVICE_PICTURE, udn, servid_pict,
			TvServiceType[TV_SERVICE_PICTURE],
			&tv_service_table[TV_SERVICE_PICTURE]);

error_handler:
	/* clean up */
	if (udn)
		free(udn);
	if (servid_ctrl)
		free(servid_ctrl);
	if (evnturl_ctrl)
		free(evnturl_ctrl);
	if (ctrlurl_ctrl)
		free(ctrlurl_ctrl);
	if (servid_pict)
		free(servid_pict);
	if (evnturl_pict)
		free(evnturl_pict);
	if (ctrlurl_pict)
		free(ctrlurl_pict);
	if (DescDoc)
		ixmlDocument_free(DescDoc);

	return (ret);
}
/********************************************************************************
 * WscUPnPCPAddDevice
 *
 * Description: 
 *       Add a new Wsc device into the wsc device list or just update its advertisement 
 *       expiration timeout if it alreay exists in the list.
 *
 * Parameters:
 *   	deviceType -- The device type want to add to the Device List
 *   	d_event -- The "Upnp_Discovery" data
 *
 * Return:
 *	 	WSC_SYS_SUCCESS - if success
 *   	other value     - if failure
 ********************************************************************************/
int WscUPnPCPAddDevice(
	IN char *deviceType,
	IN struct Upnp_Discovery *d_event,
	OUT unsigned int *outIPAddr)
{
	IXML_Document *DescDoc = NULL, *scpdDescDoc = NULL;
	char *deviceTypeStr = NULL, *friendlyName = NULL, *baseURL = NULL, *relURL = NULL, *UDN = NULL;
	char presURL[200] = {0};
	char *serviceId = NULL, *SCPDURL = NULL, *eventURL = NULL, *controlURL = NULL;
	Upnp_SID eventSID;
	struct upnpDeviceNode *newDeviceNode, *devNodePtr;
	int ret = WSC_SYS_ERROR;
	int found = 0;
	int TimeOut = DEF_SUBSCRIPTION_TIMEOUT;
	unsigned int ipAddr = 0;
	unsigned short port = 0;

	if(d_event->DestAddr != NULL)
	{
		ipAddr = (unsigned int)d_event->DestAddr->sin_addr.s_addr;
		port = (unsigned short)d_event->DestAddr->sin_port;
		*outIPAddr = ipAddr;
	}
	
	printf("%s():outIPAddr=0x%x!\n", __FUNCTION__, *outIPAddr);
	if( !(strcmp(&HostDescURL[0], &d_event->Location[0])))
	{
//		DBGPRINTF(RT_DBG_INFO, "%s():Adver from LocalDev, ignore it!\n", __FUNCTION__);
		goto done;
	}
		
	// Check if this device is already in the list
	devNodePtr = WscDeviceList;
	while (devNodePtr)
	{
		if((strcmp(devNodePtr->device.UDN, d_event->DeviceId) == 0) 
			&& (strcmp(devNodePtr->device.DescDocURL, d_event->Location) == 0))
		{
			found = 1;
			break;
		}
		devNodePtr = devNodePtr->next;
	}

	if (found)
	{
		// Update the advertisement timeout field
//		DBGPRINTF(RT_DBG_INFO, "Old device, just update the expires!\n");
		devNodePtr->device.AdvrTimeOut = d_event->Expires;
		devNodePtr->device.timeCount = 0;
	} else {
		DBGPRINTF(RT_DBG_INFO, "Adver from a new device!\n");
		if((ret = UpnpDownloadXmlDoc(d_event->Location, &DescDoc)) != UPNP_E_SUCCESS){
			DBGPRINTF(RT_DBG_ERROR, "Get device description failed from %s -- err=%d\n", d_event->Location, ret);
			goto done;
		}

		/* Read key elements from description document */
		UDN = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN");
		deviceTypeStr = SampleUtil_GetFirstDocumentItem(DescDoc, "deviceType");
		friendlyName = SampleUtil_GetFirstDocumentItem(DescDoc, "friendlyName");
		baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase");
		relURL = SampleUtil_GetFirstDocumentItem(DescDoc, "presentationURL");

		if((UDN == NULL) || (deviceTypeStr == NULL) || (friendlyName == NULL))
		{
			DBGPRINTF(RT_DBG_ERROR, "%s(): Get UDN failed!\n", __FUNCTION__);
			goto done;
		}
		UpnpResolveURL((baseURL ? baseURL : d_event->Location), relURL, presURL);
	
		if (SampleUtil_FindAndParseService(DescDoc, d_event->Location, WscServiceTypeStr,
											&serviceId, &SCPDURL, &eventURL,&controlURL))
		{
			if (SCPDURL != NULL)
			{	
				if ((ret = UpnpDownloadXmlDoc(SCPDURL, &scpdDescDoc)) != UPNP_E_SUCCESS)
				{
					DBGPRINTF(RT_DBG_ERROR, "Get service description failed from %s -- err=%d\n", SCPDURL, ret);
				} else {
					WscUPnPCPCheckService(scpdDescDoc);
					free(scpdDescDoc);
				}
			}

			if ((ret = UpnpSubscribe(WscCPHandle, eventURL, &TimeOut, eventSID)) != UPNP_E_SUCCESS)
			{
				DBGPRINTF(RT_DBG_ERROR, "Error Subscribing to EventURL(%s) -- %d\n", eventURL, ret);
				goto done;
			}
		
			/* Create a new device node */
			newDeviceNode = (struct upnpDeviceNode *)malloc(sizeof(struct upnpDeviceNode));
			if (newDeviceNode == NULL) {
				DBGPRINTF(RT_DBG_ERROR, "%s: create new wsc Device Node failed!\n", __FUNCTION__);
				goto done;
			}
			memset(newDeviceNode, 0, sizeof(newDeviceNode));
			newDeviceNode->device.services.StateVarVal[WSC_EVENT_WLANEVENT] = NULL;
			newDeviceNode->device.services.StateVarVal[WSC_EVENT_APSTATUS] = NULL;
			newDeviceNode->device.services.StateVarVal[WSC_EVENT_STASTATUS] = NULL;

			strncpy(newDeviceNode->device.UDN, UDN, NAME_SIZE-1);
			strncpy(newDeviceNode->device.DescDocURL, d_event->Location, NAME_SIZE-1);
			strncpy(newDeviceNode->device.FriendlyName, friendlyName, NAME_SIZE-1);
			strncpy(newDeviceNode->device.PresURL, presURL, NAME_SIZE-1);
			newDeviceNode->device.AdvrTimeOut = d_event->Expires;
			newDeviceNode->device.timeCount = 0;
			newDeviceNode->device.ipAddr = ipAddr;
			strncpy(newDeviceNode->device.services.ServiceType, WscServiceTypeStr, NAME_SIZE-1);
			if (serviceId)
				strncpy(newDeviceNode->device.services.ServiceId, serviceId, NAME_SIZE-1);
			if (SCPDURL)
				strncpy(newDeviceNode->device.services.SCPDURL, SCPDURL, NAME_SIZE-1);
			if (eventURL)
				strncpy(newDeviceNode->device.services.EventURL, eventURL, NAME_SIZE-1);
			if (controlURL)
				strncpy(newDeviceNode->device.services.ControlURL, controlURL, NAME_SIZE-1);
			if (eventSID)
				strncpy(newDeviceNode->device.services.SID, eventSID, NAME_SIZE-1);

			newDeviceNode->next = NULL;
#if 0
			for (var = 0; var < WSC_STATE_VAR_COUNT; var++)
			{
				deviceNode->device.services.serviceList.stateVarVals[var] = (char *)malloc(WSC_STATE_VAR_MAX_STR_LEN);
				strcpy(deviceNode->device.services.serviceList.stateVarVals[var], "");
			}
#endif
			// Insert the new device node in the list
			if(WscDeviceList)
			{
				newDeviceNode->next = WscDeviceList->next;
				WscDeviceList->next = newDeviceNode;
			} else {
				WscDeviceList = newDeviceNode;
			}

			ret = WSC_SYS_SUCCESS;

			// TODO:Notify New Device Added
			//WscCPDevUpdate(NULL, NULL, deviceNode->device.UDN, DEVICE_ADDED);
		} else {
			DBGPRINTF(RT_DBG_ERROR, "Error: Could not find Service: %s\n", WscServiceTypeStr);
		}
	}

done:
	if (DescDoc)
		ixmlDocument_free(DescDoc);
			
	if (UDN)
		free(UDN);
	if (deviceTypeStr)
		free(deviceTypeStr);
    if (friendlyName)
		free(friendlyName);
	if (baseURL)
		free(baseURL);
	if (relURL)
		free(relURL);

	if (serviceId)
		free(serviceId);
	if (controlURL)
		free(controlURL);
	if (eventURL)
		free(eventURL);

	return ret;
}