diff -r 0aa8cc770c8a -r 4a793f564d72 localconnectivityservice/dun/plugins/src/usb/DunUsbPlugin.cpp --- a/localconnectivityservice/dun/plugins/src/usb/DunUsbPlugin.cpp Tue Aug 31 16:03:15 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,781 +0,0 @@ -/* -* Copyright (c) 2006-2007 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: DUN USB plugin -* -*/ - - -#include -#include -#include "DunPlugin.h" -#include "DunUtils.h" -#include "DunUsbPlugin.h" -#include "DunDebug.h" - -_LIT( KUsbCsyName, "ECACM" ); -_LIT( KUsbPortName, "ACM" ); -_LIT( KUsbPortPort, "::" ); -_LIT( KUsbLddName, "EUSBC" ); -_LIT( KUsbChannelName, "DUNUSB::" ); - -const TInt KCharactersInTInt = 10; // For "2147483648" -const TUint8 KDefaultAcmProtocolNum = 0x01; // Hayes compatible modem - -// ======== MEMBER FUNCTIONS ======== - -// --------------------------------------------------------------------------- -// CDunUsbPlugin::CDunUsbPlugin -// --------------------------------------------------------------------------- -// -CDunUsbPlugin::CDunUsbPlugin() : - iServer( NULL ), - iUsbListen( NULL ), - iUsbConfig( NULL ), - iTransporter( NULL ) - { - } - -// --------------------------------------------------------------------------- -// Destructor. -// --------------------------------------------------------------------------- -// -CDunUsbPlugin::~CDunUsbPlugin() - { - FTRACE(FPrint( _L( "CDunUsbPlugin::~CDunUsbPlugin()" ) )); - Uninitialize(); - FTRACE(FPrint( _L( "CDunUsbPlugin::~CDunUsbPlugin() complete" ) )); - } - -// --------------------------------------------------------------------------- -// State of this plugin -// --------------------------------------------------------------------------- -// -TDunPluginState CDunUsbPlugin::PluginState() - { - return iServer->GetPluginStateByUid( KDunUsbPluginUid ); - } - -// --------------------------------------------------------------------------- -// Constructs a listener object for this plugin -// --------------------------------------------------------------------------- -// -void CDunUsbPlugin::ConstructListenerL() - { - FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL()"))); - if ( PluginState() != EDunStateLoaded ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() (not ready) complete"))); - User::Leave( KErrNotReady ); - } - ReportStateChangeUp( EDunStateTryListen ); - if ( iUsbListen ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() (already exists) complete"))); - User::Leave( KErrAlreadyExists ); - } - InitUsbL(); - CDunUsbListen* listen = CDunUsbListen::NewL( iServer, this, iUsbServer ); - CleanupStack::PushL( listen ); - TInt retTemp = listen->IssueRequestL(); - CleanupStack::Pop( listen ); - iUsbListen = listen; - // Here return value of KErrAlreadyExists means the device is already - // configured - // In this case we have to switch directly to channeled mode - ReportStateChangeUp( EDunStateListening ); - if ( retTemp == KErrAlreadyExists ) - { - TBool noFreeChans = EFalse; - // noFreeChans will be omitted (not needed to set to RComm) - NotifyChannelAllocate( noFreeChans ); // Create channel and change state - } - FTRACE(FPrint(_L("CDunUsbPlugin::ConstructListenerL() complete"))); - } - -// --------------------------------------------------------------------------- -// Initializes USB by loading LDD -// --------------------------------------------------------------------------- -// -void CDunUsbPlugin::InitUsbL() - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL()") )); - // Load Logical device driver for USB - FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() LoadLogicalDevice") )); - TInt retTemp = User::LoadLogicalDevice( KUsbLddName ); - if ( retTemp!=KErrAlreadyExists && retTemp!=KErrNone ) - { - User::Leave( retTemp ); - } - // Connect to the USB Manager server - FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() Connect()") )); - User::LeaveIfError( iUsbServer.Connect() ); - // Create USB configuration accessor and listener - iUsbConfig = CDunUsbConfig::NewL( iServer, this, KDefaultAcmProtocolNum ); - FTRACE(FPrint( _L( "CDunUsbPlugin::InitUsbL() complete") )); - } - -// --------------------------------------------------------------------------- -// Initializes all usable USB ports for DUN -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::InitPorts() - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() (num=%d)" ), iUsbPorts.Count())); - TInt i; - TInt retTemp = CreateAllPorts(); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitPorts() (ERROR) complete" ))); - return retTemp; - } - TInt count = iUsbPorts.Count(); - for ( i=0; iStop(); - // Find out what ports can be supported and append them to array - TBool validConfig; - TUsbPortEntity entity; - for ( TInt i=0;; i++ ) - { - retTemp = iUsbConfig->GetConfigValidityByIndex( i, validConfig ); - if ( retTemp != KErrNone ) - { - break; - } - if ( !validConfig ) - { - continue; - } - // Valid config found, append it to array - entity.iPortNum = i; - retTemp = iUsbPorts.Append( entity ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() (append failed!) complete" ) )); - return retTemp; - } - } - FTRACE(FPrint( _L( "CDunUsbPlugin::CreateAllPorts() complete" ) )); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Initializes one USB port for DUN -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::InitOnePort( TUsbPortEntity* aEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort()" ))); - if ( !aEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() (not initialized!) complete" ))); - return KErrGeneral; - } - TInt retTemp; - TName portName; - portName.Copy( KUsbPortName ); - portName.Append( KUsbPortPort ); - portName.AppendNum( aEntity->iPortNum ); - retTemp = aEntity->iUsbPort.Open( iCommServer, - portName, - ECommExclusive, - ECommRoleDCE ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() Open failed (%d)" ), retTemp)); - return retTemp; - } - TRAPD( retTrap, SetChannelL(aEntity) ); - if ( retTrap != KErrNone ) - { - iTransporter->FreeChannel( &aEntity->iUsbPort ); - FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() (trapped!) complete" ))); - return retTrap; - } - FTRACE(FPrint( _L( "CDunUsbPlugin::InitOnePort() complete" ))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Sets channel for one USB port -// --------------------------------------------------------------------------- -// -void CDunUsbPlugin::SetChannelL( TUsbPortEntity* aEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL()" ))); - if ( !aEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL() (not initialized!) complete" ))); - User::Leave( KErrGeneral ); - } - HBufC8* channelName = HBufC8::NewMaxLC( KUsbChannelName().Length() + - KCharactersInTInt ); - TPtr8 channelNamePtr = channelName->Des(); - channelNamePtr.Copy( KUsbChannelName ); - channelNamePtr.AppendNum( aEntity->iPortNum ); - iTransporter->AllocateChannelL( &aEntity->iUsbPort, - KDunUsbPluginUid, - channelNamePtr, - ETrue, - this ); - AddSkippedErrorL( KErrUsbInterfaceChange, &aEntity->iUsbPort ); - iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, - this, - EDunReaderUpstream, - EFalse ); - iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, - this, - EDunWriterUpstream, - EFalse ); - iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, - this, - EDunReaderDownstream, - EFalse ); - iTransporter->AddConnMonCallbackL( &aEntity->iUsbPort, - this, - EDunWriterDownstream, - EFalse ); - iTransporter->IssueTransferRequestsL( &aEntity->iUsbPort ); - CleanupStack::PopAndDestroy( channelName ); - FTRACE(FPrint( _L( "CDunUsbPlugin::SetChannelL() complete" ))); - } - -// --------------------------------------------------------------------------- -// Adds skipped error code to Transporter -// The skipped error is added to local media's read and write operations -// --------------------------------------------------------------------------- -// -void CDunUsbPlugin::AddSkippedErrorL( TInt aError, RComm* aComm ) - { - iTransporter->AddSkippedErrorL( aError, aComm, EDunReaderUpstream ); - iTransporter->AddSkippedErrorL( aError, aComm, EDunWriterDownstream ); - } - -// --------------------------------------------------------------------------- -// Sets new state -// New state must be one more than the old state -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::ReportStateChangeUp( TDunPluginState aPluginState ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp()"))); - TInt retTemp = iServer->NotifyPluginStateChangeUp( aPluginState, - KDunUsbPluginUid ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp() (ERROR) complete"))); - return retTemp; - } - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeUp() complete"))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Sets new state -// New state must be one less than the old state -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::ReportStateChangeDown( TDunPluginState aPluginState ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown()"))); - TInt retTemp = iServer->NotifyPluginStateChangeDown( aPluginState, - KDunUsbPluginUid ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown() (ERROR) complete"))); - return retTemp; - } - FTRACE(FPrint(_L("CDunUsbPlugin::ReportStateChangeDown() complete"))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Frees existing channels -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::FreeChannels() - { - FTRACE(FPrint(_L("CDunUsbPlugin::FreeChannels()"))); - if ( PluginState() != EDunStateTryUninitialize ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::FreeChannels() (not ready) complete" ) )); - return KErrNotReady; - } - TInt i; - TInt count = iUsbPorts.Count(); - for ( i=0; iFreeChannel( &iUsbPorts[i].iUsbPort ); - iUsbPorts[i].iUsbPort.SetSignals( 0, KSignalDCEOutputs ); - iUsbPorts[i].iUsbPort.Close(); - } - } - iUsbPorts.Close(); - if ( iCommServer.Handle() != KNullHandle ) - { - iCommServer.UnloadCommModule( KUsbCsyName ); - iCommServer.Close(); - } - FTRACE(FPrint(_L("CDunUsbPlugin::FreeChannels() complete"))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Uninitializes this plugin -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::Uninitialize() - { - FTRACE(FPrint( _L( "CDunUsbPlugin::Uninitialize()" ) )); - ReportStateChangeDown( EDunStateTryUninitialize ); - // Free channel(s), ignore errors - FreeChannels(); - delete iUsbListen; // delete before iUsbServer close - iUsbListen = NULL; - delete iUsbConfig; - iUsbConfig = NULL; - if ( iUsbServer.Handle() != KNullHandle ) - { - iUsbServer.Close(); - } - User::FreeLogicalDevice( KUsbLddName ); - ReportStateChangeUp( EDunStateUninitialized ); - ReportStateChangeUp( EDunStateTryLoad ); - ReportStateChangeUp( EDunStateLoaded ); - FTRACE(FPrint( _L( "CDunUsbPlugin::Uninitialize() complete" ) )); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// Gets port's index and entity by connection ID -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::GetEntityByConnId( TConnId aConnId, - TUsbPortEntity*& aEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::GetEntityByConnId()")) ); - TInt i; - TInt count = iUsbPorts.Count(); - for ( i=0; iIssueRequest(); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() (ERROR) complete"))); - return retTemp; - } - iShutdown = EFalse; - ReportStateChangeUp( EDunStateChanneled ); - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelAllocate() complete"))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// From class MDunListenCallback. -// Gets called when an existing channel must be freed -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::NotifyChannelFree() - { - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree()"))); - if ( PluginState() != EDunStateChanneled ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() (not ready) complete"))); - return KErrNotReady; - } - // Cable removed or PC sleep, hibernate or reset. - // Just remove channels. - ReportStateChangeDown( EDunStateTryUninitialize ); - TInt retTemp = FreeChannels(); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() (ERROR) complete"))); - return retTemp; - } - ReportStateChangeUp( EDunStateUninitialized ); - ReportStateChangeUp( EDunStateTryLoad ); - ReportStateChangeUp( EDunStateLoaded ); - ReportStateChangeUp( EDunStateTryListen ); - ReportStateChangeUp( EDunStateListening ); - FTRACE(FPrint(_L("CDunUsbPlugin::NotifyChannelFree() complete"))); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// From class MDunConnMon. -// Gets called when line status changes or when any type of error is detected -// --------------------------------------------------------------------------- -// -void CDunUsbPlugin::NotifyProgressChangeL( - TConnId aConnId, - TDunConnectionReason aConnReason ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL()")) ); - // Find matching failed ID - TUsbPortEntity* foundEntity = NULL; - TInt foundIndex = GetEntityByConnId( aConnId, foundEntity ); - if ( !foundEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (not found) complete")) ); - User::Leave( KErrNotFound ); - } - if ( aConnReason.iReasonType == EDunReasonTypeRW || - aConnReason.iReasonType == EDunReasonTypeRunL ) - { - // The following check will make it possible for CDunUsbListen to react - // to cable removal (iUsbPort.SubSessionHandle() ) - { - iTransporter->FreeChannel( &foundEntity->iUsbPort ); - foundEntity->iUsbPort.SetSignals( 0, KSignalDCEOutputs ); - foundEntity->iUsbPort.Close(); - } - TInt retTemp = InitOnePort( foundEntity ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() (ERROR) complete")) ); - User::Leave( KErrGeneral ); - } - // Now this plugin was basically "restarted", but only for one - // channel. Because transporter has channels with waiters, notify - // server to reopen queued plugin(s) - iServer->NotifyPluginReopenRequest(); - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyProgressChangeL() complete")) ); - } - -// --------------------------------------------------------------------------- -// From class MDunBufferCorrection. -// Gets called when request to change local media's buffer size -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::NotifyBufferCorrection( TInt aLength ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyBufferCorrection()")) ); - /* - * This method modifies the default buffer length to match the maximum value - * used by "CanHandleZLP=0" configuration option. This length is nearest length - * divisible by 64 - 1. With slow USB compared to high speed HSDPA some products - * can start to collect data to Dataport which results in full packet writes to - * USB. However, the default full packet must not be divisible by 64, which results - * in the ACM to send the full packet to LDD plus one extra packet with one byte - * (disabling interrupts for a long time with current non-DMA USB driver). - */ - TInt newLength = aLength; - if ( newLength % 64 == 0 ) - { - newLength = ((aLength >> 6) << 6) - 1; - } - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyBufferCorrection() complete")) ); - return newLength; - } - -// --------------------------------------------------------------------------- -// From class MDunUsbConfig. -// Gets called when one or more ACM configurations are added -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::NotifyConfigAddition( TInt aIndex ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition()")) ); - // Configuration added so aIndex is the port number to be added to array. - // This port number must not already exist in the array. - TUsbPortEntity* foundEntity = NULL; - TInt foundIndex = GetEntityByPortNumber( aIndex, foundEntity ); - if ( foundEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (already exists) complete")) ); - return KErrAlreadyExists; - } - // Now either find port with KErrNotFound set as port number or if that is - // not found then try to append to array - foundIndex = GetFirstFreeEntity( foundEntity ); - if ( !foundEntity ) // free not found so add new - { - // Now append the new port to array - TUsbPortEntity newEntity; - newEntity.iPortNum = aIndex; - TInt retTemp = iUsbPorts.Append( newEntity ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (append failed!) complete")) ); - return KErrGeneral; - } - // entity not valid here so set now - foundEntity = &iUsbPorts[iUsbPorts.Count()-1]; - } - else // free found so change array - { - foundEntity->iPortNum = aIndex; - } - // Open port and create channel for it - TInt retTemp = InitOnePort( foundEntity ); - if ( retTemp != KErrNone ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() (ERROR) complete" ))); - return KErrGeneral; - } - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigAddition() complete")) ); - return KErrNone; - } - -// --------------------------------------------------------------------------- -// From class MDunUsbConfig. -// Gets called when one or more ACM configurations are removed -// --------------------------------------------------------------------------- -// -TInt CDunUsbPlugin::NotifyConfigRemoval( TInt aIndex ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval()")) ); - // Configuration removed so aIndex is the port number to be added to array. - // This port number must already exist in the array. - TUsbPortEntity* foundEntity = NULL; - TInt foundIndex = GetEntityByPortNumber( aIndex, foundEntity ); - if ( !foundEntity ) - { - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval() (not found) complete")) ); - return KErrNotFound; - } - // Now free channel and mark as unused - iTransporter->FreeChannel( &foundEntity->iUsbPort ); - foundEntity->iUsbPort.SetSignals( 0, KSignalDCEOutputs ); - foundEntity->iUsbPort.Close(); - iUsbPorts[foundIndex].iPortNum = KErrNotFound; - FTRACE(FPrint( _L( "CDunUsbPlugin::NotifyConfigRemoval() complete")) ); - return KErrNone; - } - -// ======== GLOBAL FUNCTIONS ======== - -// --------------------------------------------------------------------------- -// NewLocalPluginL implements factory construction for -// the class CDunUsbPlugin. -// The function is exported at ordinal 1. -// Returns: Pointer: The new instance of CDunUsbPlugin -// --------------------------------------------------------------------------- -// -EXPORT_C MDunLocalMediaPlugin* NewLocalPluginL() - { - return new (ELeave) CDunUsbPlugin; - }