
You are here: MyURC.org > Tools & Prototypes > UCHe > tutorial > Writing a TA
How to Write a Target Adapter (TA)
Table of Contents
Understand the UCH Architecture
Please refer to the UCH specification.
Write Your TA
Your TA must implement the ITA Interface, and may use any method of the ITAListener interface. Implement the Interface IUpdateListener (only required for UPnP Targets).
ITA has the following methods:
void init(ITAListener *taListener, map taProps, map uchProps)
init() is called only once by the UCH prior to any other method of TA when any target is discovered in the network. UCH decides to instantiate this TA for communicating with that particular Device (for which this TA is implemented).
Store the reference to 'taListener' for sending updates/events to UCH which are further forwarded to Client through the appropriate UIPM (selected by the Client).
One of the uchProps keys - 'docRoot' points to the property defined in uch.config file under the <uch> tag. In UCH offline mode, please put the TD, UIS and RSHEET's for this TA in the docRoot. You can also create sub-folders in the docRoot for convenience. The reason to keep them in the 'docRoot' path, is because the TD and UIS are also served to clients from that path like: http://192.168.0.1/UCH/.../xxx.td and http://192.168.0.1/UCH/.../xxx.uis
void registerTarget(string targetId, map<string, void*> *targetProps)
It is called when target is registered in UCH.'targetProps' Map has the Device properties that are parsed by the TDM and forwarded to the UCH.
TA should parse Target Description File(.td) and its Socket Description Files(.uis) and get the Elements which are used to save state/value of the Device discovered from network.
If TA has to subscribe to services of the Device, then TA should subscribe to all such services, for sending updates to Controllers.
Note that if same type of Device is discovered in network then UCH does not cteate new instance of TA.Instead UCH just invokes registerTarget() of already intantiated TA. So TA must have capability to handle multiple Devices of the same type.
-
The UCH asks for permission to open a session with a specified client on a specified socket. Note that this function asks for permission only, and is not supposed to actually open a session.
TA should check targetId, socketName and clientProps whether they are appropriate and valid to open a session with this target.
If requirements are fulfilled then TA should return below mentioned key/value pair in return Map.
- "result", "A".
If requirements are not fulfilled, but TA knows of any other TA that can open session with this client then TA should return below mentioned key/value pair in return Map.
- "result", "F".
- "targetName", "[Name of Target]".
- "socketName", "[Name of Socket]".
- "authorizationCode", "[AuthorizationCode]"
- Otherwise TA should reject the request and return below mentioned key/value pair in return Map.
- "result", "R".
-
If the TA had accepted an open session request (see above), and if the UCH succeeded in the necessary steps to open a session with the client, the UCH will call sessionOpened and provide the sessionId pertaining to the new session.
Now TA should open a new session for the client and possibly maintain a new copy of the elements of that socket for this new session. If TA programmer wants, they can escape maintaining a copy of elements and instead always go to actual Device for latest values/updates.
In future, when any request comes to TA for this session then it will process the request with the locally stored elements of this new session or directly go to the actual Device for latest updated values.
map<string, string> *getValues(string sessionId, list<string>* paths)
TA decides whether it get the values from Device or return the value stored with the element of that session.
TA should return Map of elementPath v/s. value.
-
TA should change the value/state of Device as per the new value requested for the given 'path'. If caching is done locally then cache should be updated accordingly.
If caching is done then TA is responsible to make changes to all sessions of this target.
If device send updates if any of its value/state is changed then TA should send updates to the UCH and if caching then update the values of all sessions.
SetValue, InvokeCommand, AddDimension, RemoveDimension and Notify Acknowledgement all are handled with this method.
void sessionClosed(String sessionId)
TA should clean up all the information regarding to the session specified by 'sessionId', and update the actual Device if necessary.
Note that if all sessions are closed with one particular target and if TA had subscribed to any of the services of the actual Device then it should unsubscribe to all the services.
unregisterTarget(string targetId)
When any target is discarded/removed from the network then UCH invokes this method.
TA should clean up all the information regarding to the target specified by 'targetId'.
It should close all the sessions with this target as well as invoke abortSession() of ITAListener.
Note that if TA has subscribed for any services of the actual Device then it should unsubscribe to all the services at this point.
TDMs are target discovery modules and are responsible for searching the device in network. Type of device searched varies from TDM to TDMS. TDM must instantiate Control Point for searching devices. Control Point started by TDM will register itself to the UCH and UCH will store it’s reference in UCHLocalStore. Whenever TA wants to register itself for the updates from the network devices, TA will retrieve the control point reference from UCHLocalStore and will register itself for updates in that Control Point.
For example, upnpTDM has initiated the upnpControlPoint, which will search the upnp devices and updates the TDM. Now if TA want to register for updates(events), then following code will do the functionality:
IUCHStore *uchStore = taListener->getLocalUCHStore(); If(uchStore !=NULL){ Void *upnpCP = uchStore->getValue(“edu.wisc.trace.uch.tdm.upnp.lib.IUpnpControlPoint”); If(upnpCP!=NULL){ try{ (static_cast<IUpnpControlPoint*>(upnpCP))->addUpdateListener(this); }catch(…){ } } }Now, whenever updates(events) are received by the upnpControlPoint, it will directly sent this to TA instead of TDM.
Using the same upnpControlPoint reference TA can perform other functions like subscribe to upnp device, perform upnp action etc. Please see documentation for IUpnpControlPoint
- ITA.h
- ITAListener.h
- TargetDescription.h
- Session.h
- IUpdateListener.h
- LoggerUtil.h #if developer wants to use logging system of UCH
- IUpnpControlPoint.h
- IUpnpControlPointListener.h
Make Your TA a Dynamic Library
Please refer to How to create a dynamic library.
Configure the UCH to Use Your TA
Please refer to How to Modify the UCH Configuration File.
Last update: Gottfried Zimmermann, Parikshit Thakur & Team, 2008-12-03