Digging Into The Exchange ActiveSync Protocol

ActiveSync is hardly a new topic on this blog. And once more I’ll be looking into an aspect of it, that I don’t believe I’ve covered in detail before. Let’s start a little easy, and see if we end up with some more knowledge of how to test/debug/play with Exchange ActiveSync. I am making the assumption you are already aware of the basics like setting up devices and installing servers.

Playing the numbers
Microsoft like all other software companies use versioning to differentiate the releases of their products. This applies even if the product name has nothing to do with where in the line of releases you are. Windows 7 is a nice exception, with it actually being version 7 of Windows too. (Now, we’re not counting minor releases of course.) Exchange, Office, and some other products are coordinated, and Exchange 2010 is version 14 – or “wave 14” in Microspeak. For ActiveSync this is an indicator as to what kind of functionality you can expect – for instance certain features might require Exchange 2007 server side, and Windows Mobile 6.0 client side. (Which unsurprisingly means you might have discrepancies between your Exchange server, and your ActiveSync device, but the server side is backwards compatible so this is not an issue as such.)

Server side you can find out the details in this location:
image

As you can see the main version is in the directory path, but if you check properties for the dll files you can see the complete build number:
image

On the client side things might be a bit different – there are after all a lot of different clients out there. This is from a Windows Phone 6.5.3 (when synced up with Exchange 2010):
image 
HKCU\Software\Microsoft\ActiveSync\Partners\{GUID}

For some strange reason you need to establish a partnership before you can read out which version your device supports. Sort of silly if you ask me, but I didn’t find any other key. Maybe it’s intended to reflect the version in use, as negotiated with the server, and not what the device is capable of.

Well, clever me for finding my way through the registry I suppose… It doesn’t offer much value knowing this by itself. But a not uncommon issue I encounter what with Apple, Nokia, and everyone implementing ActiveSync is knowing what is actually implemented. Oh, sure, you can sync. But can you sync tasks? Or text messages? If in doubt ask the vendor which EAS version they support.

Admittedly these numbers aren’t interesting by themselves any which way you look at it. Looking at another registry key under the same hive we find something called “CommandsSupported” which contains a comma separated list. Here’s what my list looks like:
Sync,SendMail,SmartForward,SmartReply,GetAttachment,GetHierarchy,CreateCollection,
DeleteCollection,MoveCollection,FolderSync,FolderCreate,FolderDelete,FolderUpdate,
MoveItems,GetItemEstimate,MeetingResponse,Search,Settings,Ping,ItemOperations,
Provision,ResolveRecipients,ValidateCert

Now I do not know the meaning of all of these commands by heart (Microsoft has them documented on MSDN), but for instance “SmartForward” means the ability to receive a mail with an attachment, and forward it with the attachment intact, without needing to download the attachment to the device and upload to the server first thus saving some traffic on your data plan. These commands are used in the HTTP POST the device communicates to the Exchange Server. More on that later.

Some of the other registry values are fairly self explanatory, and I’m not digging into these, you will be able to figure out some on your own 🙂 While you can usually always (seemingly) modify a value it might be that you’re not really editing it, as some keys may very well be a read-only representation of a setting stored somewhere else. If this is the case you probably do not have easy access to modify the source.

I believe I’ve mentioned before that ActiveSync is implemented as a series of HTTP POST/GET methods and not a wsdl web service. But let’s recap quickly; this means you can in theory play the ActiveSync game through your browser. However you’ll most likely see a title like this in your browser if you try to surf to the address directly:
image

If you get the 501/505 error it means that ActiveSync is responding, so it’s not worthless but it’s not telling you a lot either. It is one of the first things I check when I’ve configured ActiveSync on a server – because if you’re not getting this response something might be wrong.

Now if what you want is a quick diagnostic or health check of your ActiveSync service you can check out http://www.testexchangeconnectivity.com for Microsoft’s “Exchange Remote Connectivity Analyzer”, and this tool might indicate if you’re on the right track to a working sync solution. This requires that ActiveSync is exposed to the Internet (which usually is the end goal with EAS), and is not provided as a stand-alone utility you can run on your desktop computer on the LAN. As far as I can tell it reports Exchange 2007 RTM as the supported client version (12.0), and while it will work (and provide good help for) Exchange 2010 it’s not updated so if you for instance uncheck “Allow non-provisionable devices” in your ActiveSync policy you’ll get a 403 error even if that is not entirely accurate (it is by design however). But maybe it’s updated by the time you read this, so don’t rely on my little experiment for this one 🙂

If you want to perform the test your self, and get your hands dirty, read on 🙂

Using the browser to surf is so…end-user isn’t it? To get the HTTP 200 return code you want, you have to hand craft the HTTP POST yourself. I would recommend checking out Fiddler from MSFT: http://www.fiddler2.com (There are of course other options out there too if you have other preferences.)

So, what have you got for me dear Exchange
There’s two parts to building this request; the POST string, and the request headers. Let’s look at the string first.

ActiveSync HTTP POST
Your Exchange server is published to the Internet at an address like https://sync.contoso.com. The virtual directory for ActiveSync (and what you might use in a publishing rule on your ISA/TMG Server) is /Microsoft-Server-ActiveSync. The following parameters string along (bad pun intended):
User – The username. (Only the user alias, not the domain part.)
DeviceId – A unique id for the device that is synchronizing.
DeviceType – An id for the device/model you are using, or the ActiveSync client.
Cmd = The command you want to execute

So say I’ve got this same Windows Mobile device as above a complete string could look like this:
https://sync.contoso.com/Microsoft-Server-ActiveSync?User=andreas&DeviceId=1234&DeviceType=Pocket_PC&Cmd=Sync

ActiveSync Request Headers
If you only provide this POST you’re no further than using the browser – you also need to specify a couple of parameters for the request header:
User-Agent – The user agent of the HTTP client; could be MSFT-PPC/5.2.5300.
Content-Length – A requirement of the POST method and the length of the request. (Set to 0 to have Fiddler calculate it for you.)
Authorization – A base64 encoded string formatted as such (before encoding) domain\username:password.
Content-Type – The MIME type of the content. Should be application/vnd.ms-sync.WBXML.
MS-ASProtocolVersion – The client version of ActiveSync. Set to 14.0 in our example.

A complete example would look like this in Fiddler (use HTTP 1.1 as protocol version):
image

If you get a 403 error check that the username&password combo is correctly encoded.

If it works as expected you should see a HTTP /1.1 200 OK response. It seems you’ll get an empty response body if using the DeviceId of a device that has an ActiveSync partnership configured, whereas using a “fake” id there will be a body.  If you inspect the response body returned you’re not likely to see much useful though – for two reasons:
– It’s WBXML so you’ll need to decode it to something readable.
– And if you do you’ll find some error since you didn’t supply all the necessary commands for a full sync in your POST. (As a side note the “Sync” command is one of few commands that are accepted with headers only and an empty body.)

But still, we’re getting somewhere as opposed to the 501/505 we saw earlier 🙂

The sync shown above is just a quick connectivity test – it does not explain how an actual device would interact with Exchange. You might say I started in the wrong end, but in troubleshooting you often try the easy things first before you go all in. While the HTTP 501/505 will identify issues DNS errors, SSL trust issues, and general reachability of the server, the HTTP 200 response (or lack thereof) might identify application level issues.

Being Exchange ActiveSync
So, let’s say I emulate what a clean device would do when going through the configuration wizard. The first part would actually be the AutoDiscover, but this is optional and on most devices you can skip it if you like. (I also don’t consider it a “core” ActiveSync feature.) The next step is pulling down some info from the server through HTTP OPTIONS as the terminology goes. Execute this one (remember correct credentials for this request too):
 image

And you’ll get a response header like this:
image

OPTIONS is one of the things that the Exchange Remote Connectivity Analyzer tests, and it’s not entirely uncommon for this to fail in some scenarios. You don’t configure this on your Exchange Server, and it’s not likely you did something wrong installing your Client Access Server. But some firewalls with tightened security might block the OPTIONS keyword/method. ActiveSync clients may or may not work properly if OPTIONS is blocked (implementation specific). A symptom might be that you’re not able to use all the features your Exchange version provides.

The next thing you would do is do the initial synchronization job. This is done by issuing the “FolderSync” command. And this is where things start to get interesting/challenging/frustrating (strike out the non-applicable ones) 🙂

Do you remember the first sync
There are two accepted methods for stringing together the URI used in the POST. The one we saw above, and a base64 encoded variant – so it would be something like http://sync.contoso.com/Microsoft-Server-Activesync/?abc1234

Now if it was as easy as doing a base64 of the ?User=andreas… variant above you could just use an encoder and figure it out. But it’s not that easy. For instance the server version is also encoded into the URI, and unless you happen to be really good at bytes versus strings you’re not going to be able to do the math without utilities. The good thing? You don’t have to do this. Both methods – plain-text and base64 are accepted. The last one uses a few bytes less and can probably be considered more efficient  with regards to bandwidth, but personally I don’t see this as an issue. As far as I can tell Windows Mobile devices use base64, while Nokias and the iPhone use plain-text. (This is only an observation for a few select models and might not reflect the implementation for all of these devices.)

Next challenge? At this point you have to provide a request body, and not just an empty header. As so many other things coming to interacting with web interfaces this is done through writing down some xml. The xml required for the initial synchronization would be similar to this:
<?xml version=”1.0″ encoding=”utf-8″?>
<FolderSync xmlns=”FolderHierarchy:”>
  <SyncKey>0</SyncKey>
</FolderSync>

Looks easy enough. Oh, wait, that’s right – there’s an additional step. You need to compact it to binary xml – or wbxml as the formal name is. Which means something like “32 00 12 …”. This is also a task you’re not likely to do without a utility, but although you probably cannot convert in your head you can convert with a hex editor if you are so inclined. Just remember that you cannot enter a string of bytes if you’re using Fiddler, and you have to enter a text representation of the bytes. I’ll admit that at this point I ran into problems using Fiddler for this very reason. These bytes will not encode properly in Fiddler and I had to write up some C# code to do it right. (And while this is relevant I’m not going into the details right now as to not further confuse matters.) Just trust me when I say the request body looks like this:
 image
(If you are interested in the byte sequence – here goes: 03 01 6a 00 00 07 56 52 03 30 00 01 01.)

This time around you must include the following headers:
– Content-Type: application/vnd.ms-sync.wbxml
– User-Agent: xyz
– MS-ASProtocolVersion (see numbers above)
– Authorization
– X-MS-PolicyKey (see below for explanation)

So what should you expect as the response? Well, this would be dependent on which Exchange server you happen to be querying. There are currently three Exchange releases that support ActiveSync – Exchange 2003, Exchange 2007 and Exchange 2010. (Exchange 2003 requires Service Pack 2 for DirectPush, but supports EAS in RTM. Not that I know of many 2003 deployments without SP2…) Exchange 2003 provided a rather lackluster selection of policies that you could implement. Exchange 2007 improved on this and also introduced the concept of non-provisionable devices meaning devices that are not able to implement the desired policies. With Service Pack 1 for Exchange 2007 came the requirement that you could not activate ActiveSync for a user without defining a policy (in RTM this was optional). The policy could be “empty” in the sense that you didn’t actually set any policies, and I think you might be able to “hack” your way around it with PowerShell, but proper behavior is to have a policy. Exchange 2010 doesn’t really add much in the policy department as compared to Exchange 2007, and works similar for the scenario we are playing out.

So what does this boil down to? Well, as I said I’m having problems building the request properly with Fiddler, but we can inspect the traffic with Fiddler. After attempting this FolderSync Exchange now wants to know if you are able to do provisioning, and will want you to actually do the provisioning before you are allowed to do the FolderSync. I have not tested this syncing against Exchange 2003, and it might behave differently. The results I got (working against an Exchange 2010 server) were the following:
Request Header: MS-ASProtocolVersion: 12.0 – X-MS-PolicyKey not present
image

Request Header: MS-ASProtocolVersion: 12.0 – X-MS-PolicyKey: 0
image

Request Header: MS-ASProtocolVersion: 14.0 – X-MS-PolicyKey not present
For this I get a HTTP 200 so I have to check the HexView of the response to learn the details
image 
I see “141” meaning:
“A policy is in place but the device is not provisionable.”

Request Header: MS-ASProtocolVersion: 14.0 – X-MS-PolicyKey: 0
image
Same here, but this time I see “142” meaning:
”There is a policy in place, the device needs to provision.”

There was no psychic guessing involved – I just spotted the numbers and deduced it might be the values referenced in this table:
http://msdn.microsoft.com/en-us/library/ee218647(EXCHG.80).aspx

I reject your policies, and substitute my own
Here’s where it get’s funny. The next thing is that there are some requests and responses going back and forth asking for the provisioning xml. The device then tries another “FolderSync” after it has pulled down the policies. If you have disabled the “allow non-provisionable devices” setting Exchange will say “hold on there boy, have you actually implemented the policies I sent you?” The device will hopefully say yes, and the command will be processed server side. (There are some details I’ve left out – like some simple “keys” generated so you can’t hi-jack the session, but these details aren’t relevant for the bigger picture.) This is entirely an issue of trust, and Exchange cannot actually check if the policies have been applied. So let me re-phrase this behavior in other words: If I do not like your pesky policies, I can implement a client that will always respond that policies are ok regardless of whether the device supports them or not. I can ignore them completely!

This means that if you really want to make sure your users are using the power-on-password feature you cannot do this with Exchange by itself. I’m definitely repeating myself here trying to bring a message across – but you cannot properly implement a strategy for handling mobile devices without having two additional things:
– An MDM solution that will handle management of devices. This includes policy enforcement.
– An ISA/TMG server, ISAPI filter or something similar that will inspect what kind of devices are trying to synchronize the data from the Exchange server.

But back to the topic at hand 🙂
To do this I have to issue a HTTP POST with the “Provision” command using a value of 0 for X-MS-PolicyKey. Exchange will respond with the provisioning xml, and a new temporary PolicyKey. My client will then apply the proper actions, and after this is done I report back to the server with the temporary key and a value of 1 as status indicating I have implemented these policies. I will then be issued the final PolicyKey which I have to include in subsequent operations. (If  you change the policies this triggers a new provisioning/PolicyKey cycle on the device.) And yes; I have checked that I can get this working 🙂 (I did a lot of manual byte manipulations as I have not yet written proper parsers to automate things.)

What you get in return from the server after we have played the policy charade will still be in the user-friendly wbxml format, but you will be able to recognize item types you’ve got in your Outlook if you inspect the response. The names will be localized to your chosen language – not sure which variable controls this server side, but that’s an Exchange thing.

Going further from here you can use other commands too like sending mail, etc. While that is a nice thing, it is a bit further than I planned at the moment since the intention of this article was to provide some background for a deep dive troubleshooting session if you ever run into a tricky ActiveSync issue. It also works, (in my opinion), as a primer for understanding the ActiveSync protocol, and not just the configuration & setup bits.

A few tips if you want to play with this on your own:
– WireShark (www.wireshark.org) can parse wbxml if you want to sniff the traffic.
– When learning/debugging it’s much easier if you run the traffic over HTTP rather than HTTPS. Depending on your Exchange server this might be disabled by default and have to be specifically enabled. (Do remember to switch it back on after testing.)

If you want more detail than I’m ever going to be able to supply check out the MSDN library:
http://msdn.microsoft.com/en-us/library/cc425499(EXCHG.80).aspx

It might not be what you’re likely to read as bedtime stories, but it does provide pretty much everything MSFT will release to the general public for the time being. You’ll be interested in the ones starting with “MS-AS”.

I know I indicated a couple of paragraphs ago I resorted to using Fiddler only for inspecting the traffic, and actually creating the requests in code. And you might be feeling that leaves some of this as a theoretical exercise since I didn’t provide an app. Theory will only get you so far, and actually being able to test it proper provides a greater value for most people. I do apologize for that, but I felt that mixing in code in this article would possibly make it less understandable/readable and scare away the non-programmers. I am working on this separately however, and I’m looking to release some sort of utility to help you along the way.

Phew, that was a longer run than expected – so till next time; get to it and start “breaking” your ActiveSync 🙂

30 thoughts on “Digging Into The Exchange ActiveSync Protocol”

  1. Hi,
    This post is very useful for the development purpose. I would like to ask a query in this regard.

    As per the specification document [MS-ASCMD].pdf, using sync command [2.2.1.19.1.6 Add] we can use the “Add” operation to add one item from client to the server. But it is explicitly mentioned in the document that “The element cannot be used to add any e-mail items from the client to the server”.

    Then how can the client add email items from client to the server in the “Drafts” folder ?This is required as the client should allow the user to add email items to the drafts folder and later sync the items with the server

  2. Good question 🙂

    I have not tested this (yet) so I do not know what happens if you try to do this. What I assume MSFT might be making references to is the fact that mail should not be sent through this command. (This requires SendMail as per 2.2.1.15.) It is not recommended to store items directly to the “Sent Items” folder, and this behaviour is present in Exchange Web Services too to my knowledge.

    The “Drafts” folder should be treated as any other folder I guess. But always add the items client-side, and not directly to server-side. Exchange and ActiveSync doesn’t differentiate between email and other items on the database level. If it’s a mail item or a calendar item is just an attribute. The “Add” command will not let you add MIME-formatted data as the “SendMail” command requires either so you can’t add emails in that sense.

    But, if you add the item to the local Drafts folder – shouldn’t it be synced to the server through the “Sync” command? (You obviously need some data storage mechanism device-side to handle this.)

    But as I said, I have not tried this so I cannot be sure how it works 🙂

  3. Thanks for the informative article. I was asked to set up monitoring using nagios for our exchange server, specifically the active sync portion of it, and the information you presented here enabled me to do (somewhat) better than just seeing if I got a web response. Specifically, using the information you presented I’ve implemented a system that uses the OPTIONS method as illustrated in your article to query the server for the AS version running. Thanks!

  4. Thank you for the tutorial. It worked perfectly for once (the sync command that is). However right after that I keep getting HTTP 400 (Bad request) errors. Do you know how I can debug this. I am not sure what I am doing wrong. I have tried with two different Exchange servers, but I seem to be getting the same error. Would appreciate any assistance. Here is my POST method

    https:///Microsoft-Server-Activesync?User=&DeviceId=123412341234&DeviceType=PocketPC&Cmd=Sync

    Host:
    User-Agent: Android
    Content-Length: 0
    Authorization: Basic
    Content-Type: application/vnd.ms-sync.wbxml
    MS-ASProtocolVersion: 14.0

  5. And this is when testing with Fiddler? What version Exchange are you testing against? I have just done a test against my Exchange 2010 SP1 box, and get the same error. This might be related to a similar error I am seeing with Exchange 2007 SP2/SP3. I am investigating if there are some changes in the EAS protocol that I am not aware of.

  6. I tested against Exchange 2007 and Exchange 2003. I tested using both Fiddler and a C# client that sends the data via a POST message. In both cases I see the same error.

  7. I wasn’t able to reproduce it on my E2K10 box again – possibly due to tweaking some other things there.
    For Exchange 2007 12.0 or 12.1 would be the correct values to use for MS-ASProtocolVersion (12.0 for RTM, 12.1 for SP1/2/3.)
    For Exchange 2003 the value is 2.0 or 2.5 if I remember corrrectly. I haven’t tested on a 2003 server though.
    Setting the incorrect protocolversion might cause issues like this.

    If you are running a proper environment you’re probably running SSL on the EAS dir, and I find this to be a major hassle when developing/debugging/testing. I always do it over plain HTTP. (I actually just got error 400 when connecting to the HTTPS variant on a 2007 server.)

    Also make sure in an environment with mixed versions of Exchange that the user account you use has the mailbox located on that specific server. (Not sure how it plays out with a lot of different CAS and MBX servers.)

  8. Hi Andreas!

    I was really happy to find your article! I was spending last days trying to get my Acer Liquid synchronize with my office EAS server. All I was able to get – is Error 500 in response. I know my colleagues were able to Sync easily using their iPhones, and other phones. But there is only me who is trying to use Android. Unfortunately I will not be able to get any kind of support from our IT support, so I need to dig it myself.

    One positive thing is that when trying to use my Wife’s Samsung GD540 – it configures and Syncs fine!! It is also android
    The bad thing is that I already tried 3 different 3rd party softwares on my Liquid – and nothing was working.

    What I am thinking of – maybe if someone have a Playground Exchange – I can try to login from both phones and compare data exchange to understand what my phone communicates wrong? Maybe you have such server?
    Or maybe you have another clue …

  9. Androids can be a lot of fun depending on what version they happen to be running. Some of them are unfortunately not as compatible with Exchane as they claim to be. If there is an Android 2.2 firmware available that usually works nicely with Exchange 2003 and 2007 while there are some reports about problems with Exchange 2010. (I do not know what you are running server side. )

    There are providers offering hosted Exchange, and while I am not aware of any free Exchange servers there might be some free trials. Unfortunately it doesn’t really tell much about why it’s not working with your Exchange server at work since there are a number of possible configurations of the server. While your IT department will not be able to support you I suppose they can check basic things like whether your account is allowed to sync, and whether they are trying to apply any policies which can cause some devices to fail.

    Error 500 can be related to both the device, the user account used, and the server and can be difficult to track down. I don’t know if you have tested my EAS diagnostic tool? (Available in the downloads section.) You can check if you get any useful output with that and report back. Test first without checking “Provisionable” and “Support security policies”, and then check those two boxes as necessary afterwards. If you get error 142 when both are checked just change the device id.

  10. Hi,

    I tried to make search request to Exchange server by EAS protocol but i’m getting Numeric number 3 in response. what is reason? how to solve please help me.

  11. Hi,

    I’m working on Android(java), tried to make email search request to Exchange server by EAS protocol but i’m getting Numeric number 3 in response, but same code is working for GAL(Global address lookup)as store name but not for store name as a Mailbox, what is reason? how to solve please help me.

    Thanks

  12. Hi Andreas,

    I’m trying to build an ActiveSync library and am currently stuck at the first try to send the wbxml code. Apparently Exchange is terminating the handshake because it doesn’t recognize my request code.

    Comparing it with your wbxml example, I see that you don’t send the actual codes as defined in the FolderHierarchy codepage, but add 64 to them. Can you explain why?

    Here is my Request in plain xml and the encoded variant:

    0

    03 01 6a 00 00 07 16 12 03 30 00 01 01

    Your variant:
    03 01 6a 00 00 07 56 52 03 30 00 01 01

    Thanks for your help!

  13. Because 64 is a magic number?

    No, that’s probably not the reason 🙂

    I can’t remember the link to the msdn page I used as reference material. But the initial FolderSync is an “empty” sync request. You don’t need to include the folder hierarchy, (this is part of what you’re interested in acquiring), and since you haven’t synced before you don’t have a sync key either. So the first sync key is 0, and you know that the max length of the sync key is 64 characters. This is just the way my initial wbxml works out I guess – not able to give a better explanation at the moment.

    Your xml was filtered out by the WordPress commenting system which doesn’t allow that kind of text so I’m not able to compare notes on that part.

  14. Actually, the 64 is 0x40, ie bit 6 on.
    This is defined in the WAP Binary XML spec: http://www.w3.org/1999/06/NOTE-wbxml-19990624/#_Toc443384904 (I don’t see it anywhere in the MS-ASWBXML doc on MSDN).

    From that w3.org spec:
    “Bit 6 Indicates whether this tag begins an element containing content. If this bit is zero, the tag contains no content and no end tag. If this bit is one, the tag is followed by any content it contains and is terminated by an END token”

    Without bit 6 on (ie, sending 0x16 instead of 0x56) you’re telling Exchange that there’s no content in your element, which isn’t true, so it rejects the request.

  15. Hi,

    Thanks for the detailed explanation.I would like to ask something. For EAS, I want to download the headers only(not body of the mail).So which command i shall use or else what is the way to download the headers only.

    Please help me out.

    Thanks in Advance,
    Neha

  16. I am also getting a 400 Bad Request Error. We are using EXCHANGE 2007 and the supported ASPProtocolVersion based on your OPTIONS strategy shows that 1.0…12.0,12.1 are supported. I used this in the POST headers to the server and still get 400 BAD Request.

    https://xxxxxxx.com/Microsoft-Server-ActiveSync?User=userx&DeviceId=12345&DeviceType=Pocket_PC&Cmd=Sync

    User-Agent: MSFT-PPC/5.2.5300
    Content-Length: 0
    Authorization: Basic bmV0XHN0b3Jtc2FnZTpwYXNzd29yZA==
    Content-Type: application/vnd.ms-sync.WBXML
    MS-ASProtocolVersion: 12.0

    The response in fiddler is
    HTTP/1.1 400 Bad Request
    Cache-Control: private
    Content-Type: text/html
    Server: Microsoft-IIS/7.0
    X-AspNet-Version: 2.0.50727
    MS-Server-ActiveSync: 8.3
    X-Powered-By: ASP.NET
    Date: Fri, 11 Nov 2011 17:10:03 GMT
    Connection: close

    Bad Request

    Any ideas what could be the problem?

  17. Is this hand-crafted with Fiddler? I’m not sure why, but Exchange does not always seem to like POST requests with a content-length of 0. (Zero-length POSTs serve no purpose though…) If you’re testing with Fiddler it seems the GET is the only test that will give you the basic info you want for verifying that the server is online (in addition to using OPTIONS of course).
    For further tests I recommend my EAS MD utility available in the downloads section – you can inspect the results in Fiddler of course. There’s also source code available if you want to implement your own tools.

  18. Very helpful. But for me, the EAS MD applicaiton gives an “Unhandled Exception error” when I run the Full Sync test.

    The Response is incomplete, and has:

    http://msdn.microsoft.com/en-us/library/ee218647(v=EXCHG.80).aspx
    Testing FolderSync:
    /Microsoft-Server-ActiveSync?Cmd=FolderSync&User=xyz.onmicrosoft.com&DeviceId=EASMD&DeviceType=FakeDevice
    HTTP 200 – OK
    Response body
    More status codes can be looked up here:
    http://msdn.microsoft.com/en-us/library/ee218647(v=EXCHG.80).aspx

    Index out of range. Parameter Name: index.

    See the end of this message for details on invoking
    just-in-time (JIT) debugging instead of this dialog box.

    ************** Exception Text **************
    System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
    Parameter name: index
    at System.ThrowHelper.ThrowArgumentOutOfRangeException()
    at System.SZArrayHelper.get_Item[T](Int32 index)
    at System.Linq.Enumerable.ElementAt[TSource](IEnumerable`1 source, Int32 index)
    at WBXML.WBXMLReader.ConumeHeader(IList`1 document)
    at WBXML.WBXMLReader.Parse(IList`1 document)
    at WBXML.WBXMLConverter.Parse(IList`1 document)
    at EAS_MD.frmEAS.btnFullTest_Click(Object sender, EventArgs e)
    at System.Windows.Forms.Control.OnClick(EventArgs e)
    at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
    at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    at System.Windows.Forms.Control.WndProc(Message& m)
    at System.Windows.Forms.ButtonBase.WndProc(Message& m)
    at System.Windows.Forms.Button.WndProc(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    ************** Loaded Assemblies **************
    mscorlib
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5466 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/Microsoft.NET/Framework64/v2.0.50727/mscorlib.dll
    —————————————-
    EAS_MD
    Assembly Version: 1.7.1.0
    Win32 Version: 1.7.1.0
    CodeBase: file:///C:/Users/VenkatRangan/Downloads/EAS_MD/EAS_MD_1.71.exe
    —————————————-
    System.Windows.Forms
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5460 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Windows.Forms/2.0.0.0__b77a5c561934e089/System.Windows.Forms.dll
    —————————————-
    System
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5466 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System/2.0.0.0__b77a5c561934e089/System.dll
    —————————————-
    System.Drawing
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5462 (Win7SP1GDR.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Drawing/2.0.0.0__b03f5f7f11d50a3a/System.Drawing.dll
    —————————————-
    WBXML
    Assembly Version: 1.0.0.0
    Win32 Version: 1.0.0.0
    CodeBase: file:///C:/Users/VenkatRangan/Downloads/EAS_MD/WBXML.DLL
    —————————————-
    System.Xml.Linq
    Assembly Version: 3.5.0.0
    Win32 Version: 3.5.30729.5420 built by: Win7SP1
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Xml.Linq/3.5.0.0__b77a5c561934e089/System.Xml.Linq.dll
    —————————————-
    System.Core
    Assembly Version: 3.5.0.0
    Win32 Version: 3.5.30729.5420 built by: Win7SP1
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Core/3.5.0.0__b77a5c561934e089/System.Core.dll
    —————————————-
    System.Xml
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Xml/2.0.0.0__b77a5c561934e089/System.Xml.dll
    —————————————-
    System.Configuration
    Assembly Version: 2.0.0.0
    Win32 Version: 2.0.50727.5420 (Win7SP1.050727-5400)
    CodeBase: file:///C:/Windows/assembly/GAC_MSIL/System.Configuration/2.0.0.0__b03f5f7f11d50a3a/System.Configuration.dll
    —————————————-

    ************** JIT Debugging **************
    To enable just-in-time (JIT) debugging, the .config file for this
    application or computer (machine.config) must have the
    jitDebugging value set in the system.windows.forms section.
    The application must also be compiled with debugging
    enabled.

    For example:

    When JIT debugging is enabled, any unhandled exception
    will be sent to the JIT debugger registered on the computer
    rather than be handled by this dialog box.

  19. My application invokes the API for the First Sync with:

    03 01 6a 00 00 07 56 52 03 30 00 01 01

    I get back content-length of 15 and

    03 01 6a 00 00 07 56 4c 03 31 34 32 00 01 01

    Evidently, something went wrong.

    The EAS MD gives me 382 bytes of proper folder hierarchy. All data seem to match on the wire.

  20. I can’t spot any errors by a brief look – it looks ok. (I’m not converting the timezone in my head, but that’s optional anyways and as you say it doesn’t work without it either.)
    I have only performed quick investigations into the calendar syncs previously, so I can’t tell you exactly what a good entry looks like (without sniffing the traffic on the wire from a known good client).
    I have considered doing a post on calendar sync, and produce code for it, but I haven’t gotten around to it yet.

  21. Thanks for helpful article.I am new in this filed and have gotten a active sync project recently . the server and client are working good in mail but when server read a unread mail ,the client does not change but when client read a unread mail the server shows changes.
    I could follow based on your information in your article :

    serverProtocolVersions MS-ASProtocolVersions: 1.0,2.0,2.1,2.5,12.0,12.1
    Request Method: POST
    Query string: User=postmaster&DeviceId=ApplDX3HX5EHDPMW&DeviceType=iPhone&Cmd=Ping
    input message encoding: UTF-8
    unCompressedLength: null

    ActiveSyncrequest….
    authorization: Basic bWFpbi5hcHBsaWNhdGlvbi5jb21ccG9zdG1hc3Rlcjpwb3N0bWFzdGVy
    contentType: application/vnd.ms-sync.wbxml
    user: postmaster
    deviceId: ApplDX3HX5EHDPMW
    deviceType: iPhone
    cmd: Ping
    acceptMultiPart: false
    collectionId: null
    itemId: null
    saveInSent: null
    attachmentName: null
    MS-ASProtocolVersion: 12.1

    MsSyncWbxmlParser:

    1270

    Email-MTI1LTEtMS0xLTEO-46fNA
    Email

    resumeNotifyDevice count is 7
    previousPing is not null for HypersyncPrincipal{id=3, device=Device{id=’ApplDX3HX5EHDPMW’}, user=SyncUser{id=’1′, userId=’OTAtMS1udWxsLW51bGwtMRGND79C’, email=’postmaster@main.application.com’}, active=true, ctpNumOfRetries=4, deviceTimeZone=’null’, modificationCode=0, pollLockedBy=’sara-pc**app’, pollLockedOn=2015-10-25 17:57:45.0, push=true, pushSent=2015-10-25 15:59:30.0, smsNumOfRetries=0, stpNumOfRetries=0}
    A new PingProcessor was set, the principal is HypersyncPrincipal{id=3, device=Device{id=’ApplDX3HX5EHDPMW’}, user=SyncUser{id=’1′, userId=’OTAtMS1udWxsLW51bGwtMRGND79C’, email=’postmaster@main.application.com’}, active=true, ctpNumOfRetries=4, deviceTimeZone=’null’, modificationCode=0, pollLockedBy=’sara-pc**app’, pollLockedOn=2015-10-25 17:57:45.0, push=true, pushSent=2015-10-25 15:59:30.0, smsNumOfRetries=0, stpNumOfRetries=0}
    clazz is [Email] so we query db for SyncOption.
    syncOption for [Email] is SyncOption{id=4, filterType=3, conflict=null, mimeTruncation=1, mimeSupport=0, clazz=’Email’, maxItems=null, bp1Type=1, bp1TruncationSize=500, bp1AllOrNone=null, bp1Preview=null, bp2Type=null, bp2TruncationSize=null, bp2AllOrNone=null, bp2Preview=null}
    [FilterType] getNumberOfDays – filterType is [3]
    [LastSyncTimestamp] checkForChangesAndModifyCounter – noChangeCounter is [18] token is [null] lastSync is {serverlastSyncTime=2015-10-25 14:07:19.0, lastModified=2015-10-25 14:07:19.0, targetURI=’Email-MTI1LTEtMS0xLTEO-46fNA’, serverNextSync=1445870145733, id=26, principal=HypersyncPrincipal{id=3, device=Device{id=’ApplDX3HX5EHDPMW’}, user=SyncUser{id=’1′, userId=’OTAtMS1udWxsLW51bGwtMRGND79C’, email=’postmaster@main.application.com’}, active=true, ctpNumOfRetries=4, deviceTimeZone=’null’, modificationCode=0, pollLockedBy=’sara-pc**app’, pollLockedOn=2015-10-25 17:57:45.0, push=true, pushSent=2015-10-25 15:59:30.0, smsNumOfRetries=0, stpNumOfRetries=0}, lastItemId=Ni0xLTEtMS0xNDdFlc0SqA, noChangeCounter=18, nDay=7, pushSent=false, syncStart=null, syncKey=1445870078961, lastContinuesStartTime=2015-10-18 00:00:00.0, pushSent=false, pushPaused=false, nextSync=2015-10-26 14:35:45.733, synced=false, syncFailed=false}
    [LastSyncTimestamp] checkForChangesAndModifyCounter – noChangeCounter is [18] lastModified is [2015-10-25 14:07:19.0] and lastSync is [2015-10-25 14:07:19.0] – anyChanges is [false]
    [LastSyncTimestamp] this.nDay is [7] and nDay is [7] so checkForChangesAndModifyCounterConsiderNDay is [false]
    [EmailActiveSyncAdapter] no change so we won’t call mailFacade.getCount
    [HyperGetItemEstimateAdapter] collectionId is Email-MTI1LTEtMS0xLTEO-46fNA and estimate is 0
    [AbstractPingProcessor] about to suspend for [1255]

    I have no idea for that I hope you could guide me for this.

    thanks

Leave a Reply

Your email address will not be published. Required fields are marked *

*