--- a/usbmgmt/usbmgr/device/classdrivers/ncm/classcontroller/src/ncmclientmanager.cpp Tue Aug 31 17:01:47 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,556 +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:
-*
-*/
-
-/**
- * @file
- * @internalComponent
- */
-
-#include "ncmclientmanager.h"
-
-
-#ifdef OVERDUMMY_NCMCC
-#include <usb/testncmcc/dummy_ncminternalsrv.h>
-#else
-#include "ncminternalsrv.h"
-#endif // OVERDUMMY_NCMCC
-
-#include "ncmclassdescriptor.h"
-// For OST tracing
-#include "OstTraceDefinitions.h"
-#ifdef OST_TRACE_COMPILER_IN_USE
-#include "ncmclientmanagerTraces.h"
-#endif
-
-
-// NCM Interface MTU size
-extern const TUint KEthernetFrameSize;
-
-// NCM MAC Address String descriptor buffer length
-const TUint KMacAddrStringDescSize = 32;
-
-
-/**
- * Construtor
- * @param aMacAddress the NCM ethernet interface MAC address
- */
-CNcmClientManager::CNcmClientManager(const TNcmMacAddress& aHostMacAddress):
- iHostMacAddress(aHostMacAddress)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY, this );
-
- // No implementation required
- OstTraceFunctionExit1( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_EXIT, this );
- }
-
-/**
- * Destructor
- */
-CNcmClientManager::~CNcmClientManager()
- {
- OstTraceFunctionEntry0( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY_DESTRUCTOR );
-
- TInt err = KErrNone;
- if (iCommLddInitiated)
- {
- RChunk* commChunk = NULL;
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_PRE_CLOSE_COMM_INTERFACE, "About to get chunk handle for communication interface!");
- err = iCommLdd.GetDataTransferChunk(commChunk);
- if (KErrNone == err)
- {
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_CHUNK, "About to close chunk handle for communication interface!");
- commChunk->Close();
- }
- else
- {
- OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_CHUNK_FAIL, "Can not get chunk handle for communication interface: err = %d", err);
- }
-
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_INTERFACE, "About to close device handle for communication interface!");
- iCommLdd.Close();
- }
-
- if (iDataLddInitiated)
- {
- RChunk* dataChunk = NULL;
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_PRE_CLOSE_DATA_INTERFACE, "About to get chunk handle for data interface!");
- err = iDataLdd.GetDataTransferChunk(dataChunk);
- if (KErrNone == err)
- {
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_CHUNK, "About to close chunk handle for communication interface!");
- dataChunk->Close();
- }
- else
- {
- OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_CHUNK_FAIL, "Can not get chunk handle for data interface: err = %d", err);
- }
-
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_INTERFACE, "About to close device handle for data interface!");
- iDataLdd.Close();
- }
- OstTraceFunctionExit0( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY_DESTRUCTOR_EXIT );
- }
-
-
-/**
- * Setup NCM interfaces
- * @param[out] aDataEpBufferSize, NCM data interface EP buffer size
- */
-void CNcmClientManager::SetNcmInterfacesL(TUint& aDataEpBufferSize)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETNCMINTERFACESL_ENTRY, this );
-
- // Setup NCM communication interface
- SetCommunicationInterfaceL();
-
- // Setup NCM data interface
- SetDataInterfaceL(aDataEpBufferSize);
-
- // Retrieve data interface number
- TUint8 dataInterfaceNumber = 1;
- User::LeaveIfError(DataInterfaceNumber(dataInterfaceNumber));
-
- // Setup NCM class descriptor with correct interface number
- User::LeaveIfError(SetupClassSpecificDescriptor(dataInterfaceNumber));
- OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETNCMINTERFACESL_EXIT, this );
- }
-
-/**
- * Transfer NCM interface handlers from NCM class controller to NCM
- * packet driver through NCM internal server.
- * @param aServer a reference to RNcmInternalSrv
- */
-void CNcmClientManager::TransferInterfacesL(RNcmInternalSrv& aServer)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_TRANSFERINTERFACESL_ENTRY, this );
-
- RChunk* commChunk = NULL;
- RChunk* dataChunk = NULL;
-
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_TRANSFERINTERFACESL_PRE_TRANSFER_INTERFACES, "About to Transfer handles to NCM internal server!");
- User::LeaveIfError(iCommLdd.GetDataTransferChunk(commChunk));
- User::LeaveIfError(iDataLdd.GetDataTransferChunk(dataChunk));
- User::LeaveIfError(aServer.TransferHandle(iCommLdd, *commChunk,
- iDataLdd, *dataChunk));
- OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_TRANSFERINTERFACESL_INTERFACES_TRANSFERED, "Transfer handles to NCM internal server Done!");
- OstTraceFunctionExit1( CNCMCLIENTMANAGER_TRANSFERINTERFACESL_EXIT, this );
- }
-
-/**
- * Setup NCM communication inteface
- */
-void CNcmClientManager::SetCommunicationInterfaceL()
- {
- OstTraceFunctionEntry1( CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_ENTRY, this );
-
- User::LeaveIfError(iCommLdd.Open(0));
- iCommLddInitiated = ETrue;
-
- TInt err = KErrNone;
-
- TUsbcScInterfaceInfoBuf ifc0;
- TUsbcDeviceState deviceStatus;
-
- User::LeaveIfError(iCommLdd.DeviceStatus(deviceStatus));
-
- if (deviceStatus == EUsbcDeviceStateConfigured)
- {
- User::Leave( KErrInUse);
- }
-
- TUsbDeviceCaps dCaps;
- User::LeaveIfError(iCommLdd.DeviceCaps(dCaps));
-
- TInt epNum = dCaps().iTotalEndpoints;
-
- TUsbcEndpointData data[KUsbcMaxEndpoints];
- TPtr8 dataptr(reinterpret_cast<TUint8*> (data), sizeof(data),
- sizeof(data));
-
- User::LeaveIfError(iCommLdd.EndpointCaps(dataptr));
-
- TBool foundIntIN = EFalse;
- const TUint KEndPointType = KUsbEpTypeInterrupt | KUsbEpDirIn;
- for (TInt i = 0; i < epNum; i++)
- {
- const TUsbcEndpointData* epData = &data[i];
- if ((!epData->iInUse) && // Not in use
- ((epData->iCaps.iTypesAndDir & KEndPointType) == KEndPointType))
- {
- // EEndpoint1 is going to be our INTERRUPT (IN, write) endpoint
- ifc0().iEndpointData[0].iType = KUsbEpTypeInterrupt;
- ifc0().iEndpointData[0].iDir = KUsbEpDirIn;
- ifc0().iEndpointData[0].iSize = epData->iCaps.MinPacketSize();
- ifc0().iEndpointData[0].iInterval = 0x01;
- ifc0().iEndpointData[0].iInterval_Hs = 0x01;
-
- foundIntIN = ETrue;
- break;
- }
- }
- if (EFalse == foundIntIN)
- {
- OstTrace0( TRACE_ERROR, CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL, "Can not find proper endpint for NCM communication interface" );
- User::Leave( KErrNotFound);
- }
-
- /*********************************************************************************************/
- //Communication Class Interface (0x00)
- /*********************************************************************************************/
- _LIT16(KIfClassName0, "USB Networking (NCM)");
- HBufC16* string0 = KIfClassName0().AllocLC();
-
- ifc0().iString = string0;
- ifc0().iTotalEndpointsUsed = 1;
- ifc0().iClass.iClassNum = 0x02;
- ifc0().iClass.iSubClassNum = 0x0D;
- ifc0().iClass.iProtocolNum = 0x00;
-
- User::LeaveIfError(iCommLdd.SetInterface(0, ifc0));
-
- err = iCommLdd.FinalizeInterface();
- if (KErrNone != err)
- {
- OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_FAIL_TO_INIT, "Failed to FinalizeInterface, err %d", err);
- User::Leave(err);
- }
- CleanupStack::PopAndDestroy(string0);
- OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_EXIT, this );
- }
-
-/**
- * Setup NCM data interface
- * @param aDataEpBufferSize, the determined data interface
- * endpoint buffer size.
- */
-void CNcmClientManager::SetDataInterfaceL(TUint& aDataEpBufferSize)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETDATAINTERFACEL_ENTRY, this );
-
- const TUint KMaxScBufferSize = 1048576; // Up limit of end point buffer
- const TUint KMinScBufferSize = 262144; // Lower limit of end point buffer
- const TUint KMaxScReadSize = 65536;
-
- User::LeaveIfError(iDataLdd.Open(0));
- iDataLddInitiated = ETrue;
-
- TUsbcScInterfaceInfoBuf ifc0, ifc1;
- TUsbDeviceCaps dCaps;
- User::LeaveIfError(iDataLdd.DeviceCaps(dCaps));
-
- TBool isResourceAllocationV2 = ((dCaps().iFeatureWord1
- & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
-
- TUsbcDeviceState deviceStatus;
-
- User::LeaveIfError(iDataLdd.DeviceStatus(deviceStatus));
- if (deviceStatus == EUsbcDeviceStateConfigured)
- {
- User::Leave(KErrInUse);
- }
-
- TInt epNum = dCaps().iTotalEndpoints;
- TUsbcEndpointData data[KUsbcMaxEndpoints];
- TPtr8 dataptr(reinterpret_cast<TUint8*> (data), sizeof(data),
- sizeof(data));
-
- User::LeaveIfError(iDataLdd.EndpointCaps(dataptr));
-
- const TUint KNcmDataInterfaceEpNumber = 2;
- TBool foundBulkIN = EFalse;
- TBool foundBulkOUT = EFalse;
- TInt maxPacketSize = 0;
- const TUint KEndPointBulkInType = KUsbEpTypeBulk | KUsbEpDirIn;
- const TUint KEndPointBulkOutType = KUsbEpTypeBulk | KUsbEpDirOut;
- for (TInt i = 0; i < epNum; i++)
- {
- const TUsbcEndpointData* epData = &data[i];
-
- // Check if this endpoint is in use
- if (epData->iInUse)
- {
- continue;
- }
-
- maxPacketSize = epData->iCaps.MaxPacketSize();
- if (!foundBulkIN &&
- ((epData->iCaps.iTypesAndDir & KEndPointBulkInType) == KEndPointBulkInType))
- {
- // EEndpoint1 is going to be our TX (IN, write) endpoint
- ifc1().iEndpointData[0].iType = KUsbEpTypeBulk;
- ifc1().iEndpointData[0].iDir = KUsbEpDirIn;
- ifc1().iEndpointData[0].iSize = maxPacketSize;
- ifc1().iEndpointData[0].iInterval_Hs = 0x0;
- ifc1().iEndpointData[0].iBufferSize = KMaxScBufferSize;
-
- if (isResourceAllocationV2)
- {
- ifc1().iEndpointData[0].iFeatureWord1 |=
- (KUsbcEndpointInfoFeatureWord1_DMA | KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
- }
-
- foundBulkIN = ETrue;
- if (foundBulkIN && foundBulkOUT)
- {
- break;
- }
- continue;
- }
-
- if (!foundBulkOUT &&
- ((epData->iCaps.iTypesAndDir & KEndPointBulkOutType) == KEndPointBulkOutType))
- {
- // EEndpoint2 is going to be our RX (OUT, read) endpoint
- ifc1().iEndpointData[1].iType = KUsbEpTypeBulk;
- ifc1().iEndpointData[1].iDir = KUsbEpDirOut;
- ifc1().iEndpointData[1].iSize = maxPacketSize;
- ifc1().iEndpointData[1].iInterval_Hs = 0x1;
- ifc1().iEndpointData[1].iBufferSize = KMaxScBufferSize;
- ifc1().iEndpointData[1].iReadSize = KMaxScReadSize;
-
- if (isResourceAllocationV2)
- {
- ifc1().iEndpointData[1].iFeatureWord1 |=
- (KUsbcEndpointInfoFeatureWord1_DMA | KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
- }
-
- foundBulkOUT = ETrue;
- if (foundBulkIN && foundBulkOUT)
- {
- break;
- }
- continue;
- }
- }
-
- // Leave if no properly endpoint is found
- if (EFalse == foundBulkIN || EFalse == foundBulkOUT)
- {
- User::Leave(KErrNotFound);
- }
-
- _LIT16(KIfClassName0, "NCM Data Interface 0");
-
- HBufC16* string0 = KIfClassName0().AllocL();
- CleanupStack::PushL(string0);
- ifc0().iString = string0;
- ifc0().iTotalEndpointsUsed = 0;
- ifc0().iClass.iClassNum = 0x0A;
- ifc0().iClass.iSubClassNum = 0x00;
- ifc0().iClass.iProtocolNum = 0x01;
- User::LeaveIfError(iDataLdd.SetInterface(0, ifc0));
-
- _LIT16(KIfClassName1, "NCM Data Interface 1");
- HBufC16* string1 = KIfClassName1().AllocL();
- CleanupStack::PushL(string1);
- ifc1().iString = string1;
- ifc1().iTotalEndpointsUsed = KNcmDataInterfaceEpNumber;
- ifc1().iClass.iClassNum = 0x0A;
- ifc1().iClass.iSubClassNum = 0x00;
- ifc1().iClass.iProtocolNum = 0x01;
-
- // Try to allocate expected memory for data interface endpoints
- aDataEpBufferSize = KMaxScBufferSize;
-
- TInt err = KErrNone;
- FOREVER
- {
- OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_SETDATAINTERFACEL_TRY_NEW_BUF_SIZE, "Try buffer size: %d", aDataEpBufferSize);
- err = iDataLdd.SetInterface(1, ifc1);
- if (KErrNoMemory == err)
- {
- // Reduce buffer size and retry
- aDataEpBufferSize = aDataEpBufferSize / 2;
- if (aDataEpBufferSize < KMinScBufferSize)
- {
- User::Leave(KErrNoMemory);
- }
- ifc1().iEndpointData[0].iBufferSize = aDataEpBufferSize;
- ifc1().iEndpointData[1].iBufferSize = aDataEpBufferSize;
- continue;
- }
- else
- {
- OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_SETDATAINTERFACEL_SET_INTERFACE_FAIL, "Set data interface and the returned err code is %d", err);
- // Leave with error code
- User::LeaveIfError(err);
- break;
- }
- }
-
- CleanupStack::PopAndDestroy(2, string0);
-
- User::LeaveIfError(iDataLdd.FinalizeInterface());
- OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETDATAINTERFACEL_EXIT, this );
- }
-
-/**
- * Setup the Class Descriptors
- * @param aDataInterfaceNumber The interface number of the data class
- * @return Error.
- */
-TInt CNcmClientManager::SetupClassSpecificDescriptor(TUint8 aDataInterfaceNumber)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_ENTRY, this );
-
- TInt res;
-
- TNcmClassDescriptor descriptor;
-
- // Header Functional Descriptor- CDC spec table 15
- descriptor.iHdrSize = 0x05;
- descriptor.iHdrType = 0x24;
- descriptor.iHdrSubType = 0x00;
- descriptor.iHdrBcdCDC = 0x0120;
-
- // Ethernet Networking Functional Descriptor- ECM spec table 3
- descriptor.iEthFunLength = 0x0D;
- descriptor.iEthFunType = 0x24;
- descriptor.iEthFunSubtype = 0x0F;
-
- // Generate the MAC address new NCM interface
- res = SetMacAddressString(descriptor.iMACAddress);
-
- if (res != KErrNone)
- {
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT, this, res );
- return res;
- }
-
- descriptor.iEthernetStatistics = 0;
- descriptor.iMaxSegmentSize = KEthernetFrameSize;
- descriptor.iNumberMCFilters = 0;
- descriptor.iNumberPowerFilters = 0;
-
- // NCM Functional Descriptor- NCM spec table 5-2
- descriptor.iNcmFunLength = 0x06;
- descriptor.iNcmFunType = 0x24;
- descriptor.iNcmFunSubtype = 0x1A;
- descriptor.iNcmVersion = 0x0100;
- descriptor.iNetworkCapabilities = 0;
-
- // Union functional descriptor- CDC spec table 16
- descriptor.iUnSize = 0x05;
- descriptor.iUnType = 0x24;
- descriptor.iUnSubType = 0x06;
- descriptor.iUnMasterInterface = 0;
- descriptor.iUnSlaveInterface = aDataInterfaceNumber;
-
- OstTrace0( TRACE_NORMAL, CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_PRE_SET_BLOCK, "About to call SetCSInterfaceDescriptorBlock" );
- res = iCommLdd.SetCSInterfaceDescriptorBlock(0, descriptor.Des());
- if (res != KErrNone)
- {
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT_DUP1, this, res );
- return res;
- }
-
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT_DUP2, this, KErrNone );
- return KErrNone;
- }
-
-/**
- * Set the MAC address string in descriptor
- * @param aStrIndex the MAC address string index
- */
-TInt CNcmClientManager::SetMacAddressString(TUint8& aStrIndex)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETMACADDRESSSTRING_ENTRY, this );
-
- TBuf16<KMacAddrStringDescSize> str;
-
- // Search for MAC address string from index 0x10
- aStrIndex = 0x10;
-
- TInt ret = KErrNone;
-#ifndef OVERDUMMY_NCMCC
- while (aStrIndex++ < 0xFF && ret != KErrNotFound)
- {
- ret = iDataLdd.GetStringDescriptor(aStrIndex, str);
- }
-#endif // OVERDUMMY_NCMCC
-
- if (aStrIndex < 0xFF)
- {
- TBuf8<KEthernetAddressLength*2> macAddrStr;
- _LIT8(KMacAddressFormat, "%02X%02X%02X%02X%02X%02X");
- OstTraceExt1(TRACE_NORMAL, CNCMCLIENTMANAGER_SETMACADDRESSSTRING, "The MAC address is %s", iHostMacAddress);
- macAddrStr.AppendFormat(KMacAddressFormat, iHostMacAddress[0],
- iHostMacAddress[1], iHostMacAddress[2], iHostMacAddress[3],
- iHostMacAddress[4], iHostMacAddress[5]);
- str.Copy(macAddrStr);
- ret = iDataLdd.SetStringDescriptor(aStrIndex, str);
- }
-
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETMACADDRESSSTRING_EXIT, this, ret );
- return ret;
- }
-
-/**
- * Get NCM data interface number
- * @param aInterfaceNumber NCM data interface number
- * @return Error.
- */
-TInt CNcmClientManager::DataInterfaceNumber(TUint8& aInterfaceNumber)
- {
- OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_ENTRY, this );
-
- TInt interfaceSize = 0;
-
- // 0 means the main interface in the LDD API
- TInt res = iDataLdd.GetInterfaceDescriptorSize(0, interfaceSize);
-
- if ( KErrNone == res )
- {
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT, this, res );
- return res;
- }
-
- HBufC8* interfaceBuf = HBufC8::New(interfaceSize);
- if ( !interfaceBuf )
- {
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP1, this, KErrNoMemory);
- return KErrNoMemory;
- }
-
- TPtr8 interfacePtr = interfaceBuf->Des();
- interfacePtr.SetLength(0);
- // 0 means the main interface in the LDD API
- res = iDataLdd.GetInterfaceDescriptor(0, interfacePtr);
-
- if ( KErrNone == res )
- {
- delete interfaceBuf;
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP2, this, res );
- return res;
- }
-
- OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER_INTERFACE_INFO, "***Interface length =% d", interfacePtr.Length());
- for ( TInt i = 0 ; i < interfacePtr.Length() ; i++ )
- {
- OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER_INTERFACE_INFO2, "***** %x", interfacePtr[i]);
- }
-
- const TUint8* buffer = reinterpret_cast<const TUint8*>(interfacePtr.Ptr());
- // 2 is where the interface number is, according to the LDD API
- aInterfaceNumber = buffer[2];
- OstTraceExt1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER, "Interface number = %hhu", aInterfaceNumber);
-
- delete interfaceBuf;
-
- OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP3, this, KErrNone );
- return KErrNone;
- }