Exemple #1
0
void TvCtrlPointPrintLongHelp(void)
{
	SampleUtil_Print(
		"\n"
		"******************************\n"
		"* TV Control Point Help Info *\n"
		"******************************\n"
		"\n"
		"This sample control point application automatically searches\n"
		"for and subscribes to the services of television device emulator\n"
		"devices, described in the tvdevicedesc.xml description document.\n"
		"It also registers itself as a tv device.\n"
		"\n"
		"Commands:\n"
		"  Help\n"
		"       Print this help info.\n"
		"  ListDev\n"
		"       Print the current list of TV Device Emulators that this\n"
		"         control point is aware of.  Each device is preceded by a\n"
		"         device number which corresponds to the devnum argument of\n"
		"         commands listed below.\n"
		"  Refresh\n"
		"       Delete all of the devices from the device list and issue new\n"
		"         search request to rebuild the list from scratch.\n"
		"  PrintDev       <devnum>\n"
		"       Print the state table for the device <devnum>.\n"
		"         e.g., 'PrintDev 1' prints the state table for the first\n"
		"         device in the device list.\n"
		"  PowerOn        <devnum>\n"
		"       Sends the PowerOn action to the Control Service of\n"
		"         device <devnum>.\n"
		"  PowerOff       <devnum>\n"
		"       Sends the PowerOff action to the Control Service of\n"
		"         device <devnum>.\n"
		"  SetChannel     <devnum> <channel>\n"
		"       Sends the SetChannel action to the Control Service of\n"
		"         device <devnum>, requesting the channel to be changed\n"
		"         to <channel>.\n"
		"  SetVolume      <devnum> <volume>\n"
		"       Sends the SetVolume action to the Control Service of\n"
		"         device <devnum>, requesting the volume to be changed\n"
		"         to <volume>.\n"
		"  SetColor       <devnum> <color>\n"
		"       Sends the SetColor action to the Control Service of\n"
		"         device <devnum>, requesting the color to be changed\n"
		"         to <color>.\n"
		"  SetTint        <devnum> <tint>\n"
		"       Sends the SetTint action to the Control Service of\n"
		"         device <devnum>, requesting the tint to be changed\n"
		"         to <tint>.\n"
		"  SetContrast    <devnum> <contrast>\n"
		"       Sends the SetContrast action to the Control Service of\n"
		"         device <devnum>, requesting the contrast to be changed\n"
		"         to <contrast>.\n"
		"  SetBrightness  <devnum> <brightness>\n"
		"       Sends the SetBrightness action to the Control Service of\n"
		"         device <devnum>, requesting the brightness to be changed\n"
		"         to <brightness>.\n"
		"  CtrlAction     <devnum> <action>\n"
		"       Sends an action request specified by the string <action>\n"
		"         to the Control Service of device <devnum>.  This command\n"
		"         only works for actions that have no arguments.\n"
		"         (e.g., \"CtrlAction 1 IncreaseChannel\")\n"
		"  PictAction     <devnum> <action>\n"
		"       Sends an action request specified by the string <action>\n"
		"         to the Picture Service of device <devnum>.  This command\n"
		"         only works for actions that have no arguments.\n"
		"         (e.g., \"PictAction 1 DecreaseContrast\")\n"
		"  CtrlGetVar     <devnum> <varname>\n"
		"       Requests the value of a variable specified by the string <varname>\n"
		"         from the Control Service of device <devnum>.\n"
		"         (e.g., \"CtrlGetVar 1 Volume\")\n"
		"  PictGetVar     <devnum> <action>\n"
		"       Requests the value of a variable specified by the string <varname>\n"
		"         from the Picture Service of device <devnum>.\n"
		"         (e.g., \"PictGetVar 1 Tint\")\n"
		"  Exit\n"
		"       Exits the control point application.\n");
}
Exemple #2
0
int TvCtrlPointProcessCommand(char *cmdline)
{
	char cmd[100];
	char strarg[100];
	int arg_val_err = -99999;
	int arg1 = arg_val_err;
	int arg2 = arg_val_err;
	int cmdnum = -1;
	int numofcmds = (sizeof cmdloop_cmdlist) / sizeof (cmdloop_commands);
	int cmdfound = 0;
	int i;
	int rc;
	int invalidargs = 0;
	int validargs;

	validargs = sscanf(cmdline, "%s %d %d", cmd, &arg1, &arg2);
	for (i = 0; i < numofcmds; ++i) {
		if (strcasecmp(cmd, cmdloop_cmdlist[i].str ) == 0) {
			cmdnum = cmdloop_cmdlist[i].cmdnum;
			cmdfound++;
			if (validargs != cmdloop_cmdlist[i].numargs)
				invalidargs++;
			break;
		}
	}
	if (!cmdfound) {
		SampleUtil_Print("Command not found; try 'Help'\n");
		return TV_SUCCESS;
	}
	if (invalidargs) {
		SampleUtil_Print("Invalid arguments; try 'Help'\n");
		return TV_SUCCESS;
	}
	switch (cmdnum) {
	case PRTHELP:
		TvCtrlPointPrintShortHelp();
		break;
	case PRTFULLHELP:
		TvCtrlPointPrintLongHelp();
		break;
	case POWON:
		TvCtrlPointSendPowerOn(arg1);
		break;
	case POWOFF:
		TvCtrlPointSendPowerOff(arg1);
		break;
	case SETCHAN:
		TvCtrlPointSendSetChannel(arg1, arg2);
		break;
	case SETVOL:
		TvCtrlPointSendSetVolume(arg1, arg2);
		break;
	case SETCOL:
		TvCtrlPointSendSetColor(arg1, arg2);
		break;
	case SETTINT:
		TvCtrlPointSendSetTint(arg1, arg2);
		break;
	case SETCONT:
		TvCtrlPointSendSetContrast(arg1, arg2);
		break;
	case SETBRT:
		TvCtrlPointSendSetBrightness(arg1, arg2);
		break;
	case CTRLACTION:
		/* re-parse commandline since second arg is string. */
		validargs = sscanf(cmdline, "%s %d %s", cmd, &arg1, strarg);
		if (validargs == 3)
			TvCtrlPointSendAction(TV_SERVICE_CONTROL, arg1, strarg,
				NULL, NULL, 0);
		else
			invalidargs++;
		break;
	case PICTACTION:
		/* re-parse commandline since second arg is string. */
		validargs = sscanf(cmdline, "%s %d %s", cmd, &arg1, strarg);
		if (validargs == 3)
			TvCtrlPointSendAction(TV_SERVICE_PICTURE, arg1, strarg,
				NULL, NULL, 0);
		else
			invalidargs++;
		break;
	case CTRLGETVAR:
		/* re-parse commandline since second arg is string. */
		validargs = sscanf(cmdline, "%s %d %s", cmd, &arg1, strarg);
		if (validargs == 3)
			TvCtrlPointGetVar(TV_SERVICE_CONTROL, arg1, strarg);
		else
			invalidargs++;
		break;
	case PICTGETVAR:
		/* re-parse commandline since second arg is string. */
		validargs = sscanf(cmdline, "%s %d %s", cmd, &arg1, strarg);
		if (validargs == 3)
			TvCtrlPointGetVar(TV_SERVICE_PICTURE, arg1, strarg);
		else
			invalidargs++;
		break;
	case PRTDEV:
		TvCtrlPointPrintDevice(arg1);
		break;
	case LSTDEV:
		TvCtrlPointPrintList();
		break;
	case REFRESH:
		TvCtrlPointRefresh();
		break;
	case EXITCMD:
		rc = TvCtrlPointStop();
		exit(rc);
		break;
	default:
		SampleUtil_Print("Command not implemented; see 'Help'\n");
		break;
	}
	if(invalidargs)
		SampleUtil_Print("Invalid args in command; see 'Help'\n");

	return TV_SUCCESS;
}
Exemple #3
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 */
	//Debug	
//	SampleUtil_Print("DescDocURL: %s, Servid_ctrl %s, evnturl_ctrl %s, ctrlurl_ctrl %s\n",
//				 DescDocURL,servid_ctrl, evnturl_ctrl, ctrlurl_ctrl);
	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);
}
Exemple #4
0
/********************************************************************************
 * TvCtrlPointCallbackEventHandler
 *
 * Description: 
 *       The callback handler registered with the SDK while registering
 *       the control point.  Detects the type of callback, and passes the 
 *       request on to the appropriate function.
 *
 * Parameters:
 *   EventType -- The type of callback event
 *   Event -- Data structure containing event data
 *   Cookie -- Optional data specified during callback registration
 *
 ********************************************************************************/
int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, const void *Event, void *Cookie)
{
	int errCode = 0;

	SampleUtil_PrintEvent(EventType, Event);
	switch ( EventType ) {
	/* SSDP Stuff */
	case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
	case UPNP_DISCOVERY_SEARCH_RESULT: {
		const UpnpDiscovery *d_event = (UpnpDiscovery *)Event;
		IXML_Document *DescDoc = NULL;
		const char *location = NULL;
		int errCode = UpnpDiscovery_get_ErrCode(d_event);

		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print(
				"Error in Discovery Callback -- %d\n", errCode);
		}

		location = UpnpString_get_String(UpnpDiscovery_get_Location(d_event));
		errCode = UpnpDownloadXmlDoc(location, &DescDoc);
		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print(
				"Error obtaining device description from %s -- error = %d\n",
				location, errCode);
		} else {
			TvCtrlPointAddDevice(
				DescDoc, location, UpnpDiscovery_get_Expires(d_event));
		}
		if (DescDoc) {
			ixmlDocument_free(DescDoc);
		}
		TvCtrlPointPrintList();
		break;
	}
	case UPNP_DISCOVERY_SEARCH_TIMEOUT:
		/* Nothing to do here... */
		break;
	case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE: {
		UpnpDiscovery *d_event = (UpnpDiscovery *)Event;
		int errCode = UpnpDiscovery_get_ErrCode(d_event);
		const char *deviceId = UpnpString_get_String(
		UpnpDiscovery_get_DeviceID(d_event));

		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print(
				"Error in Discovery ByeBye Callback -- %d\n", errCode);
		}
		SampleUtil_Print("Received ByeBye for Device: %s\n", deviceId);
		TvCtrlPointRemoveDevice(deviceId);
		SampleUtil_Print("After byebye:\n");
		TvCtrlPointPrintList();
		break;
	}
	/* SOAP Stuff */
	case UPNP_CONTROL_ACTION_COMPLETE: {
		UpnpActionComplete *a_event = (UpnpActionComplete *)Event;
		int errCode = UpnpActionComplete_get_ErrCode(a_event);
		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print("Error in  Action Complete Callback -- %d\n",
				errCode);
		}
		/* No need for any processing here, just print out results.
		 * Service state table updates are handled by events. */
		break;
	}
	case UPNP_CONTROL_GET_VAR_COMPLETE: {
		UpnpStateVarComplete *sv_event = (UpnpStateVarComplete *)Event;
		int errCode = UpnpStateVarComplete_get_ErrCode(sv_event);
		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print(
				"Error in Get Var Complete Callback -- %d\n", errCode);
		} else {
			TvCtrlPointHandleGetVar(
				UpnpString_get_String(UpnpStateVarComplete_get_CtrlUrl(sv_event)),
				UpnpString_get_String(UpnpStateVarComplete_get_StateVarName(sv_event)),
				UpnpStateVarComplete_get_CurrentVal(sv_event));
		}
		break;
	}
	/* GENA Stuff */
	case UPNP_EVENT_RECEIVED: {
		UpnpEvent *e_event = (UpnpEvent *)Event;
		TvCtrlPointHandleEvent(
			UpnpEvent_get_SID_cstr(e_event),
			UpnpEvent_get_EventKey(e_event),
			UpnpEvent_get_ChangedVariables(e_event));
		break;
	}
	case UPNP_EVENT_SUBSCRIBE_COMPLETE:
	case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
	case UPNP_EVENT_RENEWAL_COMPLETE: {
		UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event;

		errCode = UpnpEventSubscribe_get_ErrCode(es_event);
		if (errCode != UPNP_E_SUCCESS) {
			SampleUtil_Print(
				"Error in Event Subscribe Callback -- %d\n", errCode);
		} else {
			TvCtrlPointHandleSubscribeUpdate(
				UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)),
				UpnpString_get_String(UpnpEventSubscribe_get_SID(es_event)),
				UpnpEventSubscribe_get_TimeOut(es_event));
		}
		break;
	}
	case UPNP_EVENT_AUTORENEWAL_FAILED:
	case UPNP_EVENT_SUBSCRIPTION_EXPIRED: {
		UpnpEventSubscribe *es_event = (UpnpEventSubscribe *)Event;
		int TimeOut = default_timeout;
		Upnp_SID newSID;

		errCode = UpnpSubscribe(
			ctrlpt_handle,
			UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)),
			&TimeOut,
			newSID);
		if (errCode == UPNP_E_SUCCESS) {
			SampleUtil_Print("Subscribed to EventURL with SID=%s\n", newSID);
			TvCtrlPointHandleSubscribeUpdate(
				UpnpString_get_String(UpnpEventSubscribe_get_PublisherUrl(es_event)),
				newSID,
				TimeOut);
		} else {
			SampleUtil_Print("Error Subscribing to EventURL -- %d\n", errCode);
		}
		break;
	}
	/* ignore these cases, since this is not a device */
	case UPNP_EVENT_SUBSCRIPTION_REQUEST:
	case UPNP_CONTROL_GET_VAR_REQUEST:
	case UPNP_CONTROL_ACTION_REQUEST:
		break;
	}

	return 0;
	Cookie = Cookie;
}
int SampleUtil_FindAndParseService(IXML_Document *DescDoc, const char *location,
	const char *serviceType, char **serviceId, char **eventURL, char **controlURL)
{
	unsigned int i;
	unsigned long length;
	int found = 0;
	int ret;
#ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
	unsigned int sindex = 0;
#endif /* OLD_FIND_SERVICE_CODE */
	char *tempServiceType = NULL;
	char *baseURL = NULL;
	const char *base = NULL;
	char *relcontrolURL = NULL;
	char *releventURL = NULL;
	IXML_NodeList *serviceList = NULL;
	IXML_Element *service = NULL;

	baseURL = SampleUtil_GetFirstDocumentItem(DescDoc, "URLBase");
	if (baseURL)
		base = baseURL;
	else
		base = location;
#ifdef OLD_FIND_SERVICE_CODE
	serviceList = SampleUtil_GetFirstServiceList(DescDoc);
#else /* OLD_FIND_SERVICE_CODE */
	for (sindex = 0;
	     (serviceList = SampleUtil_GetNthServiceList(DescDoc , sindex)) != NULL;
	     sindex++) {
		tempServiceType = NULL;
		relcontrolURL = NULL;
		releventURL = NULL;
		service = NULL;
#endif /* OLD_FIND_SERVICE_CODE */
		length = ixmlNodeList_length(serviceList);
		for (i = 0; i < length; i++) {
			service = (IXML_Element *)ixmlNodeList_item(serviceList, i);
			tempServiceType = SampleUtil_GetFirstElementItem(
				(IXML_Element *)service, "serviceType");
			if (tempServiceType && strcmp(tempServiceType, serviceType) == 0) {
				SampleUtil_Print("Found service: %s\n", serviceType);
				*serviceId = SampleUtil_GetFirstElementItem(service, "serviceId");
				SampleUtil_Print("serviceId: %s\n", *serviceId);
				relcontrolURL = SampleUtil_GetFirstElementItem(service, "controlURL");
				releventURL = SampleUtil_GetFirstElementItem(service, "eventSubURL");
				*controlURL = (char *)malloc(strlen(base) + strlen(relcontrolURL) + 1);
				if (*controlURL) {
					ret = UpnpResolveURL(base, relcontrolURL, *controlURL);
					if (ret != UPNP_E_SUCCESS)
						SampleUtil_Print("Error generating controlURL from %s + %s\n",
							base, relcontrolURL);
				}
				*eventURL = (char *)malloc(strlen(base) + strlen(releventURL) + 1);
				if (*eventURL) {
					ret = UpnpResolveURL(base, releventURL, *eventURL);
					if (ret != UPNP_E_SUCCESS)
						SampleUtil_Print("Error generating eventURL from %s + %s\n",
							base, releventURL);
				}
				free(relcontrolURL);
				free(releventURL);
				relcontrolURL = NULL;
				releventURL = NULL;
				found = 1;
				break;
			}
			free(tempServiceType);
			tempServiceType = NULL;
		}
		free(tempServiceType);
		tempServiceType = NULL;
		if (serviceList)
			ixmlNodeList_free(serviceList);
		serviceList = NULL;
#ifdef OLD_FIND_SERVICE_CODE
#else /* OLD_FIND_SERVICE_CODE */
	}
#endif /* OLD_FIND_SERVICE_CODE */
	free(baseURL);

	return found;
}
Exemple #6
0
int TvDeviceStart(char *ip_address, unsigned short port,
		  const char *desc_doc_name, const char *web_dir_path,
		  print_string pfun, int combo)
{
	int ret = UPNP_E_SUCCESS;
	char desc_doc_url[DESC_URL_SIZE];

	ithread_mutex_init(&TVDevMutex, NULL);

	SampleUtil_Initialize(pfun);
	SampleUtil_Print("Initializing UPnP Sdk with\n"
			 "\tipaddress = %s port = %u\n",
			 ip_address ? ip_address : "{NULL}", port);
	ret = UpnpInit(ip_address, port);
	if (ret != UPNP_E_SUCCESS) {
		SampleUtil_Print("Error with UpnpInit -- %d\n", ret);
		UpnpFinish();

		return ret;
	}
	ip_address = UpnpGetServerIpAddress();
	port = UpnpGetServerPort();
	SampleUtil_Print("UPnP Initialized\n"
			 "\tipaddress = %s port = %u\n",
			 ip_address ? ip_address : "{NULL}", port);
	if (!desc_doc_name) {
		if (combo) {
			desc_doc_name = "tvcombodesc.xml";
		} else {
			desc_doc_name = "tvdevicedesc.xml";
		}
	}
	if (!web_dir_path) {
		web_dir_path = DEFAULT_WEB_DIR;
	}
	snprintf(desc_doc_url, DESC_URL_SIZE, "http://%s:%d/%s", ip_address,
		 port, desc_doc_name);
	SampleUtil_Print("Specifying the webserver root directory -- %s\n",
			 web_dir_path);
	ret = UpnpSetWebServerRootDir(web_dir_path);
	if (ret != UPNP_E_SUCCESS) {
		SampleUtil_Print
		    ("Error specifying webserver root directory -- %s: %d\n",
		     web_dir_path, ret);
		UpnpFinish();

		return ret;
	}
	SampleUtil_Print("Registering the RootDevice\n"
			 "\t with desc_doc_url: %s\n", desc_doc_url);
	ret = UpnpRegisterRootDevice(desc_doc_url, TvDeviceCallbackEventHandler,
				     &device_handle, &device_handle);
	if (ret != UPNP_E_SUCCESS) {
		SampleUtil_Print("Error registering the rootdevice : %d\n",
				 ret);
		UpnpFinish();

		return ret;
	} else {
		SampleUtil_Print("RootDevice Registered\n"
				 "Initializing State Table\n");
		//Debug
		SampleUtil_Print("Descurl is %s\n",desc_doc_url);
		TvDeviceStateTableInit(desc_doc_url);
		SampleUtil_Print("State Table Initialized\n");
		ret = UpnpSendAdvertisement(device_handle, default_advr_expire);
		if (ret != UPNP_E_SUCCESS) {
			SampleUtil_Print("Error sending advertisements : %d\n",
					 ret);
			UpnpFinish();

			return ret;
		}
		SampleUtil_Print("Advertisements Sent\n");
	}

	return UPNP_E_SUCCESS;
}
void SampleUtil_PrintEventType(Upnp_EventType S)
{
	switch (S) {
	/* Discovery */
	case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
		SampleUtil_Print("UPNP_DISCOVERY_ADVERTISEMENT_ALIVE\n");
		break;
	case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
		SampleUtil_Print("UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE\n");
		break;
	case UPNP_DISCOVERY_SEARCH_RESULT:
		SampleUtil_Print( "UPNP_DISCOVERY_SEARCH_RESULT\n");
		break;
	case UPNP_DISCOVERY_SEARCH_TIMEOUT:
		SampleUtil_Print( "UPNP_DISCOVERY_SEARCH_TIMEOUT\n");
		break;
	/* SOAP */
	case UPNP_CONTROL_ACTION_REQUEST:
		SampleUtil_Print("UPNP_CONTROL_ACTION_REQUEST\n");
		break;
	case UPNP_CONTROL_ACTION_COMPLETE:
		SampleUtil_Print("UPNP_CONTROL_ACTION_COMPLETE\n");
		break;
	case UPNP_CONTROL_GET_VAR_REQUEST:
		SampleUtil_Print("UPNP_CONTROL_GET_VAR_REQUEST\n");
		break;
	case UPNP_CONTROL_GET_VAR_COMPLETE:
		SampleUtil_Print("UPNP_CONTROL_GET_VAR_COMPLETE\n");
		break;
	/* GENA */
	case UPNP_EVENT_SUBSCRIPTION_REQUEST:
		SampleUtil_Print("UPNP_EVENT_SUBSCRIPTION_REQUEST\n");
		break;
	case UPNP_EVENT_RECEIVED:
		SampleUtil_Print("UPNP_EVENT_RECEIVED\n");
		break;
	case UPNP_EVENT_RENEWAL_COMPLETE:
		SampleUtil_Print("UPNP_EVENT_RENEWAL_COMPLETE\n");
		break;
	case UPNP_EVENT_SUBSCRIBE_COMPLETE:
		SampleUtil_Print("UPNP_EVENT_SUBSCRIBE_COMPLETE\n");
		break;
	case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
		SampleUtil_Print("UPNP_EVENT_UNSUBSCRIBE_COMPLETE\n");
		break;
	case UPNP_EVENT_AUTORENEWAL_FAILED:
		SampleUtil_Print("UPNP_EVENT_AUTORENEWAL_FAILED\n");
		break;
	case UPNP_EVENT_SUBSCRIPTION_EXPIRED:
		SampleUtil_Print("UPNP_EVENT_SUBSCRIPTION_EXPIRED\n");
		break;
	}
}
int SampleUtil_PrintEvent(Upnp_EventType EventType, void *Event)
{
	ithread_mutex_lock(&display_mutex);

	SampleUtil_Print(
		"======================================================================\n"
		"----------------------------------------------------------------------\n");
	SampleUtil_PrintEventType(EventType);
	switch (EventType) {
	/* SSDP */
	case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
	case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
	case UPNP_DISCOVERY_SEARCH_RESULT: {
		struct Upnp_Discovery *d_event = (struct Upnp_Discovery *)Event;

		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(d_event->ErrCode), d_event->ErrCode);
		SampleUtil_Print("Expires     =  %d\n",  d_event->Expires);
		SampleUtil_Print("DeviceId    =  %s\n",  d_event->DeviceId);
		SampleUtil_Print("DeviceType  =  %s\n",  d_event->DeviceType);
		SampleUtil_Print("ServiceType =  %s\n",  d_event->ServiceType);
		SampleUtil_Print("ServiceVer  =  %s\n",  d_event->ServiceVer);
		SampleUtil_Print("Location    =  %s\n",  d_event->Location);
		SampleUtil_Print("OS          =  %s\n",  d_event->Os);
		SampleUtil_Print("Ext         =  %s\n",  d_event->Ext);
		break;
	}
	case UPNP_DISCOVERY_SEARCH_TIMEOUT:
		/* Nothing to print out here */
		break;
	/* SOAP */
	case UPNP_CONTROL_ACTION_REQUEST: {
		struct Upnp_Action_Request *a_event =
			(struct Upnp_Action_Request *)Event;
		char *xmlbuff = NULL;

		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(a_event->ErrCode), a_event->ErrCode);
		SampleUtil_Print("ErrStr      =  %s\n", a_event->ErrStr);
		SampleUtil_Print("ActionName  =  %s\n", a_event->ActionName);
		SampleUtil_Print("UDN         =  %s\n", a_event->DevUDN);
		SampleUtil_Print("ServiceID   =  %s\n", a_event->ServiceID);
		if (a_event->ActionRequest) {
			xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest);
			if (xmlbuff) {
				SampleUtil_Print("ActRequest  =  %s\n", xmlbuff);
				ixmlFreeDOMString(xmlbuff);
			}
			xmlbuff = NULL;
		} else {
			SampleUtil_Print("ActRequest  =  (null)\n");
		}
		if (a_event->ActionResult) {
			xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionResult);
			if (xmlbuff) {
				SampleUtil_Print("ActResult   =  %s\n", xmlbuff);
				ixmlFreeDOMString(xmlbuff);
			}
			xmlbuff = NULL;
		} else {
			SampleUtil_Print("ActResult   =  (null)\n");
		}
		break;
	}
	case UPNP_CONTROL_ACTION_COMPLETE: {
		struct Upnp_Action_Complete *a_event =
			(struct Upnp_Action_Complete *)Event;
		char *xmlbuff = NULL;

		SampleUtil_Print("ErrCode     =  %s(%d)\n",  
			UpnpGetErrorMessage(a_event->ErrCode), a_event->ErrCode);
		SampleUtil_Print("CtrlUrl     =  %s\n", a_event->CtrlUrl);
		if (a_event->ActionRequest) {
			xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionRequest);
			if (xmlbuff) {
				SampleUtil_Print("ActRequest  =  %s\n", xmlbuff);
				ixmlFreeDOMString(xmlbuff);
			}
			xmlbuff = NULL;
		} else {
			SampleUtil_Print("ActRequest  =  (null)\n");
		}
		if (a_event->ActionResult) {
			xmlbuff = ixmlPrintNode((IXML_Node *)a_event->ActionResult);
			if (xmlbuff) {
				SampleUtil_Print("ActResult   =  %s\n", xmlbuff);
				ixmlFreeDOMString(xmlbuff);
			}
			xmlbuff = NULL;
		} else {
			SampleUtil_Print("ActResult   =  (null)\n");
		}
		break;
	}
	case UPNP_CONTROL_GET_VAR_REQUEST: {
		struct Upnp_State_Var_Request *sv_event =
			(struct Upnp_State_Var_Request *)Event;

		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(sv_event->ErrCode), sv_event->ErrCode);
		SampleUtil_Print("ErrStr      =  %s\n", sv_event->ErrStr);
		SampleUtil_Print("UDN         =  %s\n", sv_event->DevUDN);
		SampleUtil_Print("ServiceID   =  %s\n", sv_event->ServiceID);
		SampleUtil_Print("StateVarName=  %s\n", sv_event->StateVarName);
		SampleUtil_Print("CurrentVal  =  %s\n", sv_event->CurrentVal);
		break;
	}
	case UPNP_CONTROL_GET_VAR_COMPLETE: {
		struct Upnp_State_Var_Complete *sv_event =
			(struct Upnp_State_Var_Complete *)Event;

		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(sv_event->ErrCode), sv_event->ErrCode);
		SampleUtil_Print("CtrlUrl     =  %s\n", sv_event->CtrlUrl);
		SampleUtil_Print("StateVarName=  %s\n", sv_event->StateVarName);
		SampleUtil_Print("CurrentVal  =  %s\n", sv_event->CurrentVal);
		break;
	}
	/* GENA */
	case UPNP_EVENT_SUBSCRIPTION_REQUEST: {
		struct Upnp_Subscription_Request *sr_event =
			(struct Upnp_Subscription_Request *)Event;

		SampleUtil_Print("ServiceID   =  %s\n", sr_event->ServiceId);
		SampleUtil_Print("UDN         =  %s\n", sr_event->UDN);
		SampleUtil_Print("SID         =  %s\n", sr_event->Sid);
		break;
	}
	case UPNP_EVENT_RECEIVED: {
		struct Upnp_Event *e_event = (struct Upnp_Event *)Event;
		char *xmlbuff = NULL;

		SampleUtil_Print("SID         =  %s\n", e_event->Sid);
		SampleUtil_Print("EventKey    =  %d\n",	e_event->EventKey);
		xmlbuff = ixmlPrintNode((IXML_Node *)e_event->ChangedVariables);
		SampleUtil_Print("ChangedVars =  %s\n", xmlbuff);
		ixmlFreeDOMString(xmlbuff);
		xmlbuff = NULL;
		break;
	}
	case UPNP_EVENT_RENEWAL_COMPLETE: {
		struct Upnp_Event_Subscribe *es_event =
			(struct Upnp_Event_Subscribe *)Event;

		SampleUtil_Print("SID         =  %s\n", es_event->Sid);
		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
		SampleUtil_Print("TimeOut     =  %d\n", es_event->TimeOut);
		break;
	}
	case UPNP_EVENT_SUBSCRIBE_COMPLETE:
	case UPNP_EVENT_UNSUBSCRIBE_COMPLETE: {
		struct Upnp_Event_Subscribe *es_event =
			(struct Upnp_Event_Subscribe *)Event;

		SampleUtil_Print("SID         =  %s\n", es_event->Sid);
		SampleUtil_Print("ErrCode     =  %s(%d)\n",
			UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
		SampleUtil_Print("PublisherURL=  %s\n", es_event->PublisherUrl);
		SampleUtil_Print("TimeOut     =  %d\n", es_event->TimeOut);
		break;
	}
	case UPNP_EVENT_AUTORENEWAL_FAILED:
	case UPNP_EVENT_SUBSCRIPTION_EXPIRED: {
		struct Upnp_Event_Subscribe *es_event =
			(struct Upnp_Event_Subscribe *)Event;

		SampleUtil_Print("SID         =  %s\n", es_event->Sid);
		SampleUtil_Print("ErrCode     =  %s(%d)\n",  
			UpnpGetErrorMessage(es_event->ErrCode), es_event->ErrCode);
		SampleUtil_Print("PublisherURL=  %s\n", es_event->PublisherUrl);
		SampleUtil_Print("TimeOut     =  %d\n", es_event->TimeOut);
		break;
	}
	}
	SampleUtil_Print(
		"----------------------------------------------------------------------\n"
		"======================================================================\n"
		"\n\n\n");

	ithread_mutex_unlock(&display_mutex);

	return 0;
}
Exemple #9
0
/********************************************************************************
 * TvStateUpdate
 *
 * Description: 
 *       Update a Tv state table.  Called when an event is
 *       received.  Note: this function is NOT thread save.  It must be
 *       called from another function that has locked the global device list.
 *
 * Parameters:
 *   UDN     -- The UDN of the parent device.
 *   Service -- The service state table to update
 *   ChangedVariables -- DOM document representing the XML received
 *                       with the event
 *   State -- pointer to the state table for the Tv  service
 *            to update
 *
 ********************************************************************************/
void
TvStateUpdate( char *UDN,
               int Service,
               IXML_Document * ChangedVariables,
               char **State )
{
    IXML_NodeList *properties,
     *variables;
    IXML_Element *property,
     *variable;
    int length,
      length1;
    int i,
      j;
    char *tmpstate = NULL;

    SampleUtil_Print( "Tv State Update (service %d): ", Service );

    /*
       Find all of the e:property tags in the document 
     */
    properties =
        ixmlDocument_getElementsByTagName( ChangedVariables,
                                           "e:property" );
    if( NULL != properties ) {
        length = ixmlNodeList_length( properties );
        for( i = 0; i < length; i++ ) { /* Loop through each property change found */
            property =
                ( IXML_Element * ) ixmlNodeList_item( properties, i );

            /*
               For each variable name in the state table, check if this
               is a corresponding property change 
             */
            for( j = 0; j < TvVarCount[Service]; j++ ) {
                variables =
                    ixmlElement_getElementsByTagName( property,
                                                      TvVarName[Service]
                                                      [j] );

                /*
                   If a match is found, extract the value, and update the state table 
                 */
                if( variables ) {
                    length1 = ixmlNodeList_length( variables );
                    if( length1 ) {
                        variable =
                            ( IXML_Element * )
                            ixmlNodeList_item( variables, 0 );
                        tmpstate = SampleUtil_GetElementValue( variable );

                        if( tmpstate ) {
                            strcpy( State[j], tmpstate );
                            SampleUtil_Print
                                ( " Variable Name: %s New Value:'%s'",
                                  TvVarName[Service][j], State[j] );
                        }

                        if( tmpstate )
                            free( tmpstate );
                        tmpstate = NULL;
                    }

                    ixmlNodeList_free( variables );
                    variables = NULL;
                }
            }

        }
        ixmlNodeList_free( properties );
    }
}
Exemple #10
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,
                      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,
      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", baseURL,
                          relURL );

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

        // 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...",
                                      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",
                              eventSID[service] );
                    } else {
                        SampleUtil_Print
                            ( "Error Subscribing to EventURL -- %d", ret );
                        strcpy( eventSID[service], "" );
                    }
                } else {
                    SampleUtil_Print( "Error: Could not find Service: %s",
                                      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] );
    }
}
Exemple #11
0
/********************************************************************************
 * TvCtrlPointPrintDevice
 *
 * Description: 
 *       Print the identifiers and state table for a device from
 *       the global device list.
 *
 * Parameters:
 *   devnum -- The number of the device (order in the list,
 *             starting with 1)
 *
 ********************************************************************************/
int
TvCtrlPointPrintDevice( int devnum )
{
    struct TvDeviceNode *tmpdevnode;
    int i = 0,
      service,
      var;
    char spacer[15];

    if( devnum <= 0 ) {
        SampleUtil_Print
            ( "Error in TvCtrlPointPrintDevice: invalid devnum = %d",
              devnum );
        return TV_ERROR;
    }

    ithread_mutex_lock( &DeviceListMutex );

    SampleUtil_Print( "TvCtrlPointPrintDevice:" );
    tmpdevnode = GlobalDeviceList;
    while( tmpdevnode ) {
        i++;
        if( i == devnum )
            break;
        tmpdevnode = tmpdevnode->next;
    }

    if( !tmpdevnode ) {
        SampleUtil_Print
            ( "Error in TvCtrlPointPrintDevice: invalid devnum = %d  --  actual device count = %d",
              devnum, i );
    } else {
        SampleUtil_Print( "  TvDevice -- %d", devnum );
        SampleUtil_Print( "    |                  " );
        SampleUtil_Print( "    +- UDN        = %s",
                          tmpdevnode->device.UDN );
        SampleUtil_Print( "    +- DescDocURL     = %s",
                          tmpdevnode->device.DescDocURL );
        SampleUtil_Print( "    +- FriendlyName   = %s",
                          tmpdevnode->device.FriendlyName );
        SampleUtil_Print( "    +- PresURL        = %s",
                          tmpdevnode->device.PresURL );
        SampleUtil_Print( "    +- Adver. TimeOut = %d",
                          tmpdevnode->device.AdvrTimeOut );

        for( service = 0; service < TV_SERVICE_SERVCOUNT; service++ ) {
            if( service < TV_SERVICE_SERVCOUNT - 1 )
                sprintf( spacer, "    |    " );
            else
                sprintf( spacer, "         " );
            SampleUtil_Print( "    |                  " );
            SampleUtil_Print( "    +- Tv %s Service",
                              TvServiceName[service] );
            SampleUtil_Print( "%s+- ServiceId       = %s", spacer,
                              tmpdevnode->device.TvService[service].
                              ServiceId );
            SampleUtil_Print( "%s+- ServiceType     = %s", spacer,
                              tmpdevnode->device.TvService[service].
                              ServiceType );
            SampleUtil_Print( "%s+- EventURL        = %s", spacer,
                              tmpdevnode->device.TvService[service].
                              EventURL );
            SampleUtil_Print( "%s+- ControlURL      = %s", spacer,
                              tmpdevnode->device.TvService[service].
                              ControlURL );
            SampleUtil_Print( "%s+- SID             = %s", spacer,
                              tmpdevnode->device.TvService[service].SID );
            SampleUtil_Print( "%s+- ServiceStateTable", spacer );

            for( var = 0; var < TvVarCount[service]; var++ ) {
                SampleUtil_Print( "%s     +- %-10s = %s", spacer,
                                  TvVarName[service][var],
                                  tmpdevnode->device.TvService[service].
                                  VariableStrVal[var] );
            }
        }
    }

    SampleUtil_Print( "" );
    ithread_mutex_unlock( &DeviceListMutex );

    return TV_SUCCESS;
}
Exemple #12
0
/********************************************************************************
 * TvCtrlPointCallbackEventHandler
 *
 * Description: 
 *       The callback handler registered with the SDK while registering
 *       the control point.  Detects the type of callback, and passes the 
 *       request on to the appropriate function.
 *
 * Parameters:
 *   EventType -- The type of callback event
 *   Event -- Data structure containing event data
 *   Cookie -- Optional data specified during callback registration
 *
 ********************************************************************************/
int
TvCtrlPointCallbackEventHandler( Upnp_EventType EventType,
                                 void *Event,
                                 void *Cookie )
{
    SampleUtil_PrintEvent( EventType, Event );

    switch ( EventType ) {
            /*
               SSDP Stuff 
             */
        case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
        case UPNP_DISCOVERY_SEARCH_RESULT:
            {
                struct Upnp_Discovery *d_event =
                    ( struct Upnp_Discovery * )Event;
                IXML_Document *DescDoc = NULL;
                int ret;

                if( d_event->ErrCode != UPNP_E_SUCCESS ) {
                    SampleUtil_Print( "Error in Discovery Callback -- %d",
                                      d_event->ErrCode );
                }

                if( ( ret =
                      UpnpDownloadXmlDoc( d_event->Location,
                                          &DescDoc ) ) !=
                    UPNP_E_SUCCESS ) {
                    SampleUtil_Print
                        ( "Error obtaining device description from %s -- error = %d",
                          d_event->Location, ret );
                } else {
                    TvCtrlPointAddDevice( DescDoc, d_event->Location,
                                          d_event->Expires );
                }

                if( DescDoc )
                    ixmlDocument_free( DescDoc );

                TvCtrlPointPrintList(  );
                break;
            }

        case UPNP_DISCOVERY_SEARCH_TIMEOUT:
            /*
               Nothing to do here... 
             */
            break;

        case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
            {
                struct Upnp_Discovery *d_event =
                    ( struct Upnp_Discovery * )Event;

                if( d_event->ErrCode != UPNP_E_SUCCESS ) {
                    SampleUtil_Print
                        ( "Error in Discovery ByeBye Callback -- %d",
                          d_event->ErrCode );
                }

                SampleUtil_Print( "Received ByeBye for Device: %s",
                                  d_event->DeviceId );
                TvCtrlPointRemoveDevice( d_event->DeviceId );

                SampleUtil_Print( "After byebye:" );
                TvCtrlPointPrintList(  );

                break;
            }

            /*
               SOAP Stuff 
             */
        case UPNP_CONTROL_ACTION_COMPLETE:
            {
                struct Upnp_Action_Complete *a_event =
                    ( struct Upnp_Action_Complete * )Event;

                if( a_event->ErrCode != UPNP_E_SUCCESS ) {
                    SampleUtil_Print
                        ( "Error in  Action Complete Callback -- %d",
                          a_event->ErrCode );
                }

                /*
                   No need for any processing here, just print out results.  Service state
                   table updates are handled by events. 
                 */

                break;
            }

        case UPNP_CONTROL_GET_VAR_COMPLETE:
            {
                struct Upnp_State_Var_Complete *sv_event =
                    ( struct Upnp_State_Var_Complete * )Event;

                if( sv_event->ErrCode != UPNP_E_SUCCESS ) {
                    SampleUtil_Print
                        ( "Error in Get Var Complete Callback -- %d",
                          sv_event->ErrCode );
                } else {
                    TvCtrlPointHandleGetVar( sv_event->CtrlUrl,
                                             sv_event->StateVarName,
                                             sv_event->CurrentVal );
                }

                break;
            }

            /*
               GENA Stuff 
             */
        case UPNP_EVENT_RECEIVED:
            {
                struct Upnp_Event *e_event = ( struct Upnp_Event * )Event;

                TvCtrlPointHandleEvent( e_event->Sid, e_event->EventKey,
                                        e_event->ChangedVariables );
                break;
            }

        case UPNP_EVENT_SUBSCRIBE_COMPLETE:
        case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:
        case UPNP_EVENT_RENEWAL_COMPLETE:
            {
                struct Upnp_Event_Subscribe *es_event =
                    ( struct Upnp_Event_Subscribe * )Event;

                if( es_event->ErrCode != UPNP_E_SUCCESS ) {
                    SampleUtil_Print
                        ( "Error in Event Subscribe Callback -- %d",
                          es_event->ErrCode );
                } else {
                    TvCtrlPointHandleSubscribeUpdate( es_event->
                                                      PublisherUrl,
                                                      es_event->Sid,
                                                      es_event->TimeOut );
                }

                break;
            }

        case UPNP_EVENT_AUTORENEWAL_FAILED:
        case UPNP_EVENT_SUBSCRIPTION_EXPIRED:
            {
                int TimeOut = default_timeout;
                Upnp_SID newSID;
                int ret;

                struct Upnp_Event_Subscribe *es_event =
                    ( struct Upnp_Event_Subscribe * )Event;

                ret =
                    UpnpSubscribe( ctrlpt_handle, es_event->PublisherUrl,
                                   &TimeOut, newSID );

                if( ret == UPNP_E_SUCCESS ) {
                    SampleUtil_Print( "Subscribed to EventURL with SID=%s",
                                      newSID );
                    TvCtrlPointHandleSubscribeUpdate( es_event->
                                                      PublisherUrl, newSID,
                                                      TimeOut );
                } else {
                    SampleUtil_Print
                        ( "Error Subscribing to EventURL -- %d", ret );
                }
                break;
            }

            /*
               ignore these cases, since this is not a device 
             */
        case UPNP_EVENT_SUBSCRIPTION_REQUEST:
        case UPNP_CONTROL_GET_VAR_REQUEST:
        case UPNP_CONTROL_ACTION_REQUEST:
            break;
    }

    return 0;
}
/********************************************************************************
 * SampleUtil_FindAndParseService
 *
 * Description: 
 *       This routine finds the first occurance of a service in a DOM representation
 *       of a description document and parses it.  
 *
 * Parameters:
 *   DescDoc -- The DOM description document
 *   location -- The location of the description document
 *   serviceSearchType -- The type of service to search for
 *   serviceId -- OUT -- The service ID
 *   eventURL -- OUT -- The event URL for the service
 *   controlURL -- OUT -- The control URL for the service
 *
 ********************************************************************************/
int
SampleUtil_FindAndParseService( IN IXML_Document * DescDoc,
                                IN char *location,
                                IN char *serviceType,
                                OUT char **serviceId,
                                OUT char **eventURL,
                                OUT char **controlURL )
{
    int i,
      length,
      found = 0;
    int ret;
    char *tempServiceType = NULL;
    char *baseURL = NULL;
    char *base;
    char *relcontrolURL = NULL,
     *releventURL = NULL;
    IXML_NodeList *serviceList = NULL;
    IXML_Element *service = NULL;

    baseURL = SampleUtil_GetFirstDocumentItem( DescDoc, "URLBase" );

    if( baseURL )
        base = baseURL;
    else
        base = location;

    serviceList = SampleUtil_GetFirstServiceList( DescDoc );
    length = ixmlNodeList_length( serviceList );
    for( i = 0; i < length; i++ ) {
        service = ( IXML_Element * ) ixmlNodeList_item( serviceList, i );
        tempServiceType =
            SampleUtil_GetFirstElementItem( ( IXML_Element * ) service,
                                            "serviceType" );

        if( strcmp( tempServiceType, serviceType ) == 0 ) {
            SampleUtil_Print( "Found service: %s\n", serviceType );
            *serviceId =
                SampleUtil_GetFirstElementItem( service, "serviceId" );
            SampleUtil_Print( "serviceId: %s\n", ( *serviceId ) );
            relcontrolURL =
                SampleUtil_GetFirstElementItem( service, "controlURL" );
            releventURL =
                SampleUtil_GetFirstElementItem( service, "eventSubURL" );

            *controlURL =
                malloc( strlen( base ) + strlen( relcontrolURL ) + 1 );
            if( *controlURL ) {
                ret = UpnpResolveURL( base, relcontrolURL, *controlURL );
                if( ret != UPNP_E_SUCCESS )
                    SampleUtil_Print
                        ( "Error generating controlURL from %s + %s\n",
                          base, relcontrolURL );
            }

            *eventURL =
                malloc( strlen( base ) + strlen( releventURL ) + 1 );
            if( *eventURL ) {
                ret = UpnpResolveURL( base, releventURL, *eventURL );
                if( ret != UPNP_E_SUCCESS )
                    SampleUtil_Print
                        ( "Error generating eventURL from %s + %s\n", base,
                          releventURL );
            }

            if( relcontrolURL )
                free( relcontrolURL );
            if( releventURL )
                free( releventURL );
            relcontrolURL = releventURL = NULL;

            found = 1;
            break;
        }

        if( tempServiceType )
            free( tempServiceType );
        tempServiceType = NULL;
    }

    if( tempServiceType )
        free( tempServiceType );
    if( serviceList )
        ixmlNodeList_free( serviceList );
    if( baseURL )
        free( baseURL );

    return ( found );
}