bluetooth/btstack/linkmgr/physicallinks.cpp
branchRCL_3
changeset 22 786b94c6f0a4
parent 18 1f10b9300be6
child 25 99439b07e980
equal deleted inserted replaced
21:14e240312f6f 22:786b94c6f0a4
    56 #endif
    56 #endif
    57 
    57 
    58 static const THCIErrorCode KDefaultRejectReason = EHostSecurityRejection; // see spec Error Codes
    58 static const THCIErrorCode KDefaultRejectReason = EHostSecurityRejection; // see spec Error Codes
    59 
    59 
    60 #ifdef _DEBUG
    60 #ifdef _DEBUG
    61 #define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(aHandle==iHandle, Panic(EBTLinkMgrConnectionEventInWrongSAP));
    61 #define __CHECK_CONNECTION_HANDLE(aHandle) __ASSERT_DEBUG(HasHandle(aHandle), Panic(EBTLinkMgrConnectionEventInWrongSAP));
    62 #else
    62 #else
    63 #define __CHECK_CONNECTION_HANDLE(aHandle) aHandle=aHandle; // to suppress warnings
    63 #define __CHECK_CONNECTION_HANDLE(aHandle) aHandle=aHandle; // to suppress warnings
    64 #endif
    64 #endif
    65 
    65 
    66 CPhysicalLink* CPhysicalLink::NewLC(CPhysicalLinksManager& aConnectionMan, CRegistrySession& aRegSess, const TBTNamelessDevice& aDevice)
    66 CPhysicalLink* CPhysicalLink::NewLC(CPhysicalLinksManager& aConnectionMan, CRegistrySession& aRegSess, const TBTNamelessDevice& aDevice)
  1824 		LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask);
  1824 		LOG2(_L8("Arbitration: Comparison mask (0x%04x) matched, so staying in current mode (0x%04x)"), modeCompareMask, currentModeMask);
  1825 		// The current state is the same as the permitted required role(s).
  1825 		// The current state is the same as the permitted required role(s).
  1826 		return KErrNone;
  1826 		return KErrNone;
  1827 		}
  1827 		}
  1828 	
  1828 	
  1829 	TBTLinkMode nextMode = EActiveMode;
  1829 	TBTLinkMode targetMode = EActiveMode;
  1830 	// Determine which LPM we should be in (if any)
  1830 	// Determine which LPM we should be in (if any)
  1831 	if(modeChangeMask & KExplicitActiveMode)
  1831 	if(modeChangeMask & KExplicitActiveMode)
  1832 		{
  1832 		{
  1833 		nextMode = EActiveMode;
  1833 		targetMode = EActiveMode;
  1834 		}
  1834 		}
  1835 	else if(modeChangeMask & EHoldMode)
  1835 	else if(modeChangeMask & EHoldMode)
  1836 		{
  1836 		{
  1837 		nextMode = EHoldMode;
  1837 		targetMode = EHoldMode;
  1838 		}
  1838 		}
  1839 	else if(modeChangeMask & ESniffMode)
  1839 	else if(modeChangeMask & ESniffMode)
  1840 		{
  1840 		{
  1841 		nextMode = ESniffMode;
  1841 		targetMode = ESniffMode;
  1842 		}
  1842 		}
  1843 	else if(modeChangeMask & EParkMode)
  1843 	else if(modeChangeMask & EParkMode)
  1844 		{
  1844 		{
  1845 		nextMode = EParkMode;
  1845 		targetMode = EParkMode;
  1846 		}
  1846 		}
  1847 	LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, nextMode);
  1847 	LOG2(_L8("Arbitration: Arbitrating mode 0x%02x -> 0x%02x"), currentMode, targetMode);
  1848 	
  1848 	
  1849 	if(nextMode != currentMode)
  1849 	if(IsConnected())
  1850 		{
  1850 	    {
  1851 		if(currentMode != EActiveMode)
  1851         TInt err = iLowPowModeCtrl.ExecuteModeChange(targetMode);
  1852 			{
  1852         LOG1(_L8("Arbitration: iLowPowModeCtrl.ExecuteModeChange: err:%d"), err);
  1853 			LOG(_L8("Arbitration: Exiting existing LPM mode..."));
  1853         return err;
  1854 			TInt err = RequestActive();
  1854 	    }
  1855 			if(err != KErrNone)
  1855 	else
  1856 				{
  1856 	    {
  1857 				return err;
  1857         return KErrDisconnected;
  1858 				}
  1858 	    }
  1859 			}
       
  1860 		if(nextMode == EHoldMode)
       
  1861 			{
       
  1862 			LOG(_L8("Arbitration: Entering Hold mode..."));
       
  1863 			return RequestHold();
       
  1864 			}
       
  1865 		else if(nextMode == ESniffMode)
       
  1866 			{
       
  1867 			LOG(_L8("Arbitration: Entering Sniff mode..."));
       
  1868 			return RequestSniff();
       
  1869 			}
       
  1870 		else if(nextMode == EParkMode)
       
  1871 			{
       
  1872 			LOG(_L8("Arbitration: Entering Park mode..."));
       
  1873 			return RequestPark();
       
  1874 			}
       
  1875 		else if(nextMode == EActiveMode)
       
  1876 			{
       
  1877 			LOG(_L8("Arbitration: Staying in Active mode..."));
       
  1878 			return KErrNone;
       
  1879 			}
       
  1880 		// Shouldn't reach here, we have a strange mode
       
  1881 		DEBUG_PANIC_LINENUM;
       
  1882 		}
       
  1883 
       
  1884 	LOG(_L8("Arbitration: Already in correct LPM, not doing anything"));
       
  1885 	return KErrNone;
       
  1886 	}
  1859 	}
  1887 
  1860 
  1888 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey)
  1861 void CPhysicalLink::SetPassKey(const TDesC8& aPassKey)
  1889 	{
  1862 	{
  1890 	LOG_FUNC
  1863 	LOG_FUNC
  2609 		{
  2582 		{
  2610 		iConnectionPacketTypeChanged = ETrue;
  2583 		iConnectionPacketTypeChanged = ETrue;
  2611 		}
  2584 		}
  2612 
  2585 
  2613 	return rerr;
  2586 	return rerr;
  2614 	}
       
  2615 
       
  2616 TInt CPhysicalLink::ExitMode(TBTLinkMode aMode)
       
  2617 	{
       
  2618 	LOG_FUNC
       
  2619 	return iLowPowModeCtrl.ExitMode(aMode, iHandle);
       
  2620 	}
       
  2621 
       
  2622 TInt CPhysicalLink::RequestMode(TBTLinkMode aMode)
       
  2623 	{
       
  2624 	LOG_FUNC
       
  2625 	if (!IsConnected())
       
  2626 		return KErrDisconnected;
       
  2627 
       
  2628 	// if active mode is required, try to exit whatever Low Power mode we are in -
       
  2629 	// if neither sniff nor park nothing will happen.
       
  2630 	if(aMode == EActiveMode)
       
  2631 		{
       
  2632 		return ExitMode(iLinkState.LinkMode());
       
  2633 		}
       
  2634 
       
  2635 	// now request this connection goes to requested mode
       
  2636 	return iLowPowModeCtrl.ChangeMode(aMode, iHandle);
       
  2637 	}
  2587 	}
  2638 
  2588 
  2639 TInt CPhysicalLink::RequestChangeRole(TBTBasebandRole aRole)
  2589 TInt CPhysicalLink::RequestChangeRole(TBTBasebandRole aRole)
  2640 	{
  2590 	{
  2641 	LOG_FUNC
  2591 	LOG_FUNC
  3141 	iPinRequester = NULL;
  3091 	iPinRequester = NULL;
  3142 	iPinHandler = NULL;
  3092 	iPinHandler = NULL;
  3143 	AuthenticationComplete(EPinRequestPending);
  3093 	AuthenticationComplete(EPinRequestPending);
  3144 	}
  3094 	}
  3145 
  3095 
  3146 
       
  3147 TInt CPhysicalLink::RequestHold()
  3096 TInt CPhysicalLink::RequestHold()
  3148 	{
  3097 	{
  3149 	LOG_FUNC
  3098 	LOG_FUNC
  3150 	return RequestMode(EHoldMode);
  3099 	if (!IsConnected())
  3151 	}
  3100         {
  3152 
  3101         return KErrDisconnected;
  3153 TInt CPhysicalLink::RequestSniff()
  3102         }
  3154 	{
  3103 	 return iLowPowModeCtrl.ChangeMode(EHoldMode, iHandle);
  3155 	LOG_FUNC
       
  3156 	return RequestMode(ESniffMode);
       
  3157 	}
       
  3158 
       
  3159 TInt CPhysicalLink::RequestPark()
       
  3160 	{
       
  3161 	LOG_FUNC
       
  3162 	return RequestMode(EParkMode);
       
  3163 	}
       
  3164 
       
  3165 TInt CPhysicalLink::RequestActive()
       
  3166 	{
       
  3167 	LOG_FUNC
       
  3168 	return RequestMode(EActiveMode);
       
  3169 	}
  3104 	}
  3170 
  3105 
  3171 void CPhysicalLink::ReadNewPhysicalLinkMetricValue(TUint aIoctlName, CBTProxySAP& aSAP, TInt aCurrentValue)
  3106 void CPhysicalLink::ReadNewPhysicalLinkMetricValue(TUint aIoctlName, CBTProxySAP& aSAP, TInt aCurrentValue)
  3172 	{
  3107 	{
  3173 	LOG_FUNC
  3108 	LOG_FUNC
  3431 TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority)
  3366 TInt CArbitrationDelayTimer::Start(TBool aImmediate, TBool aLocalPriority)
  3432 	{
  3367 	{
  3433 	LOG_FUNC
  3368 	LOG_FUNC
  3434 	// Work out what the local priority will be now
  3369 	// Work out what the local priority will be now
  3435 	iLocalPriority = iLocalPriority || aLocalPriority;
  3370 	iLocalPriority = iLocalPriority || aLocalPriority;
  3436 	LOG1(_L8("Arbitraion: Local Priority now %d"), iLocalPriority);
  3371 	LOG1(_L8("Arbitration: Local Priority now %d"), iLocalPriority);
  3437 	if(aImmediate)
  3372 	if(aImmediate)
  3438 		{
  3373 		{
  3439 		LOG(_L8("Arbitraion: Immediate Arbitration Requested..."));
  3374 		LOG(_L8("Arbitration: Immediate Arbitration Requested..."));
  3440 		CancelButPreserveLocalPriority();
  3375 		CancelButPreserveLocalPriority();
  3441 		return DoArbitrate();
  3376 		return DoArbitrate();
  3442 		}
  3377 		}
  3443 	else if(!IsActive())
  3378 	else if(!IsActive())
  3444 		{
  3379 		{
  3445 		LOG(_L8("Arbitraion: Arbitration requested, will execute after delay timer..."));
  3380 		LOG(_L8("Arbitration: Arbitration requested, will execute after delay timer..."));
  3446 		After(KBTArbitrationDelay);
  3381 		After(KBTArbitrationDelay);
  3447 		}
  3382 		}
  3448 	else // timer is already on its way
  3383 	else // timer is already on its way
  3449 		{
  3384 		{
  3450 		LOG(_L8("Arbitraion: Arbitration delay timer still pending..."));
  3385 		LOG(_L8("Arbitration: Arbitration delay timer still pending..."));
  3451 		}
  3386 		}
  3452 	return KErrNone;
  3387 	return KErrNone;
  3453 	}
  3388 	}
  3454 
  3389 
  3455 void CArbitrationDelayTimer::Restart()
  3390 void CArbitrationDelayTimer::Restart()
  3456 	{
  3391 	{
  3457 	LOG_FUNC
  3392 	LOG_FUNC
  3458 	LOG(_L8("Arbitraion: Arbitration timer restarted..."));
  3393 	LOG(_L8("Arbitration: Arbitration timer restarted..."));
  3459 	CancelButPreserveLocalPriority();
  3394 	CancelButPreserveLocalPriority();
  3460 	After(KBTArbitrationDelay);
  3395 	After(KBTArbitrationDelay);
  3461 	}
  3396 	}
  3462 
  3397 
  3463 void CArbitrationDelayTimer::CancelButPreserveLocalPriority()
  3398 void CArbitrationDelayTimer::CancelButPreserveLocalPriority()
  3473 /**
  3408 /**
  3474 Allow arbitration of low power modes when the timer expires
  3409 Allow arbitration of low power modes when the timer expires
  3475 **/
  3410 **/
  3476 	{
  3411 	{
  3477 	LOG_FUNC
  3412 	LOG_FUNC
  3478 	LOG(_L8("Arbitraion: Delayed Arbitration executing..."));
  3413 	LOG(_L8("Arbitration: Delayed Arbitration executing..."));
  3479 	static_cast<void>(DoArbitrate()); // ignore the error (always has been...)
  3414 	static_cast<void>(DoArbitrate()); // ignore the error (always has been...)
  3480 	}
  3415 	}
  3481 
  3416 
  3482 TInt CArbitrationDelayTimer::DoArbitrate()
  3417 TInt CArbitrationDelayTimer::DoArbitrate()
  3483 	{
  3418 	{
  4011 	LOG_FUNC
  3946 	LOG_FUNC
  4012 	TRAPD(err, DoChangeModeL(aMode, aHandle));
  3947 	TRAPD(err, DoChangeModeL(aMode, aHandle));
  4013 	return err;
  3948 	return err;
  4014 	}
  3949 	}
  4015 
  3950 
       
  3951 TInt TLowPowModeCmdController::ExecuteModeChange(TBTLinkMode aTargetMode)
       
  3952 	{
       
  3953 	LOG_FUNC
       
  3954 	iTargetMode = aTargetMode;
       
  3955 	if(iTargetMode != iParent.LinkState().LinkMode())
       
  3956 		{
       
  3957 		if(iParent.LinkState().LinkMode() != EActiveMode)
       
  3958 			{
       
  3959 			//the current mode is not in Active Mode, therefore the mode need to change to active first before change to other mode.
       
  3960 			LOG(_L8("ExecuteModeChange: Exiting existing LPM mode..."));
       
  3961 			return ExitMode(iParent.LinkState().LinkMode(), iParent.Handle());
       
  3962 			}
       
  3963 		//the current mode is in Active mode, therefore the mode is ready to go other mode.
       
  3964 		if(iTargetMode == EHoldMode)
       
  3965 			{
       
  3966 			LOG(_L8("ExecuteModeChange: Entering Hold mode..."));
       
  3967 			return ChangeMode(EHoldMode, iParent.Handle());
       
  3968 			}
       
  3969 		else if(iTargetMode == ESniffMode)
       
  3970 			{
       
  3971 			LOG(_L8("ExecuteModeChange: Entering Sniff mode..."));
       
  3972 			return ChangeMode(ESniffMode, iParent.Handle());
       
  3973 			}
       
  3974 		else if(iTargetMode == EParkMode)
       
  3975 			{
       
  3976 			LOG(_L8("ExecuteModeChange: Entering Park mode..."));
       
  3977 			return ChangeMode(EParkMode, iParent.Handle());
       
  3978 			}
       
  3979 		else if(iTargetMode == EActiveMode)
       
  3980 			{
       
  3981 			LOG(_L8("ExecuteModeChange: Staying in Active mode..."));
       
  3982 			return KErrNone;
       
  3983 			}
       
  3984 		// Shouldn't reach here, we have a strange mode
       
  3985 		DEBUG_PANIC_LINENUM;
       
  3986 		}
       
  3987 	LOG(_L8("ExecuteModeChange: Already in correct LPM, not doing anything"));
       
  3988 	return KErrNone;
       
  3989 	}
       
  3990 
  4016 void TLowPowModeCmdController::SniffL(THCIConnHandle aHandleToRemote)
  3991 void TLowPowModeCmdController::SniffL(THCIConnHandle aHandleToRemote)
  4017 	{
  3992 	{
  4018 	LOG_FUNC
  3993 	LOG_FUNC
  4019 	CSniffModeCommand* cmd = CSniffModeCommand::NewL(aHandleToRemote, KBTSniffModeMaxInterval, KBTSniffModeMinInterval, KBTSniffModeAttempt, KBTSniffModeTimeout);
  3994 	CSniffModeCommand* cmd = CSniffModeCommand::NewL(aHandleToRemote, KBTSniffModeMaxInterval, KBTSniffModeMinInterval, KBTSniffModeAttempt, KBTSniffModeTimeout);
  4020 
  3995 
  4080 		iOutstandingCmd = EFalse;	// reset the outstanding flag
  4055 		iOutstandingCmd = EFalse;	// reset the outstanding flag
  4081 
  4056 
  4082 		LOG2(_L("TLowPowModeCmdController::MhcqcCommandEventReceived: event:%d opcode:0x%x"), code, aRelatedCommand->Opcode());
  4057 		LOG2(_L("TLowPowModeCmdController::MhcqcCommandEventReceived: event:%d opcode:0x%x"), code, aRelatedCommand->Opcode());
  4083 
  4058 
  4084 		const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent);
  4059 		const TModeChangeEvent& modeChangeEvent = TModeChangeEvent::Cast(aEvent);
  4085 		TBTLinkMode mode = EActiveMode;
  4060 		TBTLinkMode currentmode = EActiveMode;
  4086 		switch(modeChangeEvent.CurrentMode())
  4061 		switch(modeChangeEvent.CurrentMode())
  4087 			{
  4062 			{
  4088 			// Mode 0, as defined for the Mode Change Event, is Active Mode
  4063 			// Mode 0, as defined for the Mode Change Event, is Active Mode
  4089 			case 0:
  4064 			case 0:
  4090 				break;
  4065 				break;
  4091 			case 1:
  4066 			case 1:
  4092 				mode = EHoldMode;
  4067 				currentmode = EHoldMode;
  4093 				break;
  4068 				break;
  4094 			case 2:
  4069 			case 2:
  4095 				mode = ESniffMode;
  4070 				currentmode = ESniffMode;
  4096 				break;
  4071 				break;
  4097 			case 3:
  4072 			case 3:
  4098 				mode = EParkMode;
  4073 				currentmode = EParkMode;
  4099 				break;
  4074 				break;
  4100 			default:
  4075 			default:
  4101 				__ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument));
  4076 				__ASSERT_ALWAYS(EFalse, Panic(EHCICommandBadArgument));
  4102 				break;
  4077 				break;
  4103 			}
  4078 			}
  4104 			// In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called.
  4079 		// In the HCI_Facade, in this situation, CPhysicalLinksManager::ModeChanged() is called.
  4105 			// Since this methods find the CPhysicalLink object (that is iParent) and then call its
  4080 		// Since this methods find the CPhysicalLink object (that is iParent) and then call its
  4106 			// ModeChange method, we can call it directly.
  4081 		// ModeChange method, we can call it directly.
  4107 			iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), mode, modeChangeEvent.Interval());
  4082 		iParent.ModeChange(aEvent.ErrorCode(), modeChangeEvent.ConnectionHandle(), currentmode, modeChangeEvent.Interval());
       
  4083 		//pass the current mode into Gear box. let gear box to decide if the mode is on the target mode. 
       
  4084 		//if it is, the gear box returns KErrNone, if it is not, the gear box will make another request for the target mode
       
  4085 		if (aEvent.ErrorCode() == EOK)
       
  4086 			{
       
  4087             TInt err = ExecuteModeChange(iTargetMode);
       
  4088 			LOG1(_L("TLowPowModeCmdController::ExecuteModeChange: err:%d"), err);
       
  4089 			}
  4108 		}
  4090 		}
  4109 	}
  4091 	}
  4110 
  4092 
  4111 void TLowPowModeCmdController::MhcqcCommandErrored(TInt __DEBUG_ONLY(aErrorCode), const CHCICommandBase* __DEBUG_ONLY(aCommand))
  4093 void TLowPowModeCmdController::MhcqcCommandErrored(TInt __DEBUG_ONLY(aErrorCode), const CHCICommandBase* __DEBUG_ONLY(aCommand))
  4112 	{
  4094 	{