bluetoothengine/btsap/src/BTSapHciExtensionMan.cpp
changeset 0 f63038272f30
child 2 0b192a3a05a4
--- /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 <e32cmn.h>
+#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