wlanutilities/wlansniffer/apwizard/src/wsfwlaniapcreator.cpp
branchRCL_3
changeset 25 f28ada11abbf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wlanutilities/wlansniffer/apwizard/src/wsfwlaniapcreator.cpp	Wed Sep 01 12:20:32 2010 +0100
@@ -0,0 +1,609 @@
+/*
+* 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 CWsfWlanIapCreator
+*
+*/
+
+
+
+
+//  EXTERNAL INCLUDES
+#include <wlancontainer.h>
+#include <EapType.h>
+#include <cmdestinationext.h>
+#include <utf.h>
+
+//  CLASS HEADER
+#include "wsfwlaniapcreator.h"
+
+//  INTERNAL INCLUDES
+#include "wsfactivewaiter.h"
+#include "wsflogger.h"
+
+
+using namespace CMManager;
+
+
+/**
+* Order of first WEP key
+*/
+static const TInt KFirstWepKey = 0;
+
+/**
+* WEP authentication modes
+*/
+static const TInt KWepAuthOpen = 0;        // Open authentication
+
+/**
+* Max length of WPA key
+*/
+static const TUint KWpaKeyMaxLength = 64;
+    
+/**
+* Max length of WEP key
+*/
+static const TUint KMaxWepKeyLen = 26; 
+
+
+
+  
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::NewL
+// ----------------------------------------------------------------------------
+//
+CWsfWlanIapCreator* CWsfWlanIapCreator::NewL()
+    {
+    CWsfWlanIapCreator* thisPtr = NewLC();
+    CleanupStack::Pop( thisPtr );
+    return thisPtr;         
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::NewLC
+// ----------------------------------------------------------------------------
+//
+CWsfWlanIapCreator* CWsfWlanIapCreator::NewLC()
+    {
+    CWsfWlanIapCreator* thisPtr = new (ELeave) CWsfWlanIapCreator();
+    CleanupStack::PushL( thisPtr );
+    thisPtr->ConstructL();
+    return thisPtr;    
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::~CWsfWlanIapCreator
+// ----------------------------------------------------------------------------
+//
+CWsfWlanIapCreator::~CWsfWlanIapCreator()
+    {
+    delete iDbSession;
+    iCmManagerExt.Close();
+    }
+    
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::CWsfWlanIapCreator
+// ----------------------------------------------------------------------------
+//
+CWsfWlanIapCreator::CWsfWlanIapCreator()     
+    {
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::ConstructL
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::ConstructL()
+    {
+    iDbSession = CommsDat::CMDBSession::NewL( CMDBSession::LatestVersion() );
+    iCmManagerExt.OpenL();
+    iDestinationId = 0;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::StoreWPADataL
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::StoreWPADataL( const TInt aIapId, 
+                                     const TDesC& aPresharedKey, 
+                                     const CMManager::TWlanSecMode aSecMode )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::StoreWPADataL" );
+    
+    CCDIAPRecord *iapRec = static_cast<CCDIAPRecord*>
+                          ( CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) );
+    
+    CleanupStack::PushL( iapRec );
+    
+    iapRec->SetRecordId( aIapId );
+    iapRec->LoadL( *iDbSession );
+        
+    TUint32 serviceId = TUint32( iapRec->iService );
+
+    LOG_WRITEF("IAP(%d).serviceID = %d", aIapId, serviceId );
+    
+    // we have the service id, now we can flush the iap record
+    CleanupStack::PopAndDestroy( iapRec );
+
+    // search for the record    
+    CMDBGenericRecord* generic = static_cast<CMDBGenericRecord*>( 
+                                          CCDRecordBase::RecordFactoryL( 0 ) );
+    CleanupStack::PushL( generic );    
+    generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL );
+    generic->LoadL( *iDbSession );
+    
+    CMDBField<TUint32>* sidField = static_cast<CMDBField<TUint32>*>
+                             ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) );
+    
+    // prime with service id                
+    *sidField = serviceId;
+    
+    TBool found = generic->FindL( *iDbSession );
+
+    LOG_WRITE( "saving common WPA settings..." );
+    TBool usesPsk( aPresharedKey.Length() > 0 );
+
+    // Save PreShared Key as 8 bit string
+    TBuf8<KWpaKeyMaxLength> keyWPA;
+    keyWPA.Copy( aPresharedKey );
+    TInt len( keyWPA.Length() );
+    LOG_WRITEF( "PSK:[%S] len = %d", &aPresharedKey, len );
+
+
+    CMDBField<TUint>* enableWpaPskField = static_cast<CMDBField<TUint>*>
+                          ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) );
+    enableWpaPskField->SetL( usesPsk );
+
+    CMDBField<TUint>* secModeField = static_cast<CMDBField<TUint>*>
+                        ( generic->GetFieldByIdL( KCDTIdWlanSecMode ) );
+    secModeField->SetL( aSecMode );
+
+    CMDBField<TDesC8>* wpaPskField = static_cast<CMDBField<TDesC8>*>
+                       ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) );
+    wpaPskField->SetL( keyWPA );
+        
+    // Save PreShared Key length
+    CMDBField<TUint>* keyLengthField = static_cast<CMDBField<TUint>*>
+                        ( generic->GetFieldByIdL( KCDTIdWlanWpaKeyLength ) );
+    keyLengthField->SetL( keyWPA.Length() );
+
+
+    if ( !usesPsk )
+        {
+        // not PSK -> must be EAP
+        LOG_WRITE( "saving EAP info..." );
+        RImplInfoPtrArray eapArray;
+        REComSession::ListImplementationsL( KEapTypeInterfaceUid, eapArray );
+        CleanupClosePushL( eapArray );
+        
+        for ( TInt i = 0; i < eapArray.Count(); ++i )
+            {
+            // IsDisallowedOutsidePEAP actually means IsDisallowedOutsideTunnel
+            if ( !CEapType::IsDisallowedOutsidePEAP( *eapArray[i] ) )
+                {
+                CEapType* eapType = CEapType::NewL( eapArray[i]->DataType(), 
+                                                    ELan, 
+                                                    serviceId );
+                CleanupStack::PushL( eapType );
+                
+                eapType->SetIndexL( ELan, serviceId );
+                CleanupStack::PopAndDestroy( eapType );
+                }
+            }
+
+        eapArray.ResetAndDestroy();
+        CleanupStack::PopAndDestroy( &eapArray );
+        }
+
+    if ( !found )
+        {
+        // there wasn't any wlan service record, we have to create it now
+        LOG_WRITE("new service record");
+        generic->SetRecordId( KCDNewRecordRequest );
+        generic->StoreL( *iDbSession );
+        }
+    else
+        {
+        // modify existing record
+        LOG_WRITE("existing service record");
+        generic->ModifyL( *iDbSession );
+        }
+    
+    CleanupStack::PopAndDestroy( generic );
+    }
+    
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::StoreWEPDataL
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::StoreWEPDataL( const TInt aIapId, 
+                                        const TDesC& aWepKey, 
+                                        const TBool aIsHexWep )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::StoreWEPDataL" );
+    
+    CCDIAPRecord *iapRec = static_cast<CCDIAPRecord*>
+                          ( CCDRecordBase::RecordFactoryL( KCDTIdIAPRecord ) );
+    
+    CleanupStack::PushL( iapRec );
+    
+    iapRec->SetRecordId( aIapId );
+    iapRec->LoadL( *iDbSession );
+
+    TUint32 serviceId = TUint32( iapRec->iService );
+    LOG_WRITEF("IAP(%d).serviceID = %d", aIapId, serviceId );
+    
+    CleanupStack::PopAndDestroy( iapRec );
+
+
+    CMDBGenericRecord* generic = static_cast<CMDBGenericRecord*>
+        ( CCDRecordBase::RecordFactoryL( 0 ) );
+    CleanupStack::PushL( generic );    
+    generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL );
+    generic->LoadL( *iDbSession );
+    
+    CMDBField<TUint32>* sidField = static_cast<CMDBField<TUint32>*>
+                             ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) );
+    
+    // prime with service id                
+    *sidField = serviceId;
+    
+    TBool found = generic->FindL( *iDbSession );
+    
+    LOG_WRITE( "saving WEP settings..." );
+
+
+    CMDBField<TUint>* indexField = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanWepIndex ) );
+    indexField->SetL( KFirstWepKey );
+
+    // Save authentication mode    
+    CMDBField<TUint>* authenticationField = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanAuthMode ) );
+    authenticationField->SetL( KWepAuthOpen );
+    
+    
+
+    // now we need to convert the key to 8bit and to hex
+    // and again detect the required bits
+    TBuf8<KMaxWepKeyLen> key;
+    
+    // convert to 8 bit
+    key.Copy( aWepKey );
+
+       
+    if ( !aIsHexWep )
+        {
+        // Must be converted to hexa and stored as a hexa
+        // Ascii key is half the length of Hex
+        HBufC8* buf8Conv = HBufC8::NewLC( key.Length()*2 );
+        TPtr8 bufptr( buf8Conv->Des() );
+        ConvertAsciiToHex( key, bufptr );
+        
+        CMDBField<TDesC8>* wepKey1Field = static_cast<CMDBField<TDesC8>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) );
+        wepKey1Field->SetL( buf8Conv->Des() );
+
+        CleanupStack::PopAndDestroy( buf8Conv );
+        }
+    else
+        {
+        // already in hexa format
+        CMDBField<TDesC8>* wepKey1Field = static_cast<CMDBField<TDesC8>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) );
+        wepKey1Field->SetL( key );
+        }
+        
+    
+     // write default values to the rest of the columns
+    key.Zero();
+    
+    CMDBField<TDesC8>* wepKey2Field = static_cast<CMDBField<TDesC8>*>
+                        ( generic->GetFieldByIdL( KCDTIdWlanWepKey2 ) );
+    wepKey2Field->SetL( key );
+    CMDBField<TDesC8>* wepKey3Field = static_cast<CMDBField<TDesC8>*>
+                        ( generic->GetFieldByIdL( KCDTIdWlanWepKey3 ) );
+    wepKey3Field->SetL( key );
+    CMDBField<TDesC8>* wepKey4Field = static_cast<CMDBField<TDesC8>*>
+                        ( generic->GetFieldByIdL( KCDTIdWlanWepKey4 ) );
+    wepKey4Field->SetL( key );
+
+
+    // write format data
+    TUint fmt( aIsHexWep );
+    
+    CMDBField<TUint>* formatKey1Field = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) );
+    formatKey1Field->SetL( fmt );
+    CMDBField<TUint>* formatKey2Field = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanFormatKey2 ) );
+    formatKey2Field->SetL( fmt );
+    CMDBField<TUint>* formatKey3Field = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanFormatKey3 ) );
+    formatKey3Field->SetL( fmt );
+    CMDBField<TUint>* formatKey4Field = static_cast<CMDBField<TUint>*>
+                            ( generic->GetFieldByIdL( KCDTIdWlanFormatKey4 ) );
+    formatKey4Field->SetL( fmt );
+    
+    
+    if ( !found )
+        {
+        // there wasn't any wlan service record, we have to create it now
+        LOG_WRITE("new service record");
+        generic->SetRecordId( KCDNewRecordRequest );
+        generic->StoreL( *iDbSession );
+        }
+    else
+        {
+        // modify existing record
+        LOG_WRITE("existing service record");
+        generic->ModifyL( *iDbSession );
+        }
+        
+    CleanupStack::PopAndDestroy( generic );    
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::ConvertAsciiToHex
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::ConvertAsciiToHex( const TDesC8& aSource, 
+                                            TDes8& aDest )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::ConvertAsciiToHex" );
+    _LIT8( hex, "0123456789ABCDEF" );
+    TInt size = aSource.Size();
+    aDest.Zero();
+    
+    for ( TInt ii = 0; ii < size; ii++ )
+        {
+        TText8 ch = aSource[ii];
+        aDest.Append( hex()[(ch/16)&0x0f] );
+        aDest.Append( hex()[ch&0x0f] );
+        }
+    }
+    
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::SetDefaultDestination
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::SetDefaultDestination( const TUint32 aDestinationId )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::SetDefaultDestination" );
+    LOG_WRITEF( "destId = %d", aDestinationId );
+    iDestinationId = aDestinationId;
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::CreateAccessPointL
+// ----------------------------------------------------------------------------
+//
+void CWsfWlanIapCreator::CreateAccessPointL( TWsfWlanInfo& aWlanInfo, 
+                                                const TDesC& aPresharedKey, 
+                                                const TBool aIsHex )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::CreateAccessPointL" );
+    TUint32 iapId( 0 );
+
+    // create connection method
+    iapId = CreateConnectionMethodL( aWlanInfo );
+    
+
+    // open a transaction
+    const TUint KMaxOpenTransAttempts = 10;
+    const TUint KRetryAfter = 100000;
+
+    TInt err( KErrNone );
+    TUint attempts( KMaxOpenTransAttempts );
+    
+    CWsfActiveWaiter* waiter = CWsfActiveWaiter::NewLC();
+    RTimer timer;
+    timer.CreateLocal();
+    CleanupClosePushL( timer );
+    
+    do
+        {
+        TRAP( err, iDbSession->OpenTransactionL() );
+        if ( err )
+            {
+            timer.After( waiter->iStatus, 
+                         TTimeIntervalMicroSeconds32( KRetryAfter ) );
+            waiter->WaitForRequest();
+            }
+        }
+    while ( err && attempts-- );
+
+    User::LeaveIfError( err );
+
+    CleanupStack::PopAndDestroy( &timer );
+    CleanupStack::PopAndDestroy( waiter );
+    
+    CleanupStack::PushL( TCleanupItem( RollbackCommsDat, iDbSession ) );
+
+    
+    // now we have a valid transaction, save security settings
+    
+    switch ( aWlanInfo.iSecurityMode )
+        {
+        case EWlanSecModeWep:
+            {
+            StoreWEPDataL( iapId, aPresharedKey, aIsHex );
+            break;
+            }
+        case EWlanSecMode802_1x:
+        case EWlanSecModeWpa:
+        case EWlanSecModeWpa2:
+            {
+            StoreWPADataL( iapId, aPresharedKey, aWlanInfo.iSecurityMode );
+            break;
+            }
+        case EWlanSecModeOpen: // fall through on purpose
+        default:
+            {
+            }
+        }
+
+    CleanupStack::Pop( 1 ); // transaction rollback popped
+    
+    // commit changes
+    if ( iDbSession->IsInTransaction() )
+        {
+        iDbSession->CommitTransactionL();
+        }
+        
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::RollbackCommsDat
+// ----------------------------------------------------------------------------
+void CWsfWlanIapCreator::RollbackCommsDat( TAny* aDbSession )
+    {
+    CommsDat::CMDBSession* session = static_cast<CommsDat::CMDBSession*>( 
+                                                                 aDbSession );
+    TRAP_IGNORE( session->RollbackTransactionL() );
+    }
+
+
+// ----------------------------------------------------------------------------
+// CWsfWlanIapCreator::CreateConnectionMethodL
+// ----------------------------------------------------------------------------
+//
+TUint32 CWsfWlanIapCreator::CreateConnectionMethodL( TWsfWlanInfo& aWlanInfo )
+    {
+    LOG_ENTERFN( "CWsfWlanIapCreator::CreateConnectionMethodL" );
+    
+    HBufC* name16 = NULL;
+    HBufC* ssid16 = NULL;
+    
+    if ( aWlanInfo.iRawSsid.Length() )
+        {
+        // ssid is from scan result store it as it is 
+        // since the encoding of ssid is unknown
+        name16 = HBufC::NewLC( aWlanInfo.iRawSsid.Length() );
+        name16->Des().Copy( aWlanInfo.iRawSsid );
+        ssid16 = HBufC::NewLC( aWlanInfo.iRawSsid.Length() );
+        ssid16->Des().Copy( aWlanInfo.iRawSsid );
+        }
+    else
+        {
+        // user has inputted ssid store it to name as unicode since it is utf-8 
+        name16 = aWlanInfo.GetSsidAsUnicodeLC();
+        ssid16 = HBufC::NewLC( aWlanInfo.iSsid.Length() );
+        ssid16->Des().Copy( aWlanInfo.iSsid );
+        }
+        
+    TUint32 iapId( 0 );
+    
+    if ( !iDestinationId )
+        {
+        // possibly temporary iap to uncategorized
+        LOG_WRITE( "destId not set -> temporary into Uncategorised" );
+        
+        RCmConnectionMethodExt cm = iCmManagerExt.CreateConnectionMethodL( 
+                                                         KUidWlanBearerType );
+        CleanupClosePushL( cm );
+        
+        cm.SetStringAttributeL( ECmName, *name16 );
+        cm.SetStringAttributeL( EWlanSSID, *ssid16 );
+        cm.SetIntAttributeL( EWlanSecurityMode, aWlanInfo.iSecurityMode );
+        cm.SetIntAttributeL( EWlanConnectionMode, aWlanInfo.iNetMode );
+        cm.SetBoolAttributeL( EWlanScanSSID, !aWlanInfo.iVisibility );
+        
+        // commit changes
+        cm.UpdateL();
+
+        // get the iap id
+        iapId = cm.GetIntAttributeL( ECmId );
+        
+        // now retrieve the name again to see if it has been changed 
+        // (ExistingCmName -> ExistingCmName(01) and alike)
+        HBufC* cmName = cm.GetStringAttributeL( ECmName );
+        
+        TInt error = CnvUtfConverter::ConvertFromUnicodeToUtf8( 
+                                                        aWlanInfo.iNetworkName, 
+                                                        *cmName  );
+        if ( error )
+            {
+            LOG_WRITE( "ConvertFromUnicodeToUtf8 failed");
+            aWlanInfo.iNetworkName.Copy( *cmName );
+            }
+
+        delete cmName;
+        
+        CleanupStack::PopAndDestroy( &cm );
+        }
+    else
+        {
+        // final iap to the default destination
+        LOG_WRITEF( "destId = %d", iDestinationId );
+        
+        RCmDestinationExt destination = iCmManagerExt.DestinationL( 
+                                                            iDestinationId );
+        CleanupClosePushL( destination );
+        
+        RCmConnectionMethodExt cm = destination.CreateConnectionMethodL( 
+                                                         KUidWlanBearerType );
+        CleanupClosePushL( cm );
+
+        cm.SetStringAttributeL( ECmName, *name16 );
+        cm.SetStringAttributeL( EWlanSSID, *ssid16 );
+        cm.SetIntAttributeL( EWlanSecurityMode, aWlanInfo.iSecurityMode );
+        cm.SetIntAttributeL( EWlanConnectionMode, aWlanInfo.iNetMode );
+        cm.SetBoolAttributeL( EWlanScanSSID, !aWlanInfo.iVisibility );
+        
+        // commit changes
+        destination.UpdateL();
+
+        // get the iap id
+        iapId = cm.GetIntAttributeL( ECmId );
+        
+        // now retrieve the name again to see if it has been changed 
+        // (ExistingCmName -> ExistingCmName(01) and alike)
+        HBufC* cmName = cm.GetStringAttributeL( ECmName );
+        TInt error = CnvUtfConverter::ConvertFromUnicodeToUtf8( 
+                                                         aWlanInfo.iNetworkName, 
+                                                         *cmName  );
+        if ( error )
+            {
+            LOG_WRITE( "ConvertFromUnicodeToUtf8 failed");
+            aWlanInfo.iNetworkName.Copy( *cmName );
+            }
+        
+        delete cmName;
+        
+        CleanupStack::PopAndDestroy( &cm );
+        CleanupStack::PopAndDestroy( &destination );
+        }
+
+    CleanupStack::PopAndDestroy( ssid16 );
+    CleanupStack::PopAndDestroy( name16 );
+
+    aWlanInfo.iIapId = iapId;
+    LOG_WRITEF( "new iapId = %d", iapId );
+
+    return iapId;
+    }
+        
+