public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [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