Update MTU Exchange Procedure Not Occurring

Hello there,

I have read other issues regarding working with a larger MTU size, but I still have not been able to get it to work correctly. I realize that the peripheral device does not initiate the actual update, but it should request the update procedure since the defined MTU size is larger (CONFIG_BT_L2CAP_TX_MTU=247). I have attached the output configuration file from my build.

Please let me know if you need any more information to help. I am using the SDK Version 1.9.1

Thanks and regards,

Pam

Parents
  • Hello Einar, all you can do is point me to documents that I already read? Can you not get someone to at least look at the configuration file I sent to determine if something is wrong? This has not been very helpful really, I have been struggling with this for days now and have been getting nowhere. 

    I am looking at the values returned directly in the MTU updated callback routine, and that is what I am observing as 23. I am trying now to actually put breakpoints and trace through the BLE stack to figure out why the maximum MTU size is not correct. I will continue to try and troubleshoot this issue, but getting some expert help would be way more productive and helpful.

    Thanks,

    Pam

  • Hello

    I am only trying to help you here, I can't know what you've already read.

    We see several issues similar to yours every week, and most of them are solved when the customer is pointed to the right resources, which is why I wanted to get that out of the way before delving deeper into your issue. 

    I have already looked at your config file, and can't see something obvious that is missing, so for anyone here to keep searching for a needle in your 1700 line haystack would be neither productive nor helpful.

    I would suggest that you observe the MTU exchange using the nRF Sniffer. That could help you get a much clearer view of what is happening, and narrow down where your issue is coming from.

    Also, I assume the config file in your project folder isn't actually named .config.txt? I believe the build system would have trouble finding the file if that is the case.

    It would also be interesting to know what type of device you are using for your central unit?

    Meanwhile I will try to put together a small example program sending packets with larger MTU size using a minimal configuration.

    Regards,

    Einar

  • Hi Einar,

    Sorry about my previous reply, I am frustrated and running out of time to get this one last part of the BLE design working. Here is what I have done today which will hopefully help to identify the issue.

    First thing I tried was using Wireshark as you suggested. However I have very little experience with this software and was not able to get it to follow the BLE communications past the advertisements. Therefore I put that aside for the moment. Note that the central device I have been using for testing is an Android 6 Pixel phone with either our Custom App or the Nordic nRF Connect App.

    Secondly I tried working with the standard Zephyr Peripheral Sample application on the NRF52DK_NRF52832 development kit board. I only made some slight tweaks to ensure I could see all the printk statements on the virtual port and ensure the larger MTU transfer was supported in the configuration file. When I run this app, I also see that the maximum MTU size specified following a connection to the Nordic phone app is only 23 bytes. Here is the comm port output:

    *** Booting Zephyr OS build v2.7.99-ncs1-1 ***

    [Bluetooth initialized
    Advertising successfully started
    Indicate VND attr 0x2d2b0 (UUID 12345678-1234-5678-1234-56789abcdef1)
    00:00:17.985,412] <inf> fs_nvs: 6 Sectors of 4096 bytes
    [00:00:17.985,443] <inf> fs_nvs: alloc wra: 0, fb8
    [00:00:17.985,443] <inf> fs_nvs: data wra: 0, 4c
    [00:00:17.985,595] <inf> sdc_hci_driver: SoftDevice Controller build revision:
    0e e7 c5 66 67 18 3c ac b3 d2 cc 81 a3 dc f1 c0 |...fg.<. ........
    c0 36 02 22 |.6."
    [00:00:17.989,501] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002)
    [00:00:17.989,532] <inf> bt_hci_core: HW Variant: nRF52x (0x0002)
    [00:00:17.989,532] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 14.50663 Build 1008232294
    [00:00:17.989,959] <inf> bt_hci_core: No ID address. App must call settings_load()
    [00:00:17.992,767] <inf> bt_hci_core: Identity: FC:BC:02:5F:35:04 (random)
    [00:00:17.992,797] <inf> bt_hci_core: HCI: version 5.2 (0x0b) revision 0x12fe, manufacturer 0x0059
    [00:00:17.992,797] <inf> bt_hci_core: LMP: version 5.2 (0x0b) subver 0x12fe
    Updated MTU: TX: 23 RX: 23 bytes
    Connected

    Attached is the updated "prj.conf" file I used, that was the file I changed, a longer vendor specific characteristic is already defined in this example. Note that with the default "prj.conf" file I also saw the "updated MTU" size (via the callback) as 23 bytes. (The attached filename was changed because this website wouldn't allow me to attach the ".conf" file extension directly).

    Please let me know if I am missing something obvious here for the MTU size used to be a larger value.

    # Incresed stack due to settings API usage
    CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
    
    CONFIG_BT=y
    CONFIG_BT_DEBUG_LOG=y
    CONFIG_BT_SMP=y
    CONFIG_BT_SIGNING=y
    CONFIG_BT_PERIPHERAL=y
    CONFIG_BT_DIS=y
    CONFIG_BT_ATT_PREPARE_COUNT=5
    CONFIG_BT_BAS=y
    CONFIG_BT_HRS=y
    CONFIG_BT_PRIVACY=y
    CONFIG_BT_DEVICE_NAME="Zephyr Peripheral Sample Long Name"
    CONFIG_BT_DEVICE_APPEARANCE=833
    CONFIG_BT_DEVICE_NAME_DYNAMIC=y
    CONFIG_BT_DEVICE_NAME_MAX=65
    
    # Make sure printk is printing to the console
    CONFIG_CONSOLE=y
    CONFIG_PRINTK=y
    CONFIG_STDOUT_CONSOLE=y
    
    CONFIG_BT_KEYS_OVERWRITE_OLDEST=y
    CONFIG_BT_SETTINGS=y
    CONFIG_FLASH=y
    CONFIG_FLASH_PAGE_LAYOUT=y
    CONFIG_FLASH_MAP=y
    CONFIG_NVS=y
    CONFIG_SETTINGS=y
    
    # Additional BLE configurations
    CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
    CONFIG_BT_CTLR_RX_BUFFERS=2
    CONFIG_BT_L2CAP_TX_MTU=247
    CONFIG_BT_L2CAP_TX_BUF_COUNT=10
    CONFIG_BT_BUF_EVT_RX_SIZE=251
    CONFIG_BT_BUF_CMD_TX_SIZE=251
    CONFIG_BT_BUF_ACL_RX_SIZE=251
    CONFIG_BT_BUF_ACL_TX_COUNT=10
    CONFIG_BT_BUF_ACL_TX_SIZE=251
    CONFIG_BT_BUF_CMD_TX_COUNT=10
    

    Thank you so much for your help on this matter, hopefully this simple example will help us work together to resolve this issue.

    Best regards,

    Pam

  • One other point I should mention. When I use a different peripheral device that uses a competitor chip / BLE stack with the same profile and services, I have no issue with the larger MTU size exchange occuring immediately upon completing the connection.

    Thanks,

    Pam

  • Hi

    I believe I might have figured out what is causing your issue.

    In the Zephyr Peripheral sample you're using it looks like the Updated MTU message is printed when a connection is established, even if no MTU exchange has occurred.

    So your central unit probably isn't initiating an MTU exchange, which just means you'll have to initiate it from your peripheral.

    I was able to do this by adding the following lines inside connected() in main.c:

        static struct bt_gatt_exchange_params exchange_params;
        exchange_params.func = exchange_func;
        err = bt_gatt_exchange_mtu(conn, &exchange_params);
        if (err) {
            printk("MTU exchange failed (err %d)", err);
        }

    with exchange_func defined like this:

    static void exchange_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_exchange_params *params)
    {
        if (!err) {
            printk("MTU exchange done");
        } else {
            printk("MTU exchange failed (err %" PRIu8 ")", err);
        }
    }

    I also had to add this to prj.conf in order to use the bt_gatt_exchange_mtu() function:

    CONFIG_BT_GATT_CLIENT=y

    Please let me know if this solves your issue or not.

    -Einar

  • Hello Einar,

    Well that definitely worked, thanks so much for your help.

    Can you please pass on the fact that this is not documented correctly for the case where the device is a peripheral in the server only role. To specify the device as a client in order to force the MTU exchange is not discussed anywhere that I could find, and to be honest it seems a bit like a hacked solution. However if there is no other side effect of specifying "client" when it is not really a client I am okay with it.

    Thanks again for helping me get to the bottom of this problem.

    Regards,

    Pam

  • Hi

    Glad to hear that it worked!

    Well, being a client only means that you're allowed to send requests to a server, such as the MTU exchange request. The only downside I can think of would be a slight increase in memory footprint, but since you're using large Bluetooth buffers this might not be the biggest concern for your application?

    If you don't want your peripheral to be a client you would have to send the MTU exchange request from your central unit, so if you're not in control of the application on the central unit your peripheral will have to be a client.

    -Einar

Reply
  • Hi

    Glad to hear that it worked!

    Well, being a client only means that you're allowed to send requests to a server, such as the MTU exchange request. The only downside I can think of would be a slight increase in memory footprint, but since you're using large Bluetooth buffers this might not be the biggest concern for your application?

    If you don't want your peripheral to be a client you would have to send the MTU exchange request from your central unit, so if you're not in control of the application on the central unit your peripheral will have to be a client.

    -Einar

Children
No Data
Related