usbmgmt/usbmgr/device/classdrivers/ncm/classcontroller/src/ncmclientmanager.cpp
branchRCL_3
changeset 15 f92a4f87e424
equal deleted inserted replaced
14:d3e8e7d462dd 15:f92a4f87e424
       
     1 /*
       
     2 * Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 /**
       
    19  * @file
       
    20  * @internalComponent
       
    21  */
       
    22 
       
    23 #include "ncmclientmanager.h"
       
    24 
       
    25 
       
    26 #ifdef OVERDUMMY_NCMCC
       
    27 #include <usb/testncmcc/dummy_ncminternalsrv.h>
       
    28 #else
       
    29 #include "ncminternalsrv.h"
       
    30 #endif // OVERDUMMY_NCMCC
       
    31 
       
    32 #include "ncmclassdescriptor.h"
       
    33 // For OST tracing
       
    34 #include "OstTraceDefinitions.h"
       
    35 #ifdef OST_TRACE_COMPILER_IN_USE
       
    36 #include "ncmclientmanagerTraces.h"
       
    37 #endif
       
    38 
       
    39 
       
    40 // NCM Interface MTU size
       
    41 extern const TUint KEthernetFrameSize;
       
    42 
       
    43 // NCM MAC Address String descriptor buffer length
       
    44 const TUint KMacAddrStringDescSize = 32;
       
    45 
       
    46 
       
    47 /**
       
    48  * Construtor
       
    49  * @param aMacAddress the NCM ethernet interface MAC address
       
    50  */
       
    51 CNcmClientManager::CNcmClientManager(const TNcmMacAddress& aHostMacAddress):
       
    52         iHostMacAddress(aHostMacAddress)
       
    53     {
       
    54     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY, this );
       
    55     
       
    56     // No implementation required
       
    57     OstTraceFunctionExit1( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_EXIT, this );
       
    58     }
       
    59 
       
    60 /**
       
    61  * Destructor
       
    62  */
       
    63 CNcmClientManager::~CNcmClientManager()
       
    64     {
       
    65     OstTraceFunctionEntry0( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY_DESTRUCTOR );
       
    66     
       
    67     TInt err = KErrNone;
       
    68     if (iCommLddInitiated)
       
    69         {
       
    70         RChunk* commChunk = NULL;
       
    71         OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_PRE_CLOSE_COMM_INTERFACE, "About to get chunk handle for communication interface!");        
       
    72         err = iCommLdd.GetDataTransferChunk(commChunk);
       
    73         if (KErrNone == err)
       
    74             {
       
    75             OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_CHUNK, "About to close chunk handle for communication interface!");
       
    76             commChunk->Close();    
       
    77             }
       
    78         else
       
    79             {
       
    80             OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_CHUNK_FAIL, "Can not get chunk handle for communication interface: err = %d", err);
       
    81             }
       
    82         
       
    83         OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_COMM_INTERFACE, "About to close device handle for communication interface!");        
       
    84         iCommLdd.Close();
       
    85         }
       
    86 
       
    87     if (iDataLddInitiated)
       
    88         {
       
    89         RChunk* dataChunk = NULL;
       
    90         OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_PRE_CLOSE_DATA_INTERFACE, "About to get chunk handle for data interface!");
       
    91         err = iDataLdd.GetDataTransferChunk(dataChunk);
       
    92         if (KErrNone == err)
       
    93             {
       
    94             OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_CHUNK, "About to close chunk handle for communication interface!");
       
    95             dataChunk->Close();
       
    96             }
       
    97         else
       
    98             {
       
    99             OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_CHUNK_FAIL, "Can not get chunk handle for data interface: err = %d", err);
       
   100             }
       
   101 
       
   102         OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_CLOSE_DATA_INTERFACE, "About to close device handle for data interface!");
       
   103         iDataLdd.Close();
       
   104         }
       
   105     OstTraceFunctionExit0( CNCMCLIENTMANAGER_CNCMCLIENTMANAGER_ENTRY_DESTRUCTOR_EXIT );
       
   106     }
       
   107 
       
   108 
       
   109 /**
       
   110  * Setup NCM interfaces
       
   111  * @param[out]   aDataEpBufferSize, NCM data interface EP buffer size
       
   112  */
       
   113 void CNcmClientManager::SetNcmInterfacesL(TUint& aDataEpBufferSize)
       
   114     {
       
   115     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETNCMINTERFACESL_ENTRY, this );
       
   116     
       
   117     // Setup NCM communication interface
       
   118     SetCommunicationInterfaceL();
       
   119     
       
   120     // Setup NCM data interface
       
   121     SetDataInterfaceL(aDataEpBufferSize);
       
   122     
       
   123     // Retrieve data interface number
       
   124     TUint8 dataInterfaceNumber = 1;
       
   125     User::LeaveIfError(DataInterfaceNumber(dataInterfaceNumber));
       
   126     
       
   127     // Setup NCM class descriptor with correct interface number
       
   128     User::LeaveIfError(SetupClassSpecificDescriptor(dataInterfaceNumber));
       
   129     OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETNCMINTERFACESL_EXIT, this );
       
   130     }
       
   131 
       
   132 /**
       
   133  * Transfer NCM interface handlers from NCM class controller to NCM 
       
   134  * packet driver through NCM internal server.
       
   135  * @param aServer a reference to RNcmInternalSrv 
       
   136  */
       
   137 void CNcmClientManager::TransferInterfacesL(RNcmInternalSrv& aServer)
       
   138     {
       
   139     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_TRANSFERINTERFACESL_ENTRY, this );
       
   140     
       
   141     RChunk* commChunk = NULL;
       
   142     RChunk* dataChunk = NULL;
       
   143 
       
   144     OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_TRANSFERINTERFACESL_PRE_TRANSFER_INTERFACES, "About to Transfer handles to NCM internal server!");
       
   145     User::LeaveIfError(iCommLdd.GetDataTransferChunk(commChunk));
       
   146     User::LeaveIfError(iDataLdd.GetDataTransferChunk(dataChunk));
       
   147     User::LeaveIfError(aServer.TransferHandle(iCommLdd, *commChunk, 
       
   148             iDataLdd, *dataChunk));
       
   149     OstTrace0(TRACE_NORMAL, CNCMCLIENTMANAGER_TRANSFERINTERFACESL_INTERFACES_TRANSFERED, "Transfer handles to NCM internal server Done!");
       
   150     OstTraceFunctionExit1( CNCMCLIENTMANAGER_TRANSFERINTERFACESL_EXIT, this );
       
   151     }
       
   152 
       
   153 /**
       
   154  * Setup NCM communication inteface
       
   155  */
       
   156 void CNcmClientManager::SetCommunicationInterfaceL()
       
   157     {
       
   158     OstTraceFunctionEntry1( CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_ENTRY, this );
       
   159         
       
   160     User::LeaveIfError(iCommLdd.Open(0));
       
   161     iCommLddInitiated = ETrue;
       
   162 
       
   163     TInt err = KErrNone;
       
   164 
       
   165     TUsbcScInterfaceInfoBuf ifc0;
       
   166     TUsbcDeviceState deviceStatus;
       
   167     
       
   168     User::LeaveIfError(iCommLdd.DeviceStatus(deviceStatus));
       
   169 
       
   170     if (deviceStatus == EUsbcDeviceStateConfigured)
       
   171         {
       
   172         User::Leave( KErrInUse);
       
   173         }
       
   174 
       
   175     TUsbDeviceCaps dCaps;
       
   176     User::LeaveIfError(iCommLdd.DeviceCaps(dCaps));
       
   177 
       
   178     TInt epNum = dCaps().iTotalEndpoints;
       
   179 
       
   180     TUsbcEndpointData data[KUsbcMaxEndpoints];
       
   181     TPtr8 dataptr(reinterpret_cast<TUint8*> (data), sizeof(data),
       
   182             sizeof(data));
       
   183 
       
   184     User::LeaveIfError(iCommLdd.EndpointCaps(dataptr));
       
   185 
       
   186     TBool foundIntIN = EFalse;
       
   187     const TUint KEndPointType = KUsbEpTypeInterrupt | KUsbEpDirIn;
       
   188     for (TInt i = 0; i < epNum; i++)
       
   189         {
       
   190         const TUsbcEndpointData* epData = &data[i];
       
   191         if ((!epData->iInUse) && // Not in use
       
   192             ((epData->iCaps.iTypesAndDir & KEndPointType) == KEndPointType))
       
   193             {
       
   194             // EEndpoint1 is going to be our INTERRUPT (IN, write) endpoint
       
   195             ifc0().iEndpointData[0].iType = KUsbEpTypeInterrupt;
       
   196             ifc0().iEndpointData[0].iDir = KUsbEpDirIn;
       
   197             ifc0().iEndpointData[0].iSize = epData->iCaps.MinPacketSize();
       
   198             ifc0().iEndpointData[0].iInterval = 0x01;
       
   199             ifc0().iEndpointData[0].iInterval_Hs = 0x01;
       
   200 
       
   201             foundIntIN = ETrue;
       
   202             break;
       
   203             }
       
   204         }
       
   205     if (EFalse == foundIntIN)
       
   206         {
       
   207         OstTrace0( TRACE_ERROR, CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL, "Can not find proper endpint for NCM communication interface" );
       
   208         User::Leave( KErrNotFound);
       
   209         }
       
   210     
       
   211     /*********************************************************************************************/
       
   212     //Communication Class Interface (0x00)
       
   213     /*********************************************************************************************/
       
   214     _LIT16(KIfClassName0, "USB Networking (NCM)");
       
   215     HBufC16* string0 = KIfClassName0().AllocLC();
       
   216 
       
   217     ifc0().iString = string0;
       
   218     ifc0().iTotalEndpointsUsed = 1;
       
   219     ifc0().iClass.iClassNum = 0x02;
       
   220     ifc0().iClass.iSubClassNum = 0x0D;
       
   221     ifc0().iClass.iProtocolNum = 0x00;
       
   222 
       
   223     User::LeaveIfError(iCommLdd.SetInterface(0, ifc0));
       
   224 
       
   225     err = iCommLdd.FinalizeInterface();
       
   226     if (KErrNone != err)
       
   227         {
       
   228         OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_FAIL_TO_INIT, "Failed to FinalizeInterface, err %d", err);
       
   229         User::Leave(err);
       
   230         }
       
   231     CleanupStack::PopAndDestroy(string0);
       
   232     OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETCOMMUNICATIONINTERFACEL_EXIT, this );
       
   233     }
       
   234 
       
   235 /**
       
   236  * Setup NCM data interface
       
   237  * @param   aDataEpBufferSize, the determined data interface 
       
   238  *          endpoint buffer size.
       
   239  */
       
   240 void CNcmClientManager::SetDataInterfaceL(TUint& aDataEpBufferSize)
       
   241     {
       
   242     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETDATAINTERFACEL_ENTRY, this );
       
   243     
       
   244     const TUint KMaxScBufferSize = 1048576; // Up limit of end point buffer
       
   245     const TUint KMinScBufferSize = 262144;  // Lower limit of end point buffer
       
   246     const TUint KMaxScReadSize = 65536;
       
   247 
       
   248     User::LeaveIfError(iDataLdd.Open(0));
       
   249     iDataLddInitiated = ETrue;
       
   250 
       
   251     TUsbcScInterfaceInfoBuf ifc0, ifc1;
       
   252     TUsbDeviceCaps dCaps;
       
   253     User::LeaveIfError(iDataLdd.DeviceCaps(dCaps));
       
   254 
       
   255     TBool isResourceAllocationV2 = ((dCaps().iFeatureWord1
       
   256             & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
       
   257     
       
   258     TUsbcDeviceState deviceStatus;
       
   259     
       
   260     User::LeaveIfError(iDataLdd.DeviceStatus(deviceStatus));
       
   261     if (deviceStatus == EUsbcDeviceStateConfigured)
       
   262         {
       
   263         User::Leave(KErrInUse);
       
   264         }
       
   265 
       
   266     TInt epNum = dCaps().iTotalEndpoints;
       
   267     TUsbcEndpointData data[KUsbcMaxEndpoints];
       
   268     TPtr8 dataptr(reinterpret_cast<TUint8*> (data), sizeof(data),
       
   269             sizeof(data));
       
   270 
       
   271     User::LeaveIfError(iDataLdd.EndpointCaps(dataptr));
       
   272 
       
   273     const TUint KNcmDataInterfaceEpNumber = 2;
       
   274     TBool foundBulkIN = EFalse;
       
   275     TBool foundBulkOUT = EFalse;
       
   276     TInt maxPacketSize = 0;
       
   277     const TUint KEndPointBulkInType = KUsbEpTypeBulk | KUsbEpDirIn;
       
   278     const TUint KEndPointBulkOutType = KUsbEpTypeBulk | KUsbEpDirOut;
       
   279     for (TInt i = 0; i < epNum; i++)
       
   280         {
       
   281         const TUsbcEndpointData* epData = &data[i];
       
   282         
       
   283         // Check if this endpoint is in use 
       
   284         if (epData->iInUse)
       
   285             {
       
   286             continue;
       
   287             }
       
   288         
       
   289         maxPacketSize = epData->iCaps.MaxPacketSize();
       
   290         if (!foundBulkIN && 
       
   291                 ((epData->iCaps.iTypesAndDir & KEndPointBulkInType) == KEndPointBulkInType))
       
   292             {
       
   293             // EEndpoint1 is going to be our TX (IN, write) endpoint
       
   294             ifc1().iEndpointData[0].iType = KUsbEpTypeBulk;
       
   295             ifc1().iEndpointData[0].iDir = KUsbEpDirIn;
       
   296             ifc1().iEndpointData[0].iSize = maxPacketSize;
       
   297             ifc1().iEndpointData[0].iInterval_Hs = 0x0;
       
   298             ifc1().iEndpointData[0].iBufferSize = KMaxScBufferSize;
       
   299 
       
   300             if (isResourceAllocationV2)
       
   301                 {
       
   302                 ifc1().iEndpointData[0].iFeatureWord1 |= 
       
   303                     (KUsbcEndpointInfoFeatureWord1_DMA | KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
       
   304                 }
       
   305             
       
   306             foundBulkIN = ETrue;
       
   307             if (foundBulkIN && foundBulkOUT)
       
   308                 {
       
   309                 break;
       
   310                 }
       
   311             continue;
       
   312             }
       
   313 
       
   314         if (!foundBulkOUT && 
       
   315                 ((epData->iCaps.iTypesAndDir & KEndPointBulkOutType) == KEndPointBulkOutType))
       
   316             {
       
   317             // EEndpoint2 is going to be our RX (OUT, read) endpoint
       
   318             ifc1().iEndpointData[1].iType = KUsbEpTypeBulk;
       
   319             ifc1().iEndpointData[1].iDir = KUsbEpDirOut;
       
   320             ifc1().iEndpointData[1].iSize = maxPacketSize;
       
   321             ifc1().iEndpointData[1].iInterval_Hs = 0x1;
       
   322             ifc1().iEndpointData[1].iBufferSize = KMaxScBufferSize;
       
   323             ifc1().iEndpointData[1].iReadSize = KMaxScReadSize;
       
   324 
       
   325             if (isResourceAllocationV2)
       
   326                 {
       
   327                 ifc1().iEndpointData[1].iFeatureWord1 |= 
       
   328                     (KUsbcEndpointInfoFeatureWord1_DMA | KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
       
   329                 }
       
   330 
       
   331             foundBulkOUT = ETrue;
       
   332             if (foundBulkIN && foundBulkOUT)
       
   333                 {
       
   334                 break;
       
   335                 }
       
   336             continue;
       
   337             }
       
   338         }
       
   339 
       
   340     // Leave if no properly endpoint is found
       
   341     if (EFalse == foundBulkIN || EFalse == foundBulkOUT)
       
   342         {
       
   343         User::Leave(KErrNotFound);
       
   344         }
       
   345     
       
   346     _LIT16(KIfClassName0, "NCM Data Interface 0");
       
   347 
       
   348     HBufC16* string0 = KIfClassName0().AllocL();
       
   349     CleanupStack::PushL(string0);    
       
   350     ifc0().iString = string0;
       
   351     ifc0().iTotalEndpointsUsed = 0;
       
   352     ifc0().iClass.iClassNum = 0x0A;
       
   353     ifc0().iClass.iSubClassNum = 0x00;
       
   354     ifc0().iClass.iProtocolNum = 0x01;    
       
   355     User::LeaveIfError(iDataLdd.SetInterface(0, ifc0));
       
   356         
       
   357     _LIT16(KIfClassName1, "NCM Data Interface 1");
       
   358     HBufC16* string1 = KIfClassName1().AllocL();
       
   359     CleanupStack::PushL(string1);
       
   360     ifc1().iString = string1;
       
   361     ifc1().iTotalEndpointsUsed = KNcmDataInterfaceEpNumber;
       
   362     ifc1().iClass.iClassNum = 0x0A;
       
   363     ifc1().iClass.iSubClassNum = 0x00;
       
   364     ifc1().iClass.iProtocolNum = 0x01;
       
   365     
       
   366     // Try to allocate expected memory for data interface endpoints
       
   367     aDataEpBufferSize = KMaxScBufferSize;
       
   368     
       
   369     TInt err = KErrNone; 
       
   370     FOREVER
       
   371         {
       
   372         OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_SETDATAINTERFACEL_TRY_NEW_BUF_SIZE, "Try buffer size: %d", aDataEpBufferSize);
       
   373         err = iDataLdd.SetInterface(1, ifc1);
       
   374         if (KErrNoMemory == err)
       
   375             {
       
   376             // Reduce buffer size and retry
       
   377             aDataEpBufferSize = aDataEpBufferSize / 2;
       
   378             if (aDataEpBufferSize < KMinScBufferSize)
       
   379                 {
       
   380                 User::Leave(KErrNoMemory);
       
   381                 }
       
   382             ifc1().iEndpointData[0].iBufferSize = aDataEpBufferSize;
       
   383             ifc1().iEndpointData[1].iBufferSize = aDataEpBufferSize;
       
   384             continue;
       
   385             }
       
   386         else
       
   387             {
       
   388             OstTrace1(TRACE_ERROR, CNCMCLIENTMANAGER_SETDATAINTERFACEL_SET_INTERFACE_FAIL, "Set data interface and the returned err code is %d", err);
       
   389             // Leave with error code
       
   390             User::LeaveIfError(err);
       
   391             break;
       
   392             }
       
   393         }
       
   394     
       
   395     CleanupStack::PopAndDestroy(2, string0);
       
   396 
       
   397     User::LeaveIfError(iDataLdd.FinalizeInterface());
       
   398     OstTraceFunctionExit1( CNCMCLIENTMANAGER_SETDATAINTERFACEL_EXIT, this );
       
   399     }
       
   400 
       
   401 /**
       
   402  * Setup the Class Descriptors
       
   403  * @param aDataInterfaceNumber The interface number of the data class
       
   404  * @return Error.
       
   405  */
       
   406 TInt CNcmClientManager::SetupClassSpecificDescriptor(TUint8 aDataInterfaceNumber)
       
   407     {
       
   408     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_ENTRY, this );
       
   409     
       
   410     TInt res;
       
   411 
       
   412     TNcmClassDescriptor descriptor;   
       
   413 
       
   414     // Header Functional Descriptor- CDC spec table 15
       
   415     descriptor.iHdrSize = 0x05;
       
   416     descriptor.iHdrType = 0x24;
       
   417     descriptor.iHdrSubType = 0x00;
       
   418     descriptor.iHdrBcdCDC = 0x0120;
       
   419 
       
   420     // Ethernet Networking Functional Descriptor-    ECM spec table 3
       
   421     descriptor.iEthFunLength = 0x0D;
       
   422     descriptor.iEthFunType = 0x24;
       
   423     descriptor.iEthFunSubtype = 0x0F;
       
   424     
       
   425     // Generate the MAC address new NCM interface
       
   426     res = SetMacAddressString(descriptor.iMACAddress);
       
   427 
       
   428     if (res != KErrNone)
       
   429         {
       
   430         OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT, this, res );
       
   431         return res;
       
   432         }
       
   433 
       
   434     descriptor.iEthernetStatistics = 0;
       
   435     descriptor.iMaxSegmentSize = KEthernetFrameSize;
       
   436     descriptor.iNumberMCFilters = 0;
       
   437     descriptor.iNumberPowerFilters = 0;
       
   438 
       
   439     // NCM Functional Descriptor-    NCM spec table 5-2
       
   440     descriptor.iNcmFunLength = 0x06;
       
   441     descriptor.iNcmFunType = 0x24;
       
   442     descriptor.iNcmFunSubtype = 0x1A;
       
   443     descriptor.iNcmVersion = 0x0100;
       
   444     descriptor.iNetworkCapabilities = 0;
       
   445 
       
   446     // Union functional descriptor- CDC spec table 16
       
   447     descriptor.iUnSize = 0x05;
       
   448     descriptor.iUnType = 0x24;
       
   449     descriptor.iUnSubType = 0x06;
       
   450     descriptor.iUnMasterInterface = 0;
       
   451     descriptor.iUnSlaveInterface = aDataInterfaceNumber;
       
   452 
       
   453     OstTrace0( TRACE_NORMAL, CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_PRE_SET_BLOCK, "About to call SetCSInterfaceDescriptorBlock" );
       
   454     res = iCommLdd.SetCSInterfaceDescriptorBlock(0, descriptor.Des());
       
   455     if (res != KErrNone)
       
   456         {
       
   457         OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT_DUP1, this, res );
       
   458         return res;
       
   459         }
       
   460 
       
   461     OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETUPCLASSSPECIFICDESCRIPTOR_EXIT_DUP2, this, KErrNone );
       
   462     return KErrNone;
       
   463     }
       
   464 
       
   465 /**
       
   466  * Set the MAC address string in descriptor
       
   467  * @param aStrIndex the MAC address string index
       
   468  */
       
   469 TInt CNcmClientManager::SetMacAddressString(TUint8& aStrIndex)
       
   470     {
       
   471     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_SETMACADDRESSSTRING_ENTRY, this );
       
   472     
       
   473     TBuf16<KMacAddrStringDescSize> str;
       
   474     
       
   475     // Search for MAC address string from index 0x10
       
   476     aStrIndex = 0x10;
       
   477 
       
   478     TInt ret = KErrNone;
       
   479 #ifndef OVERDUMMY_NCMCC
       
   480     while (aStrIndex++ < 0xFF && ret != KErrNotFound)
       
   481         {
       
   482         ret = iDataLdd.GetStringDescriptor(aStrIndex, str);
       
   483         }
       
   484 #endif // OVERDUMMY_NCMCC
       
   485 
       
   486     if (aStrIndex < 0xFF)
       
   487         {
       
   488         TBuf8<KEthernetAddressLength*2> macAddrStr;
       
   489         _LIT8(KMacAddressFormat, "%02X%02X%02X%02X%02X%02X");
       
   490         OstTraceExt1(TRACE_NORMAL, CNCMCLIENTMANAGER_SETMACADDRESSSTRING, "The MAC address is %s", iHostMacAddress);
       
   491         macAddrStr.AppendFormat(KMacAddressFormat, iHostMacAddress[0],
       
   492                 iHostMacAddress[1], iHostMacAddress[2], iHostMacAddress[3],
       
   493                 iHostMacAddress[4], iHostMacAddress[5]);
       
   494         str.Copy(macAddrStr);
       
   495         ret = iDataLdd.SetStringDescriptor(aStrIndex, str);
       
   496         }
       
   497     
       
   498     OstTraceFunctionExitExt( CNCMCLIENTMANAGER_SETMACADDRESSSTRING_EXIT, this, ret );
       
   499     return ret;
       
   500     }
       
   501 
       
   502 /**
       
   503  * Get NCM data interface number
       
   504  * @param aInterfaceNumber NCM data interface number
       
   505  * @return Error.
       
   506  */
       
   507 TInt CNcmClientManager::DataInterfaceNumber(TUint8& aInterfaceNumber)
       
   508     {
       
   509     OstTraceFunctionEntryExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_ENTRY, this );
       
   510     
       
   511     TInt interfaceSize = 0;
       
   512 
       
   513     // 0 means the main interface in the LDD API
       
   514     TInt res = iDataLdd.GetInterfaceDescriptorSize(0, interfaceSize);
       
   515 
       
   516     if ( KErrNone == res )
       
   517         {
       
   518         OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT, this, res );
       
   519         return res;
       
   520         }
       
   521 
       
   522     HBufC8* interfaceBuf = HBufC8::New(interfaceSize);
       
   523     if ( !interfaceBuf )
       
   524         {
       
   525         OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP1, this, KErrNoMemory);
       
   526         return KErrNoMemory;
       
   527         }
       
   528 
       
   529     TPtr8 interfacePtr = interfaceBuf->Des();
       
   530     interfacePtr.SetLength(0);
       
   531     // 0 means the main interface in the LDD API
       
   532     res = iDataLdd.GetInterfaceDescriptor(0, interfacePtr); 
       
   533 
       
   534     if ( KErrNone == res )
       
   535         {
       
   536         delete interfaceBuf;
       
   537         OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP2, this, res );
       
   538         return res;
       
   539         }
       
   540 
       
   541     OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER_INTERFACE_INFO, "***Interface length =% d", interfacePtr.Length());
       
   542     for ( TInt i = 0 ; i < interfacePtr.Length() ; i++ )
       
   543         {
       
   544         OstTrace1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER_INTERFACE_INFO2, "***** %x", interfacePtr[i]);
       
   545         }
       
   546 
       
   547     const TUint8* buffer = reinterpret_cast<const TUint8*>(interfacePtr.Ptr());
       
   548     // 2 is where the interface number is, according to the LDD API
       
   549     aInterfaceNumber = buffer[2];
       
   550     OstTraceExt1(TRACE_NORMAL, CNCMCLIENTMANAGER_DATAINTERFACENUMBER, "Interface number = %hhu", aInterfaceNumber);
       
   551 
       
   552     delete interfaceBuf;
       
   553 
       
   554     OstTraceFunctionExitExt( CNCMCLIENTMANAGER_DATAINTERFACENUMBER_EXIT_DUP3, this, KErrNone );
       
   555     return KErrNone;
       
   556     }