December 21, 2014
Hot Topics:

Developing ActiveSync Service Providers: The First Look

  • September 14, 2005
  • By Alex Gusev
  • Send Email »
  • More Articles »

IReplObjHandler Implementation

As noted above, the second part of the device part implementation of ASP is the IReplObjHandler interface. In the case of Windows CE, you don't need to code all standard COM orchestration, but rather develop a class that simply inherits from this interface and fulfills its methods. Hence, it may be declared like this:

class CASPSimpleFolder;
class CASPSimpleObjHandler : public IReplObjHandler
{
protected:
   long              m_cRef;
   PREPLSETUP        m_pWriteSetup;
   PREPLSETUP        m_pReadSetup;
   CASPSimpleFolder *m_pFolder;
   LPBYTE            m_pReadPacket;
private:
   virtual ~CASPSimpleObjHandler();
public:
   CASPSimpleObjHandler(CASPSimpleFolder *pFolder);
   //======== IUnknown methods ==============//
   STDMETHODIMP_(ULONG)    AddRef(void);
   STDMETHODIMP_(ULONG)    Release(void);
   STDMETHODIMP            QueryInterface(const IID& iid,
                                          void **ppv);
   //======== IReplObjHandler methods ==========//
   STDMETHODIMP Setup(PREPLSETUP pSetup);
   STDMETHODIMP Reset(PREPLSETUP pSetup);
   STDMETHODIMP GetPacket(LPBYTE *lppbData,
                          DWORD *pcbData,
                          DWORD cbRecommend);
   STDMETHODIMP SetPacket(LPBYTE lpbData, DWORD cbData);
   STDMETHODIMP DeleteObj(PREPLSETUP pSetup);
};

As you can see, this object is responsible for Item's data manipulation (serialization/deserialization/deletion). It also is notified when 'send' and 'receive' operations are about to begin or to end. You will shortly cover them all here; you will find additional details when the sample project is posted.

Setup and Reset

This function is called before ActiveSync does anything with a synchronized item. Therefore, you can perform all required initialization here. The Windows CE part of ASP uses only a few members of the REPLSETUP struct:

  • fRead—Detects whether Item is about to be read or written. ActiveSync is a mutlithreaded application, so it may send and receive data at the same time.
  • oid—Identifies the object.
  • oidNew—Identifies the newly created object.
  • dwFlagsRSF_NEW_OBJECT designates that the new object should be added to the property database.

The simplest implementations looks like this:

STDMETHODIMP CASPSimpleObjHandler::Setup(PREPLSETUP pSetup)
{
   if(pSetup == NULL)
   return E_INVALIDARG;
   //
   // TODO: Called before GetPacket() or SetPacket() is called.
   // We could be reading and writing at the same time, so we
   // need to store the setup ptr away. Add any initialization
   // code here, before starting serializing/de-serializing.
   //
   if(pSetup->fRead)
   {
      m_pReadSetup = pSetup;
      m_pReadPacket = new BYTE[MAXDATASIZE];
      // we can handle upto MAXDATASIZE bytes of data
      if(m_pReadPacket == NULL)
         return E_OUTOFMEMORY;
   }
   else
   {
      m_pWriteSetup = pSetup;
   }
   return S_OK;
}

In turn, the Reset method is the right place to release all allocated resources:

STDMETHODIMP CASPSimpleObjHandler::Reset(PREPLSETUP pSetup)
{
   if(pSetup == NULL)
   return E_INVALIDARG;
   //
   // TODO: Called right after GetPacket() or GetPacket() calls
   // are completed. Add any cleanup code here.
   //
   if(m_pReadPacket)
   {
      delete [] m_pReadPacket;
      m_pReadPacket = NULL;
   }
   else
   {
      //
      // On writing, update the object ID and time stamp
      // stored in the data file
      //
      m_pFolder->SetFileOID(m_pWriteSetup->oidNew);
      m_pFolder->UpdateFileTime();
   }
   return S_OK;
}

GetPacket and SetPacket

These functions are called to perform a conversion of a synchronized item to or from byte stream representation. There is nothing much to comment about here because actual implementation depends on your data structure. Let me just note a few things.

GetPacket can create several packets from one data chunk. For efficiency, the packet size shouldn't exceed 8K. In such multipacket conversions, GetPacket will return NOERROR for all created packets and RWRN_LAST_PACKET for the last one.

SetPacket adds given data into ASP storage and places an object identifier into the oid member of the previously saved REPLSETUP variable. If the update has failed for some reason, SetPacket returns RERR_SKIP_ALL to discard all upcoming packets.

DeleteObj

This function is called to delete items from the store, that's all. It takes an object identifier from the REPLSETUP parameter to determine what to do.

Conclusion

First, the accompanying code's zip file will be posted along with next article describing the desktop part of ASP. Recently, you were acquainted with the simplest part of all the business. Even though, an application developer always has 'black job' to do, so be it. In the next article, you will complete the desktop ASP components and also cover the registration procedure.

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.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel