--- a/bluetooth/btstack/linkmgr/physicallinks.cpp Wed Sep 15 13:27:26 2010 +0300
+++ b/bluetooth/btstack/linkmgr/physicallinks.cpp Wed Oct 13 15:48:34 2010 +0300
@@ -25,11 +25,10 @@
#include "linkconsts.h"
#include "hcifacade.h"
#include "hostresolver.h"
-#include "roleswitchhelper.h"
+#include "PhysicalLinkHelper.h"
#include "pairingscache.h"
#include "oobdata.h"
#include "pairingserver.h"
-#include "encryptionkeyrefreshhelper.h"
#include <bt_sock.h>
@@ -59,7 +58,7 @@
static const THCIErrorCode KDefaultRejectReason = EHostSecurityRejection; // see spec Error Codes
#ifdef _DEBUG
-#define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(HasHandle(aHandle), Panic(EBTLinkMgrConnectionEventInWrongSAP));
+#define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(aHandle==iHandle, Panic(EBTLinkMgrConnectionEventInWrongSAP));
#else
#define __CHECK_CONNECTION_HANDLE(aHandle) aHandle=aHandle; // to suppress warnings
#endif
@@ -92,6 +91,7 @@
, iProxySAPs(_FOFF(CBTProxySAP, iQueueLink))
, iOverrideParkRequests(EFalse)
, iOverrideLPMRequests(EFalse)
+ , iLPMOverrideTimerQueued(EFalse)
, iConnectionPacketTypeChanged(EFalse)
, iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController())
, iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController())
@@ -119,6 +119,11 @@
iACLLogicalLinks.Close();
RemoveIdleTimer();
+ if (iLPMOverrideTimerQueued)
+ {
+ BTSocketTimer::Remove(iOverrideLPMTimerEntry);
+ iLPMOverrideTimerQueued = EFalse;
+ }
LOG(_L("sec\tClosing subscribers..."))
@@ -144,11 +149,9 @@
delete iPasskeyEntry;
delete iArbitrationDelay;
delete iRoleSwitchCompleteCallBack;
- delete iKeyRefreshCompleteCallBack;
delete iEncryptionEnforcer;
DeleteRoleSwitcher();
- DeleteKeyRefresher();
}
void CPhysicalLink::ConstructL()
@@ -161,9 +164,9 @@
TCallBack cb1(RoleSwitchCompleteCallBack, this);
iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority);
- TCallBack cb2(KeyRefreshCompleteCallBack, this);
- iKeyRefreshCompleteCallBack = new (ELeave)CAsyncCallBack(cb2, EActiveHighPriority);
-
+ TCallBack cb2(OverrideLPMTimeoutCallback, this);
+ iOverrideLPMTimerEntry.Set(cb2);
+
iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController());
}
@@ -219,48 +222,11 @@
TInt CPhysicalLink::TryToAndThenPreventHostEncryptionKeyRefresh(TAny* aOutToken)
{
LOG_FUNC
- TInt err = KErrNone;
- // The handling of the TAny* parameter seems a bit wacky - but it makes sense as follows
- // this call handles a call from the bluetooth control plane (which passes
- // only a TAny* as a parameter). We need to return a value back through as well, so we need
- // a pointer to a pointer (so after using the input it can be modified to point to the
- // output). We need a Bluetooth device address so a pointer to a pointer to a TBTDevAddr
- // is passed down. Then the pointer to a pointer is used to update the pointer to a control
- // plane token (which represents a handle preventing host encryption key refreshes).
- if (!IsEncryptionPauseResumeSupported())
- {
- err = KErrNotSupported;
- *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL;
- }
- else
- {
- // Only refresh the key if no-one is preventing it and we aren't still
- // refreshing the key from a previous request. Note that although
- // the previous key refresh may actually have finished if the key
- // refresher is waiting for async delete we have only just refreshed
- // the key and there's no point doing it again.
- if (iAutoKeyRefreshQue.IsEmpty() && !iKeyRefresher)
- {
- TRAPD(err, iKeyRefresher = CEncryptionKeyRefresher::NewL(iLinksMan, *this));
- if(!err)
- {
- // Kick off the helper state machine
- iKeyRefresher->StartHelper();
- }
- // If we can't refresh the encryption key, there's not much we can do
- }
- XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken();
- if (token)
- {
- iAutoKeyRefreshQue.AddLast(*token);
- }
- else
- {
- err = KErrNoMemory;
- }
- *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = token;
- }
- return err;
+ // Currently the host encryption key refresh functionality is not supported
+ // as to work smoothly it relies on changes to disable low power modes that
+ // are not present in this codeline.
+ *reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL;
+ return KErrNotSupported;
}
void CPhysicalLink::RegistryTaskComplete(CBTRegistryHelperBase* aHelper, TInt /*aResult*/)
@@ -1371,17 +1337,6 @@
nameChanger->Start(BDAddr(), aName);
}
-void CPhysicalLink::EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH)
- {
- LOG_FUNC
- __CHECK_CONNECTION_HANDLE(aConnH);
-
- if(iKeyRefresher)
- {
- iKeyRefresher->EncryptionKeyRefreshComplete(aErr);
- }
- }
-
void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult)
{
LOG_FUNC
@@ -1844,36 +1799,63 @@
return KErrNone;
}
- TBTLinkMode targetMode = EActiveMode;
+ TBTLinkMode nextMode = EActiveMode;
// Determine which LPM we should be in (if any)
if(modeChangeMask & KExplicitActiveMode)
{
- targetMode = EActiveMode;
+ nextMode = EActiveMode;
}
else if(modeChangeMask & EHoldMode)
{
- targetMode = EHoldMode;
+ nextMode = EHoldMode;
}
else if(modeChangeMask & ESniffMode)
{
- targetMode = ESniffMode;
+ nextMode = ESniffMode;
}
else if(modeChangeMask & EParkMode)
{
- targetMode = EParkMode;
+ nextMode = EParkMode;
}
- LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, targetMode);
+ LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, nextMode);
- if(IsConnected())
- {
- TInt err = iLowPowModeCtrl.ExecuteModeChange(targetMode);
- LOG1(_L8("Arbitration: iLowPowModeCtrl.ExecuteModeChange: err:%d"), err);
- return err;
- }
- else
- {
- return KErrDisconnected;
- }
+ if(nextMode != currentMode)
+ {
+ if(currentMode != EActiveMode)
+ {
+ LOG(_L8("Arbitration: Exiting existing LPM mode..."));
+ TInt err = RequestActive();
+ if(err != KErrNone)
+ {
+ return err;
+ }
+ }
+ if(nextMode == EHoldMode)
+ {
+ LOG(_L8("Arbitration: Entering Hold mode..."));
+ return RequestHold();
+ }
+ else if(nextMode == ESniffMode)
+ {
+ LOG(_L8("Arbitration: Entering Sniff mode..."));
+ return RequestSniff();
+ }
+ else if(nextMode == EParkMode)
+ {
+ LOG(_L8("Arbitration: Entering Park mode..."));
+ return RequestPark();
+ }
+ else if(nextMode == EActiveMode)
+ {
+ LOG(_L8("Arbitration: Staying in Active mode..."));
+ return KErrNone;
+ }
+ // Shouldn't reach here, we have a strange mode
+ DEBUG_PANIC_LINENUM;
+ }
+
+ LOG(_L8("Arbitration: Already in correct LPM, not doing anything"));
+ return KErrNone;
}
void CPhysicalLink::SetPassKey(const TDesC8& aPassKey)
@@ -2245,6 +2227,22 @@
iIdleTimerQueued = EFalse;
}
+void CPhysicalLink::QueueLPMOverrideTimer(TInt aTimeout)
+/**
+ Queue LPM Override timer entry.
+ When this timer expires, it'll call UndoLPMOverride.
+**/
+ {
+ LOG_FUNC
+ __ASSERT_DEBUG(aTimeout!=0, Panic(EBTPhysicalLinksInvalidArgument));
+ if (iLPMOverrideTimerQueued)
+ {
+ BTSocketTimer::Remove(iOverrideLPMTimerEntry);
+ }
+ BTSocketTimer::Queue(aTimeout, iOverrideLPMTimerEntry);
+ iLPMOverrideTimerQueued = ETrue;
+ }
+
void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent)
{
LOG_FUNC
@@ -2588,6 +2586,29 @@
return rerr;
}
+TInt CPhysicalLink::ExitMode(TBTLinkMode aMode)
+ {
+ LOG_FUNC
+ return iLowPowModeCtrl.ExitMode(aMode, iHandle);
+ }
+
+TInt CPhysicalLink::RequestMode(TBTLinkMode aMode)
+ {
+ LOG_FUNC
+ if (!IsConnected())
+ return KErrDisconnected;
+
+ // if active mode is required, try to exit whatever Low Power mode we are in -
+ // if neither sniff nor park nothing will happen.
+ if(aMode == EActiveMode)
+ {
+ return ExitMode(iLinkState.LinkMode());
+ }
+
+ // now request this connection goes to requested mode
+ return iLowPowModeCtrl.ChangeMode(aMode, iHandle);
+ }
+
TInt CPhysicalLink::RequestChangeRole(TBTBasebandRole aRole)
{
LOG_FUNC
@@ -2666,27 +2687,6 @@
iRoleSwitcher = NULL;
}
-void CPhysicalLink::AsyncDeleteKeyRefresher()
- {
- LOG_FUNC
- iKeyRefreshCompleteCallBack->CallBack();
- }
-
-/*static*/ TInt CPhysicalLink::KeyRefreshCompleteCallBack(TAny* aPhysicalLink)
- {
- LOG_STATIC_FUNC
- CPhysicalLink* physicalLink = static_cast<CPhysicalLink*>(aPhysicalLink);
- physicalLink->DeleteKeyRefresher();
- return EFalse;
- }
-
-void CPhysicalLink::DeleteKeyRefresher()
- {
- LOG_FUNC
- delete iKeyRefresher;
- iKeyRefresher = NULL;
- }
-
TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const
/**
If link is encrypted, but role switcher temporarily disabled encryption, returns true.
@@ -2734,6 +2734,20 @@
return Arbitrate();
}
+TInt CPhysicalLink::OverrideLPMWithTimeout(TUint aTimeout)
+ {
+ LOG_FUNC
+ if(aTimeout == 0)
+ {
+ return KErrNone; //facility not wanted
+ }
+
+ TInt rerr = OverrideLPM();
+ QueueLPMOverrideTimer(aTimeout);
+
+ return rerr;
+ }
+
TInt CPhysicalLink::OverrideLPM()
/**
A request has come in that requires us to ensure we are not using
@@ -2748,6 +2762,20 @@
return Arbitrate();
}
+/*static*/ TInt CPhysicalLink::OverrideLPMTimeoutCallback(TAny* aCPhysicalLink)
+ {
+ LOG_STATIC_FUNC
+ CPhysicalLink* c = reinterpret_cast<CPhysicalLink*>(aCPhysicalLink);
+ TInt err = c->UndoOverrideLPM();
+ //we deliberately ignore this return value because we can't do anything to correct the error situation
+ if (KErrNone != err)
+ {
+ LOG2(_L("Physical link: UndoOverrideLPM returned an error %d on the connection 0x%08x"), err, c);
+ }
+ c->iLPMOverrideTimerQueued = EFalse;
+ return KErrNone;
+ }
+
TInt CPhysicalLink::UndoOverrideLPM()
/**
A need to ensure we are not in LPM has gone.
@@ -3088,14 +3116,29 @@
AuthenticationComplete(EPinRequestPending);
}
+
TInt CPhysicalLink::RequestHold()
{
LOG_FUNC
- if (!IsConnected())
- {
- return KErrDisconnected;
- }
- return iLowPowModeCtrl.ChangeMode(EHoldMode, iHandle);
+ return RequestMode(EHoldMode);
+ }
+
+TInt CPhysicalLink::RequestSniff()
+ {
+ LOG_FUNC
+ return RequestMode(ESniffMode);
+ }
+
+TInt CPhysicalLink::RequestPark()
+ {
+ LOG_FUNC
+ return RequestMode(EParkMode);
+ }
+
+TInt CPhysicalLink::RequestActive()
+ {
+ LOG_FUNC
+ return RequestMode(EActiveMode);
}
void CPhysicalLink::ReadNewPhysicalLinkMetricValue(TUint aIoctlName, CBTProxySAP& aSAP, TInt aCurrentValue)
@@ -3342,6 +3385,11 @@
CActiveScheduler::Add(this);
}
+CArbitrationDelayTimer::~CArbitrationDelayTimer()
+ {
+ LOG_FUNC
+ }
+
void CArbitrationDelayTimer::ConstructL()
{
LOG_FUNC
@@ -3363,21 +3411,21 @@
LOG_FUNC
// Work out what the local priority will be now
iLocalPriority = iLocalPriority || aLocalPriority;
- LOG1(_L8("Arbitration: Local Priority now %d"), iLocalPriority);
+ LOG1(_L8("Arbitraion: Local Priority now %d"), iLocalPriority);
if(aImmediate)
{
- LOG(_L8("Arbitration: Immediate Arbitration Requested..."));
+ LOG(_L8("Arbitraion: Immediate Arbitration Requested..."));
CancelButPreserveLocalPriority();
return DoArbitrate();
}
else if(!IsActive())
{
- LOG(_L8("Arbitration: Arbitration requested, will execute after delay timer..."));
+ LOG(_L8("Arbitraion: Arbitration requested, will execute after delay timer..."));
After(KBTArbitrationDelay);
}
else // timer is already on its way
{
- LOG(_L8("Arbitration: Arbitration delay timer still pending..."));
+ LOG(_L8("Arbitraion: Arbitration delay timer still pending..."));
}
return KErrNone;
}
@@ -3385,7 +3433,7 @@
void CArbitrationDelayTimer::Restart()
{
LOG_FUNC
- LOG(_L8("Arbitration: Arbitration timer restarted..."));
+ LOG(_L8("Arbitraion: Arbitration timer restarted..."));
CancelButPreserveLocalPriority();
After(KBTArbitrationDelay);
}
@@ -3405,7 +3453,7 @@
**/
{
LOG_FUNC
- LOG(_L8("Arbitration: Delayed Arbitration executing..."));
+ LOG(_L8("Arbitraion: Delayed Arbitration executing..."));
static_cast<void>(DoArbitrate()); // ignore the error (always has been...)
}
@@ -3943,46 +3991,6 @@
return err;
}
-TInt TLowPowModeCmdController::ExecuteModeChange(TBTLinkMode aTargetMode)
- {
- LOG_FUNC
- iTargetMode = aTargetMode;
- if(iTargetMode != iParent.LinkState().LinkMode())
- {
- if(iParent.LinkState().LinkMode() != EActiveMode)
- {
- //the current mode is not in Active Mode, therefore the mode need to change to active first before change to other mode.
- LOG(_L8("ExecuteModeChange: Exiting existing LPM mode..."));
- return ExitMode(iParent.LinkState().LinkMode(), iParent.Handle());
- }
- //the current mode is in Active mode, therefore the mode is ready to go other mode.
- if(iTargetMode == EHoldMode)
- {
- LOG(_L8("ExecuteModeChange: Entering Hold mode..."));
- return ChangeMode(EHoldMode, iParent.Handle());
- }
- else if(iTargetMode == ESniffMode)
- {
- LOG(_L8("ExecuteModeChange: Entering Sniff mode..."));
- return ChangeMode(ESniffMode, iParent.Handle());
- }
- else if(iTargetMode == EParkMode)
- {
- LOG(_L8("ExecuteModeChange: Entering Park mode..."));
- return ChangeMode(EParkMode, iParent.Handle());
- }
- else if(iTargetMode == EActiveMode)
- {
- LOG(_L8("ExecuteModeChange: Staying in Active mode..."));
- return KErrNone;
- }
- // Shouldn't reach here, we have a strange mode
- DEBUG_PANIC_LINENUM;
- }
- LOG(_L8("ExecuteModeChange: Already in correct LPM, not doing anything"));
- return KErrNone;
- }
-
void TLowPowModeCmdController::SniffL(THCIConnHandle aHandleToRemote)
{
LOG_FUNC
@@ -4052,36 +4060,29 @@
LOG2(_L("TLowPowModeCmdController::MhcqcCommandEventReceived: event:%d opcode:0x%x"), code, aRelatedCommand->Opcode());
const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent);
- TBTLinkMode currentmode = EActiveMode;
+ TBTLinkMode mode = EActiveMode;
switch(modeChangeEvent.CurrentMode())
{
// Mode 0, as defined for the Mode Change Event, is Active Mode
case 0:
break;
case 1:
- currentmode = EHoldMode;
+ mode = EHoldMode;
break;
case 2:
- currentmode = ESniffMode;
+ mode = ESniffMode;
break;
case 3:
- currentmode = EParkMode;
+ mode = EParkMode;
break;
default:
__ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument));
break;
}
- // In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called.
- // Since this methods find the CPhysicalLink object (that is iParent) and then call its
- // ModeChange method, we can call it directly.
- iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), currentmode, modeChangeEvent.Interval());
- //pass the current mode into Gear box. let gear box to decide if the mode is on the target mode.
- //if it is, the gear box returns KErrNone, if it is not, the gear box will make another request for the target mode
- if (aEvent.ErrorCode() == EOK)
- {
- TInt err = ExecuteModeChange(iTargetMode);
- LOG1(_L("TLowPowModeCmdController::ExecuteModeChange: err:%d"), err);
- }
+ // In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called.
+ // Since this methods find the CPhysicalLink object (that is iParent) and then call its
+ // ModeChange method, we can call it directly.
+ iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), mode, modeChangeEvent.Interval());
}
}