diff --git a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m index 5f4502bc2..2c353f736 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher+Sync.m +++ b/ActiveSync/SOGoActiveSyncDispatcher+Sync.m @@ -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: @"%@", 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 and // 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: @""]; [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. diff --git a/ActiveSync/SOGoActiveSyncDispatcher.m b/ActiveSync/SOGoActiveSyncDispatcher.m index 5ce7a4d29..0c00c9d0d 100644 --- a/ActiveSync/SOGoActiveSyncDispatcher.m +++ b/ActiveSync/SOGoActiveSyncDispatcher.m @@ -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: @""]; + [s appendString: @""]; + [s appendString: @""]; + [s appendString: @"3"]; + [s appendString: @""]; - 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 { diff --git a/NEWS b/NEWS index 047e7ea08..094151ae8 100644 --- a/NEWS +++ b/NEWS @@ -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) -------------------