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