ActiveSync III

Dominic Salemno

Introduction

In the last segment I went over some basic details regarding the ActiveSync protocol. In this latest in a series, I want to touch on the ability to Sync a folder.

Initialization

Before the client grabs a list of folders from the server and syncs a particular folder, the client must issue an Autodiscover command followed by a Provision (I will be explaining these in future).

Synchronization

After a client determines configuration and security policy settings, the session should be in a state to allow the synchronization of data. By issuing a FolderSync command with a SyncKey of 0, we are telling the server to send us back a list of folders and their associated synchronization key.

 

Contained blow is a sample request to the server:

 

4.13.1.1   Request

 

POST /Microsoft-Server-

ActiveSync?Cmd=FolderSync&User=deviceuser&DeviceId=v140Device&DeviceType=PPC HTTP/1.1

Content-Type: application/vnd.ms-sync.wbxml

MS-ASProtocolVersion: 14.0

User-Agent: ASOM

Host: contoso.com

Content-Length: 13

Cache-Control: no-cache

Authorization: Basic YXJocnB6LWRvbVxzLmJvbGxlczpKJHAxdGVy

 

<?xml version="1.0" encoding="utf-8"?>

<FolderSync  xmlns="FolderHierarchy:">

  <SyncKey>0</SyncKey>

</FolderSync>

 

You’ll notice in our response we have each folder and associated ID (inside of <ServerId>) in an Add element:

 

4.13.1.2   Response

 

HTTP/1.1 200 OK

Content-Type: application/vnd.ms-sync.wbxml

X-MS-RP: 2.0,2.1,2.5,12.0,12.1,14.0

MS-ASProtocolVersions: 2.0,2.1,2.5,12.0,12.1,14.0

MS-ASProtocolCommands:

Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,DeleteColle

ction,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,MoveItems,GetItemEstim

ate,MeetingResponse,Search,Settings,Ping,ItemOperations,Provision,ResolveRecipients,ValidateC

ert

Date: Wed, 01 Apr 2009 06:33:13 GMT

Content-Length: 346

 

<?xml version="1.0" encoding="utf-8"?><FolderSync xmlns="FolderHierarchy:">

  <Status>1</Status>

  <SyncKey>1</SyncKey>

  <Changes>

    <Count>11</Count>

    <Add>

      <ServerId>1</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Calendar</DisplayName>

      <Type>8</Type>

    </Add>

    <Add>

      <ServerId>2</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Contacts</DisplayName>

      <Type>9</Type>

    </Add>

    <Add>

      <ServerId>3</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Deleted Items</DisplayName>

      <Type>4</Type>

    </Add>

    <Add>

      <ServerId>4</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Drafts</DisplayName>

      <Type>3</Type>

    </Add>

    <Add>

      <ServerId>5</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Inbox</DisplayName>

      <Type>2</Type>

    </Add>

    <Add>

      <ServerId>6</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Journal</DisplayName>

      <Type>11</Type>

    </Add>

    <Add>

      <ServerId>7</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Junk E-Mail</DisplayName>

      <Type>12</Type>

    </Add>

    <Add>

      <ServerId>8</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Notes</DisplayName>

      <Type>10</Type>

    </Add>

    <Add>

      <ServerId>9</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Outbox</DisplayName>

      <Type>6</Type>

    </Add>

    <Add>

      <ServerId>10</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Sent Items</DisplayName>

      <Type>5</Type>

    </Add>

    <Add>

      <ServerId>11</ServerId>

      <ParentId>0</ParentId>

      <DisplayName>Tasks</DisplayName>

      <Type>7</Type>

    </Add>

  </Changes>

</FolderSync>

 

Now that we have our list, we can send an initial Sync to the server with a SyncKey of 0 and the associated ServerId in the <CollectionId> element. In our example below, we are informing the server we only support the JobTitle and Department properties (this is referred to as ghosting properties). (Note: A Type value of 2 indicates we are synchronizing against Contacts; please see Page 42 of MS-ASCMD.)

 

4.13.2.1   Request

 

POST /Microsoft-Server-ActiveSync?Cmd=Sync&User=deviceuser&DeviceId=v140Device&DeviceType=PPC

HTTP/1.1

Content-Type: application/vnd.ms-sync.wbxml

MS-ASProtocolVersion: 14.0

User-Agent: ASOM

Host: exh-b-252

Content-Length: 20

Cache-Control: no-cache

Authorization: Basic YXJocnB6LWRvbVxzLmJvbGxlczpKJHAxdGVy

 

<?xml version="1.0" encoding="utf-8"?>

<Sync xmlns="AirSync:" xmlns:A1="POOMCONTACTS:">

  <Collections>

    <Collection>

      <SyncKey>0</SyncKey>

      <CollectionId>2</CollectionId>

      <Supported>

        <A1:JobTitle/>>

        <A1:Department/>>

      </Supported>

    </Collection>

  </Collections>

</Sync>

 

4.13.2.2   Response

 

HTTP/1.1 200 OK

Content-Type: application/vnd.ms-sync.wbxml

Date: Wed, 01 Apr 2009 06:35:02 GMT

Content-Length: 33

 

<?xml version="1.0" encoding="utf-8"?><Sync xmlns="AirSync:">

  <Collections>

    <Collection>

      <SyncKey>878266863</SyncKey>

      <CollectionId>2</CollectionId>

      <Status>1</Status>

    </Collection>

  </Collections>

</Sync>

 

In our response you will notice the SyncKey is different and we have a Status of 1. Following MS-ASCMD (ActiveSync Command Reference Protocol Specification) on Page 206, we can see that a Status value of 1 indicates that the server successfully completed the command. The new value contained in SyncKey is our initial value that we must use to get our initial set of objects from the server. The initial SyncKey of 0 was merely used to establish a relationship (think of building a session via Syn/Ack). Now that this relationship has been established, we can use our newly obtained SyncKey to synchronize against Contacts:

 

4.13.3.1   Request

 

POST /Microsoft-Server-ActiveSync?Cmd=Sync&User=deviceuser&DeviceId=v140Device&DeviceType=PPC

HTTP/1.1

Content-Type: application/vnd.ms-sync.wbxmlMS-ASProtocolVersion: 14.0

User-Agent: ASOM

Host: exh-b-252

Content-Length: 20

Cache-Control: no-cache

Authorization: Basic YXJocnB6LWRvbVxzLmJvbGxlczpKJHAxdGV

 

<?xml version="1.0" encoding="utf-8"?>

<Sync xmlns="AirSync:" xmlns:A1="POOMCONTACTS:">

  <Collections>

    <Collection>

      <SyncKey>878266863</SyncKey>

      <CollectionId>2</CollectionId>

      <DeletesAsMoves/>>

      <GetChanges/>>

    </Collection>

  </Collections>

</Sync>

 

After issuing our Sync with our SyncKey for this session, the server will respond with the set of objects in question.

 

4.13.3.2   Response

 

HTTP/1.1 200 OK

Content-Type: application/vnd.ms-sync.wbxml

Date: Wed, 01 Apr 2009 06:38:34 GMT

Content-Length: 448

 

<?xml version="1.0" encoding="utf-8"?><Sync xmlns:A1="POOMCONTACTS:"

xmlns:A12="POOMCONTACTS2:" xmlns:A17="AirSyncBase:" xmlns="AirSync:">

  <Collections>

    <Collection>

      <SyncKey>619052475</SyncKey>

      <CollectionId>2</CollectionId>

      <Status>1</Status>

      <Commands>

        <Add>

          <ServerId>2:1</ServerId>

          <ApplicationData>

            <A17:Body>

              <A17:Type>1</A17:Type>

              <A17:EstimatedDataSize>0</A17:EstimatedDataSize>

              <A17:Truncated>1</A17:Truncated>

            </A17:Body>

            <A1:WebPage>http://contoso.com</A1:WebPage>

            <A1:BusinessCountry>USA</A1:BusinessCountry>

            <A1:Department>Executive</A1:Department>

            <A1:Email1Address>"president@contoso.com"

&lt;president@contoso.com&gt;</A1:Email1Address>

            <A1:FileAs>Hassall, Mark</A1:FileAs>

            <A1:FirstName>Mark</A1:FirstName>

            <A1:HomeCity>Seattle</A1:HomeCity>

            <A1:HomeCountry>USA</A1:HomeCountry>

            <A1:HomePhoneNumber>(206) 555-0100</A1:HomePhoneNumber>

            <A1:HomePostalCode>98000</A1:HomePostalCode>

            <A1:HomeState>WA</A1:HomeState>

            <A1:HomeStreet>234 Main Street</A1:HomeStreet>

            <A1:BusinessCity>Seattle</A1:BusinessCity>

            <A1:MiddleName>I</A1:MiddleName>

            <A1:MobilePhoneNumber>(206) 555-0101</A1:MobilePhoneNumber>

            <A1:CompanyName>Contoso Inc.</A1:CompanyName>

            <A1:BusinessPostalCode>98000</A1:BusinessPostalCode>

            <A1:AssistantName>Andy Jacobs</A1:AssistantName>

            <A1:AssistantTelephoneNumber>(206) 555-0102</A1:AssistantTelephoneNumber>

            <A1:LastName>Hassall</A1:LastName>

            <A1:BusinessState>WA</A1:BusinessState>

            <A1:BusinessStreet>123 Main Street</A1:BusinessStreet>

            <A1:BusinessPhoneNumber>(206) 555-0103</A1:BusinessPhoneNumber>

            <A1:JobTitle>President</A1:JobTitle>

            <A1:OfficeLocation>TopFloor</A1:OfficeLocation>

            <A12:ManagerName>Roya Asbari</A12:ManagerName>

            <A17:NativeBodyType>1</A17:NativeBodyType>

          </ApplicationData>

        </Add>

      </Commands>

    </Collection>

  </Collections>

</Sync>

 

From this point on the client must always include the SyncKey received from the latest response from the server. For example, from this response we will have to use a SyncKey of 619052475 as this was the latest value returned to us from the server.

 

Summary

Stay tuned for the next article which will explain the Autodiscover and Provision commands.