61
Universal Plug and Play Dirk Grunwald University of Colorado

Universal Plug and Play Dirk Grunwald University of Colorado

Embed Size (px)

Citation preview

Page 1: Universal Plug and Play Dirk Grunwald University of Colorado

Universal Plug and Play

Dirk GrunwaldUniversity of Colorado

Page 2: Universal Plug and Play Dirk Grunwald University of Colorado

Outline

What problem is UPNP trying to solve? What are the components in UPNP? Example Programming API

Page 3: Universal Plug and Play Dirk Grunwald University of Colorado

What is UPNP?

Architecture for pervasive peer-to-peer network connectivity of intelligent appliances

Allows appliances to present “controls” to computers

Peer-to-peer – does not use a central registry

Largely based on IETF standards

Page 4: Universal Plug and Play Dirk Grunwald University of Colorado

What is UPNP - Example

UPNP supports “devices” and “control points”. A device may have multiple “services”

Sample Device A TV registers itself as a “device” The TV exports a “Control Service” for

volume, power, channel It exports a “Picture” service for color, tint,

contrast and brightness

Page 5: Universal Plug and Play Dirk Grunwald University of Colorado

What is UPNP - Example

An intelligent TV Remote or PC may be a “controller”

Both devices and controllers may exist in an “unmanaged” network (no DNS or DHCP)

AutoIP is a mechanism to allocate an IP address

Multicast DNS is used to decenteralize name service

Page 6: Universal Plug and Play Dirk Grunwald University of Colorado

Important Actions in UPNP

Discover devices & services Get a description of the device Control discovered devices Be informed of events indicating

changes in the device Use a presentation prepared by the

device to present a control

Page 7: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Discovery

Based on SSDP (simple service discovery protocol – IETF draft)

When a device is added to the network, that device can advertise its services to control points

When a control point is added, it can search for existing devices

Discovery exchanges information about the device type, an identifier and a URL for more detailed information

Page 8: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Description

A control point retrieves a description using the URL provided during discovery

An XML document describes the device and services

Vendor specific info, manufacturer information (model name, version), serial number, URL’s for vendor specific web sites

Page 9: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Control

Control point can send actions to a device’s service

Send Control Message to Control URL Control messages encodded in XML using

the Simple Object Access Protocol (SOAP)

Page 10: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Eventing

A service description includes variables that model the service state

Publish / subscribe model Special first event provides initial values

Events are formatted in XML using GENA (General Event Notification Architecture)

Page 11: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Presentation

A device can offer a URL for presentation

Control point can retrieve the page, load into a browser and allow user to control or observe the device

UPNP only covers retrieving the page

Page 12: Universal Plug and Play Dirk Grunwald University of Colorado

Overview - Components

                                                      

             

Page 13: Universal Plug and Play Dirk Grunwald University of Colorado

What’s Next

Walk through specific activities

Intersperse code snips from TV example

Page 14: Universal Plug and Play Dirk Grunwald University of Colorado

Icons for Protocol Example

Service

Service

Root Device #1

Device

Service

Service

Root Device #2

Device

ControlPoint #1

ControlPoint #2

ControlPoint #3

Page 15: Universal Plug and Play Dirk Grunwald University of Colorado

Actions When New Device Is Added

Service

Service

Root Device #1

Device

ControlPoint #1

1. Device Initialization

2. Announcement

1. Start periodic re-announcements

3. Service actions

4. Disconnect

Page 16: Universal Plug and Play Dirk Grunwald University of Colorado

Actions When New Controller Added

Service

Service

Root Device #1

Device

ControlPoint #2

1. Control Initialization

2. Search for devices

1. Start periodic timeout checker

3. Issue actions

4. Disconnect

Page 17: Universal Plug and Play Dirk Grunwald University of Colorado

Coding the Device

Page 18: Universal Plug and Play Dirk Grunwald University of Colorado

Control Flow in Device

Main

Initialize Announce Command Loop

Periodic Announce

CallbackEventHandler

HandleSubscriptionRequest

HandleGetVarRequest

HandleActionRequest …Thread started by UPNP system

Thread started by Device application

Page 19: Universal Plug and Play Dirk Grunwald University of Colorado

Device Initialization

if (ret = UpnpInit(ip_address, port)) {

printf("Error with UpnpInit -- %d\n", ret);

UpnpFinish();

exit(1);

}

Specified host IP address or NULL

Specified port (NULL defaults to 80)

Cleanup routine – must be last API routine

called

Page 20: Universal Plug and Play Dirk Grunwald University of Colorado

Device Registration

UpnpRegisterRootDevice(desc_doc_url,TvDeviceCallbackEventHandler,&device_handle,&device_handle)));

TvDeviceStateTableInit(desc_doc_url);…

URL With device description

Routine to handle asynchronous

events

Void* passed to asynch handler routine OUT

UpnpDevice_Handle used to identify device

in API

Page 21: Universal Plug and Play Dirk Grunwald University of Colorado

Device State Table Initialization

if (UpnpDownloadXmlDoc(DescDocURL, &DescDoc)!= UPNP_E_SUCCESS) {

printf("Error Parsing %s\n", DescDocURL);

ret = UPNP_E_INVALID_DESC;

}

This returns a UpnpDownloadXmlDoc item, which

is a parsed DOM document. The application needs to free this data.

Each device is described by an XML document. The

device needs to know where that document lives

Page 22: Universal Plug and Play Dirk Grunwald University of Colorado

Device Description URL

<?xml version="1.0"?>

<root xmlns="urn:schemas-upnp-org:device-1-0">

<specVersion> <major>1</major> <minor>0</minor> </specVersion>

<URLBase>http://192.168.1.1</URLBase>

<device>

<deviceType>urn:schemas-upnp-org:device:tvdevice:1</deviceType>

<friendlyName>UPnP Television Emulator</friendlyName>

... model information...

<serviceList>

...exported services...

</serviceList>

<presentationURL> tvdevicepres.html </presentationURL>

</device>

</root>

Page 23: Universal Plug and Play Dirk Grunwald University of Colorado

Device Info

<deviceType>urn:schemas-upnp-org:device:tvdevice:1</deviceType>

<friendlyName>UPnP Television Emulator</friendlyName>

<manufacturer>TV Manufacturer Name</manufacturer>

<manufacturerURL>http://www.manufacturer.com

</manufacturerURL>

<modelDescription>

UPnP Television Device Emulator 1.0

</modelDescription>

<modelName>TVEmulator</modelName>

<modelNumber>1.0</modelNumber>

<modelURL>http://www.manufacturer.com/TVEmulator/</modelURL>

<serialNumber>123456789001</serialNumber>

<UDN>uuid:Upnp-TVEmulator-1_0-1234567890001</UDN>

<UPC>123456789</UPC>

Page 24: Universal Plug and Play Dirk Grunwald University of Colorado

Device Service List

<serviceList>

<service>

<serviceId> urn:upnp-org:serviceId:tvcontrol1

</serviceId>

…Remainder of TV Controller Device Specification…

</service>

<service>

<serviceType>

urn:schemas-upnp-org:service:tvpicture:1

</serviceType>

…Remainder of TV Controller Device Specification…

</service>

</serviceList>

Page 25: Universal Plug and Play Dirk Grunwald University of Colorado

Device Service Description

<service>

<serviceType>urn:schemas-upnp-org:service:tvcontrol:1

</serviceType>

<serviceId> urn:upnp-org:serviceId:tvcontrol1 </serviceId>

<controlURL>http://192.168.1.1:5431/upnp/control/tvcontrol1

</controlURL>

<eventSubURL>http://192.168.1.1:5431/upnp/event/tvcontrol1

</eventSubURL>

<SCPDURL>http://192.168.1.1/tvcontrolSCPD.xml

</SCPDURL>

</service>

Address specified by application

“Service Control Protocol Definition”What controls / events are available?

Page 26: Universal Plug and Play Dirk Grunwald University of Colorado

Device SCPD

?xml version="1.0"?>

<scpd xmlns="urn:schemas-upnp-org:service-1-0">

<serviceStateTable>

<stateVariable> … </stateVariable>

… More state variables …

</serviceStateTable>

<actionList><action>

<name>PowerOn</name></action>

… More action items …

</actionList>

</scpd>

Page 27: Universal Plug and Play Dirk Grunwald University of Colorado

State Variables Specify Type, Range and Initial Value

<stateVariable>

<name> Channel </name>

<dataType> i4 </dataType>

<allowedValueRange>

<minimum> 1 </minimum>

<maximum> 100 </maximum>

<step> 1 </step>

</allowedValueRange>

<defaultValue> 1 </defaultValue>

</stateVariable>

Page 28: Universal Plug and Play Dirk Grunwald University of Colorado

Actions Specify Arguments, Values

<action>

<name>SetChannel</name>

<argumentList>

<argument>

<name>NewChannel</name>

<relatedStateVariable>Channel

</relatedStateVariable>

<direction>in

</direction>

</argument>

</argumentList>

</action>

Page 29: Universal Plug and Play Dirk Grunwald University of Colorado

Device state represented by strings in this sample application

* Global arrays for storing Tv Control Service

variable names, values, and defaults */

char *tvc_varname[] = {"Power","Channel","Volume"};

char tvc_varval[3][5];

char *tvc_varval_def[] = {"0", "1", "5"};

/* Global arrays for storing Tv Picture Service

variable names, values, and defaults */

char *tvp_varname[] = {"Color","Tint","Contrast","Brightness"};

char tvp_varval[4][5];

char *tvp_varval_def[] = {"5","5","5","5"};

Filled in with default value later

Page 30: Universal Plug and Play Dirk Grunwald University of Colorado

Supplemental RoutinesSimplify Document Access

SampleUtil_FindAndParseService(DescDoc,TvControlServiceType,&servid_ctrl, &evnturl_ctrl,&ctrlurl_ctrl);

udn = SampleUtil_GetFirstDocumentItem(DescDoc, "UDN");

strcpy(tvcontrol_service.UDN, udn);

strcpy(tvcontrol_service.ServiceId, servid_ctrl);

strcpy(tvcontrol_service.ServiceType, TvControlServiceType);

tvcontrol_service.VariableCount=3;

for (i=0; i<tvcontrol_service.VariableCount; i++) {

tvcontrol_service.VariableName[i] = tvc_varname[i];

tvcontrol_service.VariableStrVal[i] = tvc_varval[i];

strcpy(tvcontrol_service.VariableStrVal[i], tvc_varval_def[i]);

}

Variables maintained as strings in example

Page 31: Universal Plug and Play Dirk Grunwald University of Colorado

Coding the DeviceWhere were we?

Device has initialized the UPNP system Device has registered the root device,

making it available to receive messages

Device has read the device description and initialized state variables

Probably should have used the values in the SCPD

Page 32: Universal Plug and Play Dirk Grunwald University of Colorado

Device Announcement

UpnpSendAdvertisement(device_handle, default_advr_expire;

Each advertisement has a default timeout, expressed in an integral

number of seonds

UpnpDevice_Handle used to identify device

in API

Page 33: Universal Plug and Play Dirk Grunwald University of Colorado

Details about SSDP / Announcment

Broadcasts to 239.255.255.250:1900 “Site local” multicast address

Messages delivered usingHTTPMU and HTTPU

Page 34: Universal Plug and Play Dirk Grunwald University of Colorado

Thread is spawned for Device (Re)Announcement

code = pthread_create( &advr_thread, NULL, TvCtrlPointAdvrLoop, NULL );

void* TvCtrlPointAdvrLoop(void *args)

{

int ret;

while (1) {

sleep(default_advr_interval);

if (ret = UpnpSendAdvertisement(device_handle, default_advr_expire))

printf("Error sending updated advert : %d\n", ret);

printf("Updated Advertisements Sent\n");

}

}

The application starts a thread to periodically renew

advertisements. This could also be done with timers &

signals or other mechanisms.

Page 35: Universal Plug and Play Dirk Grunwald University of Colorado

The Main thread now enters a command loop

void TvDeviceCommandLoop(){ int stoploop=0; char cmdline[100]; char cmd[100]; int i;

while (!stoploop) { sprintf(cmdline, ""); sprintf(cmd, "");

printf("\n>> ");

// Get a command line fgets(cmdline, 100, stdin);

sscanf(cmdline, "%s", &cmd);

if (strcasecmp(cmd, "exit") == 0) { printf("Shutting down...\n"); UpnpUnRegisterRootDevice(device_handle); UpnpFinish(); exit(0); } else { printf("\n Unknown command: %s\n\n", cmd); printf(" Valid Commands:\n"); printf(" Exit\n\n"); }

}}

Page 36: Universal Plug and Play Dirk Grunwald University of Colorado

The UPNP thread periodically called the “callback handler”

int TvDeviceCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie){ struct Upnp_Event * event;

/* Print a summary of the event received */ SampleUtil_PrintEvent(EventType, Event);

switch ( EventType) {

case UPNP_EVENT_SUBSCRIPTION_REQUEST: TvDeviceHandleSubscriptionRequest( (struct Upnp_Subscription_Request *) Event); break;

case UPNP_CONTROL_GET_VAR_REQUEST: TvDeviceHandleGetVarRequest( (struct Upnp_State_Var_Request *) Event); break;

case UPNP_CONTROL_ACTION_REQUEST: TvDeviceHandleActionRequest( (struct Upnp_Action_Request *) Event); break;…

Page 37: Universal Plug and Play Dirk Grunwald University of Colorado

Accepting a subscription sends out current value of state variable

int TvDeviceHandleSubscriptionRequest(struct Upnp_Subscription_Request *sr_event){

pthread_mutex_lock(&TVDevMutex);

if ((strcmp(sr_event->UDN,tvcontrol_service.UDN) == 0) && (strcmp(sr_event->ServiceId,

tvcontrol_service.ServiceId) == 0)) { /* This is a request for the TvDevice Control Service */ UpnpAcceptSubscription( device_handle sr_event->UDN, sr_event->ServiceId, (char **)tvcontrol_service.VariableName, (char **)tvcontrol_service.VariableStrVal, tvcontrol_service.VariableCount, sr_event->Sid); } else if () .. {

.. }

pthread_mutex_unlock(&TVDevMutex);

return(1);}

This identifies the controller being

registered

Page 38: Universal Plug and Play Dirk Grunwald University of Colorado

State changing routines notify subscribed listeners

int TvDeviceSetChannel(int channel){ if (channel < 1 || channel > 100) { printf("error: can't change to channel %d\n", channel); return(0); }

/* Vendor-specific code to set the channel goes here */

pthread_mutex_lock(&TVDevMutex);

sprintf(tvcontrol_service.VariableStrVal[1], "%d", channel);

/* Send updated channel setting notification to subscribed control points */ UpnpNotify(device_handle, tvcontrol_service.UDN, tvcontrol_service.ServiceId, (char **)&tvcontrol_service.VariableName[1], (char **)&tvcontrol_service.VariableStrVal[1], 1);

pthread_mutex_unlock(&TVDevMutex);

return(1);}

Number of variables in change list

List of variable that changed

In a real application, you’d

actually do something useful

here

Page 39: Universal Plug and Play Dirk Grunwald University of Colorado

Asynchronous State Changes

This example only contains synchronous event changes (caused by an external controller)

The device may change by itself (e.g. GPS)

Just call UpnpNotify in device change routine

Page 40: Universal Plug and Play Dirk Grunwald University of Colorado

The device copys values for GetVarRequest

int TvDeviceHandleGetVarRequest(struct Upnp_State_Var_Request *cgv_event)

{ int i; int getvar_succeeded = 0;

cgv_event->CurrentVal = NULL;

pthread_mutex_lock(&TVDevMutex);

if ((strcmp(cgv_event->DevUDN,tvcontrol_service.UDN)==0) && (strcmp(cgv_event->ServiceID,

tvcontrol_service.ServiceId)==0)) { /* Request for variable in the TvDevice Control Service */ for (i=0; i< tvcontrol_service.VariableCount; i++) { if (strcmp(cgv_event->StateVarName,

tvcontrol_service.VariableName[i])==0) { getvar_succeeded = 1; cgv_event->CurrentVal = (Upnp_DOMString)

malloc(sizeof(tvcontrol_service.VariableStrVal[i])); strcpy(cgv_event->CurrentVal,

tvcontrol_service.VariableStrVal[i]); break; } …

Check for correct device

Copy value to event datatype

Page 41: Universal Plug and Play Dirk Grunwald University of Colorado

The application is responsible for decoding and performing actions

int TvDeviceHandleActionRequest(struct Upnp_Action_Request *ca_event){ Upnp_DOMString bufReq; char result_str[500]; char service_type[500]; char *value=NULL;

/* Defaults if action not found */ int action_succeeded = -1; int err=401;

ca_event->ErrCode = 0; ca_event->ActionResult = NULL;

if ((strcmp(ca_event->DevUDN,tvcontrol_service.UDN)==0) && (strcmp(ca_event->ServiceID,tvcontrol_service.ServiceId)==0)) {

/* Request for action in the TvDevice Control Service */

strcpy(service_type, tvcontrol_service.ServiceType);

if (strcmp(ca_event->ActionName, "PowerOn") == 0) { action_succeeded = TvDevicePowerOn(); } else if (strcmp(ca_event->ActionName, "PowerOff") == 0) { action_succeeded = TvDevicePowerOff(); } else

Check for correct device

Page 42: Universal Plug and Play Dirk Grunwald University of Colorado

The application is responsible for decoding and performing actions

} else if (strcmp(ca_event->ActionName, "SetChannel") == 0) {

if (value = SampleUtil_GetFirstDocumentItem( ca_event->ActionRequest, "Channel")) {

action_succeeded = TvDeviceSetChannel(atoi(value)); } else { // invalid args error err = 402; action_succeeded = 0; }

The support routines provide assistance for extracting the

values from the DOM document

This greatly simplifies the parsing of complex actions. Note that

TvDeviceSetChannel will UpnpNotify any subscribers of the changed value

Page 43: Universal Plug and Play Dirk Grunwald University of Colorado

Coding the Client

Page 44: Universal Plug and Play Dirk Grunwald University of Colorado

High Level View of Client

Initialize UPNP system Register Ask devices to advertise themselves Subscribe to any devices we find by

advertisement Accept user commands to examine

variables of devices or cause actions

Page 45: Universal Plug and Play Dirk Grunwald University of Colorado

Client Registration

UpnpInit(ip_address, port);UpnpRegisterClient(TvCtrlPointCallbackEventHandler,

&ctrlpt_handle, &ctrlpt_handle)…

Routine to handle asynchronous

events

Void* passed to asynch handler routine

OUT UpnpClient_Handle

used to identify controller in API

Page 46: Universal Plug and Play Dirk Grunwald University of Colorado

Client Requests Notification

/* Search for all devices of type tvdevice version 1,waiting for up to 5 seconds for the response */

/* ret = UpnpSearchAsync(ctrlpt_handle, 5, "urn:schemas-upnp-org:device:tvdevice:1",

NULL); */

/* Search for all services of type tvcontrol version 1,waiting for up to 5 seconds for the response */

/* ret = UpnpSearchAsync(ctrlpt_handle, 5, “urn:schemas-upnp-org:service:tvcontrol:1”, NULL); */

/* Search for all root devices,waiting for up to 5 seconds for the response */

ret = UpnpSearchAsync(ctrlpt_handle, 5, "upnp:rootdevice", NULL);

If the device is found, the callback routine will be called

Page 47: Universal Plug and Play Dirk Grunwald University of Colorado

Notifications Invoke Callback

int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType,

void *Event,

void *Cookie)

{

struct Upnp_Event * event;

int ret;

SampleUtil_PrintEvent(EventType, Event);

switch ( EventType) {

/* SSDP Stuff */

case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:

case UPNP_DISCOVERY_SEARCH_RESULT:

{ if ((ret=UpnpDownloadXmlDoc(d_event->Location, &DescDoc))

!= UPNP_E_SUCCESS) {

printf("Error obtaining device description from %s -- error = %d\n",d_event->Location, ret );

} else { TvCtrlPointAddDevice(DescDoc, d_event->Location, d_event->Expires); }

Controller downloads device description from specified URL

Keeps private device

list

Page 48: Universal Plug and Play Dirk Grunwald University of Colorado

This client uses asingle callback routine

int TvCtrlPointCallbackEventHandler(Upnp_EventType EventType, void *Event, void *Cookie)

{ switch ( EventType) {

/* SSDP Stuff */case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:case UPNP_DISCOVERY_SEARCH_RESULT:case UPNP_DISCOVERY_SEARCH_TIMEOUT:case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:

/* SOAP Stuff */case UPNP_CONTROL_ACTION_COMPLETE:case UPNP_CONTROL_GET_VAR_COMPLETE:

/* GENA Stuff */case UPNP_EVENT_RECEIVED:case UPNP_EVENT_SUBSCRIBE_COMPLETE:case UPNP_EVENT_UNSUBSCRIBE_COMPLETE:case UPNP_EVENT_RENEWAL_COMPLETE:

/* 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:

}

Page 49: Universal Plug and Play Dirk Grunwald University of Colorado

Client starts thread to keep subscriptions fresh

pthread_create( &timer_thread, NULL, TvCtrlPointTimerLoop, NULL );

..

void* TvCtrlPointTimerLoop(void *args)

{

int incr = 30; // how often to verify the timeouts

while (1) {

sleep(incr);

TvCtrlPointVerifyTimeouts(incr);

}

}

Subscribes to all services that we know about, possibly renewing subscriptions or asking for new subscriptions.

Page 50: Universal Plug and Play Dirk Grunwald University of Colorado

If a previously announced device expires, it subscribes again..

if (strcmp(curdevnode->device.TvControl.SID, "") != 0) {

/* We have a valid TvControl SID, so lets check the

subscription timeout */

curdevnode->device.TvControl.SubsTimeOut -= incr;

if (curdevnode->device.TvControl.SubsTimeOut <= 0) {

/* The subscription has expired,so delete it and request a new one */

strcpy(curdevnode->device.TvControl.SID, "");

ret = UpnpSubscribeAsync(ctrlpt_handle,

curdevnode->device.TvControl.EventURL,

default_timeout,

TvCtrlPointCallbackEventHandler, NULL);

}

Async means that callback will be called later

Page 51: Universal Plug and Play Dirk Grunwald University of Colorado

But if the device is only about to expire, it renews subscription

} else if (curdevnode->device.TvControl.SubsTimeOut < 2*incr) {

/* The subscription is about to expire, so try to renew it */ret = UpnpRenewSubscriptionAsync(ctrlpt_handle,

default_timeout,curdevnode->device.TvControl.SID,

TvCtrlPointCallbackEventHandler, NULL);

This routine may eventually be called with a

RENEWAL_EVENT_COMPLETE

event

Page 52: Universal Plug and Play Dirk Grunwald University of Colorado

Mean while, the main thread is accepting user commands

void TvCtrlPointCommandLoop()

{

while (!stoploop) {

..

fgets(cmdline, 100, stdin);

...

if (cmdfound) {

switch(cmdnum) {

case PRTHELP:

TvCtrlPointPrintHelp();

break;

case POWON:

if (arg1 == arg_val_err)

invalid_args = 1;

else

TvCtrlPointSendControlAction(arg1, "PowerOn");

break;

Page 53: Universal Plug and Play Dirk Grunwald University of Colorado

..and sending actions to the device…

int TvCtrlPointSendControlAction(int devnum, char *actionname)

{

struct TvDeviceNode *devnode;

char ActionXml[250];

Upnp_Document actionNode=NULL;

int ret=0;

pthread_mutex_lock(&DeviceListMutex);

if (!TvCtrlPointGetDevice(devnum, &devnode)) {

ret = 0;;

} else {

sprintf(ActionXml, "<u:%s xmlns:u=\"%s\"></u:%s>",

actionname, TvControlServiceType, actionname);

actionNode = UpnpParse_Buffer( ActionXml);

ret = UpnpSendActionAsync( ctrlpt_handle,

devnode->device.TvControl.ControlURL, "tvcontrol:1",

devnode->device.DevUUID, actionNode,

TvCtrlPointCallbackEventHandler, NULL);

Format action requestion and turn into a DOM

document for UpnpSendAction

Page 54: Universal Plug and Play Dirk Grunwald University of Colorado

..or requesting values from the device.

int TvCtrlPointControlGetVar(int devnum, char* varname)

{

struct TvDeviceNode *devnode;

int ret=0;

pthread_mutex_lock(&DeviceListMutex);

if (!TvCtrlPointGetDevice(devnum, &devnode)) {

ret = 0;;

} else {

ret = UpnpGetServiceVarStatusAsync( ctrlpt_handle,

devnode->device.TvControl.ControlURL,

varname,

TvCtrlPointCallbackEventHandler,

NULL);

The value is eventually returned

to this callback routine

Page 55: Universal Plug and Play Dirk Grunwald University of Colorado

The actions are acknowledged to the callback routine

/* 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) printf("Error in Action Complete Callback -- %d\n", 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) printf("Error in Get Var Complete Callback -- %d\n", sv_event->ErrCode);

} break;

Page 56: Universal Plug and Play Dirk Grunwald University of Colorado

Actual variable values are passed by events

case UPNP_EVENT_RECEIVED: { struct Upnp_Event *e_event =

(struct Upnp_Event * ) Event;

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

} break;

Page 57: Universal Plug and Play Dirk Grunwald University of Colorado

That are passed to service specific decoders..

void TvCtrlPointHandleEvent(SID sid, int evntkey, Upnp_Document changes){ struct TvDeviceNode *tmpdevnode; pthread_mutex_lock(&DeviceListMutex); tmpdevnode = GlobalDeviceList; while (tmpdevnode) { if (strcmp(tmpdevnode->device.TvControl.SID,sid) == 0) { printf("Received TvControl Event: %d for SID %s\n", evntkey, sid); TvControlStateUpdate(changes,

(char **)&tmpdevnode->device.TvControl.VariableStrVal); break; } else if (strcmp(tmpdevnode->device.TvPicture.SID,sid) == 0) { printf("Received TvPicture Event: %d for SID %s\n", evntkey, sid); TvPictureStateUpdate(changes,

(char **)&tmpdevnode->device.TvPicture.VariableStrVal); break; } tmpdevnode = tmpdevnode->next; } pthread_mutex_unlock(&DeviceListMutex);}

Page 58: Universal Plug and Play Dirk Grunwald University of Colorado

ReviewOf Concepts

and Coding Style

Page 59: Universal Plug and Play Dirk Grunwald University of Colorado

Review

Discovery / description / control / events / presentation

Discovery is by multicast Control & Events are unicast

support routines provide encoding / decoding

Services and controllers are written using an asynchronous, multithreaded application model

Page 60: Universal Plug and Play Dirk Grunwald University of Colorado

System Requirements

Web server to transmit device & and control descriptions

Does not need to be on device! HTTP / HTTPU / HTTPMU parser

Built into library DOM / XML parser

Combination of CDOM and sample code handles this

Page 61: Universal Plug and Play Dirk Grunwald University of Colorado

Unanswered Questions

What about security? Basic UPNP library abstracts away

communication layer Authentication / permission models?

What about “far away access”? If you know the service exists on a device,

you can simply query it using HTTPU But, that’s not supported in current UPNP

library