// Copyright (c) 2000-2009 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:
//
#include "BTTextNotifiers.h"
#include <btdevice.h>
#include <e32cons.h>
#include <es_prot.h>
#include <bluetooth/logger.h>
#include "pannapuplinkauthorisationnotifier.h"
#ifdef __FLOG_ACTIVE
_LIT8(KLogComponent, "TextNotifiers");
#endif
void CreateNotifiersL(CArrayPtrFlat<MNotifierBase2>& aNotifiers)
{
LOG_STATIC_FUNC
// Utility macro to make this function simpler.
#define ADD_BT_NOTIFIER(XType) \
{\
XType* notifier = XType::NewLC(); \
aNotifiers.AppendL(notifier); \
CleanupStack::Pop(notifier); \
}
ADD_BT_NOTIFIER(CBTManPinNotifier);
ADD_BT_NOTIFIER(CBTManAuthNotifier);
ADD_BT_NOTIFIER(CBTManDeviceSelectionNotifier);
ADD_BT_NOTIFIER(CBTPanDeviceSelectionNotifier);
ADD_BT_NOTIFIER(CPbapAuthNotifier);
ADD_BT_NOTIFIER(CPanNapUplinkAuthorisationNotifier);
#ifndef __BT_TEXT_NOTIFIERS_NO_SSP__
ADD_BT_NOTIFIER(CBTUINumericComparison);
ADD_BT_NOTIFIER(CBTUIPasskeyEntry);
ADD_BT_NOTIFIER(CBTUIPinCodeEntry);
#endif // __BT_TEXT_NOTIFIERS_NO_SSP__
#undef ADD_BT_NOTIFIER // This macro is local to this function
}
/**
The main library entry point for a notifier implementation.
*/
EXPORT_C CArrayPtr<MNotifierBase2>* NotifierArray()
{
LOG_STATIC_FUNC
FLOG(_L("RNot\tExported entry point"));
CArrayPtrFlat<MNotifierBase2>* notifiers = new CArrayPtrFlat<MNotifierBase2>(5);
if (notifiers)
{
TRAPD(err, CreateNotifiersL(*notifiers));
if(err)
{
FLOG(_L("RNot\tError Creating notifier"));
TInt count = notifiers->Count();
while(count--)
{
(*notifiers)[count]->Release();
}
delete notifiers, notifiers = NULL;
}
}
return notifiers;
}
//
// BTTextNotifiersConsole
//
CConsoleBase* BTTextNotifiersConsole::AutoSizeNewL(const TDesC& aTitle, TSize aSize)
{
LOG_STATIC_FUNC
// Try to create a console of our preferred size, otherwise we
// guess the screen is too small and use its entirety.
CConsoleBase* console = NULL;
TRAPD(err, console = Console::NewL(aTitle, aSize));
if (err != KErrNone)
{
// If we leave now it is not because of offscreen drawing.
console = Console::NewL(aTitle, TSize(KConsFullScreen, KConsFullScreen));
}
return console;
}
//
// CBTManPinNotifier
//
CBTManPinNotifier* CBTManPinNotifier::NewLC()
{
LOG_STATIC_FUNC
CBTManPinNotifier* self = new(ELeave) CBTManPinNotifier();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CBTManPinNotifier::CBTManPinNotifier()
{
LOG_FUNC
}
void CBTManPinNotifier::ConstructL()
{
LOG_FUNC
iEngine = CBTManPinNotifierEngine::NewL(*this);
}
void CBTManPinNotifier::Release()
{
LOG_FUNC
Cancel();
delete this;
}
void CBTManPinNotifier::Cancel()
{
LOG_FUNC
iEngine->Stop();
if (iNeedToCompleteMessage)
{
iMessage.Complete(KErrCancel);
iNeedToCompleteMessage = EFalse;
}
}
CBTManPinNotifier::~CBTManPinNotifier()
{
LOG_FUNC
delete iEngine;
}
CBTManPinNotifier::TNotifierInfo CBTManPinNotifier::RegisterL()
{
LOG_FUNC
iInfo.iUid=KBTManPinNotifierUid;
iInfo.iChannel=KScreenOutputChannel;
iInfo.iPriority=ENotifierPriorityVHigh;
return iInfo;
}
CBTManPinNotifier::TNotifierInfo CBTManPinNotifier::Info() const
{
LOG_FUNC
return iInfo;
}
TPtrC8 CBTManPinNotifier::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTManPinNotifier::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
iReplySlot = aReplySlot;
iMessage = RMessage2(aMessage);
iNeedToCompleteMessage = ETrue;
TRAPD(err, iEngine->StartLegacyPinEntryL(aBuffer));
LOG1(_L("Pin Notifier started with result %d"), err);
if(err != KErrNone)
{
aMessage.Complete(err);
iNeedToCompleteMessage = EFalse;
LEAVEL(err);
}
}
TPtrC8 CBTManPinNotifier::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
return iEngine->LegacyUpdateL(aBuffer);
}
void CBTManPinNotifier::MbpceoPinInputComplete(const TBTPinCode& aPin, TInt aReason)
{
LOG_FUNC
LOG1(_L("\taReason = %d"), aReason);
if (aReason == KErrNone)
{
TInt err = iMessage.Write(iReplySlot, aPin);
iMessage.Complete(err);
}
else
{
iMessage.Complete(aReason);
}
iNeedToCompleteMessage = EFalse;
}
#ifndef __BT_TEXT_NOTIFIERS_NO_SSP__
//
// CBTUIPinCodeEntry
//
CBTUIPinCodeEntry* CBTUIPinCodeEntry::NewLC()
{
LOG_STATIC_FUNC
CBTUIPinCodeEntry* self = new(ELeave) CBTUIPinCodeEntry();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CBTUIPinCodeEntry::CBTUIPinCodeEntry()
{
LOG_FUNC
}
void CBTUIPinCodeEntry::ConstructL()
{
LOG_FUNC
iEngine = CBTManPinNotifierEngine::NewL(*this);
}
void CBTUIPinCodeEntry::Release()
{
LOG_FUNC
Cancel();
delete this;
}
void CBTUIPinCodeEntry::Cancel()
{
LOG_FUNC
iEngine->Stop();
if (iNeedToCompleteMessage)
{
iMessage.Complete(KErrCancel);
iNeedToCompleteMessage = EFalse;
}
}
CBTUIPinCodeEntry::~CBTUIPinCodeEntry()
{
LOG_FUNC
delete iEngine;
}
CBTManPinNotifier::TNotifierInfo CBTUIPinCodeEntry::RegisterL()
{
LOG_FUNC
iInfo.iUid = KBTPinCodeEntryNotifierUid;
iInfo.iChannel = KScreenOutputChannel;
iInfo.iPriority = ENotifierPriorityVHigh;
return iInfo;
}
CBTManPinNotifier::TNotifierInfo CBTUIPinCodeEntry::Info() const
{
LOG_FUNC
return iInfo;
}
TPtrC8 CBTUIPinCodeEntry::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTUIPinCodeEntry::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
iReplySlot = aReplySlot;
iMessage = RMessage2(aMessage);
iNeedToCompleteMessage = ETrue;
TRAPD(err, iEngine->StartPinEntryL(aBuffer));
LOG1(_L("Pin Notifier started with result %d"), err);
if(err != KErrNone)
{
aMessage.Complete(err);
iNeedToCompleteMessage = EFalse;
LEAVEL(err);
}
}
TPtrC8 CBTUIPinCodeEntry::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
return iEngine->UpdateL(aBuffer);
}
void CBTUIPinCodeEntry::MbpceoPinInputComplete(const TBTPinCode& aPin, TInt aReason)
{
LOG_FUNC
LOG1(_L("\taReason = %d"), aReason);
if (aReason == KErrNone)
{
TInt err = iMessage.Write(iReplySlot, aPin);
iMessage.Complete(err);
}
else
{
iMessage.Complete(aReason);
}
iNeedToCompleteMessage = EFalse;
}
#endif // __BT_TEXT_NOTIFIERS_NO_SSP__
CBTManPinNotifierEngine* CBTManPinNotifierEngine::NewL(MBTPinCodeEntryObserver& aObserver)
{
LOG_STATIC_FUNC
CBTManPinNotifierEngine* c = new (ELeave) CBTManPinNotifierEngine(aObserver);
CleanupStack::PushL(c);
c->ConstructL();
CleanupStack::Pop(c);
return c;
}
void CBTManPinNotifierEngine::ConstructL()
{
LOG_FUNC
}
void CBTManPinNotifierEngine::StartPinEntryL(const TDesC8& aBuffer)
{
LOG_FUNC
__ASSERT_DEBUG(((iHostResolverCacheProdder==NULL)&&(iGetPinFromConsole==NULL)), User::Panic(_L("BTPinProvider"), KErrGeneral));
__ASSERT_DEBUG(!IsActive(), User::Panic(_L("BTPinProvider"), KErrGeneral));
TBTPinCodeEntryNotifierParamsPckg pckg;
if(aBuffer.Length() != sizeof(TBTPinCodeEntryNotifierParams))
{
User::Leave(KErrArgument);
}
pckg.Copy(aBuffer);
iDeviceAddress = pckg().DeviceAddress();
iDeviceName = pckg().DeviceName();
iPasskeyMinLength = pckg().PinCodeMinLength();
iLocallyInitiated = pckg().LocallyInitiated();
iStrongKeyRequired = pckg().StrongPinCodeRequired();
iRecommendedPasskeyMinLength = pckg().RecommendedPinCodeMinLength();
DoStartPinEntryL();
}
void CBTManPinNotifierEngine::StartLegacyPinEntryL(const TDesC8& aBuffer)
{
LOG_FUNC
__ASSERT_DEBUG(((iHostResolverCacheProdder==NULL)&&(iGetPinFromConsole==NULL)), User::Panic(_L("BTPinProvider"), KErrGeneral));
__ASSERT_DEBUG(!IsActive(), User::Panic(_L("BTPinProvider"), KErrGeneral));
TBTPasskeyNotifierParamsPckg pckg;
if(aBuffer.Length() != sizeof(TBTPasskeyNotifierParams))
{
User::Leave(KErrArgument);
}
pckg.Copy(aBuffer);
iDeviceAddress = pckg().iBDAddr;
iDeviceName = pckg().iName;
iPasskeyMinLength = pckg().iPasskeyMinLength;
iLocallyInitiated = pckg().iLocallyInitiated;
iStrongKeyRequired = EFalse; // Cannot be signalled through legacy notifier.
DoStartPinEntryL();
}
void CBTManPinNotifierEngine::DoStartPinEntryL()
{
LOG_FUNC
if(iDevice == NULL)
{
iDevice = CBTDevice::NewL(iDeviceAddress);
FLOG(_L("RNot\tCBTManPinNotifierEngine::StartPinEntryL() - Create new CDevice"));
}
if (iDeviceName.Length()==0)
{
User::LeaveIfError(iRegistry.Connect());
User::LeaveIfError(iRegistryView.Open(iRegistry));
FLOG(_L("RNot\tPin Notifier looking for device in Registry"));
// let's try the Registry for a name
iRegistrySearch.FindAddress(iDeviceAddress);
iRegistryView.CreateView(iRegistrySearch, iStatus);
iRegistryState = EFinding;
SetActive();
}
else
{
//Just work with addresses and names
iDevice->SetDeviceNameL(BTDeviceNameConverter::ToUTF8L(iDeviceName));
//Ask Host Resolver Inquiry Cache for CoD
//DEF039276 Altered code - always try and get CoD
iHostResolverCacheProdder = CHostResolverCacheProdder::NewL(this);
iHostResolverCacheProdder->Start(iDeviceAddress);
iGetPinFromConsole = CBTGetPinFromConsole::NewL(this, *iDevice, iPasskeyMinLength, iLocallyInitiated, iStrongKeyRequired, iRecommendedPasskeyMinLength);
iGetPinFromConsole->GetPinL();
}
}
void CBTManPinNotifierEngine::RunL()
{
LOG_FUNC
if(iStatus == KErrNotFound)
{
FLOG(_L("Device not found in Registry (OK)"))
__ASSERT_DEBUG(iRegistryState == EFinding, User::Invariant());
// not to worry - just no name available for the UI
iDevice->SetDeviceAddress(iDeviceAddress);
iGetPinFromConsole = CBTGetPinFromConsole::NewL(this, *iDevice, iPasskeyMinLength, iLocallyInitiated, iStrongKeyRequired, iRecommendedPasskeyMinLength);
iGetPinFromConsole->GetPinL();
}
else if(iStatus >= KErrNone)
{
switch (iRegistryState)
{
case EFinding:
{
FLOG(_L("Device found in Registry - getting details"))
iResponse = CBTRegistryResponse::NewL(iRegistryView);
iResponse->Start(iStatus);
SetActive();
iRegistryState = EGetting;
}
break;
case EGetting:
{
FLOG(_L("Got device details, launching PIN console"))
iGetPinFromConsole = CBTGetPinFromConsole::NewL(this, *(iResponse->Results()[0]), iPasskeyMinLength, iLocallyInitiated, iStrongKeyRequired, iRecommendedPasskeyMinLength);
PerformNameUpdateL(KErrNone);
iGetPinFromConsole->GetPinL();
}
break;
}
}
}
void CBTManPinNotifierEngine::DoCancel()
{
LOG_FUNC
if (iHostResolverCacheProdder)
{
iHostResolverCacheProdder->Cancel();
delete iHostResolverCacheProdder;
iHostResolverCacheProdder = NULL;
}
iRegistryView.CancelRequest(iStatus);
if (iResponse)
{
iResponse->Cancel();
}
iGetPinFromConsole->Cancel();
}
CBTManPinNotifierEngine::~CBTManPinNotifierEngine()
{
LOG_FUNC
Cancel();
delete iHostResolverCacheProdder;
delete iGetPinFromConsole;
delete iDevice;
iRegistryView.Close();
iRegistry.Close();
}
void CBTManPinNotifierEngine::Stop()
{
LOG_FUNC
Cancel();
if (iGetPinFromConsole)
{
iGetPinFromConsole->Cancel();
delete iGetPinFromConsole;
iGetPinFromConsole = NULL;
}
if (iHostResolverCacheProdder)
{
iHostResolverCacheProdder->Cancel();
delete iHostResolverCacheProdder;
iHostResolverCacheProdder = NULL;
}
//clean up iDevice...
delete iDevice;
iDevice = NULL;
}
TPtrC8 CBTManPinNotifierEngine::LegacyUpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
TBTNotifierUpdateParamsPckg pckg;
pckg.Copy(aBuffer);
if(iDevice)
{
//we only want to do this if our device doesn't have a valid device name...
if (!iDevice->IsValidDeviceName())
{
iDeviceName = pckg().iName;
if(iGetPinFromConsole)
{
PerformNameUpdateL(pckg().iResult);
}
}
}
else
{
FLOG(_L("RNot\tCBTManPinNotifierEngine::UpdateL() called with iDevice == NULL"));
}
return KNullDesC8();
}
TPtrC8 CBTManPinNotifierEngine::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
TBTNotifierUpdateParamsPckg2 pckgRaw;
pckgRaw.Copy(aBuffer.Left(pckgRaw.MaxLength()));
// We only expect device name updates
if(pckgRaw().Type() != TBTNotifierUpdateParams2::EDeviceName)
{
User::Leave(KErrArgument);
}
TBTDeviceNameUpdateParamsPckg pckg;
pckg.Copy(aBuffer);
if(iDevice)
{
//we only want to do this if our device doesn't have a valid device name...
if(!iDevice->IsValidDeviceName())
{
iDeviceName = pckg().DeviceName();
if(iGetPinFromConsole)
{
PerformNameUpdateL(pckg().Result());
}
}
}
else
{
FLOG(_L("RNot\tCBTManPinNotifierEngine::UpdateL() called with iDevice == NULL"));
}
return KNullDesC8();
}
void CBTManPinNotifierEngine::PerformNameUpdateL(TInt aResult)
{
LOG_FUNC
iGetPinFromConsole->DeviceNameRetrieved(iDeviceName, aResult);
if(iDevice)
{
iDevice->SetDeviceNameL(BTDeviceNameConverter::ToUTF8L(iDeviceName));
}
else
{
FLOG(_L("RNot\tCBTManPinNotifierEngine::PerformNameUpdateL() called with iDevice == NULL"));
}
}
CBTManPinNotifierEngine::CBTManPinNotifierEngine(MBTPinCodeEntryObserver& aObserver)
: CActive(EPriorityStandard)
, iObserver(aObserver)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
void CBTManPinNotifierEngine::PinInputComplete(const TBTPinCode& aPin, TInt aReason)
{
LOG_FUNC
iObserver.MbpceoPinInputComplete(aPin, aReason);
delete iHostResolverCacheProdder;
iHostResolverCacheProdder = NULL;
delete iDevice;
iDevice = NULL;
delete iGetPinFromConsole;
iGetPinFromConsole = NULL;
}
void CBTManPinNotifierEngine::HostResolverCacheInfoReceived(const TNameEntry& aResult)
{
LOG_FUNC
__ASSERT_DEBUG(((iGetPinFromConsole!=NULL)), User::Panic(_L("BTPinProvider"), KErrGeneral));
TInquirySockAddr& sa = TInquirySockAddr::Cast(aResult().iAddr);
TBTDeviceClass deviceClass(sa.MajorServiceClass(), sa.MajorClassOfDevice(), sa.MinorClassOfDevice());
iGetPinFromConsole->CoDRetrieved(deviceClass);
}
//------------------------------------------------------------------------//
//Get CoD from HostResolver class
//------------------------------------------------------------------------//
CHostResolverCacheProdder* CHostResolverCacheProdder::NewL(CBTManPinNotifierEngine* aParent)
{
LOG_STATIC_FUNC
CHostResolverCacheProdder* self = CHostResolverCacheProdder::NewLC(aParent);
CleanupStack::Pop();
return self;
}
CHostResolverCacheProdder* CHostResolverCacheProdder::NewLC(CBTManPinNotifierEngine* aParent)
{
LOG_STATIC_FUNC
CHostResolverCacheProdder* self = new (ELeave) CHostResolverCacheProdder(aParent);
CleanupStack::PushL(self);
return self;
}
CHostResolverCacheProdder::~CHostResolverCacheProdder()
{
LOG_FUNC
Cancel();
}
CHostResolverCacheProdder::CHostResolverCacheProdder(CBTManPinNotifierEngine* aParent)
: CActive(EPriorityStandard), iParent(aParent)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
TInt CHostResolverCacheProdder::Start(const TBTDevAddr& aBDAddr)
{
LOG_FUNC
__ASSERT_DEBUG(!IsActive(), User::Panic(_L("HostResolverCacheProdder"), KErrGeneral));
FLOG(_L("RNot\tCHostResolverCacheProdder::Start"));
RSocketServ sockServer;
sockServer.Connect();
TProtocolDesc info;
/**/
TInt ret1 = sockServer.FindProtocol(_L("BTLinkManager"),info);
if(ret1!=KErrNone)
{
FTRACE(FPrint(_L("RNot\tFailure to find btlinkmanager - error %d"), ret1));
TInquirySockAddr& sa = TInquirySockAddr::Cast(iResult().iAddr);
sa.SetMajorServiceClass(0);
sa.SetMajorClassOfDevice(0);
sa.SetMinorClassOfDevice(0);
iParent->HostResolverCacheInfoReceived(iResult);
return ret1;
}
/**/
TInt ret = iHostResolver.Open(sockServer, KBTAddrFamily, KBTLinkManager);
iAddr.SetBTAddr(aBDAddr);
iAddr.SetIAC(KGIAC);
iAddr.SetAction(KHostResCache);
if(ret==KErrNone)
{
iHostResolver.GetByAddress(iAddr, iResult, iStatus);
SetActive();
}
return ret;
}
void CHostResolverCacheProdder::RunL()
{
LOG_FUNC
if (iStatus.Int() == KErrNone)
{
iHostResolver.Close();
iParent->HostResolverCacheInfoReceived(iResult);
}
else
{
FTRACE(FPrint(_L("RNot\tNo CoD returned from Host Resolver - error %d"), iStatus.Int()));
iHostResolver.Close();
}
}
//------------------------------------------------------------------------//
//Get pin from a console window class
//------------------------------------------------------------------------//
CBTGetPinFromConsole* CBTGetPinFromConsole::NewL(CBTManPinNotifierEngine* aParent, const CBTDevice& aDevice, TUint aPasskeyMinLength, TBool aInternallyInitiated, TBool aStrongKeyRequired, TUint aRecommendedPasskeyMinLength)
{
LOG_STATIC_FUNC
CBTGetPinFromConsole* self = new(ELeave) CBTGetPinFromConsole(aParent, aPasskeyMinLength, aInternallyInitiated, aStrongKeyRequired, aRecommendedPasskeyMinLength);
CleanupStack::PushL(self);
self->ConstructL(aDevice);
CleanupStack::Pop(self);
return self;
}
CBTGetPinFromConsole::CBTGetPinFromConsole(CBTManPinNotifierEngine* aParent, TUint aPasskeyMinLength, TBool aInternallyInitiated, TBool aStrongKeyRequired, TUint aRecommendedPasskeyMinLength)
: CActive(EPriorityStandard)
, iParent(aParent)
, iPasskeyMinLength(aPasskeyMinLength)
, iInternallyInitiated(aInternallyInitiated)
, iStrongKeyRequired(aStrongKeyRequired)
, iRecommendedPasskeyMinLength(aRecommendedPasskeyMinLength)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
void CBTGetPinFromConsole::ConstructL(const CBTDevice& aDevice)
{
LOG_FUNC
iConsole = BTTextNotifiersConsole::AutoSizeNewL(_L("PIN Input"), TSize(KConsFullScreen,KConsFullScreen));
iDevice = &aDevice;//.CopyL();
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
TCallBack autoNotifierCB(AutoNotifierCallBack, this);
iAutoNotifierCallback = new (ELeave)CAsyncCallBack(autoNotifierCB, EActiveMedPriority);
#endif // __BT_TEXT_NOTIFIERS_AUTO__
}
CBTGetPinFromConsole::~CBTGetPinFromConsole()
{
LOG_FUNC
Cancel();
delete iConsole;
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
delete iAutoNotifierCallback;
#endif
}
void CBTGetPinFromConsole::RunL()
{
LOG_FUNC
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
// Set pin to 1234
iPin().iPIN[0] = 0x31;
iPin().iPIN[1] = 0x32;
iPin().iPIN[2] = 0x33;
iPin().iPIN[3] = 0x34;
iPin().iLength = 4;
iParent->PinInputComplete(iPin, KErrNone);
#else // __BT_TEXT_NOTIFIERS_AUTO__
TKeyCode key = iConsole->KeyCode();
if (key == EKeyEnter)
{
if (iPin().iLength >= iPasskeyMinLength)
{
iParent->PinInputComplete(iPin, KErrNone);
}
else
{
iConsole->Printf(_L("\nToo short!...\nPress any key to continue\n"));
TRequestStatus stat;
iConsole->Read(stat);
User::WaitForRequest(stat);
GetPinL();
return;
}
}
else if (key == EKeyEscape)
{
iParent->PinInputComplete(iPin, KErrCancel);
}
else
{
if (iInsert < KHCIPINCodeSize)
{
TBuf<1> b;
b.Append(key);
iPin().iPIN[iInsert] = (TUint8)key;
iConsole->Printf(b);
iPin().iLength = (TUint8)++iInsert;
}
IssueRequestL();
/*
else
{
iConsole->Printf(_L("\nToo many characters...\nPress any key to continue\n"));
TRequestStatus stat;
iConsole->Read(stat);
User::WaitForRequest(stat);
GetPinL();
}
*/
}
#endif // __BT_TEXT_NOTIFIERS_AUTO__
}
void CBTGetPinFromConsole::DoCancel()
{
LOG_FUNC
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
iConsole->ReadCancel();
#endif
iConsole->Printf(_L("\nPin cancelled.\nPress any key to continue...\n"));
iPin.Zero();
}
void CBTGetPinFromConsole::GetPinL()
{
LOG_FUNC
iInsert = 0;
iConsole->ClearScreen();
iConsole->Printf(_L("Please enter pin for device:\nAddress: "));
TBTDevAddr a = iDevice->BDAddr();
iConsole->Printf(_L("0x%02x%02x%02x%02x%02x%02x"), a[0], a[1], a[2], a[3], a[4], a[5]);
if (iDevice->IsValidDeviceName())
{
TBTDeviceName dispBuf;
dispBuf.Copy(iDevice->DeviceName());
iConsole->Printf(_L("\nName: %S"), &dispBuf);
}
// check if PINCodeLength is set
if (0<iPasskeyMinLength && iPasskeyMinLength<=KHCIPINCodeSize)
{
iConsole->Printf(_L("\nRequired Minimal PIN code length: %d"), iPasskeyMinLength);
}
else
{
// set to 0 if we got some rubbish value...
iPasskeyMinLength=0;
}
//check if RecommendedPinCodeMinLength is set
if (0<iRecommendedPasskeyMinLength && iRecommendedPasskeyMinLength<=KHCIPINCodeSize)
{
iConsole->Printf(_L("\nRecommended Minimal PIN code length: %d"), iRecommendedPasskeyMinLength);
}
else
{
// set to 0 if we got some rubbish value...
iRecommendedPasskeyMinLength=0;
}
if(iInternallyInitiated)
{
iConsole->Printf(_L("\nInternally initiated authentication."));
}
else
{
iConsole->Printf(_L("\nRemote side initiated the authentication."));
}
if(iStrongKeyRequired)
{
iConsole->Printf(_L("\n!!! Strong PIN Code Required !!!"));
}
iConsole->Printf(_L("\nand press [return] to accept or [esc] to cancel\n"));
IssueRequestL();
}
void CBTGetPinFromConsole::IssueRequestL()
{
LOG_FUNC
__ASSERT_DEBUG(!IsActive(), User::Panic(_L("BTGetPinFromConsole"), KErrGeneral));
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
iAutoNotifierCallback->CallBack();
iStatus = KRequestPending;
#else //__BT_TEXT_NOTIFIERS_AUTO__
iConsole->Read(iStatus);
#endif // __BT_TEXT_NOTIFIERS_AUTO__
SetActive();
}
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
/*static*/ TInt CBTGetPinFromConsole::AutoNotifierCallBack(TAny *aConsolePin)
{
LOG_STATIC_FUNC
CBTGetAuthFromConsole* consolePin = static_cast<CBTGetAuthFromConsole*>(aConsolePin);
if(consolePin->IsActive())
{
TRequestStatus* stat = &(consolePin->iStatus);
User::RequestComplete(stat, KErrNone);
}
return EFalse;
}
#endif // __BT_TEXT_NOTIFIERS_AUTO__
void CBTGetPinFromConsole::DeviceNameRetrieved(const TPtrC aName, TInt aResult)
{
LOG_FUNC
iConsole->Printf(_L("\nDevice Name Retrieved (code %d): \n"), aResult);
iConsole->Printf(aName);
#ifdef _DEBUG
iConsole->Printf(_L("\n"));
#endif
}
void CBTGetPinFromConsole::CoDRetrieved(TBTDeviceClass& aCoD)
{
LOG_FUNC
iConsole->Printf(_L("CoD Retrieved (MajorS MajorD MinorD):"));
iConsole->Printf(_L("\t0x%04x 0x%02x 0x%02x\n"),
aCoD.MajorServiceClass(),
aCoD.MajorDeviceClass(),
aCoD.MinorDeviceClass()
);
}
//
// CBTManAuthNotifier
//
void CBTManAuthNotifier::Release()
{
LOG_FUNC
Cancel();
delete this;
}
CBTManAuthNotifier::TNotifierInfo CBTManAuthNotifier::RegisterL()
{
LOG_FUNC
iInfo.iUid=KBTManAuthNotifierUid;
iInfo.iChannel=KScreenOutputChannel;
iInfo.iPriority=ENotifierPriorityVHigh;
return iInfo;
}
CBTManAuthNotifier::TNotifierInfo CBTManAuthNotifier::Info() const
{
LOG_FUNC
return iInfo;
}
TPtrC8 CBTManAuthNotifier::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTManAuthNotifier::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
iReplySlot = aReplySlot;
iMessage = RMessage2(aMessage);
iNeedToCompleteMessage = ETrue;
TRAPD(err, iEngine->StartAuthorisationL(aBuffer));
if (err)
{
FLOG(_L("RNot\t** could not StartAuthorisation **"));
aMessage.Complete(err);
iNeedToCompleteMessage = EFalse;
User::Leave(err);
}
else
{
FLOG(_L("RNot\tCBTManAuthNotifier - Started authorisation OK"));
}
}
CBTManAuthNotifier::~CBTManAuthNotifier()
{
LOG_FUNC
delete iEngine;
}
void CBTManAuthNotifier::Cancel()
{
LOG_FUNC
iEngine->Stop();
if (iNeedToCompleteMessage)
{
iMessage.Complete(KErrCancel);
iNeedToCompleteMessage = EFalse;
}
}
TPtrC8 CBTManAuthNotifier::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
return iEngine->UpdateL(aBuffer);
}
void CBTManAuthNotifier::AuthorisationComplete(TBool aDecision, TInt aReason)
{
LOG_FUNC
if (aReason == KErrNone)
{
FTRACE(FPrint(_L("RNot\tCBTManAuthNotifier::AuthorisationComplete(TBool=%d)"), aDecision));
TInt err = iMessage.Write(iReplySlot, TPckgC<TBool>(aDecision));
iMessage.Complete(err);
}
else
{
FTRACE(FPrint(_L("RNot\tCBTManAuthNotifier::AuthorisationComplete(ERROR=%d)"), aReason));
iMessage.Complete(aReason);
}
iNeedToCompleteMessage = EFalse;
}
CBTManAuthNotifier* CBTManAuthNotifier::NewLC()
{
LOG_STATIC_FUNC
CBTManAuthNotifier* self=new (ELeave) CBTManAuthNotifier();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CBTManAuthNotifier::ConstructL()
{
LOG_FUNC
iEngine = CBTManAuthNotifierEngine::NewL(*this);
}
CBTManAuthNotifierEngine::CBTManAuthNotifierEngine(CBTManAuthNotifier& aParent)
: CActive(EPriorityStandard), iParent(aParent)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
//
// CBTManAuthNotifierEngine
//
CBTManAuthNotifierEngine* CBTManAuthNotifierEngine::NewL(CBTManAuthNotifier& aParent)
{
LOG_STATIC_FUNC
CBTManAuthNotifierEngine* self=new (ELeave) CBTManAuthNotifierEngine(aParent);
return self;
}
void CBTManAuthNotifierEngine::Stop()
{
LOG_FUNC
Cancel();
if (iGetAuthFromConsole)
{
FLOG(_L("RNot\tCancelling authorisation console..."))
iGetAuthFromConsole->Cancel();
delete iGetAuthFromConsole;
iGetAuthFromConsole = NULL;
}
//clean up iDevice...
delete iDevice;
iDevice = NULL;
}
void CBTManAuthNotifierEngine::DoCancel()
{
LOG_FUNC
iRegistryView.CancelRequest(iStatus);
if (iResponse)
{
iResponse->Cancel();
}
}
CBTManAuthNotifierEngine::~CBTManAuthNotifierEngine()
{
LOG_FUNC
Cancel();
delete iGetAuthFromConsole;
iRegistryView.Close();
iRegistry.Close();
}
void CBTManAuthNotifierEngine::AuthorisationComplete(TBool aDecision, TInt aReason)
{
LOG_FUNC
iParent.AuthorisationComplete(aDecision, aReason);
delete iGetAuthFromConsole;
iGetAuthFromConsole = NULL;
delete iDevice;
iDevice = NULL;
}
TPtrC8 CBTManAuthNotifierEngine::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
if (iGetAuthFromConsole)
{
if (!iDevice)
{
iDevice = CBTDevice::NewL();
}
//we only want to do this if our device doesn't have a valid device name...
if (!iDevice->IsValidDeviceName())
{
TBTNotifierUpdateParams params;
TPckgC<TBTNotifierUpdateParams> pckg(params);
pckg.Set(aBuffer);
iGetAuthFromConsole->DeviceNameRetrieved(pckg().iName, pckg().iResult);
iDevice->SetDeviceNameL(BTDeviceNameConverter::ToUTF8L(pckg().iName));
}
}
return KNullDesC8();
}
void CBTManAuthNotifierEngine::StartAuthorisationL(const TDesC8& aBuffer)
{
LOG_FUNC
// __ASSERT_DEBUG(((iGetAuthFromConsole==NULL)&&(iDevice==NULL)&&(iDeviceFromRegistry==NULL)), User::Panic(_L("BTAuthProvider"), KErrGeneral));
__ASSERT_DEBUG(!IsActive(), User::Panic(_L("BTAuthProvider"), KErrGeneral));
iAuthPckg.Copy(aBuffer);
TBTDeviceName name = iAuthPckg().iName;
if (name.Length()==0)
{
// Find the device - need to get the full details for the name, so do a search
FTRACE(FPrint(_L("RNot\tStarting authorisation...")));
User::LeaveIfError(iRegistry.Connect());
User::LeaveIfError(iRegistryView.Open(iRegistry));
iRegistrySearch.FindAddress(iAuthPckg().iBDAddr);
iRegistryView.CreateView(iRegistrySearch, iStatus);
iRegistryState = EFinding;
SetActive();
}
else
{
// create our dummy device (didn't really need this could just work with addresses and names!)
delete iDevice;
iDevice = NULL;
iDevice = CBTDevice::NewL(iAuthPckg().iBDAddr);
iDevice->SetDeviceNameL(BTDeviceNameConverter::ToUTF8L(name));
iGetAuthFromConsole = CBTGetAuthFromConsole::NewL(this, *iDevice, iAuthPckg().iUid);
iGetAuthFromConsole->AuthoriseL();
}
}
void CBTManAuthNotifierEngine::RunL()
{
LOG_FUNC
if (iStatus >= KErrNone)
{
switch (iRegistryState)
{
case EFinding:
{
// search has completed, get the resultset
FLOG(_L("RNot\tCBTManAuthNotifier: Found device"))
iResponse = CBTRegistryResponse::NewL(iRegistryView);
iResponse->Start(iStatus);
iRegistryState = EGetting;
SetActive();
}
break;
case EGetting:
{
// got the details, now launch the authorisor console
FLOG(_L("RNot\tCBTManAuthNotifier: Got device details"))
iGetAuthFromConsole = CBTGetAuthFromConsole::NewL(this, *(iResponse->Results()[0]), iAuthPckg().iUid);
iGetAuthFromConsole->AuthoriseL();
delete iResponse;
iResponse = NULL;
}
break;
}
}
else if (iStatus == KErrNotFound)
{
__ASSERT_DEBUG(iRegistryState == EFinding, User::Invariant());
FLOG(_L("RNot\tCBTManAuthNotifier: Device not in Registry (OK)"))
// not to worry - the device isn't in the Registry
// although strictly speaking we should only Authorise an Authenticated device
// which means it *should* be in the Registry.
// however we do allow authorisation of unauthenticated devices at BT level
// so we don't have a name at this point, but not to worry
CBTDevice* device = CBTDevice::NewLC(iAuthPckg().iBDAddr);
iGetAuthFromConsole = CBTGetAuthFromConsole::NewL(this, *device, iAuthPckg().iUid);
iGetAuthFromConsole->AuthoriseL();
CleanupStack::PopAndDestroy(device);
}
else
{
User::Invariant();
}
}
//------------------------------------------------------------------------//
//Get Auth from a console window class
//------------------------------------------------------------------------//
CBTGetAuthFromConsole* CBTGetAuthFromConsole::NewL(CBTManAuthNotifierEngine* aParent,
const CBTDevice& aDevice, TUid aUid)
{
LOG_STATIC_FUNC
CBTGetAuthFromConsole* s = CBTGetAuthFromConsole::NewLC(aParent, aDevice, aUid);
CleanupStack::Pop();
return s;
}
CBTGetAuthFromConsole* CBTGetAuthFromConsole::NewLC(CBTManAuthNotifierEngine* aParent,
const CBTDevice& aDevice, TUid aUid)
{
LOG_STATIC_FUNC
CBTGetAuthFromConsole* s = new(ELeave) CBTGetAuthFromConsole(aParent);
CleanupStack::PushL(s);
s->ConstructL(aDevice, aUid);
return s;
}
CBTGetAuthFromConsole::~CBTGetAuthFromConsole()
{
LOG_FUNC
Cancel();
delete iConsole;
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
delete iAutoNotifierCallback;
#endif
}
void CBTGetAuthFromConsole::RunL()
{
LOG_FUNC
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
iParent->AuthorisationComplete(ETrue, KErrNone);
#else // __BT_TEXT_NOTIFIERS_AUTO__
TKeyCode key = iConsole->KeyCode();
if (key == 'y')
{
iParent->AuthorisationComplete(ETrue, KErrNone);
}
else if (key == 'n')
{
iParent->AuthorisationComplete(EFalse, KErrNone);
}
else
{
iConsole->Printf(_L("\nStop being a muppet and press 'y' or 'n'\n"));
IssueRequest();
}
#endif // __BT_TEXT_NOTIFIERS_AUTO__
}
void CBTGetAuthFromConsole::DoCancel()
{
LOG_FUNC
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
FLOG(_L("RNot\tCBTGetAuthFromConsole::DoCancel()"))
iConsole->ReadCancel();
#endif
}
CBTGetAuthFromConsole::CBTGetAuthFromConsole(CBTManAuthNotifierEngine* aParent) :
CActive(EPriorityStandard), iParent(aParent)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
void CBTGetAuthFromConsole::ConstructL(const CBTDevice& aDevice, TUid aUid)
{
LOG_FUNC
iConsole = BTTextNotifiersConsole::AutoSizeNewL(_L("Authorisor"), TSize(KConsFullScreen,KConsFullScreen));
iDevice = &aDevice;
iServiceUid = aUid;
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
TCallBack autoNotifierCB(AutoNotifierCallBack, this);
iAutoNotifierCallback = new (ELeave)CAsyncCallBack(autoNotifierCB, EActiveMedPriority);
#endif // __BT_TEXT_NOTIFIERS_AUTO__
}
void CBTGetAuthFromConsole::AuthoriseL()
{
LOG_FUNC
iConsole->ClearScreen();
iConsole->Printf(_L("Can the following device:\nAddress: "));
TBTDevAddr a = iDevice->BDAddr();
iConsole->Printf(_L("0x%02x%02x%02x%02x%02x%02x"), a[0], a[1], a[2], a[3], a[4], a[5]);
if (iDevice->IsValidDeviceName())
{
iConsole->Printf(_L("\nName: "));
THostName dispBuf;
dispBuf.Copy(iDevice->DeviceName());
iConsole->Printf(dispBuf);
}
else
{
iConsole->Printf(_L("\n<No name>"));
}
iConsole->Printf(_L("\nuse the following service\nService Uid = 0x%08x\n[y/n]"), iServiceUid.iUid);
IssueRequest();
}
void CBTGetAuthFromConsole::IssueRequest()
{
LOG_FUNC
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
iAutoNotifierCallback->CallBack();
iStatus = KRequestPending;
#else //__BT_TEXT_NOTIFIERS_AUTO__
iConsole->Read(iStatus);
#endif // __BT_TEXT_NOTIFIERS_AUTO__
SetActive();
}
#ifdef __BT_TEXT_NOTIFIERS_AUTO__
/*static*/ TInt CBTGetAuthFromConsole::AutoNotifierCallBack(TAny *aConsoleAuth)
{
LOG_STATIC_FUNC
CBTGetAuthFromConsole* consoleAuth = static_cast<CBTGetAuthFromConsole*>(aConsoleAuth);
if(consoleAuth->IsActive())
{
TRequestStatus* stat = &(consoleAuth->iStatus);
User::RequestComplete(stat, KErrNone);
}
return EFalse;
}
#endif // __BT_TEXT_NOTIFIERS_AUTO__
void CBTGetAuthFromConsole::DeviceNameRetrieved(const TDesC& aName, TInt aResult)
{
LOG_FUNC
iConsole->Printf(_L("\nDevice Name Retrieved (code %d): "), aResult);
iConsole->Printf(aName);
iConsole->Printf(_L("\n"));
}
//
// CBTManDeviceSelectionNotifier
//
void CBTManDeviceSelectionNotifier::Release()
{
LOG_FUNC
delete this;
}
CBTManDeviceSelectionNotifier::TNotifierInfo CBTManDeviceSelectionNotifier::RegisterL()
{
LOG_FUNC
iInfo.iUid=KDeviceSelectionNotifierUid;
iInfo.iChannel=KScreenOutputChannel;
iInfo.iPriority=ENotifierPriorityVLow;
return iInfo;
}
CBTManDeviceSelectionNotifier::TNotifierInfo CBTManDeviceSelectionNotifier::Info() const
{
LOG_FUNC
return iInfo;
}
TPtrC8 CBTManDeviceSelectionNotifier::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTManDeviceSelectionNotifier::StartL(const TDesC8& /*aBuffer*/, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
CBTManDeviceScanner* scanner = CBTManDeviceScanner::NewL();
CleanupStack::PushL(scanner);
TKeyCode choice = GetResponseL(_L("Press 'm' to enter a devaddr,\nANY OTHER KEY for general inquiry \nfor discoverable devices."), KConsFullScreen, 3);
TInt err = 0;
TBTDeviceResponseParamsPckg pckg;
if(choice=='m'||choice=='M')
{
TRAP(err, GetAddressL(iBDAddr));
}
else
{
TRAP(err, scanner->GetByScanL(iBDAddr, iName, iClass));
}
if(err)
{
DisplayErrorMessageL();
}
else
{
pckg().SetDeviceAddress(iBDAddr);
// pckg().SetDeviceName(iName);
pckg().SetDeviceClass(iClass);
/*TInt err = */aMessage.Write(aReplySlot, pckg);
}
aMessage.Complete(err);
CleanupStack::PopAndDestroy();
return;
}
CBTManDeviceSelectionNotifier::~CBTManDeviceSelectionNotifier()
{
LOG_FUNC
}
void CBTManDeviceSelectionNotifier::Cancel()
{
LOG_FUNC
}
TPtrC8 CBTManDeviceSelectionNotifier::UpdateL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The UpdateL is not supported."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
CBTManDeviceSelectionNotifier* CBTManDeviceSelectionNotifier::NewLC()
{
LOG_STATIC_FUNC
CBTManDeviceSelectionNotifier* self=new (ELeave) CBTManDeviceSelectionNotifier();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
CBTManDeviceSelectionNotifier::CBTManDeviceSelectionNotifier()
{
LOG_FUNC
}
void CBTManDeviceSelectionNotifier::ConstructL()
{
LOG_FUNC
}
TKeyCode CBTManDeviceSelectionNotifier::GetResponseL(TRefByValue<const TDesC> aPrompt, TInt aWidth, TInt aHeight)
{
LOG_FUNC
CConsoleBase* console = BTTextNotifiersConsole::AutoSizeNewL(_L("Device Selector"), TSize(aWidth,aHeight));
CleanupStack::PushL(console);
console->Printf(aPrompt);
TKeyCode ret = console->Getch();
CleanupStack::PopAndDestroy();
return ret;
}
void CBTManDeviceSelectionNotifier::GetAddressL(TBTDevAddr& aBDAddr)
{
LOG_FUNC
TBuf<12> addrAsText;
addrAsText.Zero();
if (aBDAddr != TBTDevAddr(0))
addrAsText.Format(_L("%02x%02x%02x%02x%02x%02x"),
aBDAddr[0], aBDAddr[1], aBDAddr[2], aBDAddr[3], aBDAddr[4], aBDAddr[5]);
CConsoleBase* console = BTTextNotifiersConsole::AutoSizeNewL(_L("Device Selector"), TSize(KConsFullScreen,6));
CleanupStack::PushL(console);
TKeyCode code;
TBuf<1> character;
console->Printf(_L("Enter a device address:\n\n 0x"));
if (addrAsText.Length()>0)
console->Printf(addrAsText);
FOREVER
{
code = console->Getch();
character.SetLength(0);
character.Append(code);
// If <CR> finish editing string
if (code == 0x0d)
break;
// if <BS> remove last character
if ((code == 0x08)&&(addrAsText.Length() != 0))
{
console->Printf(_L("%S"),&character);
addrAsText.SetLength((addrAsText.Length()-1));
}
else
{
if (addrAsText.Length() < addrAsText.MaxLength())
{
console->Printf(_L("%S"),&character);
addrAsText.Append(code);
}
}
}
//now extract the new address from the string...
if(!(addrAsText.Length()))
addrAsText.Append('0'); //null string causes TLex::Val to return an error
TLex lex(addrAsText);
TInt64 addrAsInt64 = 0;
TInt err = lex.Val(addrAsInt64, EHex);
User::LeaveIfError(err);
aBDAddr = TBTDevAddr(addrAsInt64);
CleanupStack::PopAndDestroy();//console
}
void CBTManDeviceSelectionNotifier::GetNameL(TBTDeviceName& aName)
{
LOG_FUNC
CConsoleBase* console = BTTextNotifiersConsole::AutoSizeNewL(_L("Device Selector"), TSize(KConsFullScreen,6));
CleanupStack::PushL(console);
TKeyCode code;
TBuf<1> character;
console->Printf(_L("Enter a device name:\n\n "));
if (aName.Length()>0)
{
THostName dispBuf;
dispBuf.Copy(aName);
console->Printf(dispBuf);
}
FOREVER
{
code = console->Getch();
character.SetLength(0);
character.Append(code);
// If <CR> finish editing string
if (code == 0x0d)
break;
// if <BS> remove last character
if ((code == 0x08)&&(aName.Length() != 0))
{
console->Printf(_L("%S"),&character);
aName.SetLength((aName.Length()-1));
}
else
{
if (aName.Length() < aName.MaxLength())
{
console->Printf(_L("%S"),&character);
aName.Append(code);
}
}
}
CleanupStack::PopAndDestroy();//console
}
void CBTManDeviceSelectionNotifier::DisplayErrorMessageL()
{
LOG_FUNC
CConsoleBase* console = 0;
TRAPD(err, console = BTTextNotifiersConsole::AutoSizeNewL(_L("Error!"), TSize(KConsFullScreen,4)));
if(err)
return;
CleanupStack::PushL(console);
// console->Printf(_L("Sorry! An error has occurred whilst the last\npiece of data was being entered.\n\nPress any key, and then re-enter ALL data."));
console->Printf(_L("Sorry! An error has occurred. No new device\nselection has been recorded.\n\nPress any key."));
// TKeyCode code;
(void) console->Getch();
CleanupStack::PopAndDestroy();//console
}
// | |
// | Secure Simple Pairing Notifiers |
// v v
#ifndef __BT_TEXT_NOTIFIERS_NO_SSP__
CBTUINumericComparison* CBTUINumericComparison::NewLC()
{
LOG_STATIC_FUNC
CBTUINumericComparison* self=new (ELeave) CBTUINumericComparison();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CBTUINumericComparison::ConstructL()
{
LOG_FUNC
iEngine = CBTUINumericComparisonEngine::NewL(*this);
}
CBTUINumericComparison::~CBTUINumericComparison()
{
LOG_FUNC
delete iEngine;
}
void CBTUINumericComparison::Release()
{
LOG_FUNC
Cancel();
delete this;
}
CBTUINumericComparison::TNotifierInfo CBTUINumericComparison::RegisterL()
{
LOG_FUNC
iInfo.iUid=KBTNumericComparisonNotifierUid;
iInfo.iChannel=KScreenOutputChannel;
iInfo.iPriority=ENotifierPriorityVHigh;
return iInfo;
}
CBTUINumericComparison::TNotifierInfo CBTUINumericComparison::Info() const
{
LOG_FUNC
return iInfo;
}
void CBTUINumericComparison::Cancel()
{
LOG_FUNC
iEngine->Stop();
if (iNeedToCompleteMessage)
{
iMessage.Complete(KErrCancel);
iNeedToCompleteMessage = EFalse;
}
}
TPtrC8 CBTUINumericComparison::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
return iEngine->UpdateL(aBuffer);
}
TPtrC8 CBTUINumericComparison::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTUINumericComparison::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
iReplySlot = aReplySlot;
iMessage = RMessage2(aMessage);
iNumericComparisonParamsPckg.Copy(aBuffer);
iNeedToCompleteMessage = ETrue;
TRAPD(err, iEngine->DoComparisonL(iNumericComparisonParamsPckg()));
if (err)
{
FLOG(_L("\t** TRAPD error - DoComparisonL() **"));
aMessage.Complete(err);
iNeedToCompleteMessage = EFalse;
User::Leave(err);
}
}
void CBTUINumericComparison::NumericComparisonComplete(TBool aDecision, TInt aReason)
{
LOG_FUNC
if (aReason == KErrNone)
{
FTRACE(FPrint(_L("\tCBTUINumericComparison::NumericComparisonComplete(TBool=%d)"), aDecision));
TInt err = iMessage.Write(iReplySlot, TPckgC<TBool>(aDecision));
iMessage.Complete(err);
}
else
{
FTRACE(FPrint(_L("\tCBTUINumericComparison::NumericComparisonComplete(ERROR=%d)"), aReason));
iMessage.Complete(aReason);
}
iNeedToCompleteMessage = EFalse;
}
//------------------------------------------------------------------------//
// Do the numeric comparison...
//------------------------------------------------------------------------//
CBTUINumericComparisonEngine* CBTUINumericComparisonEngine::NewL(MBTGetNCResultFromConsoleObserver& aObserver)
{
LOG_STATIC_FUNC
CBTUINumericComparisonEngine* s = CBTUINumericComparisonEngine::NewLC(aObserver);
CleanupStack::Pop();
return s;
}
CBTUINumericComparisonEngine* CBTUINumericComparisonEngine::NewLC(MBTGetNCResultFromConsoleObserver& aObserver)
{
LOG_STATIC_FUNC
CBTUINumericComparisonEngine* s = new(ELeave) CBTUINumericComparisonEngine(aObserver);
CleanupStack::PushL(s);
s->ConstructL();
return s;
}
CBTUINumericComparisonEngine::CBTUINumericComparisonEngine(MBTGetNCResultFromConsoleObserver& aObserver) :
CActive(EPriorityStandard), iObserver(aObserver), iConsole(NULL)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
void CBTUINumericComparisonEngine::ConstructL()
{
LOG_FUNC
}
CBTUINumericComparisonEngine::~CBTUINumericComparisonEngine()
{
LOG_FUNC
Cancel();
delete iConsole;
}
void CBTUINumericComparisonEngine::DoComparisonL(TBTNumericComparisonParams& aNumericComparisonParams)
{
LOG_FUNC
if(iConsole==NULL)
{
iConsole = BTTextNotifiersConsole::AutoSizeNewL(_L("Numeric Comparison"), TSize(KConsFullScreen,KConsFullScreen));
}
iConsole->ClearScreen();
if(aNumericComparisonParams.LocallyInitiated())
{
iConsole->Printf(_L("\nLocally initiated Numeric Comparision \n"));
}
else
{
iConsole->Printf(_L("\nRemote initiated the Numeric Comparision \n"));
}
iConsole->Printf(_L("\nNumeric value to compare: %06d\n\n"), aNumericComparisonParams.NumericalValue());
iConsole->Printf(_L("Numbers should be displayed on local and remote device.\n"));
switch(aNumericComparisonParams.ComparisonScenario())
{
case TBTNumericComparisonParams::ERemoteCannotConfirm:
iConsole->Printf(_L("N.B. The remote device HOWEVER cannot receive input.\n"));
break;
case TBTNumericComparisonParams::ERemoteCanConfirm:
iConsole->Printf(_L("N.B. The remote device will ALSO expect input.\n"));
break;
default:
__ASSERT_DEBUG(EFalse, User::Panic(_L("CBTUINumericComparisonEngine"), KErrArgument));
break;
}
iConsole->Printf(_L("Please compare the numbers now.\n"));
iConsole->Printf(_L("\n\nDo the numbers match?[y/n]"));
IssueRequest();
}
TPtrC8 CBTUINumericComparisonEngine::UpdateL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
// need something to update the name
return KNullDesC8();
}
void CBTUINumericComparisonEngine::Stop()
{
LOG_FUNC
Cancel();
delete iConsole;
iConsole = NULL;
}
void CBTUINumericComparisonEngine::IssueRequest()
{
LOG_FUNC
iConsole->Read(iStatus);
SetActive();
}
void CBTUINumericComparisonEngine::RunL()
{
LOG_FUNC
TKeyCode key = iConsole->KeyCode();
if (key == 'y')
{
iObserver.NumericComparisonComplete(ETrue, KErrNone);
delete iConsole;
iConsole=NULL;
}
else if (key == 'n')
{
iObserver.NumericComparisonComplete(EFalse, KErrNone);
delete iConsole;
iConsole=NULL;
}
else
{
iConsole->Printf(_L("\nInvalid key pressed! Press 'y' or 'n'\n"));
IssueRequest();
}
}
void CBTUINumericComparisonEngine::DoCancel()
{
LOG_FUNC
if (iConsole)
{
iConsole->ReadCancel();
}
}
//
// CBTUIPasskeyEntry
//
CBTUIPasskeyEntry* CBTUIPasskeyEntry::NewLC()
{
LOG_STATIC_FUNC
CBTUIPasskeyEntry* self = new (ELeave) CBTUIPasskeyEntry();
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
void CBTUIPasskeyEntry::ConstructL()
{
LOG_FUNC
iEngine = CBTUIPasskeyEntryEngine::NewL(*this);
}
CBTUIPasskeyEntry::~CBTUIPasskeyEntry()
{
LOG_FUNC
delete iEngine;
}
void CBTUIPasskeyEntry::Release()
{
LOG_FUNC
Cancel();
delete this;
}
CBTUIPasskeyEntry::TNotifierInfo CBTUIPasskeyEntry::RegisterL()
{
LOG_FUNC
iInfo.iUid=KBTPasskeyDisplayNotifierUid;
iInfo.iChannel=KScreenOutputChannel;
iInfo.iPriority=ENotifierPriorityVHigh;
return iInfo;
}
CBTUIPasskeyEntry::TNotifierInfo CBTUIPasskeyEntry::Info() const
{
LOG_FUNC
return iInfo;
}
void CBTUIPasskeyEntry::Cancel()
{
LOG_FUNC
iEngine->Stop();
if (iNeedToCompleteMessage)
{
iMessage.Complete(KErrCancel);
iNeedToCompleteMessage = EFalse;
}
}
TPtrC8 CBTUIPasskeyEntry::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
return iEngine->UpdateL(aBuffer);
}
TPtrC8 CBTUIPasskeyEntry::StartL(const TDesC8& /*aBuffer*/)
{
LOG_FUNC
LOG(_L("The synchronous StartL overload is not used."))
LEAVEL(KErrNotSupported);
return KNullDesC8();
}
void CBTUIPasskeyEntry::StartL(const TDesC8& aBuffer, TInt aReplySlot, const RMessagePtr2& aMessage)
{
LOG_FUNC
iReplySlot = aReplySlot;
iMessage = RMessage2(aMessage);
iPasskeyDisplayParamsPckg.Copy(aBuffer);
iAddr = iPasskeyDisplayParamsPckg().DeviceAddress();
iName = iPasskeyDisplayParamsPckg().DeviceName();
iNumericValue = iPasskeyDisplayParamsPckg().NumericalValue();
iNeedToCompleteMessage = ETrue;
TRAPD(err, iEngine->DoPasskeyL(iPasskeyDisplayParamsPckg()));
if (err)
{
FLOG(_L("\t** TRAPD error - DoComparisonL() **"));
aMessage.Complete(err);
iNeedToCompleteMessage = EFalse;
User::Leave(err);
}
}
void CBTUIPasskeyEntry::PasskeyComplete(TInt aReason)
{
LOG_FUNC
LOG1(_L("\taReason = %d"), aReason)
iMessage.Complete(aReason);
iNeedToCompleteMessage = EFalse;
}
//
// CBTUIPasskeyEntryEngine
//
CBTUIPasskeyEntryEngine* CBTUIPasskeyEntryEngine::NewL(MBTGetPasskeyResultFromConsoleObserver& aObserver)
{
LOG_STATIC_FUNC
CBTUIPasskeyEntryEngine* s = CBTUIPasskeyEntryEngine::NewLC(aObserver);
CleanupStack::Pop();
return s;
}
CBTUIPasskeyEntryEngine* CBTUIPasskeyEntryEngine::NewLC(MBTGetPasskeyResultFromConsoleObserver& aObserver)
{
LOG_STATIC_FUNC
CBTUIPasskeyEntryEngine* s = new(ELeave) CBTUIPasskeyEntryEngine(aObserver);
CleanupStack::PushL(s);
s->ConstructL();
return s;
}
CBTUIPasskeyEntryEngine::CBTUIPasskeyEntryEngine(MBTGetPasskeyResultFromConsoleObserver& aObserver) :
CActive(EPriorityStandard), iObserver(aObserver), iConsole(NULL)
{
LOG_FUNC
CActiveScheduler::Add(this);
}
void CBTUIPasskeyEntryEngine::ConstructL()
{
LOG_FUNC
}
CBTUIPasskeyEntryEngine::~CBTUIPasskeyEntryEngine()
{
LOG_FUNC
Cancel();
delete iConsole;
}
void CBTUIPasskeyEntryEngine::DoPasskeyL(TBTPasskeyDisplayParams& aPasskeyParams)
{
LOG_FUNC
if(iConsole==NULL)
{
iConsole = BTTextNotifiersConsole::AutoSizeNewL(_L("Numeric Comparison"), TSize(KConsFullScreen,KConsFullScreen));
}
if(aPasskeyParams.LocallyInitiated())
{
iConsole->Printf(_L("\nLocally initiated Authentication \n"));
}
else
{
iConsole->Printf(_L("\nRemote initiated the Authentication \n"));
}
iConsole->ClearScreen();
iConsole->Printf(_L("\nEnter the following number on the remote device: %06d\n\n"), aPasskeyParams.NumericalValue());
iConsole->Printf(_L("Press [ESC] to cancel.\n"));
IssueRequest();
}
TPtrC8 CBTUIPasskeyEntryEngine::UpdateL(const TDesC8& aBuffer)
{
LOG_FUNC
TBTNotifierUpdateParamsPckg2 pckgRaw;
pckgRaw.Copy(aBuffer.Left(pckgRaw.MaxLength()));
if (iConsole)
{
if (pckgRaw().Type() == TBTNotifierUpdateParams2::EPasskeyDisplay)
{
TBTPasskeyDisplayUpdateParamsPckg pckg;
pckg.Copy(aBuffer);
THCIPasskeyEntryNotificationType keypressNotification = pckg().KeypressNotification();
switch (keypressNotification)
{
case EPasskeyEntryStarted:
{
break;
}
case EPasskeyDigitEntered:
{
iConsole->Write(_L("*"));
break;
}
case EPasskeyDigitDeleted:
{
TInt xPos = iConsole->WhereX();
if (xPos > 0)
{
iConsole->SetPos(xPos - 1);
}
iConsole->ClearToEndOfLine();
break;
}
case EPasskeyCleared:
{
iConsole->SetPos(0);
iConsole->ClearToEndOfLine();
break;
}
case EPasskeyEntryCompleted:
{
Cancel();
iObserver.PasskeyComplete(KErrNone);
delete iConsole;
iConsole=NULL;
break;
}
}
}
else if(pckgRaw().Type() == TBTNotifierUpdateParams2::EDeviceName)
{
// handle the name update
}
}
return KNullDesC8();
}
void CBTUIPasskeyEntryEngine::Stop()
{
LOG_FUNC
Cancel();
delete iConsole;
iConsole=NULL;
}
void CBTUIPasskeyEntryEngine::IssueRequest()
{
LOG_FUNC
iConsole->Read(iStatus);
SetActive();
}
void CBTUIPasskeyEntryEngine::RunL()
{
LOG_FUNC
TKeyCode key = iConsole->KeyCode();
if (key == EKeyEscape)
{
iObserver.PasskeyComplete(KErrCancel);
delete iConsole;
iConsole=NULL;
}
else
{
IssueRequest();
}
}
void CBTUIPasskeyEntryEngine::DoCancel()
{
LOG_FUNC
if (iConsole)
{
iConsole->ReadCancel();
}
}
#endif // __BT_TEXT_NOTIFIERS_NO_SSP__