Hi Pauli, On Fri, Jul 11, 2025 at 9:53 AM Pauli Virtanen <pav@xxxxxx> wrote: > > Hi, > > to, 2025-06-12 kello 09:50 +0200, Frédéric Danis kirjoitti: > > OBEX download from iPhone is currently slow due to small packet size > > used to transfer data which doesn't follow the MTU negotiated during > > L2CAP connection, i.e. 672 bytes instead of 32767: > > There are some reports that appear to indicate this commit causes > regressions for A2DP: > > https://gitlab.archlinux.org/archlinux/packaging/packages/linux/-/issues/149#note_285698 > > https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/4793#note_3001287 Might be a good idea to create a github issue for it, doesn't seem like the above issues had collected any btmon traces yet, perhaps the MTU is not updated or left to 0? Anyway we may want to add a test in l2cap-tester to try to reproduce the same scenario. > > > > > < ACL Data TX: Handle 11 flags 0x00 dlen 12 > > L2CAP: Connection Request (0x02) ident 18 len 4 > > PSM: 4103 (0x1007) > > Source CID: 72 > > > ACL Data RX: Handle 11 flags 0x02 dlen 16 > > L2CAP: Connection Response (0x03) ident 18 len 8 > > Destination CID: 14608 > > Source CID: 72 > > Result: Connection successful (0x0000) > > Status: No further information available (0x0000) > > < ACL Data TX: Handle 11 flags 0x00 dlen 27 > > L2CAP: Configure Request (0x04) ident 20 len 19 > > Destination CID: 14608 > > Flags: 0x0000 > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 32767 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 63 > > Max transmit: 3 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > > ACL Data RX: Handle 11 flags 0x02 dlen 26 > > L2CAP: Configure Request (0x04) ident 72 len 18 > > Destination CID: 72 > > Flags: 0x0000 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 32 > > Max transmit: 255 > > Retransmission timeout: 0 > > Monitor timeout: 0 > > Maximum PDU size: 65527 > > Option: Frame Check Sequence (0x05) [mandatory] > > FCS: 16-bit FCS (0x01) > > < ACL Data TX: Handle 11 flags 0x00 dlen 29 > > L2CAP: Configure Response (0x05) ident 72 len 21 > > Source CID: 14608 > > Flags: 0x0000 > > Result: Success (0x0000) > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 672 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 32 > > Max transmit: 255 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > > ACL Data RX: Handle 11 flags 0x02 dlen 32 > > L2CAP: Configure Response (0x05) ident 20 len 24 > > Source CID: 72 > > Flags: 0x0000 > > Result: Success (0x0000) > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 32767 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 63 > > Max transmit: 3 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > Option: Frame Check Sequence (0x05) [mandatory] > > FCS: 16-bit FCS (0x01) > > ... > > > ACL Data RX: Handle 11 flags 0x02 dlen 680 > > Channel: 72 len 676 ctrl 0x0202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} > > I-frame: Unsegmented TxSeq 1 ReqSeq 2 > > < ACL Data TX: Handle 11 flags 0x00 dlen 13 > > Channel: 14608 len 9 ctrl 0x0204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} > > I-frame: Unsegmented TxSeq 2 ReqSeq 2 > > > ACL Data RX: Handle 11 flags 0x02 dlen 680 > > Channel: 72 len 676 ctrl 0x0304 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} > > I-frame: Unsegmented TxSeq 2 ReqSeq 3 > > > > The MTUs are negotiated for each direction. In this traces 32767 for > > iPhone->localhost and no MTU for localhost->iPhone, which based on > > '4.4 L2CAP_CONFIGURATION_REQ' (Core specification v5.4, Vol. 3, Part > > A): > > > > The only parameters that should be included in the > > L2CAP_CONFIGURATION_REQ packet are those that require different > > values than the default or previously agreed values. > > ... > > Any missing configuration parameters are assumed to have their > > most recently explicitly or implicitly accepted values. > > > > and '5.1 Maximum transmission unit (MTU)': > > > > If the remote device sends a positive L2CAP_CONFIGURATION_RSP > > packet it should include the actual MTU to be used on this channel > > for traffic flowing into the local device. > > ... > > The default value is 672 octets. > > > > is set by BlueZ to 672 bytes. > > > > It seems that the iPhone used the lowest negotiated value to transfer > > data to the localhost instead of the negotiated one for the incoming > > direction. > > > > This could be fixed by using the MTU negotiated for the other > > direction, if exists, in the L2CAP_CONFIGURATION_RSP. > > This allows to use segmented packets as in the following traces: > > > > < ACL Data TX: Handle 11 flags 0x00 dlen 12 > > L2CAP: Connection Request (0x02) ident 22 len 4 > > PSM: 4103 (0x1007) > > Source CID: 72 > > < ACL Data TX: Handle 11 flags 0x00 dlen 27 > > L2CAP: Configure Request (0x04) ident 24 len 19 > > Destination CID: 2832 > > Flags: 0x0000 > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 32767 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 63 > > Max transmit: 3 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > > ACL Data RX: Handle 11 flags 0x02 dlen 26 > > L2CAP: Configure Request (0x04) ident 15 len 18 > > Destination CID: 72 > > Flags: 0x0000 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 32 > > Max transmit: 255 > > Retransmission timeout: 0 > > Monitor timeout: 0 > > Maximum PDU size: 65527 > > Option: Frame Check Sequence (0x05) [mandatory] > > FCS: 16-bit FCS (0x01) > > < ACL Data TX: Handle 11 flags 0x00 dlen 29 > > L2CAP: Configure Response (0x05) ident 15 len 21 > > Source CID: 2832 > > Flags: 0x0000 > > Result: Success (0x0000) > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 32767 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 32 > > Max transmit: 255 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > > ACL Data RX: Handle 11 flags 0x02 dlen 32 > > L2CAP: Configure Response (0x05) ident 24 len 24 > > Source CID: 72 > > Flags: 0x0000 > > Result: Success (0x0000) > > Option: Maximum Transmission Unit (0x01) [mandatory] > > MTU: 32767 > > Option: Retransmission and Flow Control (0x04) [mandatory] > > Mode: Enhanced Retransmission (0x03) > > TX window size: 63 > > Max transmit: 3 > > Retransmission timeout: 2000 > > Monitor timeout: 12000 > > Maximum PDU size: 1009 > > Option: Frame Check Sequence (0x05) [mandatory] > > FCS: 16-bit FCS (0x01) > > ... > > > ACL Data RX: Handle 11 flags 0x02 dlen 1009 > > Channel: 72 len 1005 ctrl 0x4202 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} > > I-frame: Start (len 21884) TxSeq 1 ReqSeq 2 > > > ACL Data RX: Handle 11 flags 0x02 dlen 1009 > > Channel: 72 len 1005 ctrl 0xc204 [PSM 4103 mode Enhanced Retransmission (0x03)] {chan 8} > > I-frame: Continuation TxSeq 2 ReqSeq 2 > > > > This has been tested with kernel 5.4 and BlueZ 5.77. > > > > Signed-off-by: Frédéric Danis <frederic.danis@xxxxxxxxxxxxx> > > --- > > net/bluetooth/l2cap_core.c | 9 ++++++++- > > 1 file changed, 8 insertions(+), 1 deletion(-) > > > > diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c > > index a5bde5db58ef..40daa38276f3 100644 > > --- a/net/bluetooth/l2cap_core.c > > +++ b/net/bluetooth/l2cap_core.c > > @@ -3415,7 +3415,7 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data > > struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC }; > > struct l2cap_conf_efs efs; > > u8 remote_efs = 0; > > - u16 mtu = L2CAP_DEFAULT_MTU; > > + u16 mtu = 0; > > u16 result = L2CAP_CONF_SUCCESS; > > u16 size; > > > > @@ -3520,6 +3520,13 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data > > /* Configure output options and let the other side know > > * which ones we don't like. */ > > > > + /* If MTU is not provided in configure request, use the most recently > > + * explicitly or implicitly accepted value for the other direction, > > + * or the default value. > > + */ > > + if (mtu == 0) > > + mtu = chan->imtu ? chan->imtu : L2CAP_DEFAULT_MTU; > > + > > if (mtu < L2CAP_DEFAULT_MIN_MTU) > > result = L2CAP_CONF_UNACCEPT; > > else { > > -- > Pauli Virtanen -- Luiz Augusto von Dentz