email/pop3andsmtpmtm/servermtmutils/src/IMSK.CPP
changeset 0 72b543305e3a
child 76 60a8a215b0ec
equal deleted inserted replaced
-1:000000000000 0:72b543305e3a
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "IMSK.H"
       
    17 #include <imutcon.h>
       
    18 #include "IMSKSCR.H"
       
    19 #include "IMUTDLL.H"
       
    20 #include "cimsocketidletimer.h"
       
    21 
       
    22 #include <e32hal.h>
       
    23 #include <securesocket.h>
       
    24 
       
    25 #include <bautils.h>
       
    26 #include <barsread.h>
       
    27 
       
    28 #include <es_enum.h>
       
    29 #include <ssl_internal.h>
       
    30 
       
    31 
       
    32 /*************************************************************
       
    33 * Notes:                                           
       
    34 *                                                  
       
    35 * GetIAPBearer won't work if a new bearer is added,
       
    36 * it will return KImskUnknownBearer                 
       
    37 *                                                  
       
    38 *************************************************************/
       
    39 
       
    40 _LIT8(KImCarriageReturn,"\r\n");
       
    41 _LIT(KSSLProtocol,"tls1.0");
       
    42 _LIT8(KNullSSLDomainName, "");
       
    43 
       
    44 const TInt KImutMicroSecondsToMinutes = 60000000;
       
    45 const TInt KImutMicroSecondsToSeconds = 1000000;
       
    46 
       
    47 #if defined(__IMSK_SIMULATION)
       
    48 _LIT(KGPRSConfigFile, "c:\\logs\\email\\imutconf\\gprs.cfg");
       
    49 _LIT(KFailIAPConfigFile, "c:\\logs\\email\\imutconf\\iapfail.cfg");
       
    50 _LIT8(KStart, "start:");
       
    51 _LIT8(KDuration, "duration:");
       
    52 _LIT8(KRepeat, "repeat:");
       
    53 _LIT8(KLogGPRSSimSuspended, "GPRS simulated suspend (%d)");
       
    54 _LIT8(KLogGPRSSimUnSuspended, "GPRS returned from suspend");
       
    55 #endif 	// __IMSK_SIMULATION
       
    56 
       
    57 #ifndef _NO_MSG_LOGGING
       
    58 #define __IMSK_LOGGING
       
    59 #endif
       
    60 
       
    61 #if defined(__IMSK_LOGGING)
       
    62 #define __LOG_IN(text) (iLog?iLog->AppendResponse(text):void(0))
       
    63 #define __LOG_COMMENT_OUT(text) (iLog?iLog->AppendComment(text):void(0))
       
    64 #define __LOG_OUT(text) (iLog?iLog->AppendOut(text):void(0))
       
    65 #define __LOG_ERR(text,err) (iLog?iLog->AppendError(text,err):void(0))
       
    66 #else
       
    67 #define __LOG_IN(text) (void(0))
       
    68 #define __LOG_COMMENT_OUT(text) (void(0))
       
    69 #define __LOG_OUT(text) (void(0))
       
    70 #define __LOG_ERR(text,err) (void(0))
       
    71 #endif
       
    72 
       
    73 
       
    74 #if defined(__IMSK_LOGGING)
       
    75 // IMSK Logging
       
    76 _LIT8(KLogResolveCompleted, "Resolve completed");
       
    77 _LIT8(KLogResolveQueued, "Resolve queued");
       
    78 _LIT8(KLogConnectQueued, "Connect queued on port ");
       
    79 _LIT8(KLogConnectCompleted, "Connect completed");
       
    80 _LIT8(KLogSendReceiveCompleted, "SendReceive/Receiving completed");
       
    81 _LIT8(KLogSendReceiveBinaryCompleted, "SendReceive/ReceivingBinaryData completed");
       
    82 _LIT8(KLogServerConnectionError, "Server Connection error");
       
    83 _LIT8(KLogReadCancelled, "Read cancelled");
       
    84 _LIT8(KLogWriteCancelled, "Write cancelled");
       
    85 _LIT8(KLogOverridefailed, "Overide failed with"); 
       
    86 _LIT8(KLogTLSHandShake, "TLS handshake Started"); 
       
    87 _LIT8(KLogTLSHandShakeCompleted, "TLS handshake completed"); 
       
    88 _LIT8(KLogSocketClosed, "Closed socket"); 
       
    89 _LIT8(KLogTLSResponse, "SSL/TLS response should be '%S'");
       
    90 _LIT8(KLogSendReceiveTimedOut, "SendReceive has timed out");
       
    91 
       
    92 #endif
       
    93 
       
    94 //*********************************************************************************************/
       
    95 //*                                                                                           */
       
    96 //*                           Construction/Destruction functions                              */
       
    97 //*                                                                                           */
       
    98 //*********************************************************************************************/
       
    99 
       
   100 LOCAL_C void RequestComplete(TRequestStatus& aStatus,TInt aError)
       
   101 	{
       
   102 	TRequestStatus* pStatus=&aStatus;
       
   103 	User::RequestComplete(pStatus,aError);
       
   104 	}
       
   105 
       
   106 EXPORT_C CImTextServerSession  *CImTextServerSession::NewL()
       
   107 	{
       
   108 	CImTextServerSession* self=new (ELeave) CImTextServerSession();
       
   109 	CleanupStack::PushL(self);
       
   110 	self->ConstructL();
       
   111 	CleanupStack::Pop();
       
   112 	return self;
       
   113 	}
       
   114 
       
   115 /**
       
   116 @internalTechnology
       
   117 @released
       
   118 */
       
   119 EXPORT_C CImTextServerSession  *CImTextServerSession::NewL(RSocketServ& aSocketServ, CImConnect& aConnect)
       
   120 	{
       
   121 	CImTextServerSession* self=new (ELeave) CImTextServerSession(aSocketServ, aConnect);
       
   122 	CleanupStack::PushL(self);
       
   123 	self->ConstructL();
       
   124 	CleanupStack::Pop();
       
   125 	return self;
       
   126 	}
       
   127 
       
   128 /**
       
   129 Factory constructor that allows setting of send and receive idle times.
       
   130 
       
   131 An idle time of zero implies that no timer should be set.
       
   132 
       
   133 @param	aSendIdleTime
       
   134 The idle time in minutes allowed for sending. A value of zero indicates that no timer 
       
   135 should be set.
       
   136 
       
   137 @param	aReceiveIdleTime
       
   138 The idle time in minutes allowed for receiving. A value of zero indicates that no timer 
       
   139 should be set.
       
   140 
       
   141 @return
       
   142 A pointer to the newly created CImTextServerSession object. 
       
   143 */
       
   144 EXPORT_C CImTextServerSession  *CImTextServerSession::NewL(TInt aSendIdleTime, TInt aReceiveIdleTime)
       
   145 	{
       
   146 	CImTextServerSession* self=new (ELeave) CImTextServerSession(aSendIdleTime, aReceiveIdleTime);
       
   147 	CleanupStack::PushL(self);
       
   148 	self->ConstructL();
       
   149 	CleanupStack::Pop();
       
   150 	return self;
       
   151 	}
       
   152 
       
   153 /**
       
   154 @internalTechnology
       
   155 @released
       
   156 */
       
   157 EXPORT_C CImTextServerSession* CImTextServerSession::NewL(TInt aSendIdleTime, TInt aReceiveIdleTime, RSocketServ& aSocketServ, CImConnect& aConnect)
       
   158 	{
       
   159 	CImTextServerSession* self=new (ELeave) CImTextServerSession(aSendIdleTime, aReceiveIdleTime, aSocketServ, aConnect);
       
   160 	CleanupStack::PushL(self);
       
   161 	self->ConstructL();
       
   162 	CleanupStack::Pop();
       
   163 	return self;
       
   164 	}
       
   165 
       
   166 CImTextServerSession::CImTextServerSession()
       
   167 	: CMsgActive(EActivePriorityHigh), 
       
   168 	  iState(EImClosed),
       
   169 	  iPerformLogging(ETrue)
       
   170 	{
       
   171 	}
       
   172 
       
   173 CImTextServerSession::CImTextServerSession(RSocketServ& aSocketServ, CImConnect& aConnect)
       
   174 	: CMsgActive(EActivePriorityHigh), 
       
   175 	  iServ(aSocketServ),
       
   176 	  iState(EImClosed),
       
   177 	  iConnect(&aConnect),
       
   178 	  iPerformLogging(ETrue),
       
   179 	  iClientOwnsConnection(ETrue)
       
   180 	{
       
   181 	}
       
   182 
       
   183 /**
       
   184 Constructor that allows setting of the send and receive idle times.
       
   185 
       
   186 An idle time of zero implies that no timer should be set.
       
   187 
       
   188 @param	aSendIdleTime
       
   189 The idle time in minutes allowed for sending. A value of zero indicates that no timer 
       
   190 should be set.
       
   191 
       
   192 @param	aReceiveIdleTime
       
   193 The idle time in minutes allowed for receiving. A value of zero indicates that no timer 
       
   194 should be set.
       
   195 */
       
   196 CImTextServerSession::CImTextServerSession(TInt aSendIdleTime, TInt aReceiveIdleTime)
       
   197 	: CMsgActive(EActivePriorityHigh), 
       
   198 	  iState(EImClosed),
       
   199 	  iPerformLogging(ETrue),
       
   200 	  iSendIdleTime(aSendIdleTime*KImutMicroSecondsToMinutes),
       
   201 	  iReceiveIdleTime(aReceiveIdleTime*KImutMicroSecondsToMinutes),iPrimaryTextServerSession(NULL)
       
   202 	{
       
   203 	}
       
   204 
       
   205 CImTextServerSession::CImTextServerSession(TInt aSendIdleTime, TInt aReceiveIdleTime, RSocketServ& aSocketServ, CImConnect& aConnect)
       
   206 	: CMsgActive(EActivePriorityHigh), 
       
   207 	  iServ(aSocketServ),
       
   208 	  iState(EImClosed),
       
   209 	  iConnect(&aConnect),
       
   210 	  iPerformLogging(ETrue),
       
   211 	  iSendIdleTime(aSendIdleTime*KImutMicroSecondsToMinutes),
       
   212 	  iReceiveIdleTime(aReceiveIdleTime*KImutMicroSecondsToMinutes),
       
   213 	  iClientOwnsConnection(ETrue)
       
   214 	{
       
   215 	}
       
   216 
       
   217 //
       
   218 // 2nd stage of construction
       
   219 //
       
   220 void CImTextServerSession::ConstructL()
       
   221 	{
       
   222 	iBuffer = HBufC8::NewL(KImMailMaxBufferSize*2 +2);
       
   223 
       
   224 	if (!iClientOwnsConnection)
       
   225 		{
       
   226 		User::LeaveIfError(iServ.Connect());
       
   227 		}
       
   228 
       
   229 #if defined(__IMSK_SIMULATION)
       
   230 
       
   231 	// if gprs suspension file exists - use its contents to determine
       
   232 	// the the time to delay TCP/IP traffic
       
   233 
       
   234 	User::LeaveIfError(iFs.Connect());
       
   235 	TInt err = iGprsFile.Open(iFs,KGPRSConfigFile,EFileShareAny);
       
   236 
       
   237 	if (err != KErrNone && err != KErrPathNotFound && err != KErrNotFound)
       
   238 		User::Leave(err);
       
   239 	
       
   240 	if (err == KErrNone)
       
   241 		{
       
   242 		iGprsConfigExists=ETrue;
       
   243 		// read the first delay period
       
   244 		ReadNextPeriod();
       
   245 
       
   246 		// get baseline time
       
   247 		if (SuspendPeriodSet())
       
   248 			iLastSuspend.UniversalTime();
       
   249 		
       
   250 		User::LeaveIfError(iSuspendTimer.CreateLocal());
       
   251 		}
       
   252 	else
       
   253 		iGprsConfigExists=EFalse;
       
   254 #endif	// __IMSK_SIMULATION
       
   255 
       
   256 	iSocketIdleTimer = CImSocketIdleTimer::NewL(*this);
       
   257 	CActiveScheduler::Add(this); 
       
   258 	}
       
   259 
       
   260 //
       
   261 // Destruction
       
   262 //
       
   263 CImTextServerSession::~CImTextServerSession()
       
   264 	{
       
   265 	Disconnect();
       
   266 	delete iBuffer;
       
   267 	if (!iClientOwnsConnection)
       
   268 		{
       
   269 		delete iConnect;
       
   270 		iServ.Close();
       
   271 		}
       
   272 	delete iSentData;
       
   273 	delete iTLSResponse;
       
   274 #if defined(__IMSK_SIMULATION)
       
   275 	iGprsFile.Close();
       
   276 	delete iSendData;
       
   277 	iFs.Close();
       
   278 #endif // __IMSK_SIMULATION
       
   279 	delete iSocketIdleTimer;
       
   280 	delete iSSLDomainName;
       
   281 	}
       
   282 
       
   283 
       
   284 //*********************************************************************************************/
       
   285 //*                                                                                           */
       
   286 //*                           Connect/Disconnect functions                                    */
       
   287 //*                                                                                           */
       
   288 //*********************************************************************************************/
       
   289 
       
   290 //
       
   291 // Queue a standard or wrapped SSL connect (depending on state of iWrappedSocket) assuming the 
       
   292 //  socket is successfully opened- RunL called on completion
       
   293 //
       
   294 
       
   295 void CImTextServerSession::QueueGenericConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName)
       
   296 	{
       
   297 #if defined(__IMSK_LOGGING)
       
   298 	CreateLogFile(aPortNum);  // Attempt to create the log file
       
   299 #endif
       
   300 	Queue(aStatus);
       
   301 
       
   302 	iIAPPreferences=&aIAPPreferences;
       
   303 	iPortNum=aPortNum;
       
   304 	iAddressDesc.Set(anAddressDesc);
       
   305 
       
   306 	delete iSSLDomainName;
       
   307 	iSSLDomainName = NULL;
       
   308 	if (aSSLDomainName.Length() > 0)
       
   309 		{
       
   310 		iSSLDomainName = aSSLDomainName.AllocL();
       
   311 		}
       
   312 	else
       
   313 		{
       
   314 		iSSLDomainName = HBufC8::NewL(iAddressDesc.Length());
       
   315 		TPtr8 addr8ptr = iSSLDomainName->Des();
       
   316 		addr8ptr.Copy(iAddressDesc);
       
   317 		}
       
   318 
       
   319 	__ASSERT_ALWAYS(iState==EImClosed,gPanic(EImskSocketOpen));
       
   320 
       
   321 	iState = EImDialUsingOverride;
       
   322 #if defined(__IMSK_SCRIPTING)
       
   323 	if (!iScript)
       
   324 		OpenScriptFile(iPortNum); // open the relevant script file if it exists
       
   325 
       
   326 	if(iScript)
       
   327 		RequestComplete(iStatus,KErrNone);
       
   328 	else
       
   329 #endif //(__IMSK_SCRIPTING)
       
   330 		{
       
   331 		// If we are not using the clients connection, create our own one now
       
   332 		if (!iClientOwnsConnection)
       
   333 			{
       
   334 			delete iConnect;
       
   335 			iConnect = 0;
       
   336 			iConnect = CImConnect::NewL(*iIAPPreferences,*this);
       
   337 			}
       
   338 #if defined(__IMSK_SIMULATION)
       
   339 		iConnect->SetIAPsToFail(ReadConfigNum(KFailIAPConfigFile));
       
   340 #endif //(__IMSK_SIMULATION)
       
   341 
       
   342 		// if local textseversession is active, then connect the session using existing RConnection
       
   343 		if(iPrimaryTextServerSession)
       
   344 			{
       
   345 			// Attaching the existing RConnection.
       
   346 			iConnect->SecondaryStartL(iPrimaryTextServerSession);			
       
   347 			// Queue the connection
       
   348 			DoQueueConnect();
       
   349 			return;			
       
   350 			}
       
   351 		else
       
   352 			{
       
   353 			// If we are using the clients connection then it should have already been
       
   354 			// started, so just self complete to keep the state machine going. If it is
       
   355 			// our own connection, start it now.
       
   356 			if (iClientOwnsConnection)
       
   357 				{
       
   358 				RequestComplete(iStatus, KErrNone);
       
   359 				}
       
   360 			else
       
   361 				{
       
   362 				iConnect->StartL(iStatus);	
       
   363 				}
       
   364 			}
       
   365 		}
       
   366 	SetActive();
       
   367 	}
       
   368 
       
   369 //
       
   370 // Queue a connect assuming the socket is successfully opened- RunL called on completion
       
   371 //
       
   372 
       
   373 EXPORT_C void CImTextServerSession::QueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool /*aEnableTimeout*/)
       
   374 	{
       
   375 		iWrappedSocket=EFalse;
       
   376 		QueueGenericConnectL(aStatus, anAddressDesc, aPortNum,  aIAPPreferences, KNullSSLDomainName);
       
   377 	}
       
   378 
       
   379 /**
       
   380 Queue a connect on a socket assuming the socket is successfully opened.
       
   381 
       
   382 @param aStatus Asynchronous completion status
       
   383 @param aAddressDesc Address of the server to connect to
       
   384 @param aIAPPreferences IAP connection preferences to be used		
       
   385 @param aPortNum Port number eg. 993, 465, 995.
       
   386 @param aSSLDomainName SSL domain name to use for the connection
       
   387 @pre   None
       
   388 @post  Connection is ready to send and receive data
       
   389 @since 9.5
       
   390 */
       
   391 EXPORT_C void CImTextServerSession::QueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName)
       
   392 	{
       
   393 	iWrappedSocket=EFalse;
       
   394 	QueueGenericConnectL(aStatus, anAddressDesc, aPortNum,  aIAPPreferences, aSSLDomainName);
       
   395 	}
       
   396 
       
   397 //
       
   398 // Queue a wrapped SSL connect assuming the socket is successfully opened- RunL called on completion
       
   399 //
       
   400 
       
   401 EXPORT_C void CImTextServerSession::SSLQueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, TBool /*aEnableTimeout*/)
       
   402 	{
       
   403 		iWrappedSocket=ETrue;
       
   404 		QueueGenericConnectL(aStatus, anAddressDesc, aPortNum,  aIAPPreferences, KNullSSLDomainName);
       
   405 	}
       
   406 
       
   407 /**
       
   408 Queue a wrapped SSL connect on a socket assuming the socket is successfully opened.
       
   409 
       
   410 @param aStatus Asynchronous completion status
       
   411 @param aAddressDesc Address of the server to connect to
       
   412 @param aIAPPreferences IAP connection preferences to be used		
       
   413 @param aPortNum Port number eg. 993, 465, 995.
       
   414 @param aSSLDomainName SSL domain name to use for the connection
       
   415 @pre   None
       
   416 @post  Connection is ready to send and receive data
       
   417 @since 9.5
       
   418 */
       
   419 EXPORT_C void CImTextServerSession::SSLQueueConnectL(TRequestStatus &aStatus,const TDesC& anAddressDesc, TInt aPortNum, const CImIAPPreferences& aIAPPreferences, const TDesC8& aSSLDomainName)
       
   420 	{
       
   421 	iWrappedSocket=ETrue;
       
   422 	QueueGenericConnectL(aStatus, anAddressDesc, aPortNum, aIAPPreferences, aSSLDomainName);
       
   423 	}
       
   424 
       
   425 //
       
   426 // Public socket disconnection
       
   427 //	
       
   428 EXPORT_C void CImTextServerSession::Disconnect()
       
   429 	{
       
   430 	iIAPCached=EFalse;
       
   431 	Cancel();
       
   432 	Close();
       
   433 	}
       
   434 
       
   435 
       
   436 EXPORT_C void CImTextServerSession::Disconnect(TRequestStatus& aStatus)
       
   437 	{
       
   438 	Disconnect();
       
   439 	RequestComplete(aStatus,KErrNone);
       
   440 	}
       
   441 
       
   442 
       
   443 //*********************************************************************************************/
       
   444 //*                                                                                           */
       
   445 //*                           Send/Recieve/Query functions                                    */
       
   446 //*                                                                                           */
       
   447 //*********************************************************************************************/
       
   448 
       
   449 //
       
   450 // Async send functions
       
   451 //
       
   452 EXPORT_C void CImTextServerSession::Send(TRequestStatus &aStatus, const TDesC8& aDesc)
       
   453 	{
       
   454 	if (iState!=EImSendReceive)
       
   455 		{
       
   456 		RequestComplete(aStatus,KErrDisconnected);
       
   457 		return;
       
   458 		}
       
   459 	
       
   460 	iSendShortIdleTime		= 0;
       
   461 	iReceiveShortIdleTime	= 0;
       
   462 	
       
   463 	Queue(aStatus);
       
   464 
       
   465 	iSendReceive=EImSending;
       
   466 	RealSend(aDesc);
       
   467 	}
       
   468 
       
   469 //
       
   470 // Async send function, specifying short idle timeouts should be used.
       
   471 // aIdleTime specifies the send and next receive timeout to be used in seconds
       
   472 //
       
   473 EXPORT_C void CImTextServerSession::SendWithTimeout(TRequestStatus &aStatus, TInt aIdleTime, const TDesC8& aDesc)
       
   474 	{
       
   475 	if (iState!=EImSendReceive)
       
   476 		{
       
   477 		RequestComplete(aStatus,KErrDisconnected);
       
   478 		return;
       
   479 		}
       
   480 	
       
   481 	iSendShortIdleTime    = aIdleTime*KImutMicroSecondsToSeconds;
       
   482 	iReceiveShortIdleTime = aIdleTime*KImutMicroSecondsToSeconds;
       
   483 
       
   484 	Queue(aStatus);
       
   485 
       
   486 	iSendReceive=EImSending;
       
   487 	RealSend(aDesc);
       
   488 	}
       
   489 	
       
   490 EXPORT_C void CImTextServerSession::SendQueueReceiveWithTimeout(TRequestStatus& aStatus, TInt aIdleTime, const TDesC8& aDesc) 
       
   491 	{ 
       
   492 	if (iState!=EImSendReceive)      
       
   493 		{ 
       
   494 		RequestComplete(aStatus, KErrDisconnected);
       
   495 		return;
       
   496 		} 
       
   497                
       
   498 		iSendShortIdleTime    = aIdleTime*KImutMicroSecondsToSeconds; 
       
   499 		iReceiveShortIdleTime = aIdleTime*KImutMicroSecondsToSeconds; 
       
   500     	Queue(aStatus); 
       
   501     
       
   502 		iSendReceive=EImSendingQueueReceive; 
       
   503 		RealSend(aDesc);
       
   504 	} 	
       
   505 
       
   506 //
       
   507 // async. Send
       
   508 //
       
   509 EXPORT_C void CImTextServerSession::Send(TRequestStatus &aStatus, TRefByValue<const TDesC8> aFmt,...)
       
   510 	{
       
   511 	VA_LIST list;
       
   512 	VA_START(list,aFmt);
       
   513 	TBuf8<2*KImMailMaxBufferSize+2>aBuf;
       
   514 	aBuf.AppendFormatList(aFmt,list);
       
   515 
       
   516 	Send(aStatus, aBuf);
       
   517 	}
       
   518 
       
   519 
       
   520 //
       
   521 // async Send and receive operation
       
   522 //
       
   523 EXPORT_C void CImTextServerSession::SendQueueReceive(TRequestStatus &aStatus, const TDesC8& aDesc)
       
   524 	{
       
   525 	if (iState!=EImSendReceive)
       
   526 		{
       
   527 		RequestComplete(aStatus,KErrDisconnected);
       
   528 		return;
       
   529 		}
       
   530 
       
   531 	Queue(aStatus);
       
   532 
       
   533 	iSendReceive=EImSendingQueueReceive;
       
   534 
       
   535 	RealSend(aDesc);
       
   536 	}
       
   537 
       
   538 
       
   539 //
       
   540 // async. SendQueueRecieve
       
   541 //
       
   542 EXPORT_C void CImTextServerSession::SendQueueReceive(TRequestStatus &aStatus, TRefByValue<const TDesC8> aFmt,...)
       
   543 	{
       
   544 	VA_LIST list;
       
   545 	VA_START(list,aFmt);
       
   546 	TBuf8<2*KImMailMaxBufferSize+2>aBuf;
       
   547 	aBuf.AppendFormatList(aFmt,list);
       
   548 
       
   549 	SendQueueReceive(aStatus, aBuf);
       
   550 	}
       
   551 
       
   552 
       
   553 
       
   554 //
       
   555 // User queues a new request from the socket (unless there's a full line of data in buffer
       
   556 // then signal user and there's no need to make a receive request)
       
   557 //
       
   558 EXPORT_C void CImTextServerSession::QueueReceiveNextTextLine(TRequestStatus& aStatus)
       
   559 	{
       
   560 	if (iState!=EImSendReceive)
       
   561 		{
       
   562 		RequestComplete(aStatus,KErrDisconnected);
       
   563 		return;
       
   564 		}
       
   565 
       
   566 	iSendReceive=EImReceiving;
       
   567 
       
   568 
       
   569 	Queue(aStatus);
       
   570 
       
   571 	// Is there already a full text line in the buffer (ie is there a CRLF?)
       
   572 	if(iBuffer->Find(KImCarriageReturn)==KErrNotFound)
       
   573 		{
       
   574 		RealReceive(iReceive);
       
   575 		return;
       
   576 		}
       
   577 	// force calling active object to terminate
       
   578 	Complete(KErrNone);
       
   579 	}
       
   580 
       
   581 //
       
   582 // Return first full line of data received from socket to user
       
   583 //
       
   584 EXPORT_C TImLineType CImTextServerSession::GetCurrentTextLine(TDes8& aDesc)
       
   585 	{
       
   586 	__ASSERT_ALWAYS(this->IsActive()==EFalse,gPanic(EImskSocketStillActive));
       
   587 	// we have two possibilites a CRLF term line or we've filled our buffer
       
   588 	TInt bufLength=aDesc.MaxLength();
       
   589 	TPtr8 bufPtr=iBuffer->Des();
       
   590 
       
   591 	if(iBuffer->Length()==0)
       
   592 		{
       
   593 		aDesc.Zero();
       
   594 		return EReceiveBufferEmpty;
       
   595 		}
       
   596 
       
   597 	TInt crLfPos=iBuffer->Find(KImCarriageReturn); // need to update 
       
   598 	if(crLfPos!=KErrNotFound)
       
   599 		{
       
   600 		if(crLfPos<bufLength-1) // the user's buffer is big enough
       
   601 			{
       
   602 			bufLength=crLfPos+KCarriageLineFeedLength;
       
   603 			iCurrentLineType=ECRLFTerminated;
       
   604 			}
       
   605 		else if(crLfPos==bufLength-1)
       
   606 			{
       
   607 			iCurrentLineType=EBufferTooSmall;
       
   608 			--bufLength;
       
   609 			}
       
   610 		else // not big enough fill it and tell him there's more left incl. the CRLF
       
   611 			{
       
   612 			iCurrentLineType=EBufferTooSmall;
       
   613 			}
       
   614 		}
       
   615 	else if(iCurrentLineType==EReceiveBufferFull) // buffer full - you sort it out
       
   616 		{
       
   617 		bufLength=Min(iBuffer->Length(),bufLength);
       
   618 		}
       
   619 	else
       
   620 		{
       
   621 		// gPanic coz this shouldn't happen
       
   622 		gPanic(EImskUnknownState);
       
   623 		}
       
   624 	aDesc=iBuffer->Left(bufLength);
       
   625 	bufPtr.Delete(0,bufLength);
       
   626 
       
   627 	TInt left=iReceive.Length();
       
   628 	if (left)
       
   629 		{
       
   630 		if (left>bufLength)
       
   631 			left=bufLength;
       
   632 		bufPtr.Append(iReceive.Left(left));
       
   633 		iReceive.Delete(0,left);
       
   634 		}
       
   635 #if defined(__IMSK_SCRIPTING)
       
   636 	if(iScript)
       
   637 		__LOG_IN(aDesc);
       
   638 #endif
       
   639 	return iCurrentLineType;
       
   640 	}
       
   641 
       
   642 
       
   643 
       
   644 EXPORT_C void CImTextServerSession::ReceiveBinaryData(TRequestStatus& aStatus, TDes8& aDes, TInt aLen)
       
   645 	{
       
   646 	if (iState!=EImSendReceive)
       
   647 		{
       
   648 		RequestComplete(aStatus,KErrDisconnected);
       
   649 		return;
       
   650 		}
       
   651 	
       
   652 
       
   653 	Queue(aStatus);
       
   654 	iSendReceive=EImReceivingBinaryData;
       
   655 	iLen=aLen;
       
   656 	RealReceive(aDes);
       
   657 	}
       
   658 
       
   659 
       
   660 // Returns the IAP we are connecting/connected with in aIAP or returns an error code
       
   661 EXPORT_C TInt CImTextServerSession::GetIAPValue(TUint32 &aIAP)
       
   662 	{
       
   663 	TInt err=KErrNone;
       
   664 
       
   665 	if(iIAPCached)
       
   666 		// Return cached IAP value
       
   667 		{
       
   668 		aIAP=iCurrentIAPcache;
       
   669 		}
       
   670 	else
       
   671 		// IAP not yet cached
       
   672 		{
       
   673 #if defined(__IMSK_SCRIPTING)
       
   674 		if (iScript)
       
   675 			{
       
   676 			aIAP = 0;
       
   677 			return KErrNotFound;
       
   678 			}
       
   679 		else
       
   680 #endif //(__IMSK_SCRIPTING)
       
   681 			{			
       
   682 			err = iConnect->GetIAPValue(aIAP);
       
   683 			if(err==KErrNone && !(iState == EImClosed || iState == EImDialUsingOverride))
       
   684 				// Only cache if no error and connection is complete
       
   685 				{
       
   686 				iCurrentIAPcache=aIAP;
       
   687 				iIAPCached=ETrue;
       
   688 				}
       
   689 			}
       
   690 		}
       
   691 
       
   692 	return(err);
       
   693 	}
       
   694 //Returns the Name of the RConnection in use.
       
   695 EXPORT_C TInt CImTextServerSession::GetRConnectionName(TName &aName)
       
   696 	{
       
   697 #if defined(__IMSK_SCRIPTING)
       
   698 	if (iScript)
       
   699 		{
       
   700 		_LIT(KNull,"");
       
   701 		aName.Copy(KNull);
       
   702 		return KErrNotFound;			
       
   703 		}
       
   704 	else		
       
   705 #endif //(__IMSK_SCRIPTING)
       
   706 		{
       
   707 		return (iConnect->GetRConnectionName(aName));		
       
   708 		}
       
   709 	}
       
   710 
       
   711 // Returns the bearer type we are connected to with in aBearer or returns an error code
       
   712 EXPORT_C TInt CImTextServerSession::GetIAPBearer(TUint32 &aBearer)
       
   713 	{
       
   714 #if defined(__IMSK_SCRIPTING)
       
   715 	if (iScript)
       
   716 		{
       
   717 		aBearer = 0;
       
   718 		return KErrNotFound;
       
   719 		}
       
   720 	else
       
   721 #endif //(__IMSK_SCRIPTING)
       
   722 		{		
       
   723 		return iConnect->GetIAPBearer(aBearer);
       
   724 		}
       
   725 	}
       
   726 
       
   727 // Returns the last socket activity timeout value for the connection
       
   728 EXPORT_C TInt CImTextServerSession::GetLastSocketActivityTimeout(TUint32& aTimeout)
       
   729 	{
       
   730 #if defined(__IMSK_SCRIPTING)
       
   731 	if (iScript)
       
   732 		{
       
   733 		aTimeout = 0;
       
   734 		return KErrNotFound;
       
   735 		}
       
   736 	else
       
   737 #endif //(__IMSK_SCRIPTING)
       
   738 		{		
       
   739 		return iConnect->GetLastSocketActivityTimeout(aTimeout);
       
   740 		}
       
   741 	}
       
   742 
       
   743 RSocketServ& CImTextServerSession::GetSocketServ()
       
   744 	{
       
   745 	return iServ;
       
   746 	}
       
   747 
       
   748 //*********************************************************************************************/
       
   749 //*                                                                                           */
       
   750 //*                           Other public functions                                          */
       
   751 //*                                                                                           */
       
   752 //*********************************************************************************************/
       
   753 
       
   754 
       
   755 EXPORT_C const TDesC& CImTextServerSession::LocalName()
       
   756 	{
       
   757    	return iLocalName;	// a text descriptor - containing the numeric IP address of this client, eg "194.255.242.34"
       
   758 	}
       
   759 
       
   760 
       
   761 EXPORT_C void CImTextServerSession::LogText(const TDesC8& aDesc)
       
   762 	{
       
   763 	__LOG_COMMENT_OUT(aDesc);
       
   764 	}
       
   765 
       
   766 
       
   767 
       
   768 EXPORT_C void CImTextServerSession::PerformLogging(TBool aLogging)
       
   769 	{
       
   770 	iPerformLogging = aLogging;
       
   771 	}
       
   772 
       
   773 
       
   774 
       
   775 EXPORT_C void CImTextServerSession::LogError(const TDesC8& aDesc, const TInt aNumber)
       
   776 	{
       
   777 	__LOG_ERR(aDesc,aNumber);
       
   778 	}
       
   779 
       
   780 
       
   781 
       
   782 
       
   783 EXPORT_C void CImTextServerSession::SetSSLTLSResponseL(const TDesC8& aDesc)
       
   784 	{
       
   785 	__ASSERT_ALWAYS( aDesc.Length(), gPanic(EImskNoTLSResponseString));
       
   786 	iTLSResponse=aDesc.AllocL();
       
   787 	if (iTLSResponse==NULL)
       
   788 		User::Leave(KErrNoMemory);
       
   789 	iReadTLSResponse=ETrue;
       
   790 #if defined(__IMSK_LOGGING)
       
   791 	TBuf8<1024> buf;
       
   792 	buf.AppendFormat(KLogTLSResponse,&aDesc);
       
   793 	__LOG_COMMENT_OUT(buf);
       
   794 #endif
       
   795 	}
       
   796 
       
   797 
       
   798 void CImTextServerSession::SocketIdle()
       
   799 	{
       
   800 	__LOG_COMMENT_OUT(KLogSendReceiveTimedOut);
       
   801 
       
   802 	// The socket has been idle too long - probably in a half open situation 
       
   803 	// and server could well have disconnected the session and we'll never 
       
   804 	// know about it. So disconnect and notify the observer.
       
   805 	iSocketIdleTimeSet=ETrue;
       
   806 	Disconnect();
       
   807 	}
       
   808 
       
   809 
       
   810 //*********************************************************************************************/
       
   811 //*                                                                                           */
       
   812 //*                           Private IMSK connect functions                                  */
       
   813 //*                                                                                           */
       
   814 //*********************************************************************************************/
       
   815 
       
   816 	
       
   817 //
       
   818 // Queue a connect assuming the socket is successfully opened- RunL called on completion
       
   819 //
       
   820 void CImTextServerSession::ParseSSLTLSResponseL()
       
   821 	{
       
   822 	__LOG_COMMENT_OUT(*iBuffer);
       
   823 	if (iBuffer->Find(*iTLSResponse)==KErrNotFound)
       
   824 		{
       
   825 		__LOG_ERR(_L8("ParseSSLTLSResponseL failed with "),KImskSSLTLSNegotiateFailed);
       
   826 		Complete(KImskSSLTLSNegotiateFailed);
       
   827 		return;
       
   828 		}
       
   829 	delete iTLSResponse;  //finished with TLSresponse.  free the memory
       
   830 	iTLSResponse=NULL;
       
   831 	iReadTLSResponse=EFalse;
       
   832 	CreateSecureSocketL();
       
   833 	}
       
   834 
       
   835 void CImTextServerSession::CreateSecureSocketL()
       
   836 	{
       
   837 #if defined(__IMSK_SCRIPTING)
       
   838 	if (iScript)
       
   839 		{
       
   840 		iState=EImTLSHandShakeStarted;
       
   841 		RequestComplete(iStatus,KErrNone);
       
   842 		SetActive();
       
   843 		__LOG_COMMENT_OUT(KLogTLSHandShake);
       
   844 		return;
       
   845 		}
       
   846 #endif
       
   847 	iSecureSocket = CSecureSocket::NewL( iSocket, KSSLProtocol);
       
   848 	__ASSERT_DEBUG(iSSLDomainName, gPanic(EPanicNoSSLDomainName));
       
   849 	if (iSSLDomainName)
       
   850 		{
       
   851 		User::LeaveIfError(iSecureSocket->SetOpt(KSoSSLDomainName, KSolInetSSL, *iSSLDomainName));
       
   852 		}
       
   853 	iSecureSocket->StartClientHandshake( iStatus );
       
   854 	iState=EImTLSHandShakeStarted;
       
   855 	SetActive();
       
   856 	__LOG_COMMENT_OUT(KLogTLSHandShake);
       
   857 	}
       
   858 
       
   859 void CImTextServerSession::SocketConnect()
       
   860 	{
       
   861 
       
   862 	iState=EImConnect;
       
   863 
       
   864 #if defined(__IMSK_SCRIPTING)
       
   865 	if (iScript)
       
   866 		{
       
   867 		SetActive();
       
   868 		RequestComplete(iStatus,KErrNone);
       
   869 		}
       
   870 	else
       
   871 #endif
       
   872 		{
       
   873 		__ASSERT_DEBUG(iScript==NULL,User::Invariant());
       
   874 
       
   875 		iHostResolver.Close();
       
   876 		TInt err;
       
   877 		__ASSERT_ALWAYS(iPortNum>=0, gPanic(EImskInvalidPortNumber));
       
   878 		
       
   879 		TSockAddr& addr=iHostent().iAddr;
       
   880 		addr.SetPort(iPortNum);
       
   881 		LogText(addr);
       
   882 		err=iSocket.Open(iServ,KAfInet,KSockStream, KProtocolInetTcp, iConnect->GetConnection());
       
   883 		
       
   884 		if(err==KErrNone)
       
   885 			{
       
   886 			iSocket.Connect(addr,iStatus);
       
   887 			SetActive();
       
   888 			return;
       
   889 			}
       
   890 		__LOG_ERR(KLogServerConnectionError,err);
       
   891 		Complete(err);
       
   892 		}
       
   893 	}
       
   894 
       
   895 
       
   896 // called from DoRunL after a connection has been opened
       
   897 void CImTextServerSession::DoQueueConnect()
       
   898 	{
       
   899 #if defined(__IMSK_LOGGING)
       
   900 	if (!iLog)
       
   901 		CreateLogFile(iPortNum);  // Attempt to create the log file
       
   902 #endif
       
   903 	TInt err;
       
   904 #if defined(__IMSK_SCRIPTING)
       
   905 	if (iScript)
       
   906 		{
       
   907 		iState=EImResolve;
       
   908 		RequestComplete(iStatus,KErrNone);
       
   909 		SetActive();
       
   910 		return;
       
   911 		}
       
   912 	else
       
   913 #endif
       
   914 		{
       
   915 		iState=EImResolve;
       
   916 		err = iHostResolver.Open(iServ, KAfInet, KProtocolInetTcp, iConnect->GetConnection());
       
   917 		if(err==KErrNone)
       
   918 			{
       
   919 			iHostResolver.GetByName(iAddressDesc, iHostent,iStatus);
       
   920 			SetActive();
       
   921 			__LOG_COMMENT_OUT(KLogResolveQueued);
       
   922 			return;
       
   923 			}
       
   924 		}
       
   925 	Complete(err);
       
   926 	}
       
   927 
       
   928 
       
   929 // called from DoRunL after a socket has been connected to
       
   930 void CImTextServerSession::DoConnectedToSocketL()
       
   931 	{
       
   932 #if defined(__IMSK_SCRIPTING)
       
   933 	// Retrieve the local IP address of this client
       
   934 	if(!iScript)
       
   935 #endif
       
   936 		{
       
   937 		TInetAddr address;
       
   938 		iSocket.LocalName(address);
       
   939 		address.Output(iLocalName);
       
   940 		}
       
   941 
       
   942 	if(iWrappedSocket)
       
   943 		{
       
   944 		CreateSecureSocketL();
       
   945 		}
       
   946 	else
       
   947 		{
       
   948 		iState=EImSendReceive;
       
   949 		iSendReceive=EImInactive;
       
   950 		TPtr8 bufPtr=iBuffer->Des();
       
   951 		bufPtr.Zero();
       
   952 		}
       
   953 	}
       
   954 
       
   955 
       
   956 //
       
   957 // Close all socket and resovler access. Restore to just created state.
       
   958 //
       
   959 void CImTextServerSession::Close()
       
   960 	{
       
   961 	iHostResolver.Close();
       
   962 	if (iSecureSocket)
       
   963 		{
       
   964 		//Closing the Secure Connection & the Socket.
       
   965 		//Since the Socket is closed, Shutdown shouldn't be called again, so making iSocketIdelTimeSet=EFalse
       
   966 		iSecureSocket->Close();
       
   967 		delete iSecureSocket;
       
   968 		iSecureSocket=NULL;
       
   969 		iSocketIdleTimeSet = EFalse;
       
   970 		}
       
   971  	else if(iSocketIdleTimeSet) 
       
   972 		{ 
       
   973 		//For non Secure Socket, if idle time is set then shutdown the socket
       
   974 		// Shutdown should be called only once, so make iSocketIdelTimeSet=EFalse 
       
   975 		iSocketIdleTimeSet=EFalse; 
       
   976 		iSocket.Shutdown(RSocket::EImmediate, iStatus); 
       
   977 		iState = EImSendReceiveTimedOut; 
       
   978 		SetActive();
       
   979 		return; 
       
   980 		} 
       
   981 	else
       
   982 		{
       
   983 		//For non Secure Socket, if idle time is not set then close the socket
       
   984 		iSocket.Close();	
       
   985 		}
       
   986 
       
   987 	iState=EImClosed;
       
   988 	__LOG_COMMENT_OUT(KLogSocketClosed);
       
   989 #if defined(__IMSK_SCRIPTING)
       
   990 	delete iScript;
       
   991 	iScript=NULL;
       
   992 #endif
       
   993 #if defined(__IMSK_LOGGING)
       
   994 	delete iLog;
       
   995 	iLog=NULL;
       
   996 #endif
       
   997 
       
   998 #if defined(__IMSK_SIMULATION)
       
   999 	if (iGprsConfigExists)
       
  1000 		{
       
  1001 		// reset to begin of config file
       
  1002 		iCfgFilePos = 0;
       
  1003 		// read the first delay period
       
  1004 		ReadNextPeriod();
       
  1005 
       
  1006 		if (SuspendPeriodSet())
       
  1007 			iLastSuspend.UniversalTime();
       
  1008 		}
       
  1009 #endif	// __IMSK_SIMULATION
       
  1010 	}
       
  1011 	
       
  1012 
       
  1013 //*********************************************************************************************/
       
  1014 //*                                                                                           */
       
  1015 //*                           CActive private IMSK functions                                  */
       
  1016 //*                                                                                           */
       
  1017 //*********************************************************************************************/
       
  1018 
       
  1019 
       
  1020 
       
  1021 //
       
  1022 // Current request has completed - deal with it
       
  1023 //
       
  1024 void CImTextServerSession::DoRunL()
       
  1025 	{
       
  1026 	delete iSentData;
       
  1027 	iSentData = 0;
       
  1028 
       
  1029 	switch(iState)
       
  1030 		{
       
  1031 		case EImTLSHandShakeStarted:
       
  1032 			__LOG_COMMENT_OUT(KLogTLSHandShakeCompleted);
       
  1033 			iState=EImSendReceive;
       
  1034 			iSendReceive=EImInactive;
       
  1035 			iSecurityState=EImSecurityStateOn;
       
  1036 			break;
       
  1037 		case EImDialUsingOverride:
       
  1038 			DoQueueConnect();
       
  1039 			break;
       
  1040 		case EImResolve:   // we have a internet connection
       
  1041 			__LOG_COMMENT_OUT(KLogResolveCompleted);
       
  1042 			__LOG_ERR(KLogConnectQueued,iPortNum);
       
  1043 			
       
  1044 			SocketConnect();
       
  1045 			break;
       
  1046 
       
  1047 		case EImConnect:  // we have a socket connected
       
  1048 			__LOG_COMMENT_OUT(KLogConnectCompleted);
       
  1049 			DoConnectedToSocketL();
       
  1050 			break;
       
  1051 
       
  1052 		case EImSendReceive:
       
  1053 			{
       
  1054 			// Cancel the socket idle timer as the socket request has completed.
       
  1055 			iSocketIdleTimer->Cancel();
       
  1056 
       
  1057 			if(iSendReceive==EImReceiving)
       
  1058 				{
       
  1059 				__LOG_COMMENT_OUT(KLogSendReceiveCompleted);
       
  1060 				__LOG_IN(iReceive);
       
  1061 
       
  1062 	
       
  1063 				TPtr8 bufPtr=iBuffer->Des();
       
  1064 				TInt space=bufPtr.MaxLength()-bufPtr.Length();
       
  1065 				if(iReceive.Length()>space)
       
  1066 					{
       
  1067 					bufPtr.Append(iReceive.Left(space));
       
  1068 					iReceive.Delete(0,space);
       
  1069 					iSendReceive=EImInactive;
       
  1070 					iCurrentLineType=EReceiveBufferFull;
       
  1071 					}
       
  1072 				else
       
  1073 					{
       
  1074 					bufPtr.Append(iReceive);
       
  1075 					iReceive.Zero();
       
  1076 					// search for a CRLF in iBuffer
       
  1077 					if(iBuffer->Find(KImCarriageReturn)==KErrNotFound)
       
  1078 						{
       
  1079 						// Start up the socket idle timer.
       
  1080 						if(iReceiveShortIdleTime.Int() > 0 )
       
  1081 							{
       
  1082 							iSocketIdleTimer->After(iReceiveShortIdleTime);
       
  1083 							iReceiveShortIdleTime = 0;
       
  1084 							} 
       
  1085 						else if( iReceiveIdleTime.Int() > 0 )
       
  1086 							{
       
  1087 							iSocketIdleTimer->After(iReceiveIdleTime);
       
  1088 							}
       
  1089 
       
  1090 						if (iSecurityState==EImSecurityStateOn)
       
  1091 							iSecureSocket->RecvOneOrMore(iReceive,iStatus,iLen);
       
  1092 						else
       
  1093 							iSocket.RecvOneOrMore(iReceive,NULL,iStatus,iLen);
       
  1094 						SetActive();
       
  1095 						}
       
  1096 					else
       
  1097 						{
       
  1098 						iSendReceive=EImInactive;
       
  1099 						iCurrentLineType=ECRLFTerminated;
       
  1100 						if (iReadTLSResponse)
       
  1101 							{
       
  1102 							ParseSSLTLSResponseL();
       
  1103 							return;
       
  1104 							}
       
  1105 						}
       
  1106 					}	
       
  1107 			}
       
  1108 			else if (iSendReceive==EImReceivingBinaryData)
       
  1109 				{
       
  1110 				// just pass raw binary data straight back to caller without any processing
       
  1111 				__LOG_COMMENT_OUT(KLogSendReceiveBinaryCompleted);
       
  1112 				__LOG_IN(*iReceiveData);
       
  1113 				}
       
  1114 			else if(iSendReceive==EImSendingQueueReceive)
       
  1115 				{
       
  1116 				iSendReceive=EImReceiving;
       
  1117 				// Is there already a full text line in the buffer (ie is there a CRLF?)
       
  1118 				if(iBuffer->Find(KImCarriageReturn)==KErrNotFound)
       
  1119 					{
       
  1120 					RealReceive(iReceive);
       
  1121 					return;
       
  1122 					}
       
  1123 				}
       
  1124   			else if (iSendReceive==EImSending)
       
  1125   				{
       
  1126 				if (iReadTLSResponse)
       
  1127 					{
       
  1128 					iSendReceive=EImReceiving;
       
  1129 					RealReceive(iReceive);
       
  1130 					return;
       
  1131 					}
       
  1132 				Complete(KErrNone);
       
  1133 				}
       
  1134 #if defined(__IMSK_SIMULATION)
       
  1135 			else if(iSendReceive==EImSuspended)
       
  1136 				{
       
  1137 				__LOG_COMMENT_OUT(KLogGPRSSimUnSuspended);
       
  1138 
       
  1139 				iSendReceive=iSuspendedState;
       
  1140 				if(iSendReceive==EImSending || iSendReceive==EImSendingQueueReceive)
       
  1141 					{
       
  1142 					RealSend(*iSendData);
       
  1143 					delete iSendData;
       
  1144 					iSendData=NULL;
       
  1145 					}
       
  1146 				else
       
  1147 					RealReceive(*iReceiveData);
       
  1148 				}
       
  1149 #endif	// __IMSK_SIMULATION
       
  1150 			}
       
  1151 			break;
       
  1152 		case EImSendReceiveTimedOut: 
       
  1153 			{ 
       
  1154 			iSocket.Close();     
       
  1155 			iState=EImClosed; 
       
  1156 			Complete(KErrTimedOut); 
       
  1157 			break;               
       
  1158 			} 
       
  1159 
       
  1160 		default:
       
  1161 			gPanic(EImskUnknownState);
       
  1162 		}
       
  1163 
       
  1164 	}
       
  1165 
       
  1166 
       
  1167 //
       
  1168 // Cancel connect/receive if one is currently occurring
       
  1169 //
       
  1170 void CImTextServerSession::DoCancel()
       
  1171 	{
       
  1172 	// clear out receive buffer if we cancel
       
  1173 	TPtr8 bufPtr=iBuffer->Des();
       
  1174 	bufPtr.Zero();
       
  1175 
       
  1176 	switch(iState)
       
  1177 		{
       
  1178 	case EImResolve:
       
  1179 		iHostResolver.Cancel();
       
  1180 		break;
       
  1181 	case EImConnect:
       
  1182 		iSocket.CancelConnect();
       
  1183 		break;
       
  1184 	case EImSendReceive:
       
  1185 		{
       
  1186 #if defined(__IMSK_SCRIPTING)
       
  1187 		if (!iScript)
       
  1188 #endif
       
  1189 			{
       
  1190 			// Cancel the socket idle timer as the socket request is also being
       
  1191 			// cancelled.
       
  1192 			iSocketIdleTimer->Cancel();
       
  1193 
       
  1194 			if(iSendReceive==EImSending || iSendReceive==EImSendingQueueReceive)
       
  1195 				{
       
  1196 				__LOG_COMMENT_OUT(KLogWriteCancelled);
       
  1197 				if (iSecurityState==EImSecurityStateOn)
       
  1198 					iSecureSocket->CancelSend();
       
  1199 				else
       
  1200 					iSocket.CancelSend();
       
  1201 				}
       
  1202 			else if(iSendReceive==EImReceiving || iSendReceive==EImReceivingBinaryData)
       
  1203 				{
       
  1204 				__LOG_COMMENT_OUT(KLogReadCancelled);
       
  1205 				if (iSecurityState==EImSecurityStateOn)
       
  1206 					iSecureSocket->CancelRecv();
       
  1207 				else
       
  1208 					iSocket.CancelRead();
       
  1209 				}
       
  1210 			}
       
  1211 #if defined(__IMSK_SCRIPTING)
       
  1212 		else
       
  1213 			iScript->Cancel();
       
  1214 #endif//__IMSK_SCRIPTING
       
  1215 #if defined(__IMSK_SIMULATION)
       
  1216 		if(iSendReceive==EImSuspended) iSuspendTimer.Cancel();
       
  1217 #endif//__IMSK_SIMULATION
       
  1218 		}
       
  1219 		break;
       
  1220 	case EImTLSHandShakeStarted:
       
  1221         if (iSecureSocket)
       
  1222         	{
       
  1223             iSecureSocket->CancelHandshake();
       
  1224         	}
       
  1225         break;
       
  1226 	case EImClosed:
       
  1227 	default:
       
  1228 		break;
       
  1229 	case EImDialUsingOverride:
       
  1230 		if (iConnect)
       
  1231 			iConnect->Cancel();
       
  1232 		break;
       
  1233 	case EImSendReceiveTimedOut: 
       
  1234 		iSocket.CancelAll(); 
       
  1235 		iSocket.Close();     
       
  1236 		iState=EImClosed; 
       
  1237 		break; 
       
  1238 		}
       
  1239     
       
  1240 	delete iSentData;
       
  1241 	iSentData = 0;
       
  1242 
       
  1243 	if(!iSocketIdleTimeSet)
       
  1244 		{
       
  1245 		CMsgActive::DoCancel();
       
  1246 		}
       
  1247 	}
       
  1248 
       
  1249 //
       
  1250 // If it all goes wrong
       
  1251 //
       
  1252 void CImTextServerSession::DoComplete(TInt& aStatusValue)
       
  1253 	{
       
  1254 	TInt status=aStatusValue;
       
  1255 	//
       
  1256 	// test for KErrEof returns from socket.  This might indicate that there has been 
       
  1257 	// a TCPIP half close - with the remote end sending a FIN
       
  1258 	// If this occurs as response to QUIT treat as a remote disconnection
       
  1259 	//
       
  1260 	if (iState==EImDialUsingOverride)
       
  1261 		{
       
  1262 		__LOG_ERR(KLogOverridefailed,aStatusValue);
       
  1263 		Close();
       
  1264 		return;
       
  1265 		}
       
  1266 	if(status==KErrEof)
       
  1267 		{
       
  1268 		aStatusValue=KErrDisconnected;
       
  1269 		Close();
       
  1270 		return;
       
  1271 		}
       
  1272 	// don't close the socket if the ide timer timed out, or if asynch operation was cancelled...
       
  1273 	if((aStatusValue) && (aStatusValue!=KErrCancel) && (aStatusValue!=KErrTimedOut))
       
  1274 		{
       
  1275 		// there was an error so no need to keep on running these timers...
       
  1276 		if(iState==EImResolve)
       
  1277 			{
       
  1278 			if (aStatusValue==KErrNotFound)
       
  1279 				aStatusValue=KImskErrorDNSNotFound;
       
  1280 		
       
  1281 			if (aStatusValue==KErrLocked)
       
  1282 				aStatusValue=KImskErrorControlPanelLocked;
       
  1283 			}
       
  1284 
       
  1285 		if(iState!=EImClosed)
       
  1286 			Close();
       
  1287 		}
       
  1288 
       
  1289 	delete iSentData;
       
  1290 	iSentData = 0;
       
  1291 	}
       
  1292 
       
  1293 
       
  1294 //*********************************************************************************************/
       
  1295 //*                                                                                           */
       
  1296 //*                           Private IMSK send/receive functions                             */
       
  1297 //*                                                                                           */
       
  1298 //*********************************************************************************************/
       
  1299 
       
  1300 // log & Send to a socket
       
  1301 void CImTextServerSession::RealSend(const TDesC8& aDesc)
       
  1302 	{
       
  1303 	// Cancel the socket idle timer as we are about to send some data	
       
  1304 	iSocketIdleTimer->Cancel();
       
  1305 
       
  1306 #if defined(__IMSK_SIMULATION)
       
  1307 	if(IsSuspended())
       
  1308 		{
       
  1309 		iSuspendedState=iSendReceive;
       
  1310 		iSendReceive=EImSuspended;
       
  1311 		iSendData=aDesc.Alloc();
       
  1312 		if(iSendData==NULL)
       
  1313 		   {
       
  1314 		   TInt err=KErrNoMemory;
       
  1315 		   DoComplete(err);
       
  1316 		   }
       
  1317 		SetAfterTimer();
       
  1318 		}
       
  1319 	else
       
  1320 #endif
       
  1321 		{
       
  1322 		// Do the logging of the text if required
       
  1323 		if (iPerformLogging)
       
  1324 			__LOG_OUT(aDesc);
       
  1325 
       
  1326 #if defined(__IMSK_SCRIPTING)
       
  1327 		if(iScript)
       
  1328 			RequestComplete(iStatus,KErrNone);
       
  1329 		else
       
  1330 #endif
       
  1331 			{
       
  1332 			if(iSecurityState==EImSecurityStateFailed) 
       
  1333 				RequestComplete(iStatus,KImskSecuritySettingsFailed);
       
  1334 			else
       
  1335 				{
       
  1336 				iSentData = aDesc.Alloc();
       
  1337 				
       
  1338 				if (iSentData==NULL)
       
  1339 					RequestComplete(iStatus, KErrNoMemory);
       
  1340 				else
       
  1341 					{
       
  1342 					// Start up the socket idle timer.
       
  1343 					if( iSendShortIdleTime.Int() > 0 )
       
  1344 						{
       
  1345 						iSocketIdleTimer->After(iSendShortIdleTime);						
       
  1346 						iSendShortIdleTime = 0;
       
  1347 						}
       
  1348 					else if( iSendIdleTime.Int() > 0 )
       
  1349 						{
       
  1350 						iSocketIdleTimer->After(iSendIdleTime);
       
  1351 						}
       
  1352 
       
  1353 					if (iSecurityState==EImSecurityStateOn)
       
  1354 						iSecureSocket->Send(*iSentData,iStatus);
       
  1355 					else
       
  1356 						iSocket.Write(*iSentData,iStatus);
       
  1357 					}
       
  1358 				}
       
  1359 			}
       
  1360 		}
       
  1361 	SetActive();
       
  1362 	}
       
  1363 
       
  1364 //
       
  1365 // Queue a recieve from a socket
       
  1366 //
       
  1367 void CImTextServerSession::RealReceive(TDes8& aDesc)
       
  1368 	{
       
  1369 	// Cancel the socket idle timer as we are about to receive some data
       
  1370 	iSocketIdleTimer->Cancel();
       
  1371 
       
  1372 	iReceiveData=&aDesc;
       
  1373 #if defined(__IMSK_SIMULATION)
       
  1374 	if(IsSuspended())
       
  1375 		{
       
  1376 		iSuspendedState=iSendReceive;
       
  1377 		iSendReceive=EImSuspended;	
       
  1378 		SetAfterTimer();
       
  1379 		}
       
  1380 	else
       
  1381 #endif
       
  1382 		{
       
  1383 #if defined(__IMSK_SCRIPTING)
       
  1384 
       
  1385 		if(iScript)
       
  1386 			{
       
  1387 			TPtr8 bufPtr=iBuffer->Des();
       
  1388 			iScript->RetrieveResponse(bufPtr, iStatus);
       
  1389 			TInt bufLength = aDesc.MaxLength();
       
  1390 			aDesc=iBuffer->Left(bufLength);
       
  1391 			bufPtr.Delete(0,bufLength);
       
  1392 			}
       
  1393 		else
       
  1394 #endif	
       
  1395 			{
       
  1396 			if(iSecurityState==EImSecurityStateFailed) 
       
  1397 				RequestComplete(iStatus,KImskSecuritySettingsFailed);
       
  1398 			else 
       
  1399 				{
       
  1400 				// Start up the socket idle timer.
       
  1401 				if(iReceiveShortIdleTime.Int() > 0 )
       
  1402 					{
       
  1403 					iSocketIdleTimer->After(iReceiveShortIdleTime);
       
  1404 					iReceiveShortIdleTime = 0;
       
  1405 					} 
       
  1406 				else if( iReceiveIdleTime.Int() > 0 )
       
  1407 					{
       
  1408 					iSocketIdleTimer->After(iReceiveIdleTime);
       
  1409 					}
       
  1410 
       
  1411 				if (iSecurityState==EImSecurityStateOn)
       
  1412 					iSecureSocket->RecvOneOrMore(aDesc,iStatus,iLen);
       
  1413 				else
       
  1414 					iSocket.RecvOneOrMore(aDesc,NULL,iStatus,iLen);
       
  1415 				}
       
  1416 			}
       
  1417 		}
       
  1418 	SetActive();
       
  1419 	}
       
  1420 
       
  1421 
       
  1422 
       
  1423 //*********************************************************************************************/
       
  1424 //*                                                                                           */
       
  1425 //*                           Private logging/scripting/suspend functions                     */
       
  1426 //*                                                                                           */
       
  1427 //*********************************************************************************************/
       
  1428 
       
  1429 
       
  1430 
       
  1431 
       
  1432 #if defined(__IMSK_LOGGING)
       
  1433 //
       
  1434 // Attempt to create a log file to record messages sent to/from socket
       
  1435 //
       
  1436 void CImTextServerSession::CreateLogFile(TInt aPortNum)
       
  1437 	{
       
  1438 	//attempt to create a log file
       
  1439 	TRAP_IGNORE(iLog = CImLog::NewL(aPortNum));
       
  1440 	}
       
  1441 #endif
       
  1442 
       
  1443 #if defined(__IMSK_SCRIPTING)
       
  1444 //
       
  1445 // See if a script file exists for the type of session we're perforiming
       
  1446 // if it doesn't really try to connect
       
  1447 // if it does exits then load the iap and bearer we should pretend to be connected to
       
  1448 void CImTextServerSession::OpenScriptFile(TInt aPortNum)
       
  1449 	{
       
  1450 	TRAP_IGNORE(iScript=CImTextServerScript::NewL(aPortNum));
       
  1451 	}
       
  1452 
       
  1453 #endif
       
  1454 
       
  1455 #if defined(__IMSK_SIMULATION)
       
  1456 
       
  1457 // *************************************************************************
       
  1458 // GPRS Suspend code
       
  1459 // *************************************************************************
       
  1460 //
       
  1461 // Read next suspension time from configuration file gprs.cfg
       
  1462 // The tokens start:, duration: and repeat: are located and their
       
  1463 // values used to setup the next suspension period.
       
  1464 // NB, The tokens are assumed (must be) to be paired as follows:
       
  1465 //
       
  1466 //	start: nn
       
  1467 //	duration: nn
       
  1468 //	
       
  1469 //	or
       
  1470 //
       
  1471 //	repeat:
       
  1472 //	start: nn
       
  1473 //	duration: nn
       
  1474 //	
       
  1475 //	or
       
  1476 //
       
  1477 //	duration: nn	(where start is assumed to be 0.
       
  1478 
       
  1479 void CImTextServerSession::ReadNextPeriod()
       
  1480 	{
       
  1481 	ResetSuspendPeriod();
       
  1482 
       
  1483     //  Read into the buffer
       
  1484     TBuf8<80> buffer;
       
  1485 
       
  1486     //  Get the current file position
       
  1487 	TInt pos;
       
  1488 	TInt err;
       
  1489 
       
  1490     iGprsFile.Seek(ESeekStart, iCfgFilePos);
       
  1491 
       
  1492 	// look for the tokens
       
  1493 
       
  1494 	while (! SuspendPeriodSet())
       
  1495 		{
       
  1496 		err = iGprsFile.Read(buffer);
       
  1497     
       
  1498 		if (err != KErrNone)
       
  1499 			{
       
  1500 			ResetSuspendPeriod();
       
  1501 			return;
       
  1502 			}
       
  1503 
       
  1504 		// quit on eof
       
  1505 		if (buffer.Length() == 0)
       
  1506 			break;
       
  1507 
       
  1508 		//  Copy to the lfcr and then set the file pointer
       
  1509 		//  to the point after that...
       
  1510 		pos = buffer.Find(KImCarriageReturn);
       
  1511 		if (pos != KErrNotFound)
       
  1512 			{
       
  1513 			iCfgFilePos += pos + 2;
       
  1514 			buffer.Delete(pos,buffer.Length());
       
  1515 			}
       
  1516 		else
       
  1517 			iCfgFilePos += buffer.Length();
       
  1518 
       
  1519 		iGprsFile.Seek(ESeekStart, iCfgFilePos);  
       
  1520 		              
       
  1521 		// check the line read in
       
  1522 		buffer.TrimLeft();
       
  1523 
       
  1524 		if (buffer.FindF(KRepeat) != KErrNotFound)
       
  1525 			{
       
  1526 			iRepeat = ETrue;
       
  1527 			}
       
  1528 		else if (buffer.FindF(KStart) != KErrNotFound)
       
  1529 			{
       
  1530 			iStart = GetTokenValue(KStart.iTypeLength, buffer);
       
  1531 			}
       
  1532 		else if (buffer.FindF(KDuration) != KErrNotFound)
       
  1533 			{
       
  1534 			iDuration = GetTokenValue(KDuration.iTypeLength, buffer);
       
  1535 			}
       
  1536 		}
       
  1537 	}
       
  1538 
       
  1539 
       
  1540 
       
  1541 TInt CImTextServerSession::ReadConfigNum(const TDesC& aName)
       
  1542 	{
       
  1543 	RFile	configFile;
       
  1544 	TInt err = configFile.Open(iFs,aName,EFileShareAny);
       
  1545 	TInt toreturn=0;
       
  1546 	if(err==KErrNone)
       
  1547 		{
       
  1548 	    TBuf8<20> buffer;    // we ignore more than 20 chars in the file
       
  1549 		configFile.Read(buffer,20);
       
  1550 		configFile.Close();
       
  1551 		
       
  1552 		TLex8 lexical(buffer);
       
  1553 		lexical.Val(toreturn);
       
  1554 		}
       
  1555 	return toreturn;
       
  1556 	}
       
  1557 
       
  1558 
       
  1559 
       
  1560 TUint32 CImTextServerSession::GetTokenValue(TInt aTokenLen, const TPtrC8& aBuffer)
       
  1561 	{
       
  1562 	TUint32 num;
       
  1563 	TInt i = aTokenLen;
       
  1564 
       
  1565 	TBuf<70> value;
       
  1566 	value.Copy(aBuffer);
       
  1567 
       
  1568 	// remove leading token, space and tabs
       
  1569 	while(i < value.Length())
       
  1570 		{
       
  1571 		if (value[i] != ' ' && value[i] != '\t')
       
  1572 			break;
       
  1573 		i++;
       
  1574 		}
       
  1575 	value.Delete(0,i);
       
  1576 
       
  1577 	TLex lex(value);
       
  1578 
       
  1579 	if (lex.Val(num,EDecimal) != KErrNone)
       
  1580 		num = 0;
       
  1581 
       
  1582 	return num;
       
  1583 	}
       
  1584 
       
  1585 // determine if we are in a suspension period based on the last 
       
  1586 // time one took place. If we have passed over the last period
       
  1587 // get the next period from the config file.
       
  1588 TBool CImTextServerSession::IsSuspended()
       
  1589 	{
       
  1590 	if (iGprsConfigExists && SuspendPeriodSet())
       
  1591 		{
       
  1592 		TTime now;
       
  1593 		now.UniversalTime();		
       
  1594 
       
  1595 		// suspend period has not yet started
       
  1596 		if (now < iLastSuspend + iStart)
       
  1597 			return EFalse;
       
  1598 		
       
  1599 		// we are in the suspend period
       
  1600 		if (now < iLastSuspend + iStart + iDuration)
       
  1601 			return ETrue;
       
  1602 
       
  1603 		// we have moved out of the period so get the next one
       
  1604 		// if not required to repeat the last
       
  1605 		if (! iRepeat)
       
  1606 			ReadNextPeriod();
       
  1607 	
       
  1608 		// reset baseline time/send buffer len if one set
       
  1609 		if (SuspendPeriodSet())
       
  1610 			{
       
  1611 			iLastSuspend.UniversalTime();
       
  1612 
       
  1613 			// check for immediate start
       
  1614 			if (iStart.Int() == 0)
       
  1615 				return ETrue;
       
  1616 			}
       
  1617 		}
       
  1618 
       
  1619 	return EFalse;
       
  1620 	}
       
  1621 
       
  1622 // determine if a suspend period has been defined.
       
  1623 // start can be immediate.
       
  1624 TBool CImTextServerSession::SuspendPeriodSet()
       
  1625 	{
       
  1626 	return iStart.Int() >= 0 && iDuration.Int() != 0 ? ETrue : EFalse;
       
  1627 	}
       
  1628 
       
  1629 void CImTextServerSession::ResetSuspendPeriod()
       
  1630 	{
       
  1631 	iStart = 0;
       
  1632 	iDuration = 0;
       
  1633 	iRepeat = EFalse;
       
  1634 	}
       
  1635 
       
  1636 
       
  1637 // calls DoRunL after the delay period has expired
       
  1638 // NB, delay is expected to be < KMinTInt32 secs
       
  1639 // used to queue async calls
       
  1640 void CImTextServerSession::SetAfterTimer()
       
  1641 	{
       
  1642 
       
  1643 		{
       
  1644 		TBuf8<1024> buf;
       
  1645 		buf.Format(KLogGPRSSimSuspended,iDuration.Int());
       
  1646 		__LOG_COMMENT_OUT(buf);
       
  1647 		}
       
  1648 	TTime now;		
       
  1649 
       
  1650 	now.UniversalTime();
       
  1651 	
       
  1652 	TTimeIntervalMicroSeconds usecs(TInt64(0));
       
  1653 
       
  1654 	TTime delayEnd = iLastSuspend + iStart + iDuration;
       
  1655 	if (now <= delayEnd)
       
  1656 		usecs=delayEnd.MicroSecondsFrom(now);
       
  1657 	TInt64 delay=usecs.Int64()+500000;
       
  1658 	iSuspendTimer.After(iStatus,I64INT(delay));
       
  1659 	}
       
  1660 
       
  1661 
       
  1662 #endif	// __IMSK_SIMULATION
       
  1663 
       
  1664 
       
  1665 
       
  1666 // Depreciated functions - do not use.
       
  1667 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus& ,const TDesC& , TInt , TBool )
       
  1668 	{
       
  1669 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1670 	}
       
  1671 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus&,const TDesC&, TInt, TCallBack,const TUint32,TInt, TBool)
       
  1672 	{
       
  1673 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1674 	}
       
  1675 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus &,const TDesC& , TInt ,const TUint32 , TInt , TBool )
       
  1676 	{
       
  1677 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1678 	}
       
  1679 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus& ,const TDesC& , TInt , TCallBack , TBool )
       
  1680 	{
       
  1681 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1682 	}
       
  1683 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus& ,const TDesC& , TInt , TCallBack , const CImIAPPreferences& ,TInt , TBool )
       
  1684 	{
       
  1685 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1686 	}
       
  1687 EXPORT_C void CImTextServerSession::QueueConnect(TRequestStatus &,const TDesC& , TInt , const CImIAPPreferences& ,TInt , TBool )
       
  1688 	{
       
  1689 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1690 	}
       
  1691 EXPORT_C TInt CImTextServerSession::Send(const TDesC8& )
       
  1692 	{
       
  1693     __ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1694 	return 0;
       
  1695 	}
       
  1696 EXPORT_C TInt CImTextServerSession::Send(TRefByValue<const TDesC8>,...)
       
  1697 	{
       
  1698 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1699 	return 0;
       
  1700 	}
       
  1701 EXPORT_C TInt CImTextServerSession::SendReceive(const TDesC8& )
       
  1702 	{
       
  1703 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1704 	return 0;
       
  1705 	}
       
  1706 EXPORT_C TInt CImTextServerSession::Receive(TDes8&)
       
  1707 	{
       
  1708 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1709 	return 0;
       
  1710 	}
       
  1711 EXPORT_C void CImTextServerSession::Receive(TRequestStatus &, TDes8&)
       
  1712 	{
       
  1713 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1714 	}
       
  1715 
       
  1716 EXPORT_C CImTextServerSession *CImTextServerSession::NewLC (TImOperationMode, RSocketServ &)
       
  1717 	{
       
  1718 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1719 	return 0;
       
  1720 	}
       
  1721 EXPORT_C CImTextServerSession *CImTextServerSession::NewL(RSocketServ &)
       
  1722 	{
       
  1723 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1724 	return 0;
       
  1725 	}
       
  1726 
       
  1727 EXPORT_C TInt CImTextServerSession::SetSecurity(TBool, TBool)
       
  1728 	{
       
  1729 	__ASSERT_ALWAYS(EFalse, gPanic(EImskNotSupported));
       
  1730 	return 0;
       
  1731 	}
       
  1732 
       
  1733 /**
       
  1734 	Intended Usage	:	Gets the stage of the connection process obtained from RConnection
       
  1735 	@since			7.0s
       
  1736 	@return			The current connection stage from RConnection or a system-wide error code.
       
  1737 
       
  1738 	*/
       
  1739 EXPORT_C TInt CImTextServerSession::GetConnectionStage()
       
  1740 	{
       
  1741 #if defined(__IMSK_SCRIPTING)
       
  1742 	if (iScript)
       
  1743 		{
       
  1744 		return KErrNotFound;
       
  1745 		}
       
  1746 	else
       
  1747 #endif //(__IMSK_SCRIPTING)
       
  1748 		{	
       
  1749 		TNifProgress progress;
       
  1750 		TInt err = iConnect->Progress(progress);
       
  1751 		return (err == KErrNone) ? (progress.iStage) : (err);
       
  1752 		}
       
  1753 	}
       
  1754 
       
  1755 // Setting of PrimaryTextServerSession, Going to be set on the secondary session.
       
  1756 EXPORT_C void CImTextServerSession::SetPrimaryTextServerSession(CImTextServerSession* aPrimaryTextServerSession)
       
  1757 	{
       
  1758 	iPrimaryTextServerSession=aPrimaryTextServerSession;
       
  1759 	}
       
  1760 
       
  1761 // Return of current Connection
       
  1762 CImConnect* CImTextServerSession::GetCImConnect()
       
  1763 	{
       
  1764 	return iConnect;
       
  1765 	}