--- /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 <bt_sock.h>
+#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