--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothengine/bthid/bthidengplugin/src/bthidengplugin.cpp Mon Jan 18 20:28:57 2010 +0200
@@ -0,0 +1,373 @@
+/*
+* Copyright (c) 2006 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: Bluetooth Hid ECom plug-in class definition.
+ *
+*/
+
+
+#include <ecom/ecom.h>
+#include <ecom/implementationproxy.h>
+#include <btmanclient.h>
+#include "bthidengplugin.h"
+#include "bthidclient.h"
+
+#include "debug.h"
+
+//Used to identify the type of request to the AO
+enum TRequestId
+ {
+ ERequestConnect = 1,
+ ERequestDisconnect = 2,
+ ENotifyProfileStatusChange = 3,
+ ERequestDisconnectAll,
+ };
+
+CBTHidPlugin::CBTHidPlugin()
+ {
+ }
+
+CBTHidPlugin* CBTHidPlugin::NewL()
+ {
+ CBTHidPlugin* self = new (ELeave) CBTHidPlugin();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop(self);
+ return self;
+ }
+
+void CBTHidPlugin::ConstructL()
+ {
+ TRACE_FUNC
+ LEAVE_IF_ERROR( iClient.Connect() );
+
+ iActive4ProfileStatus = CGenericActive::NewL(*this,
+ CActive::EPriorityStandard, ENotifyProfileStatusChange);
+ iDiagnosticAddress.Zero();
+ iClient.NotifyStatusChange(iHIDStateUpdatePckg, iDiagnosticAddress,
+ iActive4ProfileStatus->iStatus);
+ iActive4ProfileStatus->GoActive();
+
+ TRACE_FUNC_EXIT
+ }
+
+CBTHidPlugin::~CBTHidPlugin()
+ {
+ delete iActive4ClientReq;
+ delete iActive4ProfileStatus;
+ if (iClient.Handle())
+ {
+ TRequestStatus req = KRequestPending;
+ iClient.DisconnectAllGracefully(req);
+ User::WaitForRequest(req);
+ }
+ iClient.Close();
+ TRACE_FUNC
+ }
+
+void CBTHidPlugin::SetObserver(MBTEngPluginObserver* aObserver)
+ {
+ iObserver = aObserver;
+ }
+
+void CBTHidPlugin::GetSupportedProfiles(RProfileArray& aProfiles)
+ {
+ aProfiles.Reset();
+ aProfiles.Append(EBTProfileHID);
+ }
+
+TBool CBTHidPlugin::IsProfileSupported(const TBTProfile aProfile) const
+ {
+ return (aProfile == EBTProfileHID);
+ }
+
+TInt CBTHidPlugin::Connect(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ return HandleAsyncRequest(aAddr, ERequestConnect);
+ }
+
+void CBTHidPlugin::CancelConnect(const TBTDevAddr& aAddr)
+ {
+ TRACE_FUNC
+ (void) aAddr;
+ iClient.CancelConnectDevice();
+ }
+
+TInt CBTHidPlugin::Disconnect(const TBTDevAddr& aAddr,
+ TBTDisconnectType aDiscType)
+ {
+ TRACE_FUNC
+ (void) aDiscType;
+ return HandleAsyncRequest(aAddr, ERequestDisconnect);
+ }
+
+void CBTHidPlugin::GetConnections(RBTDevAddrArray& aAddrArray,
+ TBTProfile aConnectedProfile)
+ {
+ if (aConnectedProfile == EBTProfileHID)
+ {
+ TBuf8<KBTDevAddrSize * 2> addrbuf;
+ iClient.GetConnections(addrbuf, aConnectedProfile);
+ TPtrC8 ptr(addrbuf);
+ while (ptr.Length() >= KBTDevAddrSize)
+ {
+ aAddrArray.Append(TBTDevAddr(ptr.Left(KBTDevAddrSize)));
+ ptr.Set(ptr.Mid(KBTDevAddrSize));
+ }
+ }
+ }
+
+void CBTHidPlugin::HandleNotifyProfileStatusChange(CGenericActive& aActive)
+ {
+ if (aActive.iStatus.Int() == KErrNone && iObserver)
+ {
+ TBool retStatus = EFalse;
+
+ THIDStateUpdate& HIDStateUpdate = iHIDStateUpdatePckg();
+
+ if (HIDStateUpdate.iState == EBTDeviceConnected
+ || HIDStateUpdate.iState == EBTDeviceLinkRestored)
+ {
+ retStatus = ETrue;
+ ReportProfileConnectionEvents(HIDStateUpdate.iDeviceAddress,
+ retStatus);
+ }
+
+ if (HIDStateUpdate.iState == EBTDeviceDisconnected
+ || HIDStateUpdate.iState == EBTDeviceLinkLost
+ || HIDStateUpdate.iState == EBTDeviceUnplugged)
+ {
+ retStatus = EFalse;
+ ReportProfileConnectionEvents(HIDStateUpdate.iDeviceAddress,
+ retStatus);
+ }
+ iDiagnosticAddress.Zero();
+ iClient.NotifyStatusChange(iHIDStateUpdatePckg, iDiagnosticAddress,
+ aActive.iStatus);
+ aActive.GoActive();
+ }
+ else
+ {
+ if (aActive.iStatus.Int() != KErrNone)
+ {
+ THIDStateUpdate& HIDStateUpdate = iHIDStateUpdatePckg();
+ if (iDiagnosticAddress.Length() >= KBTDevAddrSize)
+ {
+ RBTDevAddrArray array;
+ TPtrC8 ptr(iDiagnosticAddress);
+ while (ptr.Length() >= KBTDevAddrSize)
+ {
+ TRAP_IGNORE(array.AppendL(TBTDevAddr(ptr.Left(KBTDevAddrSize))););
+#ifdef _DEBUG
+ const TPtrC8 myPtr(array[array.Count() - 1].Des());
+#endif
+ TRACE_INFO((_L8("conflict <%S>"), &myPtr))
+ ptr.Set(ptr.Mid(KBTDevAddrSize));
+ }
+
+ iBTDevAddrPckgBuf() = HIDStateUpdate.iDeviceAddress;
+ iObserver->ConnectComplete(iBTDevAddrPckgBuf(),
+ EBTProfileHID, aActive.iStatus.Int(), &array);
+ array.Close();
+ }
+ else
+ {
+ iObserver->ConnectComplete(HIDStateUpdate.iDeviceAddress,
+ EBTProfileHID, aActive.iStatus.Int());
+ }
+ iClient.NotifyStatusChange(iHIDStateUpdatePckg,
+ iDiagnosticAddress, aActive.iStatus);
+ aActive.GoActive();
+ }
+ }
+ }
+
+void CBTHidPlugin::HandelRequestConnectComplete()
+ {
+ if (iActive4ClientReq->iStatus.Int() != KErrNone) // might have conflicts, decode iDiagnostic
+ {
+ if (iDiagnostic.Length() >= KBTDevAddrSize)
+ {
+ RBTDevAddrArray array;
+ TPtrC8 ptr(iDiagnostic);
+ while (ptr.Length() >= KBTDevAddrSize)
+ {
+ TRAP_IGNORE(array.AppendL(TBTDevAddr(ptr.Left(KBTDevAddrSize))););
+#ifdef _DEBUG
+ const TPtrC8 myPtr(array[array.Count() - 1].Des());
+#endif
+ TRACE_INFO((_L8("conflict <%S>"), &myPtr))
+ ptr.Set(ptr.Mid(KBTDevAddrSize));
+ }
+ iObserver->ConnectComplete(iBTDevAddrPckgBuf(), EBTProfileHID,
+ iActive4ClientReq->iStatus.Int(), &array);
+ array.Close();
+ }
+ else
+ {
+ iObserver->ConnectComplete(iBTDevAddrPckgBuf(), EBTProfileHID,
+ iActive4ClientReq->iStatus.Int());
+ }
+ }
+ else
+ {
+ TInt profile = 0;
+ if (iDiagnostic.Length() >= sizeof(TInt))
+ {
+ TPckg<TInt> pckg(profile);
+ pckg.Copy(iDiagnostic.Mid(0, sizeof(TInt)));
+ }
+ ReportProfileConnectionEvents(iBTDevAddrPckgBuf(), ETrue);
+ }
+ delete iActive4ClientReq;
+ iActive4ClientReq = NULL;
+ }
+
+void CBTHidPlugin::HandelRequestDisconnectComplete()
+ {
+ if (iActive4ClientReq->iStatus.Int() != KErrNone)
+ {
+ iObserver->DisconnectComplete(iBTDevAddrPckgBuf(), EBTProfileHID,
+ iActive4ClientReq->iStatus.Int());
+ }
+ else
+ {
+ TInt profile = 0;
+ if (iDiagnostic.Length() >= sizeof(TInt))
+ {
+ TPckg<TInt> pckg(profile);
+ pckg.Copy(iDiagnostic.Mid(0, sizeof(TInt)));
+ }
+ ReportProfileConnectionEvents(iBTDevAddrPckgBuf(), EFalse);
+ }
+ delete iActive4ClientReq;
+ iActive4ClientReq = NULL;
+ }
+
+void CBTHidPlugin::RequestCompletedL(CGenericActive& aActive)
+ {
+ TRACE_FUNC
+ switch (aActive.RequestId())
+ {
+ case ENotifyProfileStatusChange:
+ {
+ HandleNotifyProfileStatusChange(aActive);
+ break;
+ }
+ case ERequestConnect:
+ {
+ HandelRequestConnectComplete();
+ break;
+ }
+ case ERequestDisconnect:
+ {
+ HandelRequestDisconnectComplete();
+ break;
+ }
+ case ERequestDisconnectAll:
+ {
+ iObserver->DisconnectComplete(iBTDevAddrPckgBuf(), EBTProfileHID,
+ iActive4ClientReq->iStatus.Int());
+ break;
+ }
+ }
+ }
+
+TBTEngConnectionStatus CBTHidPlugin::IsConnected(const TBTDevAddr& aAddr)
+ {
+ TInt stat = 0;
+ stat = iClient.IsConnected(aAddr);
+ TRACE_INFO((_L("CBTHidPlugin::IsConnected() = %d"), stat))
+ return ((TBTEngConnectionStatus) stat);
+ }
+
+void CBTHidPlugin::CancelRequest(CGenericActive& aActive)
+ {
+ if (aActive.RequestId() == ENotifyProfileStatusChange)
+ {
+ iClient.CancelNotifyStatusChange();
+ }
+ else
+ {
+ if (aActive.RequestId() == ERequestConnect)
+ {
+ iClient.CancelConnectDevice();
+ }
+ }
+ }
+
+TInt CBTHidPlugin::HandleAsyncRequest(const TBTDevAddr& aAddr,
+ TInt aRequestId)
+ {
+ TInt err = KErrNone;
+ if (!iClient.Handle())
+ {
+ err = iClient.Connect();
+ }
+ if (err)
+ {
+ return err;
+ }
+ if (iActive4ClientReq)
+ {
+ err = KErrServerBusy;
+ }
+ if (!err)
+ {
+ iActive4ClientReq = CGenericActive::New(*this,
+ CActive::EPriorityStandard, aRequestId);
+ if (iActive4ClientReq)
+ {
+ iBTDevAddrPckgBuf() = aAddr;
+ if (aRequestId == ERequestConnect)
+ {
+ iDiagnostic.Zero();
+ iClient.ConnectDevice(iBTDevAddrPckgBuf, iDiagnostic,
+ iActive4ClientReq->iStatus);
+ }
+ else
+ {
+ iClient.DisconnectDevice(iBTDevAddrPckgBuf, EBTDiscImmediate,
+ iActive4ClientReq->iStatus);
+ }
+ iActive4ClientReq->GoActive();
+ }
+ else
+ {
+ err = KErrNoMemory;
+ }
+ }
+ return err;
+ }
+
+void CBTHidPlugin::ReportProfileConnectionEvents(const TBTDevAddr& aAddr,
+ TBool aConnected)
+ {
+ TRACE_FUNC
+ TRACE_INFO((_L("CBTHidPlugin::ReportProfileConnectionEvents() == %d"), aConnected))
+
+ if (iObserver)
+ {
+ if (aConnected)
+ {
+ iObserver->ConnectComplete(aAddr, EBTProfileHID, KErrNone);
+ }
+ else
+ {
+ iObserver->DisconnectComplete(aAddr, EBTProfileHID, KErrNone);
+ }
+ }
+ }
+
+//End of File