wlanutilities/wlansniffer/apwizard/src/wsfwlaniapwizard.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:32 +0100
branchRCL_3
changeset 55 f28ada11abbf
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201029 Kit: 201035

/*
* Copyright (c) 2007-2008 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 CWsfWlanIapWizard
*
*/



//  EXTERNAL INCLUDES
#include <e32std.h>
#include <utf.h>
#include <wlanmgmtcommon.h>
#include <StringLoader.h> 
#include <cmpluginwlandef.h>
#include <cmsettingsui.h>
#include <ConnectionUiUtilities.h>
#include <data_caging_path_literals.hrh>
#include <bautils.h>
#include <AknQueryDialog.h> 
#include <aknnotewrappers.h>
#include <wsfapwizard.rsg>

//  CLASS HEADER
#include "wsfwlaniapwizard.h"

//  INTERNAL INCLUDES
#include "wsfwlaniapcreator.h"
#include "wsfwlanssiddiscovery.h"
#include "wsflogger.h"



using namespace CMManager;


/**
* ROM folder
*/
_LIT( KDriveZ, "z:" );

/**
* Resource file name
*/
_LIT( KResourceFileName, "wsfapwizard.rsc" );
    
/**
* the longest possible key is the 64 character long hex WPA key
*/
static const TInt KMaxSecureKeyLength = 64;



#ifdef _DEBUG
    _LIT( KApWizardPanic, "wsfapwizard" );
    #define __ASSERTD( v )  __ASSERT_DEBUG( (v), \
                                    User::Panic( KApWizardPanic, 0 ) )
#else
    #define __ASSERTD( v )
#endif



// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::NewL
// ----------------------------------------------------------------------------
//
EXPORT_C CWsfWlanIapWizard* CWsfWlanIapWizard::NewL()
    {
    CWsfWlanIapWizard* thisPtr = NewLC();
    CleanupStack::Pop( thisPtr );
    return thisPtr;    
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::NewLC
// ----------------------------------------------------------------------------
//
EXPORT_C CWsfWlanIapWizard* CWsfWlanIapWizard::NewLC()
    {
    CWsfWlanIapWizard* thisPtr = new (ELeave) CWsfWlanIapWizard();
    CleanupStack::PushL( thisPtr );
    thisPtr->ConstructL();
    return thisPtr;
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::CWsfWlanIapWizard
// ----------------------------------------------------------------------------
//
CWsfWlanIapWizard::CWsfWlanIapWizard():
    iEnv( *CEikonEnv::Static() ),
    iResourceFileOffset( -1 ),
    iWlanInfo( NULL )
    {
    }
   

// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::ConstructL
// ----------------------------------------------------------------------------
//
void CWsfWlanIapWizard::ConstructL()
    {
    iResourceFileOffset = InitResourcesL( iEnv );    

    iCreator = CWsfWlanIapCreator::NewL();    
    iSsidDiscovery = CWsfWlanSsidDiscovery::NewL();
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::~CWsfWlanIapWizard
// ----------------------------------------------------------------------------
//
EXPORT_C CWsfWlanIapWizard::~CWsfWlanIapWizard()
    {
    delete iCreator;

    ReleaseResources( iEnv, iResourceFileOffset );

    delete iUsedPassword;
    delete iWaitDialog;
    delete iSsidDiscovery;
    }


// ---------------------------------------------------------------------------
// CWsfWlanIapWizard::InitResourcesL
// ---------------------------------------------------------------------------
//
TInt CWsfWlanIapWizard::InitResourcesL( CEikonEnv& aEnv )
    {
    // The resource has to be loaded manually since it is not an application.
    TFileName resourceFileName;

    resourceFileName.Append( KDriveZ );
    resourceFileName.Append( KDC_RESOURCE_FILES_DIR );   
    resourceFileName.Append( KResourceFileName );

    BaflUtils::NearestLanguageFile( aEnv.FsSession(), resourceFileName );
    
    return aEnv.AddResourceFileL( resourceFileName );
    }


// ---------------------------------------------------------------------------
// CWsfWlanIapWizard::ReleaseResources
// ---------------------------------------------------------------------------
//
void CWsfWlanIapWizard::ReleaseResources( CEikonEnv& aEnv, TInt aResOffset )
    {
    if ( aResOffset != -1 )
        {
        aEnv.DeleteResourceFile( aResOffset );
        }
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::LaunchWizardL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool CWsfWlanIapWizard::LaunchWizardL( TWsfWlanInfo& aWlanInfo, 
                                                 TBool aDefineNewAccessPoint )
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::LaunchWizardL" );
    LOG_WRITEF( "defineAp = %d", aDefineNewAccessPoint );
    
    if ( aDefineNewAccessPoint && 
         !( aWlanInfo.Hidden() && !aWlanInfo.Known() ) )
        {
        HBufC* ssid16 = aWlanInfo.GetSsidAsUnicodeLC();
        LOG_WRITEF( "ssid = %S", ssid16 );
        HBufC* infoText = StringLoader::LoadLC( 
                                     R_QTN_CMON_QUEST_CREATE_WLAN_IAP, 
                                     *ssid16 ); 

        CAknQueryDialog* confirmQuery = CAknQueryDialog::NewL();
        TBool result = confirmQuery->ExecuteLD( 
                                     R_QTN_WIZARD_CONFIRMATION_QUERY,
                                     *infoText );
            
        CleanupStack::PopAndDestroy( infoText );
        CleanupStack::PopAndDestroy( ssid16 );        
        
        if ( !result )
            {
            return result;
            }
        }

    iWlanInfo = &aWlanInfo;    
    iDefineNewAccessPoint = aDefineNewAccessPoint;
        
    TRAPD( err, AskNetworkDetailsL() );
    if ( err )
        {
        // We are here also if selection of 
        // the hidden network AP leaves or is 
        // cancelled by the end-user
        LOG_WRITE( "AskNetworkDetailsL failed" );
        }
        
    return ( !err );
    }
    

// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::CreateAccessPointL
// ----------------------------------------------------------------------------
//
EXPORT_C TBool CWsfWlanIapWizard::CreateAccessPointL()
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::CreateAccessPointL" );
    __ASSERTD( iWlanInfo );
    
    
    if ( iWlanInfo->iIapId != 0 )    
        {
        // Access Point already exists
        User::Leave( KErrAlreadyExists );
        }    
 
    
    // otherwise new Access Point will be created
    if ( !iWlanInfo->iSsid.Length() )
        {
        User::Leave( KErrGeneral );
        }
        
    TPtrC sharedKey = iUsedPassword ? *iUsedPassword : KNullDesC();

    TUint32 destId( 0 );

    if ( iDefineNewAccessPoint )
        {
        // define access point was selected, select destination query follows
        LOG_WRITE( "defineAp = ETrue, opening select destination dialog..." );
        
        CCmSettingsUi* settings = CCmSettingsUi::NewL();
        CleanupStack::PushL( settings );
        
        TBool result( EFalse );
        result = settings->SelectDestinationDlgL( destId );
        
        CleanupStack::PopAndDestroy( settings ); //settings
        
        if ( !result )
            {
            LOG_WRITE( "dialog cancelled" );
            // cancel was pressed, abort creation
            return EFalse;
            }
        LOG_WRITEF( "target destination = %d", destId );
        }
    
    iCreator->SetDefaultDestination( destId );
    
    iCreator->CreateAccessPointL( *iWlanInfo, sharedKey, iIsHexWep );
    
    return ETrue;
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::QueryTextL
// ----------------------------------------------------------------------------
//
TInt CWsfWlanIapWizard::QueryTextL( TInt aQueryStringResource, 
                                    TDes& aVariable, 
                                    const TInt &aMaxLength )
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::QueryTextL" );
    HBufC* queryText = StringLoader::LoadLC( aQueryStringResource );
    CAknTextQueryDialog* textQuery = CAknTextQueryDialog::NewL( aVariable );
    CleanupStack::PushL( textQuery );
    textQuery->SetPromptL( *queryText );
    textQuery->SetMaxLength( aMaxLength );
    CleanupStack::Pop( textQuery );
    TInt result = textQuery->ExecuteLD( R_QTN_WIZARD_QUERY_GENERAL );    
    CleanupStack::PopAndDestroy( queryText );
    return result;
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::QuerySecureKeyL
// ----------------------------------------------------------------------------
//
TBool CWsfWlanIapWizard::QuerySecureKeyL()
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::QuerySecureKeyL" );
    TBool okPressed( ETrue );

    switch ( iWlanInfo->iSecurityMode )
        {
        case EWlanSecModeWep:
            {
            LOG_WRITE( "secmode WEP" );
            CConnectionUiUtilities* connUiUtils = 
                                            CConnectionUiUtilities::NewL();
            CleanupStack::PushL( connUiUtils );
            iUsedPassword = HBufC::NewL( KMaxSecureKeyLength );
            TPtr ptr( iUsedPassword->Des() );
            okPressed = connUiUtils->EasyWepDlg( &ptr, iIsHexWep );
            CleanupStack::PopAndDestroy( connUiUtils );
            break;
            }
            
        case EWlanSecModeWpa:
        case EWlanSecModeWpa2:
        case EWlanSecMode802_1x:
            {
            if ( iWlanInfo->UsesPreSharedKey() )
                {
                // WPA-PSK
                LOG_WRITE( "secmode WPA-PSK" );
                
                CConnectionUiUtilities* connUiUtils = 
                                            CConnectionUiUtilities::NewL();
                CleanupStack::PushL( connUiUtils );
                iUsedPassword = HBufC::NewL( KMaxSecureKeyLength );
                TPtr ptr( iUsedPassword->Des() );
                okPressed = connUiUtils->EasyWpaDlg( &ptr );
                CleanupStack::PopAndDestroy( connUiUtils );
                }
            else
                {
                // no key prompt in EAP mode, but the usual note is shown
                LOG_WRITE( "secmode WPA-EAP" );

                HBufC* eapText = StringLoader::LoadLC( 
                                 R_QTN_NETW_CONSET_INFO_EAP_SETTINGS_DEFAULT );
                CAknInformationNote* informationNote = 
                                     new (ELeave) CAknInformationNote( ETrue );
                informationNote->ExecuteLD( *eapText );
                
                CleanupStack::PopAndDestroy( eapText );
                }
            
            break;                
            }
        
        case EWlanSecModeOpen:
        default:
            {
            LOG_WRITE( "secmode Open" );

            delete iUsedPassword;
            iUsedPassword = NULL;
            }
        }
        
    return okPressed;
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::DismissWaitNote
// ----------------------------------------------------------------------------
//
void CWsfWlanIapWizard::DismissWaitNote( TAny* aPtr )
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::DismissWaitNote" );
    CWsfWlanIapWizard* self = static_cast<CWsfWlanIapWizard*>( aPtr );
    
    if ( self->iWaitDialog )
        {
        // close waitnote
        LOG_WRITE( "closing waitnote..." );
        TRAP_IGNORE( self->iWaitDialog->ProcessFinishedL() );

        // cleanup
        delete self->iWaitDialog;
        self->iWaitDialog = NULL;        
        }
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::AskNetworkDetailsL
// ----------------------------------------------------------------------------
//
void CWsfWlanIapWizard::AskNetworkDetailsL()
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::AskNetworkDetailsL" );
    
   
    // check the wlan info, and make proper questions....
    if ( iWlanInfo->Hidden() && !iWlanInfo->Known() )
        {
        LOG_WRITE( "unlisted network" );
        
        // query network SSID
        HBufC* ssid16 = AskSsidL();
        LOG_WRITEF( "SSID: [%S]", ssid16 );

        // update SSID        
        CnvUtfConverter::ConvertFromUnicodeToUtf8( iWlanInfo->iSsid, *ssid16 );
        delete ssid16;

        // pop up waitnote
        iWaitDialog = new ( ELeave ) CAknWaitDialog( 
                       reinterpret_cast<CEikDialog**>( &iWaitDialog ), ETrue );
        iWaitDialog->SetCallback( this );
        iWaitDialog->ExecuteLD( R_SEARCHING_WLAN_WAIT_NOTE ); 
        
        CleanupStack::PushL( TCleanupItem( DismissWaitNote, this ) );
        
        // start to scan for surrounding WLAN networks
        TBool foundSsid( EFalse );
        TBool usePsk( EFalse );
        TWlanSsid ssid( iWlanInfo->iSsid );

        // make a broadcast scan
        LOG_WRITE( "broadcast scanning for SSID" );
        foundSsid = iSsidDiscovery->ScanForSsidL( ssid, ETrue, 
                                         iWlanInfo->iNetMode, 
                                         iWlanInfo->iSecurityMode, 
                                         usePsk );

        // SSID found?
        if ( !foundSsid )
            {
            // must be really hidden, direct scan for SSID
            LOG_WRITE( "broadcast scan failed, direct scanning for SSID" );
            foundSsid = iSsidDiscovery->ScanForSsidL( ssid, EFalse, 
                                             iWlanInfo->iNetMode, 
                                             iWlanInfo->iSecurityMode, 
                                             usePsk );

            // it can only be found as hidden
            iWlanInfo->iVisibility = EFalse;

            CleanupStack::PopAndDestroy( 1 ); // DismissWaitNote
            
            if ( !foundSsid )
                {
                LOG_WRITE( "direct scan failed, entering fully manual mode" );
                
                // pop up discreet popup: No WLANs found
                CConnectionUiUtilities* connUiUtils = CConnectionUiUtilities::NewL();        
                connUiUtils->NoWLANNetworksAvailableNote();
                delete connUiUtils;                
                
                // now entering fully manual mode

                // query network mode
                TInt mode( 0 );
                CAknListQueryDialog* listQuery = 
                                  new (ELeave) CAknListQueryDialog( &mode );
                listQuery->PrepareLC( R_QTN_WIZARD_NETWORK_MODE );
                TInt retval = listQuery->RunLD();
                if ( !retval )
                    {
                    User::Leave( KErrCancel );
                    }
                
                const TInt KModeInfraPublic = 0;
                const TInt KModeInfraHidden = 1;
                const TInt KModeAdhocPublic = 2;
                
                TBool adhoc( EFalse );
                
                switch ( mode )
                    {
                    case KModeInfraPublic: 
                        {
                        LOG_WRITE( "infra public mode" );
                        iWlanInfo->iNetMode = EInfra;
                        iWlanInfo->iVisibility = ETrue;
                        break;
                        }

                    case KModeInfraHidden: 
                        {
                        LOG_WRITE( "infra hidden mode" );
                        iWlanInfo->iNetMode = EInfra;
                        iWlanInfo->iVisibility = EFalse;
                        break;
                        }
                        
                    case KModeAdhocPublic: 
                        {
                        LOG_WRITE( "adhoc public mode" );
                        adhoc = ETrue;
                        iWlanInfo->iNetMode = EAdhoc;
                        iWlanInfo->iVisibility = ETrue;
                        break;
                        }
                    }

            
                // query security mode
                const TInt KSecModeOpen = 0;
                const TInt KSecModeWep = 1;
                const TInt KSecMode8021x = 2;
                const TInt KSecModeWpa = 3;

                mode = KSecModeOpen;
                listQuery = new (ELeave) CAknListQueryDialog( &mode );
                
                if ( adhoc )
                    {
                    listQuery->PrepareLC( R_QTN_WIZARD_AUTH_MODE_AD_HOC );
                    }
                else
                    {
                    listQuery->PrepareLC( R_QTN_WIZARD_AUTH_MODE );
                    }

                retval = listQuery->RunLD();

                if ( !retval )
                    {
                    User::Leave( KErrCancel );
                    }
                    
                // map the security mode
                
                switch ( mode )
                    {
                    case KSecModeWep:
                        {
                        LOG_WRITE( "security: WEP" );
                        iWlanInfo->iSecurityMode = EWlanSecModeWep;
                        break;
                        }
                    case KSecMode8021x:
                        {
                        LOG_WRITE( "security: 802.1x" );
                        iWlanInfo->iSecurityMode = EWlanSecMode802_1x;
                        break;    
                        }
                    case KSecModeWpa:
                        {
                        LOG_WRITE( "security: WPA" );
                        iWlanInfo->iSecurityMode = EWlanSecModeWpa;
                        break;    
                        }

                    case KSecModeOpen:
                    default:
                        {
                        LOG_WRITE( "security: Open" );
                        iWlanInfo->iSecurityMode = EWlanSecModeOpen;
                        }
                    }                

                // if WPA, query WPA mode
                if ( iWlanInfo->iSecurityMode == EWlanSecModeWpa )
                    {
                    const TInt KWpaModeEap = 0;
                    const TInt KWpaModePsk = 1;

                    mode = KWpaModeEap;
                    listQuery = new (ELeave) CAknListQueryDialog( &mode );
                    listQuery->PrepareLC( R_QTN_WIZARD_WPA_MODE );
                    retval = listQuery->RunLD();
                    if ( !retval )
                        {
                        User::Leave( KErrCancel );
                        }
                    
                    // 0 - EAP, 1 - PSK    
                    
                    usePsk = ( mode == KWpaModePsk );
                    if ( usePsk )
                        {
                        LOG_WRITE( "WPA-PSK" );
                        }
                    else
                        {
                        LOG_WRITE( "WPA-EAP" );
                        }
                    }

                } // if !foundssid (direct)

            
            } // if !foundssid (broadcast)
        else
            {
            // it was thought to be hidden but actually it isn't
            LOG_WRITE( "broadcast scan succeeded, "
                       L"network isn't hidden as it was thought" );
            LOG_WRITEF( "netmode: %d, secmode: %d, usepsk: %d", 
                        iWlanInfo->iNetMode,
                        iWlanInfo->iSecurityMode,
                        usePsk );
            
            CleanupStack::PopAndDestroy( 1 ); // DismissWaitNote

            // set WLAN to public
            iWlanInfo->iVisibility = ETrue;
            }

        // convey PSK settings to iwlaninfo 
        // (netmode and secmode are already updated)
        iWlanInfo->SetUsesPreSharedKey( usePsk );
        
        }
    else
        {
        // if NOT hidden
        LOG_WRITE( "visible network" );
        LOG_WRITEF( "netmode: %d, secmode: %d, usepsk: %d", 
        iWlanInfo->iNetMode,
        iWlanInfo->iSecurityMode,
        iWlanInfo->UsesPreSharedKey() );
        }

    // query the key and leave if cancelled
    if ( !QuerySecureKeyL() )
        {
        User::Leave( KErrCancel );
        }

    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::AskSsidL
// ----------------------------------------------------------------------------
//
HBufC* CWsfWlanIapWizard::AskSsidL()
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::AskSsidL" );
    
    HBufC* apName = HBufC::NewLC( KWlanMaxSsidLength );    
    TPtr namePtr( apName->Des() );
    if ( iWlanInfo->iSsid.Length() )
        {
        CnvUtfConverter::ConvertToUnicodeFromUtf8( namePtr, iWlanInfo->iSsid );
        }
    TInt response = QueryTextL( R_QTN_ENTER_NETWORK_SSID, 
                                namePtr, 
                                KWlanMaxSsidLength );
    if ( response != EEikBidOk )
        {    
        User::Leave( KErrCancel );
        }

    CleanupStack::Pop( apName ); 
    return apName;
    }


// ----------------------------------------------------------------------------
// CWsfWlanIapWizard::DialogDismissedL
// ----------------------------------------------------------------------------
//
void CWsfWlanIapWizard::DialogDismissedL( TInt aButtonId )
    {
    LOG_ENTERFN( "CWsfWlanIapWizard::DialogDismissedL" );
    iWaitDialog = NULL;
    
    if ( aButtonId == EEikBidCancel )
        {
        // dialog was cancelled by the user
        LOG_WRITE( "dialog was cancelled" );
        iSsidDiscovery->AbortScanning();        
        }    
    }