mtpfws/mtpfw/src/cmtpdataprovider.cpp
changeset 0 d0791faffa3f
child 6 f8e15b44d440
child 17 aabe5387f5ce
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 #include <mtp/cmtpdataproviderplugin.h>
       
    17 #include <mtp/mtpdataproviderconfig.hrh>
       
    18 #include <mtp/mtpprotocolconstants.h>
       
    19 #include <mtp/tmtptyperesponse.h> 
       
    20 
       
    21 #include "cmtpsession.h"
       
    22 #include "cmtpconnection.h"
       
    23 #include "cmtpconnectionmgr.h"
       
    24 #include "cmtpdataprovider.h"
       
    25 #include "cmtpdataproviderconfig.h"
       
    26 #include "cmtpframeworkconfig.h"
       
    27 #include "cmtpobjectmgr.h"
       
    28 #include "cmtpparserrouter.h"
       
    29 #include "cmtpreferencemgr.h"
       
    30 #include "cmtpstoragemgr.h"
       
    31 #include "mmtptransactionproxy.h"
       
    32 #include "rmtpframework.h"
       
    33 #include "cdummydp.h"
       
    34 #include "cmtpdatacodegenerator.h"
       
    35 
       
    36 // Class constants.
       
    37 __FLOG_STMT(_LIT8(KComponent,"DataProvider");)
       
    38 
       
    39 const TInt KWaitForEnumeration = 1000000 * 3;
       
    40 
       
    41 #define KMTPDummyDataProvider             0x0000
       
    42 
       
    43 /**
       
    44 CMTPDataProvider factory method. 
       
    45 @param aId The data provider identifier.
       
    46 @param aUid The data provider implementation UID.
       
    47 @param aConfig The data provider configurability parameter data. Ownership IS 
       
    48 transfered.
       
    49 @return A pointer to a new CMTPDataProvider instance. Ownership IS transfered.
       
    50 @leave One of the system wide error codes if a processing failure occurs.
       
    51 */
       
    52 CMTPDataProvider* CMTPDataProvider::NewL(TUint aId, TUid aUid, CMTPDataProviderConfig* aConfig)
       
    53     {
       
    54     CMTPDataProvider* self = CMTPDataProvider::NewLC(aId, aUid, aConfig);
       
    55     CleanupStack::Pop(self);
       
    56     return self;
       
    57     }
       
    58 
       
    59 /**
       
    60 CMTPDataProvider factory method. A pointer to the CMTPDataProvider instance is
       
    61 placed on the cleanup stack.
       
    62 @param aUid The data provider implementation UID.
       
    63 @param aConfig The data provider configurability parameter data. Ownership IS 
       
    64 transfered.
       
    65 @return A pointer to a new CMTPDataProvider instance. Ownership IS transfered.
       
    66 @leave One of the system wide error codes if a processing failure occurs.
       
    67 */ 
       
    68 CMTPDataProvider* CMTPDataProvider::NewLC(TUint aId, TUid aUid, CMTPDataProviderConfig* aConfig)
       
    69     {
       
    70     CMTPDataProvider* self = new (ELeave) CMTPDataProvider(aId, aUid, aConfig);
       
    71     CleanupStack::PushL(self);
       
    72     self->ConstructL();    
       
    73     return self;
       
    74     }
       
    75     
       
    76 /**
       
    77 Destructor.
       
    78 */
       
    79 CMTPDataProvider::~CMTPDataProvider()
       
    80     {
       
    81     __FLOG_VA((_L8("~CMTPDataProvider - Entry, data provider %d "), iId));
       
    82     Cancel();
       
    83     iSupported.ResetAndDestroy();
       
    84     delete iImplementation;
       
    85     iSingletons.Close();
       
    86 
       
    87     // Only delete passed objects when fully constructed.
       
    88     if (iConstructed)
       
    89         {
       
    90         delete iConfig;
       
    91         }
       
    92 	
       
    93 	iTimer.Close();  
       
    94     __FLOG_VA((_L8("~CMTPDataProvider - Exit, data provider %d "), iId));
       
    95     __FLOG_CLOSE;
       
    96     }
       
    97     
       
    98 void CMTPDataProvider::ExecuteEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
       
    99     {   
       
   100     __FLOG_VA((_L8("ExecuteEventL - Entry, data provider %d "), iId));
       
   101     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   102 	
       
   103     if (iTimerActive && aEvent.Uint16(TMTPTypeEvent::EEventCode) == EMTPEventCodeCancelTransaction)
       
   104 	    {
       
   105 	    Cancel();
       
   106 	    }
       
   107     
       
   108     // Pass this event notification directly to the plugin...
       
   109     // In reality we will only ever see one event canceltransaction.
       
   110     iImplementation->ProcessEventL(aEvent, aConnection);
       
   111     __FLOG_VA((_L8("ExecuteEventL - Exit, data provider %d "), iId));
       
   112     }
       
   113         
       
   114 void CMTPDataProvider::ExecuteRequestL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   115     {
       
   116     __FLOG_VA((_L8("ExecuteRequestL - Entry, data provider %d "), iId));
       
   117     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   118                
       
   119     iCurrentRequest = &aRequest;
       
   120     iCurrentConnection = &iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId());
       
   121     // Schedule data provider to process this request.  
       
   122     Schedule(); 
       
   123     
       
   124     __FLOG_VA((_L8("ExecuteRequestL - Exit, data provider %d "), iId));
       
   125     }
       
   126     
       
   127 EXPORT_C void CMTPDataProvider::ExecuteProxyRequestL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection, MMTPTransactionProxy& aProxy)
       
   128     {
       
   129     __FLOG_VA((_L8("ExecuteProxyRequestL - Entry, data provider %d "), iId));
       
   130     iProxy = &aProxy;
       
   131     iCurrentRequest    = &aRequest;
       
   132     iCurrentConnection = static_cast<CMTPConnection*>(&aConnection);
       
   133     Schedule();
       
   134     __FLOG_VA((_L8("ExecuteProxyRequestL - Exit, data provider %d "), iId));
       
   135     }
       
   136     
       
   137 void CMTPDataProvider::EnumerateObjectsL(TUint32 aStorageId)
       
   138     {
       
   139     __FLOG_VA((_L8("EnumerateObjectsL - Entry, data provider %d "), iId));
       
   140     iEnumerationState = ((iEnumerationState & ~EObjectsEnumerationState) | EObjectsEnumerating);
       
   141     TBool abnormaldown = EFalse;
       
   142     iSingletons.FrameworkConfig().GetValueL(CMTPFrameworkConfig::EAbnormalDown, abnormaldown);
       
   143     iImplementation->StartObjectEnumerationL(aStorageId, abnormaldown);
       
   144     __FLOG_VA((_L8("EnumerateObjectsL - Exit, data provider %d "), iId));
       
   145     }
       
   146 
       
   147 void CMTPDataProvider::EnumerateStoragesL()
       
   148     {
       
   149     __FLOG_VA((_L8("EnumerateStoragesL - Entry, data provider %d "), iId));
       
   150     iEnumerationState = ((iEnumerationState & ~EStoragesEnumerationState) | EStoragesEnumerating);
       
   151     iImplementation->StartStorageEnumerationL();
       
   152     __FLOG_VA((_L8("EnumerateStoragesL - Exit, data provider %d "), iId));
       
   153     }
       
   154 
       
   155 /**
       
   156 Provides the data provider's enumeration state.
       
   157 @return The data provider's enumeration state.
       
   158 */
       
   159 EXPORT_C TUint CMTPDataProvider::EnumerationState() const
       
   160 	{
       
   161     return iEnumerationState;	
       
   162 	}
       
   163     
       
   164 /**
       
   165 Provides the data provider's implementation UID
       
   166 @return The data provider's implementation UID.
       
   167 */
       
   168 EXPORT_C TUid CMTPDataProvider::ImplementationUid() const 
       
   169     {
       
   170     return iImplementationUid;
       
   171     }
       
   172     
       
   173 /**
       
   174 Provides the handle of the bound data provider plug-in.
       
   175 @return The data provider plug-in.
       
   176 */
       
   177 EXPORT_C CMTPDataProviderPlugin& CMTPDataProvider::Plugin() const
       
   178     {
       
   179     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   180     return *iImplementation;
       
   181     }
       
   182     
       
   183 EXPORT_C TBool CMTPDataProvider::Supported(TMTPSupportCategory aCategory, TUint aCode) const
       
   184     {
       
   185     return iSupported[aCategory]->Supported(aCode);
       
   186     }
       
   187     
       
   188 EXPORT_C const RArray<TUint>& CMTPDataProvider::SupportedCodes(TMTPSupportCategory aCategory) const
       
   189     {
       
   190     return iSupported[aCategory]->Codes();
       
   191     }
       
   192 
       
   193 /**
       
   194 Sets the 
       
   195 */    
       
   196 void CMTPDataProvider::SetDataProviderId(TUint aId)
       
   197     {
       
   198     __FLOG_VA((_L8("~CMTPDataProvider - Entry, data provider %d "), iId));
       
   199     iId = aId;
       
   200     __FLOG_VA((_L8("~CMTPDataProvider - Entry, data provider %d "), iId));
       
   201     }
       
   202 	
       
   203 /**
       
   204 Implements a linear order relation for @see CMTPDataProvider 
       
   205 objects based on relative @see CMTPDataProvider::ImplementationUid.
       
   206 @param aUid The implementation UID object to match.
       
   207 @param aObject The object instance to match.
       
   208 @return Zero, if the two objects are equal; A negative value, if the first 
       
   209 object is less than the second, or; A positive value, if the first object is 
       
   210 greater than the second.
       
   211 */     
       
   212 TInt CMTPDataProvider::LinearOrderUid(const TUid* aUid, const CMTPDataProvider& aObject)
       
   213     {
       
   214     return (aUid->iUid - aObject.ImplementationUid().iUid);
       
   215     }
       
   216     
       
   217 /**
       
   218 Implements a @see TLinearOrder for @see CMTPDataProvider objects based on 
       
   219 relative @see CMTPDataProvider::ImplementationUid.
       
   220 @param aL The first object instance.
       
   221 @param aR The second object instance.
       
   222 @return Zero, if the two objects are equal; A negative value, if the first 
       
   223 object is less than the second, or; A positive value, if the first object is 
       
   224 greater than the second.
       
   225 */   
       
   226 TInt CMTPDataProvider::LinearOrderUid(const CMTPDataProvider& aL, const CMTPDataProvider& aR)
       
   227     {
       
   228     return (aL.iImplementationUid.iUid - aR.iImplementationUid.iUid);
       
   229     }
       
   230 
       
   231 /**
       
   232 Implements a @see TLinearOrder for @see CMTPDataProvider objects based on 
       
   233 relative @see CMTPDataProvider::DataProviderId.
       
   234 @param aDPId The Dataprovider ID to match.
       
   235 @param aR The second object instance.
       
   236 @return Zero, if the two objects are equal; A negative value, if the first 
       
   237 object is less than the second, or; A positive value, if the first object is 
       
   238 greater than the second.
       
   239 */   
       
   240 TInt CMTPDataProvider::LinearOrderDPId(const TUint* aDPId, const CMTPDataProvider& aObject)
       
   241     {
       
   242     return (*aDPId - aObject.DataProviderId());
       
   243     }
       
   244 
       
   245 /**
       
   246 Implements a @see TLinearOrder for @see CMTPDataProvider objects based on 
       
   247 relative @see CMTPDataProvider::DataProviderId.
       
   248 @param aL The first object instance.
       
   249 @param aR The second object instance.
       
   250 @return Zero, if the two objects are equal; A negative value, if the first 
       
   251 object is less than the second, or; A positive value, if the first object is 
       
   252 greater than the second.
       
   253 */   
       
   254 TInt CMTPDataProvider::LinearOrderDPId(const CMTPDataProvider& aL, const CMTPDataProvider& aR)
       
   255     {
       
   256     return (aL.DataProviderId() - aR.DataProviderId());
       
   257     }
       
   258 
       
   259 /**
       
   260 Implements a @see TLinearOrder for @see CMTPDataProvider objects based on 
       
   261 relative enumeration phase
       
   262 @param aL The first object instance.
       
   263 @param aR The second object instance.
       
   264 @return Zero, if the two objects are equal; A negative value, if the first 
       
   265 object is less than the second, or; A positive value, if the first object is 
       
   266 greater than the second.
       
   267 */   
       
   268 TInt CMTPDataProvider::LinearOrderEnumerationPhase(const CMTPDataProvider& aL, const CMTPDataProvider& aR)
       
   269     {    
       
   270     return (aL.DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase)
       
   271     	      - aR.DataProviderConfig().UintValue(MMTPDataProviderConfig::EEnumerationPhase));
       
   272     }
       
   273 
       
   274     
       
   275 TUint CMTPDataProvider::DataProviderId() const
       
   276     {
       
   277     return iId;
       
   278     }    
       
   279     
       
   280 TMTPOperationalMode CMTPDataProvider::Mode() const
       
   281     {
       
   282     return (iSingletons.DpController().Mode());    
       
   283     }
       
   284     
       
   285 void CMTPDataProvider::ReceiveDataL(MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   286     {
       
   287     __FLOG_VA((_L8("ReceiveDataL - Entry, data provider %d "), iId));
       
   288     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   289     __ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   290     
       
   291     if (iProxy)
       
   292         {
       
   293         // Pass to proxy plugin for processing
       
   294         iProxy->ProxyReceiveDataL(aData, aRequest, aConnection, iStatus);
       
   295         SetActive();
       
   296         
       
   297         // Running under proxy mode so manually set the next transaction phase to be processed by the plugin
       
   298         iProxyTransactionPhase = EResponsePhase;
       
   299         }
       
   300     else
       
   301         {
       
   302         // Inform the connection that we wish to receive data from the connection
       
   303         CMTPConnection& connection(iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId()));
       
   304         connection.ReceiveDataL(aData, aRequest, iStatus);
       
   305         SetActive();
       
   306         // Async call so wait for object to be activated...
       
   307         }
       
   308     __FLOG_VA((_L8("ReceiveDataL - Exit, data provider %d "), iId));
       
   309     }
       
   310 
       
   311 void CMTPDataProvider::SendDataL(const MMTPType& aData, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   312     {
       
   313     __FLOG_VA((_L8("SendDataL - Entry, data provider %d "), iId));
       
   314     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   315     __ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   316     
       
   317     if (iProxy)
       
   318         {
       
   319         // Pass to proxy plugin for processing
       
   320         iProxy->ProxySendDataL(aData,aRequest, aConnection, iStatus);
       
   321         SetActive();
       
   322         
       
   323         // Running under proxy mode so manually set the next transaction phase to be processed by the plugin
       
   324         iProxyTransactionPhase = EResponsePhase;
       
   325         }
       
   326     else
       
   327         {
       
   328         // Pass request to connection...
       
   329         CMTPConnection& connection(iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId()));
       
   330         connection.SendDataL(aData, aRequest, iStatus);
       
   331         SetActive();
       
   332         // Async call so wait for object to be activated...
       
   333         }
       
   334     __FLOG_VA((_L8("SendDataL - Exit, data provider %d "), iId));
       
   335     }
       
   336 
       
   337 void CMTPDataProvider::SendEventL(const TMTPTypeEvent& aEvent, MMTPConnection& aConnection)
       
   338     {
       
   339     __FLOG_VA((_L8("SendEventL - Entry, data provider %d "), iId));
       
   340     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   341     
       
   342     CMTPConnection& connection(iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId()));
       
   343     connection.SendEventL(aEvent);
       
   344     __FLOG_VA((_L8("SendEventL - Exit, data provider %d "), iId));
       
   345     }
       
   346 
       
   347 void CMTPDataProvider::SendEventL(const TMTPTypeEvent& aEvent)
       
   348     {
       
   349     __FLOG_VA((_L8("SendEventL - Entry, data provider %d "), iId));
       
   350     if (aEvent.Uint32(TMTPTypeEvent::EEventSessionID) != KMTPSessionAll)
       
   351         {
       
   352         User::Leave(KErrArgument);            
       
   353         }
       
   354     
       
   355     TUint numConnections(iSingletons.ConnectionMgr().ConnectionCount());
       
   356     
       
   357     for (TUint i(0); (i < numConnections); i++)
       
   358         {
       
   359         iSingletons.ConnectionMgr()[i].SendEventL(aEvent);       
       
   360         }
       
   361     __FLOG_VA((_L8("SendEventL - Exit, data provider %d "), iId));
       
   362     }
       
   363 
       
   364 void CMTPDataProvider::SendResponseL(const TMTPTypeResponse& aResponse, const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   365     {
       
   366     __FLOG_VA((_L8("SendResponseL - Entry, data provider %d "), iId));
       
   367     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   368     __ASSERT_DEBUG(!IsActive(), User::Invariant());
       
   369     
       
   370     if (iProxy)
       
   371         {
       
   372         // Pass to proxy plugin for processing
       
   373         iProxy->ProxySendResponseL(aResponse, aRequest, aConnection, iStatus);
       
   374         SetActive();
       
   375         
       
   376         // Running under proxy mode so manually set the next transaction phase to be processed by the plugin
       
   377         iProxyTransactionPhase = ECompletingPhase;
       
   378         }
       
   379     else
       
   380         {
       
   381         CMTPConnection& connection(iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId()));
       
   382         connection.SendResponseL(aResponse, aRequest, iStatus);
       
   383         SetActive();
       
   384         }
       
   385     __FLOG_VA((_L8("SendResponseL - Exit, data provider %d "), iId));
       
   386     }
       
   387 
       
   388 void CMTPDataProvider::TransactionCompleteL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   389     {
       
   390     __FLOG_VA((_L8("TransactionCompleteL - Entry, data provider %d "), iId));
       
   391     __ASSERT_DEBUG(iImplementation, User::Invariant());
       
   392     
       
   393     if (iProxy)
       
   394         {
       
   395         // Pass to proxy plugin for processing
       
   396         iProxy->ProxyTransactionCompleteL(aRequest, aConnection);
       
   397         // Running under proxy mode so manually set the next transaction phase to be processed by the plugin
       
   398         iProxyTransactionPhase = ERequestPhase;
       
   399         }
       
   400     else
       
   401         {
       
   402         CMTPConnection& connection(iSingletons.ConnectionMgr().ConnectionL(aConnection.ConnectionId()));
       
   403         connection.TransactionCompleteL(aRequest);            
       
   404         }
       
   405     
       
   406     // Clear pointers
       
   407     iProxy = NULL;
       
   408     iCurrentRequest = NULL;
       
   409     iCurrentConnection = NULL;
       
   410     
       
   411     __FLOG_VA((_L8("TransactionCompleteL - Exit, data provider %d "), iId));
       
   412     } 
       
   413     
       
   414 void CMTPDataProvider::RouteRequestRegisterL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   415     {
       
   416     __FLOG_VA((_L8("RouteRequestRegisterL - Entry, data provider %d "), iId));
       
   417     iSingletons.Router().RouteRequestRegisterL(aRequest, aConnection, iId);
       
   418     __FLOG_VA((_L8("RouteRequestRegisterL - Exit, data provider %d "), iId));
       
   419     }
       
   420 
       
   421 void CMTPDataProvider::RouteRequestUnregisterL(const TMTPTypeRequest& aRequest, MMTPConnection& aConnection)
       
   422     {
       
   423     __FLOG_VA((_L8("RouteRequestUnregister - Entry, data provider %d "), iId));
       
   424     iSingletons.Router().RouteRequestUnregisterL(aRequest, aConnection);
       
   425     __FLOG_VA((_L8("RouteRequestUnregister - Exit, data provider %d "), iId));
       
   426     }
       
   427 
       
   428 #ifdef __FLOG_ACTIVE  	
       
   429 void CMTPDataProvider::ObjectEnumerationCompleteL(TUint32 aStorageId)
       
   430 #else
       
   431 void CMTPDataProvider::ObjectEnumerationCompleteL(TUint32 /*aStorageId*/)
       
   432 #endif // __FLOG_ACTIVE
       
   433     {
       
   434     __FLOG_VA((_L8("ObjectEnumerationCompleteL - Entry, data provider %d "), iId));
       
   435     __FLOG_VA((_L8("StorageId = 0x%08X "), aStorageId));
       
   436     iEnumerationState = ((iEnumerationState & ~EObjectsEnumerationState) | EObjectsEnumerated);
       
   437     iSingletons.DpController().EnumerationStateChangedL(*this);
       
   438     __FLOG_VA((_L8("ObjectEnumerationCompleteL - Exit, data provider %d "), iId));
       
   439     }
       
   440     
       
   441 void CMTPDataProvider::StorageEnumerationCompleteL()
       
   442     {
       
   443     __FLOG_VA((_L8("StorageEnumerationCompleteL - Entry, data provider %d "), iId));
       
   444     iEnumerationState = ((iEnumerationState & ~EStoragesEnumerationState) | EStoragesEnumerated);
       
   445     iSingletons.DpController().EnumerationStateChangedL(*this);
       
   446     __FLOG_VA((_L8("StorageEnumerationCompleteL - Exit, data provider %d "), iId));
       
   447     }
       
   448 
       
   449 const MMTPDataProviderConfig& CMTPDataProvider::DataProviderConfig() const
       
   450 	{
       
   451 	return *iConfig;
       
   452 	}
       
   453 	
       
   454 const MMTPFrameworkConfig& CMTPDataProvider::FrameworkConfig() const
       
   455 	{
       
   456     return iSingletons.FrameworkConfig();
       
   457 	}
       
   458 
       
   459 MMTPObjectMgr& CMTPDataProvider::ObjectMgr() const
       
   460     {    
       
   461     return iSingletons.ObjectMgr();
       
   462     }
       
   463     
       
   464 MMTPReferenceMgr& CMTPDataProvider::ReferenceMgr() const
       
   465     {
       
   466     return iSingletons.ReferenceMgr();
       
   467     }
       
   468     
       
   469 MMTPStorageMgr& CMTPDataProvider::StorageMgr() const
       
   470     {    
       
   471     return iSingletons.StorageMgr();
       
   472     } 
       
   473     
       
   474 RFs& CMTPDataProvider::Fs() const
       
   475     {
       
   476     return iSingletons.Fs();
       
   477     }
       
   478 
       
   479 MMTPDataCodeGenerator& CMTPDataProvider::DataCodeGenerator() const
       
   480     {
       
   481     return iSingletons.DataCodeGenerator();
       
   482     }
       
   483 
       
   484 void CMTPDataProvider::DoCancel()
       
   485     {
       
   486     __FLOG_VA((_L8("DoCancel - Entry, data provider %d "), iId));
       
   487     __FLOG_VA((_L8("DoCancel - Exit, data provider %d "), iId)); 
       
   488 	
       
   489     if (iTimerActive)
       
   490 	    {
       
   491 	    iTimer.Cancel();
       
   492 	    iTimerActive = EFalse;
       
   493 	    }
       
   494     else
       
   495 	    {
       
   496     	TRequestStatus* status = &iStatus;
       
   497 	    User::RequestComplete(status, KErrCancel);
       
   498 	    }  
       
   499     }
       
   500     
       
   501 void CMTPDataProvider::RunL()
       
   502     {  
       
   503     __FLOG_VA((_L8("RunL - Entry, data provider %d "), iId));
       
   504     __MTP_HEAP_FLOG
       
   505     __ASSERT_DEBUG(iCurrentConnection, User::Invariant());
       
   506      
       
   507 	
       
   508     iTimerActive = EFalse; 
       
   509 
       
   510 	if (iProxy)
       
   511         {
       
   512         iCurrentTransactionPhase = iProxyTransactionPhase;
       
   513         }
       
   514     else
       
   515         {
       
   516         iCurrentTransactionPhase = iCurrentConnection->TransactionPhaseL(iCurrentRequest->Uint32(TMTPTypeRequest::ERequestSessionID));        
       
   517         }
       
   518     __FLOG_VA((_L8("Current transaction phase = 0x%08X"), iCurrentTransactionPhase));
       
   519     
       
   520     TInt status(iStatus.Int());
       
   521     if ((status != KErrNone) &&
       
   522     	(status != KErrAbort) &&
       
   523     	(status != KErrCancel))
       
   524 	    {
       
   525 	    // Framework or transport error has occured, force error recovery.
       
   526         iErrorRecovery = iStatus.Int();
       
   527 	    }
       
   528     else if (status == KErrCancel)
       
   529         {
       
   530         iImplementation->Cancel();
       
   531         }
       
   532 
       
   533     
       
   534     if (iErrorRecovery != KErrNone)
       
   535         {
       
   536         __FLOG(_L8("Error recovery in progress"));
       
   537         switch (iCurrentTransactionPhase)
       
   538             {
       
   539         case ERequestPhase:
       
   540         case EDataIToRPhase:
       
   541         case EDataRToIPhase:
       
   542         case EResponsePhase:
       
   543             SendErrorResponseL(iErrorRecovery);
       
   544             break;
       
   545             
       
   546         case ECompletingPhase:
       
   547             TRAPD(err, iImplementation->ProcessRequestPhaseL(iCurrentTransactionPhase, *iCurrentRequest, *iCurrentConnection));
       
   548             __FLOG_VA((_L8("iImplementation->ProcessRequestPhaseL error %d"), err));
       
   549             if (err != KErrNone)
       
   550                 {
       
   551                 TransactionCompleteL(*iCurrentRequest, *iCurrentConnection);   
       
   552                 }
       
   553             iErrorRecovery = KErrNone;
       
   554             break;
       
   555             
       
   556         default:
       
   557             break;                
       
   558             }
       
   559         }
       
   560     
       
   561 		else if (iSingletons.DpController().EnumerateState() != CMTPDataProviderController::EEnumerated)
       
   562     	{
       
   563         __FLOG(_L8("DP Enumeration is not complete"));
       
   564 
       
   565         TUint16 opCode = iCurrentRequest->Uint16(TMTPTypeRequest::ERequestOperationCode);
       
   566 
       
   567         switch(opCode)
       
   568         {
       
   569         case EMTPOpCodeOpenSession:
       
   570         case EMTPOpCodeCloseSession:
       
   571         case EMTPOpCodeGetDeviceInfo:
       
   572         case EMTPOpCodeGetDevicePropDesc:
       
   573         case EMTPOpCodeGetObjectPropsSupported:
       
   574         case EMTPOpCodeGetObjectPropDesc:
       
   575         case EMTPOpCodeVendorExtextensionEnd:
       
   576             iImplementation->ProcessRequestPhaseL(iCurrentTransactionPhase, *iCurrentRequest, *iCurrentConnection);
       
   577     	break;
       
   578 
       
   579         case EMTPOpCodeGetStorageIDs:
       
   580         case EMTPOpCodeGetStorageInfo:
       
   581         	if(iSingletons.DpController().EnumerateState() > CMTPDataProviderController::EEnumeratingDataProviderStorages)
       
   582         	{
       
   583         		iImplementation->ProcessRequestPhaseL(iCurrentTransactionPhase, *iCurrentRequest, *iCurrentConnection);
       
   584         	}
       
   585         	else
       
   586         	{
       
   587         	    //If storages are not enumerated wait for 3 secs and check it again.
       
   588     			iTimer.After(iStatus, TTimeIntervalMicroSeconds32(KWaitForEnumeration));
       
   589     			SetActive();
       
   590     			iTimerActive = ETrue;
       
   591         	}
       
   592             break;
       
   593         	    	
       
   594         default:
       
   595 
       
   596 	    switch (iCurrentTransactionPhase)
       
   597 		    {
       
   598 		case ERequestPhase:
       
   599 		   	// Wait till the objects are enumerated. 
       
   600 		    // checks for every 3 secs till the objects are eumrated.
       
   601 		    // Won't send any device busy response.
       
   602 		    // Windows wont repond if it gets device busy response after it has send Openseesion.
       
   603 			iTimer.After(iStatus, TTimeIntervalMicroSeconds32(KWaitForEnumeration));
       
   604 			SetActive();
       
   605 			iTimerActive = ETrue;
       
   606 			break;		   
       
   607 	   	case ECompletingPhase:
       
   608 	   		TransactionCompleteL(*iCurrentRequest, *iCurrentConnection);   
       
   609 		   	break;
       
   610 	   	default:
       
   611 		   	break;
       
   612 		    }
       
   613 	    }
       
   614 		}
       
   615     else
       
   616         {
       
   617         // Pass to the bound plugin for processing.
       
   618         iImplementation->ProcessRequestPhaseL(iCurrentTransactionPhase, *iCurrentRequest, *iCurrentConnection);
       
   619         
       
   620         //Make ActiveRequest processor and CancelRequest processing to occur synchronously
       
   621         if( iCurrentTransactionPhase == ERequestPhase )
       
   622         	{
       
   623         	CMTPSession& session(static_cast<CMTPSession&>(iCurrentConnection->SessionWithMTPIdL(iCurrentRequest->Uint32(TMTPTypeRequest::ERequestSessionID))));
       
   624         	MMTPConnectionProtocol& connection(static_cast<MMTPConnectionProtocol&>(*iCurrentConnection)); 
       
   625         	
       
   626         	// Pass transaction to session to check against any pending events
       
   627            	if ( session.CheckPendingEvent(*iCurrentRequest) )
       
   628             	{
       
   629                 //Current request matches a pending event, pass event to connection layer event processing
       
   630                 connection.ReceivedEventL(session.PendingEvent());
       
   631                 }
       
   632         	}
       
   633         
       
   634         }
       
   635     
       
   636     __MTP_HEAP_FLOG
       
   637     __FLOG_VA((_L8("RunL - Exit, data provider %d "), iId));
       
   638     }
       
   639      
       
   640 TInt CMTPDataProvider::RunError(TInt aError)
       
   641 	{
       
   642     __FLOG_VA((_L8("RunError - Entry, data provider %d "), iId));
       
   643     __FLOG_VA((_L8("Error = %d"), aError));
       
   644     
       
   645     /* 
       
   646     CMTPDataProvider or iImplementation error, save the error state and 
       
   647     re-schedule.
       
   648     */
       
   649     iErrorRecovery = aError;
       
   650     Schedule();
       
   651     
       
   652     __FLOG_VA((_L8("RunError - Exit, data provider %d "), iId));
       
   653 	return KErrNone;
       
   654 	}
       
   655 
       
   656 /**
       
   657 Constructor.
       
   658 @param aId The data provider identifier.
       
   659 @param aUid The data provider implementation UID.
       
   660 @param aConfig The data provider configurability parameter data. Ownership IS 
       
   661 transfered.
       
   662 */
       
   663 CMTPDataProvider::CMTPDataProvider(TUint aId, TUid aUid, CMTPDataProviderConfig* aConfig) : 
       
   664 	CActive(EPriorityStandard),
       
   665 	iConfig(aConfig),
       
   666 	iId(aId),
       
   667 	iImplementationUid(aUid),
       
   668 	iProxyTransactionPhase(ERequestPhase)
       
   669     {
       
   670     CActiveScheduler::Add(this);
       
   671     }
       
   672         
       
   673 /**
       
   674 Second phase constructor.
       
   675 @leave One of the system wide error codes if a processing failure occurs.
       
   676 */
       
   677 void CMTPDataProvider::ConstructL()
       
   678 	{
       
   679     __FLOG_OPEN(KMTPSubsystem, KComponent);
       
   680     __FLOG_VA((_L8("ConstructL - Entry, data provider %d "), iId));
       
   681     
       
   682     iSingletons.OpenL();
       
   683     TUint tDPType = iConfig->UintValue(MMTPDataProviderConfig::EDataProviderType);   
       
   684     const TUint KExcludeCategoryStart = EVendorExtensionSets;
       
   685     const TUint KExcludeCategoryEnd = EFormatExtensionSets;
       
   686     if( tDPType == KMTPDummyDataProvider)
       
   687     	{
       
   688 		iImplementation = static_cast<CMTPDataProviderPlugin*>(CDummyDp::NewL(static_cast<MMTPDataProviderFramework*>(this)));
       
   689 		//create your dummy classCMTPDataProviderPlugin
       
   690 		for (TUint i(EAssociationTypes); (i < ENumCategories); i++)
       
   691             {
       
   692             CSupportedCodes* codes = CSupportedCodes::NewLC(static_cast<TMTPSupportCategory>(i), Plugin());
       
   693             
       
   694             if((i >= KExcludeCategoryStart) && (i <= KExcludeCategoryEnd) && (codes->Codes().Count() >0))
       
   695             	{
       
   696             	User::Leave(KErrNotSupported);
       
   697             	}
       
   698             
       
   699             iSupported.AppendL(codes);
       
   700             CleanupStack::Pop(codes);
       
   701             }
       
   702 		iConstructed = ETrue;	
       
   703 		}
       
   704 	else   
       
   705     	{
       
   706     	iImplementation = CMTPDataProviderPlugin::NewL(iImplementationUid, static_cast<MMTPDataProviderFramework*>(this));
       
   707 	
       
   708     	for (TUint i(EAssociationTypes); (i < ENumCategories); i++)
       
   709         	{
       
   710         	CSupportedCodes* codes = CSupportedCodes::NewLC(static_cast<TMTPSupportCategory>(i), Plugin());
       
   711         	
       
   712         	if((i >= KExcludeCategoryStart) && (i <= KExcludeCategoryEnd) && (codes->Codes().Count() >0))
       
   713             	{
       
   714             	User::Leave(KErrNotSupported);
       
   715             	}
       
   716         	iSupported.AppendL(codes);
       
   717         	CleanupStack::Pop(codes);
       
   718         	}
       
   719 				
       
   720     	User::LeaveIfError(iTimer.CreateLocal());
       
   721 
       
   722 		// Only assume ownership of passed objects on successful construction.
       
   723 		iConstructed = ETrue;
       
   724 	
       
   725 		__FLOG_VA((_L8("Data provider %d iImplementationUid 0x08%X "), iId, iImplementationUid));
       
   726     	__FLOG_VA((_L8("ConstructL - Exit, data provider %d "), iId));	
       
   727     	}
       
   728 	 
       
   729 	}
       
   730 
       
   731 /**
       
   732 Schedules the next request phase or event.
       
   733 */
       
   734 void CMTPDataProvider::Schedule()
       
   735     {
       
   736     __FLOG_VA((_L8("Schedule - Entry, data provider %d "), iId));
       
   737     iStatus = KRequestPending;
       
   738     TRequestStatus* status = &iStatus;
       
   739     SetActive();
       
   740     User::RequestComplete(status, KErrNone);
       
   741     __FLOG_VA((_L8("Schedule - Exit, data provider %d "), iId));
       
   742     }
       
   743 
       
   744 /**
       
   745 Formats and sends an MTP response dataset from the specified error code.
       
   746 @param aError The error code.
       
   747 @leave One of the system wide error codes, if a processing error occurs.
       
   748 */
       
   749 void CMTPDataProvider::SendErrorResponseL(TInt aError)
       
   750 	{
       
   751     __FLOG_VA((_L8("SendResponseL - Entry, data provider %d "), iId));
       
   752 	__ASSERT_DEBUG(iCurrentRequest != NULL, User::Invariant());
       
   753 	
       
   754 	TMTPResponseCode code;
       
   755 	switch (aError)
       
   756 	    {
       
   757     case KErrOverflow:
       
   758     case KMTPDataTypeInvalid:
       
   759         code = EMTPRespCodeInvalidDataset;
       
   760         break;
       
   761         
       
   762     default:
       
   763         code = EMTPRespCodeGeneralError;
       
   764         break;
       
   765 	    }
       
   766 	    
       
   767     __FLOG_VA((_L8("Sending response code  0x%04X"), code));
       
   768 	iResponse.SetUint16(TMTPTypeResponse::EResponseCode, code);		    
       
   769     iResponse.SetUint32(TMTPTypeResponse::EResponseSessionID, iCurrentRequest->Uint32(TMTPTypeResponse::EResponseSessionID));	
       
   770 	iResponse.SetUint32(TMTPTypeResponse::EResponseTransactionID, iCurrentRequest->Uint32(TMTPTypeResponse::EResponseTransactionID));
       
   771 	SendResponseL(iResponse, *iCurrentRequest, *iCurrentConnection);
       
   772 	
       
   773     __FLOG_VA((_L8("SendResponseL - Exit, data provider %d "), iId));	
       
   774 	}
       
   775     
       
   776 CMTPDataProvider::CSupportedCodes* CMTPDataProvider::CSupportedCodes::NewLC(TMTPSupportCategory aCategory, MMTPDataProvider& aDp)
       
   777     {
       
   778     CSupportedCodes* self = new(ELeave) CSupportedCodes();
       
   779     CleanupStack::PushL(self);
       
   780     self->ConstructL(aCategory, aDp);
       
   781     return self;
       
   782     }
       
   783     
       
   784 CMTPDataProvider::CSupportedCodes::~CSupportedCodes()
       
   785     {
       
   786     iCodes.Close();
       
   787     }
       
   788     
       
   789 const RArray<TUint>& CMTPDataProvider::CSupportedCodes::Codes() const
       
   790     {
       
   791     return iCodes;
       
   792     }
       
   793     
       
   794 TBool CMTPDataProvider::CSupportedCodes::Supported(TUint aCode) const
       
   795     {
       
   796     return (iCodes.FindInOrder(aCode) != KErrNotFound);
       
   797     }
       
   798     
       
   799 CMTPDataProvider::CSupportedCodes::CSupportedCodes() :
       
   800     iCodes()
       
   801     {
       
   802     
       
   803     }
       
   804     
       
   805 void CMTPDataProvider::CSupportedCodes::ConstructL(TMTPSupportCategory aCategory, MMTPDataProvider& aDp)
       
   806     {
       
   807     aDp.Supported(aCategory, iCodes);
       
   808     iCodes.Sort();
       
   809     }
       
   810 
       
   811