/*
* Copyright (c) 2002 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: Declares authentication (PIN query) notifier class.
*
*/
// INCLUDE FILES
#include <StringLoader.h> // Localisation stringloader
#include <utf.h> // Unicode character conversion utilities
#include <avkon.mbg>
#include <btengconnman.h>
#include <btotgpairpub.inl>
#include <btextnotifiers.h>
#include <BTNotif.rsg> // Own resources
#include "btnotif.hrh" // Own resource header
#include "btnpinnotifier.h" // Own class definition
#include "btNotifDebug.h" // Debugging macros
#include "btnotifnameutils.h"
#ifndef SYMBIAN_ENABLE_SPLIT_HEADERS
#include <btextnotifiers.h>
#else
#include <btextnotifiers.h>
#include <btextnotifierspartner.h>
#endif
#include <SecondaryDisplay/BTnotifSecondaryDisplayAPI.h>
#ifdef __SERIES60_HELP
#include <hlplch.h>
#include <csxhelp/bt.hlp.hrh> // The bt hrh info is needed, for help launching
#endif
const TInt KDefaultPinCodeLength=4;
const TUint8 KZeroPinValue = '0';
// ================= MEMBER FUNCTIONS =======================
// ----------------------------------------------------------
// CBTPinNotifier::NewL
// Two-phased constructor.
// ----------------------------------------------------------
//
CBTPinNotifier* CBTPinNotifier::NewL()
{
CBTPinNotifier* self=new (ELeave) CBTPinNotifier();
CleanupStack::PushL(self);
self->ConstructL();
CleanupStack::Pop(self);
return self;
}
// ----------------------------------------------------------
// CBTPinNotifier::CBTPinNotifier
// C++ default constructor can NOT contain any code, that
// might leave.
// ----------------------------------------------------------
//
CBTPinNotifier::CBTPinNotifier()
{
}
// ----------------------------------------------------------
// Destructor
// ----------------------------------------------------------
//
CBTPinNotifier::~CBTPinNotifier()
{
}
// ----------------------------------------------------------
// CBTPinNotifier::RegisterL
// Register notifier.
// ----------------------------------------------------------
//
CBTPinNotifier::TNotifierInfo CBTPinNotifier::RegisterL()
{
iInfo.iUid=KBTPinCodeEntryNotifierUid;
iInfo.iChannel=KBTAuthenticationChannel;
iInfo.iPriority=ENotifierPriorityVHigh;
return iInfo;
}
// ----------------------------------------------------------
// CBTPinNotifier::GetParamsL
// Initialize parameters and check if device is already
// in registry. Jump to RunL as soon as possible.
// ----------------------------------------------------------
//
void CBTPinNotifier::GetParamsL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::GetParamsL() >>"));
CBTNPairNotifierBase::GetParamsL( aBuffer, aReplySlot, aMessage );
TBTPinCodeEntryNotifierParams param;
TPckgC<TBTPinCodeEntryNotifierParams> pckg(param);
pckg.Set(aBuffer);
iBTAddr = pckg().DeviceAddress();
if ( OtherOutgoPairing(iBTAddr) )
{
// We won't allow incoming pairing during outgoing pairing:
FLOG(_L("[BTNOTIF]\t CBTPinNotifier: outgoing pair in progress, reject incoming pair"));
CompleteMessage(KErrCancel);
return;
}
iLocallyInitiated = pckg().LocallyInitiated();
iPasskeyLength = pckg().PinCodeMinLength();
iStrongPinRequired = pckg().StrongPinCodeRequired();
ProcessParamsGetDeviceL( iBTAddr, pckg().DeviceName() );
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::GetParamsL() <<"));
}
// ----------------------------------------------------------
// CBTPinNotifier::HandleGetDeviceCompletedL
// Ask user response and return it to caller.
// Store device into registry if user has accepted pairing.
// ----------------------------------------------------------
//
void CBTPinNotifier::HandleGetDeviceCompletedL(const CBTDevice* aDev)
{
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::HandleGetDeviceCompletedL() >>"));
(void) aDev;
// Check if blocked device
if( CheckBlockedDeviceL() )
return;
// Turn lights on and deactivate apps -key
iNotifUiUtil->TurnLightsOn();
if( CheckAndSetAutomatedPairing() )
{
CompleteMessage(iPinCode, KErrNone);
return;
}
// For incoming pairing request
if(!iLocallyInitiated)
{
TBool userAnswer = AuthoriseIncomingPairingL();
if( !userAnswer )
{
//User rejects the incoming pairing, complete message in QueryBlockDevice.
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::HandleGetDeviceCompletedL() <<"));
return;
}
}
// Use a forever loop here to show query dialog again of ínput pin code does't fulfill the
// minimum length requirement
//
FOREVER
{
TBuf<KBTPassKeyMaxLength> tempResultBuffer;
HBufC* prompt = GenerateQueryPromoptLC(); // prompt still in stack.
TInt keypress = iNotifUiUtil->ShowTextInputQueryL(tempResultBuffer, *prompt, R_BT_ENTER_PASSKEY_QUERY,
ECmdShowBtOpenCoverNote, CAknQueryDialog::EConfirmationTone );
CleanupStack::PopAndDestroy( prompt );
if( keypress ) // OK pressed
{
// Convert data from buf to pin
TBuf8<KBTPassKeyMaxLength> buf8;
buf8.Zero();
CnvUtfConverter::ConvertFromUnicodeToUtf8(buf8, tempResultBuffer);
//check if the length of pin less that minimum required pin code length
if ((iPasskeyLength == 0) || ( buf8.Length() >= iPasskeyLength))
{
iPinCode().iLength = STATIC_CAST(TUint8, buf8.Length());
for (TInt index=0; index<buf8.Length(); index++)
{
iPinCode().iPIN[index] = buf8[index];
}
CompleteMessage(iPinCode, KErrNone);
break;
}
else
{
//keep FOREVER loop runing, till the user input pin meet the requirement.
tempResultBuffer.Zero();
}
}
else // Cancel pressed
{
// If the outgoing pairing mode is set, then this is bonding initiated by the user.
TBool incomingConn = ( OutgoPairingMode( iBTAddr ) == EBTOutgoingPairNone );
if( !iMessage.IsNull() )
{
// No need to inform the user of the pairing result if the user cancelled it.
// If user doesn't answer anything but stack cancels, pairing result is needed
// to show for outgoing pairing. In this case, don't stop pairng observer.
CBTEngConnMan::StopPairingObserver( iBTAddr );
}
// We may be asking for pairing (locally initiated), because a remote device is requesting
// accesss to a service for which we require authentication.
if( iLocallyInitiated && incomingConn )
{
CheckAndHandleQueryIntervalL();
}
CompleteMessage(KErrCancel);
return;
}
}//END of FOREVER loop
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::HandleGetDeviceCompletedL() completed"));
}
// ----------------------------------------------------------
// CBTPinNotifier::CheckAndSetAutomatedPairing
// ----------------------------------------------------------
TBool CBTPinNotifier::CheckAndSetAutomatedPairing()
{
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::CheckAndSetAutomatedPairing()"));
TBool ret( EFalse );
// check if device is headset and passkey is empty -> do automated pairing with 0000.
if ( iDevice &&
OutgoPairingMode( iBTAddr ) == EBTOutgoingHeadsetAutoPairing &&
iPasskeyLength <= KDefaultPinCodeLength )
{
FLOG( _L( "[BTNOTIF]\t CBTPinNotifier::CheckAndSetAutomatedPairing - automated pairing on" ) );
FLOG(_L("[BTNOTIF]\t Setting default PIN code"));
iPinCode().iLength = KDefaultPinCodeLength;
for( TInt i=0; i < KDefaultPinCodeLength; ++i)
{
iPinCode().iPIN[i] = KZeroPinValue;
}
ret = ETrue;
}
return ret;
}
// ----------------------------------------------------------
// CBTPinNotifier::GenerateQueryPromoptLC
// ----------------------------------------------------------
HBufC* CBTPinNotifier::GenerateQueryPromoptLC()
{
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::GenerateQueryPromoptLC() >>"));
HBufC* prompt = NULL;
TBTDeviceName devName;
BtNotifNameUtils::GetDeviceDisplayName( devName, iDevice );
if (iPasskeyLength > 0) //Minimum length passkey is defined
{
CDesCArray* stringArray = new ( ELeave ) CDesCArrayFlat( 1 );
CleanupStack::PushL( stringArray );
CArrayFix<TInt>* indexArray = new(ELeave) CArrayFixFlat<TInt>(1);
CleanupStack::PushL( indexArray );
stringArray->AppendL( BTDeviceNameConverter::ToUnicodeL(iDevice->DeviceName()) );
indexArray->AppendL( iPasskeyLength);
prompt = StringLoader::LoadL( R_BT_MIN_PASSKEY_PROMPT, *stringArray, *indexArray );
CleanupStack::PopAndDestroy( indexArray );
CleanupStack::PopAndDestroy( stringArray );
CleanupStack::PushL( prompt );
}
else
{
prompt = StringLoader::LoadLC( R_BT_PASSKEY_PROMPT, devName );
}
FLOG(_L("[BTNOTIF]\t CBTPinNotifier::GenerateQueryPromoptLC() <<"));
return prompt;
}
// End of File