--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/localconnectivityservice/dun/server/src/DunServerUtils.cpp Mon Jan 18 21:03:15 2010 +0200
@@ -0,0 +1,497 @@
+/*
+* 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: Utility class for CDunServer
+*
+*/
+
+
+#include <e32uid.h>
+#include "DunServer.h"
+#include "DunServerUtils.h"
+#include "DunDebug.h"
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+CDunServerUtils* CDunServerUtils::NewL( CDunServer& aParent )
+ {
+ CDunServerUtils* self = new (ELeave) CDunServerUtils( aParent );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// Destructor.
+// ---------------------------------------------------------------------------
+//
+CDunServerUtils::~CDunServerUtils()
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::~CDunServerUtils()")));
+ FTRACE(FPrint(_L("CDunServerUtils::~CDunServerUtils() complete")));
+ }
+
+// ---------------------------------------------------------------------------
+// CDunServerUtils::CDunServerUtils
+// ---------------------------------------------------------------------------
+//
+CDunServerUtils::CDunServerUtils( CDunServer& aParent ) :
+ iParent( aParent ),
+ iTransporter( aParent.iTransporter ),
+ iCloseWait( aParent.iCloseWait ),
+ iConnData( aParent.iConnData ),
+ iPluginQueue( aParent.iPluginQueue ),
+ iClosedQueue( aParent.iClosedQueue )
+ {
+ }
+
+// ---------------------------------------------------------------------------
+// CDunServerUtils::ConstructL
+// ---------------------------------------------------------------------------
+//
+void CDunServerUtils::ConstructL()
+ {
+ FTRACE(FPrint( _L("CDunServerUtils::ConstructL()" ) ));
+ FTRACE(FPrint( _L("CDunServerUtils::ConstructL() complete" ) ));
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Closes plugins with state marked as zombie
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::RemoveZombiePlugins()
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::RemoveZombiePlugins()")));
+ TInt i;
+ TInt retVal = KErrNone;
+ for ( i=iConnData.Count()-1; i>=0; i-- )
+ {
+ if ( iConnData[i].iPluginState == EDunStateZombie )
+ {
+ // Following closes and removes if remove ok
+ FTRACE(FPrint(_L("CDunServerUtils::RemoveZombiePlugins() trying close at index %d"), i));
+ TInt retTemp = TryClosePlugin( i, ETrue, EFalse, EFalse );
+ if ( retTemp != KErrNone )
+ {
+ retVal = KErrGeneral;
+ }
+ }
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::RemoveZombiePlugins() complete")));
+ return retVal;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Loads local media module
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::CreateNewPlugin( TUid aPluginUid )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::CreateNewPlugin()")));
+ // plugin not constructed, construct now
+ TFileName pluginFile;
+ switch ( aPluginUid.iUid )
+ {
+ case KDunBtPluginUidValue:
+ pluginFile.Copy( KDunPluginBt );
+ break;
+ case KDunIrPluginUidValue:
+ pluginFile.Copy( KDunPluginIrda );
+ break;
+ case KDunUsbPluginUidValue:
+ pluginFile.Copy( KDunPluginUsb );
+ break;
+ default:
+ FTRACE(FPrint(_L("CDunServerUtils::CreateNewPlugin() (not supported) complete")));
+ return KErrNotSupported;
+ }
+ TDunConnectionData emptyConn;
+ emptyConn.iLocalModulePtr = NULL;
+ emptyConn.iLocalModuleUid = TUid::Null();
+ emptyConn.iPluginState = EDunStateNone;
+ TInt retTemp = iConnData.Append( emptyConn );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::CreateNewPlugin() (append failed!) complete")));
+ return retTemp;
+ }
+ retTemp = ConstructLocalMediaModule( aPluginUid, pluginFile );
+ if ( retTemp != KErrNone )
+ {
+ iConnData.Remove( iConnData.Count()-1 );
+ FTRACE(FPrint(_L("CDunServerUtils::CreateNewPlugin() (ERROR) complete")));
+ return retTemp;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::CreateNewPlugin() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Constructs local media module
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::ConstructLocalMediaModule( const TUid& aPluginUid,
+ const TPtrC& aDllName )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule()")));
+ // Create a new library object
+ if ( iConnData.Count() == 0 )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() (not ready) complete")));
+ return KErrNotReady;
+ }
+ TInt index = iConnData.Count() - 1;
+ iConnData[index].iLocalModuleUid = aPluginUid;
+ iConnData[index].iPluginState = EDunStateTryLoad;
+ // Load the DLL containing the plug-in
+ TUidType uidType( KDynamicLibraryUid,
+ KDunLocalMediaPluginInterfaceUid,
+ aPluginUid );
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() loading")));
+ TInt retTemp = iConnData[index].iModuleLibrary.Load( aDllName, uidType );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() (ERROR) complete")));
+ return retTemp;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() plugin 0x%08X loaded"), aPluginUid.iUid));
+ // Create the plugin object.
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() looking up")));
+ TLibraryFunction factoryFunction = iConnData[index].iModuleLibrary.Lookup( 1 );
+ if ( !factoryFunction )
+ {
+ iConnData[index].iModuleLibrary.Close();
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() (ERROR) complete")));
+ return KErrNotFound;
+ }
+ MDunLocalMediaPlugin* localPlugin =
+ reinterpret_cast<MDunLocalMediaPlugin*>( factoryFunction() );
+ if ( !localPlugin )
+ {
+ iConnData[index].iModuleLibrary.Close();
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() (ERROR) complete")));
+ return KErrGeneral;
+ }
+ iConnData[index].iLocalModulePtr = localPlugin;
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() constructing")));
+ TRAPD( retTrap, localPlugin->ConstructL(&iParent, iTransporter) );
+ if ( retTrap != KErrNone )
+ {
+ delete iConnData[index].iLocalModulePtr;
+ iConnData[index].iLocalModulePtr = NULL;
+ iConnData[index].iModuleLibrary.Close();
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() (ERROR) complete")));
+ return retTrap;
+ }
+ iConnData[index].iPluginState = EDunStateLoaded;
+ FTRACE(FPrint(_L("CDunServerUtils::ConstructLocalMediaModule() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Clears queued UIDs
+// ---------------------------------------------------------------------------
+//
+TBool CDunServerUtils::ClearQueuedUIDs( TUid aPluginUid,
+ TBool aClearClosed,
+ TBool aClearQueued )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::ClearQueuedUIDs()")));
+ TInt i;
+ TBool cleared = EFalse;
+ if ( aClearClosed )
+ {
+ for ( i=iClosedQueue.Count()-1; i>=0; i-- )
+ {
+ if ( iClosedQueue[i] == aPluginUid )
+ {
+ iClosedQueue.Remove( i );
+ cleared = ETrue;
+ FTRACE(FPrint(_L("CDunServerUtils::ClearQueuedUIDs() removed from closed queue at %d"), i));
+ }
+ }
+ }
+ if ( aClearQueued )
+ {
+ for ( i=iPluginQueue.Count()-1; i>=0; i-- )
+ {
+ if ( iPluginQueue[i] == aPluginUid )
+ {
+ iPluginQueue.Remove( i );
+ cleared = ETrue;
+ FTRACE(FPrint(_L("CDunServerUtils::ClearQueuedUIDs() removed from plugin queue at %d"), i));
+ }
+ }
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::ClearQueuedUIDs() complete")));
+ return cleared;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Tries to close loaded local media plugin
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::TryClosePlugin( TInt aIndex,
+ TBool aDequeue,
+ TBool aClientClose,
+ TBool aSelfClose )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin()")));
+ if ( aIndex < 0 ||
+ aIndex >= iConnData.Count() )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() (not found) complete")));
+ return KErrNotFound;
+ }
+ TInt retTemp = TryUninitialize( aIndex );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() (ERROR) complete")));
+ return retTemp;
+ }
+ if ( !aSelfClose )
+ {
+ retTemp = DoClosePlugin( aIndex, aDequeue, aClientClose );
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() complete")));
+ return retTemp;
+ }
+ retTemp = iCloseWait->AddPluginToClose( iConnData[aIndex].iLocalModulePtr );
+ if ( retTemp != KErrNone )
+ {
+ iConnData[aIndex].iPluginState = EDunStateZombie;
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() state changed to %d"), EDunStateZombie));
+ return retTemp;
+ }
+ retTemp = iCloseWait->IssueRequest();
+ if ( retTemp != KErrNone )
+ {
+ iConnData[aIndex].iPluginState = EDunStateZombie;
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() state changed to %d"), EDunStateZombie));
+ return retTemp;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryClosePlugin() (waiting) complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Closes a plugin directly without uninitializing it
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::DoClosePlugin(
+ TInt aIndex,
+ TBool aDequeue,
+ TBool aClientClose )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin()")));
+ if ( aIndex < 0 ||
+ aIndex >= iConnData.Count() )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin() (not found) complete")));
+ return KErrNotFound;
+ }
+ TUid pluginUid = iConnData[aIndex].iLocalModuleUid;
+ DoImmediatePluginClose( aIndex, aDequeue );
+ if ( !aClientClose )
+ {
+ // Plugin was closed by something else than client
+ // Enqueue it to closed queue
+ TInt i;
+ TInt count = iClosedQueue.Count();
+ for ( i=0; i<count; i++ )
+ {
+ if ( iClosedQueue[i] == pluginUid )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin() (already exists) complete")));
+ return KErrAlreadyExists;
+ }
+ }
+ TInt retTemp = iClosedQueue.Append( pluginUid );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin() (append failed!) complete")));
+ return retTemp;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin() appended to index %d"), iClosedQueue.Count()-1));
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::DoClosePlugin() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Does immediate close of plugin
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::DoImmediatePluginClose( TInt aIndex, TBool aDequeue )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoImmediatePluginClose()")));
+ if ( aIndex < 0 ||
+ aIndex >= iConnData.Count() )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::DoImmediatePluginClose() (not found) complete")));
+ return KErrNotFound;
+ }
+ delete iConnData[aIndex].iLocalModulePtr;
+ iConnData[aIndex].iLocalModulePtr = NULL;
+ if ( iConnData[aIndex].iModuleLibrary.Handle() != KNullHandle )
+ {
+ iConnData[aIndex].iModuleLibrary.Close();
+ }
+ iConnData.Remove( aIndex );
+ // Now, the following check is needed to avoid recursion by:
+ // ReopenQueuedPlugins()->OpenMediaByUid()->TryClosePlugin()->
+ // DoImmediatePluginClose()->ReopenQueuedPlugins()
+ if ( aDequeue )
+ {
+ iParent.ReopenQueuedPlugins();
+ }
+ // Ignore error(s); this function must only report it's own operation status
+ FTRACE(FPrint(_L("CDunServerUtils::DoImmediatePluginClose() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Tries uninitialization and after that listening state switch on a plugin
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::TryInitializeToListening( TUid aPluginUid )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryInitializeToListening()")));
+ TInt i;
+ TInt count = iConnData.Count();
+ for ( i=0; i<count; i++ )
+ {
+ if ( iConnData[i].iLocalModuleUid == aPluginUid )
+ {
+ break;
+ }
+ }
+ if ( i >= count )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryInitializeToListening() (not found) complete")));
+ return KErrNotFound;
+ }
+ TInt retTemp = TryUninitialize( i );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryInitializeToListening() (uninitialize error) complete")));
+ return retTemp;
+ }
+ // Change from Uninitialized to Loaded because listening mode needs it
+ // (plugin is already loaded anyway)
+ iConnData[i].iPluginState = EDunStateLoaded;
+ retTemp = TryListening( i );
+ if ( retTemp != KErrNone )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryInitializeToListening() (listening error) complete")));
+ return retTemp;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryInitializeToListening() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Tries listening state switch on a plugin
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::TryListening( TInt aIndex )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening()")));
+ if ( aIndex < 0 ||
+ aIndex >= iConnData.Count() )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() (not found) complete")));
+ return KErrNotFound;
+ }
+ if ( iConnData[aIndex].iPluginState != EDunStateLoaded )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() (not ready) complete")));
+ return KErrNotReady;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() notifying server state change (%d)"), EDunStateTryListen));
+ TInt retTemp =
+ iConnData[aIndex].iLocalModulePtr->NotifyServerStateChange( EDunStateTryListen );
+ if ( retTemp != KErrNone )
+ {
+ iConnData[aIndex].iPluginState = EDunStateZombie;
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() state changed to %d"), EDunStateZombie));
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() (ERROR) complete")));
+ return retTemp;
+ }
+ // Plugin could have changed state, only change state if possible
+ // This can happen if plugin has no real listening and switches directly
+ // from listening mode to channeled mode
+ if ( iConnData[aIndex].iPluginState == EDunStateTryListen )
+ {
+ iConnData[aIndex].iPluginState = EDunStateListening;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() state changed to %d"), EDunStateListening));
+ FTRACE(FPrint(_L("CDunServerUtils::TryListening() complete")));
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------------------------
+// From class MDunServerUtility.
+// Tries uninitialization of a plugin
+// ---------------------------------------------------------------------------
+//
+TInt CDunServerUtils::TryUninitialize( TInt aIndex )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize()")));
+ if ( aIndex < 0 ||
+ aIndex >= iConnData.Count() )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() (not found) complete")));
+ return KErrNotFound;
+ }
+ if ( iConnData[aIndex].iPluginState == EDunStateUninitialized )
+ {
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() (already uninitialized) complete")));
+ return KErrNotReady;
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() notifying server state change (%d)"), EDunStateTryUninitialize));
+ TInt retTemp =
+ iConnData[aIndex].iLocalModulePtr->NotifyServerStateChange( EDunStateTryUninitialize );
+ if ( retTemp != KErrNone )
+ {
+ iConnData[aIndex].iPluginState = EDunStateZombie;
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() state changed to %d"), EDunStateZombie));
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() (ERROR) complete")));
+ return retTemp;
+ }
+ // Plugin state must be EDunStateLoaded after uninitialization
+ if ( iConnData[aIndex].iPluginState == EDunStateLoaded )
+ {
+ iConnData[aIndex].iPluginState = EDunStateUninitialized;
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() state changed to %d"), EDunStateUninitialized));
+ }
+ else
+ {
+ // Should never come here
+ iConnData[aIndex].iPluginState = EDunStateZombie;
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() state changed to %d"), EDunStateZombie));
+ }
+ FTRACE(FPrint(_L("CDunServerUtils::TryUninitialize() complete")));
+ return KErrNone;
+ }