1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // This file contains the API definition for the class CImTextServerSession.
15 // This class creates sockets and is responsible for transmitting data between client and the server
36 #ifdef SYMBIAN_ENABLE_SPLIT_HEADERS
37 #include "timrfc822datefield.h"
41 #define __IMSK_SIMULATION
44 // Enable Scripting in Debug Builds only
46 #define __IMSK_SCRIPTING
53 const TInt EActivePriorityHigh = 1;
58 const TInt KCarriageLineFeedLength=2;
59 /** Max numeric IP address len = "0:0:0:0:0:0:194.217.242.23" = 45 chars
63 const TInt KImskIPAddressLen=45; // Max numeric IP address len = "255.255.255.255" = 15 chars
65 /** Maximum buffer size of the received data
69 typedef TBuf8<KImMailMaxBufferSize> TImMailBuffer;
71 /** received buffer data line type
85 class CImTextServerScript;
86 class CImIAPPreferences;
89 class CImSocketIdleTimer;
92 Creates/opens socket and sends and receives data.
97 class CImTextServerSession : public CMsgActive
100 enum TImOperationMode{
108 Intended Usage : Static factory constructor. Uses two phase construction and
109 leaves nothing on the CleanupStack.
112 @return A pointer to the newly created CImTextServerSession object.
114 @post A fully constructed and initialised CImTextServerSession object.
117 IMPORT_C static CImTextServerSession *NewL();
123 IMPORT_C static CImTextServerSession* NewL(RSocketServ& aSocketServ, CImConnect& aConnect);
127 @fn NewL(TInt aSendIdleTime, TInt aReceiveIdleTime)
128 Intended Usage : Static factory constructor. Uses two phase construction and
129 leaves nothing on the CleanupStack.
131 @param aSendIdleTime is the time for which the idle timer runs (for a send)
132 @param aReceiveIdleTime is the time for which the idle timer runs (for a recieve)
134 @return A pointer to the newly created CImTextServerSession object.
136 @post A fully constructed and initialised CImTextServerSession object.
138 IMPORT_C static CImTextServerSession* NewL(TInt aSendIdleTime, TInt aReceiveIdleTime);
144 IMPORT_C static CImTextServerSession* NewL(TInt aSendIdleTime, TInt aReceiveIdleTime, RSocketServ& aSocketServ, CImConnect& aConnect);
148 @fn ~CImTextServerSession()
149 Intended Usage : Destructor.
152 ~CImTextServerSession();
155 @fn QueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool aEnableTimeout = ETrue)
156 Intended Usage : Queue a connect assuming the socket is successfully opened.
157 Error Condition : KErrNoMemory
159 @param aStatus Asynchronous completion status
160 @param anAddressDesc is the IP address
161 @param aIAPPreferences is the IAP connection preference to be used
162 @param aPortNum is the port number eg. 143, 25, 110.
163 @param aEnableTimeout Not used
165 @post connection is ready to send and receive data.
167 IMPORT_C void QueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool aEnableTimeout = ETrue);
169 IMPORT_C void QueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName);
172 @fn SSLQueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool aEnableTimeout = ETrue)
173 Intended Usage : Queue a wrapped SSL connect on an socket assuming the socket is successfully opened.
174 Error Condition : KErrNoMemory, EImskSocketOpen
176 @param aStatus Asynchronous completion status
177 @param anAddressDesc is the IP address
178 @param aIAPPreferences is the IAP connection preference to be used
179 @param aPortNum is the port number eg. 993, 465, 995.
180 @param aEnableTimeout Not used
182 @post connection is ready to send and receive data.
184 IMPORT_C void SSLQueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool aEnableTimeout = ETrue);
186 IMPORT_C void SSLQueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName);
190 Intended Usage : To disconnect and close socket connection.
191 Error Condition : None
194 @post connection is closed.
196 IMPORT_C void Disconnect();
197 IMPORT_C void Disconnect(TRequestStatus &aStatus);
201 IMPORT_C const TDesC& LocalName();
203 This method should be called before Send/SendQueueReceive()
205 @fn SetSSLTLSResponseL(const TDesC8& aDesc)
206 Intended Usage : To use for secure connection.
207 Error Condition : KErrNoMemory
209 @param aDesc is the positive response the MTM expects from the connected
210 server for TLS command. e.g. OK, +OK, 220 etc..
211 @pre aDesc cannot be zero length
212 @leave EImskNoTLSResponseString
213 @post iTLSResponse is filled with aDesc contents
216 IMPORT_C void SetSSLTLSResponseL(const TDesC8& aDesc);
219 @fn Send(TRequestStatus &aStatus, const TDesC8& aDesc)
220 Intended Usage : To send data.
221 Error Condition : None
223 @param aStatus Asynchronous completion status
224 @param aDesc is the aData to be sent
230 IMPORT_C void Send(TRequestStatus &aStatus, const TDesC8& aDesc);
231 IMPORT_C void SendWithTimeout(TRequestStatus& aStatus, TInt aIdleTime, const TDesC8& aDesc);
232 IMPORT_C void SendQueueReceiveWithTimeout(TRequestStatus& aStatus, TInt aIdleTime, const TDesC8& aDesc);
233 IMPORT_C void Send(TRequestStatus &aStatus, TRefByValue<const TDesC8> aFmt,...);
235 @fn SendQueueReceive(TRequestStatus &aStatus, const TDesC8& aDesc)
236 Intended Usage : To send data and queue a receive.
237 Error Condition : None
239 @param aStatus Asynchronous completion status
240 @param aDesc is the aData to be sent
241 @post Sends the data and queues a receive.
242 GetCurrentTextLine should be called after this method to read received data
244 IMPORT_C void SendQueueReceive(TRequestStatus &aStatus, const TDesC8& aDesc);
245 IMPORT_C void SendQueueReceive(TRequestStatus &aStatus, TRefByValue<const TDesC8> aFmt,...);
249 Returns first full line of data received from socket to user
250 @fn GetCurrentTextLine(TDes8& aDesc)
251 Intended Usage : To return received data.
252 Error Condition : None
254 @param aDesc will be filled with received buffer
255 @post returns the received buffer in the form of aDesc
256 @return EReceiveBufferEmpty when received data is empty
257 EBufferTooSmall when aDesc length is smaller than received data
258 ECRLFTerminated when received data is complete (full line)
259 EReceiveBufferFull when received data length is more than aDesc length
260 GetCurrentTextLine should be called after Send methods
262 IMPORT_C TImLineType GetCurrentTextLine(TDes8& aDesc);
264 User queues a new request from the socket (unless there's a full line of data in buffer
265 then signal user and there's no need to make a receive request)
266 @fn QueueReceiveNextTextLine(TRequestStatus &aStatus)
267 Intended Usage : User queues a new request from the socket.
268 Error Condition : None
270 @param aStatus for asynchronous request
273 IMPORT_C void QueueReceiveNextTextLine(TRequestStatus &aStatus);
275 @fn ReceiveBinaryData(TRequestStatus &aStatus, TDes8& aDes,TInt aLen)
276 Intended Usage : Users queue a request for received data
277 Error Condition : None
279 @param aStatus Asynchronous completion status
280 @param aDes is the aData to be received
281 @param aLen is the length of the data the user wants to read
282 @post aDes will be filled with received data of aLen.
283 ReceiveBinaryData should be called after Send.
285 IMPORT_C void ReceiveBinaryData(TRequestStatus &aStatus, TDes8& aDes,TInt aLen);
287 IMPORT_C void LogText(const TDesC8& aString); // write string into log file
288 IMPORT_C void LogError(const TDesC8& aString,const TInt aError); // write string and integer into log file
291 @fn GetIAPValue(TUint32 &aIAP)
292 Intended Usage : Returns the IAP we are connecting/connected with in aIAP or returns an error code
294 @param aIAP will be the current IAP
295 @post aIAP will be filled with current IAP connected.
296 @return will return genconn errors if any
299 IMPORT_C TInt GetIAPValue(TUint32 &aIAP);
301 @fn GetRConnectionName(TName &aName)
302 Intended Usage : Returns the name of the RConnection.
304 @param aName Buffer in which the name is returned.
305 @post aName will be filled with current name of the RConnection.
306 @return KErrNone if successful, or another of the system-wide error codes.
309 IMPORT_C TInt GetRConnectionName(TName &aName);
311 /** Returns the bearer type we are connected to with in aBearer or returns an error code */
312 IMPORT_C TInt GetIAPBearer(TUint32 &aBearer);
317 @fn GetLastSocketActivityTimeout(TUint32& aTimeout)
318 Intended Usage : Returns the last socket activity timeout value
320 @param aTimeout is a return argument containing the timeout if it was found
321 @post aTimeout will be filled with the timeout value
322 @return Returns KErrNone, KErrNotFound or KErrBadHandle
324 IMPORT_C TInt GetLastSocketActivityTimeout(TUint32& aTimeout);
328 Intended Usage : Returns the Socket Server
330 @return Socket Server
332 RSocketServ& GetSocketServ();
335 @fn GetConnectionStage()
336 Intended Usage : Gets the stage of the connection process obtained from RConnection
338 @return The current connection stage from RConnection or a system-wide error code.
341 IMPORT_C TInt GetConnectionStage();
345 Intended Usage : disconnects the socket and notifies the observer when the socket has been idle
352 @fn SetPrimaryTextServerSession(CImTextServerSession& aPrimaryTextServerSession)
353 Intended Usage : Users set only on the secondary session
355 @param aPrimaryTextServerSession is PrimarySession's TextServerSession
357 @post Going to be use on the secondary session
359 IMPORT_C void SetPrimaryTextServerSession(CImTextServerSession* aPrimaryTextServerSession);
363 Intended Usage : Returns the CImConnect object
366 @post Going to be use on the secondary session
368 CImConnect* GetCImConnect();
370 // Depreciated functions - do not use.
371 IMPORT_C void QueueConnect(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, TBool aEnableTimeout = ETrue);
372 IMPORT_C void QueueConnect(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TInt aType, TBool aEnableTimeout = ETrue);
373 IMPORT_C void QueueConnect(TRequestStatus& aStatus,const TDesC& anAddressDesc, TInt aPortNum, TCallBack aDisconnectFunction,const TUint32 aIntraddress,TInt aType, TBool aEnableTimeout = ETrue);
374 IMPORT_C void QueueConnect(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum,const TUint32 aIAPaddress, TInt aType, TBool aEnableTimeout = ETrue);
375 IMPORT_C void QueueConnect(TRequestStatus& aStatus,const TDesC& anAddressDesc, TInt aPortNum, TCallBack aDisconnectFunction, TBool aEnableTimeout = ETrue);
376 IMPORT_C void QueueConnect(TRequestStatus& aStatus,const TDesC& anAddressDesc, TInt aPortNum, TCallBack aDisconnectFunction, const CImIAPPreferences& aIAPPreferences,TInt aType, TBool aEnableTimeout = ETrue);
377 IMPORT_C TInt Send(const TDesC8& aDesc);
378 IMPORT_C TInt Send(TRefByValue<const TDesC8> aFmt,...);
379 IMPORT_C TInt SendReceive(const TDesC8& aDesc);
380 IMPORT_C TInt Receive(TDes8& rDes);
381 IMPORT_C void Receive(TRequestStatus &aStatus, TDes8& rDes);
382 IMPORT_C static CImTextServerSession *NewLC (TImOperationMode aMode, RSocketServ &aServerServ);
383 IMPORT_C static CImTextServerSession *NewL(RSocketServ &aServerServ);
384 //Do not call SetSecurity. Call SetSSLTLSResponseL
385 IMPORT_C TInt SetSecurity(TBool aSecurityOn, TBool aUnattendedMode = FALSE);
386 IMPORT_C void PerformLogging(TBool aLogging);
390 //cat Construction and Destruction
391 @fn CImTextServerSession()
392 Intended Usage : Constructor. First phase of two-phase construction method. Does
393 non-allocating construction.
397 CImTextServerSession();
399 CImTextServerSession(RSocketServ& aSocketServ, CImConnect& aConnect);
402 @fn CImTextServerSession(TInt aSendIdleTime, TInt aReceiveIdleTime)
403 Intended Usage : Constructor. First phase of two-phase construction method. Does
404 non-allocating construction.
406 @param aSendIdleTime is the time for which the idle timer runs (for a send)
407 @param aReceiveIdleTime is the time for which the idle timer runs (for a receive)
409 CImTextServerSession(TInt aSendIdleTime, TInt aReceiveIdleTime);
411 CImTextServerSession(TInt aSendIdleTime, TInt aReceiveIdleTime, RSocketServ& aSocketServ, CImConnect& aConnect);
414 //cat Construction and Destruction.
416 Intended Usage : Second phase of two-phase construction method. Does any
417 allocations required to fully construct the object.
420 @pre First phase of construction is complete
421 @post The object is fully constructed and initialised.
428 void CreateLogFile(TInt aPortNum);
429 void OpenScriptFile(TInt aPortNum);
432 void DoComplete(TInt& aStatusValue); // Cleanup code
435 // these called from DoRunL;
436 void SocketConnect();
437 void DoConnectedToSocketL();
438 void DoQueueConnect();
440 void RealReceive(TDes8& aDesc);
441 void RealSend(const TDesC8& aDesc);
443 @fn ParseSSLTLSResponseL()
444 Intended Usage : session will compare the response(for TLS command)
445 with the MTMs response
447 @leave KImskSSLTLSNegotiateFailed if the response doesn't match
448 @post CSecureSocket object is created
450 void ParseSSLTLSResponseL();
453 @fn CreateSecureSocketL()
454 Intended Usage : to use secure socket connection
457 @post CSecureSocket object is created and iSecurityState is set to EImSecurityStateOn;
459 void CreateSecureSocketL();
462 @fn QueueGenericConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool aEnableTimeout = ETrue)
463 Intended Usage : Queue a standard or wrapped SSL connect on an socket assuming the socket is successfully opened. Called by SSLQueueConnectL and QueueConnectL
464 Error Condition : KErrNoMemory, EImskSocketOpen
466 @param aStatus Asynchronous completion status
467 @param anAddressDesc is the IP address
468 @param aIAPPreferences is the IAP connection preference to be used
469 @param aPortNum is the port number eg. 143, 993
470 @param aSSLDomainName SSL domain name to use for secure sockets
472 @post connection is ready to send and receive data.
474 void QueueGenericConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName);
476 #if defined(__IMSK_SIMULATION)
477 void ReadNextPeriod();
478 TUint32 GetTokenValue(TInt aTokenLen, const TPtrC8& aBuffer);
480 TBool SuspendPeriodSet();
481 void ResetSuspendPeriod();
482 void SetAfterTimer();
483 TInt ReadConfigNum(const TDesC& aName);
492 EImDialUsingOverride,
493 EImTLSHandShakeStarted,
494 EImSendReceiveTimedOut
497 enum TImSendReceiveState
502 EImReceivingBinaryData,
503 EImSendingQueueReceive,
504 EImSuspended, //used when we are in a simulated GPRS suspend.
507 enum TImSecurityState
511 EImSecurityStateFailed
514 /** handle to the socket */
516 /** handle to RSocketServ */
518 /** handle to Hostresolver */
519 RHostResolver iHostResolver;
520 /** handle to secure socket for SSL/TLS connection */
521 CSecureSocket* iSecureSocket;
523 TUint32 iCurrentIAPcache;
524 /** Used to find if IAP is cached */
525 TBool iIAPCached; // true if the above value can be used.
526 /** result of the host resolver */
528 /** port number e.g. 25 for SMTP, 143 for IMAP and 110 for POP */
530 /** server address */
532 /** data returned by the socket */
533 TImMailBuffer iReceive;
535 TImSocketState iState;
536 TImSendReceiveState iSendReceive;
539 TImLineType iCurrentLineType;
541 /** to log connection data */
543 /** IP address name */
544 TBuf<KImskIPAddressLen> iLocalName;
545 /** secure state i.e to use Secure socket */
547 TImSecurityState iSecurityState;
548 const CImIAPPreferences* iIAPPreferences;
550 CImConnect* iConnect;
552 TDes8* iReceiveData; // buffer we just recieved data into
556 /** response for different mail protocols like 220,+OK, OK, BAD */
557 HBufC8* iTLSResponse; //response for different mail protocols like 220,+OK, OK, BAD
558 /** internal flag to read tls response */
559 TBool iReadTLSResponse;
560 TBool iPerformLogging;
561 TBool iWrappedSocket;
563 CImSocketIdleTimer* iSocketIdleTimer;
564 TTimeIntervalMicroSeconds32 iSendIdleTime;
565 TTimeIntervalMicroSeconds32 iReceiveIdleTime;
567 /** A shorter idle timeout, used when a fast response is expected */
568 TTimeIntervalMicroSeconds32 iSendShortIdleTime;
569 TTimeIntervalMicroSeconds32 iReceiveShortIdleTime;
572 #ifdef __IMSK_SCRIPTING
573 CImTextServerScript* iScript;
576 #if defined(__IMSK_SIMULATION)
581 TUint32 iScriptedIAP; // value to return for iap when scripting
582 TUint32 iBearerIAP; // value to return for bearer when scripting
585 TImSendReceiveState iSuspendedState;
587 RTimer iSuspendTimer;
591 TBool iGprsConfigExists;
595 TTime iLastSuspend; // time last suspension took place
598 TTimeIntervalSeconds iStart; // number of seconds since last delay
599 // before the following delay occurs.
600 // if 0 no suspend is required.
601 TTimeIntervalSeconds iDuration; // how long to delay. If 0 no suspend is
603 TBool iRepeat; // repeat the above delay for an
606 HBufC8* iSendData; // suspended data
607 #endif // __IMSK_SIMULATION
609 CImTextServerSession* iPrimaryTextServerSession; //Only going to be set on the secondary session
611 TBool iClientOwnsConnection;
613 /** SSL domain name for secure sockets */
614 HBufC8* iSSLDomainName;
615 TBool iSocketIdleTimeSet; // iSocketIdleTimeSet=ETrue, if smtp server did not responds within 10 seconds after sending "."