This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Updating MTU size Zephyr

I have a Bluetooth device that has a long characteristic. On previous central device projects there is usually a function like read_long_char. I am trying to get a zephyr-based product up and going which has to make multiple calls to read at 19 bytes per transaction. I need to speed this up, I think what I want is a larger MTU.

I have been trying to update the MTU within Zephyr but I am not having much luck. I have attempted to use information from other support cases as well.

I am running Zephyr 2.6.99

Here is the relevant conf file, BT settings copied from https://github.com/nrfconnect/sdk-nrf/tree/main/samples/bluetooth/throughput

CONFIG_BT=y
CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_MAX_CONN=2

CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y
CONFIG_BT_SCAN_UUID_CNT=1

CONFIG_BT_THROUGHPUT=y

CONFIG_BT_GATT_DM=y
CONFIG_HEAP_MEM_POOL_SIZE=2048

CONFIG_BT_USER_DATA_LEN_UPDATE=y

CONFIG_BT_BUF_ACL_RX_SIZE=251
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_ATT_PREPARE_COUNT=2
CONFIG_BT_CONN_TX_MAX=10
CONFIG_BT_L2CAP_TX_BUF_COUNT=10
CONFIG_BT_L2CAP_TX_MTU=247
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_CTLR_PHY_2M=y
CONFIG_BT_CTLR_RX_BUFFERS=2
CONFIG_BT_BUF_ACL_TX_COUNT=10
CONFIG_BT_BUF_ACL_TX_SIZE=251
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251

I attempt the MTU update after services have been discovered:

static void ebl_set_mtu_cb(struct bt_conn *conn, uint8_t att_err,
			   struct bt_gatt_exchange_params *params)
{
	struct bt_conn_info info = {0};
	int err;

	if (att_err) {
		LOG_DBG("MTU exchange failed");
	}
	else {
		LOG_DBG("MTU exchange successful");
	}

	LOG_DBG("MTU size is: %d", bt_gatt_get_mtu(conn));

	err = bt_conn_get_info(conn, &info);
	if (err) {
		LOG_ERR("Failed to get connection info %d", err);
		return;
	}

	LOG_DBG("MTU exchange complete");

	ctx.app_state = APP_STATE_MTU_SET;

}

static void ebl_set_conn_mtu()
{

	int err = bt_conn_le_data_len_update(ctx.btle_device.default_conn, BT_LE_DATA_LEN_PARAM_MAX);
	if (err) {
		LOG_DBG("LE data length update failed: %d", err);
	}
	else {
		LOG_DBG("LE data length set to MAX");
	}

	ctx.btle_device.exchange_params.func = ebl_set_mtu_cb;

	LOG_DBG("MTU size is: %d", bt_gatt_get_mtu(ctx.btle_device.default_conn));

	int ex_err = bt_gatt_exchange_mtu(ctx.btle_device.default_conn,
					  &ctx.btle_device.exchange_params);

	if (ex_err) {
		LOG_DBG("MTU exchange failed (err %d)", ex_err);
	} else {
		LOG_DBG("MTU exchange pending");
	}

	ctx.app_state = APP_STATE_SETTING_MTU;
}

Output, MTU is never changed:

[00:06:52.830,444] <dbg> e2e_btle.scan_cb: D6:CA:73:E7:32:15 	 -38 	 v0.2
[00:06:52.916,931] <inf> e2e_btle: Attempting to connect to: D6:CA:73:E7:32:15 (random)
[00:06:54.038,055] <inf> e2e_btle: Connected: D6:CA:73:E7:32:15 (random)
[00:06:55.239,624] <dbg> e2e_btle.ebl_discover_func: [ATTRIBUTE] handle 14, type 2800, uuid 00000001-6f73-6e65-5364-6e4532646e45, permission 0
[00:06:56.839,660] <dbg> e2e_btle.ebl_discover_func: [ATTRIBUTE] handle 15, type 2803, uuid , permission 0
[00:06:56.839,874] <dbg> e2e_btle.ebl_discover_func: [CHARACTERISTIC] handle 16, properties 10, uuid 00000003-6f73-6e65-5364-6e4532646e45,
[00:06:57.639,617] <dbg> e2e_btle.ebl_discover_func: [ATTRIBUTE] handle 17, type 2803, uuid , permission 0
[00:06:57.639,801] <dbg> e2e_btle.ebl_discover_func: [CHARACTERISTIC] handle 18, properties 18, uuid 00000002-6f73-6e65-5364-6e4532646e45,
Connection parameters update request received.
Minimum interval: 80, Maximum interval: 160
Latency: 0, Timeout: 500
[00:06:58.439,422] <dbg> e2e_btle.ebl_discover_func: Discover complete
[00:06:58.521,789] <dbg> e2e_btle.ebl_set_conn_mtu: LE data length set to MAX
[00:06:58.521,789] <dbg> e2e_btle.ebl_set_conn_mtu: MTU size is: 23
[00:06:58.521,911] <dbg> e2e_btle.ebl_set_conn_mtu: MTU exchange pending
[00:06:59.239,257] <dbg> e2e_btle.ebl_set_mtu_cb: MTU exchange successful
[00:06:59.239,257] <dbg> e2e_btle.ebl_set_mtu_cb: MTU size is: 23
[00:06:59.239,257] <dbg> e2e_btle.ebl_set_mtu_cb: MTU exchange complete

I am new to Zephyr, any help would be greatly appreciated. I can enable HCI debugging or any other debugging if that would help.

Parents
  • Are you in control of the peripheral or the central? If you're in charge of both, setting both prj.conf files to something similar to what you shared should be enough to update the MTU upon exchange. If you're only in charge of one, then you'd be limited by the MTU of the third-party device. Also, if you're wanting higher throughput, then you could initially connect on the 2 Mbps PHY or update it upon connection like this

    err = bt_conn_le_phy_update(conn, BT_CONN_LE_PHY_PARAM_2M);

  • Thanks for the reply, I think you got me close enough to what I needed. I may have been assuming the MTU was negotiable but that looks to be incorrect. I instead changed the default connection intervals and I am now seeing approximately the speeds I see on other devices. I will have to circle back to the peripheral code in the future and see what I con do about the MTU.

Reply
  • Thanks for the reply, I think you got me close enough to what I needed. I may have been assuming the MTU was negotiable but that looks to be incorrect. I instead changed the default connection intervals and I am now seeing approximately the speeds I see on other devices. I will have to circle back to the peripheral code in the future and see what I con do about the MTU.

Children
No Data
Related