bluetooth/btstack/l2cap/L2CapFecNegotiator.cpp
branchRCL_3
changeset 10 8a27654f7b62
parent 0 29b1cd4cb562
child 22 786b94c6f0a4
equal deleted inserted replaced
8:2b6718f05bdb 10:8a27654f7b62
    49 void TModeSpecificFecOptionHandlerBase::BuildNegativeResponse(TRetransmissionAndFlowControlOption& /*aPreferred*/,
    49 void TModeSpecificFecOptionHandlerBase::BuildNegativeResponse(TRetransmissionAndFlowControlOption& /*aPreferred*/,
    50 															  const TRetransmissionAndFlowControlOption& /*aPeer*/) const
    50 															  const TRetransmissionAndFlowControlOption& /*aPeer*/) const
    51 	{
    51 	{
    52 	LOG_FUNC
    52 	LOG_FUNC
    53 	// Just send what we've got in Preferred.
    53 	// Just send what we've got in Preferred.
       
    54 	}
       
    55 
       
    56 void TModeSpecificFecOptionHandlerBase::BuildRequestBasedOnUnacceptableParamsResponse(
       
    57 											TRetransmissionAndFlowControlOption& aPreferred,
       
    58 											const TRetransmissionAndFlowControlOption& aPeer,
       
    59 											const TL2CapFecNegotiator& aFecNegotiator) const
       
    60 	{
       
    61 	LOG_FUNC
       
    62 	// In general the only negotiable parameter is channel mode - that's what we should
       
    63 	// take from the suggested response passed here in aPeer. The rest of the parameters are
       
    64 	// informative and we should use our own values, based on the mode - the remote can not
       
    65 	// reject informative parameters.
       
    66 	// Note on interop:
       
    67 	// Unfortunately <= 9.4 Symbian code _WILL_ reject if e.g. we send a MaxTransmit value
       
    68 	// which is greater than its own preference. To interoperate with those this method is
       
    69 	// overridden in the Legacy handler.
       
    70 
       
    71 	aPreferred = TRetransmissionAndFlowControlOption(aPeer.LinkMode(), ETrue);
       
    72 	SetMaxTransmit(aPreferred, aFecNegotiator.MaxTransmit());
       
    73 	ZeroUnspecifiedRequestFields(aPreferred);
    54 	}
    74 	}
    55 
    75 
    56 void TModeSpecificFecOptionHandlerBase::SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 /*aMaxTransmit*/) const
    76 void TModeSpecificFecOptionHandlerBase::SetMaxTransmit(TRetransmissionAndFlowControlOption& aFecOption, TUint8 /*aMaxTransmit*/) const
    57 	{
    77 	{
    58 	LOG_FUNC
    78 	LOG_FUNC
   247 	{
   267 	{
   248 	aFecOption.SetMaxTransmit(aMaxTransmit == TRetransmissionAndFlowControlOption::KMaxValidEnhancedNumberTransmit ?
   268 	aFecOption.SetMaxTransmit(aMaxTransmit == TRetransmissionAndFlowControlOption::KMaxValidEnhancedNumberTransmit ?
   249 							  TRetransmissionAndFlowControlOption::KMaxValidLegacyNumberTransmit :
   269 							  TRetransmissionAndFlowControlOption::KMaxValidLegacyNumberTransmit :
   250 							  aMaxTransmit);
   270 							  aMaxTransmit);
   251 	}
   271 	}
       
   272 
       
   273 void TLegacyFecHandler::BuildRequestBasedOnUnacceptableParamsResponse(
       
   274 		TRetransmissionAndFlowControlOption& aPreferred,
       
   275 		const TRetransmissionAndFlowControlOption& aPeer,
       
   276 		const TL2CapFecNegotiator& aFecNegotiator) const
       
   277     {
       
   278     LOG_FUNC
       
   279 	// In general the only negotiable parameter is channel mode - that's what we should
       
   280 	// take from the suggested response passed here in aPeer. The rest of the parameters are
       
   281 	// informative and we should use our own values, based on the mode - the remote can not
       
   282 	// reject informative parameters.
       
   283 	//
       
   284 	// HOWEVER:
       
   285 	//
       
   286 	// Unfortunately <= 9.4 Symbian code _WILL_ reject if e.g. we send a MaxTransmit value
       
   287 	// which is greater than its own preference. To interoperate with those we take
       
   288 	// the whole FEC option suggested by the remote, including the informational parameters.
       
   289 	// <= 9.4 Symbian devices implement RTM and FC modes (and not ERTM and Streaming).
       
   290 	// Additionally, pretty much noone else in the market does - most people jumped from
       
   291 	// Basic straight to ERTM & Streaming. So it can be assumed that:
       
   292 	// Legacy (RTM & FC) ~= pre-ERTM Symbian. 
       
   293 
       
   294 	typedef TRetransmissionAndFlowControlOption TFec;	// just 'coz I'm lazy
       
   295 
       
   296 	// Use the remote's whole suggestion if all informational parameters look edible ...
       
   297 	if (aPeer.TxWindowSize()          >= TFec::KMinValidTxWindowSize &&
       
   298 		aPeer.MaxTransmit()           >= TFec::KMinValidNumberTransmit &&
       
   299 		aPeer.RetransmissionTimeout() >= TFec::KMinAcceptableRetransmissionTimeout &&
       
   300 		aPeer.MonitorTimeout()        >= TFec::KMinAcceptableMonitorTimeout &&
       
   301 		aPeer.MaximumPDUSize()        >= TFec::KMinValidMaximumPDUSize)
       
   302 		{
       
   303 		aPreferred = aPeer;
       
   304 		}
       
   305 	else // ... otherwise only use channel mode to prevent DoS attacks.
       
   306 		{
       
   307 		aPreferred = TRetransmissionAndFlowControlOption(aPeer.LinkMode(), ETrue);
       
   308 		SetMaxTransmit(aPreferred, aFecNegotiator.MaxTransmit());
       
   309 		ZeroUnspecifiedRequestFields(aPreferred);
       
   310 		}
       
   311 	}
       
   312 
   252 
   313 
   253 // Basic mode
   314 // Basic mode
   254 
   315 
   255 TBool TBasicFecHandler::IsOptionValid(const TRetransmissionAndFlowControlOption& /*aFecOption*/) const
   316 TBool TBasicFecHandler::IsOptionValid(const TRetransmissionAndFlowControlOption& /*aFecOption*/) const
   256 	{
   317 	{
   474  	else
   535  	else
   475  		{
   536  		{
   476 	 	if (aIsUnacceptableParameters)
   537 	 	if (aIsUnacceptableParameters)
   477 			{
   538 			{
   478 	 		iConfigStatus = EOptionConfigOutstanding;
   539 	 		iConfigStatus = EOptionConfigOutstanding;
   479             // Only take the channel mode from peer's proposal and set informational
   540 	 		// Build a new request based on suggestion sent by the peer.
   480             // (i.e. all other) parameters to our values.
   541 	 		iFecNegotiator.ModeSpecificHandlers().BuildRequestBasedOnUnacceptableParamsResponse(
   481             BuildRequest(aFecOption.LinkMode(), iPreferred);
   542 	 				iPreferred, iPeer, iFecNegotiator);
   482 			}
   543 			}
   483 		else
   544 		else
   484 			{
   545 			{
   485 			iConfigStatus = EOptionConfigComplete;
   546 			iConfigStatus = EOptionConfigComplete;
   486 			}
   547 			}