Set MTU size in Zephyr

Hello,

I ran the throughput example ,but I found that setting the MTU size actually requires calling the bt_gatt_exchange_mtu function, which is different from sdk16.0 .

In sdk16.0 or other versions, I can set the MTU size by calling nrf_ble_gatt_att_mtu_periph_set()  and nrf_ble_gatt_att_mtu_central_set() .

Is there any way to automatically set the MTU size in Zephyr?

Best Regards,

Gray

Parents Reply Children
  • You can't set it before a connection as the MTU exchange is a negotiation between the Central and Peripheral (where the Central ultimately decides what value to use). You'll have to initiate such an exchange for each established connection. 

  • Hi,haakonsh

    My doubt is why the Central does not choose to set MTU_SIZE?

    After connecting, I called bt_gatt_get_mtu() and the read size was 23 instead of the set size.

    https://github.com/nrfconnect/sdk-nrf/blob/master/samples/bluetooth/throughput/prj.conf

    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

  • Hey Gray,

    You configs looks good.

    We need more information however. I suggest you start by enabling debug logs for the BT stack and share that. A sniffer trace would also help. 

  • Hello, haakonsh

    The demo I ran was provided by Nordic( throughput example). I didn’t change the code much. I only called get_mtu_size() in the connected() and exchange_func() functions.

  • Hey again Grey,

    I added the bt_gatt_get_mtu functions to the exchange and discovery complete functions:

    static void exchange_func(struct bt_conn *conn, uint8_t att_err,
    			  struct bt_gatt_exchange_params *params)
    {
    	struct bt_conn_info info = {0};
    	int err;
    
    	printk("MTU exchange %s\n", att_err == 0 ? "successful" : "failed");
    	printk("MTU size is: %d\n", bt_gatt_get_mtu(conn));
    
    	err = bt_conn_get_info(conn, &info);
    	if (err) {
    		printk("Failed to get connection info %d\n", err);
    		return;
    	}
    
    	if (info.role == BT_CONN_ROLE_MASTER) {
    		instruction_print();
    		test_ready = true;
    	}
    }
    
    static void discovery_complete(struct bt_gatt_dm *dm,
    			       void *context)
    {
    	int err;
    	struct bt_throughput *throughput = context;
    
    	printk("Service discovery completed\n");
    
    	bt_gatt_dm_data_print(dm);
    	bt_throughput_handles_assign(dm, throughput);
    	bt_gatt_dm_data_release(dm);
    
    	exchange_params.func = exchange_func;
    
    	printk("MTU size is: %d\n", bt_gatt_get_mtu(default_conn));
    
    	err = bt_gatt_exchange_mtu(default_conn, &exchange_params);
    	if (err) {
    		printk("MTU exchange failed (err %d)\n", err);
    	} else {
    		printk("MTU exchange pending\n");
    	}
    }

    This was my output: 
    Connected as master
    Conn. interval is 320 units
    Service discovery completed
    MTU size is: 23
    MTU exchange pending
    MTU exchange successful
    MTU size is: 247
    I'm on NCS 1.7.1 btw.
Related