kerneltest/f32test/shostmassstorage/testclient/usbtestmsclient/transport/botcontrolinterface.cpp
author hgs
Tue, 02 Nov 2010 15:29:23 +0000
changeset 300 1d28c8722707
parent 0 a41df078684a
permissions -rw-r--r--
201043_09

// Copyright (c) 2009-2010 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:
//



/**
 @file
 @internalTechnology
*/

#include <e32base.h>
#include <d32usbc.h>

#include "mstypes.h"
#include "msctypes.h"
#include "usbmsclientpanic.h"
#include "botmsctypes.h"
#include "testman.h"
#include "botmscserver.h"
#include "mdevicetransport.h"
#include "mserverprotocol.h"
#include "cbulkonlytransport.h"

#include "cusbmassstoragecontroller.h"
#include "botcontrolinterface.h"
#include "debug.h"

TTestConfig::TTestConfig()
:   iTestMode(ENone)
    {
    }


////////////////////////////////////
/**
Called by CBulkOnlyTransport to create an instance of CControlInterface

@param aParent reference to the CBulkOnlyTransport
*/
CBotControlInterface* CBotControlInterface::NewL(CBulkOnlyTransport& aParent)
    {
    CBotControlInterface* self = new(ELeave) CBotControlInterface(aParent);
    CleanupStack::PushL(self);
    self->ConstructL();
    CActiveScheduler::Add(self);
    CleanupStack::Pop();
    return self;
    }


void CBotControlInterface::ConstructL()
    {
    }


/**
c'tor

@param aParent reference to the CBulkOnlyTransport
*/
CBotControlInterface::CBotControlInterface(CBulkOnlyTransport& aParent):
    CActive(EPriorityStandard),
    iParent(aParent),
    iCurrentState(ENone)
    {
    }


/**
d'tor
*/
CBotControlInterface::~CBotControlInterface()
    {
    Cancel();
    }


/**
Called by  CBulkOnlyTransportStart to start control interface
*/
TInt CBotControlInterface::Start()
    {
    if (IsActive())
        {
        __PRINT(_L("Still active\n"));
        return KErrServerBusy;
        }
    ReadEp0Data();
    return KErrNone;
    }


/**
Called by CBulkOnlyTransportStart to stop control interface
*/
void CBotControlInterface::Stop()
    {
    if (!IsActive())
        {
        __PRINT(_L("Not active\n"));
        return;
        }

    __PRINT(_L("\nStopping...\n"));
    iCurrentState = ENone;
    Cancel();
    }


/**
Cancel outstanding request (if any)
*/
void CBotControlInterface::DoCancel()
    {
    switch(iCurrentState)
        {
        case EReadEp0Data:
            iParent.Ldd().ReadCancel(EEndpoint0);
            break;
        case ESendMaxLun:
            iParent.Ldd().WriteCancel(EEndpoint0);
            break;
        default:
            __PRINT(_L("\nWrong state !\n"));
            __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState));
        }
    }


/**
Implement CBotControlInterface state machine
*/
void CBotControlInterface::RunL()
    {
    if (iStatus != KErrNone)
        {
        __PRINT1(_L("Error %d in RunL\n"), iStatus.Int());

        //read EP0  again
        ReadEp0Data();
        return;
        }

    switch (iCurrentState)
        {
    case ESendMaxLun:
        ReadEp0Data();
        break;

    case EReadEp0Data:
        DecodeEp0Data();
        break;

    default:
        __PRINT(_L("  error: (Shouldn't end up here...)\n"));
        __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState));
        break;
        }
    }


/**
Post a read request to EEndpoint0 to read request header
*/
void CBotControlInterface::ReadEp0Data()
    {
    iParent.Ldd().Read(iStatus, EEndpoint0, iData, KRequestHdrSize);
    iCurrentState = EReadEp0Data;
    SetActive();
    }


/**
Decode request header and do appropriate action - get max LUN info or post a reset request
*/
void CBotControlInterface::DecodeEp0Data()
    {
    TInt err = iRequestHeader.Decode(iData);
    if (err != KErrNone)
        return;

    switch(iRequestHeader.iRequest)
        {
    //
    // GET MAX LUN (0xFE)
    //
    case TBotFunctionReqCb::EReqGetMaxLun:
        {
        __PRINT1(_L("DecodeEp0Data : 'Get Max LUN' Request MaxLun = %d"),iParent.MaxLun());

        if (   iRequestHeader.iRequestType != 0xA1 //value from USB MS BOT spec
            || iRequestHeader.iIndex > 15
            || iRequestHeader.iValue != 0
            || iRequestHeader.iLength != 1)
            {
            __PRINT(_L("GetMaxLun command packet check error"));
            iParent.Ldd().EndpointZeroRequestError();
            ReadEp0Data();  //try to get another request
            }
        else
            {
            iData.FillZ(1);  //Return only 1 byte to host
            iData[0] = static_cast<TUint8>(iParent.MaxLun());   // Supported Units
            iParent.Ldd().Write(iStatus, EEndpoint0, iData, 1);

            iCurrentState = ESendMaxLun;
            SetActive();
            }
        }
        break;
    //
    // RESET (0xFF)
    //
    case TBotFunctionReqCb::EReqReset:
        {
        __PRINT(_L("DecodeEp0Data : 'Mass Storage Reset' Request"));
        __TESTMODEPRINT("------- BOT RESET ------");

        if (   iRequestHeader.iRequestType != 0x21 //value from USB MS BOT spec
            || iRequestHeader.iIndex > 15
            || iRequestHeader.iValue != 0
            || iRequestHeader.iLength != 0)
            {
            __PRINT(_L("MSC Reset command packet check error"));
            iParent.Ldd().EndpointZeroRequestError();
            ReadEp0Data();  //try to get another request
            }
        else
            {
            iParent.HwStop();
            iParent.Controller().Reset();
            iParent.HwStart(ETrue);
            iParent.Ldd().SendEp0StatusPacket();
            }
        }
        break;
    //
    // Unknown?
    //
    default:
        __PRINT(_L("DecodeEp0Data : Unknown Request"));
        ReadEp0Data();  //try to get another request
        break;
        }
    }