cmmanager/cmmgr/Plugins/cmpluginwlan/src/cmwlancoveragecheck.cpp
changeset 0 5a93021fdf25
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmmanager/cmmgr/Plugins/cmpluginwlan/src/cmwlancoveragecheck.cpp	Thu Dec 17 08:55:21 2009 +0200
@@ -0,0 +1,413 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  Implementation of WLAN Coverage Check class
+*
+*/
+
+
+#include <wlanmgmtclient.h>
+
+#include "cmwlancoveragecheck.h"
+#include "cmpluginwlan.h"
+#include "cmpluginwlandata.h"
+#include "cmpluginwlandataarray.h"
+#include "cmlogger.h"
+
+
+/**
+* Management frame information element IDs.
+* needed to determine coverage
+*/
+enum T802Dot11InformationElementID
+    {
+    E802Dot11SsidIE                 = 0,
+    E802Dot11SupportedRatesIE       = 1,
+    E802Dot11FhParameterSetIE       = 2,
+    E802Dot11DsParameterSetIE       = 3,
+    E802Dot11CfParameterSetIE       = 4,
+    E802Dot11TimIE                  = 5,
+    E802Dot11IbssParameterSetIE     = 6,
+    E802Dot11CountryIE              = 7,
+    E802Dot11HoppingPatternParamIE  = 8,
+    E802Dot11HoppingPatternTableIE  = 9,
+    E802Dot11RequestIE              = 10,
+
+    E802Dot11ChallengeTextIE        = 16,
+    // Reserved for challenge text extension 17 - 31
+    E802Dot11ErpInformationIE       = 42,
+    E802Dot11ExtendedRatesIE        = 50,
+    E802Dot11AironetIE              = 133,
+    E802Dot11ApIpAddressIE          = 149,
+    E802Dot11RsnIE                  = 221
+    };
+
+
+/**
+* Bit masks for Capability Information field.
+*/
+enum T802Dot11CapabilityBitMask
+    {
+    E802Dot11CapabilityEssMask          = 0x0001,
+    E802Dot11CapabilityIbssMask         = 0x0002,
+    E802Dot11CapabilityCfPollableMask   = 0x0004,
+    E802Dot11CapabilityCfPollRequestMask= 0x0008,
+    E802Dot11CapabilityPrivacyMask      = 0x0010,
+    E802Dot11ShortPreambleMask          = 0x0020,
+    E802Dot11PbccMask                   = 0x0040,      
+    E802Dot11ChannelAgilityMask         = 0x0080
+    };
+
+
+// ======================= MEMBER FUNCTIONS =================================
+
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::CCmWlanCoverageCheck()
+// ----------------------------------------------------------------------------
+//
+CCmWlanCoverageCheck::CCmWlanCoverageCheck() : CActive( EPriorityStandard )
+    {
+    CActiveScheduler::Add( this );
+    }
+    
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::~CCmWlanCoverageCheck()
+// ----------------------------------------------------------------------------
+//
+CCmWlanCoverageCheck::~CCmWlanCoverageCheck()
+    {
+    Cancel();
+    }
+    
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::DoCancel
+// ----------------------------------------------------------------------------
+//
+void CCmWlanCoverageCheck::DoCancel()
+    {
+    iWait.AsyncStop();
+    }
+    
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::RunL
+// ----------------------------------------------------------------------------
+//
+void CCmWlanCoverageCheck::RunL()
+    {
+    CLOG_WRITE( "RunL entered" );
+    switch( iProgState )
+        {
+        case EScanning:
+            {
+             if( !iStatus.Int() )
+                // The list is ready 
+                {
+                iProgState = EDone;
+                iWait.AsyncStop();
+                }
+            else
+                // something went wrong -> no coverage.
+                {
+                iWait.AsyncStop();
+                }
+            }
+            break;            
+        case EDone:
+            {
+            iWait.AsyncStop();
+            }
+            break;
+            
+        default:
+            {
+            User::Leave( KErrCorrupt );
+            }
+        }
+    }
+
+
+
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::GetCoverageL
+// ----------------------------------------------------------------------------
+//
+TInt CCmWlanCoverageCheck::GetCoverageL()
+    {
+    LOGGER_ENTERFN( "CCmWlanCoverageCheck::GetCoverageL" );
+
+    iProgState = EServiceStatus;
+    iCoverage = 0;
+    
+    CWlanMgmtClient* wlanMgmt = CWlanMgmtClient::NewL();
+    CleanupStack::PushL( wlanMgmt );
+
+    CWlanScanInfo* scanInfo = CWlanScanInfo::NewL();
+    CleanupStack::PushL( scanInfo );
+
+    iProgState = EScanning;
+    
+    wlanMgmt->GetScanResults( iStatus, *scanInfo );
+    
+    SetActive();
+    iWait.Start();
+    
+    // now we have the results and might start to work on them...
+    if ( iProgState == EDone )
+        { //finished without error, work on the result...
+        CCmPluginWlanDataArray* wlandataarray = new ( ELeave ) 
+            CCmPluginWlanDataArray();
+        CleanupStack::PushL( wlandataarray );
+
+        for ( scanInfo->First(); !scanInfo->IsDone(); scanInfo->Next() )
+            {
+            // iWlanNetworks cannot be modified 'directly' in
+            // a const method (like GetBoolAttributeL), so we have to
+            // cast away the constness.
+            
+            // not simply count as before, but check if it is hidden,
+            // and do not allow duplicates...
+            TBool isHidden( EFalse );
+            
+            TUint8 ieLen( 0 );
+            const TUint8* ieData;
+            TBuf8<KWlanMaxSsidLength> ssid8;
+            
+            TInt ret = scanInfo->InformationElement( E802Dot11SsidIE, ieLen, 
+                                                      &ieData );
+            if ( ret == KErrNone ) 
+                {               
+                isHidden = IsHiddenSsid( ieLen, ieData );
+                if ( !isHidden )
+                    {
+                    // get the ssid
+                    ssid8.Copy( ieData, ieLen );
+                    HBufC* tmp = HBufC::NewLC(KWlanMaxSsidLength);
+                    TPtr tmpptr( tmp->Des() );
+                    
+                    tmpptr.Copy(ssid8);
+                    // get the signal strength                        
+                    TUint8 rxLevel8 = scanInfo->RXLevel();
+                    TInt rxLevel = static_cast< TInt >( rxLevel8 );
+                    
+                    // now add it to an array of CCmPluginWlanData,
+                    // as it is not hidden
+                    // the adding function should handle uniqeness and 
+                    // signal strength checking, it should contain only
+                    // the strongest signal!                        
+                    AddToArrayIfNeededL( *wlandataarray, rxLevel, tmpptr );
+                    
+                    CleanupStack::PopAndDestroy( tmp );
+                    }                
+                }
+            else
+                {
+                User::Leave( ret );
+                }
+            }
+        iCoverage = wlandataarray->Count();
+        
+        CleanupStack::PopAndDestroy( wlandataarray );
+
+        CleanupStack::PopAndDestroy( 2, wlanMgmt );
+        }
+    else
+        {
+        User::LeaveIfError( iStatus.Int() );        
+        }        
+        
+    return iCoverage;
+    }
+
+// ---------------------------------------------------------
+// CCmWlanCoverageCheck::IsHiddenSsid
+// ---------------------------------------------------------
+//    
+TBool CCmWlanCoverageCheck::IsHiddenSsid( TUint aSsidLength, 
+                                   const TUint8* aSsid ) const
+    {
+    LOGGER_ENTERFN( "CCmWlanCoverageCheck::IsHiddenSsid" );
+    
+    const TUint8 CSPACE = 0x20; 
+    TBool result( EFalse );
+    TBool result2( ETrue );
+
+    if ( !aSsidLength )
+        {
+        result = ETrue;
+        }
+
+    TInt count( 0 );
+    TUint8 temp( 0x00 );
+    
+    for ( TUint i( 0 ); i < aSsidLength; ++i )
+        {
+        temp = aSsid[i];
+        count += temp; // in hidden networks characters are: 0x00
+        result2 &= temp == CSPACE ;
+        }
+
+    if( !count || result2 )
+        {
+        result = ETrue;
+        }
+        
+    return result;    
+    }
+
+
+// ---------------------------------------------------------
+// CCmWlanCoverageCheck::AddToArrayIfNeededL
+// ---------------------------------------------------------
+//    
+void CCmWlanCoverageCheck::AddToArrayIfNeededL( 
+                            CCmPluginWlanDataArray& aArray, 
+                            TInt aRXLevel, 
+                            TDesC& aNetworkName ) const
+    {
+    LOGGER_ENTERFN( "CCmWlanCoverageCheck::AddToArrayIfNeededL" );
+
+    // first check if it is already in the array
+    
+    TBool found( EFalse );
+    TInt index( 0 );
+    TInt count = aArray.Count();
+    
+    while( ( index <  count ) && !found  )
+        {
+        if( ( aArray )[index]->iNetworkName->Compare( aNetworkName ) )
+            {
+            ++index;   
+            }
+        else
+            {
+            found = ETrue;
+            }
+        }
+
+    TSignalStrength strength = ( TSignalStrength )aRXLevel;
+    if ( found )
+        {
+        // if already exists, check signal strengths
+        TSignalStrength signal = ( aArray )[index]->iSignalStrength;
+        
+        // set to higher value
+        ( aArray )[index]->iSignalStrength = 
+                              signal < strength ? signal : strength ;
+        }
+    else
+        {
+        // new element, add it to array with signal strength!!
+        CCmPluginWlanData* data = CCmPluginWlanData::NewLC();
+        data->iNetworkName = aNetworkName.AllocL();
+        data->iSignalStrength = strength;
+        aArray.AppendL( data );
+        CleanupStack::Pop( data ); // item owned by list!
+        }    
+    }
+
+
+// ----------------------------------------------------------------------------
+// CCmWlanCoverageCheck::ScanForPromptedSsidL
+// ----------------------------------------------------------------------------
+//
+TBool CCmWlanCoverageCheck::ScanForPromptedSsidL( TWlanSsid aEnteredSsid,
+                                TBool aBroadcast,
+                                TWlanNetMode& aNetworkMode, 
+                                TWlanConnectionExtentedSecurityMode& aSecurityMode,
+                                TBool& aProtectedSetupSupported )
+    {
+    LOGGER_ENTERFN( "CCmWlanCoverageCheck::ScanForPromptedSsidL" );
+    
+    TBool found = EFalse;
+
+    iProgState = EServiceStatus;
+       
+    CWlanMgmtClient* wlanMgmt = CWlanMgmtClient::NewL();
+    CleanupStack::PushL( wlanMgmt );
+
+    CWlanScanInfo* scanInfo = CWlanScanInfo::NewL();
+    CleanupStack::PushL( scanInfo );
+
+    iProgState = EScanning;
+    
+    if ( aBroadcast )
+        {
+        wlanMgmt->GetScanResults( iStatus, *scanInfo );
+        }
+    else
+        {
+        wlanMgmt->GetScanResults( aEnteredSsid, iStatus, *scanInfo );
+        }
+
+    SetActive();
+    iWait.Start();
+    
+    // now we have the results and might start to work on them...
+    if ( iProgState == EDone )
+        {       //finished without error, work on the result...
+        TSignalStrength signalStrength = ESignalStrengthMin;
+
+        for ( scanInfo->First(); !scanInfo->IsDone(); scanInfo->Next() )
+            {
+            TUint8 ieLen( 0 );
+            const TUint8* ieData;
+            TBuf8<KWlanMaxSsidLength> ssid8;
+            
+            TInt ret = scanInfo->InformationElement( E802Dot11SsidIE, ieLen, 
+                                                     &ieData );
+            if ( ret == KErrNone ) 
+                {               
+                // get the ssid
+                ssid8.Copy( ieData, ieLen );
+                
+                if ( !aEnteredSsid.Compare( ssid8 ) )
+                    {
+                    // get the signal strength                        
+                    TUint8 rxLevel8 = scanInfo->RXLevel();
+                    TInt rxLevel = static_cast< TInt >( rxLevel8 );
+            
+                    TSignalStrength strength = ( TSignalStrength )rxLevel;
+                    if ( !found || ( found && strength < signalStrength ) )
+                        {
+                        found = ETrue;
+                        signalStrength = strength;
+
+                        aNetworkMode = ( scanInfo->Capability() & 
+                                         E802Dot11CapabilityEssMask ) ?
+                                       EInfra : EAdhoc;
+                        aSecurityMode = scanInfo->ExtendedSecurityMode();
+
+                        aProtectedSetupSupported = 
+                                        scanInfo->IsProtectedSetupSupported();
+                        }
+                    }
+                }
+            else
+                {
+                User::Leave( ret );
+                }
+        
+            }
+        
+        CleanupStack::PopAndDestroy( scanInfo );
+        CleanupStack::PopAndDestroy( wlanMgmt );
+        }
+    else
+        {
+        User::LeaveIfError( iStatus.Int() );        
+        }
+    
+    return found;
+    }
+
+