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 } |