sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_gml_tur_protocol.h" sl@0: #include "t_gml_tur_controller.h" sl@0: #include "cbulkonlytransport.h" sl@0: sl@0: LOCAL_D RTest test(_L("t_gml_tur")); sl@0: sl@0: _LIT(KDriverFileName,"TESTUSBC.LDD"); sl@0: _LIT(KLddName,"usbc"); sl@0: _LIT(KTransportThreadName,"TransportThread"); sl@0: _LIT(KTransportSemName,"TransportThreadSem"); sl@0: sl@0: LOCAL_D const TInt KFiveDrives = 5; sl@0: LOCAL_D const TEndpointNumber KOutEp = EEndpoint1; sl@0: sl@0: GLDEF_D CUsbMassStorageController* gController = NULL; sl@0: sl@0: LOCAL_C void SetCBWHeader(TDes8& cbwData, TInt32 aDataTransferLength, TBool aDataIn, TUint8 aLun, TUint8 aCBLength) sl@0: { sl@0: //dCBWSignature sl@0: cbwData[0] = 0x55; sl@0: cbwData[1] = 0x53; sl@0: cbwData[2] = 0x42; sl@0: cbwData[3] = 0x43; sl@0: //dCBWTag sl@0: cbwData[4] = 0x01; sl@0: cbwData[5] = 0x00; sl@0: cbwData[6] = 0x00; sl@0: cbwData[7] = 0x00; sl@0: //dCBWDataTransferLength sl@0: cbwData[8] = TUint8((aDataTransferLength & 0x000000FF)); sl@0: cbwData[9] = TUint8((aDataTransferLength & 0x0000FF00) >> 8); sl@0: cbwData[10] = TUint8((aDataTransferLength & 0x00FF0000) >> 16); sl@0: cbwData[11] = TUint8((aDataTransferLength & 0xFF000000) >> 24); sl@0: //bmCBWFlags sl@0: if (aDataIn) sl@0: { sl@0: cbwData[12] = 0x80; sl@0: } sl@0: else sl@0: { sl@0: cbwData[12] = 0x00; sl@0: } sl@0: //bCBWLUN sl@0: cbwData[13] = aLun; sl@0: //bCBWCBLength sl@0: cbwData[14] = aCBLength; sl@0: } sl@0: sl@0: LOCAL_C TInt TransportThreadEntry(TAny* aPtr) sl@0: { sl@0: TInt err = KErrNone; sl@0: TInt numDrives = KFiveDrives; sl@0: sl@0: //Create and install cleanup trap and active scheduler sl@0: CTrapCleanup* cleanup = CTrapCleanup::New(); sl@0: if (cleanup == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: sl@0: CActiveScheduler* sched = new CActiveScheduler; sl@0: if (sched == NULL) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: CActiveScheduler::Install(sched); sl@0: sl@0: //Start transport sl@0: CScsiProtocol* protocol = NULL; sl@0: TRAP(err, protocol = CScsiProtocol::NewL()); sl@0: if (err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: sl@0: CUsbMassStorageController* controller = (CUsbMassStorageController*)aPtr; sl@0: gController = controller; sl@0: controller->CreateL(0); sl@0: sl@0: CBulkOnlyTransport* transport = NULL; sl@0: TRAP(err, transport = CBulkOnlyTransport::NewL(numDrives, *controller)); sl@0: if (err != KErrNone) sl@0: { sl@0: return err; sl@0: } sl@0: sl@0: controller->SetTransport(transport); sl@0: TRAP(err, transport->InitialiseTransportL(1)); sl@0: sl@0: transport->RegisterProtocol(*protocol); sl@0: transport->Start(); sl@0: sl@0: //Synchronize with test thread sl@0: RSemaphore gSemThreadReady; sl@0: gSemThreadReady.OpenGlobal(KTransportSemName); sl@0: gSemThreadReady.Signal(); sl@0: gSemThreadReady.Close(); sl@0: sl@0: CActiveScheduler::Start(); sl@0: sl@0: delete transport; sl@0: delete controller; sl@0: delete protocol; sl@0: delete sched; sl@0: delete cleanup; sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: test.Title(); sl@0: sl@0: TInt err; sl@0: sl@0: test.Start(_L("Loading ldd")); sl@0: err = User::LoadLogicalDevice(KDriverFileName); sl@0: test(err == KErrNone || err == KErrAlreadyExists); sl@0: sl@0: RDevTestUsbcClient ldd; sl@0: err = ldd.Open(0); sl@0: test(err == KErrNone); sl@0: sl@0: //ldd.ResetEndpoints(); sl@0: sl@0: RSemaphore gSemThreadReady; sl@0: err = gSemThreadReady.CreateGlobal(KTransportSemName, 0); sl@0: sl@0: CUsbMassStorageController* controller = new CUsbMassStorageController(); sl@0: test(controller != NULL); sl@0: sl@0: //Start transport thread. sl@0: RThread transportThread; sl@0: test.Next(_L("Creating transport thread, Max Lun = 4")); sl@0: err = transportThread.Create(KTransportThreadName, TransportThreadEntry, KDefaultStackSize, NULL, (void*)controller); sl@0: test(err == KErrNone); sl@0: transportThread.Resume(); sl@0: sl@0: //Synchronize with transport thread. sl@0: gSemThreadReady.Wait(); sl@0: gSemThreadReady.Close(); sl@0: test(gController != NULL); sl@0: sl@0: TRequestStatus status; sl@0: sl@0: test.Next(_L("Writing GetMaxLun request to endpoint 0")); sl@0: //Write GetMaxLun request to endpoint 0 sl@0: TBuf8 controlData; sl@0: controlData.SetLength(KRequestHdrSize); sl@0: controlData.FillZ(); sl@0: controlData[0] = 0xA1; sl@0: controlData[1] = 0xFE; sl@0: controlData[6] = 0x01; sl@0: ldd.HostWrite(status, EEndpoint0, controlData, KRequestHdrSize); sl@0: sl@0: User::WaitForRequest(status); sl@0: test.Printf(_L("status = %d"), status.Int()); sl@0: test(status.Int() == KErrNone); sl@0: sl@0: //Read request response sl@0: controlData.SetLength(1); sl@0: ldd.HostRead(status, EEndpoint0, controlData, 1); sl@0: sl@0: User::WaitForRequest(status); sl@0: test(status.Int() == KErrNone); sl@0: sl@0: test.Printf(_L("Max LUN: %d\n"), controlData[0]); sl@0: test(controlData[0] == KFiveDrives - 1); sl@0: sl@0: //Send TEST UNIT READY command sl@0: TBuf8 cbwData; sl@0: cbwData.SetLength(KCbwLength); sl@0: cbwData.FillZ(); sl@0: SetCBWHeader(cbwData, 6, ETrue, 0, 6); sl@0: ldd.HostWrite(status, KOutEp, cbwData, KCbwLength); sl@0: User::WaitForRequest(status); sl@0: test(status.Int() == KErrNone); sl@0: sl@0: test.Next(_L("Writing Reset request to endpoint 0")); sl@0: //Write Reset request to endpoint 0 sl@0: controlData.SetLength(KRequestHdrSize); sl@0: controlData.FillZ(); sl@0: controlData[0] = 0x21; sl@0: controlData[1] = 0xFF; sl@0: ldd.HostWrite(status, EEndpoint0, controlData, KRequestHdrSize); sl@0: sl@0: User::WaitForRequest(status); sl@0: test(status.Int() == KErrNone); sl@0: sl@0: User::After(3000000); //3 seconds sl@0: test(gController->IsReset()); sl@0: test.Printf(_L("Controller got reset request\n")); sl@0: sl@0: TRequestStatus logonStatus; sl@0: transportThread.Logon(logonStatus); sl@0: TRequestStatus* statusPtr = &(controller->iStatus); sl@0: transportThread.RequestComplete(statusPtr, KErrNone); sl@0: //Wait for thread to die sl@0: test.Printf(_L("Waiting for controller thread to die\n")); sl@0: User::WaitForRequest(logonStatus); sl@0: transportThread.Close(); sl@0: test.Printf(_L("The thread is dead, long live the thread\n")); sl@0: sl@0: ldd.Close(); sl@0: sl@0: test.Printf(_L("Unloading ldd")); sl@0: err = User::FreeLogicalDevice(KLddName); sl@0: test(err == KErrNone); sl@0: sl@0: test.End(); sl@0: sl@0: return 0; sl@0: }