ActiveSync III
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>https://contoso.com</A1:WebPage>
<A1:BusinessCountry>USA</A1:BusinessCountry>
<A1:Department>Executive</A1:Department>
<A1:Email1Address>"president@contoso.com"
<president@contoso.com></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.
Comments
Anonymous
October 12, 2010
Really helpful and interesting article ! Thanks ! (No matter but some xml in your article has two > instead of one)Anonymous
November 19, 2010
I want to provide the ability for a user to choose if a given folder should be sync'ed or not. I understand how to create a sync key with the server, but how do I tell the server, "i know we had this relationship established with folder id 10, but now I don't want it." It seems that remving the folder id from "Ping" won't do it completely since when I push new data from the device via the Sync command, I will get changes for folder 10. Please helpAnonymous
February 14, 2011
Is it possible to use the Fetch or the ItemOperations command to get all the contact information (not just what is indexed in the ANR via the GAL Search)? I would appreciate any kind of help with his.Anonymous
February 14, 2011
Currently, there are two options available to engage our team and get support on the open specifications:
- either you send the question to dochelp <at> winse.microsoft.com;
- or you post the question on one of the open specifications forums under social.msdn.microsoft.com/.../openspecifications Once you send us the request, we will happy to work with you and investigate this. Thanks!