--- a/bluetooth/btstack/l2cap/L2CapSDUQueue.cpp Thu Sep 23 17:06:47 2010 +0300
+++ b/bluetooth/btstack/l2cap/L2CapSDUQueue.cpp Wed Oct 13 16:20:29 2010 +0300
@@ -39,12 +39,13 @@
TUint16 aFlushTimeout,
TUint16 aMaxOutgoingMTU,
TUint16 aMaxIncomingMTU,
+ TUint16 aAclBufSize,
TBool aCanDropSdus)
{
LOG_STATIC_FUNC
CL2CapSDUQueue* self = new(ELeave) CL2CapSDUQueue(aL2CapSap, aOutboundQueueSize, aPDUSize, aFlushTimeout, aMaxOutgoingMTU, aMaxIncomingMTU, aCanDropSdus);
CleanupStack::PushL(self);
- self->ConstructL(aLocalCID, aRemoteCID, aMuxer, aConfig);
+ self->ConstructL(aLocalCID, aRemoteCID, aMuxer, aConfig, aAclBufSize);
return self;
}
@@ -58,15 +59,17 @@
TUint16 aFlushTimeout,
TUint16 aMaxOutgoingMTU,
TUint16 aMaxIncomingMTU,
+ TUint16 aAclBufSize,
TBool aCanDropSdus)
{
LOG_STATIC_FUNC
- CL2CapSDUQueue* self = NewLC(aL2CapSap, aLocalCID, aRemoteCID, aMuxer, aPDUSize, aOutboundQueueSize, aConfig, aFlushTimeout, aMaxOutgoingMTU, aMaxIncomingMTU, aCanDropSdus);
+ CL2CapSDUQueue* self = NewLC(aL2CapSap, aLocalCID, aRemoteCID, aMuxer, aPDUSize, aOutboundQueueSize, aConfig, aFlushTimeout,
+ aMaxOutgoingMTU, aMaxIncomingMTU, aAclBufSize, aCanDropSdus);
CleanupStack::Pop();
return self;
}
-void CL2CapSDUQueue::ConstructL(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, TL2CapDataControllerConfig* aConfig)
+void CL2CapSDUQueue::ConstructL(TL2CAPPort aLocalCID, TL2CAPPort aRemoteCID, CL2CAPMux& aMuxer, TL2CapDataControllerConfig* aConfig, TUint16 aAclBufSize)
{
LOG_FUNC
iDataController = CL2CapBasicDataController::NewL(aLocalCID, aRemoteCID, aMuxer, *this, aConfig);
@@ -77,6 +80,8 @@
iSDUSentAsyncCallBack = new (ELeave)CAsyncCallBack(sdusSentCB, EActiveLowPriority);
TCallBack qClosingCB(QueueClosingAsyncCallBack, this);
iQueueClosingCallBack = new (ELeave)CAsyncCallBack(qClosingCB, EActiveHighPriority);
+
+ iCurrentPDUSize = HL2CapPDU::GetPDUOrFragmentSize(iMaxOutgoingMTU, iMaximumPDUSize, aAclBufSize, iDataController->IsBasicDataVersion());
}
@@ -665,7 +670,8 @@
TUint16 aFlushTimeout,
TUint16 aPDUSize,
TUint16 aMaxOutgoingMTU,
- TUint16 aMaxIncomingMTU)
+ TUint16 aMaxIncomingMTU,
+ TUint16 aAclBufSize)
{
LOG_FUNC
// Update the data controller.
@@ -709,7 +715,7 @@
}
if (err == KErrNone)
{
- iCurrentPDUSize = iNegotiatedPDUSize;
+ iCurrentPDUSize = HL2CapPDU::GetPDUOrFragmentSize(iMaxOutgoingMTU, iMaximumPDUSize, aAclBufSize, iDataController->IsBasicDataVersion());
// Allow the outbound queue to send again, and tell the data
// plane if SDU's are available.
@@ -737,17 +743,56 @@
}
}
-TBool CL2CapSDUQueue::IsBasicDataVersion() const
+TUint CL2CapSDUQueue::GetOptimalMTUSizeL(TUint aMtuRestriction, TUint16 aAclBufSize)
{
LOG_FUNC
- TBool rValue = EFalse;
- if (iDataController)
+
+ if (!iDataController)
+ {
+ // Can happen if we're being shut down quickly due to an error and the upper layer
+ // still hasn't reacted to that.
+ LEAVEL(KErrNotReady);
+ }
+
+ // Ensure that the restriction is less then the current MTU.
+ if (aMtuRestriction < iMaxOutgoingMTU)
+ {
+ // We now need to recalculate the optimal PDU size for the restricted MTU as
+ // this is used in the calculation of the optimal MTU
+
+ iCurrentPDUSize = HL2CapPDU::GetPDUOrFragmentSize(aMtuRestriction, iMaximumPDUSize,
+ aAclBufSize, iDataController->IsBasicDataVersion());
+ }
+ else
{
- rValue = iDataController->IsBasicDataVersion();
+ // can't increase the MTU at this stage so just use the existing MTU
+ aMtuRestriction = iMaxOutgoingMTU;
}
- return rValue;
+
+ // If the negotiated MTU minus any overhead will fit into the optimal PDU then that
+ // is the optimal MTU. The overhead will differ for basic and non-basic mode, for basic mode
+ // we have to consider the SDU overhead as there is no fragment overhead and for non-basic we
+ // consider the PDU overhead only (the additional SDU overhead is taken account of later if
+ // more than one PDU is required for the optimal MTU).
+ TUint optimalMTU = aMtuRestriction;
+
+ // Calculate the size of the MTU + any overhead assuming that the MTU is not segmented
+ TUint singlePduSize = iDataController->IsBasicDataVersion() ?
+ (aMtuRestriction + CL2CapSDU::GetSDUOverhead(iDataController->IsBasicDataVersion())) : aMtuRestriction;
+
+ // If the unsegmented MTU + overhead can fit into the optimal PDU size then no
+ // further calculation is required
+ if(singlePduSize > iCurrentPDUSize)
+ {
+ // The MTU will need to be segmented / fragmented (depending on L2CAP mode).
+ // Calculate an MTU size that will be a factor of the PDU size.
+ optimalMTU = aMtuRestriction - ((aMtuRestriction + CL2CapSDU::GetSDUOverhead(iDataController->IsBasicDataVersion())) % iCurrentPDUSize);
+ }
+
+ return optimalMTU;
}
+
#ifdef _DEBUG
TInt CL2CapSDUQueue::GetDataPlaneConfig(TL2DataPlaneConfig& conf) const
{