bluetooth/btstack/linkmgr/physicallinks.cpp
branchRCL_3
changeset 25 99439b07e980
parent 22 786b94c6f0a4
equal deleted inserted replaced
24:e9b924a62a66 25:99439b07e980
    23 #include "SCOSAP.h"
    23 #include "SCOSAP.h"
    24 #include "ProxySAP.h"
    24 #include "ProxySAP.h"
    25 #include "linkconsts.h"
    25 #include "linkconsts.h"
    26 #include "hcifacade.h"
    26 #include "hcifacade.h"
    27 #include "hostresolver.h"
    27 #include "hostresolver.h"
    28 #include "PhysicalLinkHelper.h"
    28 #include "roleswitchhelper.h"
    29 #include "pairingscache.h"
    29 #include "pairingscache.h"
    30 #include "oobdata.h"
    30 #include "oobdata.h"
    31 #include "pairingserver.h"
    31 #include "pairingserver.h"
       
    32 #include "encryptionkeyrefreshhelper.h"
    32 
    33 
    33 #include <bt_sock.h>
    34 #include <bt_sock.h>
    34 
    35 
    35 #include <bluetooth/hci/commandstatusevent.h>
    36 #include <bluetooth/hci/commandstatusevent.h>
    36 #include <bluetooth/hci/sniffmodecommand.h>
    37 #include <bluetooth/hci/sniffmodecommand.h>
    89 	, iDeviceResult(KDeviceNotObtained)
    90 	, iDeviceResult(KDeviceNotObtained)
    90 	, iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink))
    91 	, iRegistryHelpers(_FOFF(CBTRegistryHelperBase,iLink))
    91 	, iProxySAPs(_FOFF(CBTProxySAP, iQueueLink))
    92 	, iProxySAPs(_FOFF(CBTProxySAP, iQueueLink))
    92 	, iOverrideParkRequests(EFalse)
    93 	, iOverrideParkRequests(EFalse)
    93 	, iOverrideLPMRequests(EFalse)
    94 	, iOverrideLPMRequests(EFalse)
    94 	, iLPMOverrideTimerQueued(EFalse)
       
    95 	, iConnectionPacketTypeChanged(EFalse)
    95 	, iConnectionPacketTypeChanged(EFalse)
    96 	, iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    96 	, iLowPowModeCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    97 	, iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    97 	, iDisconnectCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    98 	, iAuthenticationCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    98 	, iAuthenticationCtrl(*this, iLinksMan.HCIFacade().CommandQController())
    99 	, iLSTO(0)
    99 	, iLSTO(0)
   117 	// tell ConnectionsManager...
   117 	// tell ConnectionsManager...
   118 	iLinksMan.RemovePhysicalLink(*this);
   118 	iLinksMan.RemovePhysicalLink(*this);
   119 	iACLLogicalLinks.Close();
   119 	iACLLogicalLinks.Close();
   120 
   120 
   121 	RemoveIdleTimer();
   121 	RemoveIdleTimer();
   122 	if (iLPMOverrideTimerQueued)
       
   123 		{
       
   124 		BTSocketTimer::Remove(iOverrideLPMTimerEntry);
       
   125 		iLPMOverrideTimerQueued = EFalse;
       
   126 		}
       
   127 
   122 
   128 	LOG(_L("sec\tClosing subscribers..."))
   123 	LOG(_L("sec\tClosing subscribers..."))
   129 
   124 
   130 	LOG(_L("sec\tClosing helpers..."))
   125 	LOG(_L("sec\tClosing helpers..."))
   131 	TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers);
   126 	TSglQueIter<CBTRegistryHelperBase> iter(iRegistryHelpers);
   147 	delete iNumericComparator;
   142 	delete iNumericComparator;
   148 	delete iUserConfirmer;
   143 	delete iUserConfirmer;
   149 	delete iPasskeyEntry;
   144 	delete iPasskeyEntry;
   150 	delete iArbitrationDelay;
   145 	delete iArbitrationDelay;
   151 	delete iRoleSwitchCompleteCallBack;
   146 	delete iRoleSwitchCompleteCallBack;
       
   147 	delete iKeyRefreshCompleteCallBack;
   152 	delete iEncryptionEnforcer;
   148 	delete iEncryptionEnforcer;
   153 
   149 
   154 	DeleteRoleSwitcher();
   150 	DeleteRoleSwitcher();
       
   151 	DeleteKeyRefresher();
   155 	}
   152 	}
   156 
   153 
   157 void CPhysicalLink::ConstructL()
   154 void CPhysicalLink::ConstructL()
   158 	{
   155 	{
   159 	LOG_FUNC
   156 	LOG_FUNC
   162 	iArbitrationDelay = CArbitrationDelayTimer::NewL(this);
   159 	iArbitrationDelay = CArbitrationDelayTimer::NewL(this);
   163 
   160 
   164 	TCallBack cb1(RoleSwitchCompleteCallBack, this);
   161 	TCallBack cb1(RoleSwitchCompleteCallBack, this);
   165 	iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority);
   162 	iRoleSwitchCompleteCallBack = new (ELeave)CAsyncCallBack(cb1, EActiveHighPriority);
   166 
   163 
   167 	TCallBack cb2(OverrideLPMTimeoutCallback, this);
   164 	TCallBack cb2(KeyRefreshCompleteCallBack, this);
   168 	iOverrideLPMTimerEntry.Set(cb2);
   165 	iKeyRefreshCompleteCallBack = new (ELeave)CAsyncCallBack(cb2, EActiveHighPriority);
   169 
   166 	
   170 	iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController());
   167 	iPhysicalLinkMetrics = CPhysicalLinkMetrics::NewL(*this, iLinksMan.HCIFacade().CommandQController());
   171 	}
   168 	}
   172 
   169 
   173 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const
   170 TBool CPhysicalLink::HasHandle(THCIConnHandle aHandle) const
   174 	{
   171 	{
   235 		err = KErrNotSupported;
   232 		err = KErrNotSupported;
   236 		*reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL;
   233 		*reinterpret_cast<MBluetoothControlPlaneToken**>(aOutToken) = NULL;
   237 		}
   234 		}
   238 	else
   235 	else
   239 		{
   236 		{
   240 		if (iAutoKeyRefreshQue.IsEmpty())
   237 		// Only refresh the key if no-one is preventing it and we aren't still 
   241 			{
   238 		// refreshing the key from a previous request.  Note that although
   242 			TRAP_IGNORE(iLinksMan.HCIFacade().RefreshEncryptionKeyL(iHandle));
   239 		// the previous key refresh may actually have finished if the key
       
   240 		// refresher is waiting for async delete we have only just refreshed 
       
   241 		// the key and there's no point doing it again.
       
   242 		if (iAutoKeyRefreshQue.IsEmpty() && !iKeyRefresher)
       
   243 			{
       
   244 			TRAPD(err, iKeyRefresher = CEncryptionKeyRefresher::NewL(iLinksMan, *this));
       
   245 			if(!err)
       
   246 				{
       
   247 				// Kick off the helper state machine
       
   248 				iKeyRefresher->StartHelper();
       
   249 				}
   243 			// If we can't refresh the encryption key, there's not much we can do
   250 			// If we can't refresh the encryption key, there's not much we can do
   244 			}
   251 			}
   245 		XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken();
   252 		XAutoKeyRefreshToken* token = new XAutoKeyRefreshToken();
   246 		if (token)
   253 		if (token)
   247 			{
   254 			{
  1360 	{
  1367 	{
  1361 	LOG_FUNC
  1368 	LOG_FUNC
  1362 	CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this);
  1369 	CBTDeviceNameChanger* nameChanger = CBTDeviceNameChanger::NewL(iRegSess, *this);
  1363 	iRegistryHelpers.AddLast(*nameChanger);
  1370 	iRegistryHelpers.AddLast(*nameChanger);
  1364 	nameChanger->Start(BDAddr(), aName);
  1371 	nameChanger->Start(BDAddr(), aName);
       
  1372 	}
       
  1373 
       
  1374 void CPhysicalLink::EncryptionKeyRefreshComplete(THCIErrorCode aErr, THCIConnHandle aConnH)
       
  1375 	{
       
  1376 	LOG_FUNC
       
  1377 	__CHECK_CONNECTION_HANDLE(aConnH);
       
  1378 
       
  1379 	if(iKeyRefresher)
       
  1380 		{
       
  1381 		iKeyRefresher->EncryptionKeyRefreshComplete(aErr);
       
  1382 		}
  1365 	}
  1383 	}
  1366 
  1384 
  1367 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult)
  1385 void CPhysicalLink::Disconnection(THCIErrorCode aErr, THCIConnHandle aConnH, THCIErrorCode aResult)
  1368 	{
  1386 	{
  1369 	LOG_FUNC
  1387 	LOG_FUNC
  2225 		}
  2243 		}
  2226 	BTSocketTimer::Remove(iIdleTimerEntry);
  2244 	BTSocketTimer::Remove(iIdleTimerEntry);
  2227 	iIdleTimerQueued = EFalse;
  2245 	iIdleTimerQueued = EFalse;
  2228 	}
  2246 	}
  2229 
  2247 
  2230 void CPhysicalLink::QueueLPMOverrideTimer(TInt aTimeout)
       
  2231 /**
       
  2232 	Queue LPM Override timer entry.
       
  2233 	When this timer expires, it'll call UndoLPMOverride.
       
  2234 **/
       
  2235 	{
       
  2236 	LOG_FUNC
       
  2237 	__ASSERT_DEBUG(aTimeout!=0, Panic(EBTPhysicalLinksInvalidArgument));
       
  2238 	if (iLPMOverrideTimerQueued)
       
  2239 		{
       
  2240 		BTSocketTimer::Remove(iOverrideLPMTimerEntry);
       
  2241 		}
       
  2242 	BTSocketTimer::Queue(aTimeout, iOverrideLPMTimerEntry);
       
  2243 	iLPMOverrideTimerQueued = ETrue;
       
  2244 	}
       
  2245 
       
  2246 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent)
  2248 void CPhysicalLink::NotifyStateChange(TBTBasebandEventNotification& aEvent)
  2247 	{
  2249 	{
  2248 	LOG_FUNC
  2250 	LOG_FUNC
  2249 	// If this event is 'physical link down' / 'physical link error' then any ProxySAP
  2251 	// If this event is 'physical link down' / 'physical link error' then any ProxySAP
  2250 	// subscribers will unsubscribe as a result of PhysicalLinkChange being called.
  2252 	// subscribers will unsubscribe as a result of PhysicalLinkChange being called.
  2662 	LOG_FUNC
  2664 	LOG_FUNC
  2663 	delete iRoleSwitcher;
  2665 	delete iRoleSwitcher;
  2664 	iRoleSwitcher = NULL;
  2666 	iRoleSwitcher = NULL;
  2665 	}
  2667 	}
  2666 
  2668 
       
  2669 void CPhysicalLink::AsyncDeleteKeyRefresher()
       
  2670 	{
       
  2671 	LOG_FUNC
       
  2672 	iKeyRefreshCompleteCallBack->CallBack();
       
  2673 	}
       
  2674 
       
  2675 /*static*/ TInt CPhysicalLink::KeyRefreshCompleteCallBack(TAny* aPhysicalLink)
       
  2676 	{
       
  2677 	LOG_STATIC_FUNC
       
  2678 	CPhysicalLink* physicalLink = static_cast<CPhysicalLink*>(aPhysicalLink);
       
  2679 	physicalLink->DeleteKeyRefresher();
       
  2680 	return EFalse;
       
  2681 	}
       
  2682 
       
  2683 void CPhysicalLink::DeleteKeyRefresher()
       
  2684 	{
       
  2685 	LOG_FUNC
       
  2686 	delete iKeyRefresher;
       
  2687 	iKeyRefresher = NULL;
       
  2688 	}
       
  2689 
  2667 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const
  2690 TBool CPhysicalLink::IsEncryptionDisabledForRoleSwitch() const
  2668 /**
  2691 /**
  2669 	If link is encrypted, but role switcher temporarily disabled encryption, returns true.
  2692 	If link is encrypted, but role switcher temporarily disabled encryption, returns true.
  2670 **/
  2693 **/
  2671 	{
  2694 	{
  2709 	//Arbitrate even if there isn't an outstanding local park mode request beacuse
  2732 	//Arbitrate even if there isn't an outstanding local park mode request beacuse
  2710 	//the remote device may be requesting park mode.
  2733 	//the remote device may be requesting park mode.
  2711 	return Arbitrate();
  2734 	return Arbitrate();
  2712 	}
  2735 	}
  2713 
  2736 
  2714 TInt CPhysicalLink::OverrideLPMWithTimeout(TUint aTimeout)
       
  2715 	{
       
  2716 	LOG_FUNC
       
  2717 	if(aTimeout == 0)
       
  2718 		{
       
  2719 		return KErrNone; //facility not wanted
       
  2720 		}
       
  2721 
       
  2722 	TInt rerr = OverrideLPM();
       
  2723 	QueueLPMOverrideTimer(aTimeout);
       
  2724 
       
  2725 	return rerr;
       
  2726 	}
       
  2727 
       
  2728 TInt CPhysicalLink::OverrideLPM()
  2737 TInt CPhysicalLink::OverrideLPM()
  2729 /**
  2738 /**
  2730 	A request has come in that requires us to ensure we are not using
  2739 	A request has come in that requires us to ensure we are not using
  2731 	an LPM (low power mode).
  2740 	an LPM (low power mode).
  2732 
  2741 
  2735 	{
  2744 	{
  2736 	LOG_FUNC
  2745 	LOG_FUNC
  2737 	iOverrideLPMRequests = ETrue;
  2746 	iOverrideLPMRequests = ETrue;
  2738 
  2747 
  2739 	return Arbitrate();
  2748 	return Arbitrate();
  2740 	}
       
  2741 
       
  2742 /*static*/ TInt CPhysicalLink::OverrideLPMTimeoutCallback(TAny* aCPhysicalLink)
       
  2743 	{
       
  2744 	LOG_STATIC_FUNC	
       
  2745 	CPhysicalLink* c = reinterpret_cast<CPhysicalLink*>(aCPhysicalLink);
       
  2746 	TInt err = c->UndoOverrideLPM();
       
  2747 	//we deliberately ignore this return value because we can't do anything to correct the error situation
       
  2748 	if (KErrNone != err)
       
  2749 		{
       
  2750 		LOG2(_L("Physical link: UndoOverrideLPM returned an error %d on the connection 0x%08x"), err, c);
       
  2751 		}
       
  2752 	c->iLPMOverrideTimerQueued = EFalse;
       
  2753 	return KErrNone;
       
  2754 	}
  2749 	}
  2755 
  2750 
  2756 TInt CPhysicalLink::UndoOverrideLPM()
  2751 TInt CPhysicalLink::UndoOverrideLPM()
  2757 /**
  2752 /**
  2758 	A need to ensure we are not in LPM has gone.
  2753 	A need to ensure we are not in LPM has gone.