usbengines/usbremotepersonality/src/cremotepersonalityhandler.cpp
changeset 34 7858bc6ead78
parent 31 dfdd8240f7c8
child 35 9d8b04ca6939
equal deleted inserted replaced
31:dfdd8240f7c8 34:7858bc6ead78
     1 /*
       
     2 * Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Handles Remote personalities change
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <e32std.h>
       
    21 #include <versioninfo.h>
       
    22 #include <d32usbc.h>
       
    23 #include <usbman.h>
       
    24 #include <usbwatcher.h>
       
    25 
       
    26 #include "cremotepersonalityhandler.h"
       
    27 #include "csetpersonality.h" 
       
    28 #include "debug.h"
       
    29 
       
    30 const TUint KValueLoByte = 2;
       
    31 const TUint KValueHiByte = 3;
       
    32 const TUint KIndexLoByte = 4;
       
    33 const TUint KIndexHiByte = 5;
       
    34 const TUint KLengthLoByte = 6;
       
    35 const TUint KLengthHiByte = 7;
       
    36 
       
    37 const TUint KOneByte = 8; // for shifting data to one byte
       
    38 
       
    39 const TUint KGetPersonalitiesHeaderLen = 4;
       
    40 const TUint KItemsPerPersonality = 2;
       
    41 
       
    42 const TUint8 KStringDescriptorsBase = 0xED; // string descriptors will be written starting from this index, descendingly; 0xEE is used for OS string descriptor
       
    43 
       
    44 const TUint KAllPersonalitiesDescriptorType = 0x12; // All Personalities Descriptor type 
       
    45 
       
    46 const TUint KSetupPacketLength = 8; // 8 bytes
       
    47 
       
    48 const TUint KS6032MajorNumber = 3; // 3.2 major number is 3
       
    49 
       
    50 const TInt K32DevicePCSuite = 113;
       
    51 const TInt K32DeviceMS = 114;
       
    52 const TInt K32DevicePTP = 115;
       
    53 
       
    54 const TInt KHostPCSuite = 1;
       
    55 const TInt KHostMS = 2;
       
    56 const TInt KHostPTP = 3;
       
    57 
       
    58 // ---------------------------------------------------------------------------
       
    59 // Decoding EP0 buffer
       
    60 // ---------------------------------------------------------------------------
       
    61 //
       
    62 void TSetupPacket::Decode(const RBuf8& aSetupPacket)
       
    63     {
       
    64         
       
    65     if (aSetupPacket.Length() < KSetupPacketLength)
       
    66         {
       
    67         iRequest = CRemotePersonalityHandler::EUnknown; 
       
    68         return;
       
    69         }
       
    70     
       
    71     iType           = aSetupPacket[0];
       
    72     iRequest        = static_cast<CRemotePersonalityHandler::TRequest>(aSetupPacket[1]);
       
    73     iValue          = static_cast<TUint16>(aSetupPacket[KValueLoByte] | 
       
    74                                             (aSetupPacket[KValueHiByte] << KOneByte) );
       
    75     iIndex          = static_cast<TUint16>(aSetupPacket[KIndexLoByte] |
       
    76                                             (aSetupPacket[KIndexHiByte] << KOneByte) );
       
    77     iLength         = static_cast<TUint16>(aSetupPacket[KLengthLoByte] |
       
    78                                             (aSetupPacket[KLengthHiByte] << KOneByte) );
       
    79     }
       
    80 
       
    81 // ---------------------------------------------------------------------------
       
    82 // Two-phase construction
       
    83 // ---------------------------------------------------------------------------
       
    84 //  
       
    85 CRemotePersonalityHandler* CRemotePersonalityHandler::NewL()
       
    86     {
       
    87     
       
    88     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::NewL" ) );
       
    89     
       
    90     CRemotePersonalityHandler* self = new (ELeave) CRemotePersonalityHandler();
       
    91     CleanupStack::PushL(self);
       
    92     self->ConstructL();
       
    93     CleanupStack::Pop(self);
       
    94     return self;    
       
    95     }
       
    96 
       
    97 // ---------------------------------------------------------------------------
       
    98 // Default construction
       
    99 // ---------------------------------------------------------------------------
       
   100 //
       
   101 CRemotePersonalityHandler::CRemotePersonalityHandler() : 
       
   102                                         iLastResult(EUndefinedError)
       
   103     {
       
   104     iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown;
       
   105     }
       
   106         
       
   107 // ---------------------------------------------------------------------------
       
   108 // Two-phase construction
       
   109 // ---------------------------------------------------------------------------
       
   110 //
       
   111 void CRemotePersonalityHandler::ConstructL()
       
   112     {
       
   113     
       
   114     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ConstructL" ) );
       
   115     iSetPersonalityHandler = CSetPersonality::NewL(*this);
       
   116     
       
   117     iMappingIsNeeded = IsMappingNeededL();
       
   118     }
       
   119     
       
   120 // ---------------------------------------------------------------------------
       
   121 // Destruction
       
   122 // ---------------------------------------------------------------------------
       
   123 //
       
   124 CRemotePersonalityHandler::~CRemotePersonalityHandler()
       
   125     {
       
   126     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::~CRemotePersonalityHandler" ) );
       
   127     
       
   128     delete iSetPersonalityHandler;
       
   129                  
       
   130     iPersonalities.Close(); // T-classes' objects in RArray do not require to be "destroyed"
       
   131             
       
   132     }   
       
   133     
       
   134 // ---------------------------------------------------------------------------
       
   135 // SetPersonality request has been completed
       
   136 // ---------------------------------------------------------------------------
       
   137 //
       
   138 void CRemotePersonalityHandler::SetPersonalityCallBack(TLastResult aResult)
       
   139     {
       
   140     
       
   141     FTRACE(FPrint(
       
   142           _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SetPersonalityCallBack aResult = %d" ), aResult));
       
   143     
       
   144     iLastResult = aResult;
       
   145     iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown;
       
   146     
       
   147     }
       
   148 
       
   149 // ---------------------------------------------------------------------------
       
   150 // Personality-related requests handler
       
   151 // ---------------------------------------------------------------------------
       
   152 //
       
   153 TInt CRemotePersonalityHandler::Handle(const RBuf8& aSetupBuffer, RBuf8& aData)
       
   154     {
       
   155     
       
   156     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Handle" ) );
       
   157     
       
   158     TRAPD(err, DoHandleL(aSetupBuffer, aData));
       
   159     
       
   160     return static_cast<TLastResult>(err);
       
   161     
       
   162     }
       
   163 
       
   164 // ---------------------------------------------------------------------------
       
   165 // Personality-related requests internal handler
       
   166 // ---------------------------------------------------------------------------
       
   167 //
       
   168 void CRemotePersonalityHandler::DoHandleL(const RBuf8& aSetupBuffer, RBuf8& aData)
       
   169     {
       
   170     
       
   171     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::DoHandleL" ) );
       
   172     
       
   173     iSetupPacket.Decode(aSetupBuffer);
       
   174     
       
   175     FTRACE(FPrint(
       
   176            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::DoHandleL: Request = %d" ), iSetupPacket.iRequest));
       
   177     
       
   178     switch(iSetupPacket.iRequest)
       
   179         {
       
   180         
       
   181         case EGetAllPersonalities       :
       
   182             {
       
   183             iLastResult = EUndefinedError; // will be updated after completing the request
       
   184             
       
   185             GetPersonalitiesL(aData);
       
   186             
       
   187             iLastResult = ESuccess; //static_cast<TLastResult>(err);
       
   188             
       
   189             break;
       
   190             }
       
   191         
       
   192         case EGetLastResult             :
       
   193             {
       
   194             GetLastResultL(aData);
       
   195             break;
       
   196             }
       
   197         
       
   198         case ESetPersonality            :
       
   199             {
       
   200             
       
   201             iLastResult = EUndefinedError; // will be updated after copmleting the request
       
   202 
       
   203             SetPersonalityL();
       
   204             
       
   205             iLastResult = EDataTransferInProgress; 
       
   206             
       
   207             break;
       
   208             
       
   209             }
       
   210                 
       
   211         case EGetPersonalityDescriptor  :
       
   212         case EGetPersonality            :
       
   213         case EGetLockState              :
       
   214         case ESetLockState              :
       
   215         
       
   216         default:
       
   217             {
       
   218                 
       
   219             FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Handle ***Request Is Not Supported***" ) );
       
   220             
       
   221             User::Leave(KErrNotSupported); 
       
   222             
       
   223             }
       
   224         }
       
   225      
       
   226     }
       
   227     
       
   228 // ---------------------------------------------------------------------------
       
   229 // Set links to needed services
       
   230 // ---------------------------------------------------------------------------
       
   231 //
       
   232 void CRemotePersonalityHandler::Initialize( RDevUsbcClient& aLdd, 
       
   233                                             RUsbWatcher& aUsbWatcher,
       
   234                                             RUsb& aUsbManager)
       
   235     {
       
   236     
       
   237     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize" ) );
       
   238     
       
   239     iUsbWatcher = &aUsbWatcher;
       
   240     iUsbManager = &aUsbManager;
       
   241     iLdd = &aLdd;
       
   242     
       
   243     iSetPersonalityHandler->SetUsbWatcher(iUsbWatcher);
       
   244     
       
   245     // Read personalities
       
   246     TRAPD(err, ReadPersonalitiesL());
       
   247     
       
   248     FTRACE(FPrint(
       
   249            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize: ReadPersonalities err  = %d" ), err));
       
   250     
       
   251     // Save personalities descriptions, to enable read of them by standard GetDescriptor request 
       
   252     TRAP(err, SavePersonalitiesStringsL());
       
   253     
       
   254     FTRACE(FPrint(
       
   255            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::Initialize: SavePersString err  = %d" ), err));
       
   256    
       
   257     }
       
   258 
       
   259 // ---------------------------------------------------------------------------
       
   260 // Process GetAllPersonalities request
       
   261 // ---------------------------------------------------------------------------
       
   262 //
       
   263 void CRemotePersonalityHandler::GetPersonalitiesL(RBuf8& aPersonalities)
       
   264     {
       
   265     
       
   266     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities" ) );
       
   267     
       
   268     // check the request
       
   269     if((iSetupPacket.iValue != 0) || (iSetupPacket.iIndex != 0))
       
   270         {
       
   271 
       
   272         FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::GetPersonalities SetupPacket has wrong data *****" ) );
       
   273         User::Leave(EInvalidRequest);
       
   274 
       
   275         }
       
   276 
       
   277     TInt8 responseLength(KGetPersonalitiesHeaderLen+iPersonalities.Count()*KItemsPerPersonality); // 4 mandatory bytes for header + 2 bytes per personality
       
   278 
       
   279     FTRACE(FPrint(
       
   280            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Response length is %d bytes" ), responseLength));
       
   281     
       
   282     aPersonalities.Close();
       
   283     aPersonalities.Create(responseLength);
       
   284     
       
   285     // Panic on Append never can be rised in this method, due to aPersonalities length exactly equal the appending data length.  
       
   286     aPersonalities.Append(responseLength);
       
   287     aPersonalities.Append(KAllPersonalitiesDescriptorType); // All Personalities Descriptor type 
       
   288     
       
   289     TInt err(ESuccess);
       
   290     TInt currentPersonalityId;
       
   291     
       
   292     err = iUsbManager->GetCurrentPersonalityId(currentPersonalityId);
       
   293     if(ESuccess != err)
       
   294         {
       
   295         User::Leave(EUndefinedError);
       
   296         }
       
   297         
       
   298     FTRACE(FPrint(
       
   299           _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Current personality Id is %d" ), currentPersonalityId));
       
   300     
       
   301     // in S60 3.2 or older, map some personality ids into newer set
       
   302     if(iMappingIsNeeded)
       
   303     	{
       
   304     	currentPersonalityId = MapPersonalityIdFromDeviceToHostL(currentPersonalityId);
       
   305     	}
       
   306     
       
   307     aPersonalities.Append(static_cast<TInt8>(currentPersonalityId));
       
   308     aPersonalities.Append(static_cast<TInt8>(iPersonalities.Count()));
       
   309     
       
   310     TUint counter(KGetPersonalitiesHeaderLen); // counter for aPersonalities descriptor, 4 bytes already written
       
   311     
       
   312     for(TUint i(0); i < iPersonalities.Count(); ++i, counter = counter + KItemsPerPersonality)
       
   313         {
       
   314         
       
   315         TPersonality personality;
       
   316         
       
   317         if(iMappingIsNeeded)
       
   318         	{
       
   319         	personality.iId = MapPersonalityIdFromDeviceToHostL(iPersonalities[i].iId);
       
   320         	}
       
   321         	else
       
   322         	{
       
   323         	personality.iId = iPersonalities[i].iId;	
       
   324         	}
       
   325         	
       
   326         aPersonalities.Append(static_cast<TInt8>(personality.iId));
       
   327         aPersonalities.Append(static_cast<TInt8>(iPersonalities[i].iIndex));        
       
   328     
       
   329         FTRACE(FPrint(
       
   330            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetPersonalities Added personality id %d Index %d" ), aPersonalities[counter], aPersonalities[counter + 1]));
       
   331 
       
   332         }
       
   333     
       
   334     }
       
   335 
       
   336 // ---------------------------------------------------------------------------
       
   337 // Reads personalities 
       
   338 // ---------------------------------------------------------------------------
       
   339 //
       
   340 void CRemotePersonalityHandler::ReadPersonalitiesL()
       
   341     {
       
   342     
       
   343     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalitiesL" ) );
       
   344     
       
   345     RArray<TInt> personalityIds;
       
   346     CleanupClosePushL(personalityIds);
       
   347     
       
   348     User::LeaveIfError(iUsbManager->GetPersonalityIds(personalityIds));
       
   349     
       
   350     FTRACE(FPrint(
       
   351            _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalities There are %d personalities supported" ), personalityIds.Count()));
       
   352     
       
   353     // save ids to iPersonalities           
       
   354     iPersonalities.Reset();
       
   355     TPersonality p;
       
   356     
       
   357     for(TUint i(0); i < personalityIds.Count(); ++i)
       
   358         {
       
   359     
       
   360         p.iId = personalityIds[i];
       
   361         p.iIndex = KStringDescriptorsBase - i;
       
   362         
       
   363         // iPersonalities is a dynamic array, no error handling is needed on Append    
       
   364         iPersonalities.Append(p);
       
   365             
       
   366         FTRACE(FPrint(
       
   367           _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::ReadPersonalities Personality id = %d Index = %d" ), iPersonalities[i].iId, iPersonalities[i].iIndex));
       
   368 
       
   369         }
       
   370         
       
   371     CleanupStack::PopAndDestroy(&personalityIds); // personalityIds
       
   372 
       
   373     }
       
   374 
       
   375 // ---------------------------------------------------------------------------
       
   376 // Saves personalities descriptions as standard usb string descriptors
       
   377 // ---------------------------------------------------------------------------
       
   378 //  
       
   379 void CRemotePersonalityHandler::SavePersonalitiesStringsL()
       
   380     {
       
   381     
       
   382     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStringsL" ) );
       
   383     
       
   384     HBufC* description; // personality description
       
   385     for(TUint i(0); i<iPersonalities.Count(); ++i)
       
   386         {
       
   387         // gets description; data owenerships hands over to caller
       
   388         User::LeaveIfError(iUsbManager->GetDescription(iPersonalities[i].iId, description));
       
   389         
       
   390         FTRACE(FPrint(
       
   391           _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStrings Personality Id = %d Description length =  %d" ), iPersonalities[i].iId, description->Length()));
       
   392         
       
   393         // save string to repository
       
   394         User::LeaveIfError(iLdd->SetStringDescriptor(iPersonalities[i].iIndex, *description));
       
   395         
       
   396         FTRACE(FPrint(
       
   397           _L("[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SavePersonalitiesStrings Personality description saved with index %d" ), iPersonalities[i].iIndex));
       
   398 
       
   399         delete description;
       
   400         description = 0;
       
   401         }
       
   402         
       
   403     }
       
   404     
       
   405 // ---------------------------------------------------------------------------
       
   406 // Process SetPersonality request
       
   407 // ---------------------------------------------------------------------------
       
   408 //  
       
   409 void CRemotePersonalityHandler::SetPersonalityL()
       
   410     {
       
   411     
       
   412     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::SetPersonality" ) );
       
   413     
       
   414     // check the request
       
   415     if((iSetupPacket.iLength != 0) || (iSetupPacket.iIndex != 0))
       
   416         {
       
   417 
       
   418         FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::SetPersonality SetupPacket has wrong data *****" ) );
       
   419         User::Leave(EInvalidRequest);
       
   420 
       
   421         }
       
   422     
       
   423     if(iMappingIsNeeded)
       
   424     	{
       
   425     	iSetupPacket.iValue = MapPersonalityIdFromHostToDeviceL(iSetupPacket.iValue);
       
   426     	}
       
   427     	
       
   428     // due to watcher process SetPersonality somehow strange, here is check for valid id	
       
   429     for(TUint i(0); i < iPersonalities.Count(); ++i)
       
   430     	{
       
   431     	if(iSetupPacket.iValue == iPersonalities[i].iId)
       
   432     		{
       
   433     		// set personality
       
   434     		iSetPersonalityHandler->SetPersonality(iSetupPacket.iValue);
       
   435     		return;
       
   436     		}
       
   437     	}
       
   438     	
       
   439     // did not find personality id in list of supported personalities
       
   440     iLastResult = ENonExistingPersonality;
       
   441     iSetupPacket.iRequest = CRemotePersonalityHandler::EUnknown;
       
   442     User::Leave(ENonExistingPersonality);    
       
   443     
       
   444     }
       
   445 
       
   446 // ---------------------------------------------------------------------------
       
   447 // Process GetLastResult request
       
   448 // ---------------------------------------------------------------------------
       
   449 //  
       
   450 void CRemotePersonalityHandler::GetLastResultL(RBuf8& aLastResult)
       
   451     {
       
   452     
       
   453     FLOG( _L( "[USBREMOTEPERSONALITY]\tCRemotePersonalityHandler::GetLastResult" ) );
       
   454     
       
   455     // check the request
       
   456     if((iSetupPacket.iValue != 0) || (iSetupPacket.iIndex != 0))
       
   457         {
       
   458 
       
   459         FLOG( _L( "[USBREMOTEPERSONALITY]\t**** CRemotePersonalityHandler::GetLastResult SetupPacket has wrong data *****" ) );
       
   460         User::Leave(EInvalidRequest);
       
   461 
       
   462         }
       
   463     
       
   464     aLastResult.Close();
       
   465     aLastResult.Create(1); // Length of response to GetLastResult request is 1 byte always.
       
   466     
       
   467     // Panic on Append never can be rised here, due to aPersonalities length exactly equal the appending data length.  
       
   468     aLastResult.Append(static_cast<TInt8>(iLastResult));
       
   469     
       
   470 }
       
   471 
       
   472 TBool CRemotePersonalityHandler::IsMappingNeededL()
       
   473 {
       
   474 	VersionInfo::TPlatformVersion platformVersion;
       
   475 	User::LeaveIfError( VersionInfo::GetVersion( platformVersion ) );
       
   476 	
       
   477 	if(platformVersion.iMajorVersion > KS6032MajorNumber) return EFalse;
       
   478 	
       
   479 	return ETrue;	
       
   480 }
       
   481 
       
   482 TInt CRemotePersonalityHandler::MapPersonalityIdFromDeviceToHostL(TInt aPersonality)
       
   483 {
       
   484 	switch(aPersonality)
       
   485 	{
       
   486 		case K32DevicePCSuite: return KHostPCSuite;
       
   487 		case K32DeviceMS: return KHostMS;
       
   488 		case K32DevicePTP: return KHostPTP;
       
   489 		
       
   490 		default: return aPersonality;	
       
   491 	}
       
   492 }
       
   493 
       
   494 TInt CRemotePersonalityHandler::MapPersonalityIdFromHostToDeviceL(TInt aPersonality)
       
   495 {
       
   496 	switch(aPersonality)
       
   497 	{
       
   498 		case KHostPCSuite: return K32DevicePCSuite;
       
   499 		case KHostMS: return K32DeviceMS;
       
   500 		case KHostPTP: return K32DevicePTP;
       
   501 		
       
   502 		default: return aPersonality;	
       
   503 	}
       
   504 	
       
   505 }
       
   506 
       
   507