diff -r 63be7eb3fc78 -r f28ada11abbf wlanutilities/wlansniffer/apwizard/src/wsfwlaniapcreator.cpp --- /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 +#include +#include +#include + +// 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 + ( 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( + CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( *iDbSession ); + + CMDBField* sidField = static_cast*> + ( 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 keyWPA; + keyWPA.Copy( aPresharedKey ); + TInt len( keyWPA.Length() ); + LOG_WRITEF( "PSK:[%S] len = %d", &aPresharedKey, len ); + + + CMDBField* enableWpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanEnableWpaPsk ) ); + enableWpaPskField->SetL( usesPsk ); + + CMDBField* secModeField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanSecMode ) ); + secModeField->SetL( aSecMode ); + + CMDBField* wpaPskField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWpaPreSharedKey ) ); + wpaPskField->SetL( keyWPA ); + + // Save PreShared Key length + CMDBField* keyLengthField = static_cast*> + ( 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 + ( 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 + ( CCDRecordBase::RecordFactoryL( 0 ) ); + CleanupStack::PushL( generic ); + generic->InitializeL( TPtrC( WLAN_SERVICE ), NULL ); + generic->LoadL( *iDbSession ); + + CMDBField* sidField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanServiceId ) ); + + // prime with service id + *sidField = serviceId; + + TBool found = generic->FindL( *iDbSession ); + + LOG_WRITE( "saving WEP settings..." ); + + + CMDBField* indexField = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepIndex ) ); + indexField->SetL( KFirstWepKey ); + + // Save authentication mode + CMDBField* authenticationField = static_cast*> + ( 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 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* wepKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) ); + wepKey1Field->SetL( buf8Conv->Des() ); + + CleanupStack::PopAndDestroy( buf8Conv ); + } + else + { + // already in hexa format + CMDBField* wepKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey1 ) ); + wepKey1Field->SetL( key ); + } + + + // write default values to the rest of the columns + key.Zero(); + + CMDBField* wepKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey2 ) ); + wepKey2Field->SetL( key ); + CMDBField* wepKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey3 ) ); + wepKey3Field->SetL( key ); + CMDBField* wepKey4Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanWepKey4 ) ); + wepKey4Field->SetL( key ); + + + // write format data + TUint fmt( aIsHexWep ); + + CMDBField* formatKey1Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey1 ) ); + formatKey1Field->SetL( fmt ); + CMDBField* formatKey2Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey2 ) ); + formatKey2Field->SetL( fmt ); + CMDBField* formatKey3Field = static_cast*> + ( generic->GetFieldByIdL( KCDTIdWlanFormatKey3 ) ); + formatKey3Field->SetL( fmt ); + CMDBField* formatKey4Field = static_cast*> + ( 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( + 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; + } + +