Imported Upstream version 1.2.99~20120606~SE~ff65aef~SYSYNC~2728cb4
[platform/upstream/syncevolution.git] / src / synthesis / src / sysync / syncsession.h
1 /*
2  *  TSyncSession
3  *    Represents an entire Synchronisation Session, possibly consisting
4  *    of multiple SyncML-Toolkit "Sessions" (Message composition/de-
5  *    composition) as well as multiple database synchronisations.
6  *
7  *  Copyright (c) 2001-2011 by Synthesis AG + plan44.ch
8  *
9  */
10
11 #ifndef SYNC_SESSION_H
12 #define SYNC_SESSION_H
13
14 // general includes (SyncML tookit, windows, Clib)
15 #include "sysync.h"
16
17 // specific includes
18 #include "syncappbase.h"
19 #include "localengineds.h"
20 #include "remotedatastore.h"
21 #include "profiling.h"
22 #include "scriptcontext.h"
23
24
25 namespace sysync {
26
27 extern const char * const SyncMLVerProtoNames[numSyncMLVersions];
28 extern const SmlVersion_t SmlVersionCodes[numSyncMLVersions];
29 extern const char * const SyncMLVerDTDNames[numSyncMLVersions];
30 extern const char * const SyncMLDevInfNames[numSyncMLVersions];
31 #ifndef HARDCODED_CONFIG
32 extern const char * const SyncMLVersionNames[numSyncMLVersions];
33 #endif
34
35 extern const char * const authTypeNames[numAuthTypes];
36
37 extern const char * const SyncModeNames[numSyncModes];
38
39 #ifdef SYDEBUG
40 extern const char * const PackageStateNames[numPackageStates];
41 extern const char * const SyncOpNames[numSyncOperations];
42 #endif
43
44 extern const char * const SyncModeDescriptions[numSyncModes];
45
46
47 // secret type for SessionLogin
48 typedef enum {
49   // Note: changes here will change AUTHTYPE() script func API in ODBC-Agent!
50   sectyp_anonymous, // anonymous
51   sectyp_clearpass, // clear text password
52   sectyp_md5_V10, // SyncML V1.0 MD5
53   sectyp_md5_V11 // SyncML V1.1 MD5
54 } TAuthSecretTypes;
55
56
57 // minimal free message size required to end message
58 // %%% rough approx, should always be enough
59 #define SIZEFORMESSAGEEND 200
60
61
62 // Container types
63 typedef std::list<TRemoteDataStore*> TRemoteDataStorePContainer; // contains data stores
64
65
66
67 // forward declaration
68 class TSyncAppBase;
69 class TSmlCommand;
70 class TStatusCommand;
71 class TSyncHeader;
72 class TLocalEngineDS;
73 class TRemoteDataStore;
74 class TRootConfig;
75
76
77 #ifdef SCRIPT_SUPPORT
78
79 // publish as derivates might need it
80 extern const TFuncTable ErrorFuncTable;
81
82 typedef struct {
83   TSyError statuscode;
84   TSyError newstatuscode;
85   bool resend;
86   TLocalEngineDS *datastoreP;
87   TSyncOperation syncop;
88 } TErrorFuncContext;
89
90 typedef struct {
91   bool isPut;
92   bool canIssue;
93   TSyError statuscode;
94   string itemURI;
95   string itemData;
96   string metaType;
97 } TGetPutResultFuncContext;
98
99 #endif // SCRIPT_SUPPORT
100
101
102 #ifndef NO_REMOTE_RULES
103
104 class TRemoteRuleConfig; // forward
105
106 typedef std::list<TRemoteRuleConfig *> TRemoteRulesList;
107
108 // remote party special rule
109 class TRemoteRuleConfig: public TConfigElement
110 {
111   typedef TConfigElement inherited;
112 public:
113   TRemoteRuleConfig(const char *aElementName, TConfigElement *aParentElementP);
114   virtual ~TRemoteRuleConfig();
115   // properties
116   // - identification of remote
117   string fManufacturer;
118   string fModel;
119   string fOem;
120   string fFirmwareVers;
121   string fSoftwareVers;
122   string fHardwareVers;
123   string fDevId;
124   string fDevTyp;
125   // - options specific for that remote party (0=false, 1=true, -1=unspecified)
126   sInt8 fLegacyMode; // set if remote is known legacy, so don't use new types
127   sInt8 fLenientMode; // set if remote's SyncML should be handled leniently, i.e. not too strict checking where not absolutely needed
128   sInt8 fLimitedFieldLengths; // set if remote has limited field lengths
129   sInt8 fDontSendEmptyProperties; // set if remote does not want empty properties
130   sInt8 fDoQuote8BitContent; // set if 8-bit chars should generally be encoded with QP in MIME-DIR
131   sInt8 fDoNotFoldContent; // set if content should not be folded in MIME-DIR
132   sInt8 fNoReplaceInSlowsync; // do not use Replace (as server) in slow sync (this is to COMPLETELY avoid replaces being sent during slowsync, for clients that crash on that such as old 9210)
133   sInt8 fTreatRemoteTimeAsLocal; // treat remote time as localtime even if it carries different time zone information ("Z" suffix or zone spec)
134   sInt8 fTreatRemoteTimeAsUTC; // treat remote time as UTC even if it carries different time zone information (no suffix or zone spec)
135   sInt8 fVCal10EnddatesSameDay; // send end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive) instead of midnight of next day (exclusive, like in iCalendar 2.0)
136   sInt8 fIgnoreDevInfMaxSize; // ignore <maxsize> specification in CTCap (when device has bad specs like in E90 for example)
137   sInt8 fIgnoreCTCap; // ignore entire ctcap
138   sInt8 fDSPathInDevInf; // use actual DS path as used in Alert for creating datastore devInf (needed for newer Nokia clients)
139   sInt8 fDSCgiInDevInf; // also show CGI as used in Alert for creating datastore devInf (needed for newer Nokia clients)
140   sInt8 fUpdateClientDuringSlowsync; // do not update client records (due to merge) in slowsync (However, updates can still occur in first-time sync and if server wins conflict)
141   sInt8 fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!)
142   sInt8 fAllowMessageRetries; // allow that client sends same message ID again (retry attempt)
143   sInt8 fStrictExecOrdering; // requires strict SyncML-standard ordering of status responses
144   sInt8 fTreatCopyAsAdd; // treat COPY like ADD (needed for Calmeno/Weblicon clients)
145   sInt8 fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style)
146   sInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited, -1=not specified
147   TCharSets fDefaultOutCharset; // default charset for generation
148   TCharSets fDefaultInCharset; // default charset for input interpretation
149   TSyError fRejectStatusCode; // if >=0, attempt to connect will always be rejected with given status code
150   sInt8 fForceUTC; // force sending time in UTC (overrides SyncML 1.1 <utc/> devInf flag)
151   sInt8 fForceLocaltime; // force sending time in localtime (overrides SyncML 1.1 <utc/> devInf flag)
152   #ifndef MINIMAL_CODE
153   string fRemoteDescName; // descriptive name of remote
154   #endif
155   #ifdef SCRIPT_SUPPORT
156   string fRuleScriptTemplate; // template for rule script
157   #endif
158   // DevInf in XML format which is to be used instead of the one sent by peer.
159   // If set, it is evaluated after identifying the peer based on the DevInf
160   // that it has sent and before applying other remote rule workarounds.
161   // XML DevInf directly from XML config.
162   string fOverrideDevInfXML;
163   SmlDevInfDevInfPtr_t fOverrideDevInfP;
164   VoidPtr_t fOverrideDevInfBufferP;
165   // list of subrules to activate
166   TRemoteRulesList fSubRulesList;
167   // flag if this is a final rule (if matches, no more rules will be checked)
168   bool fFinalRule;
169   // flag if this is a subrule (cannot match by itself)
170   bool fSubRule;
171 protected:
172   // check config elements
173   #ifndef HARDCODED_CONFIG
174   virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine);
175   #endif
176   virtual void clear();
177 }; // TRemoteRuleConfig
178
179
180
181 #endif // NO_REMOTE_RULES
182
183 // session config
184 class TSessionConfig: public TConfigElement
185 {
186   typedef TConfigElement inherited;
187 public:
188   TSessionConfig(const char *aElementName, TConfigElement *aParentElementP);
189   virtual ~TSessionConfig();
190   // Properties
191   // - session timeout (in seconds)
192   sInt32 fSessionTimeout;
193   // - Maximally supported SyncML version
194   TSyncMLVersions fMaxSyncMLVersionSupported;
195   // - Minimally supported SyncML version
196   TSyncMLVersions fMinSyncMLVersionSupported;
197   // - support of server alerted sync codes
198   bool fAcceptServerAlerted;
199   #ifndef NO_REMOTE_RULES
200   // - list of remote rules
201   TRemoteRulesList fRemoteRulesList;
202   #endif
203   // - simple auth
204   string fSimpleAuthUser;
205   string fSimpleAuthPassword;
206   // - local datastores
207   TLocalDSList fDatastores;
208   #ifndef MINIMAL_CODE
209   // - logfile
210   string fLogFileName;
211   string fLogFileFormat;
212   string fLogFileLabels;
213   bool fLogEnabled;
214   uInt32 fDebugChunkMaxSize;
215   #endif
216   bool fRelyOnEarlyMaps; // if set, we rely on early maps sent by clients for adds from the previous session
217   // defaults for remote-rule configurable behaviour
218   bool fUpdateClientDuringSlowsync; // do not update client records (due to merge) in slowsync (However, updates can still occur in first-time sync and if server wins conflict)
219   bool fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!)
220   bool fAllowMessageRetries; // allow that client sends same message ID again (retry attempt)
221   uInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited
222   sInt32 fRequestMinTime; // min time [seconds] spent until returning answer (for debug purposes, 0=no minimum time)
223   bool fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style)
224   // default value for flag to send property lists in CTCap
225   bool fShowCTCapProps;
226   // default value for flag to send type/size in CTCap for SyncML 1.0 (disable as old clients like S55 crash on this)
227   bool fShowTypeSzInCTCap10;
228   // default value for sending end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive)
229   // instead of midnight of next day (exclusive, like in iCalendar 2.0)
230   bool fVCal10EnddatesSameDay;
231   // instead of folding long lines (as required by the standard) use one line per property
232   bool fDoNotFoldContent;
233   // - set if we should show default parameter in mimo_old types as list of <propparam>s for each value
234   //   Note that this is a tristate: 0=no, 1=yes, -1=auto (=yes for <SyncML 1.2, no for >=SyncML 1.2,
235   //   thus making it work for Nokia 7610 (1.1) as well as E-Series like E90)
236   sInt8 fEnumDefaultPropParams;
237   // decides whether multi-threading for the datastores will be used
238   bool fMultiThread;
239   // defines if the engine waits with continuing interrupted commands until previous part received status
240   bool fWaitForStatusOfInterrupted;
241   // accept delete commands for already deleted items with 200 (rather that 404 or 211)
242   bool fDeletingGoneOK;
243   // abort if all items sent to remote fail
244   bool fAbortOnAllItemsFailed;
245   // - Session user time context (what time zone the current session's user is in, for clients w/o TZ/UTC support)
246   timecontext_t fUserTimeContext;
247   #ifdef SCRIPT_SUPPORT
248   // session init script
249   string fSessionInitScript;
250   // Error status handling scripts
251   string fSentItemStatusScript;
252   string fReceivedItemStatusScript;
253   // session init script
254   string fSessionFinishScript;
255   // custom GET command handler script
256   string fCustomGetHandlerScript;
257   // custom GET and PUT command generator scripts
258   string fCustomGetPutScript;
259   string fCustomEndPutScript;
260   // custom PUT and RESULT handler script
261   string fCustomPutResultHandlerScript;
262   #endif
263   // public methods
264   TLocalDSConfig *getLocalDS(const char *aName, uInt32 aDBTypeID=0);
265   lineartime_t getSessionTimeout(void) { return fSessionTimeout * secondToLinearTimeFactor; };
266   // - MUST be called after creating config to load (or pre-load) variable parts of config
267   //   such as binfile profiles. If aDoLoose==false, situations, where existing config
268   //   is detected but cannot be re-used will return an error. With aDoLoose==true, config
269   //   files etc. are created even if it means a loss of data.
270   virtual localstatus loadVarConfig(bool aDoLoose=false) { return LOCERR_OK; }
271 protected:
272   // check config elements
273   #ifndef HARDCODED_CONFIG
274   virtual bool localStartElement(const char *aElementName, const char **aAttributes, sInt32 aLine);
275   virtual TLocalDSConfig *newDatastoreConfig(const char *aName, const char *aType,TConfigElement *aParentP);
276   #endif
277   virtual void clear();
278   virtual void localResolve(bool aLastPass);
279 }; // TSessionConfig
280
281
282 // forward
283 class TLocalEngineDS;
284
285 // Container types
286 typedef std::list<TLocalEngineDS*> TLocalDataStorePContainer; // contains local data stores
287
288
289 // Sync session
290 class TSyncSession {
291   friend class TSmlCommand;
292   friend class TSyncHeader;
293   friend class TAlertCommand;
294   friend class TSyncCommand;
295   friend class TStatusCommand;
296   friend class TSyncOpCommand;
297   friend class TRemoteDataStore;
298   friend class TLocalEngineDS;
299   #ifdef SUPERDATASTORES
300   friend class TSuperDataStore;
301   #endif
302 public:
303   // constructors/destructors
304   TSyncSession(
305     TSyncAppBase *aSyncAppBaseP, // the owning application base (dispatcher/client base)
306     const char *aSessionID // a session ID
307   );
308   virtual ~TSyncSession();
309   /// @brief terminate a session.
310   /// @Note: Termination is final - session cannot be restarted by RestartSession() after
311   ///        calling this routine
312   virtual void TerminateSession(void);
313   // Announce destruction of descendant to all datastores which might have direct links to these descendants and must cancel those
314   void announceDestruction(void); ///< must be called by derived class' destructors to allow datastores to detach from agent BEFORE descendant destructor has run
315   // Reset session
316   virtual void ResetSession(void); ///< resets session as if created totally new. Descendants must rollback any pending database transactions etc.
317   void InternalResetSessionEx(bool terminationCall); // static implementation for calling through virtual destructor and virtual ResetSession();
318   #ifdef DBAPI_TUNNEL_SUPPORT
319   // Initialize a datastore tunnel session
320   virtual localstatus InitializeTunnelSession(cAppCharP aDatastoreName) { return LOCERR_NOTIMP; }; // is usually implemented in customimplagent, as it depends on DBApi architecture
321   virtual TLocalEngineDS *getTunnelDS() { return NULL; }; // is usually implemented in customimplagent
322   #endif // DBAPI_TUNNEL_SUPPORT
323   #ifdef PROGRESS_EVENTS
324   // Create Session level progress event
325   bool NotifySessionProgressEvent(
326     TProgressEventType aEventType,
327     TLocalDSConfig *aDatastoreID,
328     sInt32 aExtra1,
329     sInt32 aExtra2,
330     sInt32 aExtra3
331   );
332   // Handle (or dispatch) Session level progress event
333   virtual bool HandleSessionProgressEvent(TEngineProgressInfo aProgressInfo) { return true; }; // no handling by default
334   #endif // PROGRESS_EVENTS
335   // called when incoming SyncHdr fails to execute
336   virtual bool syncHdrFailure(bool aTryAgain) = 0;
337   // Abort session
338   void AbortSession(TSyError aStatusCode, bool aLocalProblem, TSyError aReason=0); // resets session and sets aborted flag to prevent further processing of message
339   void MarkSuspendAlertSent(bool aSent);
340   // Suspend session
341   void SuspendSession(TSyError aReason);
342   // Session status
343   bool isAborted(void) { return fAborted; }; // test abort status
344   bool isSuspending(void) { return fSuspended; }; // test if flagged for suspend
345   bool isSuspendAlertSent (void) { return fSuspendAlertSent; }; // test if suspend alert was already sent
346   bool isAllSuccess(void); // test if session was completely successful
347   void DatastoreFailed(TSyError aStatusCode, bool aLocalProblem=false); // let session know that datastore has failed
348   void DatastoreHadErrors(void) { fErrorItemDatastores++; }; // let session know that sync was ok, but some items had errors
349   bool outgoingMessageFull(void) { return fOutgoingMessageFull; }; // test if outgoing full
350   bool isInterrupedCmdPending(void) { return fInterruptedCommandP!=NULL; };
351   bool getIncomingState(void) { return fIncomingState; };
352   // stop processing commands in this message
353   void AbortCommandProcessing(TSyError aStatusCode); // all further commands in message will be answered with given status
354   // returns remaining time for request processing [seconds]
355   virtual sInt32 RemainingRequestTime(void) { return 0x7FFFFFFF; }; // quasi infinite
356   // forget commands waiting to be sent when header is generated
357   void forgetHeaderWaitCommands(void);
358   // SyncML toolkit workspace access
359   void setSmlWorkspaceID(InstanceID_t aSmlWorkspaceID);
360   InstanceID_t getSmlWorkspaceID(void) { return fSmlWorkspaceID; };
361   const char *getEncodingName(void); // encoding suffix in MIME type
362   SmlEncoding_t getEncoding(void) { return fEncoding; }; // current encoding
363   void setEncoding(SmlEncoding_t aEncoding); // set encoding for session
364   void addEncoding(string &aString); // add current encoding spec to given (type-)string
365   sInt32 getSmlWorkspaceFreeBytes(void) { return ((sInt32) smlGetFreeBuffer(fSmlWorkspaceID)); };
366   #ifdef ENGINEINTERFACE_SUPPORT
367   /// @brief Get new session key to access details of this session
368   virtual appPointer newSessionKey(TEngineInterface *aEngineInterfaceP) = 0;
369   #endif // ENGINEINTERFACE_SUPPORT
370   // session handling
371   // - get session owner (dispatcher/clientbase)
372   TSyncAppBase *getSyncAppBase(void) { return fSyncAppBaseP; }
373   // - get time when session was last used
374   lineartime_t getSessionLastUsed(void) { return fSessionLastUsed; };
375   // - get time when session was started and ended
376   lineartime_t getSessionStarted(void) { return fSessionStarted; };
377   // - get time when last request started processing
378   lineartime_t getLastRequestStarted(void) { return fLastRequestStarted; };
379   // - update last used time
380   void SessionUsed(void) { fSessionLastUsed=getSystemNowAs(TCTX_UTC); };
381   // - session custom time zones object access
382   GZones *getSessionZones(void) { return &fSessionZones; };
383   // - convenience version for getting time
384   lineartime_t getSystemNowAs(timecontext_t aContext) { return sysync::getSystemNowAs(aContext,getSessionZones()); };
385   // debug and log printing (should NOT be virtual, so that they can be used in destructors)
386   void DebugShowCfgInfo(void); // show some information about the config
387   //%%%void LogPrintf(const char *text, ...);
388   //%%%void LogPuts(const char *text);
389   // properties
390   TSyncMLVersions getSyncMLVersion(void) { return fSyncMLVersion; };
391   const char *getLocalURI(void) { return fLocalURI.c_str(); };
392   const char *getInitialLocalURI(void) { return fInitialLocalURI.c_str(); };
393   const char *getRemoteURI(void) { return fRemoteURI.c_str(); };
394   const char *getSynchdrSessionID(void) { return fSynchdrSessionID.c_str(); };
395   const char *getLocalSessionID(void) { return fLocalSessionID.c_str(); };
396   localstatus getAbortReasonStatus(void) { return fLocalAbortReason ? localError(fAbortReasonStatus) : syncmlError(fAbortReasonStatus); };
397   #ifndef MINIMAL_CODE
398   const char *getRemoteInfoString(void) { return fRemoteInfoString.c_str(); };
399   const char *getRemoteDescName(void) { return fRemoteDescName.c_str(); };
400   const char *getSyncUserName(void) { return fSyncUserName.c_str(); };
401   #endif // MINIMAL_CODE
402   sInt32 getLastIncomingMsgID(void) { return fIncomingMsgID; };
403   void setSessionBusy(bool aBusy) { fSessionIsBusy=aBusy; }; // make session behave busy generally
404   bool getReadOnly(void) { return fReadOnly; }; // read-only option
405   void setReadOnly(bool aReadOnly) { fReadOnly=aReadOnly; }; // read-only option
406   // - check if we can handle UTC time (devices without time zone might override this)
407   virtual bool canHandleUTC(void) { return true; }; // assume yes
408   // helpers
409   // - get session relative URI
410   const char *SessionRelativeURI(const char *aURI)
411     { return relativeURI(aURI,getLocalURI()); };
412   // - add local datastore from config
413   TLocalEngineDS *addLocalDataStore(TLocalDSConfig *aLocalDSConfigP);
414   // - add local type
415   void addLocalItemType(TSyncItemType *aItemTypeP)
416     { fLocalItemTypes.push_back(aItemTypeP); };
417   // - find local datatype by config pointer (used to avoid duplicating types
418   //   in session if used by more than a single datastore)
419   TSyncItemType *findLocalType(TDataTypeConfig *aDataTypeConfigP);
420   // - find implemented remote datatype by config pointer (and related datastore, if any)
421   TSyncItemType *findRemoteType(TDataTypeConfig *aDataTypeConfigP, TSyncDataStore *aRelatedRemoteDS);
422   // internal processing events implemented in derived classes
423   // - message start and end
424   virtual bool MessageStarted(SmlSyncHdrPtr_t aContentP, TStatusCommand &aStatusCommand, bool aBad=false)=0;
425   virtual void MessageEnded(bool aIncomingFinal)=0;
426   // - get command item processing, may return a Results command. Must set status to non-404 if get could be served
427   virtual TResultsCommand *processGetItem(const char *aLocUri, TGetCommand *aGetCommandP, SmlItemPtr_t aGetItemP, TStatusCommand &aStatusCommand);
428   // - put and results command processing
429   virtual void processPutResultItem(bool aIsPut, const char *aLocUri, TSmlCommand *aPutResultsCommandP, SmlItemPtr_t aPutResultsItemP, TStatusCommand &aStatusCommand);
430   // - alert processing
431   virtual TSmlCommand *processAlertItem(
432     uInt16 aAlertCode,   // alert code
433     SmlItemPtr_t aItemP, // alert item to be processed (as one alert can have multiple items)
434     SmlCredPtr_t aCredP, // alert cred element, if any
435     TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors
436     TLocalEngineDS *&aLocalDataStoreP // receives datastore pointer, if alert affects a datastore
437   );
438   // - handle status received for SyncHdr, returns false if not handled
439   virtual bool handleHeaderStatus(TStatusCommand * /* aStatusCmdP */) { return false; } // no special handling by default
440   // - map operation
441   virtual bool processMapCommand(
442     SmlMapPtr_t aMapCommandP,       // the map command contents
443     TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors
444     bool &aQueueForLater
445   );
446   // Sync processing (command group)
447   // - start sync group
448   virtual bool processSyncStart(
449     SmlSyncPtr_t aSyncP,           // the Sync element
450     TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors
451     bool &aQueueForLater // will be set if command must be queued for later (re-)execution
452   ) = 0;
453   // - end sync group
454   virtual bool processSyncEnd(bool &aQueueForLater);  // end of sync group
455   // - process generic sync command item within Sync group
456   //   - returns true (and unmodified or non-200-successful status) if
457   //     operation could be processed regularily
458   //   - returns false (but probably still successful status) if
459   //     operation was processed with internal irregularities, such as
460   //     trying to delete non-existant item in datastore with
461   //     incomplete Rollbacks (which returns status 200 in this case!).
462   bool processSyncOpItem(
463     TSyncOperation aSyncOp,        // the operation
464     SmlItemPtr_t aItemP,           // the item to be processed
465     SmlMetInfMetInfPtr_t aMetaP,   // command-wide meta, if any
466     TLocalEngineDS *aLocalSyncDatastore, // the local datastore for this syncop item
467     TStatusCommand &aStatusCommand, // pre-set 200 status, can be modified in case of errors
468     bool &aQueueForLater // must be set if item cannot be processed now, but must be processed later
469   );
470   // message handling
471   // - get current size of message
472   sInt32 getOutgoingMessageSize(void) { return fOutgoingMsgSize; }; // returns currently assembled message size
473   // - get byte statistics (only implemented in server so far)
474   virtual uInt32 getIncomingBytes(void) { return 0; };
475   virtual uInt32 getOutgoingBytes(void) { return 0; };
476   // - get how many bytes may not be used in the outgoing message buffer
477   //   because of maxMsgSize restrictions
478   sInt32 getNotUsableBufferBytes(void);
479   // - get max size outgoing message may have (either defined by remote's maxmsgsize or local buffer space)
480   sInt32 getMaxOutgoingSize(void);
481   // - returns true if given number of bytes are transferable
482   //   (not exceeding MaxMsgSize (in SyncML 1.0) or MaxObjSize (SyncML 1.1 and later)
483   bool dataSizeTransferable(uInt32 aDataBytes);
484   // - update outgoing message size
485   void incOutgoingMessageSize(sInt32 aIncrement) { fOutgoingMsgSize+=aIncrement; };
486   // - get message-global noResp status
487   bool getMsgNoResp(void) { return fMsgNoResp; }
488   // - get next outgoing command ID
489   sInt32 getNextOutgoingCmdID(void) { return (++fOutgoingCmdID); }
490   // - get next outgoing command ID without actually consuming it
491   sInt32 peekNextOutgoingCmdID(void) { return (fOutgoingCmdID+1); }
492   // - get current outgoing message ID
493   sInt32 getOutgoingMsgID(void) { return fOutgoingMsgID; }
494   // command handling
495   // - issue a command (and put it to status queue if it expects a result)
496   bool issue(TSmlCommand * &aSyncCommandP,
497     TSmlCommandPContainer &aNextMessageCommands,
498     TSmlCommand * &aInterruptedCommandP,
499     bool aNoResp=false, bool aIsOKSyncHdrStatus=false
500   );
501   bool issuePtr(TSmlCommand *aSyncCommandP, TSmlCommandPContainer &aNextMessageCommands,
502     TSmlCommand * &aInterruptedCommandP, bool aNoResp=false, bool aIsOKSyncHdrStatus=false);
503   // - issue a command in SyncBody context (uses session's interruptedCommand/NextMessageCommands)
504   bool issueRoot(TSmlCommand * &aSyncCommandP,
505     bool aNoResp=false, bool aIsOKSyncHdrStatus=false
506   );
507   bool issueRootPtr(TSmlCommand *aSyncCommandP,
508     bool aNoResp=false, bool aIsOKSyncHdrStatus=false
509   );
510   // queue a SyncBody context command for issuing after incoming message
511   // has been processed (and answers generated)
512   void queueForIssueRoot(
513     TSmlCommand * &aSyncCommandP // the command
514   );
515   // issue a command, but queue it if outgoing package has not begun yet
516   void issueNotBeforePackage(
517     TPackageStates aPackageState,
518     TSmlCommand *aSyncCommandP // the command
519   );
520   // - session continuation and status
521   void nextMessageRequest(void);
522   bool sessionMustContinue(void);
523   virtual void essentialStatusReceived(void) { /* NOP here */ };
524   void delayExecUntilNextRequest(TSmlCommand *aCommand);
525   bool delayedSyncEndsPending(void) { return fDelayedExecSyncEnds>0; };
526   // - continue interrupted or prevented issue in next package
527   void ContinuePackageRoot(void);
528   void ContinuePackage(
529     TSmlCommandPContainer &aNextMessageCommands,
530     TSmlCommand * &aInterruptedCommandP
531   );
532   // - mark all pending items for a datastore for resume
533   //   (those items that are in a session queue for being issued or getting status)
534   void markPendingForResume(TLocalEngineDS *aForDatastoreP);
535   void markPendingForResume(
536     TSmlCommandPContainer &aNextMessageCommands,
537     TSmlCommand *aInterruptedCommandP,
538     TLocalEngineDS *aForDatastoreP
539   );
540   // access to session info from commands
541   bool mustSendDevInf(void) { return fRemoteMustSeeDevinf; };
542   // - access DevInf (session owned)
543   SmlItemPtr_t getLocalDevInfItem(bool aAlertedOnly, bool aWithoutCTCapProps);
544   // - analyze devinf of remote party (can be derived to add client or server specific analysis)
545   virtual localstatus analyzeRemoteDevInf(
546     SmlDevInfDevInfPtr_t aDevInfP
547   );
548   // - get possibly cached devinf for specified device, passes ownership of
549   //   created devinf structure to caller
550   //   returns false if no devinf could be loaded
551   virtual bool loadRemoteDevInf(const char * /* aDeviceID */, SmlDevInfDevInfPtr_t & /* aDevInfP */) { return false; };
552   // - save devinf to cache for specified device
553   //   return false if devinf cannot be cached
554   virtual bool saveRemoteDevInf(const char * /* aDeviceID */, SmlDevInfDevInfPtr_t /* aDevInfP */) { return false; };
555   // - finish outgoing Message, returns true if final message of package
556   bool FinishMessage(bool aAllowFinal, bool aForceNonFinal=false);
557   // - returns true if session has pending commands
558   bool hasPendingCommands(void);
559   // - incoming message processing aborted (EndMessage will not get called, clean up)
560   void CancelMessageProcessing(void);
561   // entry points for SyncML Toolkit callbacks
562   // - message handling
563   Ret_t StartMessage(SmlSyncHdrPtr_t aContentP);
564   Ret_t EndMessage(Boolean_t final);
565   // - grouping commands
566   Ret_t StartSync(SmlSyncPtr_t aContentP);
567   Ret_t EndSync(void);
568   #ifdef ATOMIC_RECEIVE
569   Ret_t StartAtomic(SmlAtomicPtr_t aContentP);
570   Ret_t EndAtomic(void);
571   #endif
572   #ifdef SEQUENCE_RECEIVE
573   Ret_t StartSequence(SmlSequencePtr_t aContentP);
574   Ret_t EndSequence(void);
575   #endif
576   // - commands
577   Ret_t AddCmd(SmlAddPtr_t aContentP);
578   Ret_t AlertCmd(SmlAlertPtr_t aContentP);
579   Ret_t DeleteCmd(SmlDeletePtr_t aContentP);
580   Ret_t GetCmd(SmlGetPtr_t aContentP);
581   Ret_t PutCmd(SmlPutPtr_t aContentP);
582   #ifdef MAP_RECEIVE
583   Ret_t MapCmd(SmlMapPtr_t aContentP);
584   #endif
585   #ifdef RESULT_RECEIVE
586   Ret_t ResultsCmd(SmlResultsPtr_t aContentP);
587   #endif
588   Ret_t StatusCmd(SmlStatusPtr_t aContentP);
589   Ret_t ReplaceCmd(SmlReplacePtr_t aContentP);
590   #ifdef COPY_RECEIVE
591   Ret_t CopyCmd(SmlReplacePtr_t aContentP);
592   #endif
593   Ret_t MoveCmd(SmlReplacePtr_t aContentP);
594   // - error handling
595   Ret_t HandleError(void);
596   Ret_t DummyHandler(const char* msg);
597   // - Other Callbacks: routed directly to appropriate session, error if none
598   #ifdef SYNCSTATUS_AT_SYNC_CLOSE
599   TStatusCommand *fSyncCloseStatusCommandP;
600   #endif
601   #ifdef SYDEBUG
602   // Message dump
603   void DumpSyncMLMessage(bool aOutgoing);
604   void DumpSyncMLBuffer(MemPtr_t aBuffer, MemSize_t aBufSize, bool aOutgoing, Ret_t aDecoderError);
605   uInt32 fDumpCount;
606   // XML translations of communication
607   // - recoding instances
608   InstanceID_t fOutgoingXMLInstance,fIncomingXMLInstance;
609   // - routines
610   void XMLTranslationIncomingStart(void);
611   void XMLTranslationOutgoingStart(void);
612   void XMLTranslationIncomingEnd(void);
613   void XMLTranslationOutgoingEnd(void);
614   // - flags
615   bool fXMLtranslate; // dump XML translation of SyncML traffic
616   bool fMsgDump; // dump raw SyncML messages
617   #endif // SYDEBUG
618   // log writing
619   #ifndef MINIMAL_CODE
620   void WriteLogLine(const char *aLogline);
621   bool logEnabled(void) { return fLogEnabled; };
622   #endif // MINIMAL_CODE
623   // current database date & time (defaults to system time)
624   virtual lineartime_t getDatabaseNowAs(timecontext_t aContext) { return getSystemNowAs(aContext); };
625   // devinf
626   void remoteGotDevinf(void) { fRemoteGotDevinf=true; };
627   void remoteMustSeeDevinf(void) { fRemoteMustSeeDevinf=true; };
628   // config access
629   TRootConfig *getRootConfig(void);
630   // access to logging for session
631   #ifdef SYDEBUG
632   TDebugLogger *getDbgLogger(void) { return &fSessionLogger; };
633   uInt32 getDbgMask(void) { return fSessionDebugLogs ? fSessionLogger.getMask() : 0; };
634   #endif // SYDEBUG
635   // Remote-specific options, will be set up by checkClient/ServerSpecifics()
636   bool fLimitedRemoteFieldLengths; // if set, all fields will be assumed to have limited, but unknown field length (used for cut-off detection)
637   bool fDontSendEmptyProperties; // if set, no empty properties will be sent to client
638   bool fDoQuote8BitContent; // set if 8-bit chars should generally be encoded with QP in MIME-DIR
639   bool fDoNotFoldContent; // set if content should not be folded in MIME-DIR
640   bool fNoReplaceInSlowsync; // prevent replace commands totally at slow sync
641   bool fTreatRemoteTimeAsLocal; // treat remote time as localtime even if it carries different time zone information ("Z" suffix or zone spec)
642   bool fTreatRemoteTimeAsUTC; // treat remote time as UTC even if it carries different time zone information (no suffix or zone spec)
643   bool fVCal10EnddatesSameDay; // send end date-only values (like DTEND) as last time unit of previous day (i.e. 23:59:59, inclusive) instead of midnight of next day (exclusive, like in iCalendar 2.0)
644   bool fIgnoreDevInfMaxSize; // ignore <maxsize> specification in CTCap (when device has bad specs like in E90 for example)
645   bool fIgnoreCTCap; // ignore entire ctcap
646   bool fDSPathInDevInf; // use actual DS path as used in Alert for creating datastore devInf (needed for newer Nokia clients)
647   bool fDSCgiInDevInf; // also show CGI as used in Alert for creating datastore devInf (needed for newer Nokia clients)
648   bool fUpdateClientDuringSlowsync; // prevent updates of client records during non-first-time slow sync
649   bool fUpdateServerDuringSlowsync; // do not update server records during NON-FIRST-TIME slowsync (but do it for first sync!)
650   bool fAllowMessageRetries; // allow that client sends same message ID again (retry attempt)
651   bool fStrictExecOrdering; // if set (=default, SyncML standard requirement), statuses are sent in order of incoming commands (=execution is ordered)
652   bool fTreatCopyAsAdd; // treat copy commands as if they were adds
653   bool fCompleteFromClientOnly; // perform complete from-client-only session (non conformant, Synthesis before 2.9.8.2 style)
654   sInt32 fRequestMaxTime; // max time [seconds] allowed for processing a single request, 0=unlimited
655   sInt32 fRequestMinTime; // min time [seconds] spent until returning answer (for debug purposes, 0=no minimum time)
656   TCharSets fDefaultOutCharset; // default charset for output generation
657   TCharSets fDefaultInCharset; // default charset for input interpretation
658   #ifndef NO_REMOTE_RULES
659   bool isActiveRule(cAppCharP aRuleName, TRemoteRuleConfig *aRuleP=NULL); // check if given rule (by name, or if aRuleName=NULL by rule pointer) is active
660   TRemoteRulesList fActiveRemoteRules; // list of remote rules currently active in this session
661   #endif // NO_REMOTE_RULES
662   // legacy mode
663   bool fLegacyMode; // if set, remote will see the types marked preferred="legacy" in devInf as preferred types, not the regular preferred ones
664   // lenient mode
665   bool fLenientMode; // if set, enine is less strict in checking (e.g. client-side anchor checking, terminating session while some status missing etc.)
666   #ifdef EXPIRES_AFTER_DATE
667   // copy of scrambled now
668   sInt32 fCopyOfScrambledNow;
669   #endif // EXPIRES_AFTER_DATE
670   // Sync datastores
671   // - find local datastore by URI and separate identifying from optional part of URI
672   TLocalEngineDS *findLocalDataStoreByURI(const char *aURI,string *aOptions=NULL, string *aIdentifyingURI=NULL);
673   // - find local datastore by relative path (may not contain any CGI)
674   TLocalEngineDS *findLocalDataStore(const char *aDatastoreURI);
675   // - find local datastore by datastore handle (=config pointer)
676   TLocalEngineDS *findLocalDataStore(void *aDSHandle);
677   // - find remote datastore by (remote party specified) URI
678   TRemoteDataStore *findRemoteDataStore(const char *aDatastoreURI);
679   // Profiling
680   TP_DEFINFO(fTPInfo)
681   // access to config
682   TSessionConfig *getSessionConfig(void);
683   #ifdef SCRIPT_SUPPORT
684   // access to session script context
685   TScriptContext *getSessionScriptContext(void) { return fSessionScriptContextP; };
686   #endif // SCRIPT_SUPPORT
687   // unprotected options
688   // - set if we should send property lists in CTCap
689   bool fShowCTCapProps;
690   // - set if we should send type/size in CTCap for SyncML 1.0 (disabled by default as old clients like S55 crash on this)
691   bool fShowTypeSzInCTCap10;
692   // - set if we should show default parameter in mimo_old types as list of <propparam>s for each value
693   //   Note that this is a tristate: 0=no, 1=yes, -1=auto (=yes for <SyncML 1.2, no for >=SyncML 1.2,
694   //   thus making it work for Nokia 7610 (1.1) as well as E-Series like E90)
695   sInt8 fEnumDefaultPropParams;
696   #ifdef SYDEBUG
697   /// @todo
698   /// fSessionDebugLogs should be removed (but this needs rewriting of the XML and SML dumpers)
699   // - set if debug log for this session is enabled
700   bool fSessionDebugLogs;
701   #endif // SYDEBUG
702   #ifndef MINIMAL_CODE
703   // - se if normal log for this session is enabled
704   bool fLogEnabled; // real log file enabled
705   #endif // MINIMAL_CODE
706   // - remote options (SyncML 1.1)
707   bool fRemoteWantsNOC; // remote wants number-of-changes info
708   bool fRemoteCanHandleUTC; // remote can handle UTC time
709   bool fRemoteSupportsLargeObjects; // remote can handle large object splitting/reassembly
710   // - object size handling
711   sInt16 fOutgoingCmds; // number of outgoing commands in message, but NOT counting SyncHdr status and Alert 222 status (which are ALWAYS there even in an otherwise empty message)
712   sInt32 fMaxRoomForData; // max room for data (free bytes available for data when startin a <sync> command)
713   // - Session user time context
714   timecontext_t fUserTimeContext;
715 protected:
716   // Session control
717   // - terminate all datastores
718   void TerminateDatastores(localstatus aAbortStatusCode=408);
719   // - remove all datastores
720   void ResetAndRemoveDatastores(void);
721   // - session layer credential checking
722   bool checkCredentials(const char *aUserName, const SmlCredPtr_t aCredP, TStatusCommand &aStatusCommand);
723   bool checkCredentials(const char *aUserName, const char *aCred, TAuthTypes aAuthType);
724   // - session layer challenge
725   SmlChalPtr_t newSessionChallenge(void);
726   // datastore and type vars
727   // - list of local datastores
728   TLocalDataStorePContainer fLocalDataStores;
729   // - list of remote (client-side) datastores
730   TRemoteDataStorePContainer fRemoteDataStores;
731   bool receivedSyncModeExtensions(); // any of the remote datastores in fRemoteDataStores
732                                      // had custom sync modes
733   // - list of local content types
734   TSyncItemTypePContainer fLocalItemTypes;
735   // - list of remote item types
736   TSyncItemTypePContainer fRemoteItemTypes;
737   // - Local Database currently targeted by a Sync command, NULL if none
738   //   Note: This must be set correctly whenever sync commands (and </sync> syncend) are processed
739   //         This can be during actual receiving them, OR while processing them from the fDelayedExecutionCommands
740   //         queue.
741   TLocalEngineDS *fLocalSyncDatastoreP;
742   // set if we have received DevInf for remote DataStores / CTCap
743   bool fRemoteDevInfKnown; // remote devInf known
744   bool fRemoteDataStoresKnown; // data stores known
745   bool fRemoteDataTypesKnown; // CTCap known
746   bool fRemoteDevInfLock; // set after starting sync according to devInf we had to prevent in-sync devInf changes
747   // see if we have sent or should send DevInf to remote
748   bool fRemoteGotDevinf; // set if we sent a Put or Result containig DevInf
749   bool fRemoteMustSeeDevinf; // set if we should force (Put) devinf to remote
750   bool fCustomGetPutSent; // set if custom get/put has been sent to remote
751   // DevInf
752   // - get new sml list of all datastores (owner of list is transferred, but items are still owned by datastore
753   SmlDevInfDatastoreListPtr_t newDevInfDataStoreList(bool aAlertedOnly, bool aWithoutCTCapProps);
754   SmlDevInfCtcapListPtr_t newLocalCTCapList(bool aAlertedOnly, TLocalEngineDS *aOnlyForDS, bool aWithoutCTCapProps);
755   // - get new DevInf for this session (as Result for GET or item for PUT)
756   virtual SmlDevInfDevInfPtr_t newDevInf(bool aAlertedOnly, bool aWithoutCTCapProps);
757   // - called to issue custom get and put commands
758   virtual void issueCustomGetPut(bool aGotDevInf, bool aSentDevInf);
759   virtual void issueCustomEndPut(void);
760   // Sync processing
761   // - prepare for sending and receiving Sync commands
762   localstatus initSync(
763     const char *aLocalDatastoreURI,
764     const char *aRemoteDatastoreURI
765   );
766   // Command processing
767   // - process a command (analyze and execute it),
768   //   exception-free for simple call from smlCallback adaptors
769   Ret_t process(TSmlCommand *aSyncCommandP);
770   // - handle incoming status
771   //   exception-free for simple call from smlCallback adaptors
772   Ret_t handleStatus(TStatusCommand *aStatusCommandP);
773   // helpers for derived classes
774   // - create, send and delete SyncHeader "command"
775   void issueHeader(bool aNoResp=false);
776   // - process the SyncHeader "command"
777   Ret_t processHeader(TSyncHeader *aSyncHdrP);
778   // Helpers for commands
779   // - create new SyncHdr structure for TSyncHeader command
780   //   (here because all data for this is in session anyway)
781   SmlSyncHdrPtr_t NewOutgoingSyncHdr(bool aOutgoingNoResp=false);
782   // virtuals for overriding in specialized session derivates
783   // - device ID must be handled on session level as it might depend on session runtime conditions
784   //   (like special pseudo-unique ID for Oracle servers when basic id is not unique etc.)
785   virtual string getDeviceID(void)=0;
786   virtual string getDeviceType(void)=0; // abstract, must be client or server
787   // - get new response URI to be sent to remote party for subsequent messages TO local party
788   virtual SmlPcdataPtr_t newResponseURIForRemote(void) { return NULL; }; // no RespURI by default
789   // Authorisation
790   // - required authentication type and mode
791   virtual TAuthTypes requestedAuthType(void) = 0; // get preferred authentication type for authentication of remote party
792   virtual bool isAuthTypeAllowed(TAuthTypes aAuthType) = 0; // test if auth type is allowed for authentication by remote party
793   virtual bool messageAuthRequired(void) { return false; }; // no message-by-message auth by default
794   // - get credentials/username to authenticate with remote party, NULL if none
795   virtual SmlCredPtr_t newCredentialsForRemote(void) { return NULL; }; // normally (server case), none
796   virtual const char * getUsernameForRemote(void) { return NULL; }; // normally (server case), none
797   // - generate credentials (based on fRemoteNonce, fRemoteRequestedAuth, fRemoteRequestedAuthEnc)
798   SmlCredPtr_t newCredentials(const char *aUser, const char *aPassword);
799 public:
800   // - URI to send outgoing message to
801   virtual const char *getSendURI(void) { return ""; }; // none by default (and server)
802   // - get common sync capabilities mask of this session (datastores might modify it)
803   virtual uInt32 getSyncCapMask(void);
804   // - check credentials, login to server
805   virtual bool SessionLogin(const char *aUserName, const char *aAuthString, TAuthSecretTypes aAuthStringType, const char *aDeviceID);
806 protected:
807   // - get next nonce string top be sent to remote party for subsequent MD5 auth
808   virtual void getNextNonce(const char * /* aDeviceID */, string &aNextNonce) { aNextNonce.erase(); }; // empty nonce
809 public:
810   // - get nonce string for specified device
811   virtual void getAuthNonce(const char * /* aDeviceID */, string &aAuthNonce) { aAuthNonce.erase(); };
812   // - check auth helpers
813   bool checkAuthPlain(
814     const char *aUserName, const char *aPassWord, const char *aNonce, // given values
815     const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this
816   );
817   bool checkAuthMD5(
818     const char *aUserName, const char *aMD5B64, const char *aNonce, // given values
819     const char *aAuthString, TAuthSecretTypes aAuthStringType // check against this
820   );
821   bool checkMD5WithNonce(
822     const char *aStringBeforeNonce, const char *aNonce, // given input
823     const char *aMD5B64Creds // credential string to check
824   );
825 protected:
826   // - helper functions (for use be derived classes)
827   bool getAuthBasicUserPass(const char *aBasicCreds, string &aUsername, string &aPassword);
828   // - load remote connect params (syncml version, type, format and last nonce)
829   //   Note: agents that can cache this information between sessions will load
830   //   last info here.
831   virtual void loadRemoteParams(void)
832     { fSyncMLVersion=syncml_vers_unknown; fRemoteRequestedAuth=auth_none; fRemoteRequestedAuthEnc=fmt_chr; fRemoteNonce.erase(); }; // static defaults
833   // - save remote connect params for use in next session (if descendant implements it)
834   virtual void saveRemoteParams(void) { /* nop */ };
835   // - Session level meta
836   virtual SmlPcdataPtr_t newHeaderMeta(void);
837   // - check remote devinf to detect special behaviour needed for some clients. Base class
838   //   does not do anything on server level (configured rules are handled at session level)
839   virtual localstatus checkRemoteSpecifics(SmlDevInfDevInfPtr_t aDevInfP, SmlDevInfDevInfPtr_t *aOverrideDevInfP);
840   // - remote device is analyzed, possibly save status
841   virtual void remoteAnalyzed(void) { /* nop */ };
842   // - tell session whether it may accept an <Alert> in the map
843   //   phase and restart the sync
844   virtual bool allowAlertAfterMap() { return false; }
845   // SyncML Toolkit interface
846   InstanceID_t fSmlWorkspaceID; // SyncML toolkit workspace instance ID
847   SmlEncoding_t fEncoding;      // Current encoding type in SyncML toolkit instance
848   // Session custom time zones
849   GZones fSessionZones;
850   // session timing
851   lineartime_t fSessionLastUsed; // time when session was last used
852   lineartime_t fSessionStarted; // time when session was started
853   lineartime_t fLastRequestStarted; // time when last request was received
854   // session busy status (used for session count limiting normally)
855   bool fSessionIsBusy;
856   // session type
857   // - SyncML protocol version
858   TSyncMLVersions fSyncMLVersion;
859   // - outgoing authorisation
860   TAuthTypes fRemoteRequestedAuth; // type of auth requested by the remote
861   TFmtTypes fRemoteRequestedAuthEnc; // type of encoding requested by the remote
862   string fRemoteNonce; // next nonce to be used to authenticate with remote
863   bool fNeedAuth; // set if we need to authorize to remote for next message
864   // session ID vars
865   string fSynchdrSessionID; // SyncML-protocol ID of this sync session (client generated)
866   string fLocalURI; // local party URI
867   string fInitialLocalURI; // local URI used in first message (or preconfigured with <externalurl>)
868   string fLocalName; // local party optional name
869   string fRemoteURI; // remote party URI (remote deviceID or URL)
870   string fRemoteName; // remote party optional name
871   string fRespondURI; // remote party URI to send response to
872   string fLocalSessionID; // locally generated session ID (server generated)
873   #ifndef MINIMAL_CODE
874   string fRemoteDescName; // descriptive name of remote (set from DevInf and probably adjusted by remoterule)
875   string fRemoteInfoString; // remote party information string (from DevInf)
876   string fSyncUserName; // remote user name
877   // 1:1 devInf details
878   string fRemoteDevInf_devid;
879   string fRemoteDevInf_devtyp;
880   string fRemoteDevInf_mod;
881   string fRemoteDevInf_man;
882   string fRemoteDevInf_oem;
883   string fRemoteDevInf_swv;
884   string fRemoteDevInf_fwv;
885   string fRemoteDevInf_hwv;
886   #endif // MINIMAL_CODE
887   #ifdef SCRIPT_SUPPORT
888   // Session level script context
889   TScriptContext *fSessionScriptContextP;
890   #endif // SCRIPT_SUPPORT
891   // Session options
892   bool fReadOnly;
893   // Session state vars
894   // - incoming authorisation
895   bool fSessionAuthorized; // session is (permanently) authorized, that is, further messages do not need authorization
896   bool fMessageAuthorized; // this message is authorized
897   sInt16 fAuthFailures; // count of failed authentication attempts by remote in a row (normally, server case), will cause abort if too many
898   sInt16 fAuthRetries; // count of failed authentication attempts by myself at remote (normally, client case)
899   // - session state
900   TPackageStates fIncomingState; // incoming package state
901   TPackageStates fCmdIncomingState; // while executing commands: state when command was received (actual might be different due to queueing)
902   TPackageStates fOutgoingState; // outgoing package state
903   bool fRestarting; // Set to true in TSyncSession::processAlertItem() while processing the first Alert from a
904                     // client which requests another sync cycle. Applies to all further Alerts, cleared
905                     // when entering fOutgoingState==psta_sync again.
906   bool fFakeFinalFlag; // special flag to work around broken resume implementations
907   bool fNewOutgoingPackage; // set if first outgoing message in outgoing package
908   bool fNeedToAnswer; // set if an answer to currently processed message is needed (will be set by issuing of first non-synchdr-status)
909   sInt32 fIncomingMsgID; // last incoming message ID (0 if none received yet)
910   sInt32 fOutgoingMsgID; // last outgoing message ID (0 if none sent yet)
911   bool fMessageRetried; // if set (by TSyncHeader::execute()) we have received a retried message and should resend the last answer
912   bool fAborted; // if set, session is being aborted (and will be deleted at EndRequest)
913   bool fSuspended; // if set, session is being suspended (stopped processing commands, will send Suspend Alert to remote at next opportunity)
914   bool fSuspendAlertSent; // if set, session has sent a suspend alert to the remote party
915   uInt16 fFailedDatastores;
916   uInt16 fErrorItemDatastores;
917   TSyError fAbortReasonStatus; // if fAborted, this contains a status code what command has aborted the session
918   bool fLocalAbortReason; // if aborted, this signals if aborted due to local or remote reason
919   bool fInProgress; // if set, session is in progress and must persist beyond this request
920   // incoming Message status
921   bool fMsgNoResp; // if set, current message MUST not be responded to. Suppresses all status sendig attempts
922   bool fIgnoreIncomingCommands; // if set, commands dispatched will be ignored
923   TSyError fStatusCodeForIgnored; // if fIgnoreIncomingCommands is set, this status code will be used to reply all incoming commands
924   // - incoming data from a <moredata> split data item
925   TSyncOpCommand *fIncompleteDataCommandP;
926   // outgoing message status
927   sInt32 fOutgoingCmdID; // last outgoing command ID (0 if none generated yet)
928   bool fOutgoingStarted; // started preparing an outgoing message
929   bool fOutgoingNoResp; // outgoing message does not want response at all
930   // termination flag - set when TerminateSession() has finished executing
931   bool fTerminated; // session is terminated (finally, not restartable!)
932 private:
933   // debug logging
934   #ifdef SYDEBUG
935   TDebugLogger fSessionLogger; // the logger
936   #endif // SYDEBUG
937   // internal vars
938   TSyncAppBase *fSyncAppBaseP; // the owning application base (dispatcher/client base)
939   /* %%% prepared, to be implemented. Currently constant limits
940   sInt32 fMaxIncomingMsgSize; // limit for incoming message, if<>0, causes MaxMsgSize Meta on outgoing SyncHdr
941   sInt32 fMaxIncomingObjSize; // limit for incoming objects, if<>0, causes MaxObjSize Meta on outgoing SyncHdr
942   */
943   sInt32 fMaxOutgoingMsgSize; // max size of outgoing message, 0 if unlimited
944   sInt32 fMaxOutgoingObjSize; // SyncML 1.1: max size of outgoing object, 0 if unlimited
945   sInt32 fOutgoingMsgSize; // current size of outgoing message
946   bool fOutgoingMessageFull; // outgoing message is full, message must be finished and sent
947   // context-free command queues
948   // - sent commands waiting for status
949   TSmlCommandPContainer fStatusWaitCommands;
950   // - received commands that could not be executed immediately
951   TSmlCommandPContainer fDelayedExecutionCommands;
952   sInt32 fDelayedExecSyncEnds;
953   // - commands that must be queued until SyncHdr is generated
954   TSmlCommandPContainer fHeaderWaitCommands;
955   // SyncBody-context command queues
956   // - commands to be issued only after all commands in this message have
957   //   been processed and answered by a status
958   TSmlCommandPContainer fEndOfMessageCommands;
959   // - commands waiting for being sent in next outgoing message
960   TSmlCommandPContainer fNextMessageCommands;
961   // - commands waiting for being sent in next outgoing package
962   TSmlCommandPContainer fNextPackageCommands;
963   // - outgoing command that was interrupted by end of message and must be continued in next message
964   TSmlCommand *fInterruptedCommandP;
965   // - counter that gets incremented once per Alert 222 and decremented when package contents get sent
966   uInt32 fNextMessageRequests;
967   // - sequence nesting level
968   sInt32 fSequenceNesting;
969 }; // TSyncSession
970
971
972 // macros
973 #define ISSUE_COMMAND(sp,c,l1,l2) { TSmlCommand* p=c; c=NULL; sp->issuePtr(p,l1,l2); }
974 #define ISSUE_COMMAND_ROOT(sp,c) { TSmlCommand* p=c; c=NULL; sp->issueRootPtr(p); }
975
976
977 #ifdef ENGINEINTERFACE_SUPPORT
978
979 // Support for EngineModule common interface
980 // =========================================
981
982 // session runtime parameters (such as access to session script vars)
983 class TSessionKey :
984   public TStructFieldsKey
985 {
986   typedef TStructFieldsKey inherited;
987 public:
988   TSessionKey(TEngineInterface *aEngineInterfaceP, TSyncSession *aSessionP) :
989     inherited(aEngineInterfaceP),
990     fSessionP(aSessionP)
991   {};
992   virtual ~TSessionKey() {};
993
994 protected:
995   // open subkey by name (not by path!)
996   // - this is the actual implementation
997   virtual TSyError OpenSubKeyByName(
998     TSettingsKeyImpl *&aSettingsKeyP,
999     cAppCharP aName, stringSize aNameSize,
1000     uInt16 aMode
1001   );
1002
1003   // the associated sync session
1004   TSyncSession *fSessionP;
1005 }; // TSessionKey
1006
1007 #endif // ENGINEINTERFACE_SUPPORT
1008
1009 } // namespace sysync
1010
1011
1012 #endif // SYNC_SESSION_H
1013
1014
1015 // eof