--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspotfw/hsserver/src/hotspotserver.cpp Thu Dec 17 09:20:28 2009 +0200
@@ -0,0 +1,711 @@
+/*
+* Copyright (c) 2002-2006 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 HotSpot Plugin Server
+*
+*/
+
+
+
+
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <f32file.h>
+#include <wlanmgmtclient.h>
+#include <wlanmgmtinterface.h>
+#include <e32std.h>
+#include <commsdattypesv1_1.h>
+
+#include <cmconnectionmethodext.h>
+#include <cmconnectionmethoddef.h>
+#include <cmpluginwlandef.h>
+#include <cmmanagerext.h>
+#include <cmmanagerdef.h>
+#include <cmdestinationext.h>
+
+#include "hotspotserver.h"
+#include "am_debug.h"
+#include "hotspotsession.h"
+#include "hssclientplugin.h"
+#include "hssiapsettingshandler.h"
+
+// LOCAL FUNCTION PROTOTYPES
+GLDEF_C TInt E32Main();
+
+using namespace CMManager;
+
+// CONSTANTS
+// Panic codes for HotSpot server
+const TInt KHotSpotPanicCleanupStackCreationFailed = 1;
+const TInt KHotSpotPanicOpenSemaforeFailed = 2;
+const TInt KHotSpotPanicCreationOfSchedulerFailed = 3;
+
+// Default timeout values
+
+const TUint KMillion = 1000000;
+const TUint KHssDefaultLoginTimeMicroSecs = 180 * KMillion; // 180 seconds (3 mins)
+const TUint KHssMinLoginTime = 5; // 5 seconds
+const TUint KHssMaxLoginTime = 1200; // 1200 seconds (20 mins)
+const TUint KHssDefaultLogoutTimeMicroSecs = 12 * KMillion; // 12 seconds
+const TUint KHssMinLogoutTime = 1; // 1 seconds
+const TUint KHssMaxLogoutTime = 30; // 30 seconds
+
+// Panic category of HotSpot server
+_LIT( KHotSpotModuleName, "HOTSPOTSRV" );
+
+// ============================= LOCAL FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// RunServerL
+// -----------------------------------------------------------------------------
+//
+static void RunServerL()
+ {
+ User::LeaveIfError( User::RenameThread( KHotSpotServerName ) );
+
+ CActiveScheduler* s=new(ELeave) CActiveScheduler;
+ if ( !s )
+ {
+ User::Panic( KHotSpotModuleName, KHotSpotPanicCreationOfSchedulerFailed );
+ }
+ CleanupStack::PushL(s);
+ CActiveScheduler::Install(s);
+
+ CHotSpotServer::NewLC(); // Is NewLC: Server was pushed into cleanup stack.
+
+ RSemaphore started;
+ TInt err = started.CreateGlobal( KHotSpotServerSemaphore, 0 );
+ if ( err != KErrNone )
+ {
+ err = started.OpenGlobal( KHotSpotServerSemaphore );
+ }
+
+ __ASSERT_ALWAYS(
+ err == KErrNone,
+ User::Panic( KHotSpotModuleName, KHotSpotPanicOpenSemaforeFailed )
+ );
+
+ // lets everyone know that the thread is ready to deal with requests
+ RProcess::Rendezvous(KErrNone);
+
+ started.Signal();
+ started.Close();
+
+ DEBUG("**** HotspotServer: server fully running");
+ CActiveScheduler::Start();
+ CleanupStack::PopAndDestroy( 2, s ); // Cleanup both server and scheduler
+ REComSession::FinalClose();
+ }
+
+// -----------------------------------------------------------------------------
+// PanicClient
+// -----------------------------------------------------------------------------
+//
+void PanicClient(const RMessagePtr2& aMessage,THotspotPanic aPanic)
+ {
+ _LIT(KPanic,"HotspotServer");
+ aMessage.Panic(KPanic,aPanic);
+ }
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHotSpotServer
+// -----------------------------------------------------------------------------
+//
+CHotSpotServer::CHotSpotServer()
+ :CPolicyServer( EPriorityStandard, THotSpotServerPlatSecPolicy, ESharableSessions )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// NewLC
+// -----------------------------------------------------------------------------
+//
+CHotSpotServer* CHotSpotServer::NewLC()
+ {
+ DEBUG("**** HotSpotServer: CHotSpotServer::NewLC");
+ CHotSpotServer* self = new(ELeave) CHotSpotServer;
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// ~CHotSpotServer
+// -----------------------------------------------------------------------------
+//
+CHotSpotServer::~CHotSpotServer()
+ {
+ DEBUG("**** HotSpotServer: CHotSpotServer::~CHotSpotServer");
+
+ iMap.Close();
+ iNotificationArray.Close();
+ iLoginLogoutTimerArray.Close();
+
+ if ( iMgtClient != NULL )
+ {
+#ifndef __WINS__
+ iMgtClient->CancelNotifications();
+#endif
+ delete iMgtClient;
+ }
+ iMgtClient = NULL;
+
+ }
+
+// -----------------------------------------------------------------------------
+// ConstructL
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::ConstructL()
+ {
+
+ DEBUG("**** HotSpotServer: CHotSpotServer::ConstructL");
+ StartL( KHotSpotServerName );
+
+ iIapCheckValue = EFalse;
+ iLogoutSent = EFalse;
+ iLoginValue = ETrue;
+ iAssociationValue = EFalse;
+
+#ifndef __WINS__
+
+ // Change config daemon for Easy WLAN access point
+ iConfigDaemonChanged = KErrNone;
+ TBool retVal( EFalse );
+ iEasyWlanId = KEasyWlanServiceId; // Set to default value
+ TRAPD( leave, retVal = EasyWlanIdL() );
+ if ( KErrNone != leave )
+ {
+ iConfigDaemonChanged = leave;
+ }
+ if ( !retVal )
+ {
+ iConfigDaemonChanged = KErrGeneral;
+ }
+ DEBUG1("**** HotSpotServer: CHotSpotServer::ConstructL iConfigDaemonChanged: %d", iConfigDaemonChanged );
+#endif
+ // Activate notifications for IAP check purposes
+ // When EWlanConnectionModeNotConnected is received we can cancel this and
+ // we know that it safe to go through IAPs.
+ iMgtClient = CWlanMgmtClient::NewL();
+#ifndef __WINS__
+ iMgtClient->ActivateNotificationsL( *this );
+#endif
+ }
+
+// -----------------------------------------------------------------------------
+// ConnectionStateChanged
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::ConnectionStateChanged( TWlanConnectionMode aNewState )
+ {
+ DEBUG1( "CHotSpotServer::ConnectionStateChanged() aNewState=%d", aNewState );
+ if ( aNewState == EWlanConnectionModeNotConnected )
+ {
+ if ( iMgtClient != NULL )
+ {
+#ifndef __WINS__
+ iMgtClient->CancelNotifications();
+#endif
+ DEBUG("CHotSpotServer::ConnectionStateChanged2");
+ }
+
+ TRAPD(err, CheckIapsL());
+ if ( err != KErrNone )
+ {
+ DEBUG1("CHotSpotServer::ConnectionStateChanged(): %d", err);
+ }
+ if ( iConfigDaemonChanged != KErrNone )
+ {
+ // ConstructL call leaved. Let's call again once more.
+ TRAP_IGNORE( EasyWlanIdL() );
+ }
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CheckIapsL
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::CheckIapsL()
+ {
+ DEBUG("CHotSpotServer::CheckIapsL");
+
+ _LIT(KMarkFirst, "[" );
+ _LIT(KMarkLast, "]" );
+ // This is needed to be checked only once per boot
+ if ( iIapCheckValue == EFalse )
+ {
+ iIapCheckValue = ETrue;
+
+ RCmManagerExt cmManager;
+ cmManager.OpenL();
+ CleanupClosePushL(cmManager);
+
+ TBool supportedBearersOnly = ETrue;
+ TBool legacyCmsOnly = EFalse;
+
+ RArray<TUint32> cmArray;
+ CleanupClosePushL( cmArray );
+
+ cmManager.ConnectionMethodL( cmArray, supportedBearersOnly, legacyCmsOnly );
+ DEBUG1("CHotSpotServer::CheckIapsL count: %d", cmArray.Count());
+ for( TInt i = 0; i < cmArray.Count(); i++ )
+ {
+ RCmConnectionMethodExt cm;
+ TRAPD( err, cm = cmManager.ConnectionMethodL( cmArray[i] ) );
+ DEBUG1("CHotSpotServer::CheckIapsL: err %d", err );
+ if ( KErrNone == err )
+ {
+ HBufC* client( NULL );
+ TRAPD( errr, client = cm.GetStringAttributeL( EWlanServiceExtensionTableName ));
+ DEBUG1("CHotSpotServer::CheckIapsL: errr %d", errr );
+ if( KErrNone == errr )
+ {
+ TBuf<KIapNameLength> clientUid;
+ TUid uid(TUid::Null());
+
+ clientUid.Copy( client->Des() );
+ delete client;
+ TInt indx = clientUid.Find( KMarkFirst );
+ if ( KErrNotFound != indx )
+ {
+ DEBUG("CHotSpotServer::CheckIapsL Client is found");
+ clientUid.Delete( indx, 1 );
+ indx = clientUid.Find( KMarkLast );
+ if ( KErrNotFound != indx )
+ {
+ clientUid.Delete( indx, 1 );
+ }
+ // Convert TBuf to TUid
+ TLex lex( clientUid );
+ TUint value( 0 );
+ User::LeaveIfError( lex.Val( value, EHex ) );
+ uid.iUid = value;
+
+ // Try to find if 3rd party client exists.
+ // Delete IAP if no client.
+ CHssClientPlugin* plugin(NULL);
+ TBuf8<KExtensionAPILength> nullBuf;
+ TRAPD( error, plugin = CHssClientPlugin::NewL( uid, nullBuf ) );
+ delete plugin;
+
+ DEBUG1("CHotSpotServer::CheckIapsL find client error: %d", error );
+ if ( error == KErrNotFound )
+ {
+ cm.DeleteL();
+ }
+ }
+ }
+ }
+ DEBUG("CHotSpotServer::CheckIapsLOK");
+ }
+ CleanupStack::PopAndDestroy( &cmArray );
+ CleanupStack::PopAndDestroy( &cmManager );
+ }
+ DEBUG("CHotSpotServer::CheckIapsL Done");
+ }
+
+// -----------------------------------------------------------------------------
+// NewSessionL
+// -----------------------------------------------------------------------------
+//
+CSession2* CHotSpotServer::NewSessionL( const TVersion& aVersion,
+ const RMessage2& /* aMessage */ ) const
+ {
+ TVersion version( KHotSpotMajorVersionNumber,
+ KHotSpotMinorVersionNumber,
+ KHotSpotBuildVersionNumber );
+
+ if ( !User::QueryVersionSupported( version, aVersion ) )
+ {
+ User::Leave( KErrNotSupported );
+ }
+
+ DEBUG("**** CHotSpotServer::NewSessionL");
+ CHotSpotSession* session =
+ CHotSpotSession::NewL( const_cast<CHotSpotServer&>( *this ) );
+ return session;
+ }
+
+// ---------------------------------------------------------
+// NotifyAdd
+// ---------------------------------------------------------
+//
+void CHotSpotServer::NotifyAdd(
+ CNotificationBase& aNotification )
+ {
+ DEBUG( "CHotSpotServer::NotifyAdd()" );
+ iNotificationArray.Insert( &aNotification, 0 );
+ }
+
+// ---------------------------------------------------------
+// NotifyRemove
+// ---------------------------------------------------------
+//
+void CHotSpotServer::NotifyRemove(
+ CNotificationBase& aNotification )
+ {
+ DEBUG( "CHotSpotServer::NotifyRemove()" );
+ TInt index = iNotificationArray.Find( &aNotification );
+ iNotificationArray.Remove( index );
+ }
+
+// -----------------------------------------------------------------------------
+// SaveMessage
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::SaveMessage( TUint aIapId, const RMessage2& aMessage,
+ THotSpotCommands aCommand )
+ {
+ DEBUG("**** HotspotServer: SaveMessage");
+ TInt ret( KErrNone );
+ SRequestMapEntry entry;
+ entry.iMessage = aMessage;
+ entry.iFunction = aCommand;
+ entry.iIapId = aIapId;
+ ret = iMap.Append(entry);
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// CompleteMessage
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::CompleteMessage( TInt aIndex, TInt aResult )
+ {
+ DEBUG("**** HotspotServer: CompleteMessage");
+ SRequestMapEntry entry = iMap[aIndex];
+
+ RMessagePtr2 message = entry.iMessage;
+ message.Complete( aResult );
+ iMap.Remove( aIndex );
+ }
+
+// -----------------------------------------------------------------------------
+// EditMessage
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::EditMessage( TInt aIndex, TPckg<HssScanList>& aData)
+ {
+ DEBUG("**** HotspotServer: EditMessage");
+ TInt ret( KErrNone );
+
+ iMap[aIndex].iMessage.Write(0, aData);
+
+ DEBUG1("**** HotspotServer: EditMessage ret: %d", ret);
+ return ret;
+ }
+
+
+// -----------------------------------------------------------------------------
+// FindMessage
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::FindMessage( TUint aIapId, THotSpotCommands aCommand )
+ {
+ DEBUG("**** HotspotServer: FindMessage");
+ TInt ret( KErrNotFound );
+ SRequestMapEntry entry;
+
+ for ( TInt i = 0; i < iMap.Count(); i++ )
+ {
+ entry = iMap[i];
+ if ( ( entry.iFunction == aCommand ) && ( entry.iIapId == aIapId ) )
+ {
+ // Correct message found
+ // Now stop loop and return index value, so that CompeteMessage can
+ // be called with that
+ ret = i;
+ i = iMap.Count();
+ }
+ }
+ DEBUG1("**** HotspotServer: FindMessage ret: %d", ret);
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// SetLogoutFlag
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::SetLogoutFlag( TBool aValue )
+ {
+ DEBUG("HotspotServer::SetLogoutFlag");
+ iLogoutSent = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// GetLogoutFlagValue
+// -----------------------------------------------------------------------------
+//
+TBool CHotSpotServer::GetLogoutFlagValue()
+ {
+ DEBUG("HotspotServer::GetLogoutFlagValue()");
+ return iLogoutSent;
+ }
+
+// -----------------------------------------------------------------------------
+// SetLoginFlag
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::SetLoginFlag( TBool aValue )
+ {
+ DEBUG("HotspotServer::SetLoginFlag");
+ iLoginValue = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// GetLoginFlagValue
+// -----------------------------------------------------------------------------
+//
+TBool CHotSpotServer::GetLoginFlagValue()
+ {
+ DEBUG("HotspotServer::GetLoginFlagValue()");
+ return iLoginValue;
+ }
+
+
+// -----------------------------------------------------------------------------
+// SetAssociationFlag
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::SetAssociationFlag( TBool aValue )
+ {
+ DEBUG("HotspotServer::SetAssociationFlag");
+ iAssociationValue = aValue;
+ }
+
+// -----------------------------------------------------------------------------
+// GetAssociationFlagValue
+// -----------------------------------------------------------------------------
+//
+TBool CHotSpotServer::GetAssociationFlagValue()
+ {
+ DEBUG("HotspotServer::GetAssociationFlagValue()");
+ return iAssociationValue;
+ }
+
+// -----------------------------------------------------------------------------
+// SetServiceId
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::SetServiceId( TInt aServiceId )
+ {
+ DEBUG("HotspotServer::SetServiceId");
+ iCurrentServiceIdInUse = aServiceId;
+ }
+
+// -----------------------------------------------------------------------------
+// GetServiceId
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::GetServiceId()
+ {
+ DEBUG("HotspotServer::GetServiceId()");
+ return iCurrentServiceIdInUse;
+ }
+
+// -----------------------------------------------------------------------------
+// RunError
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::RunError( TInt aError )
+ {
+ // error from CHotSpotSession::ServiceL
+ Message().Complete( aError );
+ // Continue reading client requests
+ ReStart();
+ return (KErrNone);
+ }
+
+// -----------------------------------------------------------------------------
+// EasyWlanIdL
+// -----------------------------------------------------------------------------
+//
+TBool CHotSpotServer::EasyWlanIdL()
+ {
+ TBool ret( EFalse );
+ DEBUG("CHotSpotServer::EasyWlanIdL()");
+ RCmManagerExt cmManager;
+ cmManager.OpenL();
+ CleanupClosePushL( cmManager );
+
+ iEasyWlanId = cmManager.EasyWlanIdL();
+ DEBUG1("CHotSpotServer::EasyWlanIdL() ret: % d", iEasyWlanId);
+ // if iEasyWlanId is 0, then it was not found
+ if ( iEasyWlanId > 0 )
+ {
+ RCmConnectionMethodExt plugin = cmManager.ConnectionMethodL( iEasyWlanId );
+ CleanupClosePushL( plugin );
+ //iEasyWlanId = plugin.GetIntAttributeL( /*ECmIapServiceId*/EWlanServiceId )
+ plugin.SetStringAttributeL( ECmConfigDaemonManagerName, KHotSpotPlugin );
+ // commit changes
+ plugin.UpdateL();
+ CleanupStack::PopAndDestroy( &plugin ); // Close() called on "plugin"
+ ret = ETrue;
+ }
+ CleanupStack::PopAndDestroy( &cmManager );
+ DEBUG("CHotSpotServer::EasyWlanIdL() DONE");
+ return ret;
+ }
+
+// -----------------------------------------------------------------------------
+// GetEasyWlanId
+// -----------------------------------------------------------------------------
+//
+TUint32 CHotSpotServer::GetEasyWlanId()
+ {
+ return iEasyWlanId;
+ }
+
+// -----------------------------------------------------------------------------
+// GetLoginTimerMicroSecs
+// -----------------------------------------------------------------------------
+//
+TUint CHotSpotServer::GetLoginTimeMicroSecs( TUid aClientUid )
+ {
+ // Default timer value will be returned if matching client UID isn't found.
+ TUint retval = KHssDefaultLoginTimeMicroSecs ;
+
+ TInt ret = CHotSpotServer::FindClientUid( aClientUid );
+ if (ret != KErrNotFound)
+ {
+ // ret is the matching element's index.
+ retval = iLoginLogoutTimerArray[ret].loginTimeMicroSecs;
+ }
+
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// GetLogoutTimerMicroSecs
+// -----------------------------------------------------------------------------
+//
+TUint CHotSpotServer::GetLogoutTimeMicroSecs( TUid aClientUid )
+ {
+ // Default timer value will be returned if matching client UID isn't found.
+ TUint retval = KHssDefaultLogoutTimeMicroSecs ;
+
+ TInt ret = CHotSpotServer::FindClientUid( aClientUid );
+ if (ret != KErrNotFound)
+ {
+ // ret is the matching element's index.
+ retval = iLoginLogoutTimerArray[ret].logoutTimeMicroSecs;
+ }
+
+ return retval;
+ }
+
+// -----------------------------------------------------------------------------
+// SetTimerValues
+// -----------------------------------------------------------------------------
+//
+void CHotSpotServer::SetTimerValues(
+ TUid aClientUid,
+ TUint aLoginTimerValue, // in seconds
+ TUint aLogoutTimerValue ) // in seconds
+ {
+ TInt ret = CHotSpotServer::FindClientUid( aClientUid );
+ TUint loginTimeMicroSecs = KHssDefaultLoginTimeMicroSecs ;
+ TUint logoutTimeMicroSecs = KHssDefaultLogoutTimeMicroSecs ;
+
+ // Check that values are in bounds and modify them into micro seconds.
+ if( aLoginTimerValue >= KHssMinLoginTime &&
+ aLoginTimerValue <= KHssMaxLoginTime )
+ {
+ loginTimeMicroSecs = KMillion * aLoginTimerValue;
+ }
+
+ if( aLogoutTimerValue >= KHssMinLogoutTime &&
+ aLogoutTimerValue <= KHssMaxLogoutTime )
+ {
+ logoutTimeMicroSecs = KMillion * aLogoutTimerValue;
+ }
+
+ if (ret != KErrNotFound)
+ {
+ DEBUG("CHotSpotServer::SetTimerValues(): Existing client modified.");
+ // ret is the matching element's index.
+ iLoginLogoutTimerArray[ret].loginTimeMicroSecs = loginTimeMicroSecs;
+ iLoginLogoutTimerArray[ret].logoutTimeMicroSecs = logoutTimeMicroSecs;
+ }
+ else
+ {
+ DEBUG("CHotSpotServer::SetTimerValues(): New Client added.");
+ // Create a new element and append it to the array.
+ const SLoginLogoutTimers addedElement = {
+ aClientUid,
+ loginTimeMicroSecs,
+ logoutTimeMicroSecs };
+ iLoginLogoutTimerArray.Append( addedElement );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// FindClientUid
+// -----------------------------------------------------------------------------
+//
+TInt CHotSpotServer::FindClientUid( TUid aClientUid )
+ {
+ TInt count = iLoginLogoutTimerArray.Count();
+ TInt i = 0;
+ TInt ret = KErrNotFound;
+
+ while (i < count)
+ {
+ if (aClientUid == iLoginLogoutTimerArray[i].clientUid)
+ {
+ ret = i;
+ break;
+ }
+ i++;
+ }
+
+ return ret;
+ }
+
+// ========================== OTHER EXPORTED FUNCTIONS =========================
+
+// -----------------------------------------------------------------------------
+// E32Main implements the executable entry function.
+// Note that because the target type of the IPWServer Hss
+// is EXEDLL, the entry point has different signature depending
+// on the build platform.
+// Creates a cleanup stack and runs the server.
+// Returns: Zero
+// -----------------------------------------------------------------------------
+//
+GLDEF_C TInt E32Main()
+ {
+ __UHEAP_MARK;
+ DEBUG("**** HotspotServer: E32Main");
+ CTrapCleanup* cleanup=CTrapCleanup::New();
+ TInt r=KErrNoMemory;
+ if (cleanup)
+ {
+ TRAP(r,RunServerL());
+ delete cleanup;
+ }
+ else
+ {
+ User::Panic( KHotSpotModuleName, KHotSpotPanicCleanupStackCreationFailed );
+ }
+ __UHEAP_MARKEND;
+ return r;
+ }
+
+// end of file