diff -r f92a4f87e424 -r 012cc2ee6408 usbmgmt/usbmgr/device/classdrivers/ncm/classimplementation/ncmpktdrv/pktdrv/src/ncmcommunicationinterface.cpp --- a/usbmgmt/usbmgr/device/classdrivers/ncm/classimplementation/ncmpktdrv/pktdrv/src/ncmcommunicationinterface.cpp Tue Aug 31 17:01:47 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,522 +0,0 @@ -/* -* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies). -* All rights reserved. -* This component and the accompanying materials are made available -* under the terms of "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: -* implementation of NCM communication interface class -* -*/ - - -#include -#include "ncmcommunicationinterface.h" -#include "ncmnotificationdescriptor.h" -#include "OstTraceDefinitions.h" -#ifdef OST_TRACE_COMPILER_IN_USE -#include "ncmcommunicationinterfaceTraces.h" -#endif - - - -const TUint KUsbRequestLengthIdx = 6; -const TUint KUsbRequestTypeIdx = 1; -const TInt KIntEndpoint = 1; -const TInt KNotificationRequestType = 0xA1; - - -#if defined(_DEBUG) -_LIT(KNcmCommInterfacePanic, "UsbNcmComm"); // must be <=16 chars -#endif - - -// Panic codes -enum TNcmCommPanicCode - { - ENcmCommWrongSetupLength = 1, - ENcmCommWrongDataLength, - ENcmCommWriteError, - ENcmCMEndMark - }; - - -// ======== MEMBER FUNCTIONS ======== -// - -CNcmCommunicationInterface::CNcmCommunicationInterface(MNcmControlObserver& aEngine, RDevUsbcScClient& aLdd) : CActive(CActive::EPriorityHigh), - iEngine(aEngine), iPort(aLdd) - { - CActiveScheduler::Add(this); - } - -void CNcmCommunicationInterface::ConstructL() - { - iSenderAndReceiver = CNcmCommInterfaceSenderAndReceiver::NewL(iPort, *this); - } - -CNcmCommunicationInterface* CNcmCommunicationInterface::NewL(MNcmControlObserver& aEngine, RDevUsbcScClient& aLdd) - { - OstTraceFunctionEntry0( CNCMCOMMUNICATIONINTERFACE_NEWL_ENTRY ); - CNcmCommunicationInterface *self=new (ELeave) CNcmCommunicationInterface(aEngine, aLdd); - CleanupStack::PushL(self); - self->ConstructL(); - CleanupStack::Pop(); - OstTraceFunctionExit0( CNCMCOMMUNICATIONINTERFACE_NEWL_EXIT ); - return self; - } - -CNcmCommunicationInterface::~CNcmCommunicationInterface() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_CNCMCOMMUNICATIONINTERFACE_ENTRY, this ); - - Cancel(); - delete iSenderAndReceiver; - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_CNCMCOMMUNICATIONINTERFACE_EXIT, this ); - } - -// -//Start the control channel of NCM -// -TInt CNcmCommunicationInterface::Start() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_START_ENTRY, this ); - if (iStarted) - { - OstTrace0( TRACE_WARNING, CNCMCOMMUNICATIONINTERFACE_START, "CNcmCommunicationInterface, already started!" ); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_START_EXIT, this ); - return KErrInUse; - } - - TInt ret = GetInterfaceNumber(); - if (ret != KErrNone) - { - OstTrace1( TRACE_FATAL, CNCMCOMMUNICATIONINTERFACE_START1, "GetInterfaceNumber failed ret=%d", ret); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_START_EXIT_DUP1, this ); - return ret; - } - - iStarted = ETrue; - iRWState = EStateInitial; - - iSenderAndReceiver->Start(); - - //force a call to RunL - SetActive(); - TRequestStatus* status=&iStatus; - User::RequestComplete(status, KErrNone); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_START_EXIT_DUP2, this ); - return KErrNone; - } - -// -//Listen on the ep0 to receive the NCM control message from host -// -void CNcmCommunicationInterface::ReadSetup() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_READSETUP_ENTRY, this ); - iRWState = EStateReadSetup; - iRequestType = 0; - iDataStageLength = 0; - TInt ret = iSenderAndReceiver->Read(iStatus, iSetupPacket, KSetupPacketLength); - - if (ret != KErrNone) - { - OstTrace1( TRACE_FATAL, CNCMCOMMUNICATIONINTERFACE_READSETUP, "read setup packet error %d", ret); - ControlMsgError(EInternalError); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_READSETUP_EXIT, this ); - return; - } - SetActive(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_READSETUP_EXIT_DUP1, this ); - } - - -// -//decode the setup packet to get command information. -// -void CNcmCommunicationInterface::DecodeSetup() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_DECODESETUP_ENTRY, this ); - - __ASSERT_DEBUG(iSetupPacket.Length()==KSetupPacketLength, - User::Panic(KNcmCommInterfacePanic, ENcmCommWrongSetupLength)); - - iRequestType = iSetupPacket[KUsbRequestTypeIdx]; - iDataStageLength = LittleEndian::Get16(&iSetupPacket[KUsbRequestLengthIdx]); - - switch (iRequestType) - { - case EGetNtbParameters: - if (iDataStageLength != KNtbParamStructLength) - { - ControlMsgError(EInvalidLengthToRead); - break; - } - iEngine.HandleGetNtbParam(iDataBuffer); - __ASSERT_DEBUG(iDataBuffer.Length()==KNtbParamStructLength, - User::Panic(KNcmCommInterfacePanic, ENcmCommWrongDataLength)); - WriteDataIn(); - break; - - case EGetNtbInputSize: - if (iDataStageLength != KNtbInputSizeStructLength) - { - ControlMsgError(EInvalidLengthToRead); - break; - } - iEngine.HandleGetNtbInputSize(iDataBuffer); - __ASSERT_DEBUG(iDataBuffer.Length()==KNtbInputSizeStructLength, - User::Panic(KNcmCommInterfacePanic, ENcmCommWrongDataLength)); - WriteDataIn(); - break; - - case ESetNtbInputSize: - if (iDataStageLength != KNtbInputSizeStructLength) - { - ControlMsgError(EInvalidLengthToRead); - break; - } - ReadDataOut(); - break; - default: - TInt ret = iPort.EndpointZeroRequestError(); - OstTrace1( TRACE_ERROR, CNCMCOMMUNICATIONINTERFACE_DECODESETUP, "unsupport request, halt endpoint with EndpointZeroRequestError %d", ret); - ReadSetup(); - break; - } - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_DECODESETUP_EXIT, this ); - } - - - -// -//Read the raw data of a control request message from host -// -void CNcmCommunicationInterface::ReadDataOut() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_READDATAOUT_ENTRY, this ); - iRWState = EStateReadDataout; - iSenderAndReceiver->Read(iStatus, iDataBuffer, iDataStageLength); - SetActive(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_READDATAOUT_EXIT, this ); - } - - - - -// -//Parse the data out from host to specific NCM control message -// -void CNcmCommunicationInterface::ParseDataOut() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_PARSEDATAOUT_ENTRY, this ); - - __ASSERT_DEBUG(iDataBuffer.Length()>0, - User::Panic(KNcmCommInterfacePanic, ENcmCommWrongDataLength)); - - TInt ret = KErrNone; - switch (iRequestType) - { - case ESetNtbInputSize: - ret = iEngine.HandleSetNtbInputSize(iDataBuffer); - break; - default: - ret = KErrNotSupported; - break; - } - - if (ret == KErrNone) - { - iPort.SendEp0StatusPacket(); - } - else - { - OstTrace1( TRACE_WARNING, CNCMCOMMUNICATIONINTERFACE_PARSEDATAOUT, "handle request iRequestType error %d stall endpoint", ret); - iPort.EndpointZeroRequestError(); - } - ReadSetup(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_PARSEDATAOUT_EXIT, this ); - } - -// -// send connection status notification, aConnected = ETrue if connection up, otherwise EFalse if connection discnnected -// -TInt CNcmCommunicationInterface::SendConnectionNotification(TBool aConnected) - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_SENDCONNECTIONNOTIFICATION_ENTRY, this ); - const TUint8 KConnectionNotificationCode = 0x00; - const TUint16 KConnectedCode = 0x0001; - const TUint16 KDisconnectCode = 0x0000; - - TUSBNotificationNetworkConnection netNotify; - netNotify.iRequestType = KNotificationRequestType; - netNotify.iNotification = KConnectionNotificationCode; - netNotify.iValue = (aConnected)?KConnectedCode:KDisconnectCode; - netNotify.iIndex = iInterfaceNumber; - netNotify.iLength = 0; - - return WriteInterruptData(KIntEndpoint, netNotify.Des(), - netNotify.Des().Length()); - } - -// -// send speed notification -// -TInt CNcmCommunicationInterface::SendSpeedNotification(TInt aUSBitRate, TInt aDSBitRate) - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_SENDSPEEDNOTIFICATION_ENTRY, this ); - const TUint8 KSpeedNotificationCode = 0x2A; - - TUSBNotificationConnectionSpeedChange speedNotify; - speedNotify.iRequestType = KNotificationRequestType; - speedNotify.iNotification = KSpeedNotificationCode; - speedNotify.iValue = 0x00; - speedNotify.iIndex = iInterfaceNumber; - speedNotify.iLength = 0x08; - speedNotify.iUSBitRate = aUSBitRate; - speedNotify.iDSBitRate = aDSBitRate; - - return WriteInterruptData(KIntEndpoint, speedNotify.Des(), - speedNotify.Des().Length()); - } - - -// -//According to the receving request message, send back a response to the host -// -void CNcmCommunicationInterface::WriteDataIn() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_WRITEDATAIN_ENTRY, this ); - - iRWState = EStateWriteDatain; - TInt ret = iSenderAndReceiver->Write(iStatus, iDataBuffer, iDataBuffer.Length()); - __ASSERT_DEBUG(ret==KErrNone, User::Panic(KNcmCommInterfacePanic, ENcmCommWriteError)); - SetActive(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEDATAIN_EXIT, this ); - } - -// -//Cancel the outgoing request -// -void CNcmCommunicationInterface::DoCancel() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_DOCANCEL_ENTRY, this ); - TRequestStatus* status = &iStatus; - User::RequestComplete(status, KErrCancel); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_DOCANCEL_EXIT, this ); - } - -// -//Stop the control channel to stop the NCM -// -void CNcmCommunicationInterface::Stop() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_STOP_ENTRY, this ); - iStarted = EFalse; - iSenderAndReceiver->Stop(); - Cancel(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_STOP_EXIT, this ); - } - -// -//AO RunL -// -void CNcmCommunicationInterface::RunL() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_RUNL_ENTRY, this ); - if(iStatus.Int() != KErrNone) - { - if (KErrCancel == iStatus.Int() ) - { - } - else - { - ControlMsgError(EInternalError); - } - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_RUNL_EXIT, this ); - return; - } - - switch(iRWState) - { - case EStateInitial: - { - ReadSetup(); - break; - } - - case EStateReadSetup: - { - DecodeSetup(); - break; - } - - case EStateReadDataout: - { - ParseDataOut(); - break; - } - - case EStateWriteDatain: - { - ReadSetup(); - break; - } - } - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_RUNL_EXIT_DUP1, this ); - } - - -// -//Any fatal error occurs when reading/sending a NCM control message via USB interface -// -void CNcmCommunicationInterface::ControlMsgError(TNcmCommErrorCode aCode) - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_CONTROLMSGERROR_ENTRY, this ); - OstTrace1( TRACE_NORMAL, CNCMCOMMUNICATIONINTERFACE_CONTROLMSGERROR, "CNcmCommunicationInterface, Handle Ncm Control Message with err=%d", aCode); - - // Stall bus, there's nothing else we can do - iPort.EndpointZeroRequestError(); - iEngine.ControlError(aCode); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_CONTROLMSGERROR_EXIT, this ); - } - - -TInt CNcmCommunicationInterface::WriteInterruptData(TInt aEndPoint, - TDesC8& aDes, - TInt aLength) - - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_ENTRY, this ); - - TInt ret; - RTimer timer; - ret = timer.CreateLocal(); - if ( ret ) - { - OstTrace1( TRACE_FATAL, CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA, "\ttimer.CreateLocal = %d- returning", ret); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT, this ); - return ret; - } - TRequestStatus status; - TRequestStatus timerStatus; - - TEndpointBuffer epBuffer; - ret = iPort.OpenEndpoint(epBuffer, aEndPoint); - if (ret != KErrNone) - { - timer.Close(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT_DUP1, this ); - return ret; - } - - TAny *buf; - TUint size; - ret = epBuffer.GetInBufferRange(buf, size); - if (ret != KErrNone) - { - timer.Close(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT_DUP2, this ); - return ret; - } - else if (size < aLength) - { - timer.Close(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT_DUP3, this ); - return KErrArgument; - } - - TPtr8 writeBuf((TUint8 *)buf, size); - writeBuf.Copy(aDes.Ptr(), aLength); - ret = epBuffer.WriteBuffer(buf, writeBuf.Size(), ETrue, status); - if (ret != KErrNone) - { - timer.Close(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT_DUP4, this ); - return ret; - } - - const TInt KWriteDataTimeout = 1000000; - timer.After(timerStatus, KWriteDataTimeout); - User::WaitForRequest(status, timerStatus); - if ( timerStatus != KRequestPending ) - { - // Timeout occurred, silently ignore error condition. - // Assuming that the line has been disconnected - OstTrace0( TRACE_ERROR, CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA1, "CNcmCommunicationInterface::WriteInterruptData() - Timeout occurred"); - iPort.WriteCancel(epBuffer.BufferNumber()); - User::WaitForRequest(status); - ret = timerStatus.Int(); - } - else - { - OstTrace0( TRACE_ERROR, CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA2, "CNcmCommunicationInterface::WriteInterruptData() - Write completed"); - timer.Cancel(); - User::WaitForRequest(timerStatus); - ret = status.Int(); - } - - epBuffer.Close(); - timer.Close(); - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_WRITEINTERRUPTDATA_EXIT_DUP5, this ); - return ret; - } - - -// -// Get interface number -// -TInt CNcmCommunicationInterface::GetInterfaceNumber() - { - OstTraceFunctionEntry1( CNCMCOMMUNICATIONINTERFACE_GETINTERFACENUMBER_ENTRY, this ); - - TInt interfaceSize = 0; - // 2 is where the interface number is, according to the LDD API - const TInt intNumOffsetInDes = 2; - - // 0 means the main interface in the LDD API - TInt res = iPort.GetInterfaceDescriptorSize(0, interfaceSize); - - if ( res ) - { - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_GETINTERFACENUMBER_EXIT, this ); - return res; - } - - HBufC8* interfaceBuf = HBufC8::New(interfaceSize); - if ( !interfaceBuf ) - { - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_GETINTERFACENUMBER_EXIT_DUP1, this ); - return KErrNoMemory; - } - - TPtr8 interfacePtr = interfaceBuf->Des(); - interfacePtr.SetLength(0); - // 0 means the main interface in the LDD API - res = iPort.GetInterfaceDescriptor(0, interfacePtr); - - if ( res ) - { - delete interfaceBuf; - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_GETINTERFACENUMBER_EXIT_DUP2, this ); - return res; - } - - const TUint8* buffer = reinterpret_cast(interfacePtr.Ptr()); - iInterfaceNumber = buffer[intNumOffsetInDes]; - - delete interfaceBuf; - OstTraceFunctionExit1( CNCMCOMMUNICATIONINTERFACE_GETINTERFACENUMBER_EXIT_DUP3, this ); - return KErrNone; - } - - -