Convert Kernelhwsrv package from SFL to EPL
kernel\eka\compsupp is subject to the ARM EABI LICENSE
userlibandfileserver\fatfilenameconversionplugins\unicodeTables is subject to the Unicode license
kernel\eka\kernel\zlib is subject to the zlib license
// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// @internalComponent
//
//
#include <e32std.h>
#include <e32std_private.h>
#include <u32std.h> // unicode builds
#include <e32base.h>
#include <e32base_private.h>
#include <e32cons.h>
#include <e32Test.h> // RTest header
#include <e32def.h>
#include <e32def_private.h>
#include <d32otgdi.h> // OTGDI header
#include <d32usbc.h> // USBCC header
#include "otgroot.h"
#include "testcaseroot.h"
RUsbOtgDriver oUsbOtgDriver;
RDevUsbcClient oUsbcClient;
//=====================================================================================
/* this class wraps all OTGDI calls as well to simplify
calling and normalising object access. - it has no base-class hence we can use multiple-inheritance
*/
COtgRoot::COtgRoot()
{
iOptActive = EFalse;
SetLoaded(EFalse);
}
/** otgLoadLdd
*/
TInt COtgRoot::otgLoadLdd()
{
LOG_FUNC
LOG_VERBOSE2(_L("Load driver: %S\n"), &KOTGDeviceInterfaceDriverName);
if (!LddLoaded())
{
// load ldd device drivers (load otg only, it will load the needed stuff for us)
TInt err(User::LoadLogicalDevice(KOTGDeviceInterfaceDriverName));
if ( (err != KErrNone) && (err != KErrAlreadyExists) )
{
test.Printf(_L("<Error %d> Unable to load driver: %S\n"), err, &KOTGDeviceInterfaceDriverName);
SetLoaded(EFalse);
return(err);
}
else
{
LOG_VERBOSE2(_L("Loaded driver: '%S' OK\n"), &KOTGDeviceInterfaceDriverName);
SetLoaded(ETrue);
}
}
return(KErrNone);
}
/** otgOpen
*/
TInt COtgRoot::otgOpen()
{
LOG_FUNC
LOG_VERBOSE2(_L("Opening session... loaded = %d\n"), LddLoaded());
TInt err(oUsbOtgDriver.Open());
if (err != KErrNone)
{
test.Printf(_L("<Error %d> Unable to open a channel to USB OTG driver\n"),err);
return(err);
}
else
{
LOG_VERBOSE1(_L("Open channel OK\n"));
}
return(KErrNone);
}
/** otgClose
*/
void COtgRoot::otgClose()
{
LOG_FUNC
test.Printf(_L("Closing session... loaded = %d\n"), LddLoaded());
oUsbOtgDriver.Close();
}
/* otgActivateOptTestMode
*/
TInt COtgRoot::otgActivateOptTestMode()
{
LOG_FUNC
TInt err = oUsbOtgDriver.ActivateOptTestMode();
return(err);
}
/** otgStartStacks
*/
TInt COtgRoot::otgStartStacks()
{
LOG_FUNC
TInt err(oUsbOtgDriver.StartStacks());
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
return(err);
}
/** otgStopStacks
*/
void COtgRoot::otgStopStacks()
{
LOG_FUNC
oUsbOtgDriver.StopStacks();
}
/** otgUnloadLdd
*/
void COtgRoot::otgUnloadLdd()
{
// code to unload the OTG ldd driver
TInt err (User::FreeLogicalDevice(KOTGDeviceInterfaceDriverName));
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
SetLoaded(EFalse);
}
/** otgQueueOtgEventRequest
*/
void COtgRoot::otgQueueOtgEventRequest(RUsbOtgDriver::TOtgEvent& aEvent, TRequestStatus &aStatus)
{
//LOG_FUNC
LOG_VERBOSE2(_L("Queue an Event Request %08X.\n"), (TInt)(&aStatus));
oUsbOtgDriver.QueueOtgEventRequest(aEvent, aStatus);
}
/** otgCancelOtgEventRequest
*/
void COtgRoot::otgCancelOtgEventRequest()
{
LOG_VERBOSE1(_L("Cancel Event Request.\n"));
oUsbOtgDriver.CancelOtgEventRequest();
}
/** otgQueueOtgMessageRequest
*/
void COtgRoot::otgQueueOtgMessageRequest(RUsbOtgDriver::TOtgMessage& aMessage, TRequestStatus &aStatus)
{
//LOG_FUNC
LOG_VERBOSE2(_L("Queue a Message Request %08X.\n"), (TInt)(&aStatus));
//LOG_VERBOSE1(_L("Queue a Message Request.\n"));
oUsbOtgDriver.QueueOtgMessageRequest(aMessage, aStatus);
}
/** otgCancelOtgMessageRequest
*/
void COtgRoot::otgCancelOtgMessageRequest()
{
LOG_VERBOSE1(_L("Cancel Message Request.\n"));
oUsbOtgDriver.CancelOtgMessageRequest();
}
void COtgRoot::otgQueuePeripheralStateRequest(TUint& aPeripheralState, TRequestStatus& aStatus)
{
LOG_VERBOSE1(_L("Queue Peripheral State Request.\n"));
oUsbcClient.AlternateDeviceStatusNotify(aStatus, aPeripheralState);
}
void COtgRoot::otgCancelPeripheralStateRequest()
{
LOG_VERBOSE1(_L("Cancel Peripheral State Request.\n"));
oUsbcClient.AlternateDeviceStatusNotifyCancel();
}
void COtgRoot::otgQueueAConnectionIdleRequest(RUsbOtgDriver::TOtgConnection& aAConnectionIdle, TRequestStatus& aStatus)
{
LOG_VERBOSE1(_L("Queue A Connection Idle Request.\n"));
oUsbOtgDriver.QueueOtgConnectionNotification(aAConnectionIdle, aStatus);
}
void COtgRoot::otgCancelAConnectionIdleRequest()
{
LOG_VERBOSE1(_L("Cancel A Connection Idle Request.\n"));
oUsbOtgDriver.CancelOtgConnectionNotification();
}
/** otgQueueOtgStateRequest
*/
void COtgRoot::otgQueueOtgStateRequest(RUsbOtgDriver::TOtgState& aState, TRequestStatus &aStatus)
{
//LOG_FUNC
LOG_VERBOSE2(_L("Queue a State Request %08X.\n"), (TInt)(&aStatus));
oUsbOtgDriver.QueueOtgStateRequest(aState, aStatus);
}
/** otgCancelOtgStateRequest
*/
void COtgRoot::otgCancelOtgStateRequest()
{
LOG_VERBOSE1(_L("Cancel State Request.\n"));
oUsbOtgDriver.CancelOtgStateRequest();
}
/** otgBusRequest
raise VBus (in reality this must only happen when a 'A' is present... and when not present it starts HNP)
*/
TInt COtgRoot::otgBusRequest()
{
LOG_FUNC
TInt err(0);
err = oUsbOtgDriver.BusRequest();
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
return(err);
}
/* call when SRP has been recieved, based on our HNP Enable setting, this will allow HNP. The
* A-device may choose to call BusRequest directly, which will result in a 'short-circuit' role-swap.
*/
TInt COtgRoot::otgBusRespondSRP()
{
LOG_FUNC
TInt err(0);
err = oUsbOtgDriver.BusRespondSrp();
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
return(err);
}
/** Drop VBus (A-host)
*/
TInt COtgRoot::otgBusDrop()
{
LOG_FUNC
TInt err(0);
err = oUsbOtgDriver.BusDrop();
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
return(err);
}
/** otgBusClearError
*/
TInt COtgRoot::otgBusClearError()
{
LOG_FUNC
TInt err(0);
err = oUsbOtgDriver.BusClearError();
if (err != KErrNone)
{
LOG_FUNCERROR(err)
}
return(err);
}
void COtgRoot::otgQueueOtgIdPinNotification(RUsbOtgDriver::TOtgIdPin& aPin, TRequestStatus& aStatus)
{
LOG_FUNC
oUsbOtgDriver.QueueOtgIdPinNotification(aPin, aStatus); // the kernel driver populates aPin...
}
void COtgRoot::otgCancelOtgIdPinNotification()
{
LOG_FUNC
oUsbOtgDriver.CancelOtgIdPinNotification();
}
void COtgRoot::otgQueueOtgVbusNotification(RUsbOtgDriver::TOtgVbus& aVbus,
TRequestStatus& aStatus
)
{
LOG_FUNC
oUsbOtgDriver.QueueOtgVbusNotification(aVbus, aStatus);
}
void COtgRoot::otgCancelOtgVbusNotification()
{
LOG_FUNC
oUsbOtgDriver.CancelOtgVbusNotification();
}
TBool COtgRoot::otgIdPinPresent()
{
LOG_FUNC
TRequestStatus aStatus;
RUsbOtgDriver::TOtgIdPin aPin;
oUsbOtgDriver.QueueOtgIdPinNotification(aPin, aStatus); // the kernel driver populates aPin...
LOG_VERBOSE2(_L("(sync) ID_PIN=%d\n"), iOTGIdPin);
oUsbOtgDriver.CancelOtgIdPinNotification();
// swallow the event
User::WaitForRequest(aStatus);
if (RUsbOtgDriver::EIdPinAPlug == aPin) // at this stage, the aPin value is known
{
return(ETrue);
}
return(EFalse);
}
TBool COtgRoot::otgVbusPresent()
{
LOG_FUNC
TRequestStatus aStatus;
RUsbOtgDriver::TOtgVbus aVBus;
oUsbOtgDriver.QueueOtgVbusNotification(aVBus, aStatus); // the kernel driver populates aPin in a kernel thread...
oUsbOtgDriver.CancelOtgVbusNotification();
// swallow the event
User::WaitForRequest(aStatus);
if (RUsbOtgDriver::EVbusHigh == aVBus) // by this stage, the aVBus value is known
{
return(ETrue);
}
return(EFalse);
}
TBool COtgRoot::iLoadedLdd = EFalse;
TBool COtgRoot::iFdfActorActive = EFalse;
RProcess COtgRoot::iFdfActorProcess;
/** static */
TBool& COtgRoot::LddLoaded()
{
return(iLoadedLdd);
}
/** static */
TBool COtgRoot::SetLoaded(TBool aState)
{
iLoadedLdd = aState;
return(LddLoaded());
}
/** static */
void COtgRoot::OtgEventString( RUsbOtgDriver::TOtgEvent aEvent, TBuf<MAX_DSTRLEN> &aDescription)
{
switch( aEvent )
{
case RUsbOtgDriver::EEventAPlugInserted: aDescription= _L("A Plug Inserted");break;
case RUsbOtgDriver::EEventAPlugRemoved: aDescription= _L("A Plug Removed"); break;
case RUsbOtgDriver::EEventVbusRaised: aDescription= _L("VBUS Raised"); break;
case RUsbOtgDriver::EEventVbusDropped: aDescription= _L("VBUS Dropped"); break;
case RUsbOtgDriver::EEventSrpReceived: aDescription= _L("SRP Received"); break;
case RUsbOtgDriver::EEventSrpInitiated: aDescription= _L("SRP Initiated"); break;
case RUsbOtgDriver::EEventHnpEnabled: aDescription= _L("HNP Enabled"); break;
case RUsbOtgDriver::EEventHnpDisabled: aDescription= _L("HNP Disabled"); break;
case RUsbOtgDriver::EEventRoleChangedToHost: aDescription= _L("Role->Host"); break;
case RUsbOtgDriver::EEventRoleChangedToDevice: aDescription= _L("Role->Device"); break;
case RUsbOtgDriver::EEventRoleChangedToIdle: aDescription= _L("Role->Idle"); break;
case RUsbOtgDriver::EEventHnpSupported : aDescription= _L("HNP Supported"); break;
case RUsbOtgDriver::EEventHnpAltSupported: aDescription= _L("Alt-HNP Supp."); break;
case RUsbOtgDriver::EEventBusConnectionBusy: aDescription= _L("Connection Busy"); break;
case RUsbOtgDriver::EEventBusConnectionIdle: aDescription= _L("Connection Idle"); break;
default: aDescription= _L("Unknown"); break;
}
}
/** static */
void COtgRoot::OtgStateString( RUsbOtgDriver::TOtgState aState, TBuf<MAX_DSTRLEN> &aDescription)
{
switch( aState )
{
case RUsbOtgDriver::EStateReset: aDescription= _L("Reset"); break;
case RUsbOtgDriver::EStateAIdle: aDescription= _L("A-Idle"); break;
case RUsbOtgDriver::EStateAHost: aDescription= _L("A-Host"); break;
case RUsbOtgDriver::EStateAPeripheral: aDescription= _L("A-Peripheral"); break;
case RUsbOtgDriver::EStateAVbusError: aDescription= _L("A-VBus Error"); break;
case RUsbOtgDriver::EStateBIdle: aDescription= _L("B-Idle"); break;
case RUsbOtgDriver::EStateBPeripheral: aDescription= _L("B-Peripheral"); break;
case RUsbOtgDriver::EStateBHost: aDescription= _L("B-Host"); break;
default: aDescription= _L("Unknown"); break;
}
}
/** static */
void COtgRoot::OtgMessageString( RUsbOtgDriver::TOtgMessage aMessage, TBuf<MAX_DSTRLEN> &aDescription)
{
switch( aMessage )
{
case RUsbOtgDriver::EEventQueueOverflow: aDescription = _L("Event Queue Overflow"); break;
case RUsbOtgDriver::EStateQueueOverflow: aDescription = _L("State Queue Overflow"); break;
case RUsbOtgDriver::EMessageQueueOverflow: aDescription = _L("Message Queue Overflow"); break;
case RUsbOtgDriver::EMessageBadState: aDescription = _L("Bad State"); break;
case RUsbOtgDriver::EMessageStackNotStarted: aDescription = _L("Stack Not Started"); break;
case RUsbOtgDriver::EMessageVbusAlreadyRaised: aDescription = _L("Vbus Already Raised"); break;
case RUsbOtgDriver::EMessageSrpForbidden: aDescription = _L("SRP Forbidden"); break;
case RUsbOtgDriver::EMessageBusControlProblem: aDescription = _L("Bus Control Problem"); break;
case RUsbOtgDriver::EMessageVbusError: aDescription = _L("Vbus Error"); break;
case RUsbOtgDriver::EMessageSrpTimeout: aDescription = _L("SRP Timeout"); break;
case RUsbOtgDriver::EMessageSrpActive: aDescription = _L("SRP In Use"); break;
// PREQ 1305 messages
case RUsbOtgDriver::EMessageSrpNotPermitted: aDescription = _L("Srp Not Permitted"); break;
case RUsbOtgDriver::EMessageHnpNotPermitted: aDescription = _L("Hnp Not Permitted"); break;
case RUsbOtgDriver::EMessageHnpNotEnabled: aDescription = _L("Hnp Not Enabled"); break;
case RUsbOtgDriver::EMessageHnpNotSuspended: aDescription = _L("HNP not possible, not suspended"); break;
case RUsbOtgDriver::EMessageVbusPowerUpNotPermitted: aDescription = _L("Vbus PowerUp Not Permitted"); break;
case RUsbOtgDriver::EMessageVbusPowerUpError: aDescription = _L("Vbus PowerUp Error"); break;
case RUsbOtgDriver::EMessageVbusPowerDownNotPermitted: aDescription = _L("Vbus PowerDown Not Permitted"); break;
case RUsbOtgDriver::EMessageVbusClearErrorNotPermitted: aDescription = _L("Vbus ClearError Not Permitted"); break;
case RUsbOtgDriver::EMessageHnpNotResponding: aDescription = _L("Not reposnding to HNP");
case RUsbOtgDriver::EMessageHnpBusDrop: aDescription = _L("VBUS drop during HNP");
default: aDescription = _L("Unknown"); break;
}
}
void COtgRoot::PeripheralStateString( TUint aPeripheralState, TBuf<MAX_DSTRLEN> &aDescription)
{
if(aPeripheralState & KUsbAlternateSetting)
{
aDescription = _L("Interface Alternate Setting Change");
}
else
{
switch( aPeripheralState )
{
case EUsbcDeviceStateUndefined: aDescription = _L("Undefined"); break;
case EUsbcDeviceStateAttached: aDescription = _L("Attached"); break;
case EUsbcDeviceStatePowered: aDescription = _L("Powered"); break;
case EUsbcDeviceStateDefault: aDescription = _L("Default"); break;
case EUsbcDeviceStateAddress: aDescription = _L("Addressed"); break;
case EUsbcDeviceStateConfigured: aDescription = _L("Configured"); break;
case EUsbcDeviceStateSuspended: aDescription = _L("Suspended"); break;
case EUsbcNoState: aDescription = _L("NoState!"); break;
default: aDescription = _L("Unknown"); break;
}
}
}
void COtgRoot::AConnectionIdleString(RUsbOtgDriver::TOtgConnection aAConnectionIdle, TBuf<MAX_DSTRLEN> &aDescription)
{
switch( aAConnectionIdle )
{
case RUsbOtgDriver::EConnectionBusy: aDescription = _L("Busy"); break;
case RUsbOtgDriver::EConnectionIdle: aDescription = _L("Idle"); break;
case RUsbOtgDriver::EConnectionUnknown: aDescription = _L("Unknown"); break;
default: aDescription = _L("Not recognised");break;
}
}
TInt COtgRoot::otgActivateFdfActor()
{
if(iFdfActorActive)
{
RDebug::Print(_L("FdfActor already exists!"));
return KErrAlreadyExists;
}
const TUid KFdfSvrUid={0x10282B48};
const TUidType fdfActorUid(KNullUid, KNullUid, KFdfSvrUid);
RDebug::Print(_L("About to activate FDF Actor"));
// RProcess fdfActorProcess;
TInt err = iFdfActorProcess.Create(_L("t_otgdi_fdfactor.exe"), KNullDesC, fdfActorUid);
if (err != KErrNone)
{
RDebug::Print(_L("Failed to create FDF Actor, err=%d"),err);
iFdfActorProcess.Close();
return err;
}
TRequestStatus stat;
iFdfActorProcess.Rendezvous(stat);
if (stat!=KRequestPending)
{
RDebug::Print(_L("Failed to commence rendezvous, err=%d"),stat.Int());
iFdfActorProcess.Kill(0); // abort startup
iFdfActorProcess.Close();
return stat.Int();
}
else
{
iFdfActorProcess.Resume(); // logon OK - start the server
}
User::WaitForRequest(stat); // wait for start or death
if(stat.Int()!=KErrNone)
{
// Wasn't KErrNone, which means that the FDFActor didn't successfully
// start up. We shouldn't proceed with the test we're in.
RDebug::Print(_L("Failed to activate FDF Actor, err=%d"),stat.Int());
iFdfActorProcess.Close();
return stat.Int();
}
// We rendezvoused(?) with the FDFActor OK, so it is going to suspend
// any devices it sees being attached, and will shut itself down
// when this process signals its Rendezvous (at the end of the test)...
RDebug::Print(_L("Activated FDF Actor"));
iFdfActorActive = ETrue;
return KErrNone;
}
void COtgRoot::otgDeactivateFdfActor()
{
if(!iFdfActorActive)
{
RDebug::Print(_L("FdfActor is not running!"));
return;
}
// If iFdfActorActive is set, the FDF Actor should be waiting to
// rendezvous with us before it shuts down...
// First of all, logon to wait for it to close down properly
TRequestStatus waitForCloseStat;
iFdfActorProcess.Logon(waitForCloseStat);
// Now, trigger the FDF Actor to close down
RProcess::Rendezvous(KErrNone);
// ...and wait for it to go away.
User::WaitForRequest(waitForCloseStat);
test.Printf(_L("T_OTGDI confirms FDF Actor has gone away %d\n"), waitForCloseStat.Int());
// Now close our handle, and record that the process is no more...
iFdfActorProcess.Close();
iFdfActorActive = EFalse;
}
/** Commonly used step to unload the USB Client Driver
* @return ETrue if the ldd unloaded sucessfully
*/
TBool COtgRoot::StepUnloadClient()
{
test.Printf(_L("Unload USBCC Client\n"));
TInt err;
// Close the Client
test.Printf(_L("..Close\n"));
oUsbcClient.Close();
// Unload the LDD - note the name is *not* the same as for loading
test.Printf(_L("..Unload\n"));
err = User::FreeLogicalDevice( KUsbDeviceName );
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client Unload Fail "), err);
return (EFalse);
}
return(ETrue);
}
/** Commonly used step to load the USB Client Driver and set up
* a 'useful' default device descriptor set
* @return ETrue if the ldd loaded sucessfully
*/
TBool COtgRoot::StepLoadClient(TUint16 aPID,
TBool aEnableHNP/*=ETrue*/,
TBool aEnableSRP/*=ETrue*/)
{
test.Printf(_L("Load USBCC Client 0x%04x\n"),aPID);
TInt err;
// The incoming PID is expected to have a form of 0x0TTT or 0xFTTT
// where 'TTT' is the test number: if the lead is 0xF000 we now
// overlay an 'A' or a 'B' depending on the default role
if ( ( ( aPID & 0xF000 ) != 0xF000 )
&& ( ( aPID & 0xF000 ) != 0x0000 )
)
{
AssertionFailed(KErrAbort, _L("Bad default PID"));
}
if ( aPID & 0xF000 )
{
aPID &= 0x0FFF;
if ( gTestRoleMaster )
{
// this is the 'B' device
aPID |= 0xB000;
}
else
{
// this is the 'A' device
aPID |= 0xA000;
}
}
// Load the LDD - note the name is *not* the same as for unload
test.Printf(_L("..Load LDD\n"));
err = User::LoadLogicalDevice( KUsbcLddFileName );
if ((err != KErrNone) && (err !=KErrAlreadyExists))
{
AssertionFailed2(KErrAbort, _L("Client Load Fail "), err);
return (EFalse);
}
// Open the Client
test.Printf(_L("..Open LDD\n"));
err = oUsbcClient.Open(0);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client Open Fail "), err);
return (EFalse);
}
// Set up descriptors
test.Printf(_L("..Setup Descriptors\n"));
// the OTG descriptor
TBuf8<KUsbDescSize_Otg> theOtgDescriptor;
err = oUsbcClient.GetOtgDescriptor(theOtgDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("OTG GetDes Fail "), err);
return (EFalse);
}
// modify OTG descriptor based on parameters passed
if (aEnableHNP)
aEnableSRP=ETrue; // Keep the device Legal according to OTG spec 6.4.2
/*Attribute Fields
D7…2: Reserved (reset to zero)
D1: HNP support
D0: SRP support*/
TUint8 aByte = theOtgDescriptor[2];
aByte &= (~0x03);
aByte |= (aEnableSRP? 1 : 0);
aByte |= (aEnableHNP? 2 : 0);
test.Printf(_L("..Change OTG 0x%02X->0x%02X\n"), theOtgDescriptor[2], aByte);
theOtgDescriptor[2] = aByte;
err = oUsbcClient.SetOtgDescriptor(theOtgDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("OTG SetDes Fail "), err);
return (EFalse);
}
//
TUsbDeviceCaps d_caps;
err = oUsbcClient.DeviceCaps(d_caps);
TBool softwareConnect;
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client DevCaps Fail "), err);
return (EFalse);
}
const TInt n = d_caps().iTotalEndpoints;
softwareConnect = d_caps().iConnect;
test.Printf(_L("..SoftwareConnect = %d\n"),softwareConnect);
if (n < 2)
{
AssertionFailed2(KErrAbort, _L("Client Endpoints Fail "), err);
return (EFalse);
}
// Endpoints
TUsbcEndpointData data[KUsbcMaxEndpoints];
TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
err = oUsbcClient.EndpointCaps(dataptr);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client EpCaps Fail "), err);
return (EFalse);
}
// Set up the active interface
TUsbcInterfaceInfoBuf ifc;
TInt ep_found = 0;
TBool foundBulkIN = EFalse;
TBool foundBulkOUT = EFalse;
for (TInt i = 0; i < n; i++)
{
const TUsbcEndpointCaps* const caps = &data[i].iCaps;
const TInt mps = caps->MaxPacketSize();
if (!foundBulkIN &&
(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) ==
(KUsbEpTypeBulk | KUsbEpDirIn))
{
if (!(mps == 64 || mps == 512))
{
}
// EEndpoint1 is going to be our Tx (IN) endpoint
ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
ifc().iEndpointData[0].iDir = KUsbEpDirIn;
ifc().iEndpointData[0].iSize = mps;
foundBulkIN = ETrue;
if (++ep_found == 2)
break;
}
else if (!foundBulkOUT &&
(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) ==
(KUsbEpTypeBulk | KUsbEpDirOut))
{
if (!(mps == 64 || mps == 512))
{
}
// EEndpoint2 is going to be our Rx (OUT) endpoint
ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
ifc().iEndpointData[1].iDir = KUsbEpDirOut;
ifc().iEndpointData[1].iSize = mps;
foundBulkOUT = ETrue;
if (++ep_found == 2)
break;
}
}
if (ep_found != 2)
{
AssertionFailed2(KErrAbort, _L("Client EpFound Fail "), err);
return (EFalse);
}
_LIT16(ifcname, "T_OTGDI Test Interface (Default Setting 0)");
ifc().iString = const_cast<TDesC16*>(&ifcname);
ifc().iTotalEndpointsUsed = 2;
ifc().iClass.iClassNum = 0xff; // vendor-specific
ifc().iClass.iSubClassNum = 0xff; // vendor-specific
ifc().iClass.iProtocolNum = 0xff; // vendor-specific
err = oUsbcClient.SetInterface(0, ifc, (EUsbcBandwidthOUTDefault | EUsbcBandwidthINDefault));
if( err != KErrNone )
{
AssertionFailed2(KErrAbort, _L("Client SetInt Fail "), err);
return (EFalse);
}
// Set the revised PID
TBuf8<KUsbDescSize_Device> theDeviceDescriptor;
err = oUsbcClient.GetDeviceDescriptor(theDeviceDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client GetDes Fail "), err);
return (EFalse);
}
TUint16 oldPID = ( theDeviceDescriptor[10] )
+ ( theDeviceDescriptor[11] << 8 );
theDeviceDescriptor[10] = ( aPID & 0x00FF );
theDeviceDescriptor[11] = ( aPID & 0xFF00 ) >> 8;
test.Printf(_L("..Change PID 0x%04X->0x%04X\n"), oldPID, aPID);
err = oUsbcClient.SetDeviceDescriptor(theDeviceDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client SetDes Fail "), err);
return (EFalse);
}
// Power Up UDC - KErrNotReady is expected
test.Printf(_L("..Power Up UDC\n"));
err = oUsbcClient.PowerUpUdc();
if( err != KErrNotReady )
{
AssertionFailed2(KErrAbort, _L("PowerUp UDC Fail "), err);
return (EFalse);
}
// Connect to Host
test.Printf(_L("..Connect to Host\n"));
err = oUsbcClient.DeviceConnectToHost();
if( err != KErrNone )
{
AssertionFailed2(KErrAbort, _L("Host Connect Fail "), err);
return (EFalse);
}
// Default no-problem return
return(ETrue);
}
/** Commonly used steps to control D+ connect/disconnect
* the device to/from the host
*/
TBool COtgRoot::StepDisconnect()
{
test.Printf(_L("Disconnect from Host\n"));
TInt err;
err = oUsbcClient.DeviceDisconnectFromHost();
if( err != KErrNone )
{
AssertionFailed2(KErrAbort, _L("Host Disconnect Fail "), err);
return (EFalse);
}
// Default no-problem return
return(ETrue);
}
TBool COtgRoot::StepConnect()
{
test.Printf(_L("Connect to Host\n"));
TInt err;
err = oUsbcClient.DeviceConnectToHost();
if( err != KErrNone )
{
AssertionFailed2(KErrAbort, _L("Host Connect Fail "), err);
return (EFalse);
}
// Default no-problem return
return(ETrue);
}
/** Commonly used step to load the USB Client Driver and set up
* a High-Speed electrical test VID/PID pair
* @return ETrue if the ldd loaded sucessfully
*/
TBool COtgRoot::StepChangeVidPid(TUint16 aVID, TUint16 aPID)
{
test.Printf(_L("Load USBCC HS Test Client 0x%04x/0x%04x\n"),aVID,aPID);
TInt err;
// Set the revised VID/PID pair
TBuf8<KUsbDescSize_Device> theDeviceDescriptor;
err = oUsbcClient.GetDeviceDescriptor(theDeviceDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client GetDes Fail "), err);
return (EFalse);
}
TUint16 oldVID = ( theDeviceDescriptor[8] )
+ ( theDeviceDescriptor[9] << 8 );
theDeviceDescriptor[8] = ( aVID & 0x00FF );
theDeviceDescriptor[9] = ( aVID & 0xFF00 ) >> 8;
test.Printf(_L("..Change VID 0x%04X->0x%04X\n"), oldVID, aVID);
TUint16 oldPID = ( theDeviceDescriptor[10] )
+ ( theDeviceDescriptor[11] << 8 );
theDeviceDescriptor[10] = ( aPID & 0x00FF );
theDeviceDescriptor[11] = ( aPID & 0xFF00 ) >> 8;
test.Printf(_L("..Change PID 0x%04X->0x%04X\n"), oldPID, aPID);
err = oUsbcClient.SetDeviceDescriptor(theDeviceDescriptor);
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Client SetDes Fail "), err);
return (EFalse);
}
// Default no-problem return
return(ETrue);
}
/** Commonly used step to set a flag that will cause the
OPT test mode to be activated when the stacks are
started
*/
void COtgRoot::StepSetOptActive()
{
iOptActive = ETrue;
}
/** Commonly used step to unload the ldd and shut it down
*@return ETrue if the ldd unloaded sucessfully
*/
TBool COtgRoot::StepUnloadLDD()
{
test.Printf(_L("Unload otg LDD (implicit Stop() + Close()) \n"));
LOG_VERBOSE1(_L(" Stop OTG+Host Stack\n"));
otgStopStacks();
otgClose();
LOG_VERBOSE1(_L(" Unload\n"));
otgUnloadLdd();
iOptActive = EFalse; // retain the OTGDI behavour to clears this flag when client shuts
if (LddLoaded())
return(EFalse);
return(ETrue);
}
/** StepLoadLDD - utility method : load the LDD, open it and init the stacks
a commonly used test step */
TBool COtgRoot::StepLoadLDD()
{
TInt err;
LOG_VERBOSE1(_L("Load otg LDD\n"));
err = otgLoadLdd();
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Loading LDD failed "), err);
return (EFalse);
}
LOG_VERBOSE1(_L("Open the LDD session\n"));
err = otgOpen();
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Open LDD session failed "), err);
return (EFalse);
}
if ( iOptActive )
{
test.Printf(_L("Activate OPT Test Mode\n"));
err = otgActivateOptTestMode();
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("OPT Activate failed "), err);
return (EFalse);
}
}
test.Printf(_L("Start OTG+Host Stack\n"));
err = otgStartStacks();
if (err != KErrNone)
{
AssertionFailed2(KErrAbort, _L("Start stack failed "), err);
return (EFalse);
}
// DS - Temporarily adding .1 second delay in here to beat the race
// condition to be fixed as part of third part USB HOST/OTG stack issue 60761
User::After(100000);
return(ETrue);
}
void COtgRoot::SetMaxPowerToL(TUint16 aVal)
{
TBuf8<KUsbDescSize_Config> buf;
oUsbcClient.GetConfigurationDescriptor(buf);
aVal %= 500;
buf[8] = (TUint8)(aVal / 2);
oUsbcClient.SetConfigurationDescriptor(buf);
}
void COtgRoot::GetMaxPower(TUint16& aVal)
{
TBuf8<KUsbDescSize_Config> buf;
oUsbcClient.GetConfigurationDescriptor(buf);
aVal = buf[8] * 2;
}