bluetooth/btstack/l2cap/l2sap.cpp
changeset 51 20ac952a623c
parent 34 9d84592f5036
equal deleted inserted replaced
48:22de2e391156 51:20ac952a623c
   342 	LOG_FUNC
   342 	LOG_FUNC
   343 	iRemoteDev = aAddr;
   343 	iRemoteDev = aAddr;
   344 	LOGBTDEVADDR(iRemoteDev);
   344 	LOGBTDEVADDR(iRemoteDev);
   345 	}
   345 	}
   346 
   346 
   347 TUint CL2CAPConnectionSAP::GetOptimalMTUSize(TUint aMTU, TUint aPduSize, TBool aBasicMode) const
       
   348 	{
       
   349 	LOG_FUNC
       
   350 
       
   351 	// If the negotiated MTU minus any overhead will fit into the optimal PDU then that
       
   352 	// is the optimal MTU. The overhead will differ for basic and non-basic mode, for basic mode
       
   353 	// we have to consider the SDU overhead as there is no fragment overhead and for non-basic we 
       
   354 	// consider the PDU overhead only (the additional SDU overhead is taken account of later if 
       
   355 	// more than one PDU is required for the optimal MTU).
       
   356 	TUint optimalMTU = aMTU;
       
   357 
       
   358 	// Calculate the size of the MTU + any overhead assuming that the MTU is not segmented
       
   359 	TUint singlePduSize = aBasicMode ? (aMTU + CL2CapSDU::GetSDUOverhead(aBasicMode)) : aMTU;
       
   360 
       
   361 	// If the unsegmented MTU + overhead can fit into the optimal PDU size then no 
       
   362 	// further calculation is required
       
   363 	if(singlePduSize > aPduSize)
       
   364 		{
       
   365 		// The MTU will need to be segmented / fragmented (depending on L2CAP mode).
       
   366 		// Calculate an MTU size that will be a factor of the PDU size.
       
   367 		optimalMTU = aMTU - ((aMTU + CL2CapSDU::GetSDUOverhead(aBasicMode)) % aPduSize); 
       
   368 		}
       
   369 
       
   370 	return optimalMTU;
       
   371 	}
       
   372 
       
   373 TInt CL2CAPConnectionSAP::SAPSetOption(TUint aLevel, TUint aName, const TDesC8& aOption)
   347 TInt CL2CAPConnectionSAP::SAPSetOption(TUint aLevel, TUint aName, const TDesC8& aOption)
   374 	{
   348 	{
   375 	LOG_FUNC
   349 	LOG_FUNC
   376 	// Perform a setopt
   350 	// Perform a setopt
   377 
   351 
   501 				}
   475 				}
   502 			break;	
   476 			break;	
   503 
   477 
   504 		case KL2CAPOutboundMTUForBestPerformanceWithRestriction:
   478 		case KL2CAPOutboundMTUForBestPerformanceWithRestriction:
   505 			// get the restriction value
   479 			// get the restriction value
   506 			if((aOption.Length() == sizeof(TInt)) && iL2CapDataQueue && iL2CapSAPSignalHandler)
   480 			if(aOption.Length() == sizeof(TInt))
   507 				{
   481 				{
   508 				val = *reinterpret_cast<const TInt*>(aOption.Ptr());
   482 				if(iL2CapSAPSignalHandler && iL2CapDataQueue)
   509 
   483 					{
   510 				// Ensure that the restriction is less then the current MTU.
   484 					val = *reinterpret_cast<const TInt*>(aOption.Ptr());
   511 				if (val < iL2CapDataQueue->MaxOutgoingMTU())
   485 
   512 					{
   486 					TPckgBuf<TInt> aclBufSize;	
   513 					// We now need to recalculate the optimal PDU size for the restricted MTU as
   487 					TInt getAclBufSizeErr = iL2CapSAPSignalHandler->GetOption(KSolBtACL, ELMOutboundACLSize, aclBufSize);
   514 					// this is used in the calculation of the optimal MTU
   488 
   515 					TPckgBuf<TInt> buf;	
   489 					TRAP(rValue, val = iL2CapDataQueue->GetOptimalMTUSizeL(val, (getAclBufSizeErr == KErrNone) ? aclBufSize() : 0));
   516 					TInt err = iL2CapSAPSignalHandler->GetOption(KSolBtACL, ELMOutboundACLSize, buf);
   490 					aOption = TPtrC8(reinterpret_cast<TUint8*>(&val), sizeof(TInt));
   517 
       
   518 					TInt optimalPduSize = HL2CapPDU::GetPDUOrFragmentSize(val, iL2CapDataQueue->MaximumPDUSize(), (err == KErrNone) ? buf() : 0, iL2CapDataQueue->IsBasicDataVersion());
       
   519 
       
   520 					// update the data queue to use the new optimal PDU size from now on
       
   521 					iL2CapDataQueue->SetOptimalPDUSize(optimalPduSize);
       
   522 					}
   491 					}
   523 				else
   492 				else
   524 					{
   493 					{
   525 					// can't increase the MTU at this stage so just use the existing MTU
   494 					rValue = KErrNotReady;
   526 					val = iL2CapDataQueue->MaxOutgoingMTU();
   495 					}
   527 					}
   496 				}
   528 
   497 			else
   529 				// work out the optimal MTU
   498 				{
   530 				val = GetOptimalMTUSize(val, iL2CapDataQueue->OptimalPDUSize(), iL2CapDataQueue->IsBasicDataVersion());
   499 				rValue = KErrArgument;
   531 				aOption = TPtrC8(reinterpret_cast<TUint8*>(&val), sizeof(TInt));
   500 				}
   532 				}			
       
   533 			break;
   501 			break;
   534 
   502 
   535 		case KL2CAPOutboundMTUForBestPerformance: //equals KL2CAPGetOutboundMTU
   503 		case KL2CAPOutboundMTUForBestPerformance: //equals KL2CAPGetOutboundMTU
   536 			if(aOption.Length() == sizeof(TInt))
   504 			if(aOption.Length() == sizeof(TInt))
   537 				{
   505 				{
   538 				if(iL2CapDataQueue && iL2CapSAPSignalHandler)
   506 				if(iL2CapDataQueue)
   539 					{
   507 					{
   540 					// work out the optimal MTU
   508 					TRAP(rValue, val = iL2CapDataQueue->GetOptimalMTUSizeL());
   541 					val = GetOptimalMTUSize(iL2CapDataQueue->MaxOutgoingMTU(), iL2CapDataQueue->OptimalPDUSize(), iL2CapDataQueue->IsBasicDataVersion());
       
   542 					aOption = TPtrC8(reinterpret_cast<TUint8*>(&val), sizeof(TInt));
   509 					aOption = TPtrC8(reinterpret_cast<TUint8*>(&val), sizeof(TInt));
   543 					}
   510 					}
   544 				else
   511 				else
   545 					{
   512 					{
   546 					rValue = KErrNotReady;
   513 					rValue = KErrNotReady;
  1087 		// if UpdateChannelConfig was called before iL2CapDataQueue was created we update the priority now
  1054 		// if UpdateChannelConfig was called before iL2CapDataQueue was created we update the priority now
  1088 		if (iChannelPriority != 0)
  1055 		if (iChannelPriority != 0)
  1089 			{
  1056 			{
  1090 			dataConfig->SetChannelPriority(iChannelPriority);
  1057 			dataConfig->SetChannelPriority(iChannelPriority);
  1091 			}
  1058 			}
       
  1059 
       
  1060 		TPckgBuf<TInt> aclBufSize; 
       
  1061 		TInt getAclBufSizeErr = iL2CapSAPSignalHandler->GetOption(KSolBtACL, ELMOutboundACLSize, aclBufSize);
       
  1062 
  1092 		TRAP(rerr, iL2CapDataQueue = CL2CapSDUQueue::NewL(*this,
  1063 		TRAP(rerr, iL2CapDataQueue = CL2CapSDUQueue::NewL(*this,
  1093 		                                                  aLocalPort,
  1064 		                                                  aLocalPort,
  1094 		                                                  aRemotePort,
  1065 		                                                  aRemotePort,
  1095 		                                                  aMuxer,
  1066 		                                                  aMuxer,
  1096 					                       				  fec.OutgoingMaximumPDUSize(),
  1067 					                       				  fec.OutgoingMaximumPDUSize(),
  1097 		                                                  CL2CapSDUQueue::KDefaultOutboundQueueSize,
  1068 		                                                  CL2CapSDUQueue::KDefaultOutboundQueueSize,
  1098 		                       			            	  dataConfig,
  1069 		                       			            	  dataConfig,
  1099 											   			  aConfig.OutgoingFlushTimeout().Negotiated().FlushTimeoutDuration(),
  1070 											   			  aConfig.OutgoingFlushTimeout().Negotiated().FlushTimeoutDuration(),
  1100 					                       				  aConfig.OutgoingMTU().Negotiated().MTU(),
  1071 					                       				  aConfig.OutgoingMTU().Negotiated().MTU(),
  1101 					                       				  aConfig.IncomingMTU().Negotiated().MTU(),
  1072 					                       				  aConfig.IncomingMTU().Negotiated().MTU(),
       
  1073 					                       				  (getAclBufSizeErr == KErrNone) ? aclBufSize() : 0,
  1102 					                       				  // Allow ourselves to drop SDUs we can't assemble if channel mode is not Reliable.
  1074 					                       				  // Allow ourselves to drop SDUs we can't assemble if channel mode is not Reliable.
  1103 					                       				  !TRetransmissionAndFlowControlOption::IsModeReliable(fec.IncomingLinkMode())));
  1075 					                       				  !TRetransmissionAndFlowControlOption::IsModeReliable(fec.IncomingLinkMode())));
  1104 
       
  1105 		// Set the optimal PDU size that the data controller should use.
       
  1106 		TPckgBuf<TInt> buf;	
       
  1107 		TInt err = iL2CapSAPSignalHandler->GetOption(KSolBtACL, ELMOutboundACLSize, buf);
       
  1108 
       
  1109 		TInt optimalPduSize = HL2CapPDU::GetPDUOrFragmentSize(iL2CapDataQueue->MaxOutgoingMTU(), iL2CapDataQueue->MaximumPDUSize(), (err == KErrNone) ? buf() : 0, iL2CapDataQueue->IsBasicDataVersion());
       
  1110 		iL2CapDataQueue->SetOptimalPDUSize(optimalPduSize);
       
  1111 		}
  1076 		}
  1112 	else
  1077 	else
  1113 		{
  1078 		{
  1114 		rerr = KErrNoMemory;
  1079 		rerr = KErrNoMemory;
  1115 		}
  1080 		}