improved handling of EAS Push when no heartbeat is provided

This commit is contained in:
Ludovic Marcotte
2015-01-28 15:03:49 -05:00
parent 086361b79a
commit 981c718d22
3 changed files with 40 additions and 24 deletions
+23 -7
View File
@@ -1065,13 +1065,14 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
changeDetected: (BOOL *) changeDetected
maxSyncResponseSize: (int) theMaxSyncResponseSize
{
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey;
NSString *collectionId, *realCollectionId, *syncKey, *davCollectionTag, *bodyPreferenceType, *lastServerKey, *syncKeyInCache;
SOGoMicrosoftActiveSyncFolderType folderType;
id collection, value;
NSMutableString *changeBuffer, *commandsBuffer;
BOOL getChanges, first_sync;
unsigned int windowSize, v, status;
NSMutableDictionary *folderMetadata;
changeBuffer = [NSMutableString string];
commandsBuffer = [NSMutableString string];
@@ -1186,6 +1187,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[commandsBuffer appendFormat: @"<Responses>%@</Responses>", s];
}
folderMetadata = [self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]];
// If we got any changes or if we have applied any commands
// let's regenerate our SyncKey based on the collection tag.
if ([changeBuffer length] || [commandsBuffer length])
@@ -1196,7 +1199,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
{
// Use the SyncKey saved by processSyncGetChanges - if processSyncGetChanges is not called (because of getChanges=false)
// SyncKey has the value of the previous sync operation.
davCollectionTag = [[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"SyncKey"];
davCollectionTag = [folderMetadata objectForKey: @"SyncKey"];
if (!davCollectionTag)
davCollectionTag = [collection davCollectionTag];
@@ -1206,8 +1209,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
}
else
{
if (folderType == ActiveSyncMailFolder && [syncKey isEqualToString: @"-1"])
davCollectionTag = [collection davCollectionTag];
// Make sure that client is updated with the right syncKey. - This keeps vtodo's and vevent's syncKey in sync.
syncKeyInCache = [folderMetadata objectForKey: @"SyncKey"];
if (syncKeyInCache && !([davCollectionTag isEqualToString:syncKeyInCache]))
{
davCollectionTag = syncKeyInCache;
*changeDetected = YES;
}
}
// Generate the response buffer
@@ -1228,7 +1236,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// MoreAvailable breaks Windows Mobile devices if not between <Status> and <Commands>
// https://social.msdn.microsoft.com/Forums/en-US/040b254e-f47e-4cc1-a397-6d8393cdb819/airsyncmoreavailable-breaks-windows-mobile-devices-what-am-i-doing-wrong?forum=os_exchangeprotocols
if ([[self _folderMetadataForKey: [self _getNameInCache: collection withType: folderType]] objectForKey: @"MoreAvailable"])
if ([folderMetadata objectForKey: @"MoreAvailable"])
[theBuffer appendString: @"<MoreAvailable/>"];
[theBuffer appendString: commandsBuffer];
@@ -1373,6 +1381,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
defaultInterval = [defaults maximumSyncInterval];
internalInterval = [defaults internalSyncInterval];
// If the request doesn't contain "HeartbeatInterval" there is no reason to delay the response.
if (heartbeatInterval == 0)
heartbeatInterval = internalInterval = 1;
// We check to see if our heartbeat interval falls into the supported ranges.
if (heartbeatInterval > defaultInterval || heartbeatInterval < 1)
{
@@ -1389,7 +1401,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
allCollections = (id)[theDocumentElement getElementsByTagName: @"Collection"];
// We enter our loop detection change
for (i = 0; i < (defaultInterval/internalInterval); i++)
for (i = 0; i < (heartbeatInterval/internalInterval); i++)
{
s = [NSMutableString string];
@@ -1408,11 +1420,15 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[self logWithFormat: @"Change detected, we push the content."];
break;
}
else
else if (heartbeatInterval > 1)
{
[self logWithFormat: @"Sleeping %d seconds while detecting changes...", internalInterval];
sleep(internalInterval);
}
else
{
break;
}
}
// Only send a response if there are changes otherwise send an empty response.
+11 -17
View File
@@ -1806,30 +1806,24 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// We build the list of folders to "ping". When the payload is empty, we use the list
// of "cached" folders.
allCollections = (id)[theDocumentElement getElementsByTagName: @"Folders"];
allCollections = (id)[theDocumentElement getElementsByTagName: @"Folder"];
allFoldersID = [NSMutableArray array];
if (![allCollections count])
{
SOGoMailAccounts *accountsFolder;
SOGoMailAccount *accountFolder;
SOGoUserFolder *userFolder;
NSArray *allValues;
// We received an empty Ping request. Return status '3' to ask client to resend the request with complete body.
s = [NSMutableString string];
[s appendString: @"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[s appendString: @"<!DOCTYPE ActiveSync PUBLIC \"-//MICROSOFT//DTD ActiveSync//EN\" \"http://www.microsoft.com/\">"];
[s appendString: @"<Ping xmlns=\"Ping:\">"];
[s appendString: @"<Status>3</Status>"];
[s appendString: @"</Ping>"];
userFolder = [[context activeUser] homeFolderInContext: context];
accountsFolder = [userFolder lookupName: @"Mail" inContext: context acquire: NO];
accountFolder = [accountsFolder lookupName: @"0" inContext: context acquire: NO];
d = [[s dataUsingEncoding: NSUTF8StringEncoding] xml2wbxml];
allValues = [[accountFolder imapFolderGUIDs] allValues];
for (i = 0; i < [allValues count]; i++)
[allFoldersID addObject: [NSString stringWithFormat: @"mail/%@", [[allValues objectAtIndex: i] substringFromIndex: 6]]];
[theResponse setContent: d];
// FIXME: handle multiple GCS collecitons
[allFoldersID addObject: @"vcard/personal"];
[allFoldersID addObject: @"vevent/personal"];
[allFoldersID addObject: @"vtodo/personal"];
return;
}
else
{
+6
View File
@@ -1,3 +1,9 @@
2.2.15 (2015-XX-XX)
-------------------
Enhancements
- improved handling of EAS Push when no heartbeat is provided
2.2.14 (2015-01-20)
-------------------