diff -r 000000000000 -r 29b1cd4cb562 bluetoothmgmt/bluetoothclientlib/btlib/btphysicallinks.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothmgmt/bluetoothclientlib/btlib/btphysicallinks.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,502 @@ +// Copyright (c) 2003-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: +// Generic functions associated with all Bluetooth socket addresses +// +// + +#include +#include "btsocketpanic.h" +#include "btphysicallinkshelpers.h" + +//---- +EXPORT_C CBluetoothPhysicalLinks* CBluetoothPhysicalLinks::NewL(MBluetoothPhysicalLinksNotifier& aNotifier, + RSocketServ& aServer) +/** Constructor + +Opens a Bluetooth socket. +@pre A session on the socket server has been started. +@leave No memory, or error on opening socket +@param aNotifier The object which will receive asynchronous events. +@param aServer The socket server. +@return An object of type CBluetoothPhysicalLinks +*/ + { + CBluetoothPhysicalLinks* self = NewLC(aNotifier, aServer); + CleanupStack::Pop(); + return self; + } + +EXPORT_C CBluetoothPhysicalLinks* CBluetoothPhysicalLinks::NewLC(MBluetoothPhysicalLinksNotifier& aNotifier, + RSocketServ& aServer) +/** Constructor + +Opens a Bluetooth socket. +@pre A session on the socket server has been started. +@leave No memory, or error on opening socket +@param aNotifier The object which will receive asynchronous events. +@param aServer The socket server. +@return An object of type CBluetoothPhysicalLinks +*/ + { + CBluetoothPhysicalLinks* self=new (ELeave) CBluetoothPhysicalLinks(aNotifier, aServer); + CleanupStack::PushL(self); + self->ConstructL(); + return self; + } + +EXPORT_C CBluetoothPhysicalLinks::~CBluetoothPhysicalLinks() +/** +Destructor +*/ + { + delete iBTBasebandConnecter; + delete iBTDisconnector; + BTBaseband().Close(); + } + +CBluetoothPhysicalLinks::CBluetoothPhysicalLinks(MBluetoothPhysicalLinksNotifier& aNotifier, + RSocketServ& aServer) +: iNotifier(aNotifier), iSockServer(aServer) + { + } + +void CBluetoothPhysicalLinks::ConstructL() + { + User::LeaveIfError(BTBaseband().Open(SockServer())); + } + +EXPORT_C TInt CBluetoothPhysicalLinks::CreateConnection(const TBTDevAddr& aBDAddr) +/** +Bring in a new member to the piconet + +This can be useful for preparing for a logical link (service socket). +Firstly if the local device has not bonded with the specified remote device, +then this function can be used to allow the bonding procedure can take place in advance. +Secondly if a CBluetoothSocket call is made to create a logical link within an internally +specified time of this CreateConnection function being called, then that link will come +up much faster since the physical link will already be in place. +Unless this connection is taken up by a logical link (or a synchronous link) within that +internally specified time then it will be closed. + +This function can also be used to create a physical link ready for the setting up +of a synchronous link (e.g. voice link). + +@param aBDAddr Bluetooth address specifying remote device (new member of piconet) +@return Error code +*/ + { + if(iBTBasebandConnecter) + { + return KErrInUse; + } + + //Close and re-open socket subsession + //Allow ESock to do multiple connects + BTBaseband().Close(); + TInt err = BTBaseband().Open(SockServer()); + if(err != KErrNone) + { + return err; + } + + //Create Connecting AO + TRAP(err, iBTBasebandConnecter = CBTBasebandConnecter::NewL(*this)); + if(err != KErrNone) + { + //BTBaseband().Close();//no leave it open! + return err; + } + + //Try to make BT connection + iBTBasebandConnecter->BasebandConnect(aBDAddr); + return err; + } + +EXPORT_C void CBluetoothPhysicalLinks::CancelCreateConnection() +/** Cancel bringing in a new member to the piconet +*/ + { + if(iBTBasebandConnecter) + { + delete iBTBasebandConnecter; + iBTBasebandConnecter = 0; + } + } + +EXPORT_C TInt CBluetoothPhysicalLinks::Disconnect(const TBTDevAddr& aBDAddr) +/** Disconnect a single member of piconet + +@param aBDAddr Bluetooth address specifying remote device (member of piconet) +@return Error code +@capability NetworkControl +*/ + { + if(iBTDisconnector) + { + return KErrInUse; + } + + //Allow ESock to do multiple disconnects + BTBaseband().Close(); + TInt ESockErr = BTBaseband().Open(SockServer()); + if(ESockErr != KErrNone) + { + return ESockErr; + } + + TRAPD(err, iBTDisconnector = CBTDisconnector::NewL(*this)); + if(err == KErrNone) + { + iBTDisconnector->Disconnect(aBDAddr); + } + return err; + } + +EXPORT_C TInt CBluetoothPhysicalLinks::DisconnectAll() +/** Disconnect all members of piconet +@return Error code +@capability NetworkControl +*/ + { + if(iBTDisconnector) + { + return KErrInUse; + } + + //Allow ESock to do multiple disconnects + BTBaseband().Close(); + TInt ESockErr = BTBaseband().Open(SockServer()); + if(ESockErr != KErrNone) + { + return ESockErr; + } + + TRAPD(err, iBTDisconnector = CBTDisconnector::NewL(*this)); + if(err == KErrNone) + { + iBTDisconnector->DisconnectAll(); + } + return err; + } + +EXPORT_C TInt CBluetoothPhysicalLinks::Broadcast(const TDesC8& aData) +/** Write (raw) broadcast data + +Raw broadcast data is data that is not directed to any specified service. +@param aData Contains data to be broadcast. +@test +@return Error code +@capability NetworkControl +*/ + { + return BTBaseband().Broadcast(aData); + } + +EXPORT_C TInt CBluetoothPhysicalLinks::ReadRaw(TDes8& aData) +/** Receive (raw) broadcast data + +Raw broadcast data is data that is not directed to any specified service. +@param aData Contains data received. +@test +@return Error code +@capability NetworkControl +*/ + { + return BTBaseband().ReadRaw(aData); + } + +EXPORT_C TInt CBluetoothPhysicalLinks::Enumerate(RBTDevAddrArray& aBTDevAddrArray, TUint aMaxNumber) +/** Enumerate connected members of the piconet +@param aBTDevAddrArray Bluetooth device address array to be filled with bluetooth addresses of connected members of +the piconet. +@param aMaxNumber Upper limit on number of members to be returned. +@return Error code +*/ + { + return BTBaseband().Enumerate(aBTDevAddrArray, aMaxNumber); + } + + + +void CBluetoothPhysicalLinks::HandleCreateConnectionCompleteL(TInt aErr) + { + delete iBTBasebandConnecter; + iBTBasebandConnecter = 0; + iNotifier.HandleCreateConnectionCompleteL(aErr); + } + +void CBluetoothPhysicalLinks::HandleDisconnectCompleteL(TInt aErr) + { + delete iBTDisconnector; + iBTDisconnector = 0; + iNotifier.HandleDisconnectCompleteL(aErr); + } + +void CBluetoothPhysicalLinks::HandleDisconnectAllCompleteL(TInt aErr) + { + delete iBTDisconnector; + iBTDisconnector = 0; + Notifier().HandleDisconnectAllCompleteL(aErr); + } + +RSocketServ& CBluetoothPhysicalLinks::SockServer() + { + return iSockServer; + } + +RBTBaseband& CBluetoothPhysicalLinks::BTBaseband() + { + return iBTBaseband; + } + +MBluetoothPhysicalLinksNotifier& CBluetoothPhysicalLinks::Notifier() + { + return iNotifier; + } + + + + + + + + + + + + + + +//========================================================== +//Active Object Helpers +// + +// +//for CBluetoothPhysicalLinks +// + +//-- +CBTBasebandConnecter* CBTBasebandConnecter::NewL(CBluetoothPhysicalLinks& aParent) +{ + CBTBasebandConnecter* self = new (ELeave) CBTBasebandConnecter(aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop();//self + return self; +} + +CBTBasebandConnecter::CBTBasebandConnecter(CBluetoothPhysicalLinks& aParent) +: CActive(CActive::EPriorityStandard),iParent(aParent) +// +//Constructorthe RBluetoothSocket parent is provided. +//It contains all the ESocky stuff and has suitable "Getters". +// + { + } + +void CBTBasebandConnecter::ConstructL() + { + CActiveScheduler::Add(this); + } + +CBTBasebandConnecter::~CBTBasebandConnecter() +// +//Destructor +// + { + if(IsActive()) + { + Cancel(); + } + } + + +void CBTBasebandConnecter::BasebandConnect(const TBTDevAddr& aBDAddr) +// +//Attempts to connect to the remote device. +// + { + __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness)); + + iParent.BTBaseband().Connect(aBDAddr, iStatus); + SetActive(); + } + +void CBTBasebandConnecter::RunL() +// +//When logical socket has connected (only async bit), +//opens baseband socket. +// + { + //must come LAST .. deletes this active object + iParent.HandleCreateConnectionCompleteL(iStatus.Int()); + } + +// +// Swallow any error from RunL +// +TInt CBTBasebandConnecter::RunError(TInt /*aError*/) + { + return KErrNone; + } + +void CBTBasebandConnecter::DoCancel() +// +//Cancels current asynchronous requests. +// + { + iParent.BTBaseband().TerminatePhysicalLink(0); //zam todo - check + } + + + + +//---- + +CBTDisconnector* CBTDisconnector::NewL(CBluetoothPhysicalLinks& aParent) +// +//NewL: the CBluetoothPhysicalLinkssManager parent is provided. +//It contains all the ESocky stuff and has suitable "Getters". +// +{ + CBTDisconnector* self = new (ELeave) CBTDisconnector(aParent); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop();//self + return self; +} + + +CBTDisconnector::CBTDisconnector(CBluetoothPhysicalLinks& aParent) +: CActive(CActive::EPriorityStandard), + iParent(aParent) +// +//Constructor +// + { + } + +void CBTDisconnector::ConstructL() + { + CActiveScheduler::Add(this); + } + +CBTDisconnector::~CBTDisconnector() +// +//Destructor +// + { + if(IsActive()) + { + Cancel(); + } + } + +void CBTDisconnector::Disconnect(const TBTDevAddr& aBDAddr) + { + __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness)); + + iParent.BTBaseband().TerminatePhysicalLink(0, aBDAddr, iStatus); + iCurrentRequest = EDisconnect; + SetActive(); + } + +void CBTDisconnector::DisconnectAll() + + { + __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness)); + + iParent.BTBaseband().TerminateAllPhysicalLinks(0, iStatus); + iCurrentRequest = EDisconnectAll; + SetActive(); + } + +void CBTDisconnector::RunL() +// +//When logical socket has connected (only async bit), +//opens baseband socket. +// + { + //must come LAST .. deletes this active object + switch (iCurrentRequest) + { + //zam todo do these cover all Read/Recv methods? + case EDisconnect: + //must come LAST .. deletes this active object + iParent.HandleDisconnectCompleteL(iStatus.Int()); + break; + case EDisconnectAll: + //must come LAST .. deletes this active object + iParent.HandleDisconnectAllCompleteL(iStatus.Int()); + break; + default: + Panic(EBadRequest); + iCurrentRequest = ENone; + break; + }; + } + +// +// Swallow any error from RunL +// +TInt CBTDisconnector::RunError(TInt /*aError*/) + { + return KErrNone; + } + +void CBTDisconnector::DoCancel() +// +//Cancels current asynchronous requests. +// + { + //zam todo - more here...can we cancel a shutdown? + iCurrentRequest = ENone; + } + +// +// Function Definitions for the M- Classes associated with CBluetoothPhysicalLinks +// + +/** +This virtual function allows the M- class to be extended in future in a binary +compatible way by providing a method that clients can override in future to +allow extra callbacks to be made via aObject. +*/ +EXPORT_C void MBluetoothSynchronousLinkNotifier::MBSLN_ExtensionInterfaceL(TUid /*aInterface*/, void*& aObject) + { + aObject = NULL; + } + +/** +This virtual function allows the M- class to be extended in future in a binary +compatible way by providing a method that clients can override in future to +allow extra callbacks to be made via aObject. +*/ +EXPORT_C void MBluetoothPhysicalLinksNotifier::MBPLN_ExtensionInterfaceL(TUid /*aInterface*/, void*& aObject) + { + aObject = NULL; + } + + +/** +This virtual function allows the M- class to be extended in future in a binary +compatible way by providing a method that clients can override in future to +allow extra callbacks to be made via aObject. +*/ +EXPORT_C void MBluetoothSocketNotifier::MBSN_ExtensionInterfaceL(TUid /*aInterface*/, void*& aObject) + { + aObject = NULL; + } + +// EOF