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