00001 /* 00002 * Funambol is a mobile platform developed by Funambol, Inc. 00003 * Copyright (C) 2003 - 2007 Funambol, Inc. 00004 * 00005 * This program is free software; you can redistribute it and/or modify it under 00006 * the terms of the GNU Affero General Public License version 3 as published by 00007 * the Free Software Foundation with the addition of the following permission 00008 * added to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED 00009 * WORK IN WHICH THE COPYRIGHT IS OWNED BY FUNAMBOL, FUNAMBOL DISCLAIMS THE 00010 * WARRANTY OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 00011 * 00012 * This program is distributed in the hope that it will be useful, but WITHOUT 00013 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00014 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more 00015 * details. 00016 * 00017 * You should have received a copy of the GNU Affero General Public License 00018 * along with this program; if not, see http://www.gnu.org/licenses or write to 00019 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 00020 * MA 02110-1301 USA. 00021 * 00022 * You can contact Funambol, Inc. headquarters at 643 Bair Island Road, Suite 00023 * 305, Redwood City, CA 94063, USA, or at email address info@funambol.com. 00024 * 00025 * The interactive user interfaces in modified source and object code versions 00026 * of this program must display Appropriate Legal Notices, as required under 00027 * Section 5 of the GNU Affero General Public License version 3. 00028 * 00029 * In accordance with Section 7(b) of the GNU Affero General Public License 00030 * version 3, these Appropriate Legal Notices must retain the display of the 00031 * "Powered by Funambol" logo. If the display of the logo is not reasonably 00032 * feasible for technical reasons, the Appropriate Legal Notices must display 00033 * the words "Powered by Funambol". 00034 */ 00035 00036 #ifndef INCL_SYNC_MANAGER 00037 #define INCL_SYNC_MANAGER 00038 /** @cond API */ 00039 /** @addtogroup Client */ 00040 /** @{ */ 00041 00042 #include "base/globalsdef.h" 00043 #include "base/util/ArrayList.h" 00044 #include "http/TransportAgent.h" 00045 #include "spds/constants.h" 00046 #include "spds/AbstractSyncConfig.h" 00047 #include "spds/SyncSource.h" 00048 #include "spds/SyncMLBuilder.h" 00049 #include "spds/SyncMLProcessor.h" 00050 #include "spds/CredentialHandler.h" 00051 #include "spds/CredentialHandler.h" 00052 #include "spds/SyncReport.h" 00053 00054 // Tolerance to data size for incoming items (106%) -> will be allocated some more space. 00055 #define DATA_SIZE_TOLERANCE 1.06 00056 00057 BEGIN_NAMESPACE 00058 00059 typedef enum { 00060 STATE_START = 0, 00061 STATE_PKG1_SENDING = 1, 00062 STATE_PKG1_SENT = 2, 00063 STATE_PKG3_SENDING = 3, 00064 STATE_PKG3_SENT = 4, 00065 STATE_PKG5_SENDING = 5, 00066 STATE_PKG5_SENT = 6 00067 } SyncManagerState ; 00068 00069 00070 /** 00071 * This is the core class which encodes the flow of messages between 00072 * client and server throughout a session. It is configured via the 00073 * DMTClientConfig with which it is constructed by the 00074 * SyncClient::setDMConfig() and the (optional) DevInf provided 00075 * to it by the client. 00076 */ 00077 class SyncManager { 00078 00079 public: 00080 /** 00081 * Initialize a new sync manager. Parameters provided to it 00082 * have to remain valid while this sync manager exists. 00083 * 00084 * @param config required configuration 00085 * @param report sync report reference to store sync results 00086 */ 00087 SyncManager(AbstractSyncConfig& config, SyncReport& report); 00088 ~SyncManager(); 00089 00090 /** 00091 * Prepares the sync, performing authentication and 00092 * device capability exchange. 00093 */ 00094 int prepareSync(SyncSource** sources); 00095 00096 /** 00097 * Starts the synchronization phase 00098 * 00099 * @return a status code for the sync. Can be: 00100 * 0 on success 00101 * an interal code (see: TODO) 00102 * a status code from the server 00103 */ 00104 int sync(); 00105 00106 /** 00107 * Performs the commit phase of the synchronization. 00108 */ 00109 int endSync(); 00110 00111 /** 00112 * Gathers the various bits and pieces known about the client and 00113 * its sources and builds a SyncML devinfo 1.1 instance. 00114 * 00115 * For simplicity reasons this function is called for the currently 00116 * active sync sources, changing them between runs thus causes 00117 * a (valid!) retransmission of the device info. 00118 * 00119 * @return device infos, to be deleted by caller, or NULL if unavailable 00120 */ 00121 DevInf *createDeviceInfo(); 00122 00123 private: 00124 00125 // SyncManager makes local key safe to use in SyncML by 00126 // encoding it as b64 if it contains special characters. The 00127 // SyncML standard says that the key should be a "URI" or 00128 // "URN"; we interpret that less strictly as "do not 00129 // include characters which actually break XML". 00130 // 00131 // Encoded keys are sent as "funambol-b64-<encoded original 00132 // key>". When receiving a key from the server it is only decoded 00133 // if it contains this magic tag, therefore an updated client 00134 // remains compatible with a server that already contains keys. 00135 static const char encodedKeyPrefix[]; 00136 00137 void encodeItemKey(SyncItem *syncItem); 00138 void decodeItemKey(SyncItem *syncItem); 00139 00140 // Struct used to pass command info to the method processSyncItem 00141 struct CommandInfo { 00142 const char* commandName; 00143 const char* cmdRef; 00144 const char* format; 00145 const char* dataType; 00146 long size; 00147 }; 00148 00149 DevInf* devInf; 00150 AbstractSyncConfig& config; 00151 SyncReport& syncReport; 00152 00153 CredentialHandler credentialHandler; 00154 SyncMLBuilder syncMLBuilder; 00155 SyncMLProcessor syncMLProcessor; 00156 TransportAgent* transportAgent; 00157 00158 SyncManagerState currentState; 00159 SyncSource** sources; 00160 ArrayList commands; 00161 ArrayList* mappings; 00162 00163 // Now using sources[i].checkState() method 00164 //int* check; 00165 00166 int sourcesNumber; 00167 int count; 00168 00169 /* A list of syncsource names from server. The server sends sources 00170 * modifications sorted as alerts in this list. This array is retrieved from 00171 * SyncMLProcessor::getSortedSourcesFromServer. 00172 */ 00173 char** sortedSourcesFromServer; 00174 00175 ArrayList** allItemsList; 00176 00177 StringBuffer syncURL; 00178 StringBuffer deviceId; 00179 int responseTimeout; // the response timeout for a rensponse from server (default = 5min) [in seconds] 00180 int maxMsgSize; // the max message size. Default = 512k. Setting it implies LargeObject support. 00181 int maxObjSize; // The maximum object size. The server gets this in the Meta init message and should obey it. 00182 bool loSupport; // enable support for large objects - without it large outgoing items are not split 00183 unsigned int readBufferSize; // the size of the buffer to store chunk of incoming stream. 00184 char credentialInfo[1024]; // used to store info for the des;b64 encription 00185 00186 // Handling of incomplete incoming objects by processSyncItem(). 00187 // Always active, even if Large Object support is off, 00188 // just in case the server happens to rely on it. 00189 // 00190 class IncomingSyncItem : public SyncItem { 00191 public: 00192 IncomingSyncItem(const WCHAR* key, 00193 const CommandInfo &cmdInfo, 00194 int currentSource) : 00195 SyncItem(key), 00196 offset(0), 00197 cmdName(cmdInfo.commandName), 00198 cmdRef(cmdInfo.cmdRef), 00199 sourceIndex(currentSource) { 00200 } 00201 00202 long offset; // number of bytes already received, append at this point 00203 const StringBuffer cmdName; // name of the command which started the incomplete item 00204 const StringBuffer cmdRef; // reference of the command which started the incomplete item 00205 const int sourceIndex; // the index of the source to which the incomplete item belongs 00206 } *incomingItem; // sync item which is not complete yet, more data expected 00207 00208 void initialize(); 00209 bool readSyncSourceDefinition(SyncSource& source); 00210 bool commitChanges(SyncSource& source); 00211 int assignSources(SyncSource** sources); 00212 00213 Status *processSyncItem(Item* item, const CommandInfo &cmdInfo, SyncMLBuilder &syncMLBuilder); 00214 bool checkForServerChanges(SyncML* syncml, ArrayList &statusList); 00215 00216 const char* getUserAgent(AbstractSyncConfig& config); 00217 bool isToExit(); 00218 void setSourceStateAndError(unsigned int index, SourceState state, 00219 unsigned int code, const char* msg); 00220 00221 00222 // Used to reserve some more space (DATA_SIZE_TOLERANCE) for incoming items. 00223 long getToleranceDataSize(long size); 00224 bool testIfDataSizeMismatch(long allocatedSize, long receivedSize); 00225 00226 /** 00227 * A wrapper around the sync source's first/next iterator functions. 00228 * By default the data is encoded according to the "encoding" 00229 * AbstractSyncSourceConfig property, unless the SyncSource already set an encoding. 00230 * 00231 * In case of an error the error is logged and the item is set to NULL, just as 00232 * if the source itself had returned NULL. 00233 */ 00234 SyncItem* getItem(SyncSource& source, SyncItem* (SyncSource::* getItem)()); 00235 00236 /** 00237 * Add the map command according to the current value of the 00238 * member 'mappings', and clean up the member afterwards. 00239 */ 00240 void addMapCommand(int sourceIndex); 00241 00242 }; 00243 00244 00245 END_NAMESPACE 00246 00247 /** @} */ 00248 /** @endcond */ 00249 #endif 00250