--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp Fri Jan 15 08:13:17 2010 +0200
@@ -0,0 +1,3047 @@
+// 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 "btsockethelpers.h"
+#include "e32cmn.h"
+
+#include <bluetooth/logger.h>
+
+
+
+void Panic(TBTSocketPanics aCode)
+ {
+ _LIT(KPanicName, "BTSocket");
+ User::Panic(KPanicName, aCode);
+ }
+
+
+
+
+
+//*****************//
+
+//----
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewL(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ TUint aSockType,
+ TUint aProtocol)
+/** Standard Bluetooth socket NewL constructor.
+
+Opens a Bluetooth socket. The constructor identifies the server, socket type, and bluetooth
+protocol to be used for the socket, as well as an asynchronous notifier.
+@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 A handle to an existing session on the socket server (ESock).
+@param aSockType One of a set of values defined in es_sock.h, for example KSockStream.
+@param aProtocol An entry point into the Bluetooth stack, for example KL2CAP.
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self = NewLC(aNotifier, aServer, aSockType,aProtocol);
+ CleanupStack::Pop();
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewLC(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ TUint aSockType,
+ TUint aProtocol)
+/** Standard Bluetooth socket NewLC constructor.
+
+Opens a Bluetooth socket as with the NewL() above, but leaves the returned CBluetoothSocket
+object on the cleanup stack.
+
+@param aNotifier The object which will receive asynchronous events.
+@param aServer A handle to an existing session on the socket server (ESock)
+@param aSockType One of a set of values defined in es_sock.h, for example KSockStream
+@param aProtocol An entry point into the Bluetooth stack, for example KL2CAP
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self=new (ELeave) CBluetoothSocket(aNotifier, aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSockType, aProtocol);
+ return self;
+ }
+
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewL(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ TUint aSockType,
+ TUint aProtocol,
+ RConnection& aConnection)
+/** Opens a Bluetooth socket on a specified connection.
+@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 A handle to an existing session on the socket server (ESock)
+@param aSockType One of a set of values defined in es_sock.h, for example KSockStream
+@param aProtocol An entry point into the Bluetooth stack, for example KL2CAP
+@param aConnection A socket server management interface for a connection
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self = NewLC(aNotifier, aServer, aSockType, aProtocol, aConnection);
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewLC(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ TUint aSockType,
+ TUint aProtocol,
+ RConnection& aConnection)
+/** This constructor opens a Bluetooth socket on a specified connection.
+
+Leaves the socket on the cleanup stack.
+
+@param aNotifier The object which will receive asynchronous events.
+@param aServer A handle to an existing session on the socket server (ESock)
+@param aSockType One of a set of values defined in es_sock.h, for example KSockStream
+@param aProtocol An entry point into the Bluetooth stack, for example KL2CAP
+@param aConnection A socket server management interface for a connection
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self=new (ELeave) CBluetoothSocket(aNotifier, aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSockType, aProtocol, aConnection);
+ return self;
+ }
+
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewL(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ const TDesC& aName)
+/** Bluetooth socket named protocol NewL() constructor.
+
+Opens a Bluetooth socket over a specified named protocol, such as "L2CAP".
+@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 A handle to an existing session on the socket server (ESock)
+@param aName A descriptor containing the name of the protocol wanted for
+making a Bluetooth connection, for example _L("L2CAP")
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self = NewLC(aNotifier, aServer, aName);
+ CleanupStack::Pop();
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewLC(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ const TDesC& aName)
+/** Bluetooth socket named protocol NewLC() constructor.
+
+Opens a Bluetooth socket over a specified named protocol, such as "L2CAP".
+Leaves returned CBluetoothSocket object on the cleanup stack.
+
+@param aNotifier The object which will receive asynchronous events.
+@param aServer A handle to an existing session on the socket server (ESock)
+@param aName A descriptor containing the name of the protocol wanted for
+making a Bluetooth connection, for example _L("L2CAP")
+@return The Bluetooth socket created with the constructor.
+@capability LocalServices
+*/
+ {
+ CBluetoothSocket* self=new (ELeave) CBluetoothSocket(aNotifier, aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL(aName);
+ return self;
+ }
+
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewL(MBluetoothSocketNotifier& aNotifier, RSocketServ& aServer)
+/** Bluetooth blank socket NewL() constructor.
+
+Opens a blank socket to be used when accepting an incoming connection.
+This socket should be used as the parameter when a listening socket
+calls CBluetoothSocket::Accept(CBluetoothSocket& aBlankSocket). When
+that connection completes this blank socket becomes the Bluetooth
+socket for that connection.
+
+@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 A handle to an existing session on the socket server (ESock)
+@return The Bluetooth socket created with the constructor.
+*/
+ {
+ CBluetoothSocket* self = NewLC(aNotifier, aServer);
+ CleanupStack::Pop();
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewLC(MBluetoothSocketNotifier& aNotifier, RSocketServ& aServer)
+/** Bluetooth blank socket NewLC() constructor
+
+Opens a blank socket to be used when accepting an incoming connection.
+This socket should be used as the parameter when a listening socket
+calls CBluetoothSocket::Accept(CBluetoothSocket& aBlankSocket). When
+that connection completes this blank socket becomes the Bluetooth
+socket for that connection.
+
+Leaves returned CBluetoothSocket object on the cleanup stack.
+
+@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 A handle to an existing session on the socket server (ESock)
+@return The Bluetooth socket created with the constructor.
+*/
+ {
+ CBluetoothSocket* self=new (ELeave) CBluetoothSocket(aNotifier, aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewL(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ RSocket& aSocket)
+/** Bluetooth socket using an existing RSocket instance constructor.
+
+Takes ownership of an existing socket to be used as the underlying
+connection for this Socket wrapper. This should be used where an
+existing API returned a RSocket representing a Bluetooth connection.
+
+@pre A session on the socket server has been started, and aSocket is open and is
+set as "Transferable" through the KSOEnableTransfer SetOpt.
+@leave No memory
+@param aNotifier The object which will receive asynchronous events.
+@param aServer A handle to an existing session on the socket server (ESock)
+@param aSocket A handle to an existing socket.
+@return The Bluetooth socket created with the constructor.
+*/
+ {
+ CBluetoothSocket* self = NewLC(aNotifier, aServer, aSocket);
+ CleanupStack::Pop();
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket* CBluetoothSocket::NewLC(MBluetoothSocketNotifier& aNotifier,
+ RSocketServ& aServer,
+ RSocket& aSocket)
+/** Bluetooth socket using an existing RSocket instance constructor.
+
+Takes ownership of an existing socket to be used as the underlying
+connection for this Socket wrapper. This should be used where an
+existing API returned a RSocket representing a Bluetooth connection.
+
+Leaves returned CBluetoothSocket object on the cleanup stack.
+
+@pre A session on the socket server has been started, and aSocket is open and is
+set as "Transferable" through the KSOEnableTransfer SetOpt.
+@leave No memory
+@param aNotifier The object which will receive asynchronous events.
+@param aServer A handle to an existing session on the socket server (ESock)
+@param aSocket A handle to an existing socket.
+@return The Bluetooth socket created with the constructor.
+*/
+ {
+ CBluetoothSocket* self=new (ELeave) CBluetoothSocket(aNotifier, aServer);
+ CleanupStack::PushL(self);
+ self->ConstructL(aSocket);
+ return self;
+ }
+
+EXPORT_C CBluetoothSocket::~CBluetoothSocket()
+/** Destructor
+
+Cancels any outstanding Bluetooth socket functions and closes the socket.
+Note sockets should be closed or shutdown before destructor is called.
+*/
+ {
+ delete iAutoSniffDelayTimer;
+ delete iBTConnecter;
+ delete iBTAccepter;
+ delete iBTShutdowner;
+ delete iBTReceiver;
+ delete iBTSender;
+ delete iBTIoctler;
+ delete iBTBasebandChangeEventNotifier;
+ if(Socket().SubSessionHandle())
+ {
+ Socket().Close();
+ }
+ delete iBTBasebandManager; // Unregisters any basebands it has registered
+ delete iBTBasebandChangeEventDelegate;
+ delete iAsyncDestroyer;
+ }
+
+
+//RSocket functions
+EXPORT_C TInt CBluetoothSocket::Send(const TDesC8& aDesc,TUint someFlags)
+/** Sends data to a remote bluetooth device.
+
+The Send() operation checks that another Send() operation isn't already in
+progress before sending.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleSendCompleteL(TInt aErr).
+
+If Automatic Sniff Mode is active, using this function will not automatically put the link
+into active mode. If it is required that the link be taken out of sniff mode automatically
+when data is to be sent then the CBluetoothSocket::Write(const TDesC8& aDesc) function
+should be used instead.
+
+@param aDesc A descriptor for the data being sent to the remote device.
+@param someFlags Bluetooth specific flags.
+@return KErrNone meaning the operation was successful and data is being sent to the remote device,
+ or KErrInUse meaning a previous Send() is not yet finished.
+@see RSocket::Send(const TDesC8& aDesc,TUint someFlags,TRequestStatus& aStatus)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iSending)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTSender->Send(aDesc, someFlags);
+ iSending = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Send(const TDesC8& aDesc,TUint someFlags,TSockXfrLength& aLen)
+/** Sends data to a remote bluetooth device.
+
+The Send() operation checks that another Send() operation isn't already in
+progress before sending.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleSendCompleteL(TInt aErr)
+
+If Automatic Sniff Mode is active, using this function will not automatically put the link
+into active mode. If it is required that the link be taken out of sniff mode automatically
+when data is to be sent then the CBluetoothSocket::Write(const TDesC8& aDesc) function
+should be used instead.
+
+@param aDesc A descriptor for the data being sent to the remote device.
+@param someFlags Bluetooth specific flags.
+@param aLen Amount of data being sent.
+@return KErrNone meaning the operation was successful and data is being sent to the remote device,
+ or KErrInUse meaning a previous Send() is not yet finished.
+@see RSocket::Send(const TDesC8& aDesc,TUint someFlags,TSockXfrLength& aLen)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iSending)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTSender->Send(aDesc, someFlags, aLen);
+ iSending = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelSend()
+/** Cancels an outstanding Bluetooth Send() operation.
+
+Calling the function will cause an outstanding Bluetooth Send()
+operation to complete prematurely.
+
+@see RSocket::CancelSend()
+*/
+ {
+ if(iSending)
+ {
+ iBTSender->Cancel(); //cancels 'Write' or 'Send' as appropriate
+ iSending = EFalse;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::Recv(TDes8& aDesc,TUint flags)
+/** Receives data from a remote Bluetooth device.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr)
+@param aDesc A descriptor for the information being sent to the remote Bluetooth device.
+@param flags Bluetooth information flags.
+@return KErrNone meaning the operation was successful and data is being received from the remote device,
+ or KErrInUse meaning a previous Recv() is not yet finished.
+@see RSocket::Recv(TDes8& aDesc,TUint flags)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->Recv(aDesc, flags);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Recv(TDes8& aDesc,TUint flags, TSockXfrLength& aLen)
+/** Receives data from a remote Bluetooth device.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr)
+@param aDesc A descriptor for the information being sent to the remote Bluetooth device.
+@param flags Bluetooth information flags.
+@param aLen A length indicating how much data was read. This is the same as length of the returned aDesc.
+@return KErrNone meaning the operation was successful and data is being received from the remote device,
+ or KErrInUse meaning a previous Recv() is not yet finished.
+@see RSocket::Recv(TDes8& aDesc,TUint flags, TSockXfrLength& aLen)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->Recv(aDesc, flags, aLen);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::RecvOneOrMore(TDes8& aDesc,TUint flags,TSockXfrLength& aLen)
+/** Receives data from a remote Bluetooth device, completing when data is available.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr).
+@param aDesc A descriptor for the information being sent to the remote Bluetooth device.
+@param flags Bluetooth information flags.
+@param aLen A length indicating how much data was read. This is the same as length of the returned aDesc.
+@return KErrNone meaning the operation was successful and data is being received from the remote device,
+ or KErrInUse meaning a previous Recv() is not yet finished.
+@see RSocket::RecvOneOrMore(TDes8& aDesc,TUint flags,TSockXfrLength& aLen)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->RecvOneOrMore(aDesc, flags, aLen);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelRecv()
+/** Cancels an outstanding Recv() operation.
+
+Calling this function will cause any outstanding receive operation to cancel.
+
+@see RSocket::CancelRecv()
+*/
+ {
+ if(iReceiving)
+ {
+ iBTReceiver->Cancel(); //cancels 'Read' or 'Recv' as appropriate
+ iReceiving = EFalse;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::Read(TDes8& aDesc)
+/** Receives data from a remote Bluetooth host.
+
+Read() is only used with a connected Bluetooth host.
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr)
+@param aDesc A descriptor for the data being read.
+@return KErrNone meaning the operation was successful and data is being received from the remote device,
+ or KErrInUse meaning a previous Recv() is not yet finished.
+@see RSocket::Read(TDes8& aDesc)
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->Read(aDesc);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelRead()
+/** Cancels an outstanding Read() operation.
+
+Calling this function will cause any outstanding Read() operation to cancel.
+@see RSocket::CancelRead()
+*/
+ {
+ if(iReceiving)
+ {
+ iBTReceiver->Cancel(); //cancels 'Read' or 'Recv' as appropriate
+ iReceiving = EFalse;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::Write(const TDesC8& aDesc)
+/** Writes to a remote Bluetooth device
+
+@see RSocket::Write(const TDesC8& aDesc)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleSendCompleteL(TInt aErr)
+
+If Automatic Sniff Mode is active on this socket instance, then upon calling this function
+the link will be put into active mode. If no CBluetoothSocket::Write() calls are made
+for a period of the timeout specified during activation of the automatic sniffing then
+the link will be put back into sniff mode.
+@see CBluetoothSocket::SetAutomaticSniffMode(TBool aAutoSniffMode, TInt aIdleSecondsBeforeSniffRequest)
+@see CBluetoothSocket::SetAutomaticSniffMode(TBool aAutoSniffMode)
+
+@param aDesc A descriptor for the data being sent to the remote Bluetooth device.
+@return KErrNone meaning the operation was successful and data is being sent to the remote device,
+ or KErrInUse meaning a previous Write() is not yet finished.
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iSending)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ if(iAutoSniffDelayTimer)
+ {
+ iAutoSniffDelayTimer->StartActive();
+ }
+ iBTSender->Write(aDesc);
+ iSending = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelWrite()
+/** Cancels an outstanding Write() operation.
+
+Calling this operation will cause any outstanding Write() operation to cancel.
+@see RSocket::CancelWrite()
+*/
+ {
+ if(iSending)
+ {
+ iBTSender->Cancel(); //cancels 'Write' or 'Send' as appropriate
+ iSending = EFalse;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::SendTo(const TDesC8& aDesc,TSockAddr& aAddr,TUint flags)
+/** Sends the aDesc data to the aAddr specified and applies the flags indicated to the operation.
+
+@see RSocket::SendTo(const TDesC8& aDesc,TSockAddr& aAddr,TUint flags)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleSendCompleteL(TInt aErr)
+
+If Automatic Sniff Mode is active, using this function will not automatically put the link
+into active mode. If it is required that the link be taken out of sniff mode automatically
+when data is to be sent then the CBluetoothSocket::Write(const TDesC8& aDesc) function
+should be used instead.
+
+@param aDesc A descriptor for the data being sent.
+@param aAddr The address of the Bluetooth device.
+@param flags The Bluetooth flags.
+@return KErrNone meaning the operation was successful and data is being sent to the specified
+ and addressed remote device, or KErrInUse meaning a previous SendTo() is not yet finished.
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iSending)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTSender->SendTo(aDesc, aAddr, flags);
+ iSending = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::SendTo(const TDesC8& aDesc,TSockAddr& aAddr,TUint flags,TSockXfrLength& aLen)
+/** Sends the aDesc data to the aAddr specified and applies the flags indicated to the operation.
+
+@see RSocket::SendTo(const TDesC8& aDesc,TSockAddr& aAddr,TUint flags,TSockXfrLength& aLen)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleSendCompleteL(TInt aErr)
+
+If Automatic Sniff Mode is active, using this function will not automatically put the link
+into active mode. If it is required that the link be taken out of sniff mode automatically
+when data is to be sent then the CBluetoothSocket::Write(const TDesC8& aDesc) function
+should be used instead.
+
+@param aDesc A descriptor for the data being sent.
+@param aAddr The address of the Bluetooth device.
+@param flags The Bluetooth flags.
+@param aLen An integer representing the length of the message.
+@return KErrNone meaning the operation was successful and data is being sent to the specified
+ and addressed remote device, or KErrInUse meaning a previous SendTo() is not yet finished.
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iSending)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTSender->SendTo(aDesc, aAddr, flags, aLen);
+ iSending = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags)
+/** Receives aDesc data from the named remote aAddr Bluetooth device using the flags indicated.
+
+@see RSocket::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr)
+@param aDesc A descriptor for the data being received.
+@param aAddr The address of the Bluetooth device.
+@param flags The Bluetooth flags.
+@return KErrNone meaning the operation was successful and data is being received from the specified
+ and addressed remote device, or KErrInUse meaning a previous RecvFrom() is not yet finished.
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->RecvFrom(aDesc, aAddr, flags);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags,TSockXfrLength& aLen)
+/** Receives aDesc data from the named remote aAddr Bluetooth device using the flags indicated.
+
+@see RSocket::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags,TSockXfrLength& aLen)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleReceiveCompleteL(TInt aErr)
+@param aDesc A descriptor for the data being received.
+@param aAddr The address of the Bluetooth device.
+@param flags The Bluetooth flags.
+@param aLen An integer representing the length of the message.
+@return KErrNone meaning the operation was successful and data is being received from the specified
+ and addressed remote device, or KErrInUse meaning a previous RecvFrom() is not yet finished.
+*/
+ {
+ TInt rerr = KErrNone;
+ if(iReceiving)
+ {
+ rerr = KErrInUse;
+ }
+ else
+ {
+ iBTReceiver->RecvFrom(aDesc, aAddr, flags, aLen);
+ iReceiving = ETrue;
+ }
+ return rerr;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Connect(TBTSockAddr& aAddr)
+/** Opens a connection to a specific Bluetooth device by its address.
+
+The address represents the address of the remote Bluetooth device. A socket may
+only have one connect operation outstanding at any one time. Once the connect
+is completed, the socket is ready to send or receive data. If a socket is
+unbound - i.e. Bind() has not been called yet - then it will automatically have
+a local address allocated.
+
+@see RSocket::Connect(TBTSockAddr& aAddr)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleConnectCompleteL(TInt aErr)
+@param aAddr The address of the bluetooth device to which the connection is being made.
+@return KErrInUse if the device is already being used, else KErrNone is the connection is successful.
+*/
+ {
+ if(iBTConnecter)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTConnecter = CBTConnecter::NewL(*this));
+ if(err == KErrNone)
+ {
+ iBTConnecter->Connect(aAddr);
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Connect(TBTSockAddr& aAddr,const TDesC8& aConnectDataOut,TDes8& aConnectDataIn)
+/** Connects to a remote Bluetooth device by address with a defined data-out and data-in descriptor.
+
+The address provided specifies the address of the remote Bluetooth host. Data can be sent in
+connect request packets, which may be provided in the data-out descriptor, or connect responses, which may be collected in the data-in descriptor.
+
+A socket may only have one connect operation outstanding at any one time. Once the connect is completed, the socket is ready to send or receive data. If a socket is unbound - i.e. Bind() has not been called yet - then it will automatically have a local address allocated.
+
+@see RSocket::Connect(TBTSockAddr& aAddr,const TDesC8& aConnectDataOut,TDes8& aConnectDataIn)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleConnectCompleteL(TInt aErr).
+@param aAddr The address of the remote Bluetooth device.
+@param aConnectDataOut A descriptor containing data to be sent.
+@param aConnectDataIn A descriptor to receive data.
+@return KErrInUse if the device is already being used, else KErrNone is the connection is successful.
+*/
+ {
+ if(iBTConnecter)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTConnecter = CBTConnecter::NewL(*this));
+ if(err == KErrNone)
+ {
+ iBTConnecter->Connect(aAddr, aConnectDataOut, aConnectDataIn);
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Connect(TBTSockAddr& aAddr, TUint16 aServiceBits)
+/** Sets the Service bits in the Class Of Device. If this is successful, the socket then opens
+a connection to a specific Bluetooth device by its address.
+
+The address represents the address of the remote Bluetooth device. A socket may
+only have one connect operation outstanding at any one time. Once the connect
+is completed, the socket is ready to send or receive data. If a socket is
+unbound - i.e. Bind() has not been called yet - then it will automatically have
+a local address allocated.
+
+@see RSocket::Connect(TBTSockAddr& aAddr)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleConnectCompleteL(TInt aErr)
+@param aAddr The address of the bluetooth device to which the connection is being made.
+@return KErrInUse if the device is already being used, else KErrNone is the connection is successful.
+*/
+ {
+ TInt err = KErrNone;
+ err = iSocket.SetOpt(KBTRegisterCodService, KSolBtSAPBase, aServiceBits);
+ if(err == KErrNone)
+ {
+ if(iBTConnecter)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTConnecter = CBTConnecter::NewL(*this));
+ if(err == KErrNone)
+ {
+ iBTConnecter->Connect(aAddr);
+ }
+ }
+ return err;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelConnect()
+/** Cancel an attempted connection.
+
+@see RSocket::CancelConnect()
+*/
+ {
+ if(iBTConnecter)
+ {
+ delete iBTConnecter;
+ iBTConnecter = NULL;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::Bind(TSockAddr& aAddr)
+/** Sets a Bluetooth socket address.
+
+Sets the local address of a socket. When a socket is opened it has no name associated
+with it, and binding is required so data can be routed to the socket. Bind() should be
+called before Listen() or Connect().
+
+@param aAddr The address of the socket.
+@see RSocket::Bind(TSockAddr& aAddr)
+@return aAddr The address of the socket.
+*/
+ {
+ return iSocket.Bind(aAddr);
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetLocalPort(TInt aPort)
+/** Sets the local port of a Bluetooth socket.
+
+Setting the local port is equivalent to calling Bind() with only the port set in the address.
+
+@see RSocket::SetLocalPort(TInt aPort)
+@param aPort The socket port.
+@return aPort The socket port.
+*/
+ {
+ return iSocket.SetLocalPort(aPort);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Accept(CBluetoothSocket& aBlankSocket)
+/** Accepts a connection from a remote Bluetooth socket.
+
+The call extracts the first pending connection on a queue of sockets, the queue
+size being previously specified by Listen(). On successful completion the blank
+socket is given the handle of the new socket and it may then be used to transfer
+data. After completion the accept socket may be used to make further connections
+with new blank sockets (see Open() on how to open a blank socket).
+
+@see RSocket::Accept(CBluetoothSocket& aBlankSocket)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function MBluetoothSocketNotifier::HandleAcceptCompleteL(TInt aErr)
+@param aBlankSocket A socket opened as a blank socket.
+@return KErrNone if the connection is established. KErrInUse if a connection already exists.
+*/
+ {
+ if(iBTAccepter)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTAccepter = CBTAccepter::NewL(*this, aBlankSocket));
+ if(err == KErrNone)
+ {
+ iBTAccepter->Accept();
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Accept(CBluetoothSocket& aBlankSocket,TDes8& aConnectData)
+/** Reserved for future.
+
+@param aBlankSocket a socket opened as a blank socket.
+@param aConnectData Data that may be received in connection.
+@return KErrNone if the connection is established. KErrInUse if a connection already exists.
+*/
+ {
+ if(iBTAccepter)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTAccepter = CBTAccepter::NewL(*this, aBlankSocket));
+ if(err == KErrNone)
+ {
+ iBTAccepter->Accept(aConnectData);
+ }
+ return err;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelAccept()
+/** Cancels the Accept() operation.
+@see RSocket::CancelAccept()
+*/
+ {
+ if(iBTAccepter)
+ {
+ delete iBTAccepter;
+ iBTAccepter = NULL;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::Listen(TUint qSize)
+/** Sets up a socket to listen for incoming connections.
+
+Before calling this procedure a socket should be opened using Open() and be bound
+to a local address using Bind().
+
+Listen() creates a queue to hold incoming connections which can be married with
+blank sockets using Accept().
+
+Once a listen queue has been created it will continue to allow peers to connect until
+it is full, at which point it will reject any incoming connections as specified by
+protocol behaviour. When a socket is accepted by the client a space is made
+available in the queue.
+
+@see RSocket::Listen(TUint qSize)
+@param qSize The number of connections allowed in the queue.
+@return The 'listen' queue.
+*/
+ {
+ return iSocket.Listen(qSize);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Listen(TUint qSize,const TDesC8& aConnectData)
+/** Reserved for future.
+
+@see RSocket::Listen(TUint qSize,const TDesC8& aConnectData)
+@param qSize The size of the 'listen' queue.
+@param aConnectData The descriptor for data sent in connection respoonses.
+@return The 'listen' queue.
+*/
+ {
+ return iSocket.Listen(qSize,aConnectData);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Listen(TUint qSize, TUint16 aServiceBits)
+/** Sets the Service bits in the Class Of Device. If this is successful, the socket
+will then be set to Listen for incoming connections.
+
+Before calling this procedure a socket should be opened using Open() and be bound
+to a local address using Bind().
+
+Listen() creates a queue to hold incoming connections which can be married with
+blank sockets using Accept().
+
+Once a listen queue has been created it will continue to allow peers to connect until
+it is full, at which point it will reject any incoming connections as specified by
+protocol behaviour. When a socket is accepted by the client a space is made
+available in the queue.
+
+@see RSocket::Listen(TUint qSize)
+@param qSize The number of connections allowed in the queue.
+@return The 'listen' queue.
+*/
+ {
+ TInt err = KErrNone;
+ err = iSocket.SetOpt(KBTRegisterCodService, KSolBtSAPBase, aServiceBits);
+ if(err == KErrNone)
+ {
+ return iSocket.Listen(qSize);
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetOption(TUint aOptionName, TUint aOptionLevel,const TDesC8& aOption)
+/** Sets a socket option.
+
+The socket server has options which are generic to all sockets and protocols may add specific options.
+
+Options available for all protocols can be set with anOptionLevel set to KSOLSocket. See individual protocol notes for other socket options.
+
+@see RSocket::SetOpt(TUint aOptionName, TUint aOptionLevel,const TDesC8& aOption)
+@param aOptionName An option identifier.
+@param aOptionLevel An option level. Option levels 'group' related options.
+@param aOption The option value as a descriptor.
+@return The socket options set.
+*/
+ {
+ return iSocket.SetOpt(aOptionName, aOptionLevel,aOption);
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetOpt(TUint aOptionName, TUint aOptionLevel,const TDesC8& aOption)
+/** Sets a socket option.
+
+The socket server has options which are generic to all sockets and protocols may add specific options.
+
+Options available for all protocols can be set with anOptionLevel set to KSOLSocket. See individual protocol notes for other socket options.
+
+@see RSocket::SetOpt(TUint aOptionName, TUint aOptionLevel,const TDesC8& aOption)
+@param aOptionName An option identifier.
+@param aOptionLevel An option level. Option levels 'group' related options.
+@param aOption The option value as a descriptor.
+@return The socket options set.
+@deprecated
+*/
+ {
+ return iSocket.SetOpt(aOptionName, aOptionLevel,aOption);
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetOpt(TUint aOptionName,TUint aOptionLevel,TInt aOption)
+/** Sets a socket option.
+
+The socket server has options which are generic to all sockets and protocols may add specific options.
+
+Options available for all protocols can be set with anOptionLevel set to KSOLSocket. See individual protocol notes for other socket options.
+
+@see RSocket::SetOpt(TUint aOptionName, TUint aOptionLevel,const TDesC8& aOption)
+@param aOptionName An option identifier.
+@param aOptionLevel An option level. Option levels 'group' related options.
+@param aOption The option value as an integer.
+@return The socket options set.
+*/
+ {
+ return iSocket.SetOpt(aOptionName, aOptionLevel,aOption);
+ }
+
+EXPORT_C TInt CBluetoothSocket::GetOpt(TUint aOptionName,TUint aOptionLevel,TDes8& aOption)
+/** Gets a socket option.
+
+The socket server has options which are generic to all sockets and protocols may add specific options.
+
+Options available for all protocols can be got with anOptionLevel set to KSOLSocket. See individual protocol notes for other socket options.
+
+@see RSocket::GetOpt(TUint aOptionName,TUint aOptionLevel,TDes8& aOption)
+@param aOptionName An option identifier.
+@param aOptionLevel An option level. Option levels 'group' related options.
+@param aOption The option value as a descriptor.
+@return The socket options set.
+*/
+ {
+ return iSocket.GetOpt(aOptionName, aOptionLevel, aOption);
+ }
+
+EXPORT_C TInt CBluetoothSocket::GetOpt(TUint aOptionName,TUint aOptionLevel,TInt &aOption)
+/** Gets a socket option.
+
+The socket server has options which are generic to all sockets and protocols may add specific options.
+
+Options available for all protocols can be got with anOptionLevel set to KSOLSocket. See individual protocol notes for other socket options.
+
+@see RSocket::GetOpt(TUint aOptionName,TUint aOptionLevel,TDes8& aOption)
+@param aOptionName An option identifier.
+@param aOptionLevel An option level. Option levels 'group' related options.
+@param aOption The option value as an integer.
+@return The socket options set.
+*/
+ {
+ return iSocket.GetOpt(aOptionName, aOptionLevel, aOption);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Ioctl(TUint aLevel, TUint aCommand,TDes8* aDesc)
+/** Applies an asynchronous control operation on a socket.
+
+Data may be passed and received if a descriptor address is provided as an argument.
+Only one Ioctl() operation may be outstanding for each socket.
+
+@see RSocket::Ioctl(TUint aCommand,TDes8* aDesc,TUint aLevel)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleIoctlCompleteL(TInt aErr)
+@param aCommand ioctl command.
+@param aDesc Pointer to a descriptor in which data may be sent and received on completion.
+@param aLevel Control operation level.
+@return KErrNone if the ioctl command is applied or
+ KErrInUse if another ioctl command is still being used.
+*/
+ {
+ if(iBTIoctler)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTIoctler = CBTIoctler::NewL(*this));
+ if(err == KErrNone)
+ {
+ iBTIoctler->Ioctl(aCommand, aDesc, aLevel);
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Ioctl(TUint aCommand,TDes8* aDesc,TUint aLevel)
+/** Applies an asynchronous control operation on a socket.
+
+Data may be passed and received if a descriptor address is provided as an argument.
+Only one Ioctl() operation may be outstanding for each socket.
+
+@see RSocket::Ioctl(TUint aCommand,TDes8* aDesc,TUint aLevel)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleIoctlCompleteL(TInt aErr)
+@param aCommand ioctl command.
+@param aDesc Pointer to a descriptor in which data may be sent and received on completion.
+@param aLevel Control operation level.
+@return KErrNone if the ioctl command is applied or
+ KErrInUse if another ioctl command is still being used.
+@deprecated
+*/
+ {
+ if(iBTIoctler)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTIoctler = CBTIoctler::NewL(*this));
+ if(err == KErrNone)
+ {
+ iBTIoctler->Ioctl(aCommand, aDesc, aLevel);
+ }
+ return err;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelIoctl()
+/** Cancels the Ioctl() asynchronous control operation.
+@see RSocket::CancelIoctl()
+*/
+ {
+ if(iBTIoctler)
+ {
+ delete iBTIoctler;
+ iBTIoctler = NULL;
+ }
+ }
+
+EXPORT_C TInt CBluetoothSocket::GetDisconnectData(TDes8& aDesc)
+/**
+@see RSocket::GetDisconnectData(TDes8& aDesc)
+@param aDesc A descriptor for the disconnect data.
+@return KErrNone if successful.
+*/
+ {
+ return iSocket.GetDisconnectData(aDesc);
+ }
+
+EXPORT_C void CBluetoothSocket::LocalName(TSockAddr& aAddr)
+/** Gets the local address of a socket.
+
+The local address is set either by calling Bind() or it is automatically set when Connect()
+is called. If a socket is created through Accept() then a socket will inherit the port of
+its parent unless otherwise specified by a protocol's behaviour.
+@see RSocket::LocalName(TSockAddr& aAddr)
+@param aAddr The socket address.
+*/
+ {
+ iSocket.LocalName(aAddr);
+ }
+
+EXPORT_C TUint CBluetoothSocket::LocalPort()
+/** Gets the local port of a socket.
+
+Similar to LocalName().
+
+@see RSocket::LocalPort()
+@return The local port of the socket.
+*/
+ {
+ return iSocket.LocalPort();
+ }
+
+EXPORT_C void CBluetoothSocket::RemoteName(TSockAddr& aAddr)
+/** Gets the remote address of a socket.
+
+The remote name (address) of a socket is associated with the remote host the
+socket is connected to. The remote name is only valid for a connected socket.
+A socket is either connected through calling Connect() or Accept().
+
+@see RSocket::RemoteName(TSockAddr& aAddr)
+@param aAddr The remote socket address.
+*/
+ {
+ iSocket.RemoteName(aAddr);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Shutdown(RSocket::TShutdown aHow)
+/** Shuts down a connected socket. (The socket cannot be null. @see
+CBluetoothSocket::Info.)
+
+The shutdown method allows input and output to be individually stopped for
+a protocol endpoint.
+
+@see RSocket::Shutdown(RSocket::TShutdown aHow)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleShutdownCompleteL(TInt aErr)
+@param aHow Shutdown option. All variants complete when a socket is disconnected.
+@return KErrNone if successful or
+ KErrInUse if the system is already trying to shutdown a connected socket.
+*/
+ {
+ if(iBTShutdowner)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTShutdowner = CBTShutdowner::NewL(*this));
+ if(err == KErrNone)
+ {
+ // AutomaticSniff mode should be unset, to avoid situation
+ // when sniff request is sent while we are in the middle of disconnection.
+ if ( AutomaticSniffMode() )
+ {
+ (void) SetAutomaticSniffMode(EFalse);
+ }
+ // If we are in one of LMP, in order to disconnect, link needs
+ // to be put into acitve mode. It can happen that before link
+ // disconnects LMP requester acknowledges that link is in active mode,
+ // and will send LMP request. Therefore all LMP requesters should
+ // be cancelled before disconnecting socket.
+ else
+ {
+ (void) CancelLowPowerModeRequester();
+ }
+ iBTShutdowner->Shutdown(aHow);
+ }
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::Shutdown(RSocket::TShutdown aHow,const TDesC8& aDisconnectDataOut,TDes8& aDisconnectDataIn)
+/** Reserved for future.
+The socket must not be null. (@see CBluetoothSocket::Info.)
+@see RSocket::Shutdown(RSocket::TShutdown aHow,const TDesC8& aDisconnectDataOut,TDes8& aDisconnectDataIn)
+
+When this request completes, notification is sent to the MBluetoothSocketNotifier
+object supplied when this CBluetoothSocket was constructed.
+This is done in the function
+MBluetoothSocketNotifier::HandleShutdownCompleteL(TInt aErr)
+@param aHow Shutdown option. All variants complete when a socket is disconnected.
+@param aDisconnectDataOut A descriptor to send data.
+@param aDisconnectDataIn A descriptor to recive data.
+@return KErrNone if successful or
+ KErrInUse if the system is already trying to shutdown a connected socket.
+*/
+ {
+ if(iBTShutdowner)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTShutdowner = CBTShutdowner::NewL(*this));
+ if(err == KErrNone)
+ {
+ // AutomaticSniff mode should be unset, to avoid situation
+ // when sniff request is sent while we are in the middle of disconnection.
+ if ( AutomaticSniffMode() )
+ {
+ (void) SetAutomaticSniffMode(EFalse);
+ }
+ // If we are in one of LMP, in order to disconnect, link needs
+ // to be put into acitve mode. It can happen that before link
+ // disconnects LMP requester acknowledges that link is in active mode,
+ // and will send LMP request. Therefore all LMP requesters should
+ // be cancelled before disconnecting socket.
+ else
+ {
+ (void) CancelLowPowerModeRequester();
+ }
+ iBTShutdowner->Shutdown(aHow, aDisconnectDataOut, aDisconnectDataIn);
+ }
+ return err;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelAll()
+/** Cancels all outstanding operations.
+
+Calling it will cause all outstanding operations to cancel. Outstanding operations
+for a socket include: read, write, Ioctl, connect, accept, shutdown and the Baseband
+event notifier. All of these operations will be completed by this call.
+*/
+ {
+ //Sort any active objects
+ delete iBTConnecter;
+ iBTConnecter = NULL;
+ delete iBTAccepter;
+ iBTAccepter = NULL;
+ delete iBTIoctler;
+ iBTIoctler = NULL;
+ delete iBTBasebandChangeEventNotifier;
+ iBTBasebandChangeEventNotifier = NULL;
+ CancelSend(); //ao not deleted
+ CancelRecv(); //ao not deleted
+ // The shutdowner may need to be canceled.
+// if(iBTShutdowner)
+// {
+// iBTShutdowner->Cancel();
+// }
+
+ iSocket.CancelAll(); //belt and braces
+ }
+
+EXPORT_C TInt CBluetoothSocket::Info(TProtocolDesc& aProtocol)
+/** Gets information about the protocol the socket is opened on.
+@see RSocket::Info(TProtocolDesc& aProtocol)
+@param aProtocol The protocol on which the socket is opened. Note that if the
+socket is a null socket, and aProtocol is a null TProtocolDesc when it is
+passed in, if will be null on return as well.
+@return KErrNone if successful.
+*/
+ {
+ return iSocket.Info(aProtocol);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Name(TName& aName)
+/** Used to get a unique name of a socket.
+
+The name is needed when Transfer() is called.
+
+@see RSocket::Name(TName& aName)
+@param aName The system name of a socket.
+@return KErrNone if successful.
+*/
+ {
+ return iSocket.Name(aName);
+ }
+
+EXPORT_C TInt CBluetoothSocket::Transfer(RSocketServ& aServer, const TDesC& aName)
+/** Transfers a socket from one socket server session to another.
+
+It creates the socket in the target session, and removes the socket from the source
+session. The call is made on an uninitialised RSocket object. The socket system name
+'Name()' is used to identify the socket to transfer.
+
+If the call fails, the socket that is being transferred remains with the original session.
+Success or failure can be checked on the originating socket by calling Info(), which returns
+KErrNone if the transfer failed, and KErrBadHandle if it succeeded.
+
+@see RSocket::Transfer(RSocketServ& aServer, const TDesC& aName)
+@param aServer The session to which the socket is being transfered
+@param aName The system name of the socket being transfered.
+@return KErrNone if successful.
+*/
+ {
+ return iSocket.Transfer(aServer, aName);
+ }
+
+
+
+
+
+
+//RBTBaseband functions
+//Getter
+EXPORT_C TInt CBluetoothSocket::PhysicalLinkState(TUint32& aState)
+/** Get the state of the physical link.
+@see RBTPhysicalLinkAdapter::PhysicalLinkState(TUint32& aState)
+@param aState The state of the physical link.
+@return The state of the physical link.
+*/
+ {
+ return iBTBaseband.PhysicalLinkState(aState);
+ }
+
+
+
+//Role change functions
+EXPORT_C TInt CBluetoothSocket::PreventRoleSwitch()
+/** Role switching is not allowed.
+@see RBTPhysicalLinkAdapter::PreventRoleSwitch()
+@return KErrNone if successful.
+*/
+ {
+ return iBTBaseband.PreventRoleSwitch();
+ }
+
+EXPORT_C TInt CBluetoothSocket::AllowRoleSwitch()
+/** Allow the socket to switch roles.
+@see RBTPhysicalLinkAdapter::AllowRoleSwitch()
+@return KErrNone if successful.
+*/
+ {
+ return iBTBaseband.AllowRoleSwitch();
+ }
+
+EXPORT_C TInt CBluetoothSocket::RequestMasterRole()
+/** Request the socket take on the master role.
+@see RBTPhysicalLinkAdapter::RequestMasterRole()
+@return KErrNone if successful.
+*/
+ {
+ return iBTBaseband.RequestMasterRole();
+ }
+
+EXPORT_C TInt CBluetoothSocket::RequestSlaveRole()
+/** Request the socket take on a slave role.
+@see RBTPhysicalLinkAdapter::RequestSlaveRole()
+@return KErrNone if successful.
+*/
+ {
+ return iBTBaseband.RequestSlaveRole();
+ }
+
+
+//Low power mode functions
+EXPORT_C TInt CBluetoothSocket::PreventLowPowerModes(TUint32 aLowPowerModes)
+/** Prevents low power modes from being activated.
+@see RBTPhysicalLinkAdapter::PreventLowPowerModes(TUint32 aLowPowerModes)
+@param aLowPowerModes The low power mode being prevented.
+@return KErrNone if successful.
+ KErrInUse if the socket is using automatic sniff mode.
+@panic EInvalidOpWhenAutoSniffOn (10) This API is not allowed when AutoSniff is On
+*/
+ {
+ TInt err(KErrNone);
+ __ASSERT_ALWAYS(!AutomaticSniffMode(), Panic(EInvalidOpWhenAutoSniffOn));
+ err = iBTBaseband.PreventLowPowerModes(aLowPowerModes);
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::AllowLowPowerModes(TUint32 aLowPowerModes)
+/** Allow low power modes.
+
+The power modes are indicated by aLowPowerModes.
+
+@see RBTPhysicalLinkAdapter::AllowLowPowerModes(TUint32 aLowPowerModes)
+@param aLowPowerModes The low power mode.
+@return KErrNone if successful.
+ KErrInUse if the socket is using automatic sniff mode.
+@panic EInvalidOpWhenAutoSniffOn (10) This API is not allowed when AutoSniff is On
+*/
+ {
+ TInt err(KErrNone);
+ __ASSERT_ALWAYS(!AutomaticSniffMode(), Panic(EInvalidOpWhenAutoSniffOn));
+ err = iBTBaseband.AllowLowPowerModes(aLowPowerModes);
+ return err;
+ }
+
+
+//Low power mode functions
+EXPORT_C TInt CBluetoothSocket::ActivateSniffRequester()
+/**
+@see RBTPhysicalLinkAdapter::ActivateSniffRequester()
+@return KErrNone if successful.
+ KErrInUse if the socket is using automatic sniff mode.
+@panic EInvalidOpWhenAutoSniffOn (10) This API is not allowed when AutoSniff is On
+*/
+ {
+ TInt err(KErrNone);
+ __ASSERT_ALWAYS(!AutomaticSniffMode(), Panic(EInvalidOpWhenAutoSniffOn));
+ err = iBTBaseband.ActivateSniffRequester();
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::ActivateParkRequester()
+/** Activate park requestor.
+@see RBTPhysicalLinkAdapter::ActivateParkRequester()
+@return KErrNone if successful.
+ KErrInUse if the socket is using automatic sniff mode.
+@panic EInvalidOpWhenAutoSniffOn (10) This API is not allowed when AutoSniff is On
+*/
+ {
+ TInt err(KErrNone);
+ __ASSERT_ALWAYS(!AutomaticSniffMode(), Panic(EInvalidOpWhenAutoSniffOn));
+ err = iBTBaseband.ActivateParkRequester();
+ return err;
+ }
+
+EXPORT_C TInt CBluetoothSocket::CancelLowPowerModeRequester()
+/** Cancels the low power mode request.
+@see RBTPhysicalLinkAdapter::CancelLowPowerModeRequester()
+@return KErrNone if successful.
+ KErrInUse if the socket is using automatic sniff mode.
+@panic EInvalidOpWhenAutoSniffOn (10) This API is not allowed when AutoSniff is On
+*/
+ {
+ TInt err(KErrNone);
+ __ASSERT_ALWAYS(!AutomaticSniffMode(), Panic(EInvalidOpWhenAutoSniffOn));
+ err = iBTBaseband.CancelLowPowerModeRequester();
+ return err;
+ }
+
+
+//Packet function
+EXPORT_C TInt CBluetoothSocket::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes)
+/** Request to change the supported packet types.
+@see RBTPhysicalLinkAdapter::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes)
+@param Integer representing the packet types.
+@return KErrNone if successful.
+*/
+ {
+ return iBTBaseband.RequestChangeSupportedPacketTypes(aPacketTypes);
+ }
+
+
+//Notification functions
+EXPORT_C TInt CBluetoothSocket::ActivateBasebandEventNotifier(TUint32 aEventTypes)
+/** Set up notification of baseband events
+
+Elect to be notified whenever one of a user specified selection
+of baseband events occurs.
+
+The notification takes place in the pure virtual function
+MBluetoothSocketNotifier::HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification& aEventNotification)
+
+The FIRST notification will take place ALMOST INSTANTANEOUSLY and will be
+A FULL DESCRIPTION (OR SNAPSHOT) OF THE CURRENT STATE OF THE PHYSICAL LINK
+irrespective of the specified selection of events wanted. This first notification or
+snapshot has NOTHING to do with a baseband event occurring. Once this snapshot has
+taken place, all occurrences of the specified events from the instant of the snapshot
+onwards will be notified until CBluetoothSocket::CancelBasebandEventNotifier() is called.
+
+@see PhysicalLinkState(TUint32& aState) if only a single full
+description of the physical link state is required.
+
+@param aEventTypes bitmask for those events for which notification is being requested
+(Combine elements of TBTPhysicalLinkStateNotifier and TBTPhysicalLinkStateNotifierCombinations)
+@see TBTPhysicalLinkStateNotifier
+@see TBTPhysicalLinkStateNotifierCombinations
+@return KErrNone if activated or KErrInUse if the baseband event notifier is already being used.
+*/
+ {
+ if(iBTBasebandChangeEventNotifier)
+ {
+ return KErrInUse;
+ }
+
+ TRAPD(err, iBTBasebandChangeEventNotifier = CBTBasebandChangeEventNotifier::NewL(*iBTBasebandChangeEventDelegate));
+ if(err == KErrNone)
+ {
+ iNotifierEventMask = aEventTypes;
+ iBTBasebandChangeEventNotifier->SetNotify(iNotifierEventMask);
+ }
+ return err;
+ }
+
+EXPORT_C void CBluetoothSocket::CancelBasebandEventNotifier()
+/** Cancels an active baseband notifier.
+
+No further baseband events will be notified.
+
+If this function is called when there is no active baseband notifier,
+it will do nothing.
+*/
+ {
+ if(iBTBasebandChangeEventNotifier)
+ {
+ delete iBTBasebandChangeEventNotifier;//calls Cancel()
+ iBTBasebandChangeEventNotifier = NULL;
+ }
+ }
+
+EXPORT_C void CBluetoothSocket::SetNotifier(MBluetoothSocketNotifier& aNewNotifier)
+/** Changes the owner (receiver of notifications) of the socket.
+
+The previous notifier will not be deleted after the change has been made.
+
+@param aNewNotifier The object which will receive asynchronous events.
+*/
+ {
+ // We do not delete the current notifier as although it is stored as a
+ // pointer we do not own it. (it is always passed to us by reference).
+ iNotifier = &aNewNotifier;
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetAutomaticSniffMode(TBool aAutoSniffMode)
+/** Sets up automatic sniff/unsniff requesting for the socket.
+
+If Automatic Sniff requesting is being selected, a timer with default delay in seconds before the idle socket will
+request the link to go into sniff mode. The CBluetoothSocket::Write() method will clear an outstanding sniff
+requester and start the CAutoSniffDelayTimer active object which will issue another request for sniff mode once it
+times out.
+
+If Automatic Sniff requesting is being deselected, a previous sniff requester will be cancelled.
+
+If Automatic Sniff requesting is selected when it is already active, no change will be performed and KErrInUse will
+be returned
+
+@param aAutoSniffMode ETrue if Automatic Sniff/Unsniff requests are required.
+@return KErrNone if the automatic sniff mode has been successfully changed.
+ KErrInUse if automatic sniff mode is requested, when it is already active.
+ KErrArgument if an invalid idle timer value for the sniff request is provided.
+ A Symbian wide error code for another other error that might have occurred.
+*/
+ {
+ const TInt KDefaultSecondsBeforeSniffRequest = 5;
+ return SetAutomaticSniffMode(aAutoSniffMode, KDefaultSecondsBeforeSniffRequest);
+ }
+
+EXPORT_C TInt CBluetoothSocket::SetAutomaticSniffMode(TBool aAutoSniffMode, TInt aIdleSecondsBeforeSniffRequest)
+/** Sets up automatic sniff/unsniff requesting for the socket.
+
+If Automatic Sniff requesting is being selected, supply the delay in seconds required before the idle socket will
+request the link to go into sniff mode. The CBluetoothSocket::Write() method will clear an outstanding sniff
+requester and start the CAutoSniffDelayTimer active object which will issue another request for sniff mode once
+it times out.
+
+If Automatic Sniff requesting is being deselected, a previous sniff requester will be cancelled.
+
+If Automatic Sniff requesting is selected when it is already active, no change will be performed and KErrInUse will
+be returned
+
+@param aAutoSniffMode ETrue if Automatic Sniff/Unsniff requests are required.
+@param aIdleSecondsBeforeSniffRequest A delay after the socket becomes idle before it will request sniff mode.
+@return KErrNone if the automatic sniff mode has been successfully changed.
+ KErrInUse if automatic sniff mode is requested, when it is already active.
+ KErrArgument if an invalid idle timer value for the sniff request is provided.
+ A Symbian wide error code for another other error that might have occurred.
+*/
+ {
+ TInt err(KErrNone);
+ TBool usingAutoSniffMode = AutomaticSniffMode();
+
+ if(aAutoSniffMode && usingAutoSniffMode)
+ {
+ // if we request auto sniff requesting when it is already active we error.
+ err = KErrInUse;
+ }
+ else if(aAutoSniffMode)
+ {
+ if(aIdleSecondsBeforeSniffRequest > 0)
+ {
+ // if here we know iAutoSniffDelayTimer is NULL, so there is no need to delete
+ __ASSERT_DEBUG(!iAutoSniffDelayTimer, Panic(EUnfinishedBusiness));
+ TRAP(err, iAutoSniffDelayTimer = CAutoSniffDelayTimer::NewL(*this, aIdleSecondsBeforeSniffRequest));
+ if(err == KErrNone)
+ {
+ err = iBTBaseband.CancelLowPowerModeRequester();
+ }
+ }
+ else
+ {
+ err = KErrArgument;
+ }
+ }
+ else if(usingAutoSniffMode)
+ {
+ delete iAutoSniffDelayTimer;
+ iAutoSniffDelayTimer = NULL;
+ }
+
+ return err;
+ }
+
+
+EXPORT_C TBool CBluetoothSocket::AutomaticSniffMode() const
+/** Reports the automatic sniff/unsniff requesting status of the socket.
+
+@return ETrue if automatic sniff/unsniff has been selected for this socket.
+*/
+ {
+ return iAutoSniffDelayTimer ? ETrue : EFalse;
+ }
+
+EXPORT_C void CBluetoothSocket::AsyncDelete()
+/** Asynchronous deletion of the CBluetoothSocket object.
+
+Function will cause asynchronous deletion of CBluetoothSocket object.
+It should be called if associated MBluetoothSocketNotifier needs to delete
+CBluetoothSocket from any of its callback functions.
+*/
+ {
+ iAsyncDestroyer->CallBack();
+ }
+
+
+MBluetoothSocketNotifier& CBluetoothSocket::Notifier()
+ {
+ // iNotifier should never be null, so a deref. is always valid.
+ return static_cast<MBluetoothSocketNotifier&> (*iNotifier);
+ }
+
+void CBluetoothSocket::ConfigureSocket()
+ {
+ // This is done as a best effort in order to make more efficient usage
+ // of the baseband packets being created. As a result we don't bother
+ // checking the results as if they fail it won't cause the socket to
+ // behave incorrectly
+ TPckgBuf<TUint> optBuf(65535); //If all else fails we should get a max 64K buffer
+ TProtocolDesc info;
+
+ TInt err = iSocket.Info(info);
+
+ if (err == KErrNone && info.iProtocol == KRFCOMM)
+ {
+ // For RFCOMM we set the buffers based on the optimal MTU for RFCOMM
+ iSocket.GetOpt(KRFCOMMMaximumMTU, KSolBtRFCOMM, optBuf);
+ iSocket.SetOpt(KSOSendBuf, KSOLSocket, optBuf);
+ iSocket.SetOpt(KSORecvBuf, KSOLSocket, optBuf);
+ }
+ else
+ {
+ // For L2CAP, or others, we just ensure that we can accomodate the negotiated MTU
+ iSocket.GetOpt(KL2CAPNegotiatedOutboundMTU, KSolBtL2CAP, optBuf);
+ iSocket.SetOpt(KSOSendBuf, KSOLSocket, optBuf);
+
+ iSocket.GetOpt(KL2CAPInboundMTU, KSolBtL2CAP, optBuf);
+ iSocket.SetOpt(KSORecvBuf, KSOLSocket, optBuf);
+ }
+ }
+
+void CBluetoothSocket::HandleConnectCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleConnectCompleteL(aErr %d)"), aErr));
+ delete iBTConnecter;
+ iBTConnecter = NULL;
+
+ if (aErr == KErrNone)
+ {
+ ConfigureSocket();
+ }
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+#ifdef __FLOGGING__
+ TRAPD(err, Notifier().HandleConnectCompleteL(aErr));
+ FTRACE(FPrint(_L("Connect upcall to link owner returned %d"), err));
+ User::LeaveIfError(err);
+#else
+ Notifier().HandleConnectCompleteL(aErr);
+#endif
+ }
+
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleConnectCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleAcceptCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleAcceptCompleteL(aErr %d)"), aErr));
+ delete iBTAccepter;
+ iBTAccepter = NULL;
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+#ifdef __FLOGGING__
+ TRAPD(err, Notifier().HandleAcceptCompleteL(aErr));
+ FTRACE(FPrint(_L("Accept upcall to link owner returned %d"), err));
+ User::LeaveIfError(err);
+#else
+ Notifier().HandleAcceptCompleteL(aErr);
+#endif
+ }
+
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleAcceptCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleShutdownCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleShutdownCompleteL(aErr %d)"), aErr));
+
+ CancelAll();
+ BTBasebandManager().HandleConnectionDown();
+
+ delete iBTShutdowner;
+ iBTShutdowner = NULL;
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+#ifdef __FLOGGING__
+ TRAPD(err, Notifier().HandleShutdownCompleteL(aErr));
+ FTRACE(FPrint(_L("Shutdown upcall to link owner returned %d"), err));
+ User::LeaveIfError(err);
+#else
+ Notifier().HandleShutdownCompleteL(aErr);
+#endif
+ }
+
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleShutdownCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleSendCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleSendCompleteL(aErr %d)"), aErr));
+ iSending = EFalse;
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+ Notifier().HandleSendCompleteL(aErr);
+ }
+
+ FLOG(_L("Send complete upcall complete"));
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleSendCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleReceiveCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleReceiveCompleteL(aErr %d)"), aErr));
+ iReceiving = EFalse;
+ if(iAutoSniffDelayTimer)
+ {
+ iAutoSniffDelayTimer->Start();
+ }
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+ Notifier().HandleReceiveCompleteL(aErr);
+ }
+
+ FLOG(_L("Receive complete upcall complete"));
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleReceiveCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleIoctlCompleteL(TInt aErr)
+ {
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleIoctlCompleteL(aErr %d)"), aErr));
+ delete iBTIoctler;
+ iBTIoctler = NULL;
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+#ifdef __FLOGGING__
+ TRAPD(err, Notifier().HandleIoctlCompleteL(aErr));
+ FTRACE(FPrint(_L("Ioctl upcall to link owner returned %d"), err));
+ User::LeaveIfError(err);
+#else
+ Notifier().HandleIoctlCompleteL(aErr);
+#endif
+ }
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleIoctlCompleteL(aErr);
+ }
+
+void CBluetoothSocket::HandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification aEventNotification)
+ {
+ iBTBasebandChangeEventNotifier->SetNotify(iNotifierEventMask);
+
+ // If AsyncDestroyer was called, client could delete associated MBluetoothSocketNotifier
+ // therefore no further calls to iNotifier should be made.
+ if (!iAsyncDestroyer->IsActive())
+ {
+ Notifier().HandleActivateBasebandEventNotifierCompleteL(aErr, aEventNotification);
+ }
+
+ // Third parties intend to delete CBluetoothSocket object from upcall to
+ // associated MBluetoothSocketNotifier, therefore we should make sure that
+ // there is no code to execute after upcall Notifier().HandleActivateBasebandEventNotifierCompleteL(aErr, aEventNotification);
+ }
+
+//
+//Getters
+//
+
+RSocket& CBluetoothSocket::Socket()
+ {
+ return iSocket;
+ }
+
+RSocketServ& CBluetoothSocket::SocketServer()
+ {
+ return iSockServer;
+ }
+
+RBTBaseband& CBluetoothSocket::BTBaseband()
+ {
+ return iBTBaseband;
+ }
+
+CBTBasebandManager& CBluetoothSocket::BTBasebandManager()
+ {
+ return *iBTBasebandManager;
+ }
+
+
+
+
+//
+//Private Functions
+//
+
+CBluetoothSocket::CBluetoothSocket(MBluetoothSocketNotifier& aNotifier, RSocketServ& aServer)
+: iSockServer(aServer), iNotifier(&aNotifier), iNotifierEventMask(0), iSending(EFalse), iReceiving(EFalse)
+//
+//Constructor
+//
+ {
+ }
+
+//RSocket 'Open' functions now called in NewL overloads
+void CBluetoothSocket::ConstructL(TUint sockType, TUint protocol)
+ {
+ User::LeaveIfError(Socket().Open(iSockServer, KBTAddrFamily, sockType, protocol));
+ InitialiseL();
+ }
+
+void CBluetoothSocket::ConstructL(TUint sockType,TUint protocol, RConnection& aConnection)
+ {
+ User::LeaveIfError(Socket().Open(iSockServer, KBTAddrFamily, sockType, protocol, aConnection));
+ InitialiseL();
+ }
+
+void CBluetoothSocket::ConstructL(const TDesC& aName)
+ {
+ User::LeaveIfError(Socket().Open(iSockServer, aName));
+ InitialiseL();
+ }
+
+void CBluetoothSocket::ConstructL()
+ {
+ User::LeaveIfError(Socket().Open(iSockServer));
+ InitialiseL();
+ }
+
+void CBluetoothSocket::ConstructL(RSocket& aSocket)
+ {
+ // We create the Sender and Receiver first, so that if either
+ // leave during construction the original RSocket handle will
+ // still be valid (as it has not yet been transferred.)
+ InitialiseL();
+
+ // If we leave from now on, the original RSocket should still
+ // be valid (as it won't have successfully transferred.)
+ TName name;
+ aSocket.Name(name);
+ User::LeaveIfError(Socket().Transfer(SocketServer(), name));
+
+ TProtocolDesc protocolDesc;
+ // We expect a KErrBadHandle from the original socket.
+ if (KErrBadHandle != aSocket.Info(protocolDesc))
+ {
+ // Otherwise we leave with the status of the internal RSocket.
+ User::Leave(Socket().Info(protocolDesc));
+ }
+ }
+
+void CBluetoothSocket::InitialiseL()
+ {
+ iBTSender = CBTSender::NewL(*this);
+ iBTReceiver = CBTReceiver::NewL(*this);
+ iBTBasebandManager = CBTBasebandManager::NewL();
+ iBTBasebandChangeEventDelegate = CBTBasebandChangeEventDelegate::NewL(*this);
+ User::LeaveIfError(BTBasebandManager().RegisterBTBaseband(*iBTBasebandChangeEventDelegate));
+
+ TCallBack asyncDelete(AsyncDeleteCallBack, this);
+ iAsyncDestroyer = new (ELeave) CAsyncCallBack(asyncDelete, CActive::EPriorityStandard);
+ }
+
+TInt CBluetoothSocket::AsyncDeleteCallBack(TAny *aThisPtr)
+ {
+ __ASSERT_DEBUG(aThisPtr, Panic(ENullPointerInAsyncDelete));
+ CBluetoothSocket* self = static_cast<CBluetoothSocket*>(aThisPtr);
+ delete self;
+ return KErrNone;
+ }
+
+
+//==========================================================
+//Active Object Helpers
+//
+
+//
+//for CBluetoothSocket
+//
+
+//--
+CBTConnecter* CBTConnecter::NewL(CBluetoothSocket& aParent)
+ {
+ CBTConnecter* self = new (ELeave) CBTConnecter(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+CBTConnecter::CBTConnecter(CBluetoothSocket& aParent)
+: CActive(CActive::EPriorityStandard),iParent(aParent)
+//
+//Constructor - the CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ }
+
+void CBTConnecter::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTConnecter::~CBTConnecter()
+//
+//Destructor
+//
+ {
+ Cancel();
+ iActiveModeRequester.Close();
+ }
+
+void CBTConnecter::Connect(TBTSockAddr& aSockAddr)
+//
+//Attempts to connect to the remote device.
+//
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Connect(aSockAddr, iStatus);
+
+
+ if (iParent.AutomaticSniffMode())
+ {
+ TBTDevAddr devAddr = aSockAddr.BTAddr();
+ TInt err = iActiveModeRequester.Open(iParent.SocketServer(), devAddr);
+ if(err == KErrNone)
+ {
+ // If there is an error, there is nothing we can do about it. This is safe to
+ // do as the only effect is that we will fail to ensure connection is done in active
+ // mode.
+ (void)iActiveModeRequester.RequestExplicitActiveMode(ETrue);
+ }
+ }
+
+ SetActive();
+ }
+
+void CBTConnecter::Connect(TBTSockAddr& aSockAddr, const TDesC8& aConnectDataOut, TDes8& aConnectDataIn)
+//
+//Attempts to connect to the remote device.
+//
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Connect(aSockAddr, aConnectDataOut, aConnectDataIn, iStatus);
+
+ if (iParent.AutomaticSniffMode())
+ {
+ TBTDevAddr devAddr = aSockAddr.BTAddr();
+ TInt err = iActiveModeRequester.Open(iParent.SocketServer(), devAddr);
+ if(err == KErrNone)
+ {
+ // If there is an error, there is nothing we can do about it. This is safe to
+ // do as the only effect is that we will fail to ensure connection is done in active
+ // mode.
+ (void)iActiveModeRequester.RequestExplicitActiveMode(ETrue);
+ }
+ }
+
+ SetActive();
+ }
+
+void CBTConnecter::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ TInt err = iStatus.Int();
+ if(iStatus == KErrNone)
+ {
+ err = BasebandAccessor();
+ }
+
+ // We have now finished with this temporary SAP.
+ iActiveModeRequester.Close();
+
+ //must come LAST .. deletes this active object
+ iParent.HandleConnectCompleteL(err);
+ }
+
+TInt CBTConnecter::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleConnectCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTConnecter::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ iParent.Socket().CancelConnect();
+ iActiveModeRequester.Close();
+ }
+
+//Call HandleConnectionUp() to open registered basebands
+TInt CBTConnecter::BasebandAccessor()
+ {
+ TInt err = iParent.BTBasebandManager().HandleConnectionUp(iParent.SocketServer(), iParent.Socket());
+ return err;
+ }
+
+
+
+
+
+
+
+//--
+CBTAccepter* CBTAccepter::NewL(CBluetoothSocket& aParent, CBluetoothSocket& aBlankSocket)
+ {
+ CBTAccepter* self = new (ELeave) CBTAccepter(aParent, aBlankSocket);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+CBTAccepter::CBTAccepter(CBluetoothSocket& aParent, CBluetoothSocket& aBlankSocket)
+: CActive(CActive::EPriorityStandard),iParent(aParent),iBlankSocket(aBlankSocket)
+//
+//Constructorthe CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ }
+
+void CBTAccepter::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTAccepter::~CBTAccepter()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTAccepter::Accept()
+//
+//Attempts to accept from the remote device.
+//
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+ iParent.Socket().Accept(iBlankSocket.Socket(), iStatus);
+ SetActive();
+ }
+
+void CBTAccepter::Accept(TDes8& aConnectData)
+//
+//Attempts to accept from the remote device.
+//
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Accept(iBlankSocket.Socket(), aConnectData, iStatus);
+ SetActive();
+ }
+
+void CBTAccepter::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ if(iStatus == KErrNone)
+ {
+ BasebandAccessor();
+ iBlankSocket.ConfigureSocket();
+ }
+
+ //must come LAST .. deletes this active object
+ iParent.HandleAcceptCompleteL(iStatus.Int());
+ }
+
+TInt CBTAccepter::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleAcceptCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTAccepter::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ iParent.Socket().CancelAccept();
+ }
+
+void CBTAccepter::BasebandAccessor()
+ {
+ // iBlankSocket
+ iBlankSocket.BTBasebandManager().HandleConnectionUp(iBlankSocket.SocketServer(), iBlankSocket.Socket());
+ }
+
+
+
+
+
+
+
+//--
+CBTShutdowner* CBTShutdowner::NewL(CBluetoothSocket& aParent)
+//
+//NewL: the CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ CBTShutdowner* self = new (ELeave) CBTShutdowner(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+
+CBTShutdowner::CBTShutdowner(CBluetoothSocket& aParent)
+: CActive(CActive::EPriorityStandard),
+ iParent(aParent)
+//
+//Constructor
+//
+ {
+ }
+
+void CBTShutdowner::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTShutdowner::~CBTShutdowner()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTShutdowner::Shutdown(RSocket::TShutdown aHow)
+//
+//Attempts to connect to the remote device.
+//
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Shutdown(aHow, iStatus);
+ SetActive();
+ }
+
+void CBTShutdowner::Shutdown(RSocket::TShutdown aHow,const TDesC8& aDisconnectDataOut,TDes8& aDisconnectDataIn)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+ iParent.BTBasebandManager().HandleConnectionDown();
+ iParent.Socket().Shutdown(aHow, aDisconnectDataOut, aDisconnectDataIn, iStatus);
+
+ SetActive();
+ }
+
+void CBTShutdowner::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ //must come LAST .. deletes this active object
+ iParent.HandleShutdownCompleteL(iStatus.Int());
+ }
+
+TInt CBTShutdowner::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleShutdownCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTShutdowner::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ //iParent.Socket().CancelAll();
+ //what do we do here if anything: no CancelShutdown exists in RSocket?
+ }
+
+
+
+
+
+
+
+//--
+CBTSender* CBTSender::NewL(CBluetoothSocket& aParent)
+//
+//NewL: the CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ CBTSender* self = new (ELeave) CBTSender(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+
+CBTSender::CBTSender(CBluetoothSocket& aParent)
+: CActive(CActive::EPriorityStandard),
+ iParent(aParent)
+//
+//Constructor
+//
+ {
+ }
+
+void CBTSender::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTSender::~CBTSender()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTSender::Write(const TDesC8& aDesc)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Write(aDesc, iStatus);
+ iCurrentRequest = EWrite;
+ SetActive();
+ }
+
+void CBTSender::Send(const TDesC8& aDesc, TUint someFlags)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Send(aDesc, someFlags, iStatus);
+ iCurrentRequest = ESend;
+ SetActive();
+ }
+
+void CBTSender::Send(const TDesC8& aDesc, TUint someFlags, TSockXfrLength& aLen)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Send(aDesc, someFlags, iStatus, aLen);
+ iCurrentRequest = ESend;
+ SetActive();
+ }
+
+void CBTSender::SendTo(const TDesC8& aDesc, TSockAddr& aAddr, TUint flags)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().SendTo(aDesc, aAddr, flags, iStatus);
+ iCurrentRequest = ESend;
+ SetActive();
+ }
+
+void CBTSender::SendTo(const TDesC8& aDesc, TSockAddr& aAddr, TUint flags, TSockXfrLength& aLen)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().SendTo(aDesc, aAddr, flags, iStatus, aLen);
+ iCurrentRequest = ESend;
+ SetActive();
+ }
+
+void CBTSender::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ //must come LAST .. deletes this active object
+ iParent.HandleSendCompleteL(iStatus.Int());
+ }
+
+TInt CBTSender::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleSendCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTSender::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ switch (iCurrentRequest)
+ {
+ //zam todo do these cover all Write/Send functions?
+ case EWrite:
+ iCurrentRequest = ENone;
+ iParent.Socket().CancelWrite();
+ break;
+ case ESend:
+ iCurrentRequest = ENone;
+ iParent.Socket().CancelSend();
+ break;
+ default:
+ iCurrentRequest = ENone;
+ break;
+ };
+ }
+
+
+
+
+
+
+
+//--
+CBTReceiver* CBTReceiver::NewL(CBluetoothSocket& aParent)
+//
+//NewL: the CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ CBTReceiver* self = new (ELeave) CBTReceiver(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+
+CBTReceiver::CBTReceiver(CBluetoothSocket& aParent)
+: CActive(CActive::EPriorityStandard),
+ iParent(aParent)
+//
+//Constructor
+//
+ {
+ }
+
+void CBTReceiver::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTReceiver::~CBTReceiver()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTReceiver::Read(TDes8& aDesc)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Read(aDesc, iStatus);
+ iCurrentRequest = ERead;
+ SetActive();
+ }
+
+void CBTReceiver::Recv(TDes8& aDesc,TUint flags)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Recv(aDesc, flags, iStatus);
+ iCurrentRequest = ERecv;
+ SetActive();
+ }
+
+void CBTReceiver::Recv(TDes8& aDesc,TUint flags,TSockXfrLength& aLen)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Recv(aDesc, flags, iStatus, aLen);
+ iCurrentRequest = ERecv;
+ SetActive();
+ }
+
+void CBTReceiver::RecvOneOrMore(TDes8& aDesc,TUint flags,TSockXfrLength& aLen)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().RecvOneOrMore(aDesc,flags, iStatus, aLen);
+ iCurrentRequest = ERecv;
+ SetActive();
+ }
+
+void CBTReceiver::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().RecvFrom(aDesc, aAddr, flags, iStatus);
+ iCurrentRequest = ERecv;
+ SetActive();
+ }
+
+void CBTReceiver::RecvFrom(TDes8& aDesc,TSockAddr& aAddr,TUint flags,TSockXfrLength& aLen)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().RecvFrom(aDesc, aAddr, flags, iStatus, aLen);
+ iCurrentRequest = ERecv;
+ SetActive();
+ }
+
+
+
+void CBTReceiver::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ //must come LAST .. deletes this active object
+ iParent.HandleReceiveCompleteL(iStatus.Int());
+ }
+
+TInt CBTReceiver::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleReceiveCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTReceiver::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ switch (iCurrentRequest)
+ {
+ //zam todo do these cover all Read/Recv functions?
+ case ERead:
+ iCurrentRequest = ENone;
+ iParent.Socket().CancelRead();
+ break;
+ case ERecv:
+ iCurrentRequest = ENone;
+ iParent.Socket().CancelRecv();
+ break;
+ default:
+ iCurrentRequest = ENone;
+ break;
+ };
+
+ iParent.Socket().CancelRead();
+ }
+
+
+
+
+
+
+
+//--
+CBTIoctler* CBTIoctler::NewL(CBluetoothSocket& aParent)
+//
+//NewL: the CBluetoothSocket parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ CBTIoctler* self = new (ELeave) CBTIoctler(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+
+CBTIoctler::CBTIoctler(CBluetoothSocket& aParent)
+: CActive(CActive::EPriorityStandard),
+ iParent(aParent)
+//
+//Constructor
+//
+ {
+ }
+
+void CBTIoctler::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTIoctler::~CBTIoctler()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTIoctler::Ioctl(TUint aCommand, TDes8* aDesc, TUint aLevel)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+
+ iParent.Socket().Ioctl(aCommand, iStatus, aDesc, aLevel);
+ SetActive();
+ }
+
+void CBTIoctler::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ //must come LAST .. deletes this active object
+ iParent.HandleIoctlCompleteL(iStatus.Int());
+ }
+
+
+TInt CBTIoctler::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleIoctlCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTIoctler::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ iParent.Socket().CancelIoctl();
+ }
+
+//--
+CBTBasebandChangeEventNotifier* CBTBasebandChangeEventNotifier::NewL(MBTBasebandHandler& aUser)
+//
+//NewL: the RBluetoothPhysicalLinksManager parent is provided.
+//It contains all the ESocky stuff and has suitable "Getters".
+//
+ {
+ CBTBasebandChangeEventNotifier* self = new (ELeave) CBTBasebandChangeEventNotifier(aUser);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();//self
+ return self;
+ }
+
+
+CBTBasebandChangeEventNotifier::CBTBasebandChangeEventNotifier(MBTBasebandHandler& aUser)
+: CActive(CActive::EPriorityStandard),
+ iUser(aUser)
+//
+//Constructor
+//
+ {
+ }
+
+void CBTBasebandChangeEventNotifier::ConstructL()
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CBTBasebandChangeEventNotifier::~CBTBasebandChangeEventNotifier()
+//
+//Destructor
+//
+ {
+ Cancel();
+ }
+
+void CBTBasebandChangeEventNotifier::SetNotifyNextModeChange()
+ {
+ iCurrentRequest = ENotifyAnyPowerMode;
+ SetNotify(iCurrentRequest);
+ }
+
+void CBTBasebandChangeEventNotifier::SetNotify(TUint32 aNotifications)
+ {
+ __ASSERT_ALWAYS(!IsActive(), Panic(EUnfinishedBusiness));
+ iEvent = TBTBasebandEventNotification();
+ iUser.MbbhBTBaseband().ActivateNotifierForRecall(iEvent, iStatus, aNotifications);
+ SetActive();
+ }
+
+void CBTBasebandChangeEventNotifier::RunL()
+//
+//When logical socket has connected (only async bit),
+//opens baseband socket.
+//
+ {
+ iCurrentRequest = 0;
+ TBTBasebandEventNotification notification = iEvent();
+ iUser.MbbhHandleActivateBasebandEventNotifierCompleteL(iStatus.Int(), notification);
+ }
+
+TInt CBTBasebandChangeEventNotifier::RunError(TInt aError)
+ {
+ #ifdef __FLOGGING__
+ FTRACE(FPrint(_L("CBluetoothSocket::HandleActivateBasebandEventNotifierCompleteL left with error %d"), aError));
+ #else
+ (void) aError;
+ #endif
+ return KErrNone;
+ }
+
+void CBTBasebandChangeEventNotifier::DoCancel()
+//
+//Cancels current asynchronous requests.
+//
+ {
+ iUser.MbbhBTBaseband().CancelNextBasebandChangeEventNotifier();
+ iCurrentRequest = 0;
+ }
+
+
+// CAutoSniffDelayTimer
+
+CAutoSniffDelayTimer::CAutoSniffDelayTimer(CBluetoothSocket& aParent, TInt aIdleSecondsBeforeSniffRequest)
+ :CTimer(CActive::EPriorityStandard),
+ iParent(aParent),
+ iSniffModeRequested(EFalse)
+ {
+ const TInt KMicroSecondsInASecond = 1000000;
+ iAutoSniffDelay = aIdleSecondsBeforeSniffRequest * KMicroSecondsInASecond;
+ }
+
+CAutoSniffDelayTimer::~CAutoSniffDelayTimer()
+ {
+ Cancel();
+ delete iBTAutoSniffBasebandChangeEventNotifier;
+ // Disable explicit active mode and cancel any low power request if we
+ // have done an auto sniff, there is nothing we do if we error in this process.
+ (void)MbbhBTBaseband().RequestExplicitActiveMode(EFalse);
+ if(iSniffModeRequested)
+ {
+ (void)MbbhBTBaseband().CancelLowPowerModeRequester();
+ }
+ (void)iParent.BTBasebandManager().UnRegisterBTBaseband(*this);
+ }
+
+void CAutoSniffDelayTimer::ConstructL()
+ {
+ CTimer::ConstructL();
+ User::LeaveIfError(iParent.BTBasebandManager().RegisterBTBaseband(*this));
+ iBTAutoSniffBasebandChangeEventNotifier = CBTBasebandChangeEventNotifier::NewL(*this);
+ // Issue a sniff request as soon as we enable auto sniffing.
+ User::LeaveIfError(MakeSniffRequest());
+ iBTAutoSniffBasebandChangeEventNotifier->SetNotify(ENotifyActiveMode);
+ CActiveScheduler::Add(this);
+ }
+
+CAutoSniffDelayTimer* CAutoSniffDelayTimer::NewL(CBluetoothSocket& aParent, TInt aIdleSecondsBeforeSniffRequest)
+ {
+ CAutoSniffDelayTimer* self = new (ELeave) CAutoSniffDelayTimer(aParent, aIdleSecondsBeforeSniffRequest);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+void CAutoSniffDelayTimer::Start()
+ {
+ Cancel();
+ if(iSniffModeRequested)
+ {
+ // Try to cancel the low power modes, if we fail to do that
+ // then we just continue anyway as there isn't much else
+ // we can do.
+ (void)MbbhBTBaseband().CancelLowPowerModeRequester();
+ }
+
+ iSniffModeRequested = EFalse;
+ After(iAutoSniffDelay);
+ }
+
+//Start a 5-minute window for active mode
+void CAutoSniffDelayTimer::StartActive()
+ {
+ Start();
+ if(iSniffModeRequested)
+ {
+ // When enabling auto sniffing, we make use of Explicit active mode.
+ (void)MbbhBTBaseband().RequestExplicitActiveMode(ETrue);
+ }
+ }
+
+RBTBaseband& CAutoSniffDelayTimer::MbbhBTBaseband()
+ {
+ return iBTAutoSniffBaseband;
+ }
+
+void CAutoSniffDelayTimer::MbbhHandleActivateBasebandEventNotifierCompleteL(TInt /*aErr*/, TBTBasebandEventNotification& aEventNotification)
+ {
+ if(aEventNotification.EventType() == ENotifyActiveMode)
+ {
+ // Link has gone into active mode - if we are requesting
+ // sniff mode, then it is up to us to cancel the sniff
+ // requester to prevent the ping-pong effect.
+ if(iSniffModeRequested)
+ {
+ MbbhBTBaseband().CancelLowPowerModeRequester();
+ StartActive();
+ }
+ }
+ __ASSERT_ALWAYS(iBTAutoSniffBasebandChangeEventNotifier != NULL, Panic(EBBInvalidAddress));
+ iBTAutoSniffBasebandChangeEventNotifier->SetNotify(ENotifyActiveMode);
+ }
+
+TInt CAutoSniffDelayTimer::MbbhOpen(RSocketServ& aSocketServ, RSocket& aSocket)
+ {
+ TInt err;
+ err = iBTAutoSniffBaseband.Open(aSocketServ, aSocket);
+ if(err == KErrNone)
+ {
+ //On sucessful opening, preventing Park Mode
+ err = iParent.PreventLowPowerModes(EParkMode);
+ }
+ return err;
+ }
+
+void CAutoSniffDelayTimer::MbbhClose()
+ {
+ iParent.BTBaseband().AllowLowPowerModes(EParkMode);
+ iBTAutoSniffBaseband.Close();
+ }
+
+void CAutoSniffDelayTimer::RunL()
+/**
+Request Sniff Mode when the timer expires
+**/
+ {
+ (void)MbbhBTBaseband().RequestExplicitActiveMode(EFalse);
+ (void)MakeSniffRequest();
+ }
+
+TInt CAutoSniffDelayTimer::MakeSniffRequest()
+ {
+ TInt err = MbbhBTBaseband().ActivateSniffRequester();
+ if(err == KErrNone)
+ {
+ iSniffModeRequested = ETrue;
+ }
+ return err;
+ }
+
+
+
+
+// Class CBTBasebandManager
+
+CBTBasebandManager* CBTBasebandManager::NewL()
+ {
+ CBTBasebandManager* self = new (ELeave) CBTBasebandManager();
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CBTBasebandManager::~CBTBasebandManager()
+ {
+ CloseAllBasebands();
+ iBasebandHandlers.Close();
+ }
+
+CBTBasebandManager::CBTBasebandManager()
+// : iConnected(EFalse) // By default we are not connected.
+ {
+ }
+
+void CBTBasebandManager::ConstructL()
+ {
+ }
+
+//Register a RBTBaseband as specified by aBasebandRegisterMask.
+//After registering, Open the RBTBaseband if the connection is up.
+TInt CBTBasebandManager::RegisterBTBaseband(MBTBasebandHandler& aBasebandHandler)
+ {
+ TInt err = KErrNone;
+ //Trying to register too many basebands
+ if(KErrNotFound != iBasebandHandlers.Find(&aBasebandHandler))
+ {
+ // Trying to register an existing handler again
+ err = KErrArgument;
+ }
+ else
+ {
+ // We know we have a baseband "slot" available from the check above
+ // so just find somewhere to put it.
+ err = iBasebandHandlers.Append(&aBasebandHandler);
+
+ if(err != KErrNone)
+ {
+ //Most likely KErrNoMemory
+ return err;
+ }
+
+ // Might already be open, so to be sure we close it now.
+ aBasebandHandler.MbbhClose();
+ // Now bring the baseband up to the current state
+ if(iConnected)
+ {
+ err = aBasebandHandler.MbbhOpen(*iSocketServ, *iSocket);
+ }
+ if(err != KErrNone)
+ {
+ // On error - roll back the managers state
+ TInt handlerIndex = iBasebandHandlers.Find(&aBasebandHandler);
+ __ASSERT_DEBUG((handlerIndex != KErrNotFound),Panic(EBadArgument));
+ iBasebandHandlers.Remove(handlerIndex);
+ }
+ }
+ return err;
+ }
+
+//Un-register a RBTBaseband
+TInt CBTBasebandManager::UnRegisterBTBaseband(MBTBasebandHandler& aBasebandHandler)
+ {
+ // Check that the baseband is actually registered in the manager
+ // We check to see if it is the same instance of MBTBasebandHandler through
+ // their pointer addresses.
+ TInt handlerIndex = iBasebandHandlers.Find(&aBasebandHandler);
+ if (handlerIndex == KErrNotFound)
+ {
+ return KErrNotFound; // send error condition back to API
+ }
+ iBasebandHandlers.Remove(handlerIndex);
+
+ // Close the baseband if we successfully unregistered it.
+ aBasebandHandler.MbbhClose();
+
+ return KErrNone;
+ }
+
+//Open all registered basebands when connection is up
+TInt CBTBasebandManager::HandleConnectionUp(RSocketServ& aSocketServ, RSocket& aSocket)
+ {
+ TInt err = KErrNone;
+ TInt handlerCount = iBasebandHandlers.Count();
+
+ if(iConnected)
+ {
+ err = KErrInUse;
+ }
+ else
+ {
+ // Cache the information for basebands that register after the connection has come up
+ iSocketServ = &aSocketServ;
+ iSocket = &aSocket;
+
+ for(TInt i = 0; i < handlerCount; i++)
+ {
+ err = iBasebandHandlers[i]->MbbhOpen(aSocketServ, aSocket);
+ if(err != KErrNone)
+ {
+ // There was an error opening one of the sockets, we aren't connected
+ // so make sure we roll all RBTBasebands back to being closed.
+ CloseAllBasebands();
+ break;
+ }
+ }
+
+ if(err == KErrNone)
+ {
+ iConnected = ETrue;
+ }
+ }
+
+ return err;
+ }
+
+//Close all opened basebands when connection is down
+void CBTBasebandManager::HandleConnectionDown()
+ {
+ CloseAllBasebands();
+ iConnected = EFalse;
+ }
+
+TBool CBTBasebandManager::Connected() const
+ {
+ return iConnected;
+ }
+
+void CBTBasebandManager::CloseAllBasebands()
+ {
+ TInt handlerCount = iBasebandHandlers.Count();
+ for(TInt i = 0; i < handlerCount; i++)
+ {
+ iBasebandHandlers[i]->MbbhClose();
+ }
+ }
+
+
+//class CBTBasebandChangeEventDelegate
+CBTBasebandChangeEventDelegate* CBTBasebandChangeEventDelegate::NewL(CBluetoothSocket& aParent)
+ {
+ CBTBasebandChangeEventDelegate* self = new (ELeave) CBTBasebandChangeEventDelegate(aParent);
+ CleanupStack::PushL(self);
+ self->ConstructL();
+ CleanupStack::Pop();
+ return self;
+ }
+
+CBTBasebandChangeEventDelegate::CBTBasebandChangeEventDelegate(CBluetoothSocket& aParent)
+:iParent(aParent)
+ {
+ }
+
+void CBTBasebandChangeEventDelegate::ConstructL()
+ {
+ }
+
+RBTBaseband& CBTBasebandChangeEventDelegate::MbbhBTBaseband()
+ {
+ return iParent.BTBaseband();
+ }
+
+void CBTBasebandChangeEventDelegate::MbbhHandleActivateBasebandEventNotifierCompleteL(TInt aErr, TBTBasebandEventNotification& aEventNotification)
+ {
+ iParent.HandleActivateBasebandEventNotifierCompleteL(aErr, aEventNotification);
+ }
+
+TInt CBTBasebandChangeEventDelegate::MbbhOpen(RSocketServ& aSocketServ, RSocket& aSocket)
+ {
+ TInt err = iParent.BTBaseband().Open(aSocketServ, aSocket);
+ return err;
+ }
+
+void CBTBasebandChangeEventDelegate::MbbhClose()
+ {
+ iParent.BTBaseband().Close();
+ }