diff -r 000000000000 -r 29b1cd4cb562 bluetoothmgmt/bluetoothclientlib/btlib/btbaseband.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetoothmgmt/bluetoothclientlib/btlib/btbaseband.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,1018 @@ +// 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 +#include +#include "btsocketpanic.h" + +//................................. +// +//Actual raw client +// + +RBTBaseband::RBTBaseband() + { + } + +void RBTBaseband::Close() + { + if (SubSessionHandle()) + { + iSocket.Close(); + } + } + + +/** + + API useful for Bluetooth as seen from a single physical link perspective + +*/ + +// for 'getting' a RBTBaseband from a connected socket +TInt RBTBaseband::Open(RSocketServ& aSocketServ, RSocket& aConnectedSocket) + { + if (!aConnectedSocket.SubSessionHandle()) + { + return KErrNotReady; + } + + THCIConnHandle bbHandle; + TPckg bbHandleBuf(bbHandle); + + TInt err = aConnectedSocket.GetOpt(KLMGetACLHandle, KSolBtACL, bbHandleBuf); + if (err) + { + return err; + } + err = iSocket.Open(aSocketServ, KBTAddrFamily, bbHandle, KBTLinkManager); + + return err; + } + +TInt RBTBaseband::Open(RSocketServ& aSocketServ, const TBTDevAddr& aBDAddr) + { + //open unsubscribed socket (currently use KSockBluetoothTypeRawBroadcast) + TInt err = iSocket.Open(aSocketServ, + KBTAddrFamily, + KSockBluetoothTypeRawBroadcast, + KBTLinkManager); + if (err) + { + return err; + } + + //attempt to subscribe socket to supplied address + TPckg pckg(aBDAddr); + err = iSocket.SetOpt(EBBSubscribePhysicalLink, KSolBtLMProxy, pckg); + if(err) + //only leave open if there is an EXISTING connection + { + iSocket.Close(); + } + + return err; + } + +TInt RBTBaseband::PhysicalLinkState(TUint32& aState) + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + TBTBasebandEvent pckgEvent; + + err = iSocket.GetOpt(EBBGetPhysicalLinkState, KSolBtLMProxy, pckgEvent); + if (err == KErrNone) + { + aState = pckgEvent().EventType(); + } + } + + return err; + } + +/**Role change methods*/ +TInt RBTBaseband::PreventRoleSwitch() + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBRequestPreventRoleChange, KSolBtLMProxy, 0); + } + + return err; + } + +TInt RBTBaseband::AllowRoleSwitch() + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBRequestAllowRoleChange, KSolBtLMProxy, 0); + } + + return err; + } + +TInt RBTBaseband::RequestMasterRole() + { + return RequestRole(EBBRequestRoleMaster); + } + +TInt RBTBaseband::RequestSlaveRole() + { + return RequestRole(EBBRequestRoleSlave); + } + + +/**Low power mode methods*/ +TInt RBTBaseband::PreventLowPowerModes(TUint32 aLowPowerModes) + { + if (!SubSessionHandle()) + { + return KErrNotReady; + } + //if caller has used silly bits + if(aLowPowerModes & ~(EAnyLowPowerMode)) + { + return KErrArgument; + } + + TUint32 mask = 0; + if(aLowPowerModes & EHoldMode) + { + mask |= EBBRequestPreventHold; + } + if(aLowPowerModes & ESniffMode) + { + mask |= EBBRequestPreventSniff; + } + if(aLowPowerModes & EParkMode) + { + mask |= EBBRequestPreventPark; + } + + return iSocket.SetOpt(mask, KSolBtLMProxy); + } + +TInt RBTBaseband::AllowLowPowerModes(TUint32 aLowPowerModes) + { + + if (!SubSessionHandle()) + { + return KErrNotReady; + } + + //if caller has used silly bits + if(aLowPowerModes & ~(EAnyLowPowerMode)) + { + return KErrArgument; + } + + TUint32 mask = 0; + if(aLowPowerModes & EHoldMode) + { + mask |= EBBRequestAllowHold; + } + if(aLowPowerModes & ESniffMode) + { + mask |= EBBRequestAllowSniff; + } + if(aLowPowerModes & EParkMode) + { + mask |= EBBRequestAllowPark; + } + + return iSocket.SetOpt(mask, KSolBtLMProxy); + } + +TInt RBTBaseband::ActivateSniffRequester() + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBRequestSniff, KSolBtLMProxy, 0); + } + return err; + } + +TInt RBTBaseband::ActivateParkRequester() + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBRequestPark, KSolBtLMProxy); + } + return err; + } + +TInt RBTBaseband::CancelLowPowerModeRequester() + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBCancelModeRequest, KSolBtLMProxy, 0); + } + + return err; + } + +TInt RBTBaseband::RequestExplicitActiveMode(TBool aActive) + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + TPckgBuf active = aActive; + err = iSocket.SetOpt(EBBRequestExplicitActiveMode, KSolBtLMProxy, active); + } + return err; + } + + +/**Packet method*/ +TInt RBTBaseband::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes) + { + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + // Only allow ACL packet types to be changed + // Although EAnyNonEdrACLPacket is a confusing name in this context + // it is correct. As standard ACL packet types are to be used when the + // appropriate bit is set, for EDR packets the bit is set if they + // are not to be used. Thus we are correctly checking that only + // valid bits are set when using the EAnyNonEdrACLPacket bitmask. + + if ((aPacketTypes & ~EAnyNonEdrACLPacket) != 0) + { + return KErrArgument; + } + + TPckgBuf packetTypes = aPacketTypes; + err = iSocket.SetOpt(EBBRequestChangeSupportedPacketTypes, KSolBtLMProxy, packetTypes); + } + return err; + } + +void RBTBaseband::ReadNewPhysicalLinkMetricValue(TRequestStatus& aStatus, TDes8& aPLMData, TBTLMIoctls anIoctl) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + iSocket.Ioctl(anIoctl, aStatus, &aPLMData, KSolBtLMProxy); + } + } + +void RBTBaseband::CancelPhysicalLinkMetricUpdate() + { + if(SubSessionHandle()) + { + iSocket.CancelIoctl(); + } + } + +/**Notification methods*/ +void RBTBaseband::ActivateNotifierForOneShot(TBTBasebandEvent& aEventNotification, + TRequestStatus& aStatus, + TUint32 aEventMask) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + aEventNotification().SetEventType(aEventMask); + iSocket.Ioctl(KLMBasebandEventOneShotNotificationIoctl, aStatus, &aEventNotification, KSolBtLMProxy); + } + } + +void RBTBaseband::ActivateNotifierForRecall(TBTBasebandEvent& aEventNotification, + TRequestStatus& aStatus, + TUint32 aEventMask) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + aEventNotification().SetEventType(aEventMask); + iSocket.Ioctl(KLMBasebandEventNotificationIoctl, aStatus, &aEventNotification, KSolBtLMProxy); + } + } + +void RBTBaseband::CancelNextBasebandChangeEventNotifier() + { + if (SubSessionHandle()) + { + //only allowed one Ioctl at a time - only one used is the Notifications Ioctl + iSocket.CancelIoctl(); + } + } + +TInt RBTBaseband::Authenticate() + { + // First check that the socket is open etc + TInt err = KErrNone; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + // Send the request - this will return KErrAlreadyExists if the link is already authenticated. + err = iSocket.SetOpt(EBBRequestLinkAuthentication, KSolBtLMProxy, 0); + } + + return err; + } + + +/** + + API useful for Bluetooth as seen from a device perspective + +*/ + +TInt RBTBaseband::Open(RSocketServ& aSocketServ) + { + // need to specify this is a raw socket + TInt err = iSocket.Open(aSocketServ, + KBTAddrFamily, + KSockBluetoothTypeRawBroadcast, + KBTLinkManager); + return err; + } + +void RBTBaseband::Connect(const TBTDevAddr& aAddr, TRequestStatus& aStatus) + { + iConnectToken().iDevice.SetAddress(aAddr); + DoConnect(aStatus); + } + +void RBTBaseband::Connect(const TPhysicalLinkQuickConnectionToken& aToken, TRequestStatus& aStatus) + +// (Not for documentation!) +// param aDevice +// A valid nameless device - that may have been obtained from Registry + + { + if (!iConnectToken().iDevice.IsValidAddress()) + { + LocalComplete(aStatus, KErrArgument); + } + else + { + iConnectToken() = aToken; + DoConnect(aStatus); + } + } + + +TInt RBTBaseband::Broadcast(const TDesC8& aData) + { +#ifdef PROXY_COMMUNICATES + // have to notify Proxy that we intend to write data via it + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBBeginRaw, KSolBtLMProxy, 0); + } + if (err == KErrNone || err == KErrAlreadyExists) + { + TRequestStatus s; + TUint8 flags = KPiconetBroadcast << 2; + iSocket.Send(aData, flags, s); // 'send' to allow flags + User::WaitForRequest(s); + err = s.Int(); + } + return err; +#else + return KErrNotSupported; +#endif + } + +TInt RBTBaseband::ReadRaw(TDes8& aData) +/** + NOT PROPERLY IMPLEMENTED - JUST A PLACE HOLDER REALLY +*/ + { +#ifdef PROXY_COMMUNICATES + // have to notify Proxy that we intend to write data via it + TInt err; + if (!SubSessionHandle()) + { + err = KErrNotReady; + } + else + { + err = iSocket.SetOpt(EBBBeginRaw, KSolBtLMProxy, 0); + } + if (err == KErrNone || err == KErrAlreadyExists) + { + TRequestStatus s; + TUint8 flags = KPiconetBroadcast << 2; + iSocket.Recv(aData, flags, s); // 'send' to allow flags + User::WaitForRequest(s); + err = s.Int(); + } + return err; +#else + return KErrNotSupported; +#endif + } + + +void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/) + { + // synchronise + TRequestStatus stat; + TerminatePhysicalLink(0, stat); + User::WaitForRequest(stat); + } + +void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/, TRequestStatus& aStatus) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + // synchronise + TBuf8<1> dummy; + iSocket.Shutdown(RSocket::EImmediate, KDisconnectOnePhysicalLink, dummy, aStatus); // this *means* detach now + } + } + +void RBTBaseband::TerminatePhysicalLink(TInt /*aReason*/, const TBTDevAddr& aAddr, TRequestStatus& aStatus) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + // ensure that BT address has persistence + iSocketAddress.Zero(); + iSocketAddress.Copy(aAddr.Des()); + // the following line needs to be EImmediate when ESock has been fixed + iSocket.Shutdown(RSocket::ENormal, iSocketAddress, iConnectInData, aStatus); // this *means* detach now + } + } + +void RBTBaseband::ShutdownPhysicalLink(TRequestStatus& aStatus) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + // synchronise + TBuf8<1> dummy; + iSocket.Shutdown(RSocket::ENormal, KDisconnectOnePhysicalLink, dummy, aStatus); // this *means* detach gently + } + } + +void RBTBaseband::TerminateAllPhysicalLinks(TInt aReason) + { + TRequestStatus stat; + TerminateAllPhysicalLinks(aReason, stat); + User::WaitForRequest(stat); + } + +void RBTBaseband::TerminateAllPhysicalLinks(TInt /*aReason*/, TRequestStatus& aStatus) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + else + { + TBuf8<1> dummy; + iSocket.Shutdown(RSocket::ENormal, KDisconnectAllPhysicalLinks, dummy, aStatus); // this *means* detach now + } + } + +TInt RBTBaseband::Enumerate(RBTDevAddrArray& aBTDevAddrArray, TUint aMaxNumber) + { + if (!SubSessionHandle()) + { + return KErrNotReady; + } + + __ASSERT_DEBUG(aMaxNumber>=1, Panic(EBadArgument)); + if(!aMaxNumber) + { + return KErrArgument; + } + HBufC8* buffer=0; + const TInt KAddrLen = sizeof(TBTDevAddr); + + TRAPD(err, buffer = HBufC8::NewL(aMaxNumber*KAddrLen)); + if(err) + { + return KErrNoMemory; + } + + TPtr8 ptr = buffer->Des(); + err = iSocket.GetOpt(EBBEnumeratePhysicalLinks, KSolBtLMProxy, ptr); + if (err) + { + delete buffer; + return err; + } + + /** + Parse the supplied descriptor + */ + + aBTDevAddrArray.Reset(); + while(ptr.Length()>=KBTDevAddrSize) + { + TBTDevAddr parsedAddr(ptr.Mid(ptr.Length()-KAddrLen, KBTDevAddrSize)); + ptr.SetLength(Max(ptr.Length()-KAddrLen, 0)); + aBTDevAddrArray.Append(parsedAddr); + } + + delete buffer; + return KErrNone; + } + + +TInt RBTBaseband::SubSessionHandle() const + { + return iSocket.SubSessionHandle(); + } + + +/**Private Methods*/ +TInt RBTBaseband::RequestRole(TBTLMOptions aRole) + { + if (!SubSessionHandle()) + { + return KErrNotReady; + } + __ASSERT_DEBUG(aRole==EBBRequestRoleMaster||aRole==EBBRequestRoleSlave, + Panic(EBadArgument)); + + return iSocket.SetOpt(aRole, KSolBtLMProxy, 0); + } + + +void RBTBaseband::LocalComplete(TRequestStatus& aStatus, TInt aErr) + { + aStatus = KRequestPending; + TRequestStatus* pStat = &aStatus; + User::RequestComplete(pStat, aErr); + } + +void RBTBaseband::DoConnect(TRequestStatus& aStatus) + { + if (!SubSessionHandle()) + { + LocalComplete(aStatus, KErrNotReady); + } + + __ASSERT_DEBUG(iConnectToken().iDevice.IsValidAddress(), Panic(EBBInvalidAddress)); + + iSocketAddress.SetBTAddr(iConnectToken().iDevice.Address()); // not that useful + iSocket.Connect(iSocketAddress, iConnectToken, iConnectInData, aStatus); + } + + + +//................................. +// +//Class used for choosing baseband events to report, and for reporting +//those events to the Bluetooth client +// + +EXPORT_C TInt TBTBasebandEventNotification::SymbianErrorCode() const +/** Returns an error in 'Symbian' format + @return Symbian error code + @publishedAll + @released +*/ + { + return iErrorCode==KErrNone?iErrorCode:KHCIErrorBase-iErrorCode; + }; + + + +//................................. +// +//Facade class for developers wishing who wish to use a pre-existing connected +//physical link +// + +EXPORT_C RBTPhysicalLinkAdapter::RBTPhysicalLinkAdapter() +/** Constructor + @publishedAll + @released +*/ + { + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::Open(RSocketServ& aSocketServ, RSocket& aSocket) +/** Open a physical link adapter on an existing physical link defined by 'aSocket'. + @pre There exists a Bluetooth connection + @param aSocketServ + An existing ESock session + @param aSocket + An open connected socket (ESock subsession) on that existing ESock session + @return Error code + @publishedAll + @released + @capability LocalServices +*/ + { + return iBTBaseband.Open(aSocketServ, aSocket); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::Open(RSocketServ& aSocketServ, const TBTDevAddr& aBDAddr) +/** Open a physical link adapter on an existing physical link defined by 'aDevAddr'. + @pre There exists a Bluetooth connection + @param aSocketServ + An existing ESock session + @param aBDAddr + The Bluetooth address of a remote device with which there is an existing connection + @return Error code + @publishedAll + @released + @capability LocalServices +*/ + { + return iBTBaseband.Open(aSocketServ, aBDAddr); + } + +EXPORT_C void RBTPhysicalLinkAdapter::Close() +/** Close the physical link adapter. + @publishedAll + @released +*/ + { + iBTBaseband.Close(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::PhysicalLinkState(TUint32& aState) +/** Get the state of the physical link. + @pre One of the Open functions has been called + @param aState + Used to return the physical link state - as a combination of bit values + defined in TBTPhysicalLinkStateNotifier. + @see TBTPhysicalLinkStateNotifier + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.PhysicalLinkState(aState); + } + +//Role change methods +EXPORT_C TInt RBTPhysicalLinkAdapter::PreventRoleSwitch() +/** Blocks a role switch + + Stops a Master/Slave switch occurring until such time as 'AllowRoleSwitch' is called. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.PreventRoleSwitch(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::AllowRoleSwitch() +/** Ensures this object does not block a role switch. + + Switches off 'PreventRoleSwitch'. If another RBTPhysicalLinkAdapter object requests, + or has requested a Master/Slave switch, that request will now not be blocked by + this RBTPhysicalLinkAdapter object + The default is to allow a Master/Slave switch. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.AllowRoleSwitch(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::RequestMasterRole() +/** Attempt to be the Bluetooth Master of a Piconet. + + If the local device is currently the slave, a role switch maybe performed + if no other user of a RBTPhysicalLinkAdapter object has called PreventRoleSwitch + and the remote device allows the role switch. + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.RequestMasterRole(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::RequestSlaveRole() +/** Attempt to be a Bluetooth Slave of a Piconet. + + If the local device is currently the master, a role switch maybe performed if + no other user of a RBTPhysicalLinkAdapter object has called PreventRoleSwitch + and the remote device allows the role switch. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.RequestSlaveRole(); + } + +//Low power mode methods +EXPORT_C TInt RBTPhysicalLinkAdapter::PreventLowPowerModes(TUint32 aLowPowerModes) +/** Blocks the use of a specified set of low power modes + + Stops the physical link using any one of the set of low power modes specified by + the bit mask 'aLowPowerModes'. To undo this blocking mechanism for a given set + of low power modes, 'AllowLowPowerModes' needs to be called with appropriate values + in its 'aLowPowerModes' parameter. + + NB THIS METHOD CAN BE USED TO FORCE THE PHYSICAL LINK INTO ACTIVE MODE. + To do this set the parameter to EAnyLowPowerMode. The requests for low power + modes by any RBTPhysicalLinkAdapter objects will now be blocked by this object. + + NB Some remote devices will automatically disconnect from a device whose Link Policy + settings prevent low power modes. + + @pre One of the Open functions has been called + @param aLowPowerModes + A mask to specify which power modes are to be prevented. + (Combine EHoldMode, ESniffMode, EParkMode or use EAnyLowPowerMode) + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.PreventLowPowerModes(aLowPowerModes); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::AllowLowPowerModes(TUint32 aLowPowerModes) +/** Ensures this object does not block the use of a specified set of low power modes + + Switches off 'PreventLowPowerModes' for the low power modes specified by the parameter + 'aLowPowerModes'. If another RBTPhysicalLinkAdapter object requests, or has + requested one of those low power modes, that request will now NOT be blocked by + this RBTPhysicalLinkAdapter object. + The default is to allow all low power modes. + NB. Warning this may reactivate a low power mode requester. + For example: + ActivateSniffRequester(); //sniff requester active + PreventLowPowersModes(ESniffMode); //sniff requester dormant + .... + AllowLowPowersModes(ESniffMode); //sniff requseter active + + @pre One of the Open functions has been called + @param aLowPowerModes + A mask to specify which power modes are to be prevented. + (Combine EHoldMode, ESniffMode, EParkMode or use EAnyLowPowerMode) + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.AllowLowPowerModes(aLowPowerModes); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateSniffRequester() +/** Start a facility that will continually attempt to put the physical link into Sniff Mode. + + Attempt to put the physical link into Sniff mode. If for any reason this is + not possible (e.g another user of a RBTPhysicalLinkAdapter object has called + PreventLowPowerModes on Sniff) or the physical link comes out of Sniff mode, + this attempt will be repeated whenever a relevant event occurs or command is made. + These attempts will cease if a call to either ActivateParkRequester, ActivateActiveRequester or + CancelLowPowerModeRequester is made. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.ActivateSniffRequester(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateParkRequester() +/** Start a facility that will continually attempt to put the physical link into Park Mode. + + Attempt to put the physical link into Park mode. If for any reason this is + not possible (e.g another user of a RBTPhysicalLinkAdapter object has called + PreventLowPowerModes on Park) or the physical link comes out of Park mode, + this attempt will be repeated whenever a relevant event occurs or command is made. + These attempts will cease, if a call to either ActivateSniffRequester, ActivateActiveRequester or + CancelLowPowerModeRequester is made. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.ActivateParkRequester(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::ActivateActiveRequester() +/** Start a facility that will continually attempt to put the physical link into Active Mode. + + Puts the physical link into Active mode, even if a Low Power Mode (Sniff or Park) has + been explicitly requested by another client of the physical link. + Calling CancelLowPowerModeRequests() will cancel the explicit request for Active mode. + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + TInt err; + err = iBTBaseband.RequestExplicitActiveMode(ETrue); + if(err == KErrNone) + { + err = iBTBaseband.CancelLowPowerModeRequester(); + } + return err; + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::CancelLowPowerModeRequester() +/** Cancel a facility that is continually requesting a low power mode + + If ActivateSniffRequester, ActivateParkRequester or ActivateActiveRequester has been called by the user + of this RBTPhysicalLinkAdapter object, repeated attempts will be made to put/return + the physical link to that mode whenever a relevant event occurs or command is made. + CancelLowPowerModeRequester stops these requests. However if another user of a + RBTPhysicalLinkAdapter object has called ActivateSniffRequester, ActivateParkRequester or ActivateActiveRequester, + those requests will still be active, and so the physical link will remain controlled by these requests. + + To try to force the physical link into active mode, a call to + either PreventLowPowerModes(EAnyLowPowerMode) or ActivateActiveRequester() should be made. + + @pre One of the Open functions has been called + @return Error code + @publishedAll + @released +*/ + { + TInt err; + err = iBTBaseband.RequestExplicitActiveMode(EFalse); + if(err == KErrNone) + { + err = iBTBaseband.CancelLowPowerModeRequester(); + } + return err; + } + + +//Packet method +EXPORT_C TInt RBTPhysicalLinkAdapter::RequestChangeSupportedPacketTypes(TUint16 aPacketTypes) +/** Update the set of baseband packet types that are allowed locally + + Attempts to control which Bluetooth baseband ACL packet types (i.e. DM1, DH1, DM3 etc) + are allowed by our host controller on the physical link. + @pre One of the Open functions has been called + @param aPacketTypes + Bitmask for packet types to be supported + (Combine elements of TBTPacketType (or use TBTPacketTypeCombinations)) + @see TBTPacketType + @see TBTPacketTypeCombinations + + @return Error code + @publishedAll + @released +*/ + { + return iBTBaseband.RequestChangeSupportedPacketTypes(aPacketTypes); + } + +//Notification methods +EXPORT_C void RBTPhysicalLinkAdapter::NotifyNextBasebandChangeEvent(TBTBasebandEvent& aEventNotification, + TRequestStatus& aStatus, + TUint32 aEventMask) +/** Request a notification + + Request notification the next time one of a user specified selection (see parameter 3) + of baseband events occurs. + @pre One of the Open functions has been called + @param aEventNotification + Return parameter + @param aStatus + Status parameter for asynchronous request + @param aEventMask + Bitmask for those events for which notification is being requested + Use TBTPhysicalLinkStateNotifier (and TBTPhysicalLinkStateNotifierCombinations) + @see TBTPhysicalLinkStateNotifier + @see TBTPhysicalLinkStateNotifierCombinations + @publishedAll + @released +*/ + { + iBTBaseband.ActivateNotifierForOneShot(aEventNotification, aStatus, aEventMask); + } + +EXPORT_C void RBTPhysicalLinkAdapter::CancelNextBasebandChangeEventNotifier() +/** Cancel a currently requested notification + + Switch off the currently active baseband change event notifier. + @pre One of the Open functions has been called + @publishedAll + @released +*/ + { + iBTBaseband.CancelNextBasebandChangeEventNotifier(); + } + +EXPORT_C TInt RBTPhysicalLinkAdapter::Authenticate() +/** Attempts to authenticate the existing physical link + + If the the physical link has already been authenticated it will return an error, + otherwise an Authentication Request will be made to the remote device. + + This is a synchronous call and will return immediately the request has been issued. + If required, NotifyNextBasebandChangeEvent() should be issued before this to wait for + the completion of this authenticaton (for both authentication success and failure) + + @pre One of the Open functions has been called + @return Error code. KErrAlreadyExists if the link is already authenticated +*/ + { + return iBTBaseband.Authenticate(); + } + +EXPORT_C TBool RBTPhysicalLinkAdapter::IsOpen() const +/** Check whether the physical link adapter is open + + This method is not required to be called before the other methods. + KErrNotReady will be returned by other methods, if RBTPhysicalLinkAdapter is not open yet. + + @publishedAll + @released +*/ + { + return (iBTBaseband.SubSessionHandle() ? ETrue : EFalse); + } + + + +