diff -r 000000000000 -r f63038272f30 bluetoothengine/btsap/src/BTSapHciExtensionMan.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothengine/btsap/src/BTSapHciExtensionMan.cpp Mon Jan 18 20:28:57 2010 +0200 @@ -0,0 +1,427 @@ +/* +* Copyright (c) 2004 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: +* This class holds the HCI Extension Conduit singleton +* +*/ + + +// INCLUDE FILES +#include +#include "BTSapHciExtensionMan.h" +#include "debug.h" + +// CONSTANT + +/** +* A prefix patch in all commands for compatible reason with stack +*/ +const TUint8 KHciExtensionCmdPatch[] = {0xFC, 0x00, 0x00}; + +/** +* Common prerfix of additional functionality command +*/ +const TUint8 KHciExtensionCmdCommomPrefix[] = {0x00, 0xFC}; + +/** +* Command Channel ID (Type of command) +*/ +// Channel Id of additional functionality command +const TUint KHciExtensionFunctionalityChannelID = 0xF0; + +/** +* Command opcode and parameter total length +*/ +// ENCRYPTION_KEY_LENGTH_READ_CMD +const TUint8 KEncryptionKeyLengthReadOpcode = 0x07; + +const TInt KEncryptionKeyLengthReadCmdParamLen = 8; + +/** +* Event constants +*/ +const TInt KHciExtensionEventIndexOfOpcode = 2; + +const TInt KEncryptionKeyLengthReadEventLen = 6; + +// DATA TYPES + +// ================= MEMBER FUNCTIONS ======================= + +// --------------------------------------------------------- +// CBTHciExtensionMan::NewL() +// --------------------------------------------------------- +// +CBTHciExtensionMan* CBTHciExtensionMan::NewL() + { + CBTHciExtensionMan* self = new (ELeave) CBTHciExtensionMan(); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(); + return self; + } + +// Destructor. +CBTHciExtensionMan::~CBTHciExtensionMan() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::~CBTHciExtensionMan >>"))); + if (iConduit) + { + iConduit->StopWaitingForEvent(); + delete iConduit; + } + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::~CBTHciExtensionMan <<"))); + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::HandleReqeustL +// --------------------------------------------------------- +// +void CBTHciExtensionMan::GetEncryptionKeyLengthL(const TBTDevAddr& aBTDevAddr, TRequestStatus& aStatus) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::HandleRequestL >>"))); + + TInt err = KErrNone; + aStatus = KRequestPending; + iStatus = &aStatus; + + CBTHciExtensionCmd* cmd = NULL; + TBTDevAddrPckgBuf pckg; + pckg = aBTDevAddr; + + cmd = CBTHciExtensionCmd::NewLC(KEncryptionKeyLengthReadOpcode); + + cmd->SetParamL(pckg().Des()); + + if (err == KErrNone) + { + iRequestOpcode = cmd->Opcode(); + TPtrC8 ptr = cmd->DesC(); + TUint16 requestOpcode = ptr[0] << 8 | ptr[1]; + err = iConduit->IssueCommandL(requestOpcode, ptr.Mid(sizeof(KHciExtensionCmdPatch))); + if (err) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_ERROR, BTSapPrintTrace(_L("[BTSap] iConduit->IssueCommandL err %d"), err)); + } + } + else + { + User::RequestComplete(iStatus, err); + } + if (cmd) + { + CleanupStack::PopAndDestroy(cmd); + } + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::HandleRequestL <<"))); + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::GetResultL +// --------------------------------------------------------- +// +TInt CBTHciExtensionMan::GetResultL(TUint8& aKeyLength) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::GetResultL: enc key length: %d"),iKeyLength )); + if ( iStatus && iStatus->Int() == KRequestPending ) + { + return KErrNotReady; + } + + aKeyLength = iKeyLength; + return KErrNone; + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::CancelRequest +// --------------------------------------------------------- +// +void CBTHciExtensionMan::CancelRequest() + { + iConduit->StopWaitingForEvent(); + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::CommandCompleted +// --------------------------------------------------------- +// +void CBTHciExtensionMan::CommandCompleted(TInt aError) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::CommandCompleted(%d)"), aError)); + if(aError == KErrNone) + { + aError = iConduit->WaitForEvent(); + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::CommandCompleted, iConduit->WaitForEvent %d"), aError)); + } + if (aError != KErrNone) + { + User::RequestComplete(iStatus, aError); + } + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::ReceiveEvent +// --------------------------------------------------------- +// +TBool CBTHciExtensionMan::ReceiveEvent(TDesC8& aEvent, TInt aError) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::ReceiveEvent(aError %d) >>"), aError)); + if (aError != KErrNone) + { + User::RequestComplete(iStatus, aError); + return EFalse; + } + + CBTHciExtensionCmdEvent* event = NULL; + TInt err; + TRAP(err, event = CBTHciExtensionCmdEvent::NewL(aEvent)); + if (!event) + { + User::RequestComplete(iStatus, err); + return EFalse; + } + if (event->Opcode() != iRequestOpcode) + { + User::RequestComplete(iStatus, KErrArgument); + delete event; + return EFalse; + } + switch (iRequestOpcode) + { + case KEncryptionKeyLengthReadOpcode: + { + TPtrC8 desptr = event->DesC(); + iKeyLength = desptr[desptr.Length() - 1]; + err = KErrNone; + break; + } + default: + { + err = KErrNotSupported; + break; + } + } + delete event; + User::RequestComplete(iStatus, err); + + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::ReceiveEvent %d <<"), err)); + return EFalse; + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::ConstructL +// --------------------------------------------------------- +// +void CBTHciExtensionMan::ConstructL() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::ConstructL >>"))); + iConduit = CHciExtensionConduit::NewL(*this); + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionMan::ConstructL, iConduit %d <<"), iConduit)); + } + +// --------------------------------------------------------- +// CBTHciExtensionMan::CBTHciExtensionMan +// --------------------------------------------------------- +// +CBTHciExtensionMan::CBTHciExtensionMan(): iKeyLength(0) + { + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::NewL +// --------------------------------------------------------- +// +CBTHciExtensionCmd* CBTHciExtensionCmd::NewL(TUint8 aOpcode) + { + CBTHciExtensionCmd* self = CBTHciExtensionCmd::NewLC(aOpcode); + CleanupStack::Pop(); + return self; + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::NewLC +// --------------------------------------------------------- +// +CBTHciExtensionCmd* CBTHciExtensionCmd::NewLC(TUint8 aOpcode) + { + CBTHciExtensionCmd* self = new (ELeave) CBTHciExtensionCmd(aOpcode); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +// Destructor. +CBTHciExtensionCmd::~CBTHciExtensionCmd() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::~CBTHciExtensionCmd >>"))); + delete iCmdDes; + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::~CBTHciExtensionCmd <<"))); + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::Opcode +// --------------------------------------------------------- +// +TUint8 CBTHciExtensionCmd::Opcode() const + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::Opcode %d >>"), iOpcode)); + return iOpcode; + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::CmdDesC +// --------------------------------------------------------- +// +TPtrC8 CBTHciExtensionCmd::DesC() const + { + return iCmdDes->Des(); + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::SetParamL +// --------------------------------------------------------- +// +void CBTHciExtensionCmd::SetParamL(const TDesC8& aParam) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::SetParamL param len %d >>"), aParam.Length())); + TInt length = aParam.Length(); + if (length != iParamTotalLength - 2) + { + User::Leave(KErrArgument); + } + iCmdDes->Des().Replace(iCmdLength - length, length, aParam); + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::SetParamL <<"))); + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::CBTHciExtensionCmd +// --------------------------------------------------------- +// +CBTHciExtensionCmd::CBTHciExtensionCmd(TUint8 aOpcode) + : iOpcode(aOpcode) + { + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::ConstructL +// --------------------------------------------------------- +// +void CBTHciExtensionCmd::ConstructL() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::ConstructL >>"))); + switch (iOpcode) + { + case KEncryptionKeyLengthReadOpcode: + { + iChannelID = KHciExtensionFunctionalityChannelID; + iParamTotalLength = KEncryptionKeyLengthReadCmdParamLen; + iCmdLength = sizeof(KHciExtensionCmdPatch) + + sizeof(KHciExtensionCmdCommomPrefix) + iParamTotalLength + 1; + break; + } + default: + User::Leave(KErrArgument); + } + InitializeCmdDesL(); + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::ConstructL <<"))); + } + +// --------------------------------------------------------- +// CBTHciExtensionCmd::InitializeCmdDesL +// --------------------------------------------------------- +// +void CBTHciExtensionCmd::InitializeCmdDesL() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::InitializeCmdDesL >>"))); + iCmdDes = HBufC8::NewL(iCmdLength); + TPtr8 cmdPtr = iCmdDes->Des(); + cmdPtr.Append(KHciExtensionCmdPatch, sizeof(KHciExtensionCmdPatch)); + cmdPtr.Append(KHciExtensionCmdCommomPrefix, sizeof(KHciExtensionCmdCommomPrefix)); + cmdPtr.Append(iParamTotalLength); + cmdPtr.Append(iChannelID); + cmdPtr.Append(iOpcode); + cmdPtr.AppendFill(0, iParamTotalLength - 2); + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmd::InitializeCmdDesL, len %d <<"), cmdPtr.Length())); + } + +CBTHciExtensionCmdEvent* CBTHciExtensionCmdEvent::NewL(const TDesC8& aEvent) + { + CBTHciExtensionCmdEvent* self = CBTHciExtensionCmdEvent::NewLC(aEvent); + CleanupStack::Pop(); + return self; + } + +CBTHciExtensionCmdEvent* CBTHciExtensionCmdEvent::NewLC(const TDesC8& aEvent) + { + CBTHciExtensionCmdEvent* self = new (ELeave) CBTHciExtensionCmdEvent(); + CleanupStack::PushL(self); + self->ConstructL(aEvent); + return self; + } + +CBTHciExtensionCmdEvent::~CBTHciExtensionCmdEvent() + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmdEvent::~CBTHciExtensionCmdEvent >>"))); + delete iEventDes; + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmdEvent::~CBTHciExtensionCmdEvent <<"))); + } + +TUint8 CBTHciExtensionCmdEvent::Opcode() const + { + return (*iEventDes)[KHciExtensionEventIndexOfOpcode]; + } + +TPtrC8 CBTHciExtensionCmdEvent::DesC() const + { + return iEventDes->Des(); + } + +CBTHciExtensionCmdEvent::CBTHciExtensionCmdEvent() + { + } + +void CBTHciExtensionCmdEvent::ConstructL(const TDesC8& aEvent) + { + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmdEvent::ConstructL len %d >>"), aEvent.Length())); + if (aEvent.Length() > KHciExtensionEventIndexOfOpcode) + { + TInt desLength = 0; + // Get the opcode of this event + TUint8 opcode = aEvent[KHciExtensionEventIndexOfOpcode]; + BTSAP_TRACE_OPT(KBTSAP_TRACE_INFO, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmdEvent::ConstructL opcode %d >>"), opcode)); + switch (opcode) + { + case KEncryptionKeyLengthReadOpcode: + { + if (aEvent.Length() != KEncryptionKeyLengthReadEventLen) + { + User::Leave(KErrArgument); + } + desLength = KEncryptionKeyLengthReadEventLen; + break; + } + default: + User::Leave(KErrNotSupported); + } + iEventDes = HBufC8::NewL(desLength); + TPtr8 ptr = iEventDes->Des(); + ptr.Append(aEvent); + } + else + { + User::Leave(KErrArgument); + } + BTSAP_TRACE_OPT(KBTSAP_TRACE_FUNCTIONS, BTSapPrintTrace(_L("[BTSap] CBTHciExtensionCmdEvent::ConstructL <<"))); + } + +// End of File