--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/wlan_bearer/wlanengine/wlan_symbian/wlanengine_symbian_3.1/src/wlmserver.cpp Tue Feb 02 02:03:13 2010 +0200
@@ -0,0 +1,5177 @@
+/*
+* Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: Server class of wlan engine
+*
+*/
+
+/*
+* %version: 96 %
+*/
+
+#include <e32def.h>
+#include <e32std.h>
+#include <featmgr.h>
+#include <in_sock.h>
+#include <bldvariant.hrh> // for feature definitions
+
+#include "wlmserver.h"
+#include "wlmdriverif.h"
+#include "wlmsession.h"
+#include "wlanconversionutil.h"
+#include "core_server_factory.h"
+#include "core_tools.h"
+#include "core_type_list.h"
+#include "wlaneapolclient.h"
+#include "wlangenericplugin.h"
+#include "wlanssidlistdb.h"
+#include "wlandevicesettingsinternalcrkeys.h"
+#include "wlanbgscan.h"
+#include "wlantimerservices.h"
+#include "am_debug.h"
+
+/** Panic codes for WlanEngine */
+const TInt KWlmPanicCleanupStackCreationFailed = 1;
+const TInt KWlmPanicOpenSemaforeFailed = 2;
+const TInt KWlmPanicCreationOfSchedulerFailed = 3;
+/** Panic category of WlanEngine */
+_LIT( KWlmModuleName, "WLANSRV" );
+
+/** Constants for sanity checks */
+const i32_t MAX_RCP_BOUNDARY = 255;
+const i32_t MAX_HYSTERESIS = 255;
+const u8_t MAX_USER_PRIORITY = 7;
+
+/** The number of hours after which the domain information expires. */
+const TInt KWlmDomainInfoExpire = 5;
+/** Operator MCC codes for North America, Canada, Taiwan, Brazil, Argentina, Mexico and Colombia. */
+const TUint KWlmOperatorMccNATable[] = { 302, 310, 311, 312, 313, 314, 315, 316, 332, 466, 724, 722, 334, 732 };
+/** The amount of operator MCC codes for North America, Canada, Taiwan, Brazil, Argentina, Mexico and Colombia. */
+const TUint KWlmOperatorMccNATableLength = 14;
+
+/** AP country information codes for North America, Canada, Taiwan, Brazil, Argentina, Mexico and Colombia
+ are defined in core_types.h. */
+
+/** Timestamp is stored in CenRep in minutes, constant for converterting this to microseconds */
+const TUint KWlmTimestampInCenrep = 60000000;
+
+/** WLAN region values in CenRep */
+const TInt KWlmRegionUnknown = 0;
+const TInt KWlmRegionETSI = 1;
+const TInt KWlmRegionFCC = 2;
+
+/** Valid range for cache lifetime in scan requests (in seconds). */
+const TInt KWlmMaxScanCacheLifetime = 60;
+const TInt KWlmMinScanCacheLifetime = 0;
+const TInt KWlmDefaultScanCacheLifetime = -1;
+
+/** Valid range for maximum scan delay in scan requests (in seconds). */
+const TUint KWlmMaxScanDelay = 1200;
+
+/** Infinite scan delay in GetAvailableIaps and GetScanResult. */
+const TUint KWlmInfiniteScanDelay = 0xFFFFFFFF;
+
+/** Granularity for WLAN SSID lists. */
+const TUint KWlanSsidListGranularity = 100;
+
+/** Bitmask of WLAN features enabled at compile-time. */
+const TUint KWlanStaticFeatures =
+ CWlmServer::EWlanFeaturePowerSaveTest |
+ CWlmServer::EWlanFeature802dot11k;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CWlmServer::CWlmServer
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CWlmServer::CWlmServer() :
+ CServer2( CActive::EPriorityStandard ),
+ iCoreServer( NULL ),
+ iDriverIf( NULL ),
+ iSupportedFeatures( KWlanStaticFeatures ),
+ iScanSchedulingTimer( NULL ),
+ iCache( NULL ),
+ iConfiguredCacheLifetime( 0 ),
+ iPlatform( NULL ),
+ iConnectionState( EWlanStateNotConnected ),
+ iPrevConnectionState( EWlanStateNotConnected ),
+ iIsRoaming( EFalse ),
+ iPrevRcpiValue( 0 ),
+ iRegion( EFCC ),
+ iTimeofDomainQuery( 0 ),
+ iClientSessionCount( 0 ),
+ iRequestIdCounter( KWlanExtCmdBase ),
+ iSessionIdCounter( 0 ),
+ iCoreAsynchCb( NULL ),
+ iCoreAsynchCbId( 0 ),
+ iCoreAsynchCbStatus( core_error_ok ),
+ iIsStartupComplete( EFalse ),
+ iEapolClient( NULL ),
+ iEapolHandler( NULL ),
+ iScanSchedulingTimerExpiration( 0 ),
+ iRequestTriggeringScanning( 0 ),
+ iCoreHandlingScanRequest( EFalse ),
+ iPowerSaveMode( EWlanPowerSaveAutomatic ),
+ iPowerSaveEnabled( EFalse ),
+ iSsidListDb( NULL ),
+ iShowBrokenPowerSaveNote( ETrue ),
+ iBrokenPowerSaveNotifierWaiter( NULL ),
+ iBgScanProvider( NULL ),
+ iTimerServices( NULL )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CWlmServer::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CWlmServer::ConstructL()
+ {
+ DEBUG( "CWlmServer::ConstructL()" );
+ User::LeaveIfError( User::RenameThread( KWLMDataServerName ) );
+ StartL( KWLMDataServerName );
+
+ // Consult FeatureManager whether startup is allowed
+ FeatureManager::InitializeLibL();
+ if( !FeatureManager::FeatureSupported( KFeatureIdProtocolWlan ) )
+ {
+ DEBUG("ERROR: FeatureManager forbids starting of WlanServer");
+ FeatureManager::UnInitializeLib();
+ User::Leave( KErrNotSupported );
+ }
+
+ if( FeatureManager::FeatureSupported( KFeatureIdFfWlanWapi ) )
+ {
+ iSupportedFeatures |= EWlanFeatureWapi;
+ }
+
+ DEBUG1( "CWlmServer::ConstructL() - supported WLAN features: 0x%08X",
+ iSupportedFeatures );
+ FeatureManager::UnInitializeLib();
+
+ // Create Driver Interface
+ iDriverIf = CWlmDriverIf::NewL();
+
+ // Get Mac Address
+ TMacAddress mac( KZeroMacAddr );
+ iDriverIf->GetMacAddress( mac );
+
+ // Test its authenticity
+ // If failure -> not starting the server
+ const TMacAddress KDeadBeefMacAddr = {{ 0x00, 0xE0, 0xDE, 0xAD, 0xBE, 0xEF }};
+ if( mac == KZeroMacAddr || mac == KDeadBeefMacAddr )
+ {
+ DEBUG("ERROR: MAC Address not acceptable -> Forbidden to start WlanServer");
+ User::Leave( KErrNotSupported );
+ }
+ core_mac_address_s core_mac( ZERO_MAC_ADDR );
+ TWlanConversionUtil::ConvertMacAddress( core_mac, mac );
+
+ // Get Device Settings
+ CWlanDeviceSettings::SWlanDeviceSettings deviceSettings;
+ GetWlanSettingsL( deviceSettings );
+ SetCachedRegion(deviceSettings.region, deviceSettings.regionTimestamp);
+ core_device_settings_s coreSettings; // core needs the settings here
+ TWlanConversionUtil::ConvertDeviceSettings( coreSettings, deviceSettings );
+
+ // Create core server
+ User::LeaveIfNull( iCoreServer = core_server_factory_c::instance(
+ *this,
+ *iDriverIf,
+ coreSettings,
+ core_mac,
+ TWlanConversionUtil::ConvertFeatureFlags( iSupportedFeatures ) ) );
+ iCoreServer->disable_wlan( KWlanIntCmdDisableWlan );
+
+ // Create scan timer
+ DEBUG( "CWlmServer::ConstructL() - create backgroundscan timer" );
+ iScanSchedulingTimer = CPeriodic::NewL( CActive::EPriorityStandard );
+
+ // Create scan cache
+ iCache = CWlanScanResultCache::NewL();
+ iConfiguredCacheLifetime = deviceSettings.scanExpirationTimer;
+
+ // Create a callback for asynchronous core requests
+ TCallBack callback( HandleCoreAsynchCb, this );
+ iCoreAsynchCb = new (ELeave) CAsyncCallBack(
+ callback, CActive::EPriorityStandard );
+
+ // Create SSID list storage.
+ iSsidListDb = CWlanSsidListDb::NewL();
+
+ // Initialise Broken Power Save Note handling
+ TCallBack cb( HandleBrokenPowerSaveNoteClosed, this );
+ iBrokenPowerSaveNotifierWaiter = CWlanCbWaiter::NewL( cb );
+
+ iTimerServices = CWlanTimerServices::NewL();
+
+ iBgScanProvider = CWlanBgScan::NewL( static_cast<MWlanScanResultProvider&>( *this ), *iTimerServices );
+
+ // Initialize Platform interface and publish mac address
+ iPlatform = CWlmPlatform::NewL( *this );
+ iPlatform->Initialize();
+ TInt err = iPlatform->PublishMacAddress( mac );
+ if( err )
+ {
+ DEBUG1( "ERROR publishing MAC address: %d", err );
+ }
+
+ iGenericWlanPlugin.StartPlugins();
+
+ DEBUG( "CWlmServer::ConstructL() - done" );
+ }
+
+// -----------------------------------------------------------------------------
+// CWlmServer::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+EXPORT_C CWlmServer* CWlmServer::NewL()
+ {
+ CWlmServer* self = new( ELeave ) CWlmServer;
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CWlmServer::~CWlmServer
+// -----------------------------------------------------------------------------
+//
+CWlmServer::~CWlmServer()
+ {
+ // Close all open sessions
+ CWlmSession* session = NULL;
+ iSessionIter.SetToFirst();
+ while( (session = static_cast<CWlmSession*>(iSessionIter++)) != NULL )
+ {
+ delete session;
+ }
+
+ iGenericWlanPlugin.StopPlugins();
+
+ delete iCoreServer;
+ delete iDriverIf;
+ iNotificationArray.Close();
+ delete iCache;
+ delete iPlatform;
+ iRequestMap.Close();
+ delete iCoreAsynchCb;
+ delete iScanSchedulingTimer;
+ delete iSsidListDb;
+ delete iBrokenPowerSaveNotifierWaiter;
+ iBrokenPowerSaveNotifier.Close();
+
+ if ( iEapolClient )
+ {
+ delete iEapolClient;
+ iEapolClient = NULL;
+ }
+ iEapolHandler = NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CWlmServer::StartServerThread
+// -----------------------------------------------------------------------------
+//
+EXPORT_C TInt CWlmServer::StartServerThread()
+ {
+ DEBUG( "CWlmServer::StartServerThread()" );
+
+ __UHEAP_MARK;
+
+ // Create cleanup stack
+ CTrapCleanup* cleanup = CTrapCleanup::New();
+ __ASSERT_ALWAYS(
+ cleanup,
+ User::Panic( KWlmModuleName, KWlmPanicCleanupStackCreationFailed )
+ );
+
+ // Open handle to semaphore
+ RSemaphore started;
+ TInt err = started.OpenGlobal( KWLMServerSemaphore, EOwnerProcess );
+ __ASSERT_ALWAYS(
+ err == KErrNone,
+ User::Panic( KWlmModuleName, KWlmPanicOpenSemaforeFailed )
+ );
+
+ // Create active scheduler
+ CWlmServer* server = NULL;
+ CActiveScheduler* scheduler = new CActiveScheduler();
+ if ( scheduler )
+ {
+ // Install scheduler
+ CActiveScheduler::Install( scheduler );
+
+ // Create server
+ TRAP( err, server = CWlmServer::NewL() );
+
+ if ( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::NewL leaved with code %d", err );
+ }
+ }
+ else
+ {
+ User::Panic( KWlmModuleName, KWlmPanicCreationOfSchedulerFailed );
+ }
+
+ // Signal calling process that we've started via semaphore
+ started.Signal();
+ started.Close();
+
+ // Start the active Scheduler (if there are no errors)
+ if ( err == KErrNone )
+ {
+ DEBUG( "CWlmServer Starting scheduler..." );
+ CActiveScheduler::Start();
+ }
+
+ // Note that CActiveScheduler::Start() will not return until the scheduler
+ // is stopped in CWlmServer::SessionClosed(). This is because we don't
+ // belong to an active object, so there's no RunL() to be called.
+
+ // Delete all objects
+ delete server;
+ delete CActiveScheduler::Current();
+ delete cleanup;
+
+ // Clean up Ecom framework
+ REComSession::FinalClose();
+
+ __UHEAP_MARKEND;
+
+ return err;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetWlanSettingsL
+// ---------------------------------------------------------
+//
+void CWlmServer::GetWlanSettingsL(
+ CWlanDeviceSettings::SWlanDeviceSettings& aSettings )
+ {
+ DEBUG( "CWlmServer::GetWlanSettingsL()" );
+ CWlanDeviceSettings* db = CWlanDeviceSettings::NewL();
+ CleanupStack::PushL( db );
+ db->ReadL( aSettings );
+ CleanupStack::PopAndDestroy( db );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetIapSettingsL
+// ---------------------------------------------------------
+//
+void CWlmServer::GetIapSettingsL(
+ const TUint32 aLanServiceId,
+ SWLANSettings& aWlanSettings,
+ RArray<TWlanSecondarySsid>& aSecondaryList )
+ {
+ DEBUG( "CWlmServer::GetIapSettingsL()" );
+
+ CWLanSettings* wlanset = new(ELeave) CWLanSettings;
+ CleanupStack::PushL( wlanset );
+
+ User::LeaveIfError( wlanset->Connect() );
+ User::LeaveIfError(
+ wlanset->GetWlanSettingsForService( aLanServiceId, aWlanSettings ) );
+ User::LeaveIfError(
+ wlanset->GetSecondarySsidsForService( aWlanSettings.Id, aSecondaryList ) );
+
+ DEBUG3( "- connMode == %d, securityMode == %d, # of secondary SSIDs == %d",
+ aWlanSettings.ConnectionMode,
+ aWlanSettings.SecurityMode,
+ aSecondaryList.Count() );
+
+ wlanset->Disconnect();
+ CleanupStack::PopAndDestroy( wlanset );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NewSessionL
+// ---------------------------------------------------------
+//
+CSession2* CWlmServer::NewSessionL(
+ const TVersion& /*aVersion*/,
+ const RMessage2& /*aMessage*/ ) const
+ {
+ DEBUG( "CWlmServer::NewSessionL()" );
+ CWlmSession* session =
+ CWlmSession::NewL(
+ const_cast<CWlmServer&>(*this) );
+ return session;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifyAdd
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifyAdd(
+ CNotificationBase& aNotification )
+ {
+ DEBUG( "CWlmServer::NotifyAdd()" );
+ iNotificationArray.Insert( &aNotification, 0 );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifyRemove
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifyRemove(
+ CNotificationBase& aNotification )
+ {
+ DEBUG( "CWlmServer::NotifyRemove()" );
+ TInt index = iNotificationArray.Find( &aNotification );
+ iNotificationArray.Remove( index );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::Connect
+// ---------------------------------------------------------
+//
+void CWlmServer::Connect(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::Connect()" );
+
+ // Get WlanSettings and secondarySSID list
+ // (lanServiceId specifies the table row in wlansettings)
+ SWLANSettings iapData;
+ RArray<TWlanSecondarySsid> secondarySsidList;
+ TInt lanServiceId = aMessage.Int0();
+ TRAPD( err, GetIapSettingsL( lanServiceId, iapData, secondarySsidList ) ) ;
+ if( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::Connect() - GetIapSettingsL leaved with %d",
+ err );
+ secondarySsidList.Close();
+ aMessage.Complete( err );
+
+ return;
+ }
+
+ DEBUG4( "CWlmServer::Connect() - SecurityMode: %u, WPAKeyLength: %u, EnableWpaPsk: %u, PresharedKeyFormat: %u",
+ iapData.SecurityMode, iapData.WPAKeyLength, iapData.EnableWpaPsk, iapData.PresharedKeyFormat );
+
+ // Check whether WAPI is supported
+ if( iapData.SecurityMode == Wapi &&
+ !( iSupportedFeatures & EWlanFeatureWapi ) )
+ {
+ DEBUG( "CWlmServer::Connect() - WAPI is not supported" );
+
+ secondarySsidList.Close();
+ aMessage.Complete( KErrNotSupported );
+
+ return;
+ }
+
+ // Get override setting from message parameter
+ TWLMOverrideSettings override = { 0 };
+ TPckg<TWLMOverrideSettings> inData( override );
+ err = aMessage.Read( 1, inData );
+ if( err )
+ {
+ secondarySsidList.Close();
+ aMessage.Complete( err );
+
+ return;
+ }
+
+ // Type conversion
+ core_iap_data_s* coreIapData = new core_iap_data_s;
+ if( !coreIapData )
+ {
+ secondarySsidList.Close();
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+
+ // Find out whether IP address should be static or dhcp
+ CLanSettings lanSettingsClient;
+ err = lanSettingsClient.Connect();
+ if( err )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ aMessage.Complete( err );
+
+ return;
+ }
+ SLanSettings lanSettings;
+ lanSettingsClient.GetLanSettings( lanServiceId, lanSettings );
+ lanSettingsClient.Disconnect();
+
+ TWlanConversionUtil::ConvertIapSettings(
+ *coreIapData,
+ iapData,
+ lanSettings.AddrFromServer,
+ override );
+
+ //
+ // Handle secondary SSID list
+ //
+ core_type_list_c<core_ssid_entry_s>* coreSsidList = NULL;
+
+ if( iapData.SSID.Length() &&
+ ( iapData.UsedSSID.Length() || secondarySsidList.Count() ) )
+ {
+ DEBUG( "CWlmServer::Connect() - secondary SSIDs defined" );
+
+ coreSsidList = new core_type_list_c<core_ssid_entry_s>();
+ if( !coreSsidList )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+ coreSsidList->clear();
+
+ core_ssid_entry_s* entry = new core_ssid_entry_s;
+ if ( !entry )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ delete coreSsidList;
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+
+ entry->id = coreIapData->id;
+ TWlanConversionUtil::ConvertSSID( entry->ssid, iapData.SSID );
+ if( iapData.UsedSSID.Length() )
+ {
+ TWlanConversionUtil::ConvertSSID( entry->used_ssid, iapData.UsedSSID );
+ }
+ else
+ {
+ entry->used_ssid = entry->ssid;
+ }
+ coreSsidList->append( entry );
+
+ for( TInt idx( 0 ); idx < secondarySsidList.Count(); ++idx )
+ {
+ entry = new core_ssid_entry_s;
+ if ( !entry )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ delete coreSsidList;
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+
+ TWlanConversionUtil::ConvertSSID(
+ entry->ssid, secondarySsidList[idx].ssid );
+ if ( secondarySsidList[idx].usedSsid.Length() )
+ {
+ TWlanConversionUtil::ConvertSSID(
+ entry->used_ssid, secondarySsidList[idx].usedSsid );
+ }
+ else
+ {
+ TWlanConversionUtil::ConvertSSID(
+ entry->used_ssid, iapData.SSID );
+ }
+ coreSsidList->append( entry );
+ }
+
+ DEBUG1( "CWlmServer::Connect() - secondary SSID count %u",
+ coreSsidList->count() );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::Connect() - no secondary SSIDs defined" );
+ }
+ secondarySsidList.Close();
+
+ // Connection status
+ core_connect_status_e* connectionStatus = new core_connect_status_e;
+ if( !connectionStatus )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ delete coreSsidList;
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+ *connectionStatus = core_connect_undefined;
+
+ TInt ret = GetCurrentIapId(
+ static_cast<TUint>(lanServiceId),
+ *coreIapData );
+
+ if ( ret != KErrNone )
+ {
+ secondarySsidList.Close();
+ delete coreIapData;
+ delete coreSsidList;
+ aMessage.Complete( ret );
+ return;
+ }
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EJoinByProfileId;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ mapEntry.iParam0 = coreIapData;
+ mapEntry.iParam1 = coreSsidList;
+ mapEntry.iParam2 = connectionStatus;
+ iRequestMap.Append( mapEntry );
+
+ iCoreServer->connect(
+ mapEntry.iRequestId,
+ *coreIapData,
+ *connectionStatus,
+ coreSsidList );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelConnect
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelConnect(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CancelConnect()" );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentBSSID
+// ---------------------------------------------------------
+//
+void CWlmServer::GetCurrentBSSID(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetCurrentBSSID()" );
+
+ core_mac_address_s coreBssid( ZERO_MAC_ADDR );
+ core_error_e ret = iCoreServer->get_current_bssid( coreBssid );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetCurrentBSSID() - get_current_bssid() failed with %u",
+ ret );
+ }
+
+ TMacPckg bssid;
+ TWlanConversionUtil::ConvertMacAddress(
+ bssid.data,
+ coreBssid );
+ TPckg<TMacPckg> outPckg( bssid );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentRCPI
+// ---------------------------------------------------------
+//
+void CWlmServer::GetCurrentRCPI(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetCurrentRCPI()" );
+
+ if ( IsRoaming() )
+ {
+ DEBUG1( "CWlmServer::GetCurrentRCPI() - roam in progress, returning a cached value (%u)",
+ iPrevRcpiValue );
+
+ TPckg<TUint32> outPckg( iPrevRcpiValue );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete( KErrNone );
+
+ return;
+ }
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EGetCurrentRSSI;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ TUint32* tmp = new TUint32;
+ if( tmp == NULL )
+ {
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+ mapEntry.iParam0 = tmp;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->get_current_rcpi(
+ mapEntry.iRequestId,
+ *tmp );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentSSID
+// ---------------------------------------------------------
+//
+void CWlmServer::GetCurrentSSID(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetCurrentSSID()" );
+
+ core_ssid_s coreSsid( BROADCAST_SSID );
+ core_error_e ret = iCoreServer->get_current_ssid( coreSsid );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetCurrentSSID() - get_current_ssid() failed with %u",
+ ret );
+ }
+
+ TSSID ssid = { 0 };
+ TWlanConversionUtil::ConvertSSID(
+ ssid,
+ coreSsid );
+ TPckg<TSSID> outPckg( ssid );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentSecurityMode
+// ---------------------------------------------------------
+//
+void CWlmServer::GetCurrentSecurityMode(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetCurrentSecurityMode()" );
+
+ core_connection_security_mode_e coreMode( core_connection_security_mode_open );
+ core_error_e ret = iCoreServer->get_current_security_mode( coreMode );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetCurrentSecurityMode() - get_current_security_mode() failed with %u",
+ ret );
+ }
+
+ TWlanSecurity mode(
+ TWlanConversionUtil::ConvertSecurityMode( coreMode ) );
+ TPckg<TWlanSecurity> outPckg( mode );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::AddBssidToRoguelist
+// ---------------------------------------------------------
+//
+void CWlmServer::AddBssidToRoguelist(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::AddBssidToRoguelist()" );
+
+ TMacAddress bssid( KZeroMacAddr );
+ TPckg<TMacAddress> inPckg( bssid );
+ TInt err( aMessage.Read( 0, inPckg ) );
+ if( err != KErrNone )
+ {
+ aMessage.Complete( err );
+ return;
+ }
+
+ core_mac_address_s coreBssid( ZERO_MAC_ADDR );
+ TWlanConversionUtil::ConvertMacAddress(
+ coreBssid,
+ bssid );
+
+ core_error_e ret = iCoreServer->add_bssid_to_rogue_list( coreBssid );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::AddBssidToRoguelist() - add_bssid_to_rogue_list() failed with %u",
+ ret );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::UpdateRcpNotificationBoundary
+// ---------------------------------------------------------
+//
+void CWlmServer::UpdateRcpNotificationBoundary(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::UpdateRcpNotificationBoundary()" );
+
+ i32_t rcp_boundary = aMessage.Int0();
+ i32_t hysteresis = aMessage.Int1();
+
+ if ( rcp_boundary < 0 || rcp_boundary > MAX_RCP_BOUNDARY ||
+ hysteresis < 0 || hysteresis > MAX_HYSTERESIS )
+ {
+ aMessage.Complete( KErrArgument );
+ return;
+ }
+
+ core_error_e ret = iCoreServer->set_rcp_level_notification_boundary(
+ rcp_boundary,
+ hysteresis );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::UpdateRcpNotificationBoundary() - set_rcp_level_notification_boundary() failed with %u",
+ ret );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::ConfigureMulticastGroup
+// ---------------------------------------------------------
+//
+void CWlmServer::ConfigureMulticastGroup(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::ConfigureMulticastGroup()" );
+
+ bool_t join;
+ if( aMessage.Int1() == KSoIp6JoinGroup )
+ {
+ join = true_t;
+ }
+ else
+ {
+ join = false_t;
+ }
+
+ TMacAddress adaptMac( KZeroMacAddr );
+ TPckg<TMacAddress> inPckg( adaptMac );
+ TInt ret( aMessage.Read( 0, inPckg ) );
+ if( ret != KErrNone )
+ {
+ aMessage.Complete( ret );
+ return;
+ }
+
+ if( !IsGroupBitSet( adaptMac ) )
+ {
+ aMessage.Complete( KErrArgument );
+ return;
+ }
+
+ if( iConnectionState == EWlanStateNotConnected )
+ {
+ aMessage.Complete( KErrNotReady );
+ return;
+ }
+
+ core_mac_address_s core_mac;
+ TWlanConversionUtil::ConvertMacAddress( core_mac, adaptMac );
+
+ core_error_e err = iCoreServer->configure_multicast_group(
+ join,
+ core_mac );
+ if ( err != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::ConfigureMulticastGroup() - configure_multicast_group() failed with %u",
+ err );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( err ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentSystemMode
+// ---------------------------------------------------------
+//
+void CWlmServer::GetCurrentSystemMode(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetCurrentSystemMode()" );
+
+ TPckg<TWlanSystemMode> outPckg( iPlatform->GetCurrentSystemMode() );
+ TInt ret( aMessage.Write( 0, outPckg ) );
+ aMessage.Complete( ret );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentState
+// ---------------------------------------------------------
+//
+TWlanConnectionState CWlmServer::GetCurrentState()
+ {
+ DEBUG( "CWlmServer::GetCurrentState()" );
+
+ return iConnectionState;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetConnectionState
+// ---------------------------------------------------------
+//
+void CWlmServer::GetConnectionState(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetConnectionState()" );
+
+ /**
+ * Do not return EWlanStateSearchingAP to the clients.
+ */
+ TWlanConnectionState state( iConnectionState );
+ if ( iConnectionState == EWlanStateSearchingAP )
+ {
+ state = iPrevConnectionState;
+ }
+
+ TPckg<TWlanConnectionState> outPckg( state );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetScanResult
+// ---------------------------------------------------------
+//
+void CWlmServer::GetScanResult(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetScanResult()" );
+
+ // Read SSID argument
+ TSSID ssid = { 0 };
+ TPckg<TSSID> inPckg( ssid );
+ if( aMessage.Read( 1, inPckg ) != KErrNone )
+ {
+ DEBUG( "CWlmServer::GetScanResult() - unable to read SSID parameter" );
+
+ aMessage.Complete( KErrArgument );
+
+ return;
+ }
+
+ if( ssid.ssidLength > MAX_SSID_LEN )
+ {
+ DEBUG1( "CWlmServer::GetScanResult() - invalid SSID length (%u)",
+ ssid.ssidLength );
+
+ aMessage.Complete( KErrArgument );
+
+ return;
+ }
+
+ // Read cacheLifetime and maxDelay arguments
+ TScanScheduling scanScheduling = { KWlmDefaultScanCacheLifetime, 0 };
+ TPckg<TScanScheduling> scanSchedulingBuf( scanScheduling );
+ if( aMessage.Read( 3, scanSchedulingBuf ) != KErrNone )
+ {
+ DEBUG( "CWlmServer::GetScanResult() - unable to read lifetime/delay parameters" );
+
+ aMessage.Complete( KErrArgument );
+
+ return;
+ }
+
+ // Check that parameters have valid ranges
+ CheckScanSchedulingParameters(
+ scanScheduling.cacheLifetime,
+ scanScheduling.maxDelay );
+
+ // Update the scan scheduling parameters to values that are going be used
+ aMessage.Write( 3, scanSchedulingBuf );
+
+ // Only check for valid cache if maxDelay is zero
+ if( scanScheduling.maxDelay == 0 )
+ {
+ // If not direct scan, try getting cached results and settle for them
+ // if they exist
+ ScanList* cacheList = iCache->GetScanList( ( scanScheduling.cacheLifetime == 0 ? 1 : scanScheduling.cacheLifetime ) );
+ if( !ssid.ssidLength && cacheList )
+ {
+ // Just return cached results
+
+ TDynamicScanList dynamicScanList;
+ dynamicScanList.count = cacheList->Count();
+ dynamicScanList.size = cacheList->Size();
+
+ TPckg<TDynamicScanList> pckgDynamicScanList( dynamicScanList );
+ TPtr8 ptrScanList(
+ cacheList->Data(),
+ cacheList->Size(),
+ cacheList->Size() );
+
+ DEBUG2( "CWlmServer::GetScanResult() - returning cached results, scan list count is %u, size is %u",
+ cacheList->Count(), cacheList->Size() );
+
+ aMessage.Write( 0, ptrScanList );
+ aMessage.Write( 2, pckgDynamicScanList );
+ aMessage.Complete( KErrNone );
+
+ return;
+ }
+ }
+
+ // If direct scan, or cached results were too old, perform scan
+ core_ssid_s* coreSsid = new core_ssid_s;
+ if( !coreSsid )
+ {
+ DEBUG( "CWlmServer::GetScanResult() - unable to instantiate core_ssid_s" );
+
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+
+ TWlanConversionUtil::ConvertSSID(
+ *coreSsid,
+ ssid );
+
+ ScanList* scanList = new ScanList( KWlmScanListMaxSize );
+ if( !scanList )
+ {
+ DEBUG( "CWlmServer::GetScanResult() - unable to instantiate ScanList" );
+
+ delete coreSsid;
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+
+ TTime* scanTime( NULL );
+ if( scanScheduling.maxDelay != KWlmInfiniteScanDelay )
+ {
+ scanTime = new TTime(
+ CalculateScanStartTime( scanScheduling.maxDelay ).Int64() );
+ if( !scanTime )
+ {
+ DEBUG( "CWlmServer::GetScanResult() - unable to instantiate TTime" );
+
+ delete coreSsid;
+ delete scanList;
+ aMessage.Complete( KErrNoMemory );
+
+ return;
+ }
+ }
+#ifdef _DEBUG
+ else
+ {
+ DEBUG( "CWlmServer::GetScanResult() - Infinite maxDelay, request will not be triggering any scans" );
+ }
+
+ if( coreSsid->length )
+ {
+ DEBUG1S( "CWlmServer::GetScanResult() - performing a direct scan with SSID: ",
+ coreSsid->length, &coreSsid->ssid[0] );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::GetScanResult() - performing a broadcast scan" );
+ }
+#endif // DEBUG
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EGetScanResults;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ mapEntry.iParam0 = scanList;
+ mapEntry.iParam1 = coreSsid;
+ mapEntry.iTime = scanTime;
+ iRequestMap.Append( mapEntry );
+
+ // Scan scheduling timer needs to be set again if this request needs the results earlier or
+ // if this is the only timed pending request
+ if( scanTime != NULL && ( IsOnlyTimedScanRequestInRequestMap( mapEntry ) || *scanTime < iScanSchedulingTimerExpiration ) )
+ {
+ UpdateScanSchedulingTimer( *scanTime, mapEntry.iRequestId );
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::IsOnlyTimedScanRequestInRequestMap
+// ---------------------------------------------------------
+//
+TBool CWlmServer::IsOnlyTimedScanRequestInRequestMap(
+ const SRequestMapEntry& aMapEntry ) const
+ {
+ DEBUG( "CWlmServer::IsOnlyTimedScanRequestInRequestMap()" );
+
+ // go through all the requests in the map
+ for(TInt index = 0; index < iRequestMap.Count(); index++)
+ {
+ // look for timed scan requests
+ if( IsPendingTimedScanRequest( index ) )
+ {
+ // if the request ids don't match there are other scan requests
+ if( iRequestMap[index].iRequestId != aMapEntry.iRequestId )
+ {
+ DEBUG( "CWlmServer::IsOnlyTimedScanRequestInRequestMap() - other timed scan requests found" );
+ return EFalse;
+ }
+ }
+ }
+
+ DEBUG( "CWlmServer::IsOnlyTimedScanRequestInRequestMap() - no other timed scan requests found" );
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelGetScanResult
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelGetScanResult(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CancelGetScanResult()" );
+
+ CancelExternalRequest(
+ aSessionId,
+ EGetScanResults );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetAvailableIaps
+// ---------------------------------------------------------
+//
+void CWlmServer::GetAvailableIaps(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps()" );
+
+ // Read cacheLifetime and maxDelay arguments
+ TPckgBuf<TInt> cacheLifetimePckg( KWlmDefaultScanCacheLifetime );
+ TPckgBuf<TUint> maxDelayPckg( 0 );
+ if( aMessage.Read( 1, cacheLifetimePckg ) != KErrNone )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - unable to read lifetime parameter" );
+
+ aMessage.Complete( KErrArgument );
+
+ return;
+ }
+
+ if( aMessage.Read( 2, maxDelayPckg ) != KErrNone )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - unable to read delay parameter" );
+
+ aMessage.Complete( KErrArgument );
+
+ return;
+ }
+
+ // Check that parameters have valid ranges
+ CheckScanSchedulingParameters(
+ cacheLifetimePckg(),
+ maxDelayPckg() );
+
+ //Update the scan scheduling parameters to values that are going be used
+ aMessage.Write( 1, cacheLifetimePckg );
+ aMessage.Write( 2, maxDelayPckg );
+
+ /**
+ * See if cached IAP availability information is available.
+ */
+ RArray<TWlanLimitedIapData> iapList;
+ RArray<TUint>* list = iCache->AvailableIaps(
+ iapList,
+ ( cacheLifetimePckg() == 0 ? 1 : cacheLifetimePckg() ) );
+
+ // Only complete with valid cache if maxDelay is zero
+ if( list && maxDelayPckg() == 0 )
+ {
+
+ TWlmAvailableIaps tmp;
+ const TInt listCount(
+ Min( list->Count(), KWlmMaxAvailableIaps ) );
+
+ DEBUG1( "CWlmServer::GetAvailableIaps() - using cached IAP list, list contains %d IAP(s)", listCount );
+
+ TInt listIdx( 0 );
+
+ while( listIdx < listCount )
+ {
+ tmp.iaps[ listIdx ] = (*list)[listIdx];
+ ++listIdx;
+ }
+ tmp.count = listCount;
+ TPckg<TWlmAvailableIaps> outPckg( tmp );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete( KErrNone );
+ iapList.Close();
+
+ return;
+ }
+
+ /**
+ * If maxDelay is not infinite, background scanning isn't enabled
+ * and there are no WLAN IAPs defined, scanning isn't needed at all.
+ */
+ if ( maxDelayPckg() != KWlmInfiniteScanDelay &&
+ !iBgScanProvider->IsBgScanEnabled() &&
+ !iapList.Count() )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - no WLAN IAPs defined, skipping scanning" );
+
+ TWlmAvailableIaps tmp = { 0 };
+ TPckg<TWlmAvailableIaps> outPckg( tmp );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete( KErrNone );
+ iapList.Close();
+
+ return;
+ }
+
+ // Create list for WLAN IAP data
+ core_type_list_c<core_iap_data_s>* iapDataList = new core_type_list_c<core_iap_data_s>;
+ if( iapDataList == NULL )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - unable to instance core_iap_data_s list" );
+
+ aMessage.Complete( KErrNoMemory );
+ iapList.Close();
+
+ return;
+ }
+
+ // Create list for secondary SSID data
+ core_type_list_c<core_ssid_entry_s>* iapSsidList = new core_type_list_c<core_ssid_entry_s>;
+ if ( iapSsidList == NULL )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - unable to instance core_ssid_entry_s list" );
+
+ aMessage.Complete( KErrNoMemory );
+ delete iapDataList;
+ iapList.Close();
+
+ return;
+ }
+
+ // Convert IAP data
+ TInt ret = GetIapDataList(
+ *iapDataList,
+ *iapSsidList,
+ iapList );
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::GetAvailableIaps() - unable to convert IAP data (%d)",
+ ret );
+
+ aMessage.Complete( ret );
+ delete iapDataList;
+ delete iapSsidList;
+ iapList.Close();
+
+ return;
+ }
+
+ iapList.Close();
+
+ // Create output list
+ core_type_list_c<u32_t>* iapIdList = new core_type_list_c<u32_t>;
+ if( iapIdList == NULL )
+ {
+ aMessage.Complete( KErrNoMemory );
+ delete iapDataList;
+ delete iapSsidList;
+ return;
+ }
+
+ // Create ScanList
+ ScanList* scanList = new ScanList( KWlmScanListMaxSize );
+ if( scanList == NULL )
+ {
+ aMessage.Complete( KErrNoMemory );
+ delete iapDataList;
+ delete iapSsidList;
+ delete iapIdList;
+ return;
+ }
+
+ TTime* scanTime( NULL );
+ if( maxDelayPckg() != KWlmInfiniteScanDelay )
+ {
+ scanTime = new TTime(
+ CalculateScanStartTime( maxDelayPckg() ).Int64() );
+ if( !scanTime )
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - unable to instantiate TTime" );
+
+ aMessage.Complete( KErrNoMemory );
+ delete iapDataList;
+ delete iapSsidList;
+ delete iapIdList;
+ delete scanList;
+
+ return;
+ }
+ }
+#ifdef _DEBUG
+ else
+ {
+ DEBUG( "CWlmServer::GetAvailableIaps() - Infinite maxDelay, request will not be triggering any scans" );
+ }
+#endif
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EGetAvailableIaps;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ mapEntry.iParam0 = iapDataList;
+ mapEntry.iParam1 = iapIdList;
+ mapEntry.iParam2 = scanList;
+ mapEntry.iParam3 = iapSsidList;
+ mapEntry.iTime = scanTime;
+ iRequestMap.Append( mapEntry );
+
+ // Scan scheduling timer needs to be set again if this request needs the results earlier or
+ // if this is the only timed pending request
+ if( scanTime != NULL && ( IsOnlyTimedScanRequestInRequestMap( mapEntry ) || *scanTime < iScanSchedulingTimerExpiration ) )
+ {
+ UpdateScanSchedulingTimer( *scanTime, mapEntry.iRequestId );
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelGetAvailableIaps
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelGetAvailableIaps(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CancelGetAvailableIaps()" );
+
+ CancelExternalRequest(
+ aSessionId,
+ EGetAvailableIaps );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::ReleaseComplete
+// ---------------------------------------------------------
+//
+void CWlmServer::ReleaseComplete(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::ReleaseComplete()" );
+
+ // Data pipe should now be disconnected
+ // -> safe to disconnect the management pipe.
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EReset;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ if( iPlatform->IsWlanDisabled() )
+ {
+ // Disable will release a possible connection
+ iCoreServer->disable_wlan( mapEntry.iRequestId );
+ }
+ else
+ {
+ iCoreServer->release( mapEntry.iRequestId );
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifySessionCreated
+// ---------------------------------------------------------
+//
+TUint CWlmServer::NotifySessionCreated()
+ {
+ DEBUG( "CWlmServer::NotifySessionCreated()" );
+ ++iClientSessionCount;
+
+ return ++iSessionIdCounter;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifySessionClosed
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifySessionClosed(
+ TUint aSessionId )
+ {
+ DEBUG( "CWlmServer::NotifySessionClosed()" );
+ for( TInt i( 0 ); i < iRequestMap.Count(); i++ )
+ {
+ if( iRequestMap[i].iSessionId == aSessionId )
+ {
+ DEBUG( "CWlmServer::NotifySessionClosed() - corresponding request found" );
+ iRequestMap[i].iSessionId = 0;
+ }
+ }
+
+ --iClientSessionCount;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifyChangedSettings
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifyChangedSettings(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::NotifyChangedSettings()" );
+
+ aMessage.Complete(
+ UpdateWlanSettings() );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::UpdateWlanSettings
+// ---------------------------------------------------------
+//
+TInt CWlmServer::UpdateWlanSettings()
+ {
+ DEBUG( "CWlmServer::UpdateWlanSettings()" );
+
+ CWlanDeviceSettings::SWlanDeviceSettings settings = { 0 };
+ TRAPD( err, GetWlanSettingsL( settings ) );
+ if( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::UpdateWlanSettings() - GetWlanSettingsL leaved with code %d", err );
+
+ return err;
+ }
+
+ // Only if startup is complete, inform current settings to BgScan
+ if( iIsStartupComplete )
+ {
+ DEBUG( "CWlmServer::UpdateWlanSettings() - notifying settings to BgScan provider" );
+ iBgScanProviderSettings = MWlanBgScanProvider::TWlanBgScanSettings( settings.backgroundScanInterval,
+ settings.psmServerMode,
+ settings.bgScanPeakPeriodStart,
+ settings.bgScanPeakPeriodEnd,
+ settings.bgScanIntervalPeak,
+ settings.bgScanIntervalOffPeak );
+ iBgScanProvider->NotifyChangedSettings( iBgScanProviderSettings );
+ }
+
+ // Keep cache lifetime for scan results up to date
+ iConfiguredCacheLifetime = settings.scanExpirationTimer;
+
+ // Store power save enabled value
+ iPowerSaveEnabled = settings.powerMode;
+
+ // Convert settings to core side struct
+ core_device_settings_s coreSettings;
+ TWlanConversionUtil::ConvertDeviceSettings(
+ coreSettings,
+ settings );
+
+ core_error_e ret = iCoreServer->update_device_settings( coreSettings );
+ if( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::UpdateWlanSettings() - update_device_settings() failed with %u",
+ ret );
+
+ return TWlanConversionUtil::ConvertErrorCode( ret );
+ }
+
+ // Store show broken power save note value
+ iShowBrokenPowerSaveNote = settings.showBrokenPowerSaveNote;
+
+ DEBUG( "CWlmServer::UpdateWlanSettings() - returning" );
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::UpdateScanSchedulingTimer
+// ---------------------------------------------------------
+//
+void CWlmServer::UpdateScanSchedulingTimer(
+ TTime aScanTime,
+ TUint aTriggeringRequestId )
+ {
+ DEBUG1( "CWlmServer::UpdateScanSchedulingTimer() - aTriggeringRequestId = %u ", aTriggeringRequestId );
+
+ if( iCoreHandlingScanRequest )
+ {
+ // Core is currently handling scanning, do not set the timer
+ DEBUG( "CWlmServer::UpdateScanSchedulingTimer() - core is currently handling scanning, do not set the timer" );
+
+ return;
+ }
+
+ TTime timeNow;
+ timeNow.UniversalTime();
+
+ TTimeIntervalMicroSeconds difference( aScanTime.MicroSecondsFrom( timeNow ) );
+ if( difference.Int64() < 0 )
+ {
+ difference = TTimeIntervalMicroSeconds( 0 );
+ }
+ TTimeIntervalMicroSeconds32 differenceMicroseconds(
+ difference.Int64() );
+
+ iScanSchedulingTimer->Cancel();
+ iScanSchedulingTimerExpiration = aScanTime;
+ iRequestTriggeringScanning = aTriggeringRequestId;
+ TCallBack callback( ScanSchedulingTimerExpired, this );
+
+ DEBUG1( "CWlmServer::UpdateScanSchedulingTimer() - scheduling the timer to %u second(s)",
+ differenceMicroseconds.Int() / SECONDS_FROM_MICROSECONDS );
+
+ TTimeIntervalMicroSeconds32 intervalMicroseconds( KWlmMaxScanDelay * SECONDS_FROM_MICROSECONDS );
+
+ iScanSchedulingTimer->Start(
+ differenceMicroseconds,
+ intervalMicroseconds,
+ callback );
+
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::FindNextTimedScanSchedulingRequest
+// ---------------------------------------------------------
+//
+TBool CWlmServer::FindNextTimedScanSchedulingRequest(
+ TUint& aTriggeringRequestIndex )
+ {
+ DEBUG( "CWlmServer::FindNextTimedScanSchedulingRequest()" );
+
+ TBool pendingScanRequestsFound( EFalse );
+ TTime closestTime = TTime( 0 );
+ aTriggeringRequestIndex = 0;
+
+ for(TInt i=0; i < iRequestMap.Count(); i++)
+ {
+ if( IsPendingTimedScanRequest( i ) )
+ {
+ TTime* checkedTime = reinterpret_cast<TTime*>( iRequestMap[i].iTime );
+ if( pendingScanRequestsFound == EFalse || closestTime > *checkedTime )
+ {
+ closestTime = *checkedTime;
+ aTriggeringRequestIndex = i;
+ pendingScanRequestsFound = ETrue;
+ }
+ }
+ }
+
+ if( pendingScanRequestsFound == EFalse )
+ {
+ // clear the scan scheduling related variables
+ iRequestTriggeringScanning = KWlanIntCmdNull;
+ iScanSchedulingTimerExpiration = TTime( 0 );
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::FindNextTimedScanSchedulingRequest() - RequestIndex %u ", aTriggeringRequestIndex );
+ }
+
+ return pendingScanRequestsFound;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifyBackgroundScanDone
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifyBackgroundScanDone(
+ ScanList* aScanList,
+ core_type_list_c<u32_t>* aIapIdList )
+ {
+ DEBUG( "CWlmServer::NotifyBackgroundScanDone()" );
+ ASSERT( aScanList != NULL );
+ ASSERT( aIapIdList != NULL );
+
+ // Unload the drivers immediately to conserve power.
+ if( !iPlatform->IsWlanDisabled() &&
+ iConnectionState == EWlanStateNotConnected )
+ {
+ iCoreServer->unload_drivers();
+ }
+
+ RArray<TWlanAvailableNetwork> networkList;
+ GetNetworkList( *aScanList, networkList );
+
+ // Update Cached results
+ iCache->UpdateScanList( aScanList );
+ TBool newIaps( EFalse );
+ TBool lostIaps( EFalse );
+ iCache->UpdateAvailableNetworksList(
+ *aIapIdList,
+ networkList,
+ newIaps,
+ lostIaps );
+
+ networkList.Close();
+
+ UpdateAvailabilityInfo(
+ newIaps,
+ lostIaps,
+ aScanList->Count() != 0 );
+ }
+
+// ---------------------------------------------------------
+//
+// Methods implementing abs_core_server_callback_c interface
+//
+// ---------------------------------------------------------
+
+// ---------------------------------------------------------
+// CWlmServer::notify
+// ---------------------------------------------------------
+//
+void CWlmServer::notify(
+ core_notification_e notification,
+ int_t data_len,
+ const u8_t* data )
+ {
+ DEBUG2( "CWlmServer::notify (notif == %d, data_len == %u)", notification, data_len );
+
+ // Convert notification type
+ TWlmNotify amNotification
+ = TWlanConversionUtil::ConvertNotificationType( notification );
+
+ // Convert notification parameter
+ TBuf8<KMaxNotificationLength> buf;
+ if ( data_len )
+ {
+ buf.Copy( data, data_len );
+
+ if ( amNotification == EWlmNotifyConnectionStateChanged )
+ {
+ // 1st byte of notification data corresponds to connection state,
+ // which must also be converted.
+ // -> Data changes -> it must be copied
+ core_connection_state_e state
+ = static_cast<core_connection_state_e>( data[0] );
+ buf[0] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertConnectionState( state ) );
+ }
+ else if ( amNotification == EWlmNotifyTransmitPowerChanged )
+ {
+ // Core uses dBm values internally, the value must be converted
+ // to mW.
+ const u32_t* value
+ = reinterpret_cast<const u32_t*>( &data[0] );
+ TUint32 retValue
+ = TWlanConversionUtil::ConvertDecibelToMilliWatts( *value );
+ buf.Copy( reinterpret_cast<TUint8*>( &retValue ), sizeof ( retValue ) );
+ }
+ else if( amNotification == EWlmNotifyRcpChanged )
+ {
+ // Data contains:
+ // 1st byte == RCP Class
+ // 2nd byte == RCP value
+ // (value is conveyed over client/server IF as 1 byte value)
+ core_rcp_class_e rcpClass = static_cast<core_rcp_class_e>( data[0] );
+ buf[0] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertRcpClass( rcpClass ) );
+ }
+ else if ( amNotification == EWlmNotifyTrafficStreamStatusChanged )
+ {
+ /**
+ * The first four bytes of notification data is the stream ID,
+ * which can be passed unmodified. The fifth byte is the status
+ * of the stream, which needs to be converted.
+ */
+ core_traffic_stream_status_e status
+ = static_cast<core_traffic_stream_status_e>( data[4] );
+ buf[4] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertTrafficStreamStatus( status ) );
+ }
+ else if( amNotification == EWlmNotifyAccessPointInfoChanged )
+ {
+ /**
+ * The core data structure has to be converted to a corresponding
+ * adaptation type.
+ */
+ const core_ap_information_s* info =
+ reinterpret_cast<const core_ap_information_s*>( &data[0] );
+
+ TWlanAccessPointInfo apInfo;
+ TWlanConversionUtil::ConvertApInformation(
+ apInfo,
+ *info );
+ buf.Copy(
+ reinterpret_cast<TUint8*>( &apInfo ),
+ sizeof ( apInfo ) );
+ }
+ else if( amNotification == EWlmNotifyAcTrafficModeChanged )
+ {
+ core_access_class_e accessClass
+ = static_cast<core_access_class_e>( data[0] );
+ core_access_class_traffic_mode_e trafficMode
+ = static_cast<core_access_class_traffic_mode_e>( data[1] );
+ buf[0] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertAccessClass( accessClass ) );
+ buf[1] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertTrafficMode( trafficMode ) );
+ }
+ else if( amNotification == EWlmNotifyAcTrafficStatusChanged )
+ {
+ core_access_class_e accessClass
+ = static_cast<core_access_class_e>( data[0] );
+ core_access_class_traffic_status_e trafficStatus
+ = static_cast<core_access_class_traffic_status_e>( data[1] );
+ buf[0] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertAccessClass( accessClass ) );
+ buf[1] = static_cast<u8_t>(
+ TWlanConversionUtil::ConvertTrafficStatus( trafficStatus ) );
+ }
+ }
+
+ // Notify subscribees
+ for ( TInt i = 0; i < iNotificationArray.Count(); i++ )
+ {
+ iNotificationArray[i]->AddNotification( amNotification, buf );
+ }
+
+ // Handle internal state changes / reactions
+ switch ( amNotification )
+ {
+ case EWlmNotifyConnectionStateChanged:
+ {
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyConnectionStateChanged<ind> ");
+ // Cache the state to adaptation side member variable.
+ if ( iConnectionState != static_cast<TWlanConnectionState>( buf[0] ) )
+ {
+ iPrevConnectionState = iConnectionState;
+ }
+ iConnectionState = static_cast<TWlanConnectionState>( buf[0] );
+
+ switch ( iConnectionState )
+ {
+ case EWlanStateNotConnected:
+ DEBUG( "CWlmServer::notify() - STATE: EWlanStateNotConnected" );
+ iIsRoaming = EFalse;
+
+ // set icon to "not available"
+ SetIconState( EWlmIconStatusNotAvailable );
+
+ // if background scan is on, this call will cause a background scan
+ // when the background scan is completed, the icon is updated
+ iBgScanProvider->NotConnected();
+
+ if ( iBrokenPowerSaveNotifierWaiter->IsActive() )
+ {
+ // cancelling the notifier will cause the iBrokenPowerSaveNotifierWaiter
+ // to be cancelled as well
+ iBrokenPowerSaveNotifier.CancelNotifier( KUidWlanPowerSaveTestNote );
+ }
+ break;
+ case EWlanStateInfrastructure:
+ DEBUG( "CWlmServer::notify() - STATE: EWlanStateInfrastructure" );
+ iIsRoaming = EFalse;
+ SetIconState( EWlmIconStatusConnected );
+ break;
+ case EWlanStateSearchingAP:
+ DEBUG( "CWlmServer::notify() - STATE: EWlanStateSearchingAP" );
+ iIsRoaming = ETrue;
+ break;
+ case EWlanStateIBSS:
+ DEBUG( "CWlmServer::notify() - STATE: EWlanStateIBSS" );
+ iIsRoaming = EFalse;
+ // Core separates adhoc mode to secure(WEP) and non-secure.
+ // set icon according to this
+ if( static_cast<core_connection_state_e>( data[0] )
+ == core_connection_state_secureibss )
+ {
+ SetIconState( EWlmIconStatusConnectedSecure );
+ }
+ else
+ {
+ SetIconState( EWlmIconStatusConnected );
+ }
+ break;
+ case EWlanStateSecureInfra:
+ DEBUG( "CWlmServer::notify() - STATE: EWlanStateSecureInfra" );
+ iIsRoaming = EFalse;
+ SetIconState( EWlmIconStatusConnectedSecure );
+ break;
+ case EConnectionStateUnknown:
+ DEBUG( "CWlmServer::notify() - STATE: EConnectionStateUnknown" );
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case EWlmNotifyBssidChanged:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyBssidChanged<ind>" );
+ break;
+ case EWlmNotifyBssLost:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyBssLost<ind>" );
+ iIsRoaming = ETrue;
+ break;
+ case EWlmNotifyBssRegained:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyBssRegained<ind>" );
+ break;
+ case EWlmNotifyRcpiRoamAttemptStarted:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyRcpiRoamAttemptStarted<ind>" );
+ iIsRoaming = ETrue;
+ break;
+ case EWlmNotifyRcpiRoamAttemptCompleted:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyRcpiRoamAttemptCompleted<ind>" );
+ iIsRoaming = EFalse;
+ break;
+ case EWlmNotifyAcTrafficModeChanged:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyAcTrafficModeChanged<ind>" );
+ break;
+ case EWlmNotifyAcTrafficStatusChanged:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyAcTrafficStatusChanged<ind>" );
+ break;
+ case EWlmNotifyBrokenPowerSaveTestFailed:
+ DEBUG( "CWlmServer::notify() - STATE: EWlmNotifyBrokenPowerSaveTestFailed<ind>" );
+
+ DEBUG1( "CWlmServer::notify() - iShowBrokenPowerSaveNote: %d",
+ static_cast<TInt>( iShowBrokenPowerSaveNote ) );
+
+ if ( iShowBrokenPowerSaveNote )
+ {
+ if ( !iBrokenPowerSaveNotifierWaiter->IsActive() )
+ {
+ TInt err = iBrokenPowerSaveNotifier.Connect();
+ DEBUG1( "CWlmServer::notify() - iNotifier.Connect() returned %d", err );
+ if ( err == KErrNone )
+ {
+ iBrokenPowerSaveNotifier.StartNotifierAndGetResponse( iBrokenPowerSaveNotifierWaiter->RequestStatus(),
+ KUidWlanPowerSaveTestNote, KNullDesC8(), iBrokenPowerSaveNotifierReply );
+
+ iBrokenPowerSaveNotifierWaiter->IssueRequest();
+ }
+ }
+#ifdef _DEBUG
+ else
+ {
+ DEBUG( "CWlmServer::notify() - Notifier already active on the screen" );
+ }
+#endif
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::BrokenPowerSaveNoteClosed
+// ---------------------------------------------------------
+//
+TInt CWlmServer::HandleBrokenPowerSaveNoteClosed(
+ TAny *aThisPtr )
+ {
+ DEBUG( "CWlmServer::HandleBrokenPowerSaveNoteClosed()" );
+
+ CWlmServer* self = static_cast<CWlmServer*>( aThisPtr );
+
+ ASSERT( self );
+ ASSERT( self->iBrokenPowerSaveNotifierWaiter );
+
+ // close the notifier
+ self->iBrokenPowerSaveNotifier.Close();
+
+ // check the request's completion status
+ TInt err = self->iBrokenPowerSaveNotifierWaiter->RequestStatus().Int();
+ switch ( err )
+ {
+ case KErrNotFound:
+ {
+ DEBUG( "CWlmServer::HandleBrokenPowerSaveNoteClosed() - Notifier not found, returning" );
+ return err;
+ }
+ case KErrCancel:
+ {
+ DEBUG( "CWlmServer::HandleBrokenPowerSaveNoteClosed() - Notifier cancelled, returning" );
+ return err;
+ }
+ default:
+ {
+ // flow through
+ }
+ }
+
+ self->iShowBrokenPowerSaveNote = self->iBrokenPowerSaveNotifierReply() ? EFalse : ETrue;
+
+ // re-use err variable
+ TRAP( err, self->StoreWlanCenRepKeyValueL( KWlanShowBrokenPowerSaveNote, self->iShowBrokenPowerSaveNote ) );
+ if ( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::HandleBrokenPowerSaveNoteClosed() - failed to update CenRep, error code %d", err );
+ return err;
+ }
+
+ DEBUG1( "CWlmServer::HandleBrokenPowerSaveNoteClosed() - iShowBrokenPowerSaveNote value (%d) stored to CenRep",
+ static_cast<TInt>( self->iShowBrokenPowerSaveNote ) );
+
+ return err;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::NotifyChangedPsmSrvMode
+// ---------------------------------------------------------
+//
+void CWlmServer::NotifyChangedPsmSrvMode(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::NotifyChangedPsmSrvMode()" );
+
+ TInt mode( aMessage.Int0() );
+ TInt err( KErrNone );
+
+ TRAP( err, StoreWlanCenRepKeyValueL( KWlanPsmSrvMode, mode ) );
+ if ( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::NotifyChangedPsmSrvMode() - failed to update CenRep, error code %d", err );
+ }
+
+ DEBUG1( "CWlmServer::NotifyChangedPsmSrvMode() - mode %i",
+ mode );
+
+ aMessage.Complete( err );
+
+ UpdateWlanSettings();
+
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::StoreWlanCenRepKeyValue
+// ---------------------------------------------------------
+//
+void CWlmServer::StoreWlanCenRepKeyValueL( const TUint32 aKey, const TInt aValue ) const
+ {
+ DEBUG( "CWlmServer::StoreWlanCenRepKeyValueL()" );
+
+ CWlanDeviceSettings* db = CWlanDeviceSettings::NewL();
+ CleanupStack::PushL( db );
+
+ // Write setting
+ db->WriteCenRepKeyL( aKey, aValue );
+
+ CleanupStack::PopAndDestroy( db );
+ db = NULL;
+
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SetCachedRegion
+// ---------------------------------------------------------
+//
+void CWlmServer::SetCachedRegion(
+ TUint32 region,
+ TInt32 timestamp )
+ {
+ DEBUG( "CWlmServer::SetCachedRegion()" );
+
+ if ( region == 0 || timestamp == 0 )
+ {
+ // cached results do not exist -> iRegion remains in its original value
+ return;
+ }
+
+ TTime currentTime(0);
+ TTimeIntervalHours difference(0);
+ TInt64 timestampInt64;
+
+ currentTime.UniversalTime();
+ timestampInt64 = static_cast<TInt64>(timestamp) * KWlmTimestampInCenrep; // timestamp is in minutes in CenRep
+
+ TTime timestampMicroseconds(timestampInt64);
+
+ TInt overflow = currentTime.HoursFrom( timestampMicroseconds, difference );
+ if ( Abs( difference.Int() ) >= KWlmDomainInfoExpire || overflow )
+ {
+ DEBUG( "CWlmServer::SetCachedRegion() - cached results are too old, region information is not changed" );
+ }
+ else if ( Abs( difference.Int()) < KWlmDomainInfoExpire )
+ {
+ DEBUG( "CWlmServer::SetCachedRegion() - cached results are valid, they are taken into use" );
+ if ( region == KWlmRegionETSI)
+ {
+ iRegion = EETSI;
+ DEBUG( "CWlmServer::SetCachedRegion() - Region is ETSI" );
+ }
+ else
+ {
+ iRegion = EFCC;
+ DEBUG( "CWlmServer::SetCachedRegion() - Region is FCC" );
+ }
+ iTimeofDomainQuery = timestampMicroseconds;
+ }
+ }
+
+
+// ---------------------------------------------------------
+// CWlmServer::store_ap_country_info
+// ---------------------------------------------------------
+//
+void CWlmServer::store_ap_country_info(
+ u32_t request_id,
+ const core_wlan_region_e& found_region,
+ bool_t inconsistent_info )
+ {
+ DEBUG( "CWlmServer::store_ap_country_info()" );
+
+ iRegion = TWlanConversionUtil::ConvertRegion( found_region );
+
+ // Write the WLAN region and timestamp to CenRep if the country information from APs was not inconsistent
+ if ( !inconsistent_info )
+ {
+ iTimeofDomainQuery.UniversalTime();
+
+ TInt region( KWlmRegionFCC );
+ if ( iRegion == EETSI )
+ {
+ region = KWlmRegionETSI;
+ }
+
+ TRAPD( ret, StoreWlanCenRepKeyValueL( KWlanRegion, region ));
+ if ( ret == KErrNone )
+ {
+ TRAP( ret, StoreWlanCenRepKeyValueL( KWlanRegionTimestamp, ( iTimeofDomainQuery.Int64() / KWlmTimestampInCenrep ) ));
+ if ( ret == KErrNone )
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - stored regulatory domain is 0x%02X ", iRegion );
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store region timestamp leaved with code %d,", ret );
+ }
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store region leaved with code %d,", ret );
+ }
+ }
+ // If the APs country information was inconsistent then region is selected to be ETSI
+ else
+ {
+ iRegion = EETSI;
+ iTimeofDomainQuery.UniversalTime();
+
+ DEBUG1( "CWlmServer::store_ap_country_info() - regulatory domain is 0x%02X", iRegion );
+ }
+
+
+ // Set timers to notice if system time is changed
+ iPlatform->InitializeSystemTimeHandler();
+
+ iCoreAsynchCbId = request_id;
+ iCoreAsynchCbStatus = core_error_ok;
+ iCoreAsynchCb->CallBack();
+
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::get_regulatory_domain
+// ---------------------------------------------------------
+//
+void CWlmServer::get_regulatory_domain(
+ u32_t request_id,
+ core_wlan_region_e& region,
+#ifndef __WINS__
+ bool_t& mcc_known )
+#else
+ bool_t& /* mcc_known */ )
+#endif // __WINS__
+ {
+ DEBUG( "CWlmServer::regulatory_domain()" );
+
+ ASSERT( !iCoreAsynchCbId );
+
+#ifndef __WINS__
+ TTime currentTime(0);
+ TTimeIntervalHours difference(0);
+ TUint mcc( 0 );
+
+ currentTime.UniversalTime();
+ mcc_known = false_t;
+
+ TInt overflow = currentTime.HoursFrom( iTimeofDomainQuery, difference );
+ if ( Abs( difference.Int() ) >= KWlmDomainInfoExpire || overflow )
+ {
+ DEBUG( "CWlmServer::regulatory_domain() - cache is not valid, querying MCC" );
+ iRegion = EETSI;
+
+ // Query the MCC of the currently used operator.
+ TRAPD( ret, iPlatform->GetCurrentOperatorMccL( mcc ) );
+ if ( ret == KErrNone &&
+ mcc )
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - MCC is %u", mcc );
+
+ mcc_known = true_t;
+ iTimeofDomainQuery.UniversalTime();
+
+ for ( TUint i(0); i < KWlmOperatorMccNATableLength; i++ )
+ {
+ if ( mcc == KWlmOperatorMccNATable[i] )
+ {
+ DEBUG( "CWlmServer::regulatory_domain() - MCC matches a US MCC" );
+ iRegion = EFCC;
+ break;
+ }
+ }
+ // Write the WLAN region and timestamp to CenRep
+ TInt wlanRegion( KWlmRegionFCC );
+ if ( iRegion == EETSI )
+ {
+ wlanRegion = KWlmRegionETSI;
+ }
+
+ TRAPD( ret, StoreWlanCenRepKeyValueL( KWlanRegion, wlanRegion ));
+ if ( ret == KErrNone )
+ {
+ TRAP( ret, StoreWlanCenRepKeyValueL( KWlanRegionTimestamp, ( iTimeofDomainQuery.Int64() / KWlmTimestampInCenrep ) ));
+ if ( ret == KErrNone )
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - stored regulatory domain is 0x%02X ", iRegion );
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store timestamp leaved with code %d,", ret );
+ }
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store region leaved with code %d,", ret );
+ }
+
+ // Set timers to notice if system time is changed
+ iPlatform->InitializeSystemTimeHandler();
+
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - GetCurrentOperatorMccL leaved with code %d,", ret );
+ iRegion = EFCC;
+ }
+ }
+ else if ( Abs( difference.Int()) < KWlmDomainInfoExpire )
+ {
+ DEBUG( "CWlmServer::regulatory_domain() - cache valid, querying MCC" );
+
+ TWlanRegion currentRegion = EETSI;
+
+ // Query the MCC of the currently used operator.
+ TRAPD( ret, iPlatform->GetCurrentOperatorMccL( mcc ) );
+ if ( ret == KErrNone &&
+ mcc )
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - MCC is %u", mcc );
+
+ mcc_known = true_t;
+ iTimeofDomainQuery.UniversalTime();
+
+ for ( TUint i(0); i < KWlmOperatorMccNATableLength; i++ )
+ {
+ if ( mcc == KWlmOperatorMccNATable[i] )
+ {
+ DEBUG( "CWlmServer::regulatory_domain() - MCC matches a US MCC" );
+ currentRegion = EFCC;
+ break;
+ }
+ }
+
+ /* WLAN region is stored to CenRep only if it has changed, because otherwise
+ * this would cause CenRep to be written always when the drivers are loaded.
+ */
+ if ( iRegion != currentRegion )
+ {
+ iRegion = currentRegion;
+
+ // Write the WLAN region and timestamp to CenRep
+ TInt wlanRegion( KWlmRegionFCC );
+ if ( iRegion == EETSI )
+ {
+ wlanRegion = KWlmRegionETSI;
+ }
+
+ TRAPD( ret, StoreWlanCenRepKeyValueL( KWlanRegion, wlanRegion ));
+ if ( ret == KErrNone )
+ {
+ TRAP( ret, StoreWlanCenRepKeyValueL( KWlanRegionTimestamp, ( iTimeofDomainQuery.Int64() / KWlmTimestampInCenrep ) ));
+ if ( ret == KErrNone )
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - stored regulatory domain is 0x%02X ", iRegion );
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store region timestamp leaved with code %d,", ret );
+ }
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - attempt to store region leaved with code %d,", ret );
+ }
+
+ // Set timers to notice if system time is changed
+ iPlatform->InitializeSystemTimeHandler();
+
+ }
+ else
+ {
+ iRegion = currentRegion;
+ }
+
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::regulatory_domain() - GetCurrentOperatorMccL leaved with code %d,", ret );
+ mcc_known = true_t;
+ }
+ }
+
+ DEBUG1( "CWlmServer::regulatory_domain() - regulatory domain is 0x%02X", iRegion );
+
+ region = TWlanConversionUtil::ConvertRegion( iRegion );
+#else // __WINS__
+ region = core_wlan_region_fcc;
+#endif // __WINS__
+
+ iCoreAsynchCbId = request_id;
+ iCoreAsynchCbStatus = core_error_ok;
+ iCoreAsynchCb->CallBack();
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::request_complete
+// ---------------------------------------------------------
+//
+void CWlmServer::request_complete(
+ u32_t request_id,
+ core_error_e status )
+ {
+ DEBUG2( "CWlmServer::request_complete(%u, %d)", request_id, status );
+
+#ifdef _DEBUG
+ TInt requestMapCount( iRequestMap.Count() );
+ if( requestMapCount )
+ {
+ DEBUG( "CWlmServer::request_complete() - current requests:" );
+ for ( TInt idx( 0 ); idx < requestMapCount; ++idx )
+ {
+ DEBUG2( "CWlmServer::request_complete() - ID %u, function %d", iRequestMap[idx].iRequestId, iRequestMap[idx].iFunction );
+ }
+ }
+#endif
+
+ // Find correct request from the map
+ TInt idx = FindRequestIndex( request_id );
+
+ if( idx >= iRequestMap.Count() )
+ {
+ DEBUG1("CWlmServer::request_complete() - completed request (ID %u) not in request map",
+ request_id );
+ return;
+ }
+
+ // create a copy of completed request's map entry
+ SRequestMapEntry completedMapEntry = iRequestMap[idx];
+
+ // If the operation was GetAvailableIaps, see if there are any SSID lists
+ // defined and update the availability results.
+ if( completedMapEntry.iFunction == EGetAvailableIaps )
+ {
+ TRAP_IGNORE( HandleSsidListAvailabilityL( completedMapEntry ) );
+ }
+
+ // Complete first all the other possible request that can be completed using the same results
+ // and the actual triggering request is completed last
+ // Background scan request should be updated after all requests have been completed
+ TBool bgScanCompleted( request_id == KWlanIntCmdBackgroundScan );
+ if( request_id == iRequestTriggeringScanning &&
+ status != core_error_cancel )
+ {
+ DEBUG( "CWlmServer::request_complete() - also additional requests can be completed" );
+
+ /*
+ * Request can be completed using other the results of another request if
+ * this method is related to scan scheduling and results of the triggering request can
+ * be used also to completed this request
+ *
+ * Following rules apply:
+ * - GetAvailableIaps results can be used to complete another GetAvailableIaps request,
+ * background scan request or GetScanResults request without given SSID (broadcast scan)
+ * - Background scan results can be used to complete GetAvailableIaps request or
+ * GetScanResults request without given SSID (broadcast scan)
+ * - GetScanResults request without given SSID (broadcast scan) results can be used to complete
+ * another GetScanResults request without given SSID (broadcast scan)
+ * - GetScanResults request with given SSID (direct scan) results can be used to complete
+ * another GetScanResults request with same given SSID (direct scan)
+ */
+
+ TInt i = 0;
+ while( i < iRequestMap.Count() )
+ {
+ if( IsPendingScanRequest(i) &&
+ iRequestMap[i].iRequestId != iRequestTriggeringScanning &&
+ CanRequestBeCompleted( iRequestMap[i], completedMapEntry ) )
+ {
+ DEBUG1( "CWlmServer::request_complete() - completing additional request (ID %u)", iRequestMap[i].iRequestId );
+
+ if( iRequestMap[i].iRequestId == KWlanIntCmdBackgroundScan )
+ {
+ CompleteInternalRequest( i, status, EFalse );
+ bgScanCompleted = ETrue;
+ }
+ else
+ {
+ CompleteExternalRequest( i, status, &completedMapEntry );
+ if( IsSessionActive( iRequestMap[i] ) )
+ {
+ iRequestMap[i].iMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ }
+ iRequestMap.Remove( i );
+ }
+ }
+ else
+ {
+ ++i;
+ }
+ }
+ }
+
+ // clear completedMapEntry as it is not needed anymore
+ completedMapEntry = SRequestMapEntry();
+
+ // complete the request which Core has actually handled
+ TInt triggerIndex = FindRequestIndex( request_id );
+
+ DEBUG1( "CWlmServer::request_complete() - completing triggering request (ID %u)", iRequestMap[triggerIndex].iRequestId );
+ if( request_id < KWlanExtCmdBase )
+ {
+ CompleteInternalRequest( triggerIndex, status );
+ }
+ else if( iRequestMap[triggerIndex].iFunction == EJoinByProfileId )
+ {
+ core_iap_data_s* coreIapData =
+ reinterpret_cast<core_iap_data_s*>( iRequestMap[triggerIndex].iParam0 );
+ core_type_list_c<core_ssid_entry_s>* coreSsidList =
+ reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( iRequestMap[triggerIndex].iParam1 );
+ core_connect_status_e* connectionStatus =
+ reinterpret_cast<core_connect_status_e*>( iRequestMap[triggerIndex].iParam2 );
+
+ if( status == core_error_ok && IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ DEBUG2("CONNECT COMPLETED WITH status == %u -> adapt == %d",
+ *connectionStatus,
+ TWlanConversionUtil::ConvertConnectStatus(
+ *connectionStatus,
+ coreIapData->security_mode ) );
+ iRequestMap[triggerIndex].iMessage.Complete(
+ TWlanConversionUtil::ConvertConnectStatus(
+ *connectionStatus,
+ coreIapData->security_mode ) );
+ }
+ else if ( IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ DEBUG2("CONNECT COMPLETED WITH error == %u -> adapt == %d",
+ status,
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ iRequestMap[triggerIndex].iMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::request_complete() - session has already closed" );
+ }
+ delete coreIapData;
+ delete coreSsidList;
+ delete connectionStatus;
+ iRequestMap.Remove( triggerIndex );
+ }
+ else if ( iRequestMap[triggerIndex].iFunction == ERunProtectedSetup )
+ {
+ core_iap_data_s* iapData =
+ reinterpret_cast<core_iap_data_s*>( iRequestMap[triggerIndex].iParam0 );
+ core_type_list_c<core_iap_data_s>* iapDataList =
+ reinterpret_cast<core_type_list_c<core_iap_data_s>*>( iRequestMap[triggerIndex].iParam1 );
+ core_protected_setup_status_e* protectedSetupStatus =
+ reinterpret_cast<core_protected_setup_status_e*>( iRequestMap[triggerIndex].iParam2 );
+
+ // Convert the received credentials.
+ TWlmProtectedSetupCredentials tmp;
+ tmp.count = 0;
+ core_iap_data_s* iter = iapDataList->first();
+ while ( iter && tmp.count < KWlmProtectedSetupMaxCount )
+ {
+ TWlanConversionUtil::ConvertProtectedSetupCredentialAttribute(
+ tmp.credentials[tmp.count],
+ *iter );
+ ++tmp.count;
+ iter = iapDataList->next();
+ }
+
+ DEBUG1( "CWlmServer::request_complete() - converted %u Protected Setup credential attributes",
+ tmp.count );
+
+ if( IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ TPckg<TWlmProtectedSetupCredentials> outPckg( tmp );
+ iRequestMap[triggerIndex].iMessage.Write( 1, outPckg );
+ }
+
+ if( status == core_error_ok && IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ DEBUG2("PROTECTED SETUP COMPLETED WITH status == %d -> adapt == %d",
+ *protectedSetupStatus,
+ TWlanConversionUtil::ConvertProtectedSetupStatus( *protectedSetupStatus ) );
+ iRequestMap[triggerIndex].iMessage.Complete(
+ TWlanConversionUtil::ConvertProtectedSetupStatus( *protectedSetupStatus ) );
+ }
+ else if ( IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ DEBUG2("PROTECTED SETUP COMPLETED WITH error == %d -> adapt == %d",
+ status,
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ iRequestMap[triggerIndex].iMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::request_complete() - session has already closed" );
+ }
+
+ delete iapData;
+ delete iapDataList;
+ delete protectedSetupStatus;
+ iRequestMap.Remove( triggerIndex );
+ }
+ else
+ {
+ CompleteExternalRequest( triggerIndex, status );
+ if( IsSessionActive( iRequestMap[triggerIndex] ) )
+ {
+ iRequestMap[triggerIndex].iMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( status ) );
+ }
+ iRequestMap.Remove( triggerIndex );
+ }
+
+ // Background scan request needs to be updated only after all the other request have been completed
+ // otherwise the new request will be appended to the pending list too early
+ if( bgScanCompleted )
+ {
+ iBgScanProvider->ScanComplete();
+ }
+
+ TUint indexNextScan;
+ if( request_id == iRequestTriggeringScanning )
+ {
+ iCoreHandlingScanRequest = EFalse;
+
+ if( FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ TTime* nextScanTime = reinterpret_cast<TTime*>( iRequestMap[indexNextScan].iTime );
+ UpdateScanSchedulingTimer( *nextScanTime, iRequestMap[indexNextScan].iRequestId );
+ }
+ }
+
+#ifdef _DEBUG
+ requestMapCount = iRequestMap.Count();
+ if( requestMapCount )
+ {
+ DEBUG( "CWlmServer::request_complete() - remaining requests:" );
+ for ( TInt idx( 0 ); idx < requestMapCount; ++idx )
+ {
+ DEBUG1( "CWlmServer::request_complete() - ID %u", iRequestMap[idx].iRequestId );
+ DEBUG1( "CWlmServer::request_complete() - function %d", iRequestMap[idx].iFunction );
+ }
+ }
+#endif
+
+ return;
+
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CanRequestBeCompleted
+// ---------------------------------------------------------
+//
+TBool CWlmServer::CanRequestBeCompleted(
+ const SRequestMapEntry& aCheckedMapEntry,
+ const SRequestMapEntry& aCompletedMapEntry ) const
+ {
+ DEBUG2( "CWlmServer::CanRequestBeCompleted() - checked %u completed %u",
+ aCheckedMapEntry.iRequestId, aCompletedMapEntry.iRequestId );
+
+ if( aCheckedMapEntry.iRequestId == KWlanIntCmdBackgroundScan )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The request to be checked is background scan" );
+
+ if( iRequestTriggeringScanning == KWlanIntCmdBackgroundScan )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is background scan" );
+
+ return ETrue;
+ }
+ else if( aCompletedMapEntry.iRequestId >= KWlanExtCmdBase &&
+ aCompletedMapEntry.iFunction == EGetAvailableIaps )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is GetAvailableIaps" );
+
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+ else if( aCheckedMapEntry.iFunction == EGetAvailableIaps )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The request to be checked is GetAvailableIaps" );
+
+ if( iRequestTriggeringScanning == KWlanIntCmdBackgroundScan )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is background scan" );
+
+ return ETrue;
+ }
+ else if( aCompletedMapEntry.iRequestId >= KWlanExtCmdBase &&
+ aCompletedMapEntry.iFunction == EGetAvailableIaps )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is GetAvailableIap" );
+
+ return ETrue;
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is not scan related" );
+
+ return EFalse;
+ }
+ }
+ else if( aCheckedMapEntry.iFunction == EGetScanResults )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The request to be checked is GetScanResults" );
+
+ core_ssid_s* triggeringSsid = reinterpret_cast<core_ssid_s*>( aCompletedMapEntry.iParam1 );
+ core_ssid_s* checkedSsid = reinterpret_cast<core_ssid_s*>( aCheckedMapEntry.iParam1 );
+
+ if( checkedSsid->length == 0 &&
+ aCompletedMapEntry.iRequestId == KWlanIntCmdBackgroundScan )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is background scan" );
+
+ return ETrue;
+ }
+ else if( aCompletedMapEntry.iRequestId >= KWlanExtCmdBase &&
+ checkedSsid->length == 0 &&
+ aCompletedMapEntry.iFunction == EGetAvailableIaps )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is GetAvailableIaps" );
+
+ return ETrue;
+ }
+ else if( aCompletedMapEntry.iRequestId >= KWlanExtCmdBase &&
+ checkedSsid->length == 0 &&
+ aCompletedMapEntry.iFunction == EGetScanResults &&
+ triggeringSsid->length == 0 )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is GetScanResults (broadcast)" );
+
+ return ETrue;
+ }
+ else if( aCompletedMapEntry.iRequestId >= KWlanExtCmdBase &&
+ checkedSsid->length != 0 &&
+ aCompletedMapEntry.iFunction == EGetScanResults &&
+ triggeringSsid->length != 0 &&
+ *checkedSsid == *triggeringSsid )
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is GetScanResults (direct) and both have same SSID" );
+
+ return ETrue;
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CanRequestBeCompleted() - The triggering request is something else" );
+
+ return EFalse;
+ }
+
+ }
+ return EFalse;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CompleteInternalRequest
+// ---------------------------------------------------------
+//
+void CWlmServer::CompleteInternalRequest(
+ TUint32 aIndex,
+ core_error_e aStatus,
+ TBool aCompletedWasTriggering )
+ {
+ DEBUG1( "CWlmServer::CompleteInternalRequest() - index (%d)", aIndex );
+
+ // Take the entry out from queue
+ SRequestMapEntry requestEntry = iRequestMap[ aIndex ];
+
+ iRequestMap.Remove( aIndex );
+
+ switch( requestEntry.iRequestId )
+ {
+ case KWlanIntCmdBackgroundScan:
+ {
+ core_type_list_c<core_ssid_entry_s>* iapSsidList =
+ reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( requestEntry.iParam3 );
+ delete iapSsidList;
+ iapSsidList = NULL;
+
+ ScanList* scanList =
+ reinterpret_cast<ScanList*>( requestEntry.iParam2 );
+ core_type_list_c<u32_t>* idList =
+ reinterpret_cast<core_type_list_c<u32_t>*>( requestEntry.iParam1 );
+
+ core_type_list_c<core_iap_data_s>* iapDataList =
+ reinterpret_cast<core_type_list_c<core_iap_data_s>*>( requestEntry.iParam0 );
+ delete iapDataList;
+ iapDataList = NULL;
+
+ TTime* completedScanTime = reinterpret_cast<TTime*>( requestEntry.iTime );
+ delete completedScanTime;
+ completedScanTime = NULL;
+
+ if( aCompletedWasTriggering )
+ {
+ DEBUG( "CWlmServer::CompleteInternalRequest() - this request was handled by core" );
+
+ if( aStatus == core_error_ok )
+ {
+ NotifyBackgroundScanDone( scanList, idList );
+ // cache takes the ownership of the scanList
+ scanList = NULL;
+ }
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CompleteInternalRequest() - this request was not handled by core" );
+ }
+
+ delete scanList;
+ scanList = NULL;
+ delete idList;
+ idList = NULL;
+
+ break;
+ }
+ case KWlanIntCmdNull: // Fall through on purpose
+ default:
+ break;
+ // not interested in rest of the internal request completions
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CompleteExternalRequest
+// ---------------------------------------------------------
+//
+void CWlmServer::CompleteExternalRequest(
+ TUint32 aIndex,
+ core_error_e aStatus,
+ SRequestMapEntry* aTriggerRequest )
+ {
+ DEBUG1( "CWlmServer::CompleteExternalRequest() - index (%d)", aIndex );
+
+ // Take the entry out from queue
+ SRequestMapEntry requestEntry = iRequestMap[ aIndex ];
+
+ // Find out the request type
+ // in order to handle possible return parameters
+ switch( requestEntry.iFunction )
+ {
+ case EGetScanResults:
+ {
+ ScanList* tmp( NULL );
+ core_ssid_s* ssid = reinterpret_cast<core_ssid_s*>( requestEntry.iParam1 );
+ TTime* completedScanTime = reinterpret_cast<TTime*>( requestEntry.iTime );
+ ScanList* completedScanList = reinterpret_cast<ScanList*>( requestEntry.iParam0 );
+
+ if( aTriggerRequest == NULL )
+ {
+ DEBUG( "CWlmServer::CompleteExternalRequest() - GetScanResults request handled by core" );
+
+ tmp = reinterpret_cast<ScanList*>( requestEntry.iParam0);
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CompleteExternalRequest() - GetScanResults request not handled by core" );
+ // Use the results of the triggering request to complete also this other request
+ // Check was the triggering request background scan or GetAvailableIaps or
+ // was it GetScanResults because the ScanList is stored to different parameter
+ if( aTriggerRequest->iRequestId >= KWlanExtCmdBase && aTriggerRequest->iFunction == EGetScanResults )
+ {
+ tmp = reinterpret_cast<ScanList*>( aTriggerRequest->iParam0 );
+ }
+ else
+ {
+ tmp = reinterpret_cast<ScanList*>( aTriggerRequest->iParam2 );
+ }
+ }
+
+ if( aStatus == core_error_ok )
+ {
+ TDynamicScanList dynamicScanList;
+ dynamicScanList.count = tmp->Count();
+ dynamicScanList.size = tmp->Size();
+
+ TPckgBuf<TDynamicScanList> pckgDynamicScanList( dynamicScanList );
+ TPtr8 ptrScanList(
+ tmp->Data(),
+ tmp->Size(),
+ tmp->Size() );
+
+ DEBUG2( "CWlmServer::CompleteExternalRequest() - scan results count is %u, size is %u",
+ tmp->Count(), tmp->Size() );
+
+ if( requestEntry.iSessionId != 0 )
+ {
+ requestEntry.iMessage.Write( 0, ptrScanList );
+ requestEntry.iMessage.Write( 2, pckgDynamicScanList );
+ }
+
+ // Check whether to cache the results or not
+ if( ssid->length > 0 && aTriggerRequest == NULL )
+ {
+ // direct scan results are not cached
+ DEBUG( "CWlmServer::CompleteExternalRequest() - direct scan; not caching scan results" );
+
+ delete tmp;
+ }
+ else if( aTriggerRequest == NULL )
+ {
+ // not deleting scanList, because cache takes the ownership
+ DEBUG( "CWlmServer::CompleteExternalRequest() - caching scan results" );
+ iCache->UpdateScanList( tmp );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CompleteExternalRequest() - request not handled by core; not caching scan results" );
+
+ delete completedScanList;
+ }
+ }
+ else
+ {
+ // scan failed due to some reason: not caching anything
+ if( aTriggerRequest == NULL )
+ {
+ delete tmp;
+ }
+ else
+ {
+ delete completedScanList;
+ }
+ }
+
+ delete ssid; // ssid
+ delete completedScanTime;
+ break;
+ }
+ case EReset:
+ {
+ // no parameters to return
+ break;
+ }
+ case EGetAvailableIaps:
+ {
+ // Create pointers to parameters
+ core_type_list_c<core_ssid_entry_s>* iapSsidList;
+ ScanList* scanList;
+ core_type_list_c<u32_t>* coreIdList;
+ core_type_list_c<core_iap_data_s>* iapDataList;
+
+ iapSsidList = reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( requestEntry.iParam3 );
+ iapDataList = reinterpret_cast<core_type_list_c<core_iap_data_s>*>( requestEntry.iParam0 );
+
+ TTime* completedScanTime = reinterpret_cast<TTime*>( requestEntry.iTime );
+ ScanList* completedScanList = reinterpret_cast<ScanList*>( requestEntry.iParam2);
+ core_type_list_c<u32_t>* completedIdList = reinterpret_cast<core_type_list_c<u32_t>*>( requestEntry.iParam1 );
+
+ if( aTriggerRequest == NULL )
+ {
+ DEBUG( "CWlmServer::CompleteExternalRequest() - GetAvailableIaps request handled by core" );
+
+ scanList = reinterpret_cast<ScanList*>( requestEntry.iParam2);
+ coreIdList = reinterpret_cast<core_type_list_c<u32_t>*>( requestEntry.iParam1 );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CompleteExternalRequest() - GetAvailableIaps request not handled by core" );
+ //Use the results of the triggering request to complete also this other request
+ scanList = reinterpret_cast<ScanList*>( aTriggerRequest->iParam2);
+ coreIdList = reinterpret_cast<core_type_list_c<u32_t>*>( aTriggerRequest->iParam1 );
+ }
+
+ delete iapSsidList;
+ iapSsidList = NULL;
+ delete iapDataList;
+ iapDataList = NULL;
+
+ if( aStatus == core_error_ok )
+ {
+ RArray<TWlanAvailableNetwork> networkList;
+ GetNetworkList( *scanList, networkList );
+
+ // Update Cached results
+ TBool newIaps( EFalse );
+ TBool lostIaps( EFalse );
+
+ if( aTriggerRequest == NULL )
+ {
+ iCache->UpdateAvailableNetworksList(
+ *coreIdList,
+ networkList,
+ newIaps,
+ lostIaps );
+ }
+ networkList.Close();
+
+ TWlmAvailableIaps tmp;
+ TUint32* pInt = coreIdList->first();
+ TInt idx = 0;
+ while( pInt )
+ {
+ DEBUG1( "CWlmServer::CompleteExternalRequest() - IAP %u is available",
+ *pInt );
+ tmp.iaps[ idx ] = *pInt;
+ idx++;
+ pInt = coreIdList->next();
+ }
+
+ tmp.count = idx;
+
+ if( requestEntry.iSessionId != 0 )
+ {
+ TPckg<TWlmAvailableIaps> outPckg( tmp );
+ requestEntry.iMessage.Write( 0, outPckg );
+ }
+ if( aTriggerRequest == NULL )
+ {
+ DEBUG1("CWlmServer::CompleteExternalRequest() - delete iapIdList (%d)", coreIdList);
+
+ delete coreIdList;
+ }
+ else
+ {
+ // If this completed request was not the triggering request then there is no need
+ // to cache anything. The triggering request results will be cached.
+ delete completedIdList;
+ delete completedScanList;
+ }
+
+ // handle scan list
+ if( aTriggerRequest == NULL )
+ {
+ iCache->UpdateScanList( scanList );
+ // not deleting scanList, because cache takes the ownership
+
+ UpdateAvailabilityInfo(
+ newIaps,
+ lostIaps,
+ scanList->Count() != 0 );
+ }
+ }
+ else
+ {
+ // scan failed due to some reason: not caching anything
+ if( aTriggerRequest == NULL )
+ {
+ delete coreIdList;
+ delete scanList;
+ }
+ else
+ {
+ // Delete only the lists of the completed request. Triggering request lists are
+ // deleted later on when that request is actually handled.
+ delete completedIdList;
+ delete completedScanList;
+ }
+ }
+ delete completedScanTime;
+ break;
+ }
+ case EGetCurrentRSSI:
+ {
+ TUint32 tmp
+ = *( reinterpret_cast<TUint32*>
+ ( requestEntry.iParam0 ) );
+ if( requestEntry.iSessionId != 0 )
+ {
+ TPckg<TUint32> outPckg( tmp );
+ requestEntry.iMessage.Write( 0, outPckg );
+ }
+ iPrevRcpiValue = tmp;
+ delete reinterpret_cast<TUint32*>( requestEntry.iParam0 );
+ break;
+ }
+ case EGetSystemMode:
+ {
+ // not asynch request; never comes here
+ break;
+ }
+ case EConfigureMulticastGroup:
+ {
+ // no parameters to return
+ delete reinterpret_cast<TUint32*>( requestEntry.iParam0 );
+ break;
+ }
+ case EGetPacketStatistics:
+ {
+ core_packet_statistics_s* coreStatistics =
+ reinterpret_cast<core_packet_statistics_s*>( requestEntry.iParam0 );
+ if( requestEntry.iSessionId != 0 )
+ {
+ TPckgBuf<TWlanPacketStatistics> statisticPckg;
+ TWlanConversionUtil::ConvertPacketStatistics(
+ statisticPckg(),
+ *coreStatistics );
+ requestEntry.iMessage.Write( 0, statisticPckg );
+ }
+ delete coreStatistics;
+ break;
+ }
+ case ECreateTrafficStream:
+ {
+ u32_t* coreStreamId =
+ reinterpret_cast<u32_t*>( requestEntry.iParam0 );
+ core_traffic_stream_status_e* coreStreamStatus =
+ reinterpret_cast<core_traffic_stream_status_e*>( requestEntry.iParam1 );
+ if( requestEntry.iSessionId != 0 &&
+ aStatus == core_error_ok )
+ {
+ TPckgBuf<TUint> streamIdPckg(
+ *coreStreamId );
+ TPckgBuf<TWlanTrafficStreamStatus> streamStatusPckg(
+ TWlanConversionUtil::ConvertTrafficStreamStatus( *coreStreamStatus ) );
+ requestEntry.iMessage.Write( 2, streamIdPckg );
+ requestEntry.iMessage.Write( 3, streamStatusPckg );
+ }
+ delete coreStreamId;
+ delete coreStreamStatus;
+ break;
+ }
+ case EDeleteTrafficStream:
+ {
+ // no parameters to return
+ break;
+ }
+ case EDirectedRoam:
+ {
+ // no parameters to return
+ break;
+ }
+ default:
+ {
+ DEBUG1( "CWlmServer::CompleteExternalRequest() - ERROR: unknown request type (%d)!",
+ requestEntry.iFunction );
+ break;
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::IsAvailableNetworkEqual
+// ---------------------------------------------------------
+//
+TBool CWlmServer::IsAvailableNetworkEqual(
+ const TWlanAvailableNetwork& aFirst,
+ const TWlanAvailableNetwork& aSecond )
+ {
+ if( aFirst.ssid != aSecond.ssid )
+ {
+ return EFalse;
+ }
+
+ if( aFirst.networkType != aSecond.networkType )
+ {
+ return EFalse;
+ }
+
+ if( aFirst.securityMode != aSecond.securityMode )
+ {
+ return EFalse;
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetNetworkList
+// ---------------------------------------------------------
+//
+TInt CWlmServer::GetNetworkList(
+ const ScanList& aScanList,
+ RArray<TWlanAvailableNetwork>& aNetworkList )
+ {
+ DEBUG( "CWlmServer::GetNetworkList()" );
+
+ ScanInfo info( aScanList );
+ TIdentityRelation<TWlanAvailableNetwork> isEqual( IsAvailableNetworkEqual );
+ for( info.First(); !info.IsDone(); info.Next() )
+ {
+ TUint8 ieLength( 0 );
+ const TUint8* ieData = NULL;
+
+ if ( info.InformationElement( E802Dot11SsidIE, ieLength, &ieData ) == WlanScanError_Ok &&
+ ieLength <= KMaxSSIDLength )
+ {
+ TWlanAvailableNetwork network;
+ network.ssid.Copy( ieData, ieLength );
+ network.securityMode = info.SecurityMode();
+ if( info.OperatingMode() == WlanOperatingModeInfra )
+ {
+ network.networkType = Infrastructure;
+ }
+ else
+ {
+ network.networkType = Adhoc;
+ }
+
+ if ( aNetworkList.Find( network, isEqual ) == KErrNotFound )
+ {
+ DEBUG1S( "CWlmServer::GetNetworkList() - appending SSID ",
+ ieLength, ieData );
+ aNetworkList.Append( network );
+ }
+ }
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::UpdateAvailabilityInfo
+// ---------------------------------------------------------
+//
+void CWlmServer::UpdateAvailabilityInfo(
+ TBool aNewNetworksDetected,
+ TBool aOldNetworksLost,
+ TBool aAnyNetworksDetected )
+ {
+ DEBUG1( "CWlmServer::UpdateAvailabilityInfo() - aNewNetworksDetected: %u",
+ aNewNetworksDetected );
+ DEBUG1( "CWlmServer::UpdateAvailabilityInfo() - aOldNetworksLost: %u",
+ aOldNetworksLost );
+ DEBUG1( "CWlmServer::UpdateAvailabilityInfo() - aAnyNetworksDetected: %u",
+ aAnyNetworksDetected );
+
+ /**
+ * Make sure background scan is on before giving any indications.
+ */
+ if( !iBgScanProvider->IsBgScanEnabled() )
+ {
+ DEBUG( "CWlmServer::UpdateAvailabilityInfo() - background scan is not enabled, not sending any indications" );
+ return;
+ }
+
+ /**
+ * Notify clients about new networks/IAPs if necessary.
+ */
+ if( aNewNetworksDetected )
+ {
+ TBuf8<1> tmp;
+ for( TInt i = 0; i < iNotificationArray.Count(); i++ )
+ {
+ iNotificationArray[i]->AddNotification( EWlmNotifyNewNetworksDetected, tmp );
+ }
+ }
+
+ /**
+ * Notify clients about lost networks/IAPs if necessary.
+ */
+ if( aOldNetworksLost )
+ {
+ TBuf8<1> tmp;
+ for( TInt i = 0; i < iNotificationArray.Count(); i++ )
+ {
+ iNotificationArray[i]->AddNotification( EWlmNotifyOldNetworksLost, tmp );
+ }
+ }
+
+ /**
+ * Set icon state if not connected.
+ */
+ if( iConnectionState == EWlanStateNotConnected )
+ {
+ if( aAnyNetworksDetected )
+ {
+ SetIconState( EWlmIconStatusAvailable );
+ }
+ else
+ {
+ SetIconState( EWlmIconStatusNotAvailable );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelExternalRequest
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelExternalRequest(
+ TUint aSessionId,
+ TWLMCommands aCommand )
+ {
+ DEBUG( "CWlmServer::CancelExternalRequest()" );
+ DEBUG1( "CWlmServer::CancelExternalRequest() - aSessionId: %u",
+ aSessionId );
+ DEBUG1( "CWlmServer::CancelExternalRequest() - aCommand: %u",
+ aCommand );
+
+#ifdef _DEBUG
+ DEBUG( "CWlmServer::CancelExternalRequest()" );
+ DEBUG( "CWlmServer::CancelExternalRequest() - iRequestMap:" );
+
+ for ( TInt idx( 0 ); idx < iRequestMap.Count(); ++idx )
+ {
+ DEBUG1( "CWlmServer::CancelExternalRequest() - iRequestId %u",
+ iRequestMap[idx].iRequestId );
+ DEBUG1( "CWlmServer::CancelExternalRequest() - iSessionId %u",
+ iRequestMap[idx].iSessionId );
+ DEBUG1( "CWlmServer::CancelExternalRequest() - iFunction: %d",
+ iRequestMap[idx].iFunction );
+ }
+#endif // _DEBUG
+
+ for( TInt i( 0 ); i < iRequestMap.Count(); i++ )
+ {
+ if( iRequestMap[i].iSessionId == aSessionId &&
+ iRequestMap[i].iFunction == aCommand )
+ {
+ DEBUG( "CWlmServer::CancelExternalRequest() - corresponding request found, cancelling" );
+
+ if( iRequestMap[i].iRequestId == iRequestTriggeringScanning &&
+ iCoreHandlingScanRequest )
+ {
+ // Core is already handling this scan request
+ // request Core to cancel the handling
+ DEBUG( "CWlmServer::CancelExternalRequest() - Core is already handling this request, send cancel request" );
+
+ iCoreServer->cancel_request(
+ iRequestMap[i].iRequestId );
+ }
+ else if( iRequestMap[i].iRequestId == iRequestTriggeringScanning )
+ {
+ // Core is not handling currently this scan request
+ // Complete the cancelled request and timer is set again
+ DEBUG( "CWlmServer::CancelExternalRequest() - Core is not handling currently this request" );
+ DEBUG( "CWlmServer::CancelExternalRequest() - Cancel timer, complete cancelled request and set timer" );
+
+ iScanSchedulingTimer->Cancel();
+ request_complete( iRequestMap[i].iRequestId, core_error_cancel );
+ }
+ else
+ {
+ if( iRequestMap[i].iFunction == EGetScanResults ||
+ iRequestMap[i].iFunction == EGetAvailableIaps )
+ {
+ // Core is not handling currently this scan request
+ // Remove the cancelled request
+ DEBUG( "CWlmServer::CancelExternalRequest() - Core is not handling currently this scan request" );
+ DEBUG( "CWlmServer::CancelExternalRequest() - this request is not the scan scheduling triggering request" );
+ DEBUG( "CWlmServer::CancelExternalRequest() - remove the cancelled request" );
+
+ CompleteExternalRequest( i, core_error_cancel );
+ if( IsSessionActive( iRequestMap[i] ) )
+ {
+ iRequestMap[i].iMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( core_error_cancel ) );
+ }
+
+ iRequestMap.Remove( i );
+ }
+ else
+ {
+ // Cancelled request is not a scan scheduling related request
+ // make normal cancel handling and request Core to cancel the handling
+ DEBUG( "CWlmServer::CancelExternalRequest() - Cancelled request is not a scan scheduling related request" );
+
+ iCoreServer->cancel_request(
+ iRequestMap[i].iRequestId );
+ }
+ }
+ return;
+ }
+ }
+
+ DEBUG( "CWlmServer::CancelExternalRequest() - no pending request found, ignoring" );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CheckScanSchedulingParameters
+// ---------------------------------------------------------
+//
+void CWlmServer::CheckScanSchedulingParameters(
+ TInt& aCacheLifetime,
+ TUint& aMaxDelay )
+ {
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - aCacheLifetime: %d", aCacheLifetime );
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - aMaxDelay: %u", aMaxDelay);
+
+ if( aMaxDelay == KWlmInfiniteScanDelay )
+ {
+ DEBUG( "CWlmServer::CheckScanSchedulingParameters() - infinite aMaxDelay" );
+ }
+ else if( aMaxDelay > KWlmMaxScanDelay )
+ {
+ aMaxDelay = KWlmMaxScanDelay;
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - new aMaxDelay: %u", aMaxDelay );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CheckScanSchedulingParameters() - no changes to aMaxDelay" );
+ }
+
+ // cacheLifetime parameter has meaning only when maxDelay is zero
+ if( aMaxDelay != 0 )
+ {
+ aCacheLifetime = 0;
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - aMaxDelay non-zero -> new aCacheLifetime: %d", aCacheLifetime );
+ }
+ else
+ {
+ if( aCacheLifetime > KWlmMaxScanCacheLifetime )
+ {
+ aCacheLifetime = KWlmMaxScanCacheLifetime;
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - new aCacheLifetime: %d", aCacheLifetime );
+ }
+ else if( aCacheLifetime == KWlmDefaultScanCacheLifetime )
+ {
+ aCacheLifetime = iConfiguredCacheLifetime;
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - new aCacheLifetime: %d", aCacheLifetime );
+ }
+ else if( aCacheLifetime < KWlmMinScanCacheLifetime )
+ {
+ aCacheLifetime = KWlmMinScanCacheLifetime;
+ DEBUG1( "CWlmServer::CheckScanSchedulingParameters() - new aCacheLifetime: %d", aCacheLifetime );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CheckScanSchedulingParameters() - no changes to aCacheLifetime" );
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::cancel_request
+// ---------------------------------------------------------
+//
+void CWlmServer::cancel_request(
+ u32_t /* request_id */ )
+ {
+ DEBUG( "CWlmServer::cancel_request" );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::load_eapol
+// ---------------------------------------------------------
+//
+u32_t CWlmServer::load_eapol(
+ core_eapol_operating_mode_e mode,
+ abs_wlan_eapol_callback_c* const partner )
+ {
+ DEBUG( "CWlmServer::load_eapol" );
+
+ if ( iEapolClient )
+ {
+ DEBUG( "CWlmServer::load_eapol - CWlanEapolClient already instantiated." );
+ return wlan_eapol_if_error_ok;
+ }
+
+ TInt implementationUid( KCWlanEapolClientUid );
+ if( mode == core_eapol_operating_mode_wapi )
+ {
+ implementationUid = KCWlanWapiClientUid;
+ }
+
+ TRAPD( ret, iEapolClient = CWlanEapolClient::NewL(
+ implementationUid, this ) ); // "this" is instance providing SendData()
+ if( ret != KErrNone )
+ {
+ DEBUG1( "ERROR: CWlanEapolClient::NewL leaved with %d.", ret );
+ return wlan_eapol_if_error_allocation_error;
+ }
+ iEapolHandler = partner;
+ return wlan_eapol_if_error_ok;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::shutdown
+// ---------------------------------------------------------
+//
+u32_t CWlmServer::shutdown()
+ {
+ DEBUG( "CWlmServer::shutdown" );
+ ASSERT( iEapolClient );
+
+ iEapolClient->Shutdown();
+ delete iEapolClient;
+ iEapolClient = NULL;
+
+ return wlan_eapol_if_error_ok;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::configure
+// ---------------------------------------------------------
+//
+u32_t CWlmServer::configure(
+ const u32_t header_offset,
+ const u32_t MTU,
+ const u32_t trailer_length )
+ {
+ DEBUG( "CWlmServer::configure" );
+ ASSERT( iEapolClient );
+ return iEapolClient->Configure( header_offset, MTU, trailer_length );
+ }
+
+
+// ---------------------------------------------------------
+// CWlmServer::process_data
+// ---------------------------------------------------------
+//
+u32_t CWlmServer::process_data(
+ const void * const data,
+ const u32_t length )
+ {
+ DEBUG( "CWlmServer::process_data" );
+ ASSERT( iEapolClient );
+ return iEapolClient->ProcessData( data, length );
+ }
+
+
+// ---------------------------------------------------------
+// CWlmServer::HandleCoreAsynchCb
+// ---------------------------------------------------------
+//
+TInt CWlmServer::HandleCoreAsynchCb( TAny* aThisPtr )
+ {
+ CWlmServer* self = static_cast<CWlmServer*>( aThisPtr );
+
+ /**
+ * This could be a problem if the core immediately sets
+ * another pending callback request.
+ */
+
+ self->iCoreServer->request_complete(
+ self->iCoreAsynchCbId,
+ self->iCoreAsynchCbStatus );
+
+ self->iCoreAsynchCbId = 0;
+ self->iCoreAsynchCbStatus = core_error_ok;
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::BackgroundScanRequest
+// ---------------------------------------------------------
+//
+TInt CWlmServer::BackgroundScanRequest(
+ TUint aScanStartInterval )
+ {
+ DEBUG1( "CWlmServer::BackgroundScanRequest() - aScanStartInterval %u", aScanStartInterval );
+
+ // Create list for WLAN IAP data
+ core_type_list_c<core_iap_data_s>* iapDataList = new core_type_list_c<core_iap_data_s>;
+ if( iapDataList == NULL )
+ {
+ // Do nothing and hope that on next expiry there is enough memory
+ DEBUG( "CWlmServer::BackgroundScanRequest() - Out of memory" );
+ return KErrNoMemory;
+ }
+
+ // Create list for secondary SSID data
+ core_type_list_c<core_ssid_entry_s>* iapSsidList = new core_type_list_c<core_ssid_entry_s>;
+ if ( !iapSsidList )
+ {
+ DEBUG( "CWlmServer::BackgroundScanRequest() - unable to instance core_ssid_entry_s list" );
+
+ delete iapDataList;
+
+ return KErrNoMemory;
+ }
+
+ // Read IAP data from CommDb
+ RArray<TWlanLimitedIapData> iapList;
+ TInt ret = iCache->GetIapDataList( iapList );
+ if( ret )
+ {
+ DEBUG1( "CWlmServer::BackgroundScanRequest() - GetIapDataList failed (%d)", ret );
+
+ delete iapDataList;
+ delete iapSsidList;
+ iapList.Close();
+
+ return ret;
+ }
+
+ // Convert IAP data
+ ret = GetIapDataList(
+ *iapDataList,
+ *iapSsidList,
+ iapList );
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::BackgroundScanRequest() - unable to convert IAP data (%d)", ret );
+
+ delete iapDataList;
+ delete iapSsidList;
+ iapList.Close();
+
+ return ret;
+ }
+
+ iapList.Close();
+
+ // Create output list
+ core_type_list_c<u32_t>* iapIdList = new core_type_list_c<u32_t>;
+ if( iapIdList == NULL )
+ {
+ DEBUG( "ERROR: Out of memory" );
+ delete iapDataList;
+ delete iapSsidList;
+ return KErrNoMemory;
+ }
+
+ // Create ScanList
+ ScanList* scanList = new ScanList( KWlmScanListMaxSize );
+ if( scanList == NULL )
+ {
+ DEBUG( "CWlmServer::BackgroundScanRequest() - Out of memory when instantiating ScanList" );
+ delete iapDataList;
+ delete iapSsidList;
+ delete iapIdList;
+ return KErrNoMemory;
+ }
+
+ TTime* scanTime = new TTime(
+ CalculateScanStartTime( aScanStartInterval ).Int64() );
+ if( !scanTime )
+ {
+ DEBUG( "CWlmServer::BackgroundScanRequest() - unable to instantiate TTime" );
+
+ delete iapDataList;
+ delete iapSsidList;
+ delete iapIdList;
+ delete scanList;
+ return KErrNoMemory;
+ }
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iRequestId = KWlanIntCmdBackgroundScan;
+ mapEntry.iParam0 = iapDataList;
+ mapEntry.iParam1 = iapIdList;
+ mapEntry.iParam2 = scanList;
+ mapEntry.iParam3 = iapSsidList;
+ mapEntry.iTime = scanTime;
+ iRequestMap.Append( mapEntry );
+
+ if( IsOnlyTimedScanRequestInRequestMap( mapEntry ) || *scanTime < iScanSchedulingTimerExpiration )
+ {
+ // Scan scheduling timer needs to be set again because this request needs the results earlier
+ UpdateScanSchedulingTimer( *scanTime, mapEntry.iRequestId );
+ }
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::ScanSchedulingTimerExpired
+// ---------------------------------------------------------
+//
+TInt CWlmServer::ScanSchedulingTimerExpired( TAny* aThisPtr )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired()" );
+
+ CWlmServer* self = static_cast<CWlmServer*>( aThisPtr );
+
+ TInt index = self->FindRequestIndex( self->iRequestTriggeringScanning );
+
+ if( index >= self->iRequestMap.Count() && self->iBgScanProvider->IsBgScanEnabled() )
+ {
+ /**
+ * This is most probably caused by the periodic background scan. It can happen if background
+ * scan is enabled but something fails when background scan request is tried to be added to
+ * scan scheduling queue.
+ *
+ * Add background scan request to scan scheduling queue and it should be handled immediately.
+ * Check that there are no background scans pending in the queue.
+ */
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - request is not in iRequestMap, but background scan enabled" );
+
+ self->BackgroundScanRequest( 0 );
+ }
+ else if( index >= self->iRequestMap.Count() )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - request is not in the iRequestMap, do nothing" );
+ return KErrNone;
+ }
+
+ DEBUG1( "CWlmServer::ScanSchedulingTimerExpired() - iRequestId %u", self->iRequestMap[index].iRequestId );
+
+ TUint indexNextScan( 0 );
+ // If roaming is ongoing, scanning is not started for GetScanResults.
+ if ( self->iRequestMap[index].iRequestId >= KWlanExtCmdBase &&
+ self->iRequestMap[index].iFunction == EGetScanResults &&
+ self->IsRoaming() )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - GetScanResults, roam in progress, returning empty scan results" );
+
+ ScanList* completedScanList = reinterpret_cast<ScanList*>( self->iRequestMap[index].iParam0 );
+ core_ssid_s* completedSsid = reinterpret_cast<core_ssid_s*>( self->iRequestMap[index].iParam1 );
+ TTime* completedScanTime = reinterpret_cast<TTime*>( self->iRequestMap[index].iTime );
+
+ // Only the triggering request is completed and then scan scheduling timer is set again
+ TPckgBuf<TUint32> pckgCount( 0 );
+ TPckgBuf<TUint32> pckgSize( 0 );
+
+ TPckgBuf<TDynamicScanList> pckgDynamicScanList;
+ pckgDynamicScanList().count = 0;
+ pckgDynamicScanList().size = 0;
+
+ if( self->IsSessionActive( self->iRequestMap[index] ) )
+ {
+ self->iRequestMap[index].iMessage.Write( 2, pckgDynamicScanList );
+ self->iRequestMap[index].iMessage.Complete( KErrNone );
+ }
+
+ delete completedScanList;
+ completedScanList = NULL;
+ delete completedSsid;
+ completedSsid = NULL;
+ delete completedScanTime;
+ completedScanTime = NULL;
+
+ self->iRequestMap.Remove( index );
+
+ if( self->FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ TTime* nextScanTime = reinterpret_cast<TTime*>( self->iRequestMap[indexNextScan].iTime );
+ self->UpdateScanSchedulingTimer( *nextScanTime, self->iRequestMap[indexNextScan].iRequestId );
+ }
+
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - message completed with empty scan results" );
+ return KErrNone;
+ }
+
+ // If roaming is ongoing, scanning is not started for GetAvailableIaps.
+ if ( self->iRequestMap[index].iRequestId >= KWlanExtCmdBase &&
+ self->iRequestMap[index].iFunction == EGetAvailableIaps &&
+ self->IsRoaming() )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - GetAvailableIaps, roam in progress, returning empty iap list" );
+
+ core_type_list_c<core_iap_data_s>* iapDataList = reinterpret_cast<core_type_list_c<core_iap_data_s>*>( self->iRequestMap[index].iParam0 );
+ core_type_list_c<u32_t>* iapIdList = reinterpret_cast<core_type_list_c<u32_t>*>( self->iRequestMap[index].iParam1 );
+ ScanList* scanList = reinterpret_cast<ScanList*>( self->iRequestMap[index].iParam2 );
+ core_type_list_c<core_ssid_entry_s>* iapSsidList = reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( self->iRequestMap[index].iParam3 );
+ TTime* scanTime = reinterpret_cast<TTime*>( self->iRequestMap[index].iTime );
+
+ // Only the triggering request is completed and then scan scheduling timer is set again
+ if( self->IsSessionActive( self->iRequestMap[index] ) )
+ {
+ TWlmAvailableIaps tmp = { 0 };
+ TPckg<TWlmAvailableIaps> outPckg( tmp );
+ self->iRequestMap[index].iMessage.Write( 0, outPckg );
+ self->iRequestMap[index].iMessage.Complete( KErrNone );
+ }
+
+ delete iapDataList;
+ iapDataList = NULL;
+ delete iapIdList;
+ iapIdList = NULL;
+ delete scanList;
+ scanList = NULL;
+ delete iapSsidList;
+ iapSsidList = NULL;
+ delete scanTime;
+ scanTime = NULL;
+
+ self->iRequestMap.Remove( index );
+
+ if( self->FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ TTime* nextScanTime = reinterpret_cast<TTime*>( self->iRequestMap[indexNextScan].iTime );
+ self->UpdateScanSchedulingTimer( *nextScanTime, self->iRequestMap[indexNextScan].iRequestId );
+ }
+
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - message completed with empty iap list" );
+ return KErrNone;
+ }
+
+ // If triggering request is background scan and WLAN connection exist, background scan is skipped
+ if( self->iRequestMap[index].iRequestId == KWlanIntCmdBackgroundScan &&
+ self->iConnectionState != EWlanStateNotConnected )
+ {
+ DEBUG("CWlmServer::ScanSchedulingTimerExpired() - active connection exists: skipping background scan");
+
+ // notify bg scan provider so it will issue a new CWlmServer::Scan() call,
+ // where the existing request map entry will be updated
+ self->iBgScanProvider->ScanComplete();
+
+ return KErrNone;
+ }
+
+ // Scan mode is either passive or active
+ core_scan_mode_e mode = core_scan_mode_active;
+ TBool isActiveScanAllowed( ETrue );
+ if( self->iPlatform->GetScanType() == EWLMScanForcedPassive )
+ {
+ mode = core_scan_mode_passive;
+ isActiveScanAllowed = EFalse;
+ }
+
+ if( self->iRequestMap[index].iRequestId == KWlanIntCmdBackgroundScan )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - starting background scan, cancel timer" );
+ // pass request to core
+ core_type_list_c<core_iap_data_s>* iapDataList = reinterpret_cast<core_type_list_c<core_iap_data_s>*>( self->iRequestMap[index].iParam0 );
+ core_type_list_c<core_ssid_entry_s>* iapSsidList = reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( self->iRequestMap[index].iParam3 );
+ core_type_list_c<u32_t>* iapIdList = reinterpret_cast<core_type_list_c<u32_t>*>( self->iRequestMap[index].iParam1 );
+ ScanList* scanList = reinterpret_cast<ScanList*>( self->iRequestMap[index].iParam2 );
+
+ self->iCoreServer->get_available_iaps(
+ self->iRequestMap[index].iRequestId,
+ isActiveScanAllowed,
+ *iapDataList,
+ *iapIdList,
+ iapSsidList,
+ *scanList );
+
+ self->iScanSchedulingTimer->Cancel();
+ }
+ else if( self->iRequestMap[index].iFunction == EGetScanResults )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - starting GetScanResults, cancel timer" );
+
+ // pass request to core
+ ScanList* tmp = reinterpret_cast<ScanList*>( self->iRequestMap[index].iParam0);
+ core_ssid_s* ssid2 = reinterpret_cast<core_ssid_s*>( self->iRequestMap[index].iParam1 );
+
+ self->iCoreServer->get_scan_result(
+ self->iRequestMap[index].iRequestId,
+ mode,
+ *ssid2,
+ SCAN_CHANNELS_2DOT4GHZ_ETSI,
+ 0,
+ *tmp,
+ false_t );
+
+ self->iScanSchedulingTimer->Cancel();
+ }
+ else if( self->iRequestMap[index].iFunction == EGetAvailableIaps )
+ {
+ DEBUG( "CWlmServer::ScanSchedulingTimerExpired() - starting GetAvailableIaps, cancel timer" );
+
+ // pass request to core
+ core_type_list_c<core_iap_data_s>* iapDataList = reinterpret_cast<core_type_list_c<core_iap_data_s>*>( self->iRequestMap[index].iParam0 );
+ core_type_list_c<core_ssid_entry_s>* iapSsidList = reinterpret_cast<core_type_list_c<core_ssid_entry_s>*>( self->iRequestMap[index].iParam3 );
+ core_type_list_c<u32_t>* iapIdList = reinterpret_cast<core_type_list_c<u32_t>*>( self->iRequestMap[index].iParam1 );
+ ScanList* scanList = reinterpret_cast<ScanList*>( self->iRequestMap[index].iParam2 );
+
+ self->iCoreServer->get_available_iaps(
+ self->iRequestMap[index].iRequestId,
+ isActiveScanAllowed,
+ *iapDataList,
+ *iapIdList,
+ iapSsidList,
+ *scanList );
+
+ self->iScanSchedulingTimer->Cancel();
+ }
+ self->iCoreHandlingScanRequest = ETrue;
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetIapDataList()
+// ---------------------------------------------------------
+//
+TInt CWlmServer::GetIapDataList(
+ core_type_list_c<core_iap_data_s>& aCoreIapDataList,
+ core_type_list_c<core_ssid_entry_s>& aCoreIapSsidList,
+ const RArray<TWlanLimitedIapData>& aAmIapDataList )
+ {
+ DEBUG( "CWlmServer::GetIapDataList()" );
+ DEBUG1( "CWlmServer::GetIapDataList() - converting %u entries",
+ aAmIapDataList.Count() );
+
+ /**
+ * Create a commsdat session for retrieving possible secondary SSIDs.
+ */
+ CWLanSettings wlanSettings;
+ TInt ret = wlanSettings.Connect();
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::GetIapDataList() - CWLanSettings::Connect() failed (%d)",
+ ret );
+
+ return ret;
+ }
+
+ // Loop given list of IAPs and create respective list of iap data
+ for( TInt idx( 0 ); idx < aAmIapDataList.Count(); idx++ )
+ {
+ if( aAmIapDataList[idx].ssid.Length() ) // filter out EasyWlan IAP
+ {
+ DEBUG1( "CWlmServer::GetIapDataList() - converting IAP %u",
+ aAmIapDataList[idx].iapId );
+
+ core_iap_data_s* coreData = new core_iap_data_s;
+ if( !coreData )
+ {
+ DEBUG( "CWlmServer::GetIapDataList() - unable to instantiate core_iap_data_s" );
+ wlanSettings.Disconnect();
+
+ return KErrNoMemory;
+ }
+
+ TWlanConversionUtil::ConvertIapSettings(
+ *coreData,
+ aAmIapDataList[idx] );
+
+ ret = aCoreIapDataList.append( coreData );
+ if( ret )
+ {
+ DEBUG1( "CWlmServer::GetIapDataList() - unable to append core_iap_data_s entry (%u)",
+ ret );
+ wlanSettings.Disconnect();
+ delete coreData;
+
+ return ret;
+ }
+
+ // Read possible secondary ssids
+ RArray<TWlanSecondarySsid> secondarySsidList;
+ wlanSettings.GetSecondarySsidsForService(
+ aAmIapDataList[idx].serviceId,
+ secondarySsidList );
+
+ // Create secondary SSID list if needed
+ if( aAmIapDataList[idx].usedSsid.Length() || secondarySsidList.Count() )
+ {
+ DEBUG1( "CWlmServer::GetIapDataList() - IAP %u has secondary SSIDs defined",
+ coreData->id );
+
+ core_ssid_entry_s* entry = new core_ssid_entry_s;
+ if ( !entry )
+ {
+ DEBUG( "CWlmServer::GetIapDataList() - unable to instantiate core_ssid_entry_s" );
+
+ secondarySsidList.Close();
+ wlanSettings.Disconnect();
+
+ return KErrNoMemory;
+ }
+
+ entry->id = coreData->id;
+ entry->ssid = coreData->ssid;
+ if( aAmIapDataList[idx].usedSsid.Length() )
+ {
+ TWlanConversionUtil::ConvertSSID( entry->used_ssid, aAmIapDataList[idx].usedSsid );
+ }
+ else
+ {
+ entry->used_ssid = entry->ssid;
+ }
+ aCoreIapSsidList.append( entry );
+
+ for( TInt idx( 0 ); idx < secondarySsidList.Count(); ++idx )
+ {
+ entry = new core_ssid_entry_s;
+ if ( !entry )
+ {
+ DEBUG( "CWlmServer::GetIapDataList() - unable to instantiate core_ssid_entry_s" );
+
+ secondarySsidList.Close();
+ wlanSettings.Disconnect();
+
+ return KErrNoMemory;
+ }
+
+ entry->id = coreData->id;
+ TWlanConversionUtil::ConvertSSID(
+ entry->ssid, secondarySsidList[idx].ssid );
+ if ( secondarySsidList[idx].usedSsid.Length() )
+ {
+ TWlanConversionUtil::ConvertSSID(
+ entry->used_ssid, secondarySsidList[idx].usedSsid );
+ }
+ else
+ {
+ entry->used_ssid = coreData->ssid;
+ }
+ aCoreIapSsidList.append( entry );
+ }
+ }
+
+ secondarySsidList.Close();
+ }
+ } // for loop
+
+ wlanSettings.Disconnect();
+
+ return KErrNone;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetLanSettings()
+// ---------------------------------------------------------
+//
+TInt CWlmServer::GetLanSettings(
+ TUint32 aLanServiceId,
+ SLanSettings& aLanSettings )
+ {
+ DEBUG("CWlmServer::GetLanSettings()");
+
+ TInt ret = KErrNone;
+ CLanSettings* lanSettings = new CLanSettings;
+ if( lanSettings == NULL )
+ {
+ DEBUG( "ERROR creating CLanSettings" );
+ return KErrNoMemory;
+ }
+
+ ret = lanSettings->Connect();
+ if( ret != KErrNone )
+ {
+ DEBUG1( "ERROR - Connect() failed with %d", ret );
+ lanSettings->Disconnect();
+ delete lanSettings;
+ return ret;
+ }
+
+ ret = lanSettings->GetLanSettings( aLanServiceId, aLanSettings );
+ if( ret != KErrNone )
+ {
+ DEBUG1( "ERROR - GetLanSettings() failed with %d", ret );
+ }
+ lanSettings->Disconnect();
+ delete lanSettings;
+ return ret;
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::BtConnectionEstablished
+// ---------------------------------------------------------
+//
+void CWlmServer::BtConnectionEstablished()
+ {
+ iDriverIf->Notify( core_am_indication_bt_connection_established );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::BtConnectionDisabled
+// ---------------------------------------------------------
+//
+void CWlmServer::BtConnectionDisabled()
+ {
+ iDriverIf->Notify( core_am_indication_bt_connection_disconnected );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SystemTimeChanged
+// ---------------------------------------------------------
+//
+void CWlmServer::SystemTimeChanged()
+ {
+ DEBUG("CWlmServer::SystemTimeChanged()");
+
+ if ( iIsStartupComplete )
+ {
+ // If the changed time is less than cached region timestamp,
+ // then cache is cleared.
+ TTime newTime;
+ newTime.UniversalTime();
+
+ if ( newTime.Int64() < iTimeofDomainQuery.Int64() )
+ {
+ // Region cache expires when user has changed the time
+ TTime timestampClear(1);
+ iTimeofDomainQuery = timestampClear;
+
+ TRAPD( ret, StoreWlanCenRepKeyValueL( KWlanRegion, KWlmRegionUnknown ));
+ if ( ret == KErrNone )
+ {
+ TRAP( ret, StoreWlanCenRepKeyValueL( KWlanRegionTimestamp, iTimeofDomainQuery.Int64() ));
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::SystemTimeChanged() - attempt to store region timestamp leaved with code %d,", ret );
+ }
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::SystemTimeChanged() - attempt to store region leaved with code %d,", ret );
+ }
+ }
+
+ DEBUG("CWlmServer::SystemTimeChanged() - inform timer services about system time change");
+ iTimerServices->HandleTimeout();
+ DEBUG("CWlmServer::SystemTimeChanged() - refreshing settings to BgScan provider");
+ iBgScanProvider->NotifyChangedSettings( iBgScanProviderSettings );
+
+ // Pending scan requests should be handled because after the system time change all the
+ // timestamps are invalid. Change the scan start times to start immediately
+
+ DEBUG("CWlmServer::SystemTimeChanged() - set all pending requests to expire immediately");
+
+ TInt i( 0 );
+ for( i = 0; i < iRequestMap.Count(); i++ )
+ {
+ if( IsPendingTimedScanRequest(i) )
+ {
+ DEBUG1( "CWlmServer::SystemTimeChanged() - setting iTime to current time for request %i",
+ iRequestMap[i].iRequestId );
+
+ TTime* requestedScanTime = reinterpret_cast<TTime*>( iRequestMap[i].iTime );
+ requestedScanTime->UniversalTime();
+ }
+ }
+ if( !iCoreHandlingScanRequest )
+ {
+ // Core is not handling any scan request so update the timer
+ DEBUG("CWlmServer::SystemTimeChanged() - Core is not currently handling any scan requests");
+ DEBUG("CWlmServer::SystemTimeChanged() - Cancel timer and set it again to new value");
+
+ iScanSchedulingTimer->Cancel();
+ TUint indexNextScan;
+ if( FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ TTime* nextScanTime = reinterpret_cast<TTime*>( iRequestMap[indexNextScan].iTime );
+ UpdateScanSchedulingTimer( *nextScanTime, iRequestMap[indexNextScan].iRequestId );
+ }
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::ClearRegionCache
+// ---------------------------------------------------------
+//
+void CWlmServer::ClearRegionCache()
+ {
+ DEBUG("CWlmServer::ClearRegionCache()");
+
+ // Region cache expires when user has changed the time
+ TTime timestampClear(1);
+ iTimeofDomainQuery = timestampClear;
+
+ TRAPD( ret, StoreWlanCenRepKeyValueL( KWlanRegion, KWlmRegionUnknown ));
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::ClearRegionCache() - StoreWlanCenRepKeyValueL() leaved with code %d,", ret );
+ }
+ TRAP( ret, StoreWlanCenRepKeyValueL( KWlanRegionTimestamp, iTimeofDomainQuery.Int64() ));
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::ClearRegionCache() - StoreWlanCenRepKeyValueL() leaved with code %d,", ret );
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SendData
+// ---------------------------------------------------------
+//
+TInt CWlmServer::SendData(
+ const void * const aData,
+ const TInt aLength )
+ {
+ DEBUG2( "CWlmServer::SendData(data=0x%08X, length=%i)", aData, aLength );
+ ASSERT( iEapolHandler );
+ return iEapolHandler->send_data( aData, aLength );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::Scan
+// ---------------------------------------------------------
+//
+void CWlmServer::Scan(
+ const TUint& aMaxDelay )
+ {
+ DEBUG1( "CWlmServer::Scan() - aMaxDelay %u", aMaxDelay );
+
+ // - by design, this method is called only if background scan is enabled
+ ASSERT( iBgScanProvider->IsBgScanEnabled() );
+ // - by design, this method is only called if iIsStartupComplete is true
+ ASSERT( iIsStartupComplete );
+ // - by design, a background scan request can already be in the queue
+ // -> instead of creating a new request to the request map, modify the existing one
+ // - by design, background scan request might be issued even if we're connected
+ // - update scan scheduling timer if needed
+
+ TInt index = FindRequestIndex( KWlanIntCmdBackgroundScan );
+
+ if( index >= iRequestMap.Count() )
+ {
+ // there are no pending background scan requests
+ DEBUG( "CWlmServer::Scan() - there are NO pending background scan requests" );
+
+ BackgroundScanRequest( aMaxDelay );
+ }
+ else
+ {
+ DEBUG1( "CWlmServer::Scan() - there is a pending background scan request, index (%d)", index);
+
+ ASSERT( iRequestMap[index].iTime );
+
+ DEBUG( "CWlmServer::Scan() - cancel scan scheduling timer (might already be cancelled but it doesn't matter)" );
+ iScanSchedulingTimer->Cancel();
+
+ if( !iCoreHandlingScanRequest )
+ {
+ DEBUG( "CWlmServer::Scan() - core is not handling background scan request" );
+
+ DEBUG( "CWlmServer::Scan() - set new scan start time for existing background scan request" );
+ *iRequestMap[index].iTime = CalculateScanStartTime( aMaxDelay );
+
+ DEBUG( "CWlmServer::Scan() - find the scan scheduling request which expires next" );
+ TUint indexNextScan;
+ if( FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ UpdateScanSchedulingTimer( *iRequestMap[indexNextScan].iTime,
+ iRequestMap[indexNextScan].iRequestId );
+ }
+#ifdef _DEBUG
+ else
+ {
+ DEBUG( "CWlmServer::Scan() - no scan scheduling request found!!" );
+ ASSERT( 0 );
+ }
+#endif
+ }
+ else
+ {
+ DEBUG( "CWlmServer::Scan() - core is currently handling some scan request" );
+
+ if( iRequestTriggeringScanning == iRequestMap[index].iRequestId )
+ {
+ DEBUG( "CWlmServer::Scan() - core is handling background scanning currently" );
+ DEBUG( "CWlmServer::Scan() - no need to update the existing background scan request" );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::Scan() - core is NOT handling background scanning currently" );
+ DEBUG( "CWlmServer::Scan() - just update the time to the background scan request" );
+ *iRequestMap[index].iTime = CalculateScanStartTime( aMaxDelay );
+ }
+ }
+ }
+
+ DEBUG( "CWlmServer::Scan() - returning" );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelScan
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelScan()
+ {
+ DEBUG( "CWlmServer::CancelScan()" );
+
+ if( iConnectionState == EWlanStateNotConnected )
+ {
+ SetIconState( EWlmIconStatusNotAvailable );
+ }
+
+ // look for the background scan request
+ TUint index = FindRequestIndex( KWlanIntCmdBackgroundScan );
+
+ if( index < iRequestMap.Count() )
+ {
+ // pending background scan request found
+ if( !iCoreHandlingScanRequest )
+ {
+ DEBUG( "CWlmServer::CancelScan() - core is not yet handling the next scan request" );
+
+ DEBUG( "CWlmServer::CancelScan() - cancel timer" );
+ iScanSchedulingTimer->Cancel();
+
+ DEBUG( "CWlmServer::CancelScan() - remove entry from request map" );
+ iRequestMap.Remove( index );
+
+ DEBUG( "CWlmServer::CancelScan() - find next possible timed scan scheduling request" );
+ TUint indexNextScan;
+ if( FindNextTimedScanSchedulingRequest( indexNextScan ) )
+ {
+ UpdateScanSchedulingTimer( *iRequestMap[indexNextScan].iTime, iRequestMap[indexNextScan].iRequestId );
+ }
+#ifdef _DEBUG
+ else
+ {
+ DEBUG( "CWlmServer::CancelScan() - no next timed scan scheduling request found" );
+ }
+#endif
+ }
+ else
+ {
+ // Core is currently handling scanning
+ DEBUG( "CWlmServer::CancelScan() - core is currently handling scanning" );
+
+ if( iRequestTriggeringScanning == iRequestMap[index].iRequestId )
+ {
+ DEBUG( "CWlmServer::CancelScan() - core is handling background scanning currently" );
+ DEBUG( "CWlmServer::CancelScan() - no need to remove background scan request" );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::CancelScan() - core is NOT handling background scanning currently" );
+ DEBUG( "CWlmServer::CancelScan() - just remove the entry from the request map" );
+
+ DEBUG( "CWlmServer::CancelScan() - remove entry from request map" );
+ iRequestMap.Remove( index );
+ }
+ }
+ }
+ DEBUG( "CWlmServer::CancelScan() - returning" );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetPacketStatistics
+// ---------------------------------------------------------
+//
+void CWlmServer::GetPacketStatistics(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetPacketStatistics()" );
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EGetPacketStatistics;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ core_packet_statistics_s* tmp = new core_packet_statistics_s;
+ if( tmp == NULL )
+ {
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+ mapEntry.iParam0 = tmp;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->get_packet_statistics(
+ mapEntry.iRequestId,
+ *tmp );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::ClearPacketStatistics
+// ---------------------------------------------------------
+//
+void CWlmServer::ClearPacketStatistics(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::ClearPacketStatistics()" );
+
+ core_error_e ret = iCoreServer->clear_packet_statistics();
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::ClearPacketStatistics() - clear_packet_statistics() failed with %u",
+ ret );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetUapsdSettings
+// ---------------------------------------------------------
+//
+void CWlmServer::GetUapsdSettings(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetUapsdSettings()" );
+
+ core_uapsd_settings_s coreSettings;
+ core_error_e ret = iCoreServer->get_uapsd_settings( coreSettings );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetUapsdSettings() - get_uapsd_settings() failed with %u",
+ ret );
+ }
+
+ TWlanUapsdSettings settings;
+ TWlanConversionUtil::ConvertUapsdSettings(
+ settings,
+ coreSettings );
+ TPckg<TWlanUapsdSettings> outPckg( settings );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SetUapsdSettings
+// ---------------------------------------------------------
+//
+void CWlmServer::SetUapsdSettings(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::SetUapsdSettings()" );
+
+ TWlanUapsdSettings settings =
+ { EWlanMaxServicePeriodLengthAll, ETrue, ETrue, ETrue, ETrue };
+ TPckg<TWlanUapsdSettings> inPckg( settings );
+ TInt err( aMessage.Read( 0, inPckg ) );
+ if( err != KErrNone )
+ {
+ aMessage.Complete( err );
+ return;
+ }
+
+ core_uapsd_settings_s coreSettings;
+ TWlanConversionUtil::ConvertUapsdSettings(
+ coreSettings,
+ settings );
+
+ core_error_e ret = iCoreServer->set_uapsd_settings( coreSettings );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::SetUapsdSettings() - set_uapsd_settings() failed with %u",
+ ret );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetPowerSaveSettings
+// ---------------------------------------------------------
+//
+void CWlmServer::GetPowerSaveSettings(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetPowerSaveSettings()" );
+
+ core_power_save_settings_s coreSettings;
+ core_error_e ret = iCoreServer->get_power_save_settings( coreSettings );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetPowerSaveSettings() - get_power_save_settings() failed with %u",
+ ret );
+ }
+
+ TWlanPowerSaveSettings settings;
+ TWlanConversionUtil::ConvertPowerSaveSettings(
+ settings,
+ coreSettings );
+ TPckg<TWlanPowerSaveSettings> outPckg( settings );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SetPowerSaveSettings
+// ---------------------------------------------------------
+//
+void CWlmServer::SetPowerSaveSettings(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::SetPowerSaveSettings()" );
+
+ TWlanPowerSaveSettings settings =
+ { ETrue, EFalse, EFalse, EFalse, EFalse, EFalse, EFalse, EFalse };
+ TPckg<TWlanPowerSaveSettings> inPckg( settings );
+ TInt err( aMessage.Read( 0, inPckg ) );
+ if( err != KErrNone )
+ {
+ aMessage.Complete( err );
+ return;
+ }
+
+ core_power_save_settings_s coreSettings;
+ TWlanConversionUtil::ConvertPowerSaveSettings(
+ coreSettings,
+ settings );
+
+ core_error_e ret = iCoreServer->set_power_save_settings( coreSettings );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::SetPowerSaveSettings() - set_power_save_settings() failed with %u",
+ ret );
+ }
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::RunProtectedSetup
+// ---------------------------------------------------------
+//
+void CWlmServer::RunProtectedSetup(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::RunProtectedSetup()" );
+
+ // Get WlanSettings and secondarySSID list
+ // (lanServiceId specifies the table row in wlansettings)
+ SWLANSettings iapData;
+ RArray<TWlanSecondarySsid> secondarySsidList;
+ TInt lanServiceId = aMessage.Int0();
+ TRAPD( err, GetIapSettingsL( lanServiceId, iapData, secondarySsidList ) ) ;
+ if( err != KErrNone )
+ {
+ DEBUG1( "CWlmServer::RunProtectedSetup() - GetIapSettingsL leaved with %d",
+ err );
+ secondarySsidList.Close();
+ aMessage.Complete( err );
+ return;
+ }
+ secondarySsidList.Close();
+
+ // Type conversion
+ core_iap_data_s* coreIapData = new core_iap_data_s;
+ if( !coreIapData )
+ {
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+
+ TWLMOverrideSettings override = { 0 };
+ TWlanConversionUtil::ConvertIapSettings(
+ *coreIapData,
+ iapData,
+ ETrue, // dhcp usage is not important here
+ override );
+
+
+ // Create a list for the results.
+ core_type_list_c<core_iap_data_s>* iapDataList = new core_type_list_c<core_iap_data_s>;
+ if( iapDataList == NULL )
+ {
+ DEBUG( "CWlmServer::RunProtectedSetup() - unable to create iapDataList" );
+ delete coreIapData;
+
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+
+ // Protected Setup status
+ core_protected_setup_status_e* protectedSetupStatus = new core_protected_setup_status_e;
+ if( !protectedSetupStatus )
+ {
+ delete coreIapData;
+ delete iapDataList;
+
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+ *protectedSetupStatus = core_protected_setup_status_undefined;
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = ERunProtectedSetup;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ mapEntry.iParam0 = coreIapData;
+ mapEntry.iParam1 = iapDataList;
+ mapEntry.iParam2 = protectedSetupStatus;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->run_protected_setup(
+ mapEntry.iRequestId, *coreIapData, *iapDataList, *protectedSetupStatus );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelProtectedSetup
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelProtectedSetup(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CancelProtectedSetup()" );
+
+ CancelExternalRequest(
+ aSessionId,
+ ERunProtectedSetup );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CreateTrafficStream
+// ---------------------------------------------------------
+//
+void CWlmServer::CreateTrafficStream(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CreateTrafficStream()" );
+
+ TPckgBuf<TWlanTrafficStreamParameters> paramsPckg( 0 );
+ TInt ret( aMessage.Read( 0, paramsPckg ) );
+ if( ret != KErrNone )
+ {
+ aMessage.Complete( ret );
+ return;
+ }
+ if( paramsPckg().iUserPriority > MAX_USER_PRIORITY )
+ {
+ aMessage.Complete( KErrArgument );
+ return;
+ }
+
+ TBool isAutomatic = aMessage.Int1();
+
+ u32_t* coreStreamId = new u32_t;
+ core_traffic_stream_status_e* coreStreamStatus = new core_traffic_stream_status_e;
+ if( !coreStreamId ||
+ !coreStreamStatus )
+ {
+ delete coreStreamId;
+ delete coreStreamStatus;
+
+ aMessage.Complete( KErrNoMemory );
+ return;
+ }
+
+ u8_t coreTid( TRAFFIC_STREAM_TID_NONE );
+ u8_t coreUserPriority( 0 );
+ core_traffic_stream_params_s coreParams = { 0 };
+ TWlanConversionUtil::ConvertTrafficStreamParameters(
+ coreTid,
+ coreUserPriority,
+ coreParams,
+ paramsPckg() );
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = ECreateTrafficStream;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ mapEntry.iParam0 = coreStreamId;
+ mapEntry.iParam1 = coreStreamStatus;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->create_traffic_stream(
+ mapEntry.iRequestId,
+ coreTid,
+ coreUserPriority,
+ isAutomatic,
+ coreParams,
+ *coreStreamId,
+ *coreStreamStatus );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelCreateTrafficStream
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelCreateTrafficStream(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ CancelExternalRequest(
+ aSessionId,
+ ECreateTrafficStream );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::DeleteTrafficStream
+// ---------------------------------------------------------
+//
+void CWlmServer::DeleteTrafficStream(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::DeleteTrafficStream()" );
+
+ u32_t streamId = aMessage.Int0();
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EDeleteTrafficStream;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->delete_traffic_stream(
+ mapEntry.iRequestId,
+ streamId );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelDeleteTrafficStream
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelDeleteTrafficStream(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ CancelExternalRequest(
+ aSessionId,
+ EDeleteTrafficStream );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetAccessPointInfo
+// ---------------------------------------------------------
+//
+void CWlmServer::GetAccessPointInfo(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetAccessPointInfo()" );
+
+ core_ap_information_s coreInfo;
+ core_error_e ret = iCoreServer->get_current_ap_info( coreInfo );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetAccessPointInfo() - get_current_ap_info() failed with %u",
+ ret );
+ }
+
+ TWlanAccessPointInfo info;
+ TWlanConversionUtil::ConvertApInformation(
+ info,
+ coreInfo );
+ TPckg<TWlanAccessPointInfo> outPckg( info );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetRoamMetrics
+// ---------------------------------------------------------
+//
+void CWlmServer::GetRoamMetrics(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetRoamMetrics()" );
+
+ core_roam_metrics_s coreRoamMetrics;
+ iCoreServer->get_roam_metrics( coreRoamMetrics );
+
+ TWlanRoamMetrics roamMetrics;
+ TWlanConversionUtil::ConvertRoamMetrics(
+ roamMetrics,
+ coreRoamMetrics );
+
+ TPckg<TWlanRoamMetrics> outPckg( roamMetrics );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( core_error_ok ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetRogueList
+// ---------------------------------------------------------
+//
+void CWlmServer::GetRogueList(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetRogueList()" );
+
+ core_type_list_c<core_mac_address_s> coreRogueList;
+ core_error_e ret = iCoreServer->get_rogue_list( coreRogueList );
+ if ( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetRogueList() - get_rogue_list() failed with %u",
+ ret );
+ }
+
+ TWlmRogueList rogueList;
+ TWlanConversionUtil::ConvertRogueList(
+ rogueList,
+ coreRogueList );
+
+ TPckg<TWlmRogueList> outPckg( rogueList );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetRegulatoryDomain
+// ---------------------------------------------------------
+//
+void CWlmServer::GetRegulatoryDomain(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetRegulatoryDomain()" );
+
+ TPckg<TWlanRegion> outPckg( iRegion );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( core_error_ok ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetPowerSaveMode
+// ---------------------------------------------------------
+//
+void CWlmServer::GetPowerSaveMode(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetPowerSaveMode()" );
+
+ TWlanPowerSave powerSaveMode( iPowerSaveMode );
+ if ( !iPowerSaveEnabled )
+ {
+ powerSaveMode = EWlanPowerSaveNone;
+ }
+
+ TPckg<TWlanPowerSave> outPckg( powerSaveMode );
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( core_error_ok ) );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::AddIapSsidListL
+// ---------------------------------------------------------
+//
+void CWlmServer::AddIapSsidListL(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::AddIapSsidListL()" );
+
+ TUint iapId(
+ aMessage.Int0() );
+ TUint ssidCount(
+ aMessage.Int1() );
+ TInt ssidListSize( 0 );
+ if( aMessage.Ptr2() )
+ {
+ ssidListSize = aMessage.GetDesLengthL( 2 );
+ }
+
+ DEBUG3( "CWlmServer::AddIapSsidListL() - IAP ID: %u, SSID list count: %u, SSID list size: %u",
+ iapId, ssidCount, ssidListSize );
+
+ if( ssidCount &&
+ ssidListSize )
+ {
+ /**
+ * Make sure the IAP ID actually exists.
+ */
+ RArray<TWlanLimitedIapData> iapList;
+ iCache->GetIapDataList( iapList );
+ TBool isMatch( EFalse );
+ for( TInt idx( 0 ); idx < iapList.Count() && !isMatch; ++idx )
+ {
+ if( iapList[idx].iapId == iapId )
+ {
+ isMatch = ETrue;
+ }
+ }
+ iapList.Close();
+ if( !isMatch )
+ {
+ DEBUG1( "CWlmServer::AddIapSsidListL() - IAP ID %u not found", iapId );
+
+ User::Leave( KErrNotFound );
+ }
+
+ /**
+ * Read the SSID list from the client side to a temporary buffer.
+ */
+ HBufC8* buffer = HBufC8::NewL( ssidListSize );
+ CleanupStack::PushL( buffer );
+
+ TPtr8 bufferPtr(
+ buffer->Des() );
+ aMessage.ReadL( 2, bufferPtr );
+
+ /**
+ * Copy the contents of the buffer to an CArrayFixFlat instance
+ * so that they can be iterated.
+ */
+ CArrayFixFlat<TWlanSsid>* ssidBuffer =
+ new CArrayFixFlat<TWlanSsid>( ssidCount );
+ if( !ssidBuffer )
+ {
+ DEBUG( "CWlmServer::AddIapSsidListL() - unable to instantiate CArrayFixFlat" );
+
+ User::Leave( KErrNoMemory );
+ }
+ CleanupStack::PushL( ssidBuffer );
+ ssidBuffer->AppendL(
+ reinterpret_cast<const TWlanSsid*>( buffer->Ptr() ), ssidCount );
+
+ CleanupStack::Pop( ssidBuffer );
+ CleanupStack::PopAndDestroy( buffer );
+ CleanupStack::PushL( ssidBuffer );
+
+ /**
+ * Initialize an SSID list and store SSIDs into it.
+ */
+ CWlanSsidList* ssidList = CWlanSsidList::NewL( ssidCount );
+ CleanupStack::PushL( ssidList );
+
+ for( TInt idx( 0 ); idx < ssidBuffer->Count(); ++idx )
+ {
+ if( ssidBuffer->At( idx ).Length() <= KWlanMaxSsidLength )
+ {
+ TInt ret = ssidList->AddSsid( ssidBuffer->At( idx ) );
+ if( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::AddIapSsidListL() - AddSsid failed with %d",
+ ret );
+ }
+
+ User::LeaveIfError( ret );
+ }
+ }
+
+ DEBUG2( "CWlmServer::AddIapSsidListL() - attaching a list of %u SSID(s) to IAP ID %u",
+ ssidList->Count(), iapId );
+
+ iSsidListDb->WriteListL(
+ iapId,
+ *ssidList );
+
+ CleanupStack::PopAndDestroy( ssidList );
+ CleanupStack::PopAndDestroy( ssidBuffer );
+
+ DEBUG( "CWlmServer::AddIapSsidListL() - SSID list succesfully attached" );
+ }
+ else
+ {
+ iSsidListDb->DeleteListL(
+ iapId );
+
+ DEBUG( "CWlmServer::AddIapSsidListL() - SSID list succesfully deleted" );
+ }
+
+ /**
+ * Invalidate cached IAP availability results since they might
+ * not be valid anymore.
+ */
+ iCache->InvalidateAvailabilityCache();
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::RemoveIapSsidListL
+// ---------------------------------------------------------
+//
+void CWlmServer::RemoveIapSsidListL(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::RemoveIapSsidListL()" );
+
+ TUint iapId = aMessage.Int0();
+
+ DEBUG1( "CWlmServer::RemoveIapSsidListL() - removing SSID list from IAP ID %u",
+ iapId );
+
+ iSsidListDb->DeleteListL(
+ iapId );
+
+ DEBUG( "CWlmServer::RemoveIapSsidListL() - SSID list succesfully removed" );
+
+ /**
+ * Invalidate cached IAP availability results since they might
+ * not be valid anymore.
+ */
+ iCache->InvalidateAvailabilityCache();
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::SetPowerSaveMode
+// ---------------------------------------------------------
+//
+void CWlmServer::SetPowerSaveMode(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::SetPowerSaveMode()" );
+
+ TWlanPowerSaveMode mode = static_cast<TWlanPowerSaveMode>(
+ aMessage.Int0() );
+
+ DEBUG1( "CWlmServer::SetPowerSaveMode() - mode %u",
+ mode );
+
+ core_power_save_mode_s coreMode;
+ TWlanConversionUtil::ConvertPowerSaveMode(
+ coreMode,
+ mode );
+
+ iCoreServer->set_power_save_mode( coreMode );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetAcTrafficStatus
+// ---------------------------------------------------------
+//
+void CWlmServer::GetAcTrafficStatus(
+ TUint /* aSessionId */,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::GetAcTrafficStatus()" );
+
+ core_ac_traffic_information_s coreInfo;
+ core_error_e ret = iCoreServer->get_current_ac_traffic_info( coreInfo );
+ if( ret != core_error_ok )
+ {
+ DEBUG1( "CWlmServer::GetAcTrafficStatus() - get_current_ac_traffic_info() failed with %u",
+ ret );
+
+ aMessage.Complete(
+ TWlanConversionUtil::ConvertErrorCode( ret ) );
+ }
+
+ TWlmAcTrafficStatusArray info;
+ TPckg<TWlmAcTrafficStatusArray> outPckg( info );
+ info[EWlmAccessClassBestEffort] = TWlanConversionUtil::ConvertTrafficStatus(
+ coreInfo.status_for_best_effort );
+ info[EWlmAccessClassBackground] = TWlanConversionUtil::ConvertTrafficStatus(
+ coreInfo.status_for_background );
+ info[EWlmAccessClassVideo] = TWlanConversionUtil::ConvertTrafficStatus(
+ coreInfo.status_for_video );
+ info[EWlmAccessClassVoice] = TWlanConversionUtil::ConvertTrafficStatus(
+ coreInfo.status_for_voice );
+
+ aMessage.Write( 0, outPckg );
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::DirectedRoam
+// ---------------------------------------------------------
+//
+void CWlmServer::DirectedRoam(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::DirectedRoam()" );
+
+ TPckgBuf<TMacAddress> bssidPckg;
+ TInt ret( aMessage.Read( 0, bssidPckg ) );
+ if( ret != KErrNone )
+ {
+ aMessage.Complete( ret );
+ return;
+ }
+
+ core_mac_address_s coreBssid( ZERO_MAC_ADDR );
+ TWlanConversionUtil::ConvertMacAddress(
+ coreBssid,
+ bssidPckg() );
+
+ // create mapping
+ SRequestMapEntry mapEntry;
+ mapEntry.iMessage = aMessage;
+ mapEntry.iFunction = EDirectedRoam;
+ mapEntry.iRequestId = iRequestIdCounter++;
+ mapEntry.iSessionId = aSessionId;
+ iRequestMap.Append( mapEntry );
+
+ // pass request to core
+ iCoreServer->directed_roam(
+ mapEntry.iRequestId,
+ coreBssid );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::CancelDirectedRoam
+// ---------------------------------------------------------
+//
+void CWlmServer::CancelDirectedRoam(
+ TUint aSessionId,
+ const RMessage2& aMessage )
+ {
+ DEBUG( "CWlmServer::CancelDirectedRoam()" );
+
+ CancelExternalRequest(
+ aSessionId,
+ EDirectedRoam );
+
+ aMessage.Complete( KErrNone );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::StartupComplete
+// ---------------------------------------------------------
+//
+void CWlmServer::StartupComplete()
+ {
+ iIsStartupComplete = ETrue;
+
+ SetIconState( EWlmIconStatusNotAvailable );
+
+ iCoreServer->enable_wlan( KWlanIntCmdEnableWlan );
+
+ /**
+ * Read the CommsDat data again so that we can be sure
+ * that it is up to date after reboot. It can happen that
+ * when WLAN engine boots up commsdat is not up to date yet.
+ */
+ UpdateWlanSettings();
+
+ iPlatform->InitializeSystemTimeHandler();
+ }
+
+
+// ---------------------------------------------------------
+// CWlmServer::EmergencyCallComplete
+// ---------------------------------------------------------
+//
+void CWlmServer::EmergencyCallComplete( TBool aStartupCompleted )
+ {
+ if ( !aStartupCompleted )
+ {
+ iCoreServer->disable_wlan( KWlanIntCmdDisableWlan );
+ }
+ else
+ {
+ if ( iIsStartupComplete == EFalse )
+ {
+ iIsStartupComplete = ETrue;
+
+ UpdateWlanSettings();
+
+ iPlatform->InitializeSystemTimeHandler();
+ }
+ }
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::HandleSsidListAvailabilityL
+// ---------------------------------------------------------
+//
+void CWlmServer::HandleSsidListAvailabilityL(
+ const SRequestMapEntry& aMapEntry )
+ {
+ DEBUG( "CWlmServer::HandleSsidListAvailabilityL()" );
+
+ ScanList* scanList =
+ reinterpret_cast<ScanList*>( aMapEntry.iParam2 );
+ core_type_list_c<u32_t>* iapIdList =
+ reinterpret_cast<core_type_list_c<u32_t>*>( aMapEntry.iParam1 );
+
+ /**
+ * Go through the IAP list and find IAPs that haven't been found
+ * during GetAvailableIaps and have an SSID list attached.
+ */
+ RArray<TWlanLimitedIapData> attachedIapList;
+ CleanupClosePushL( attachedIapList );
+ const RArray<TWlanLimitedIapData>& cachedIapList(
+ iCache->CachedIapDataList() );
+ core_type_list_iterator_c<u32_t> iter( *iapIdList );
+ for( TInt idx( 0 ); idx < cachedIapList.Count(); ++idx )
+ {
+ TBool isFound( EFalse );
+ for( u32_t* item = iter.first(); !isFound && item; item = iter.next() )
+ {
+ if( *item == cachedIapList[idx].iapId )
+ {
+ isFound = ETrue;
+ }
+ }
+ if( !isFound )
+ {
+ DEBUG1( "CWlmServer::HandleSsidListAvailabilityL() - IAP ID %u isn't available",
+ cachedIapList[idx].iapId );
+ if( iSsidListDb->IsListAttached(
+ cachedIapList[idx].iapId ) )
+ {
+ DEBUG1( "CWlmServer::HandleSsidListAvailabilityL() - IAP %u has an SSID list attached",
+ cachedIapList[idx].iapId );
+ attachedIapList.Append( cachedIapList[idx] );
+ }
+ }
+ }
+
+ if( !attachedIapList.Count() )
+ {
+ DEBUG( "CWlmServer::HandleSsidListAvailabilityL() - no IAPs with an list attached, nothing to do" );
+
+ CleanupStack::PopAndDestroy( &attachedIapList );
+
+ return;
+ }
+
+ /**
+ * Generate a list of SSIDs detected during the scan and go through
+ * the IAPs with lists attached again.
+ */
+ RArray<TWlanAvailableNetwork> networkList;
+ CleanupClosePushL( networkList );
+ GetNetworkList( *scanList, networkList );
+
+ for( TInt idx( 0 ); idx < attachedIapList.Count(); ++idx )
+ {
+ DEBUG1( "CWlmServer::HandleSsidListAvailabilityL() - requesting SSID list for IAP %u",
+ attachedIapList[idx].iapId );
+
+ CWlanSsidList* ssidList = CWlanSsidList::NewL( KWlanSsidListGranularity );
+ CleanupStack::PushL( ssidList );
+ iSsidListDb->ReadListL(
+ attachedIapList[idx].iapId,
+ *ssidList );
+ TBool isMatch( EFalse );
+ for( TInt iidx( 0 ); !isMatch && iidx < networkList.Count(); ++iidx )
+ {
+ if( attachedIapList[idx].networkType == networkList[iidx].networkType &&
+ ssidList->IsInList( networkList[iidx].ssid ) )
+ {
+ isMatch = ETrue;
+ }
+ }
+
+ if( isMatch )
+ {
+ DEBUG( "CWlmServer::HandleSsidListAvailabilityL() - matching SSID found" );
+
+ /**
+ * A match has been found, mark the IAP as available.
+ */
+ u32_t* iapId = new (ELeave) u32_t(
+ attachedIapList[idx].iapId );
+ iapIdList->append(
+ iapId );
+ }
+ else
+ {
+ DEBUG( "CWlmServer::HandleSsidListAvailabilityL() - no matching SSIDs found for IAP" );
+ }
+
+ CleanupStack::PopAndDestroy( ssidList );
+ }
+
+ CleanupStack::PopAndDestroy( &networkList );
+ CleanupStack::PopAndDestroy( &attachedIapList );
+
+ DEBUG( "CWlmServer::HandleSsidListAvailabilityL() - all done" );
+ }
+
+// ---------------------------------------------------------
+// CWlmServer::GetCurrentIapId
+// ---------------------------------------------------------
+//
+TInt CWlmServer::GetCurrentIapId(
+ const TUint aLanServiceId,
+ core_iap_data_s& aCoreIapData )
+ {
+ DEBUG( "CWlmServer::GetCurrentIapId()" );
+ /**
+ * Read all WLAN IAPs from commsdat.
+ */
+ CWLanSettings wlanSettings;
+ TInt ret = wlanSettings.Connect();
+ if ( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::GetCurrentIapId - CWLanSettings::Connect() failed (%d)",
+ ret );
+
+ return ret;
+ }
+
+ RArray<SWlanIAPId> wlanIapIds;
+ TRAP( ret, wlanSettings.GetIAPWlanServicesL( wlanIapIds ) );
+ if( ret != KErrNone )
+ {
+ DEBUG1( "CWlmServer::GetCurrentIapId - CWLanSettings::GetIAPWlanServicesL() failed (%d)",
+ ret );
+ wlanIapIds.Close();
+ wlanSettings.Disconnect();
+
+ return ret;
+ }
+ TInt IapsCount = wlanIapIds.Count();
+ /**
+ * Get the matching IAP id.
+ */
+ for ( TInt i = 0; i < IapsCount; i++ )
+ {
+ if ( wlanIapIds[i].iWLANRecordId == aLanServiceId )
+ {
+ aCoreIapData.iap_id = wlanIapIds[i].iIAPId;
+ i = IapsCount;
+ }
+ }
+
+ wlanSettings.Disconnect();
+
+ DEBUG( "CWlmServer::GetCurrentIapId() - all done" );
+
+ return KErrNone;
+ }