diff -r 000000000000 -r f63038272f30 bluetoothengine/bthid/bthidengplugin/src/bthidengplugin.cpp --- /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 +#include +#include +#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 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 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 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