--- /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;
+ }
+
+