In the last post we saw how to create a package and use that for downloading set of files.
Writing Device Agent
What do I get if I write an my own agent?
- You can reliably start your agent. When the start call is completed you are guaranteed that your agent has started running in device.
- You can create stream independent of the underlying transport mechanism. You need not worry about whether DMA or TCP is the underlying transport.
- You can use the streams for your device-desktop interaction
- You need not worry about serializing and de-serializing the data you send.
- We provide a packet class which could be used to send and receive most of the basic data types.
Let’s see how we can write a device agent.
When an agent is started in device, it should call ‘AcknowledgeLaunch’.
Calling AcknowledgeLaunch signifies 2 things.
- Agent conveys that it has done with all its initialization and ready to accept connections from desktop
- It also registers the set of Ids that will be used to create streams.
Here is the code snippet to do AcknowledgeLaunch
hMod = ::LoadLibrary(L "DeviceAgentTransport.dll");
if(hMod == NULL)
pfnGetDeviceService = (GetDeviceAgentTransportFunction) ::GetProcAddress(hMod,L"GetDeviceAgentTransport");
if( NULL == pfnGetDeviceService)
hr = pfnGetDeviceService(out_pTransport);
//We got the DeviceAgentTransport. Call acknowledgelaunch to indicate all initializations are done.
hr = out_pService->AcknowledgeLaunch(count,lpServiceIds);
Now, the Device agent is ready to accept connections…
out_pService ->AcceptConnectionEx(lpServiceId ,&out_pStream);
AcceptConnectionEx is analogous to TCP accept call. This is a blocking call and will wait till a Connect (CreatePackaetStream) call is made from desktop with the same serviced. Note that this serviced has to be one among the registered service Ids (in AcknowledgeLaunch).
Send receive Packets
Let’s send some packets to desktop.
We need to create a packet, write the info into the packet and send the packet in stream.
HINSTANCE hMod = ::LoadLibrary(L "DeviceAgentTransport.dll");
packFunc = (GetNewPacketFunc) ::GetProcAddress(hMod, L"GetNewPacket");
if( NULL == packFunc)
writePacket->WriteString(szSendString); //Some string to be sent to desktop
Just like in TCP, Read is a blocking call. Below call will wait till some data is sent from the desktop.
So far we are discussing about how the device agent will look like. We will look at the desktop counterpart for this.
//PackageId is the Guid corresponding to the package we want to deploy
RemoteAgent mRemoteAgent = Device.GetRemoteAgent(new ObjectId(packageID));
//This will start the agent. This call will be blocked till AcknowledgeLaunch is called in device side.
//This is the connect call.
//This will unblock the AcceptConnectionExe in device
DevicePAcketStream mStream = mRemoteAgent.CreatePacketStream(streamId);
Packet pkt = new Packet();
pkt = mStream.Read();
string msg = pkt.ReadString();
Below is the sequence diagram for the desktop and device interaction
In next post we will look at actual File Viewer written using CoreCon API's.