mtpfws/mtpfw/src/cmtpconnection.cpp
changeset 0 d0791faffa3f
child 1 f8e15b44d440
equal deleted inserted replaced
-1:000000000000 0:d0791faffa3f
       
     1 // Copyright (c) 2006-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 /**
       
    17  @file
       
    18  @internalComponent
       
    19 */
       
    20 
       
    21 #include <mtp/cmtpdataproviderplugin.h>
       
    22 #include <mtp/mtpprotocolconstants.h>
       
    23 #include <mtp/tmtptypeevent.h>
       
    24 #include <mtp/tmtptyperequest.h>
       
    25 #include <mtp/tmtptypeuint32.h>
       
    26 
       
    27 #include "cmtpconnection.h"
       
    28 #include "cmtpconnectionmgr.h"
       
    29 #include "cmtpdataprovider.h"
       
    30 #include "cmtpparserrouter.h"
       
    31 #include "cmtpsession.h"
       
    32 #include "mmtptransportconnection.h"
       
    33 
       
    34 #ifdef MTP_CAPTURE_TEST_DATA
       
    35 #include "cmtprequestlogger.h"
       
    36 #endif
       
    37 
       
    38 #define UNUSED_VAR(a) (a) = (a)
       
    39 
       
    40 __FLOG_STMT(_LIT8(KComponent,"MTPConnection");)
       
    41 
       
    42 /**
       
    43 CMTPConnection panics
       
    44 */
       
    45 _LIT(KMTPPanicCategory, "CMTPConnection");
       
    46 enum TMTPPanicReasons
       
    47     {
       
    48     EMTPPanicBusy = 0,
       
    49     EMTPPanicInvalidSession = 1,
       
    50     EMTPPanicInvalidState = 2,
       
    51     EMTPPanicPublishEvent = 3,
       
    52     };
       
    53     
       
    54 LOCAL_C void Panic(TInt aReason)
       
    55     {
       
    56     User::Panic(KMTPPanicCategory, aReason);
       
    57     }
       
    58 
       
    59 /**
       
    60 CMTPConnection factory method. A pointer to the new CMTPConnection instance is
       
    61 placed on the cleanup stack.
       
    62 @param aConnectionId The unique identifier assigned to this connection by the 
       
    63 MTP framework. 
       
    64 @param aTransportConnection The MTP transport layer connection interface to 
       
    65 which the CMTPConnection will bind.
       
    66 @return Pointer to the new CMTPConnection instance. Ownership IS transfered.
       
    67 @leave One of the system wide error codes if a processing failure occurs.
       
    68 */
       
    69 CMTPConnection* CMTPConnection::NewLC(TUint aConnectionId, MMTPTransportConnection& aTransportConnection)
       
    70     {
       
    71     CMTPConnection* self = new(ELeave) CMTPConnection(aConnectionId, aTransportConnection);
       
    72     CleanupStack::PushL(self);
       
    73     self->ConstructL();
       
    74     return self;
       
    75     }
       
    76 
       
    77 /**
       
    78 Destructor.
       
    79 */
       
    80 CMTPConnection::~CMTPConnection()
       
    81     {
       
    82     __FLOG(_L8("~CMTPConnection - Entry"));
       
    83     CloseAllSessions();
       
    84     
       
    85     // Remove any events not associated 
       
    86     // with a session
       
    87     TSglQueIter<CMTPEventLink> iter(iEventQ);
       
    88     iter.SetToFirst();
       
    89     CMTPEventLink* link = NULL;
       
    90     
       
    91     while ((link = iter++) != NULL)
       
    92     	{
       
    93     	delete link;
       
    94     	}
       
    95     
       
    96     if (iTransportConnection != NULL)
       
    97 	    {
       
    98 	    iTransportConnection->Unbind(*this);
       
    99 	    }
       
   100     iSessions.ResetAndDestroy();
       
   101     //close the property
       
   102     iProperty.Close();
       
   103     // delete the ‘name?property
       
   104     RProcess process;
       
   105     RProperty::Delete(process.SecureId(), EMTPConnStateKey);
       
   106     __FLOG(_L8("~CMTPConnection - Exit"));
       
   107 	__FLOG_CLOSE;
       
   108     }
       
   109 
       
   110 /**
       
   111 Unbinds the Transport Connection
       
   112 */    
       
   113 void CMTPConnection::Unbind(MMTPTransportConnection& /*aConnection*/)
       
   114 	{
       
   115 	iTransportConnection = NULL;
       
   116 	}
       
   117 
       
   118 /**
       
   119 Initiates MTP transaction data phase processing for initiator-to-responder
       
   120 data flows. This method should only be invoked when the MTP transaction phase 
       
   121 state is ERequestPhase. This is an asynchronous method.
       
   122 @param aData The MTP data object sink.
       
   123 @param aRequest The MTP request dataset of the active MTP transaction.
       
   124 @param aStatus The status used to return asynchronous completion 
       
   125 information regarding the request.
       
   126 @leave KErrNotFound If the MTP request dataset specifies an invalid SessionID.
       
   127 @panic CMTPConnection 0 If an asynchronous request is already pending on the 
       
   128 connection.
       
   129 @panic CMTPConnection 2 If the MTP transaction phase is invalid.
       
   130 */
       
   131 void CMTPConnection::ReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, TRequestStatus& aStatus)
       
   132     {   
       
   133     __FLOG(_L8("ReceiveDataL - Entry"));
       
   134     iDataReceiveResult = KErrNone;
       
   135     const TUint KValidPhases(ERequestPhase);
       
   136     CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID));
       
   137     
       
   138     if (ValidFrameworkRequest(&session, KValidPhases, &aStatus))
       
   139         {
       
   140         session.SetTransactionPhase(EDataIToRPhase);
       
   141         session.SetRequestPending(aStatus);
       
   142         if(EMTPTypeFile == aData.Type())
       
   143             {
       
   144             ValidateAndPublishConnState(session, State());
       
   145             }
       
   146         
       
   147         iTransportConnection->ReceiveDataL(aData, aRequest);      
       
   148         }
       
   149     __FLOG(_L8("ReceiveDataL - Exit"));
       
   150     }
       
   151 
       
   152 /**
       
   153 Initiates MTP transaction data phase processing for responder-to-initiator
       
   154 data flows. This method should only be invoked when the MTP transaction phase
       
   155 state is ERequestPhase. This is an asynchronous method.
       
   156 @param aData The MTP data object source.
       
   157 @param aRequest The MTP request dataset of the active MTP transaction.
       
   158 @param aStatus The status used to return asynchronous completion 
       
   159 information regarding the request.
       
   160 @leave KErrNotFound If the MTP request dataset specifies an invalid SessionID.
       
   161 @panic CMTPConnection 0 If an asynchronous request is already pending on the 
       
   162 connection.
       
   163 @panic CMTPConnection 2 If the MTP transaction phase is invalid.
       
   164 */
       
   165 void CMTPConnection::SendDataL(const MMTPType& aData, const TMTPTypeRequest& aRequest, TRequestStatus& aStatus)
       
   166     {
       
   167     __FLOG(_L8("SendDataL - Entry"));
       
   168 #ifdef MTP_CAPTURE_TEST_DATA
       
   169     iRequestLogger->WriteDataPhaseL(aData, EDataRToIPhase);
       
   170 #endif
       
   171 
       
   172     const TUint KValidPhases(ERequestPhase);
       
   173     CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID));
       
   174     
       
   175     if (ValidFrameworkRequest(&session, KValidPhases, &aStatus))
       
   176         {
       
   177         session.SetTransactionPhase(EDataRToIPhase);
       
   178         session.SetRequestPending(aStatus);
       
   179         if(EMTPTypeFile == aData.Type())
       
   180             {
       
   181             //In this case we should validate the state based on transaction phase then
       
   182             //publish the connection state info to the subscriber.
       
   183             ValidateAndPublishConnState(session, State());
       
   184             }
       
   185         iTransportConnection->SendDataL(aData, aRequest);
       
   186         }
       
   187     __FLOG(_L8("SendDataL - Exit"));
       
   188     }
       
   189 
       
   190 /**
       
   191 Sends an MTP event dataset.
       
   192 @param aEvent The MTP event dataset source.
       
   193 @leave KErrNotFound If the MTP event dataset specifies an invalid SessionID.
       
   194 */
       
   195 void CMTPConnection::SendEventL(const TMTPTypeEvent& aEvent)
       
   196     {
       
   197     __FLOG(_L8("SendEventL - Entry"));
       
   198     const TUint KValidPhases(EIdlePhase | ERequestPhase | EDataIToRPhase| EDataRToIPhase | EResponsePhase | ECompletingPhase);
       
   199     if (ValidFrameworkRequest(NULL, KValidPhases, NULL))
       
   200         {
       
   201         // Validate the SessionID
       
   202         TUint32 sessionId(aEvent.Uint32(TMTPTypeEvent::EEventSessionID));
       
   203         if (sessionId != KMTPSessionAll)
       
   204             {
       
   205             User::LeaveIfError(iSessions.FindInOrder(sessionId, SessionOrder));
       
   206             }
       
   207             
       
   208 
       
   209 		EnqueueEvent(new (ELeave) CMTPEventLink(aEvent));
       
   210 		if (iPendingEventCount == 1)
       
   211 			{
       
   212 			// Forward the event to the transport connection layer.
       
   213 			iTransportConnection->SendEventL(iEventQ.First()->iEvent);			
       
   214 			}
       
   215         }
       
   216     __FLOG(_L8("SendEventL - Exit"));
       
   217     }
       
   218 
       
   219 /**
       
   220 Initiates MTP transaction response phase processing. This method should only 
       
   221 be invoked when the MTP transaction phase state is either ERequestPhase, or 
       
   222 EResponsePhase. This is an asynchronous method.
       
   223 @param aResponse The MTP response dataset source.
       
   224 @param aRequest The MTP request dataset of the active MTP transaction.
       
   225 @param aStatus The status used to return asynchronous completion 
       
   226 information regarding the request.
       
   227 @leave KErrNotFound If the MTP response dataset specifies an invalid SessionID.
       
   228 @leave KErrArgument If the MTP response dataset does not match the specified 
       
   229 request dataset.
       
   230 @panic CMTPConnection 0 If an asynchronous request is already pending on the 
       
   231 connection.
       
   232 @panic CMTPConnection 2 If the MTP transaction phase is invalid.
       
   233 */
       
   234 void CMTPConnection::SendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, TRequestStatus& aStatus)
       
   235     {
       
   236     __FLOG(_L8("SendResponseL - Entry"));
       
   237 #ifdef MTP_CAPTURE_TEST_DATA
       
   238     // Running under debug capture mode save this request off to disk.
       
   239     iRequestLogger->LogResponseL(aResponse);
       
   240 #endif
       
   241     
       
   242     const TUint KValidPhases(ERequestPhase | EResponsePhase );
       
   243     CMTPSession& session(SessionL(aResponse, TMTPTypeResponse::EResponseSessionID));
       
   244     
       
   245     if (ValidFrameworkRequest(&session, KValidPhases, &aStatus))
       
   246         {
       
   247         if ((aResponse.Uint32(TMTPTypeResponse::EResponseSessionID) != aRequest.Uint32(TMTPTypeRequest::ERequestSessionID)) ||
       
   248             (aResponse.Uint32(TMTPTypeResponse::EResponseTransactionID) != aRequest.Uint32(TMTPTypeRequest::ERequestTransactionID)))
       
   249             {
       
   250             /* 
       
   251             Request/Response mismatch by the originating data provider plug-in. 
       
   252             Fail the transport connection to avoid leaving the current 
       
   253             transaction irrecoverably hanging.
       
   254             */
       
   255             UnrecoverableMTPError();
       
   256             User::Leave(KErrArgument);                
       
   257             }
       
   258 
       
   259         if (session.TransactionPhase() == ERequestPhase)
       
   260             {
       
   261             // Transaction has no data phase.
       
   262             session.SetTransactionPhase(EResponsePhase);
       
   263             }
       
   264             
       
   265         session.SetRequestPending(aStatus);
       
   266         
       
   267         iTransportConnection->SendResponseL(aResponse, aRequest);
       
   268         }
       
   269     __FLOG(_L8("SendResponseL - Exit"));
       
   270     }
       
   271 
       
   272 /**
       
   273 Deletes the session object assigned to the specified session and notifies all 
       
   274 loaded data providers.
       
   275 @param aMTPId The session identifier assigned by the MTP connection 
       
   276 initiator.
       
   277 @leave KErrNotFound, if a session with the specified SessionMTPId is not 
       
   278 found.
       
   279 @leave One of the system wide error codes, if a general processing failure 
       
   280 occurs.
       
   281 */
       
   282 EXPORT_C void CMTPConnection::SessionClosedL(TUint32 aMTPId)
       
   283     {
       
   284     __FLOG(_L8("SessionClosedL - Entry"));
       
   285     if(0x0FFFFFFF != aMTPId)
       
   286     	{
       
   287     	TInt idx(iSessions.FindInOrder(aMTPId, SessionOrder));
       
   288 	    __ASSERT_DEBUG((idx != KErrNotFound), Panic(EMTPPanicInvalidSession));
       
   289 	    CloseSession(idx);
       
   290 	    }
       
   291     else
       
   292 	    {
       
   293 	    CMTPSession* session = NULL;
       
   294 	    for(TInt i =0;i<iSessions.Count();i++)
       
   295 		    {
       
   296 		    session = iSessions[i];
       
   297 		    TUint id(session->SessionMTPId());	
       
   298 	    	if(0 != id)
       
   299 		    	{
       
   300 		    	SessionClosedL(id);	
       
   301 		    	}
       
   302 		    session = NULL;
       
   303 		    }
       
   304 	    }
       
   305     __FLOG(_L8("SessionClosedL - Exit"));
       
   306     }
       
   307 
       
   308 /**
       
   309 Creates a new session object for the specified session and notifies all loaded
       
   310 data providers. The session is known by two identifiers:
       
   311     1. SessionMTPId - Assigned by the MTP connection initiator and unique only 
       
   312         to the MTP connection on which the session was opened. In a multiple-
       
   313         connection configuration this identifier may not uniquely identify the 
       
   314         session.
       
   315     2. SessionUniqueId - Assigned by the MTP daemon and guaranteed to uniquely
       
   316         identify the session in a multiple-connection configuration.
       
   317 Currently the MTP daemon does not support multiple-connection configuration 
       
   318 and both identifiers are assigned the same value.
       
   319 @param aMTPId The session identifier assigned by the MTP connection 
       
   320 initiator.
       
   321 @leave KErrAlreadyExists, if a session with the specified SessionMTPId is 
       
   322 already open.
       
   323 @leave One of the system wide error codes, if a general processing failure 
       
   324 occurs.
       
   325 */
       
   326 EXPORT_C void CMTPConnection::SessionOpenedL(TUint32 aMTPId)
       
   327     {
       
   328     __FLOG(_L8("SessionOpenedL - Entry"));
       
   329     // Validate the SessionID
       
   330     if (SessionWithMTPIdExists(aMTPId))
       
   331         {
       
   332         User::Leave(KErrAlreadyExists);            
       
   333         }
       
   334     
       
   335     // Create a new session object
       
   336     CMTPSession* session = CMTPSession::NewLC(aMTPId, aMTPId);
       
   337     session->SetTransactionPhase(EIdlePhase);
       
   338     iSessions.InsertInOrder(session, CMTPConnection::SessionOrder);
       
   339     CleanupStack::Pop(session); 
       
   340     
       
   341     if (aMTPId != KMTPSessionNone)
       
   342         {
       
   343         // Notify the data providers if other than the null session is closing.
       
   344         TMTPNotificationParamsSessionChange params = {aMTPId, *this};
       
   345         iSingletons.DpController().NotifyDataProvidersL(EMTPSessionOpened, &params);
       
   346         }
       
   347     __FLOG(_L8("SessionOpenedL - Exit"));
       
   348     }
       
   349 
       
   350 /*
       
   351  * Signals the connection is suspended, the connection state is set to EStateShutdown which 
       
   352  * means that all the current transaction will not be able to send/receive any data via the
       
   353  * connection
       
   354  */
       
   355 void CMTPConnection::ConnectionSuspended()
       
   356     {
       
   357     __FLOG(_L8("ConnectionSuspended - Entry"));
       
   358     
       
   359     TUint currentState = State();
       
   360     if (currentState!=EStateShutdown && currentState!=EStateErrorShutdown)
       
   361         {
       
   362         SetState(EStateShutdown);
       
   363         
       
   364         if (iTransportConnection != NULL)
       
   365             {
       
   366             iTransportConnection->Unbind(*this);
       
   367             iTransportConnection = NULL;
       
   368             }
       
   369         PublishConnState(EDisconnectedFromHost);   
       
   370     
       
   371         if (ActiveSessions() == 0)
       
   372             {
       
   373             CloseAllSessions();
       
   374             iSessions.Reset();
       
   375             iSingletons.Close();
       
   376             }
       
   377         else 
       
   378             {
       
   379             //some session may be in data or response phase, complete them and set transaction phase to ECompletingPhase.
       
   380             const TUint count(iSessions.Count());
       
   381             for (TUint i(0); (i < count); i++)
       
   382                 {
       
   383                 if (iSessions[i]->TransactionPhase() & (EDataIToRPhase|EDataRToIPhase|EResponsePhase))
       
   384                     {
       
   385                     iSessions[i]->SetTransactionPhase(ECompletingPhase);
       
   386                     iSessions[i]->CompletePendingRequest(KErrCancel);
       
   387                     }
       
   388                 }
       
   389             }
       
   390         }
       
   391     
       
   392     __FLOG(_L8("ConnectionSuspended - Exit"));
       
   393     }
       
   394 
       
   395 /*
       
   396  * Signals that the connection is resumed to EStateOpen state which means that data providers
       
   397  * can receive requests from host again.
       
   398  * @aTransportConnection The new transport connection object
       
   399  * @leave One of the system wide error codes, if a processing failure occurs.
       
   400  */
       
   401 void CMTPConnection::ConnectionResumedL(MMTPTransportConnection& aTransportConnection)
       
   402     {
       
   403     __FLOG(_L8("ConnectionResumed - Entry"));
       
   404     
       
   405     TUint currentState = State();
       
   406     if (currentState != EStateOpen && currentState != EStateErrorRecovery)
       
   407         {
       
   408         iSingletons.OpenL();
       
   409         
       
   410         /* 
       
   411         Create the null session object which owns the transaction state for 
       
   412         transaction occuring outside a session (i.e. with SessionID == 0x00000000)
       
   413         */
       
   414         SessionOpenedL(KMTPSessionNone);            
       
   415         
       
   416         iTransportConnection = &aTransportConnection;
       
   417         iTransportConnection->BindL(*this); 
       
   418         SetState(EStateOpen); 
       
   419         PublishConnState(EConnectedToHost); 
       
   420         }
       
   421     
       
   422     __FLOG(_L8("ConnectionResumed - Exit"));
       
   423     }
       
   424 
       
   425 /**
       
   426 Signals the completion of the current transaction processing sequence. This
       
   427 method should only be invoked when the MTP transaction phase state is 
       
   428 ECompletingPhase.
       
   429 @param aRequest The MTP request dataset of the completed MTP transaction.
       
   430 @leave KErrNotFound If the MTP request dataset specifies an invalid SessionID.
       
   431 @panic CMTPConnection 2 If the MTP transaction phase is invalid.
       
   432 */
       
   433 void CMTPConnection::TransactionCompleteL(const TMTPTypeRequest& aRequest)
       
   434     {
       
   435     __FLOG(_L8("TransactionCompleteL - Entry"));
       
   436     const TUint KValidPhases(ECompletingPhase);
       
   437     CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID));    
       
   438 
       
   439     if (ValidFrameworkRequest(&session, KValidPhases, NULL))
       
   440         {
       
   441         session.SetTransactionPhase(EIdlePhase);
       
   442         if (State() == EStateShutdown)
       
   443             {
       
   444             if (ActiveSessions() == 0)
       
   445                 {        
       
   446                 CloseAllSessions();
       
   447                 iSessions.Reset();
       
   448                 iSingletons.Close();
       
   449                 
       
   450                 // Move the log here because ShutdownComplete will delete this object.
       
   451                 __FLOG(_L8("TransactionCompleteL - Exit"));
       
   452                 }
       
   453             }
       
   454         else
       
   455             {
       
   456             iTransportConnection->TransactionCompleteL(aRequest);
       
   457             __FLOG(_L8("TransactionCompleteL - Exit"));
       
   458             }
       
   459         }
       
   460     }
       
   461     
       
   462 TUint CMTPConnection::ConnectionId() const
       
   463     {
       
   464     return iConnectionId;
       
   465     }
       
   466     
       
   467 TUint CMTPConnection::SessionCount() const
       
   468     {
       
   469     return iSessions.Count();
       
   470     }
       
   471 
       
   472 TBool CMTPConnection::SessionWithMTPIdExists(TUint32 aMTPId) const
       
   473     {
       
   474     return (iSessions.FindInOrder(aMTPId, SessionOrder) != KErrNotFound);
       
   475     }
       
   476 
       
   477 MMTPSession& CMTPConnection::SessionWithMTPIdL(TUint32 aMTPId) const
       
   478     {
       
   479     TInt idx(iSessions.FindInOrder(aMTPId, SessionOrder));
       
   480     User::LeaveIfError(idx);
       
   481     return *iSessions[idx];
       
   482     }
       
   483     
       
   484 TBool CMTPConnection::SessionWithUniqueIdExists(TUint32 aUniqueId) const
       
   485     {
       
   486     return SessionWithMTPIdExists(aUniqueId);
       
   487     }
       
   488 
       
   489 MMTPSession& CMTPConnection::SessionWithUniqueIdL(TUint32 aUniqueId) const
       
   490     {
       
   491     return SessionWithMTPIdL(aUniqueId);
       
   492     }
       
   493     
       
   494 void CMTPConnection::ReceivedEventL(const TMTPTypeEvent& aEvent)
       
   495     {  
       
   496     __FLOG(_L8("ReceivedEventL - Entry"));
       
   497     TInt idx(KErrNotFound);
       
   498     
       
   499     // Validate the SessionID.
       
   500     TUint32 sessionId(aEvent.Uint32(TMTPTypeEvent::EEventSessionID));
       
   501     if (sessionId != KMTPSessionAll)
       
   502         {
       
   503         idx = iSessions.FindInOrder(sessionId, SessionOrder);
       
   504         User::LeaveIfError(idx);
       
   505         }
       
   506        
       
   507     // Check that this event is valid.
       
   508     CMTPSession& session(*iSessions[idx]);
       
   509 
       
   510     TMTPTypeRequest request; 
       
   511     TRAPD( err, MMTPType::CopyL(session.ActiveRequestL(), request) );
       
   512 
       
   513 
       
   514     if( err == KErrNotFound  )
       
   515     	{
       
   516     	session.StorePendingEventL(aEvent);
       
   517     	}
       
   518     else
       
   519     	{
       
   520 	   	if (request.Uint32(TMTPTypeRequest::ERequestTransactionID) > 
       
   521 	    	aEvent.Uint32(TMTPTypeEvent::EEventTransactionID) )
       
   522 	        {
       
   523 	        // Event to be queued for future use, we can only queue one event at a time
       
   524 	        session.StorePendingEventL(aEvent);
       
   525 	        }
       
   526 	        
       
   527 	    if (request.Uint32(TMTPTypeRequest::ERequestTransactionID) == 
       
   528 	         aEvent.Uint32(TMTPTypeEvent::EEventTransactionID) )
       
   529 	        {     
       
   530 	        // Event is valid	     
       
   531 	        // Perform transport layer processing.
       
   532 	        if (aEvent.Uint16(TMTPTypeEvent::EEventCode) == EMTPEventCodeCancelTransaction)
       
   533 	            {
       
   534 	            if (sessionId == KMTPSessionAll)
       
   535 	                {
       
   536 	                const TUint noSessions = iSessions.Count();
       
   537 	                for (TUint i(0); (i < noSessions); i++)
       
   538 	                    {
       
   539 	                    InitiateTransactionCancelL(i);
       
   540 	                    } 
       
   541 	                }
       
   542 	            else
       
   543 	                {
       
   544 	                InitiateTransactionCancelL(idx);
       
   545 	                }
       
   546 	            }
       
   547 	        
       
   548 	         // Forward the event to the DP framework layer.
       
   549 	        iSingletons.Router().ProcessEventL(aEvent, *this); 
       
   550 	        }
       
   551     	}	
       
   552     __FLOG(_L8("ReceivedEventL - Exit"));
       
   553     }
       
   554 
       
   555 void CMTPConnection::ReceivedRequestL(const TMTPTypeRequest& aRequest)
       
   556     {  
       
   557     __FLOG(_L8("ReceivedRequestL - Entry"));
       
   558 #ifdef MTP_CAPTURE_TEST_DATA
       
   559     // Running under debug capture mode save this request off to disk.
       
   560     iRequestLogger->LogRequestL(aRequest);
       
   561 #endif
       
   562 
       
   563     // Resolve the session    
       
   564     TInt idx(iSessions.FindInOrder(aRequest.Uint32(TMTPTypeRequest::ERequestSessionID), SessionOrder));
       
   565 	
       
   566     // Process the request.
       
   567     if (idx == KErrNotFound)
       
   568         {
       
   569         // Invalid SessionID
       
   570         InitiateMTPErrorRecoveryL(aRequest, EMTPRespCodeSessionNotOpen);
       
   571         }
       
   572     else
       
   573         {           
       
   574         CMTPSession& session(*iSessions[idx]);
       
   575         
       
   576         if (session.TransactionPhase() != EIdlePhase)
       
   577             {
       
   578             // Initiator violation of the MTP transaction protocol.
       
   579             UnrecoverableMTPError();
       
   580             }
       
   581         else
       
   582             {
       
   583             // Set the session state
       
   584             session.IncrementExpectedTransactionId();
       
   585             session.SetTransactionPhase(ERequestPhase);
       
   586             session.SetActiveRequestL(aRequest);
       
   587 
       
   588             // Forward the request to the DP framework layer.
       
   589             TRAPD(err,iSingletons.Router().ProcessRequestL(session.ActiveRequestL(), *this));   
       
   590             if(err!=KErrNone)
       
   591                 {
       
   592                 session.SetTransactionPhase(EIdlePhase);
       
   593                 User::Leave(err);
       
   594                 }
       
   595             }
       
   596         }
       
   597     __FLOG(_L8("ReceivedRequestL - Exit"));
       
   598     }
       
   599 
       
   600 #ifdef MTP_CAPTURE_TEST_DATA
       
   601 void CMTPConnection::ReceiveDataCompleteL(TInt aErr, const MMTPType& aData, const TMTPTypeRequest& aRequest)
       
   602 #else
       
   603 void CMTPConnection::ReceiveDataCompleteL(TInt aErr, const MMTPType& aData, const TMTPTypeRequest& aRequest)
       
   604 #endif
       
   605     {
       
   606     __FLOG(_L8("ReceiveDataCompleteL - Entry"));    
       
   607     CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID)); 
       
   608     __ASSERT_DEBUG((session.TransactionPhase() == EDataIToRPhase), Panic(EMTPPanicInvalidState));
       
   609     
       
   610 	if(EMTPTypeFile == aData.Type())
       
   611 	{
       
   612 		//All data transfer is over now we can publish that
       
   613 		//state is connected to host or idle
       
   614 		PublishConnState(EConnectedToHost);
       
   615 	}
       
   616 #ifdef MTP_CAPTURE_TEST_DATA
       
   617     iRequestLogger->WriteDataPhaseL(aData, EDataIToRPhase);
       
   618 #endif
       
   619     
       
   620 	session.SetTransactionPhase(EResponsePhase);
       
   621 	iDataReceiveResult = aErr;
       
   622 	session.CompletePendingRequest(aErr);
       
   623     
       
   624     __FLOG(_L8("ReceiveDataCompleteL - Exit"));
       
   625     }
       
   626 
       
   627 void CMTPConnection::SendDataCompleteL(TInt aErr, const MMTPType& aData, const TMTPTypeRequest& aRequest)
       
   628     {
       
   629     __FLOG(_L8("SendDataCompleteL - Entry"));  
       
   630     CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID)); 
       
   631     __ASSERT_DEBUG((session.TransactionPhase() == EDataRToIPhase), Panic(EMTPPanicInvalidState));
       
   632 
       
   633     session.SetTransactionPhase(EResponsePhase);
       
   634    
       
   635     if(EMTPTypeFile == aData.Type())
       
   636         {
       
   637         //All data transfer is over now we can publish that
       
   638         //state is connected to host or idle
       
   639         PublishConnState(EConnectedToHost);
       
   640         }
       
   641     
       
   642     session.CompletePendingRequest(aErr);
       
   643     
       
   644     __FLOG(_L8("SendDataCompleteL - Exit"));
       
   645     }
       
   646 
       
   647 void CMTPConnection::SendEventCompleteL(TInt aErr, const TMTPTypeEvent& aEvent)
       
   648     {
       
   649     __FLOG(_L8("SendEventCompleteL - Entry"));
       
   650 
       
   651     
       
   652     if (aErr != KErrNone)
       
   653         {
       
   654         UnrecoverableMTPError();            
       
   655         }    
       
   656     else if (aEvent.Uint16(TMTPTypeEvent::EEventCode) == EMTPEventCodeCancelTransaction)
       
   657         {
       
   658         TUint32 sessionId(aEvent.Uint32(TMTPTypeEvent::EEventSessionID));
       
   659         TInt idx(KErrNotFound);
       
   660         if (sessionId == KMTPSessionAll)
       
   661             {
       
   662             const TUint noSessions = iSessions.Count();
       
   663             for (TUint i(0); (i < noSessions); i++)
       
   664                 {
       
   665                 InitiateTransactionCancelL(i);
       
   666                 }    
       
   667             }
       
   668         else
       
   669             {
       
   670             idx = iSessions.FindInOrder(sessionId, SessionOrder);
       
   671             InitiateTransactionCancelL(idx);
       
   672             }   
       
   673         }
       
   674     // Dequeue first since the code below might leave.
       
   675     DequeueEvent(iEventQ.First());       
       
   676    	if (iPendingEventCount > 0)
       
   677    		{
       
   678    		// Forward the event to the transport connection layer.
       
   679    		__FLOG(_L8("Sending queued event"));
       
   680  	    iTransportConnection->SendEventL(iEventQ.First()->iEvent);
       
   681    		}
       
   682     
       
   683     __FLOG(_L8("SendEventCompleteL - Exit"));
       
   684     }
       
   685 
       
   686 void CMTPConnection::SendResponseCompleteL(TInt aErr, const TMTPTypeResponse& /*aResponse*/, const TMTPTypeRequest& aRequest)
       
   687     {   
       
   688     __FLOG(_L8("SendResponseCompleteL - Entry"));
       
   689 	if(iState == EStateErrorRecovery)
       
   690 		{
       
   691 		MTPErrorRecoveryComplete();	    
       
   692 		iTransportConnection->TransactionCompleteL(aRequest);
       
   693 		}
       
   694 	else{
       
   695         CMTPSession& session(SessionL(aRequest, TMTPTypeRequest::ERequestSessionID)); 
       
   696 	    __ASSERT_DEBUG((session.TransactionPhase() == EResponsePhase), Panic(EMTPPanicInvalidState));
       
   697     	session.SetTransactionPhase(ECompletingPhase);
       
   698     	session.CompletePendingRequest(aErr);
       
   699 		}
       
   700     __FLOG(_L8("SendResponseCompleteL - Exit"));
       
   701     }
       
   702 
       
   703    
       
   704 TMTPTransactionPhase CMTPConnection::TransactionPhaseL(TUint32 aMTPId) const
       
   705     {
       
   706     TInt idx(iSessions.FindInOrder(aMTPId, SessionOrder));
       
   707     User::LeaveIfError(idx);
       
   708     return iSessions[idx]->TransactionPhase();
       
   709     }
       
   710 
       
   711 /**
       
   712 Constructor.
       
   713 */
       
   714 CMTPConnection::CMTPConnection(TUint aConnectionId, MMTPTransportConnection& aTransportConnection) :
       
   715     iConnectionId(aConnectionId),
       
   716     iEventQ(_FOFF(CMTPEventLink, iLink)),
       
   717     iTransportConnection(&aTransportConnection)
       
   718     {
       
   719     
       
   720     }
       
   721     
       
   722 /**
       
   723 Second phase constructor.
       
   724 @leave One of the system wide error code, if a processing failure occurs.
       
   725 */
       
   726 void CMTPConnection::ConstructL()
       
   727     {
       
   728 	__FLOG_OPEN(KMTPSubsystem, KComponent);
       
   729     __FLOG(_L8("ConstructL - Entry"));
       
   730     //define the property for publishing connection state.
       
   731     DefineConnStatePropertyL();
       
   732     PublishConnState(EDisconnectedFromHost);  
       
   733 #ifdef MTP_CAPTURE_TEST_DATA
       
   734     // Running under debug capture mode save this request off to disk.
       
   735     iRequestLogger = CMTPRequestLogger::NewL();
       
   736 #endif
       
   737     __FLOG(_L8("ConstructL - Exit"));
       
   738     }
       
   739     
       
   740 /**
       
   741 Initiates an MTP connection level protocol error recovery sequence. This 
       
   742 sequence is invoked when a recoverable protocol error is detected that cannot 
       
   743 be processed above the connection layer, e.g. when a request is made on a 
       
   744 non-existant SessionID, or an out-of-sequence TransactionID is detected. An
       
   745 appropriate MTP response dataset is formed and sent to the MTP initiator. The
       
   746 error recovery sequence is concluded by MTPErrorRecoveryComplete when the 
       
   747 connection transport layer signals SendResponseComplete to the MTP connection 
       
   748 protocol layer.
       
   749 @param aRequest The MTP request dataset of the erroneous MTP transaction.
       
   750 @param aResponseCode The MTP response datacode to be returned to the MTP
       
   751 initiator.
       
   752 @leave One of the system wide error codes, if a processing failure occurs.
       
   753 @see MTPErrorRecoveryComplete
       
   754 */
       
   755 void CMTPConnection::InitiateMTPErrorRecoveryL(const TMTPTypeRequest& aRequest, TUint16 aResponseCode)
       
   756     {
       
   757     __FLOG(_L8("InitiateMTPErrorRecoveryL - Entry"));
       
   758     // Populate error response.
       
   759     iResponse.Reset();
       
   760     iResponse.SetUint16(TMTPTypeResponse::EResponseCode, aResponseCode);
       
   761     iResponse.SetUint32(TMTPTypeResponse::EResponseSessionID, aRequest.Uint32(TMTPTypeRequest::ERequestSessionID));
       
   762     iResponse.SetUint32(TMTPTypeResponse::EResponseTransactionID, aRequest.Uint32(TMTPTypeRequest::ERequestTransactionID));
       
   763     
       
   764     // Set the connection state pending completion, and send the response.
       
   765     SetState(EStateErrorRecovery);
       
   766     iTransportConnection->SendResponseL(iResponse, aRequest);
       
   767     __FLOG(_L8("InitiateMTPErrorRecoveryL - Exit"));
       
   768     }
       
   769     
       
   770 /**
       
   771 Concludes an MTP connection level protocol error recovery sequence.
       
   772 @see InitiateMTPErrorRecoveryL
       
   773 */
       
   774 void CMTPConnection::MTPErrorRecoveryComplete()
       
   775     {
       
   776     __FLOG(_L8("MTPErrorRecoveryComplete - Entry"));
       
   777     SetState(EStateOpen);
       
   778     PublishConnState(EConnectedToHost);	
       
   779     __FLOG(_L8("MTPErrorRecoveryComplete - Exit"));
       
   780     }
       
   781     
       
   782 /**
       
   783 Forces the immediate shutdown of the MTP connection. This is invoked when a 
       
   784 protocol error is detected that cannot be recovered from, e.g. if an attempt
       
   785 is detected to initiate an MTP transaction before a previous transaction has 
       
   786 concluded.
       
   787 */
       
   788 void CMTPConnection::UnrecoverableMTPError()
       
   789     {
       
   790     __FLOG(_L8("UnrecoverableMTPError - Entry"));
       
   791     SetState(EStateErrorShutdown);
       
   792     PublishConnState(EDisconnectedFromHost);		
       
   793     iTransportConnection->CloseConnection();
       
   794     __FLOG(_L8("UnrecoverableMTPError - Entry"));
       
   795     }
       
   796 
       
   797 /**
       
   798 Signals the MTP connection transport to terminate any in-progress data phase 
       
   799 processing on the specified session.
       
   800 @param aidx The sessions table index of the required session.
       
   801 @leave One of the system wide error codes, if a processing failure occurs.
       
   802 */
       
   803 void CMTPConnection::InitiateTransactionCancelL(TInt aIdx)
       
   804     {    
       
   805     __FLOG(_L8("InitiateTransactionCancelL - Entry"));
       
   806     // Initiate transport connection level termination of the active data phase.
       
   807     CMTPSession& session(*iSessions[aIdx]);
       
   808     
       
   809     switch (session.TransactionPhase())
       
   810         {
       
   811     case EIdlePhase:
       
   812     case ECompletingPhase:
       
   813     case ERequestPhase:
       
   814         break;
       
   815 
       
   816     case EDataIToRPhase:
       
   817         iTransportConnection->ReceiveDataCancelL(session.ActiveRequestL());
       
   818         break;
       
   819         
       
   820     case EResponsePhase:
       
   821     case EDataRToIPhase:
       
   822         iTransportConnection->SendDataCancelL(session.ActiveRequestL());
       
   823         break;
       
   824         }
       
   825     __FLOG(_L8("InitiateTransactionCancelL - Exit"));
       
   826     }
       
   827 
       
   828 /**
       
   829 Provides a count of the number of sessions with transactions in-progress.
       
   830 */
       
   831 TUint CMTPConnection::ActiveSessions() const
       
   832     {
       
   833     __FLOG(_L8("ActiveSessions - Entry"));
       
   834     TUint active(0);
       
   835     const TUint count(iSessions.Count());
       
   836     for (TUint i(0); (i < count); i++)
       
   837         {
       
   838         if (iSessions[i]->TransactionPhase() > EIdlePhase)
       
   839             {
       
   840             active++;
       
   841             }
       
   842         }
       
   843     __FLOG_VA((_L8("Active sessions = %d"), active));
       
   844     __FLOG(_L8("ActiveSessions - Exit"));
       
   845     return active;
       
   846     }
       
   847 
       
   848 /**
       
   849 Closes all sessions which have been opened on the connection.
       
   850 */
       
   851 void CMTPConnection::CloseAllSessions()
       
   852     {
       
   853     __FLOG(_L8("CloseAllSessions - Entry"));
       
   854 	
       
   855     TInt count = iSessions.Count();
       
   856     __FLOG_VA((_L8("Sessions number to be closed = %d"), count));   
       
   857 	for (TInt i(count - 1); i>=0; i--)
       
   858 		{
       
   859 		CloseSession(i);
       
   860 		}
       
   861 	
       
   862     __FLOG(_L8("CloseAllSessions - Exit"));
       
   863     }
       
   864 
       
   865 /**
       
   866 Closes the sessions with the specified session index.
       
   867 @param aIdx The session index.
       
   868 */
       
   869 void CMTPConnection::CloseSession(TUint aIdx)
       
   870     {
       
   871     __FLOG(_L8("CloseSession - Entry"));
       
   872     
       
   873     __FLOG_VA((_L8("Session index to be closed = %d"), aIdx));    
       
   874     CMTPSession* session(iSessions[aIdx]);
       
   875         
       
   876     TUint id(session->SessionMTPId());
       
   877     if (id != KMTPSessionNone)
       
   878         {
       
   879         // Notify the data providers if other than the null session is closing.
       
   880         TMTPNotificationParamsSessionChange params = {id, *this};
       
   881         TRAPD(err, iSingletons.DpController().NotifyDataProvidersL(EMTPSessionClosed, &params));
       
   882         UNUSED_VAR(err);
       
   883         }
       
   884     
       
   885     // Remove any queued events for session
       
   886     RemoveEventsForSession(id);
       
   887     
       
   888     // Delete the session object.
       
   889     iSessions.Remove(aIdx);
       
   890     delete session;
       
   891     
       
   892     __FLOG(_L8("CloseSession - Exit"));
       
   893     }
       
   894     
       
   895 /**
       
   896 Provides a reference to the session with the MTP connection assigned identifier
       
   897 specified in the supplied MTP dataset. 
       
   898 @param aDataset The MTP dataset.
       
   899 @param aSessionIdElementNo The element number in the MTP dataset of the MTP 
       
   900 connection assigned identifier.
       
   901 @leave KErrNotFound If the specified session identifier is not currently
       
   902 active on the connection.
       
   903 @return The reference of the session with the specified MTP connection 
       
   904 assigned identifier.
       
   905 */
       
   906 CMTPSession& CMTPConnection::SessionL(const TMTPTypeFlatBase& aDataset, TInt aSessionIdElementNo) const
       
   907     {
       
   908     return static_cast<CMTPSession&>(SessionWithMTPIdL(aDataset.Uint32(aSessionIdElementNo)));
       
   909     }
       
   910 
       
   911 /**
       
   912 Implements an order relation for CMTPSession objects based on relative MTP
       
   913 connection assigned session IDs.
       
   914 @param aL The first MTP connection assigned session ID.
       
   915 @param aR The second object.
       
   916 @return Zero, if the two objects are equal; a negative value, if the aFirst 
       
   917 is less than aSecond, or; a positive value, if the aFirst is greater than 
       
   918 aSecond.
       
   919 */
       
   920 TInt CMTPConnection::SessionOrder(const TUint32* aL, const CMTPSession& aR)
       
   921     {
       
   922     return *aL - aR.SessionMTPId();
       
   923     }
       
   924 
       
   925 /**
       
   926 Implements a TLinearOrder relation for CMTPSession objects based on relative 
       
   927 MTP connection assigned session IDs.
       
   928 @param aL The first object.
       
   929 @param aR The second object.
       
   930 @return Zero, if the two objects are equal; a negative value, if the first 
       
   931 object is less than second, or; a positive value, if the first object is 
       
   932 greater than the second.
       
   933 */
       
   934 TInt CMTPConnection::SessionOrder(const CMTPSession& aL, const CMTPSession& aR)
       
   935     {
       
   936     return aL.SessionMTPId() - aR.SessionMTPId();
       
   937     }
       
   938     
       
   939 /**
       
   940 Get the data receive result.
       
   941 @return the data recevice result.
       
   942 */
       
   943 EXPORT_C TInt CMTPConnection::GetDataReceiveResult() const
       
   944 	{
       
   945 	__FLOG(_L8("GetDataReceiveResult - Entry"));
       
   946     __FLOG_VA((_L8("Data receive result = %d"), iDataReceiveResult));
       
   947     __FLOG(_L8("GetDataReceiveResult - Exit"));
       
   948     return iDataReceiveResult;
       
   949 	}
       
   950     
       
   951 /**
       
   952 Sets the MTP connection state variable.
       
   953 @param aState The new MTP connection state value.
       
   954 */
       
   955 void CMTPConnection::SetState(TUint aState)
       
   956     {
       
   957     __FLOG(_L8("SetState - Entry"));
       
   958     __FLOG_VA((_L8("Setting state = %d"), aState));
       
   959     iState = aState;
       
   960     __FLOG(_L8("SetState - Exit"));
       
   961     }
       
   962   
       
   963     
       
   964 /**
       
   965 Provide the current MTP connection state.
       
   966 @return The current MTP connection state.
       
   967 */
       
   968 TUint CMTPConnection::State() const
       
   969     {
       
   970     __FLOG(_L8("State - Entry"));
       
   971     __FLOG_VA((_L8("State = %d"), iState));
       
   972     __FLOG(_L8("State - Exit"));
       
   973     return iState;        
       
   974     }
       
   975     
       
   976 /**
       
   977 Performs common validation processing for requests initiated from the data 
       
   978 provider framework layer. The following validation checks are performed.
       
   979     1.  Attempt to initiate concurrent asynchronous requests to the same 
       
   980         connection. This will result in a panic.
       
   981     2.  Attempt to initiate a request that is invalid for the current
       
   982         transaction phase. This will result in a panic.
       
   983     3.  Attempt to initiate a request when the connection is in an 
       
   984         unrecoverable error shutdown mode. This will result in the immediate
       
   985         cancellation of the request.
       
   986 @return ETrue if the request is valid to proceed, otherwise EFalse.
       
   987 @panic CMTPConnection 0 If an asynchronous request is already pending on the 
       
   988 connection.
       
   989 @panic CMTPConnection 2 If the MTP transaction phase is invalid.
       
   990 */
       
   991 TBool CMTPConnection::ValidFrameworkRequest(CMTPSession* aSession, TUint aValidPhases, TRequestStatus* aStatus)
       
   992     {
       
   993     __FLOG(_L8("ValidFrameworkRequest - Entry"));
       
   994     __ASSERT_ALWAYS((!aSession || (aSession->TransactionPhase() & aValidPhases)), Panic(EMTPPanicInvalidState));
       
   995     __ASSERT_ALWAYS((!aStatus || (!aSession->RequestPending())), Panic(EMTPPanicBusy));
       
   996     
       
   997     TBool ret(ETrue);
       
   998     switch (State())
       
   999         {
       
  1000     case EStateUnknown:
       
  1001     case EStateErrorRecovery:
       
  1002     default:
       
  1003         Panic(EMTPPanicInvalidState);
       
  1004         break;
       
  1005         
       
  1006     case EStateOpen:
       
  1007         break;
       
  1008 
       
  1009     case EStateShutdown:    
       
  1010     case EStateErrorShutdown:
       
  1011         // Shutdown in progress.
       
  1012         if (aSession != NULL) //Transaction is still alive during shutdown
       
  1013             {
       
  1014             ret = (aSession->TransactionPhase() == ECompletingPhase);
       
  1015             aSession->SetTransactionPhase(ECompletingPhase);
       
  1016             PublishConnState(EDisconnectedFromHost);		
       
  1017             if (aStatus)
       
  1018                 {
       
  1019                 User::RequestComplete(aStatus, KErrCancel); 
       
  1020                 }
       
  1021             }
       
  1022         else //SendEventL happens during shutdown
       
  1023             {
       
  1024             ret = EFalse;
       
  1025             }
       
  1026         break;
       
  1027         }
       
  1028         
       
  1029     __FLOG(_L8("ValidFrameworkRequest - Exit"));
       
  1030     return ret;
       
  1031     }
       
  1032 
       
  1033 void CMTPConnection::RemoveEventsForSession(TUint32 aMTPId)
       
  1034 	{
       
  1035     __FLOG(_L8("RemoveEventsForSession - Entry"));
       
  1036     
       
  1037     TSglQueIter<CMTPEventLink> iter(iEventQ);
       
  1038     iter.SetToFirst();
       
  1039     CMTPEventLink* link = NULL;
       
  1040     
       
  1041     while ((link = iter++) != NULL)
       
  1042     	{
       
  1043 		if (link->iEvent.Uint32(TMTPTypeEvent::EEventSessionID) == aMTPId)
       
  1044 			{
       
  1045 			DequeueEvent(link);
       
  1046 			}
       
  1047 		}
       
  1048     
       
  1049     __FLOG(_L8("RemoveEventsForSession - Exit"));
       
  1050 	}
       
  1051 
       
  1052 void CMTPConnection::DequeueEvent(CMTPEventLink* aLink)
       
  1053 	{
       
  1054 	iEventQ.Remove(*aLink);
       
  1055 	delete aLink;
       
  1056 	--iPendingEventCount;	
       
  1057 	}
       
  1058 
       
  1059 void CMTPConnection::EnqueueEvent(CMTPEventLink* aLink)
       
  1060 	{
       
  1061    	iEventQ.AddLast(*aLink);
       
  1062    	++iPendingEventCount;	
       
  1063 	}
       
  1064 	
       
  1065 CMTPConnection::CMTPEventLink::CMTPEventLink(const TMTPTypeEvent& aEvent) :
       
  1066 	iEvent(aEvent)
       
  1067 	{
       
  1068 	}
       
  1069 
       
  1070 /**
       
  1071   * This method define and attach the property for publishing connection state 
       
  1072   *  events.
       
  1073   */
       
  1074 void CMTPConnection::DefineConnStatePropertyL()
       
  1075 	{
       
  1076 	
       
  1077 	 __FLOG(_L8("DefineConnStatePropertyL - Entry"));
       
  1078 	 RProcess process;
       
  1079 	 TUid tSid = process.SecureId();	
       
  1080 	//Property can read by anyone who subscribe for it.
       
  1081 	_LIT_SECURITY_POLICY_PASS(KAllowReadAll);
       
  1082 	_LIT_SECURITY_POLICY_S0(KAllowWrite, (TSecureId )KMTPPublishConnStateCat);
       
  1083 	
       
  1084 	TInt error = RProperty::Define(tSid, EMTPConnStateKey, RProperty::EInt, KAllowReadAll, KAllowReadAll);	
       
  1085 	if (KErrAlreadyExists != error)
       
  1086 		{
       
  1087 		User::LeaveIfError(error);
       
  1088 		}
       
  1089 	User::LeaveIfError(iProperty.Attach(tSid, EMTPConnStateKey, EOwnerThread));
       
  1090 	__FLOG(_L8("DefineConnStatePropertyL - Exit"));
       
  1091 	}
       
  1092 
       
  1093 /**
       
  1094   * This method is to publish various connection state. 
       
  1095   */
       
  1096 void CMTPConnection::PublishConnState(TMTPConnStateType aConnState)	
       
  1097 	{
       
  1098 	__FLOG_VA((_L8("PublishConnState - Entry \n publishing state = %d"), (TInt)aConnState));
       
  1099 	RProcess process;    
       
  1100 	TInt error = iProperty.Set(process.SecureId(), EMTPConnStateKey, (TInt)aConnState);		
       
  1101 	 __ASSERT_DEBUG((error == KErrNone), Panic(EMTPPanicPublishEvent));;
       
  1102 	__FLOG(_L8("PublishConnState - Exit"));
       
  1103 	}
       
  1104 
       
  1105 /**
       
  1106   * This method is used to publish the events based on the TransactionPhase.
       
  1107   * 
       
  1108   */
       
  1109 void CMTPConnection::ValidateAndPublishConnState(CMTPSession& aSession, TInt aState)
       
  1110 	{	
       
  1111     	__FLOG_VA((_L8("ValidateAndPublishConnState - Entry \n publishing state = %d"), aState));
       
  1112 
       
  1113 	TMTPConnStateType conState = EConnectedToHost;
       
  1114 	switch((TStates)aState)
       
  1115 		{
       
  1116 		  case EStateOpen:
       
  1117 		  	{
       
  1118 		  	TMTPTransactionPhase tPhase = aSession.TransactionPhase();
       
  1119 			switch(tPhase)
       
  1120 				{
       
  1121 				case EDataRToIPhase:
       
  1122 					conState = ESendingDataToHost;
       
  1123 				break;
       
  1124 
       
  1125 				case EDataIToRPhase:
       
  1126 					conState = EReceiveDataFromHost;	
       
  1127 				break;
       
  1128 
       
  1129 				case EIdlePhase:
       
  1130 				case EUndefined:
       
  1131 				case ERequestPhase:
       
  1132 				case EResponsePhase:
       
  1133 				case ECompletingPhase:
       
  1134 				default:
       
  1135 					conState = EConnectedToHost;
       
  1136 				break;
       
  1137 				}
       
  1138 		  	}
       
  1139 		   break;
       
  1140 		  case EStateShutdown:    
       
  1141 		  case EStateErrorShutdown:
       
  1142 		  	conState = EDisconnectedFromHost;
       
  1143 		  break;
       
  1144 
       
  1145 		  case EStateErrorRecovery:
       
  1146 		  case EStateUnknown:
       
  1147 		  default:
       
  1148 		  	conState = EConnectedToHost;
       
  1149 		  break;
       
  1150 		}
       
  1151 	PublishConnState(conState);
       
  1152 	__FLOG(_L8("ValidateAndPublishConnStateL - Exit"));
       
  1153 	}
       
  1154 
       
  1155 void CMTPConnection::DisconnectionNotifyL()
       
  1156 	{
       
  1157 	iSingletons.DpController().NotifyDataProvidersL(EMTPDisconnected,this);	
       
  1158 	}