September 1, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Understanding Mobile Data Synchronization: Utilizing MS ActiveSync Capabilities at a High Level

  • August 17, 2005
  • By Alex Gusev
  • Send Email »
  • More Articles »

Getting Your Application AutoStarted

If all you need is to launch some application when a PDA is connected or disconnected, this is really a piece-of-cake task. ActiveSync uses two keys in the Registry to keep a list of all programs to run upon the above events:


HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows CE Services
                   AutoStartOnConnect
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows CE Services
                   AutoStartOnDisconnect

So, to execute your own application, simply add a value as in the following sample:


; Here, put the full path to your app, possibly with a command
; line to designate that it was launched on a device connection
[HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows CE Services
                    AutoStartOnConnect]
YourCompanyApp=notepad.exe

In this sample, notepad.exe will be called when the PDA connects successfully, either through its cradle or remotely. In your real environment, you then may recognize such a device by its ID and handle it somehow specifically.

Using Notifications to Control the Device's Connection

For more complicated cases, you have another opportunity—connection notifications. Windows helps you here and implements IDccMan, one of two interfaces responsible for this task. You in turn have to implement one of additional interfaces, IDccManSink or IDccManSink2. They are identical, but IDccManSink2 also supports the IPv6 protocol.

Take a look at the usual working flow. It is really simple:

  • Create an instance of IDccMan interface
  • Call IDccMan::Advise method to get notified about connections
  • Call IDccMan::Unadvise method when you no longer need notifications

Now let's take a closer look at IDccManSink declarations:


DECLARE_INTERFACE_ (IDccManSink,  IUnknown)
{
    STDMETHOD(OnLogIpAddr)        (THIS_ DWORD dwIpAddr) PURE;
    STDMETHOD(OnLogTerminated)    (THIS) PURE;
    STDMETHOD(OnLogActive)        (THIS) PURE;
    STDMETHOD(OnLogInactive)      (THIS) PURE;
    STDMETHOD(OnLogAnswered)      (THIS) PURE;
    STDMETHOD(OnLogListen)        (THIS) PURE;
    STDMETHOD(OnLogDisconnection) (THIS) PURE;
    STDMETHOD(OnLogError)         (THIS) PURE;
};
DECLARE_INTERFACE_ (IDccManSink2,  IDccManSink)
{
    STDMETHOD(OnLogIpAddrEx) (THIS_ const SOCKADDR_STORAGE*
                              pIpAddr) PURE;
};

You will find a short description of above methods in the following table:

Method Description
OnLogListen Indicates that the connection manager listens for incoming connections
OnLogTerminated Indicates that the connection manager has been shut down
OnLogAnswered Indicates that the connection manager has detected the communications interface
OnLogActive Indicates that a connection is established and fully operational
OnLogInactive Indicates a disconnection, or disconnected state
OnLogDisconnection Indicates that the connection manager has terminated the connection. It may be sent several seconds after actual disconnection
OnLogError Indicates that the connection manager failed to start communications
OnLogIpAddr Indicates that an IP address has been established for communications
OnLogIpAddrEx Indicates that an IP address has been established for communications, IDccManSink2 only

Now we can code our IDccManSink implementation. I left it pretty simple just to shape the idea. Full source you will find in article's sample project. Here I want to place only main loop:


CoInitialize(0);
IDccMan *pIDccMan = NULL;
HRESULT hr = CoCreateInstance(CLSID_DccMan,NULL,CLSCTX_SERVER,
                              IID_IDccMan,(void**)&pIDccMan);
if ( SUCCEEDED(hr) )
{
   CDevComDccSync DccSync;
   DWORD dwContext = 0;
   pIDccMan->Advise(&DccSync,&dwContext);
   SetConsoleTitle("Developer.com IDccManSink Sample");
   while (!kbhit());
   pIDccMan->Unadvise(dwContext);
   pIDccMan->Release();
}
else
{
   cout << "Failed to create IDccMan object: " << std::hex
        << hr << std::dec << endl;
}
CoUninitialize();

Our implementation of IDccManSink interface simply fakes a regular COM object. If you need to develop separate component which will be used by other applications, then you will have to add all standard COM stuff like ClassFactory and so forth. The sample's output is presented in Figure 1:

As you see, the connection manager informs your application about various phases of connection process. If you are going to use IP-based communications, you have PDA's address handy. Moreover, if WinCE device is connected via a cradle, the IP will indicate "localhost;" in other words, 127.0.0.1, so you will always know how device is connected.

Conclusion

This article has discussed simple yet useful techniques of managing a connectivity between Windows CE device and a desktop computer. I still haven't touched data synchronization itself, but anyway even now your application can use; for example, RAPI or WinSock to pass data back and forth. I'll describe more complicated data exchange and synchronization methods in coming articles.

Download

Download the accompanying code's zip file here

About the Author

Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. Now, he works at an international retail software company as a team leader of the Mobile R department, making programmers' lives in the mobile jungles a little bit simpler.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel