Skip to content

Commit bfd42f5

Browse files
lylezhu2012MaureenHelm
authored andcommitted
Bluetooth: GOEP: Improve the MTU configuration
The MTU of the GOEP should be not less than 255. So, if the transport is RFCOMM, the CONFIG_BT_BUF_ACL_RX_SIZE should be not less than 264. It includes, - 255 bytes for the minimum MTU of GOEP, - 4 bytes for L2CAP Header, - 5 bytes for RFCOMM header and FCS. And if the transport is L2CAP, the CONFIG_BT_BUF_ACL_RX_SIZE should be not less than 259. It includes, - 255 bytes for the minimum MTU of GOEP, - 4 bytes for L2CAP Header. Add Kconfig `BT_GOEP_RFCOMM_MTU` to configure the maximum size for RFCOMM transport. The range of `BT_GOEP_RFCOMM_MTU` is `[264, BT_RFCOMM_L2CAP_MTU]`. And the GOEP MTU via RFCOMM transport should be in the range `[255, (BT_GOEP_RFCOMM_MTU-9)]`. Add Kconfig `BT_GOEP_L2CAP_MTU` to configure the maximum size for L2CAP transport. The range of `BT_GOEP_L2CAP_MTU` is `[259, BT_BUF_ACL_RX_SIZE]`. And the GOEP MTU via L2CAP transport should be in the range `[255, (BT_GOEP_L2CAP_MTU-4)]`. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 3d91b89 commit bfd42f5

File tree

3 files changed

+126
-12
lines changed

3 files changed

+126
-12
lines changed

subsys/bluetooth/common/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,17 @@ config BT_BUF_ACL_TX_COUNT
5050

5151
config BT_BUF_ACL_RX_SIZE
5252
int "Maximum supported ACL size for incoming data"
53+
# For GOEP over RFCOMM, including,
54+
# 255 bytes - the minimum MTU of GOEP,
55+
# 4 bytes - L2CAP Header,
56+
# 5 bytes - 4 bytes for RFCOMM header with extended length, 1 byte for FCS.
57+
default 264 if BT_CLASSIC && BT_GOEP
5358
default 200 if BT_CLASSIC
5459
default 70 if BT_EATT
5560
default 69 if BT_SMP
5661
default 37 if BT_MESH_GATT
5762
default 27
63+
range 264 $(UINT16_MAX) if BT_CLASSIC && BT_GOEP
5864
range 70 $(UINT16_MAX) if BT_EATT
5965
range 69 $(UINT16_MAX) if BT_SMP
6066
range 27 $(UINT16_MAX)

subsys/bluetooth/host/classic/Kconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,31 @@ config BT_GOEP
523523
This option enables the GOEP profile
524524

525525
if BT_GOEP
526+
config BT_GOEP_RFCOMM_MTU
527+
int "RFCOMM MTU for GOEP"
528+
default BT_RFCOMM_L2CAP_MTU
529+
# For GOEP over RFCOMM, including,
530+
# 255 bytes - the minimum MTU of GOEP,
531+
# 4 bytes - L2CAP Header,
532+
# 5 bytes - 4 bytes for RFCOMM header with extended length, 1 byte for FCS.
533+
range 264 BT_RFCOMM_L2CAP_MTU
534+
help
535+
Maximum size of RFCOMM MTU for GOEP.
536+
RX MTU will be truncated to account for ACL data and type overhead, the L2CAP PDU header,
537+
and the RFCOMM header.
538+
539+
config BT_GOEP_L2CAP_MTU
540+
int "L2CAP MTU for GOEP"
541+
default BT_BUF_ACL_RX_SIZE
542+
# For GOEP over L2CAP, including,
543+
# 255 bytes - the minimum MTU of GOEP,
544+
# 4 bytes - L2CAP Header,
545+
range 259 BT_BUF_ACL_RX_SIZE
546+
help
547+
Maximum size of L2CAP MTU for GOEP.
548+
RX MTU will be truncated to account for ACL data and type overhead, and the L2CAP PDU
549+
header.
550+
526551
config BT_OEBX_RSP_CODE_TO_STR
527552
bool "Print OBEX response code as strings"
528553
help

subsys/bluetooth/host/classic/goep.c

Lines changed: 95 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#include "host/conn_internal.h"
2626
#include "l2cap_br_internal.h"
27+
#include "rfcomm_internal.h"
2728
#include "obex_internal.h"
2829

2930
#define LOG_LEVEL CONFIG_BT_GOEP_LOG_LEVEL
@@ -168,6 +169,8 @@ static int goep_rfcomm_accept(struct bt_conn *conn, struct bt_rfcomm_server *ser
168169
{
169170
struct bt_goep_transport_rfcomm_server *rfcomm_server;
170171
struct bt_goep *goep;
172+
uint32_t mtu;
173+
uint32_t hdr_size;
171174
int err;
172175

173176
rfcomm_server = CONTAINER_OF(server, struct bt_goep_transport_rfcomm_server, rfcomm);
@@ -183,13 +186,32 @@ static int goep_rfcomm_accept(struct bt_conn *conn, struct bt_rfcomm_server *ser
183186
return err;
184187
}
185188

186-
if (!goep || !goep->transport_ops || (goep->obex.rx.mtu < GOEP_MIN_MTU) ||
187-
!goep->obex.server_ops || !goep->obex.server_ops->connect ||
188-
!goep->obex.server_ops->disconnect) {
189+
if (!goep || !goep->transport_ops || !goep->obex.server_ops ||
190+
!goep->obex.server_ops->connect || !goep->obex.server_ops->disconnect) {
189191
LOG_DBG("Invalid parameter");
190192
return -EINVAL;
191193
}
192194

195+
hdr_size = sizeof(struct bt_l2cap_hdr);
196+
hdr_size += BT_RFCOMM_HDR_SIZE + BT_RFCOMM_FCS_SIZE;
197+
198+
mtu = CONFIG_BT_GOEP_RFCOMM_MTU - hdr_size;
199+
/* Use default MTU if it is not given */
200+
if (!goep->obex.rx.mtu) {
201+
goep->obex.rx.mtu = mtu;
202+
}
203+
204+
if (goep->obex.rx.mtu < GOEP_MIN_MTU) {
205+
LOG_WRN("GOEP RFCOMM MTU less than minimum size (%d < %d)", goep->obex.rx.mtu,
206+
GOEP_MIN_MTU);
207+
goep->obex.rx.mtu = GOEP_MIN_MTU;
208+
}
209+
210+
if (goep->obex.rx.mtu > mtu) {
211+
LOG_WRN("GOEP RFCOMM MTU exceeds maximum size (%d > %d)", goep->obex.rx.mtu, mtu);
212+
goep->obex.rx.mtu = mtu;
213+
}
214+
193215
err = bt_obex_reg_transport(&goep->obex, &goep_rfcomm_transport_ops);
194216
if (err) {
195217
LOG_WRN("Fail to reg transport ops");
@@ -238,14 +260,35 @@ int bt_goep_transport_rfcomm_server_register(struct bt_goep_transport_rfcomm_ser
238260
int bt_goep_transport_rfcomm_connect(struct bt_conn *conn, struct bt_goep *goep, uint8_t channel)
239261
{
240262
int err;
263+
uint32_t mtu;
264+
uint32_t hdr_size;
241265

242-
if (!conn || !goep || !goep->transport_ops || (goep->obex.rx.mtu < GOEP_MIN_MTU) ||
243-
!goep->obex.client_ops || !goep->obex.client_ops->connect ||
244-
!goep->obex.client_ops->disconnect) {
266+
if (!conn || !goep || !goep->transport_ops || !goep->obex.client_ops ||
267+
!goep->obex.client_ops->connect || !goep->obex.client_ops->disconnect) {
245268
LOG_DBG("Invalid parameter");
246269
return -EINVAL;
247270
}
248271

272+
hdr_size = sizeof(struct bt_l2cap_hdr);
273+
hdr_size += BT_RFCOMM_HDR_SIZE + BT_RFCOMM_FCS_SIZE;
274+
275+
mtu = CONFIG_BT_GOEP_RFCOMM_MTU - hdr_size;
276+
/* Use default MTU if it is not given */
277+
if (!goep->obex.rx.mtu) {
278+
goep->obex.rx.mtu = mtu;
279+
}
280+
281+
if (goep->obex.rx.mtu < GOEP_MIN_MTU) {
282+
LOG_WRN("GOEP RFCOMM MTU less than minimum size (%d < %d)", goep->obex.rx.mtu,
283+
GOEP_MIN_MTU);
284+
goep->obex.rx.mtu = GOEP_MIN_MTU;
285+
}
286+
287+
if (goep->obex.rx.mtu > mtu) {
288+
LOG_WRN("GOEP RFCOMM MTU exceeds maximum size (%d > %d)", goep->obex.rx.mtu, mtu);
289+
goep->obex.rx.mtu = mtu;
290+
}
291+
249292
err = bt_obex_reg_transport(&goep->obex, &goep_rfcomm_transport_ops);
250293
if (err) {
251294
LOG_WRN("Fail to reg transport ops");
@@ -425,6 +468,8 @@ static int goep_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *serve
425468
{
426469
struct bt_goep_transport_l2cap_server *l2cap_server;
427470
struct bt_goep *goep;
471+
uint32_t mtu;
472+
uint32_t hdr_size;
428473
int err;
429474

430475
l2cap_server = CONTAINER_OF(server, struct bt_goep_transport_l2cap_server, l2cap);
@@ -440,13 +485,31 @@ static int goep_l2cap_accept(struct bt_conn *conn, struct bt_l2cap_server *serve
440485
return err;
441486
}
442487

443-
if (!goep || !goep->transport_ops || (goep->obex.rx.mtu < GOEP_MIN_MTU) ||
444-
!goep->obex.server_ops || !goep->obex.server_ops->connect ||
445-
!goep->obex.server_ops->disconnect) {
488+
if (!goep || !goep->transport_ops || !goep->obex.server_ops ||
489+
!goep->obex.server_ops->connect || !goep->obex.server_ops->disconnect) {
446490
LOG_DBG("Invalid parameter");
447491
return -EINVAL;
448492
}
449493

494+
hdr_size = sizeof(struct bt_l2cap_hdr);
495+
496+
mtu = CONFIG_BT_GOEP_L2CAP_MTU - hdr_size;
497+
/* Use default MTU if it is not given */
498+
if (!goep->obex.rx.mtu) {
499+
goep->obex.rx.mtu = mtu;
500+
}
501+
502+
if (goep->obex.rx.mtu < GOEP_MIN_MTU) {
503+
LOG_WRN("GOEP RFCOMM MTU less than minimum size (%d < %d)", goep->obex.rx.mtu,
504+
GOEP_MIN_MTU);
505+
goep->obex.rx.mtu = GOEP_MIN_MTU;
506+
}
507+
508+
if (goep->obex.rx.mtu > mtu) {
509+
LOG_WRN("GOEP RFCOMM MTU exceeds maximum size (%d > %d)", goep->obex.rx.mtu, mtu);
510+
goep->obex.rx.mtu = mtu;
511+
}
512+
450513
err = bt_obex_reg_transport(&goep->obex, &goep_l2cap_transport_ops);
451514
if (err) {
452515
LOG_WRN("Fail to reg transport ops");
@@ -500,10 +563,11 @@ int bt_goep_transport_l2cap_connect(struct bt_conn *conn, struct bt_goep *goep,
500563
{
501564
int err;
502565
uint32_t state;
566+
uint32_t mtu;
567+
uint32_t hdr_size;
503568

504-
if (!conn || !goep || !goep->transport_ops || (goep->obex.rx.mtu < GOEP_MIN_MTU) ||
505-
!goep->obex.client_ops || !goep->obex.client_ops->connect ||
506-
!goep->obex.client_ops->disconnect) {
569+
if (!conn || !goep || !goep->transport_ops || !goep->obex.client_ops ||
570+
!goep->obex.client_ops->connect || !goep->obex.client_ops->disconnect) {
507571
LOG_DBG("Invalid parameter");
508572
return -EINVAL;
509573
}
@@ -514,6 +578,25 @@ int bt_goep_transport_l2cap_connect(struct bt_conn *conn, struct bt_goep *goep,
514578
return -EBUSY;
515579
}
516580

581+
hdr_size = sizeof(struct bt_l2cap_hdr);
582+
583+
mtu = CONFIG_BT_GOEP_L2CAP_MTU - hdr_size;
584+
/* Use default MTU if it is not given */
585+
if (!goep->obex.rx.mtu) {
586+
goep->obex.rx.mtu = mtu;
587+
}
588+
589+
if (goep->obex.rx.mtu < GOEP_MIN_MTU) {
590+
LOG_WRN("GOEP RFCOMM MTU less than minimum size (%d < %d)", goep->obex.rx.mtu,
591+
GOEP_MIN_MTU);
592+
goep->obex.rx.mtu = GOEP_MIN_MTU;
593+
}
594+
595+
if (goep->obex.rx.mtu > mtu) {
596+
LOG_WRN("GOEP RFCOMM MTU exceeds maximum size (%d > %d)", goep->obex.rx.mtu, mtu);
597+
goep->obex.rx.mtu = mtu;
598+
}
599+
517600
err = bt_obex_reg_transport(&goep->obex, &goep_l2cap_transport_ops);
518601
if (err) {
519602
LOG_WRN("Fail to reg transport ops");

0 commit comments

Comments
 (0)