* [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN
@ 2026-02-26 20:03 Luiz Augusto von Dentz
2026-02-26 20:03 ` [PATCH BlueZ v2 2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode Luiz Augusto von Dentz
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Luiz Augusto von Dentz @ 2026-02-26 20:03 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
The code has been silently dropping packets due to lack of buffer
since hciemu design is single threaded it cannot do partial writes
or flushes to force the buffer to be consumed and give space to the
next chunk, so in order to fix this the code will now attempt to
detect if a socket runs out of space and automatically bump the
buffer with use of SO_SNDBUF.
---
emulator/hciemu.c | 31 +++++++++++++++++++++++++++++--
1 file changed, 29 insertions(+), 2 deletions(-)
diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index 8c73a07eede0..01a8e80b727e 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -118,8 +118,35 @@ static void writev_callback(const struct iovec *iov, int iovlen,
fd = g_io_channel_unix_get_fd(channel);
written = writev(fd, iov, iovlen);
- if (written < 0)
- return;
+ if (written < 0) {
+ ssize_t ret;
+ int size, data_len;
+ socklen_t len = sizeof(size);
+ int i;
+
+ if (errno != EAGAIN)
+ return;
+
+ data_len = 0;
+
+ for (i = 0; i < iovlen; i++)
+ data_len += iov[i].iov_len;
+
+ /* Automatically bump the send buffer size if the data to be
+ * sent is larger than the current buffer size. This is needed
+ * for btdev which doesn't flush the socket buffer until all
+ * data has been sent.
+ */
+ ret = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, &len);
+ if (!ret) {
+ size += data_len;
+ setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &size, len);
+ }
+
+ written = writev(fd, iov, iovlen);
+ if (written < 0)
+ return;
+ }
}
static gboolean receive_bthost(GIOChannel *channel, GIOCondition condition,
--
2.52.0
^ permalink raw reply related [flat|nested] 4+ messages in thread* [PATCH BlueZ v2 2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode 2026-02-26 20:03 [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN Luiz Augusto von Dentz @ 2026-02-26 20:03 ` Luiz Augusto von Dentz 2026-02-26 21:05 ` [BlueZ,v2,1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN bluez.test.bot 2026-03-03 15:40 ` [PATCH BlueZ v2 1/2] " patchwork-bot+bluetooth 2 siblings, 0 replies; 4+ messages in thread From: Luiz Augusto von Dentz @ 2026-02-26 20:03 UTC (permalink / raw) To: linux-bluetooth From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> This fixes the following tests since the kernel now attempts to check if a segment length is bigger than the MPS: L2CAP LE Client - Read 32k Success - run Connect in progress Client connect CID 0x0040 handle 0x0001 Successfully connected to CID 0x0040 Bluetooth: Too big LE L2CAP MPS: len 672 > 188 L2CAP LE Client - RX Timestamping 32k - run Connect in progress Client connect CID 0x0040 handle 0x0001 Successfully connected to CID 0x0040 Bluetooth: Too big LE L2CAP MPS: len 672 > 188 --- emulator/bthost.c | 53 ++++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 12 deletions(-) diff --git a/emulator/bthost.c b/emulator/bthost.c index 53b12f828675..b913c8015416 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -22,6 +22,7 @@ #include <endian.h> #include <errno.h> #include <stdbool.h> +#include <sys/param.h> #include "bluetooth/bluetooth.h" @@ -185,6 +186,8 @@ struct l2conn { uint16_t scid; uint16_t dcid; uint16_t psm; + uint16_t rx_mps; + uint16_t tx_mps; uint16_t rx_credits; uint16_t tx_credits; enum l2cap_mode mode; @@ -748,14 +751,14 @@ static void send_iov(struct bthost *bthost, uint16_t handle, uint16_t cid, } static void send_acl(struct bthost *bthost, uint16_t handle, uint16_t cid, - bool sdu_hdr, const void *data, uint16_t len) + uint16_t sdu_len, const void *data, uint16_t len) { struct iovec iov[2]; uint16_t sdu; int num = 0; - if (sdu_hdr) { - sdu = cpu_to_le16(len); + if (sdu_len) { + sdu = cpu_to_le16(sdu_len); iov[num].iov_base = &sdu; iov[num].iov_len = sizeof(sdu); num++; @@ -885,18 +888,42 @@ void bthost_send_cid(struct bthost *bthost, uint16_t handle, uint16_t cid, { struct btconn *conn; struct l2conn *l2conn; - bool sdu_hdr = false; + struct iovec iov = { + .iov_base = (void *) data, + .iov_len = len, + }; conn = bthost_find_conn(bthost, handle); if (!conn) return; l2conn = btconn_find_l2cap_conn_by_dcid(conn, cid); - if (l2conn && (l2conn->mode == L2CAP_MODE_LE_CRED || - l2conn->mode == L2CAP_MODE_LE_ENH_CRED)) - sdu_hdr = true; - send_acl(bthost, handle, cid, sdu_hdr, data, len); + /* Segment SDU in case of LE (Enhanced) Credit Based Flow Control */ + if (l2conn && (l2conn->mode == L2CAP_MODE_LE_CRED || + l2conn->mode == L2CAP_MODE_LE_ENH_CRED)) { + uint16_t sdu_len = len; + uint16_t slen; + int i; + + for (i = 0; iov.iov_len; i++) { + if (sdu_len) + slen = MIN(iov.iov_len, + l2conn->tx_mps - sizeof(sdu_len)); + else + slen = MIN(iov.iov_len, l2conn->tx_mps); + + send_acl(bthost, handle, cid, sdu_len, + util_iov_pull_mem(&iov, slen), slen); + + if (sdu_len) + sdu_len = 0; + } + + return; + } + + send_acl(bthost, handle, cid, 0, data, len); } void bthost_send_cid_v(struct bthost *bthost, uint16_t handle, uint16_t cid, @@ -2104,7 +2131,7 @@ static void rfcomm_sabm_send(struct bthost *bthost, struct btconn *conn, cmd.length = RFCOMM_LEN8(0); cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd); - send_acl(bthost, conn->handle, l2conn->dcid, false, &cmd, sizeof(cmd)); + send_acl(bthost, conn->handle, l2conn->dcid, 0, &cmd, sizeof(cmd)); } static bool l2cap_conn_rsp(struct bthost *bthost, struct btconn *conn, @@ -2501,6 +2528,8 @@ static bool l2cap_le_conn_req(struct bthost *bthost, struct btconn *conn, le16_to_cpu(req->scid), le16_to_cpu(psm)); l2conn->mode = L2CAP_MODE_LE_CRED; + l2conn->rx_mps = le16_to_cpu(rsp.mps); + l2conn->tx_mps = le16_to_cpu(req->mps); l2conn->rx_credits = le16_to_cpu(rsp.credits); l2conn->tx_credits = le16_to_cpu(req->credits); @@ -2749,7 +2778,7 @@ static void rfcomm_ua_send(struct bthost *bthost, struct btconn *conn, cmd.length = RFCOMM_LEN8(0); cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd); - send_acl(bthost, conn->handle, l2conn->dcid, false, &cmd, sizeof(cmd)); + send_acl(bthost, conn->handle, l2conn->dcid, 0, &cmd, sizeof(cmd)); } static void rfcomm_dm_send(struct bthost *bthost, struct btconn *conn, @@ -2763,7 +2792,7 @@ static void rfcomm_dm_send(struct bthost *bthost, struct btconn *conn, cmd.length = RFCOMM_LEN8(0); cmd.fcs = rfcomm_fcs2((uint8_t *)&cmd); - send_acl(bthost, conn->handle, l2conn->dcid, false, &cmd, sizeof(cmd)); + send_acl(bthost, conn->handle, l2conn->dcid, 0, &cmd, sizeof(cmd)); } static void rfcomm_sabm_recv(struct bthost *bthost, struct btconn *conn, @@ -4199,7 +4228,7 @@ void bthost_send_rfcomm_data(struct bthost *bthost, uint16_t handle, } uih_frame[uih_len - 1] = rfcomm_fcs((void *)hdr); - send_acl(bthost, handle, rcconn->scid, false, uih_frame, uih_len); + send_acl(bthost, handle, rcconn->scid, 0, uih_frame, uih_len); free(uih_frame); } -- 2.52.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [BlueZ,v2,1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN 2026-02-26 20:03 [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN Luiz Augusto von Dentz 2026-02-26 20:03 ` [PATCH BlueZ v2 2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode Luiz Augusto von Dentz @ 2026-02-26 21:05 ` bluez.test.bot 2026-03-03 15:40 ` [PATCH BlueZ v2 1/2] " patchwork-bot+bluetooth 2 siblings, 0 replies; 4+ messages in thread From: bluez.test.bot @ 2026-02-26 21:05 UTC (permalink / raw) To: linux-bluetooth, luiz.dentz [-- Attachment #1: Type: text/plain, Size: 1688 bytes --] This is automated email and please do not reply to this email! Dear submitter, Thank you for submitting the patches to the linux bluetooth mailing list. This is a CI test results with your patch series: PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1058640 ---Test result--- Test Summary: CheckPatch PENDING 0.46 seconds GitLint PENDING 0.42 seconds BuildEll PASS 17.98 seconds BluezMake PASS 647.73 seconds MakeCheck PASS 17.72 seconds MakeDistcheck PASS 221.94 seconds CheckValgrind PASS 281.29 seconds CheckSmatch WARNING 317.69 seconds bluezmakeextell PASS 167.42 seconds IncrementalBuild PENDING 0.31 seconds ScanBuild PASS 934.35 seconds Details ############################## Test: CheckPatch - PENDING Desc: Run checkpatch.pl script Output: ############################## Test: GitLint - PENDING Desc: Run gitlint Output: ############################## Test: CheckSmatch - WARNING Desc: Run smatch tool with source Output: emulator/bthost.c:703:28: warning: Variable length array is used.emulator/bthost.c:704:32: warning: Variable length array is used.emulator/bthost.c:945:28: warning: Variable length array is used.emulator/bthost.c:979:28: warning: Variable length array is used.emulator/bthost.c:980:32: warning: Variable length array is used. ############################## Test: IncrementalBuild - PENDING Desc: Incremental build with the patches in the series Output: --- Regards, Linux Bluetooth ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN 2026-02-26 20:03 [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN Luiz Augusto von Dentz 2026-02-26 20:03 ` [PATCH BlueZ v2 2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode Luiz Augusto von Dentz 2026-02-26 21:05 ` [BlueZ,v2,1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN bluez.test.bot @ 2026-03-03 15:40 ` patchwork-bot+bluetooth 2 siblings, 0 replies; 4+ messages in thread From: patchwork-bot+bluetooth @ 2026-03-03 15:40 UTC (permalink / raw) To: Luiz Augusto von Dentz; +Cc: linux-bluetooth Hello: This series was applied to bluetooth/bluez.git (master) by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>: On Thu, 26 Feb 2026 15:03:29 -0500 you wrote: > From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> > > The code has been silently dropping packets due to lack of buffer > since hciemu design is single threaded it cannot do partial writes > or flushes to force the buffer to be consumed and give space to the > next chunk, so in order to fix this the code will now attempt to > detect if a socket runs out of space and automatically bump the > buffer with use of SO_SNDBUF. > > [...] Here is the summary with links: - [BlueZ,v2,1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=744fad3c342e - [BlueZ,v2,2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=b138a0849ba2 You are awesome, thank you! -- Deet-doot-dot, I am a bot. https://korg.docs.kernel.org/patchwork/pwbot.html ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-03 15:40 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-26 20:03 [PATCH BlueZ v2 1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN Luiz Augusto von Dentz 2026-02-26 20:03 ` [PATCH BlueZ v2 2/2] bthost: Add segmentation support for L2CAP LE-(E)CRED mode Luiz Augusto von Dentz 2026-02-26 21:05 ` [BlueZ,v2,1/2] hciemu: Fix silently dropping packet if writev return -EAGAIN bluez.test.bot 2026-03-03 15:40 ` [PATCH BlueZ v2 1/2] " patchwork-bot+bluetooth
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox