Date post: | 17-Jan-2016 |
Category: |
Documents |
Upload: | alexia-shepherd |
View: | 215 times |
Download: | 0 times |
Communicating with Devices
Prasun Dewan
Department of Computer Science University of North Carolina
2
Steps to UPnP Networking
0 Control point and device get addresses1 Control point finds interesting device2* Control point learns about device capabilities3 Control point invokes actions on device4 Control point listens to state changes of device5 Control point controls device and/or views device status
using HTML UI
0 Addressing0 Addressing
1 Discovery1 Discovery
2* Description2* Description
5 Presentation5 Presentation4 Eventing4 Eventing3 Control3 Control
3
Example Service
<?xml version="1.0" ?> <scpd xmlns="urn:schemas-upnp-org:service-1-0"> <specVersion> <major>1</major> <minor>0</minor> </specVersion>
4
Example Action List
<actionList> <action> <name>PowerOn</name> </action> <action> <name>SetChannel</name>
<argumentList> <argument>
<name>Channel</name> <relatedStateVariable>Channel</relatedStateVariable> <direction>in</direction>
</argument> </argumentList>
</action> ….
<actionList>
5
Example Variables<serviceStateTable> <stateVariable sendEvents="yes"> <name>Power</name> <dataType>Boolean</dataType> <defaultValue>0</defaultValue> </stateVariable> <stateVariable sendEvents="yes"> <name>Channel</name> <dataType>i4</dataType> <allowedValueRange> <minimum>1</minimum> <maximum>100</maximum> <step>1</step> </allowedValueRange> <defaultValue>1</defaultValue> </stateVariable> …..</serviceStateTable>
6
Example Server CodeObject processMessages (Message message) {
switch (message.kind) case GET_VAR_REQUEST:
switch ((GetVarMessage) message).varName) case “Channel”: message.result = getChannel();
… case ACTION_REQUEST:
actionMessage = (ActionMessage) message.switch (actionMessage.actionName) case “setChannel”: setChannel(parseString(actionMessage.params[0])) …
}int channel;int getChannel () { return curentChannel};void setChannel (int newChannel) { channel = newChannel; UPnP.announce(“Channel”, toString(getChannel());}...
7
High Programming Cost Device developer must:
define the XML-based external representation of the device
translate the client operation-invocation and variable-access requests to local operation-invocations
announce variable change notifications Exporting functionality requires more code than
implementing it in example Intel device not counting UI code
Cost proportional to complexity of type. Reason for not allowing complex types?
8
High Maintenance Cost Information repeated multiple times
operation implementation code action list state variable table message processing code event announcement code
All repetitions must be changed tedious error-prone
Channel -> Current Channel requires 9 changes!
9
Changed Action List<actionList> <action> <name>PowerOn</name> </action> <action> <name>SetCurrentChannel</name> <argumentList> <argument>
<name>CurrentChannel</name> <relatedStateVariable>CurrentChannel</relatedStateVariable>
<direction>in</direction> </argument> </argumentList>
</action> ….
<actionList>
10
Changed State Variable Table<serviceStateTable> <stateVariable sendEvents="yes"> <name>Power</name> <dataType>Boolean</dataType> <defaultValue>0</defaultValue> </stateVariable> <stateVariable sendEvents="yes"> <name>CurrentChannel</name> <dataType>i4</dataType> <allowedValueRange> <minimum>1</minimum> <maximum>100</maximum> <step>1</step> </allowedValueRange> <defaultValue>1</defaultValue> </stateVariable> …..</serviceStateTable>
11
Changed Server CodeObject processMessages (Message message) {
switch (message.kind) case GET_VAR_REQUEST: switch ((GetVarMessage) message).varName) case “CurrentChannel”: message.result = getCurrentChannel();
… case ACTION_REQUEST: actionMessage = (ActionMessage) message. switch (actionMessage.actionName)
case “setCurrentChannel”: setCurrentChannel(parseString(actionMessage.params[0]))
…}int channel;int getCurrentChannel () {return channel};void setCurrentChannel (int newChannel) { channel = newChannel; UPnP.announce(“CurrentChannel”, toString(getCurrentChannel());}...
12
Ideal Developer Effort
int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}...
13
No Programmer-Defined Types XML defines 24 data types
ui1, ui2, ui4, i1, i2, i4, int r4, r8, number, fixed.14.4, float char, string date, dateTime, dateTime.tz, time, time.tz boolean bin.base64, bin.hex uri uuid
14
No Programmer-Defined Types Only supports predefined types
state variables action parameters
No way to model dynamic composites
Dynamic programmer-defined collection
15
Generating Action List
Generator
External DescriptionDevice Code
Actions
16
<action list><action> <name>SetCurrentChannel</name> <argumentList> <argument>
<name>NewChannel</name> <relatedStateVariable>
CurrentChannel </relatedStateVariable>
<direction>in</direction> </argument> </argumentList> </action>….</actionList>
Generating Action Descriptions
Mainly syntactic issue Static approach
precompiler Dynamic approach
reflection vcr.getClass().getMethods() method.getName() method.getParameterTypes()
Done in ICrafter (Stanford) How to get related state
variable?
int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}
17
Why variables? Clients may view device as
state manager Because their user has this
view. VCR user interface
May compose state aggregating sensors
More abstract to associate events with variable changes rather than method invocations Channel changed
vs.SetChannel called Similarly access and
concurrency control state specific
18
Generating External Representation
Generator
External Description
Actions
Variables
Problem in general unsolvable
• Need help from programmer
Device class
19
Generating Variable DescriptionsBasic idea Object state stored in internal vars. Make them public.
Drawbacks Violates encapsulation
Changing internal representation changes clients
Not all state may be stored How to get
Related state vars Min, max range
How to generate events public var could be changed
directly
public int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}…
<serviceStateTable> <stateVariable sendEvents="yes"> <name>Channel</name> <dataType>i4</dataType> <allowedValueRange> <minimum>1</minimum> <maximum>100</maximum> <step>1</step> </allowedValueRange> <defaultValue>1</defaultValue> </stateVariable> …..</serviceStateTable>
20
Interface-based extraction Abstract data type helps by exposing
logical structure using standard system-defined interface (TreeNode) Approach used in Swing table
widget Equivalent to writing external
description extra programming effort extra maintenance effort no type checking (everything
TreeNode) Cannot generate types of
variables
must use common interfaces and associated object files
public Vector getVarNames();public TreeNode getVar(String fieldName);public void setVar(String fieldName, val TreeNode)
public class VCR implements TreeNode{ int channel; int getChannel () { return channel}; void setChannel (int newChannel) { channel = newChannel; }…}
21
int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}…
Pattern-based Approach Can use relationships
between operation names and signatures to derive external variables
(properties) channel : int
related state variable setChannel changes
channel Relationships defined by
Java beans
22
Simple Properties in Java
Defined by a pair of ‘getter’/’setter’ methods:String getTitle();
void setTitle(String newTitle)
define a title property of type String.
In general,<PropertyType> get<PropertyName>()void set<PropertyName>(<PropertyType>)
define a simple property named <PropertyName> of type <PropertyType> with read/write semantics.
23
Role of JavaBeans Properties
‘Properties are discrete named attributes of a Java Bean that can affect its appearance, or its behavior.’ typical properties:
font color size
24
Properties as Record FieldsMain idea: consider properties as
elements of the logical structure of the object.
record fieldsProblems Forces conventions
Channel() instead of getChannel()?
Legacy code Min, max range?
<serviceStateTable> <stateVariable sendEvents="yes"> <name>Channel</name> <dataType>i4</dataType> <allowedValueRange> <minimum>1</minimum> <maximum>100</maximum> <step>1</step> </allowedValueRange> <defaultValue>1</defaultValue> </stateVariable> …..</serviceStateTable>
int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}…
25
Property Specification
Approach: separate property specification and
interpretation Mechanism
introduce a pattern language for property specification
26
Property Extractor
Pattern specification
Property Definitions
Device Operations
Pattern specifications
Implementation must conform to specified pattern
User-defined, but less work and no duplication
Approach: separate property
specification and interpretation
Mechanism introduce a pattern
language for property specification
27
Examples Specification 1
String getTitle();
void setTitle(String newTitle)
define a title property of type String. Specification 2
String title();
void setTitle(String newTitle)
define a title property of type String.
Free Variables Unified
Literals
Grammar? Methods as
sentences Property name
and types not known
Must be extracted Unification
Methods as facts Property names
and types as unified variables
28
Property Specification Language
Canonical representation of method signatures:<return_type> method_name(arg1_type, …,argN_type)
An example specification: simple properties1. Method pattern specifications: getter = <.GetType.> get.PropName.() setter = <void> set.PropName.(.SetType.) pattern variables: GetType, PropName, SetType example matches:getter: String getTitle() {GetType == “String”,PropName == “Title”}
setter: void setTitle(String) {SetType == “String”, PropName == “Title”}
29
Java Bean Specification with Constraints
property type = simple access methods = getter, settergetter = <.GetType.> get.PropName.()
setter = <void> set.PropName.(.SetType.) constraints getter.PropName == setter.PropName getter.GetType == setter.SetType name = getter.PropNameend
30
Examples Specification 1
String getTitle();
void setTitle(String newTitle)
define a title property of type String. Specification 2
String title();
void setTitle(String newTitle)
define a title property of type String.
31
Alternative Bean Specification
property type = simple access methods = getter, setter
getter = <.GetType.>.PropName.()
setter = <void> set.PropName.(.SetType.) constraints
getter.PropName == setter.PropNamegetter.GetType == setter.SetType
name = getter.PropNameend
32
Properties as Record Fields Allows
Channel() instead of getChannel()
Legacy code Issues
Min, max range?
<serviceStateTable> <stateVariable sendEvents="yes"> <name>Channel</name> <dataType>i4</dataType> <allowedValueRange> <minimum>1</minimum> <maximum>100</maximum> <step>1</step> </allowedValueRange> <defaultValue>1</defaultValue> </stateVariable> …..</serviceStateTable>
int channel;int getChannel () { return channel};void setChannel (int newChannel) { channel = newChannel;}…
33
Min, Max Extensions
Additional Constraints
Propertytype = simple
access methods = min, max
min = <int> getMin.PropName.()
max = <int> getMax.PropName.()
step = <int> getStep.PropName.() … constraints getter.PropName==min.PropName== max.PropNameend
34
Alternative Min, Max Extensions
Constraints on variable declarations
property type = simple
access fields = min, max, stepmin = <final> <int> MIN_.PropName.max = <final> <int> MAX_.PropName.step = <final> <int> STEP_.PropName.
constraints min.PropName==max.PropName== step.PropName
== getter.PropNameend
35
No Programmer-Defined Types Only supports predefined types
state variables action parameters
No way to model dynamic composites
Dynamic programmer-defined collection
36
Two issues
Representation of programmer-defined types in XML Seems to be syntactic issue
Generating external representation Static (Record) structures addressed
JavaBeans defines field properties Language allows convention definitions
Dynamic structures?
37
Indexed Properties in Java
An indexed property isa simple property of an array type:
Section[] getSection()
void setSection( Section[] section)
with two additional methods:
Section getSection( int index)
void setSection( Section s, int index) Emulates array semantics in procedural languages
38
Understand Java Vector
class VCR { void power(); … int getCurrentChannel() ; void setCurrentChannel(int newVal) ; Vector getSettings(); void setSettings(Vector newVal)}
Cannot support programmer-defined dynamic list
39
Example Programmer-defined List class VCR { void power(); … int getCurrentChannel() ; void setCurrentChannel(int newVal) ; int size(); Setting elementAt(int index); void removeElement(Setting newVal); void addElement (Setting newVal); void setElementAt(Setting newVal, int index); }
40
Sequence propertiesinsert = <void> insert.Prop.at( int, .InsType.)remove = <void> remove.Prop.at( int)lookup = <.GetType.> .Prop.At( int)set = <void> set.Prop.At( int, .SetType.)count = <int> size()property type = sequence access methods = insert, remove, lookup, count, set constraints insert.Prop == remove.Prop == lookup.Prop insert.InsType == lookup.SetType == lookup.GetType name = insert.Prop element type = insert.InsType
public int size();public int settingAt(int index); public void setSettingAt(int index, Setting newVal);public void insertSettingAt(int index, Setting newVal);
41
Programmer-Defined Types in External Representation
Concrete Constructors Pascal enumeration Subrange Hashtable Array Sequence (variable size list) Record
Not abstract types Appliance object is abstract type Must deconstruct object so that variables are
known, that is, must map it to concrete type
42
Property Extractor
Pattern specification
Property Definitions
Device Operations
Pattern specifications
Programmer must conform to specified pattern
43
Conforming to Patterns Makes code understandable to humans Also makes code understandable to system tools
Bean builder Property Extractor
Unlike Bean framework, the patterns chosen by users
System adapts to application interfaces rather than vice versa
More flexible than the alternative of system-defined interfaces Pattern specification without pattern variables is
simply an interface
44
public int size();public int elementAt(int index); public void setElementAt(int index, Object newVal);public void insertElementAt(int index, Object newVal);public void insertElementAt(int index, Object newVal);
insert = <void> insertElementat( int, Object)
remove = <void> removeElementAt( int)lookup = Object elementAt( int)set = <void> setElementAt( int, Object)count = <int> size()property type = sequence access methods = insert, remove,
lookup, count, set name = vector element type = Object
Sequence interface
Fixes method names
Fixes element type to Object not Setting
no type
checking
45
Pattern Variables Allowing Multiple Methods Names/Element Types
insert = <void> insert.Prop.at( int, .InsType.)remove = <void> remove.Prop.at( int)lookup = <.GetType.> .Prop.At( int)set = <void> set.Prop.At( int, .SetType.)count = <int> size()property type = sequence access methods = insert, remove, lookup, count, set constraints insert.Prop == remove.Prop == lookup.Prop insert.InsType == remove.SetType == lookup.GetType name = insert.Prop element type = insert.InsType
public int size();public int elementAt(int index); public void setElementAt(int index, Object newVal);public void insertElementAt(int index, Object newVal);public void removeElementAt(int index, Object newVal)
public int size();public int settingAt(int index); public void setSettingAt(int index, Setting newVal);public void insertSettingAt(int index, Setting newVal);public void removeElementAt(int index);
46
Alternative Sequence properties with same access methods
insert = <void> insert.Prop.at( int, .InsType.)remove = <void> remove.Prop.at( int)index = <.GetType.> .Prop.At( int)set = <void> set.Prop.At( int, .SetType.)count = <int> count()property type = sequence access methods = insert, remove, index, count, set constraints insert.Prop == remove.Prop == index.Prop insert.InsType == remove.SetType == lookup.GetType name = insert.Prop element type = insert.InsType
public int count();public int settingAt(int index); public void setSettingAt(int index, Setting newVal);public void insertSettingAt(int index, Setting newVal);public void removeElementAt(int index);
47
Alternative Sequence properties with different access methods
insert = <void> insert.Prop.at( int, .InsType.)remove = <void> remove.Prop.at( int)iterate = Enumeration elements()set = <void> set.Prop.At( int, .SetType.)property type = sequence access methods = insert, remove, iterate, set constraints insert.Prop == remove.Prop == lookup.Prop insert.InsType == remove.SetType == lookup.GetType name = insert.Prop element type = insert.InsType
public Enumeration elements(); public void setSettingAt(int index, Setting newVal);public void insertSettingAt(int index, Setting newVal);public void removeElementAt(int index);
48
Reducing High Programming Cost Device developer must:
define the XML-based external representation of the device system does it automatically, mapping operations to
external representation translate the client operation-invocation and
variable-access requests to local operation-invocations based on its knowledge of the mapping it can
translate automatically announce variable change notifications
system does successive object diffs to announce events automatically
49
Device ObjectDiffer
Subscription Manager
Generating Events
Subscription Manager Separate from device Allows clients to register
interests in device Forwards announcements
to them Differ assumes subscription
manager exists Takes successive snapshots
When? How?
Client
register interest
forward event
50
When Snapshots Taken? Client requests
user refreshed wants the differences rather than complete values
Some client has taken an action on device informs some global object about it other clients can now be notified
Timer-based differ polls when upto date information not crucial
Device requests Differ.announce() vs. UPnP.announce(“Channel”, toString(getChannel());
More maintainable
51
How Snapshots Compared?
Operations diff(s1, s2) for each property p of s1 and s2
diffs += diff (s1.p1, s2.p2)
diff(o1,o2) returns a sequence of operations that when applied to o1 take it to o2.
52
How properties found?
Property extraction based on pattern specifications. But pattern specifications defined and interpreted by
user. matchedProperty.getMethod(“getter”).invoke (params) “getter” is user-defined
Also multiple access methods possible per property type indexing and iteration for sequences
Need a standard device-independent interface for each property constructor
property type = sequence access methods = getter, setter
...
53
Device Independent Interface Unix file operations for all devices
do not model structured objects UPnP
standard operation to read any variable no standard operation to write variable
client must determine device-specific write operation via relatedStateVariable clause
no programmer-defined types Need standard operations for each property
say indexing for sequence how mapped to device-specific methods?
54
Mapping Approaches Global table/registry
Standard OS approach may not have one to one
mapping from device-independent to device-dependent indexing to iteration
Mapping per device? Additional effort on device
programmer Per-pattern mapping
done by property handlers apply to multiple device
classes
Device
Mapper
Device-Indep
Device-Dep
read() get ()
write() set ()
DeviceProperty Handlers
Device
55
Property Handlers Specified in pattern
definition Implement device-
indep interface
property type = sequence access methods = elements, ... ... handlers lookup = IteratorToIndexing ...
interface Indexing { Object elementAt(Object target, MatchedProperty mp, int index;}
class IteratorToIndexing implements Indexing { ... Object elementAt(Object target, MatchedProperty mp, int index { Enumeration elements = mp.getMethod( ”elements")).invoke(target, null); for (i = 0; i < index; i++)
elements.nextElement(); return elements.nextElement(); }}
56
Three Levels of Indirection Level 0
Client calls operation directly device.elementAt(index) bound to specific names
Level 1 Client calls pattern-specific access methods
mp.getMethod(“index”).invoke(device, {index}) lookup may be bound to elementAt() or settingAt()
Level 2 Client calls property handler mp.getClass(“lookup”).newInstance().invoke ( device, mp, {index}) Independent of access methods
indexing iteration
57
Three Levels of Indirection
device1.elementAt (index) device2.settingAt(index)device3.iterate
()
mp.getAccessMethod(“index”). invoke(device, {index})
mp.getAccessMethod(“iterate”). invoke(device, {})
mp.getPropertyHandler (“lookup”). invoke(device, mp, {index})
58
Late Binding vs. Programmability/Efficiency
The later the binding the more levels of indirection the more awkward the programming the less efficient the program
Choose the minimum amount of indirection for the lateness desired
Device-independent interface meant really for system functions such as diff may be useful to clients
59
Vassil’s thesis Reduces programming cost
No cost of exporting functionality to distributed clients Like RPC, but accommodates late binding as UPnP
does dynamic service discovery
Reduces maintenance cost No duplication of information as it is all automatically
generated. Supports predefined and programmer-defined types
Makes reduction of programming and maintenance costs harder
60
Channel -> Current Channel requires 9 changes! getChannel -> getCurrentChannel setChannel -> setCurrentChannel
Reducing High Prog/Maintenance Cost
Information manually repeated multiple times operation implementation code action list state variable table message processing code event announcement code
2
Generated automatically
61
Device Operations
Access Controller
Event Generator
External Description Generator
Property Extractor
Subscription Manager
Inter-Process Communication
Reflection
Differ
Access Specification
Device Handler
Device-Independent Interface
Property Specification
Architecture