diff -r 000000000000 -r 29b1cd4cb562 bluetoothmgmt/bluetoothclientlib/btlib/btsocket.cpp --- /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 +#include "btsocketpanic.h" +#include "btsockethelpers.h" +#include "e32cmn.h" + +#include + + + +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 (*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 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(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(); + }