Cannot alter MTU after connecting a peripheral device using the python library "pc_ble_driver_py"

Hello, 

I'm using the nRF device to communicate with a peripheral device I get some characteristic notifications but only 20 bytes for a packet.

When using the 'nRF connect' GUI I manage to update the MTU from 23 to any larger value and get the full notification.

But I cannot alter MTU after connecting a peripheral device using the python library "pc_ble_driver_py".

Iv'e tried many ways like setting the default_mtu and the att_mtu on adapter initialization:

driver = BLEDriver(
    serial_port=port,
    auto_flash=auto_flash,
    baud_rate=baud_rate,
    retransmission_interval=retransmission_interval,
    response_timeout=response_timeout,
    log_severity_level=driver_log_level,
)
driver.ble_gattc_exchange_mtu_req
adapter = BLEAdapter(driver)
adapter.default_mtu = 247
adapter.driver.open()
gatt_cfg = BLEConfigConnGatt()
gatt_cfg.att_mtu = adapter.default_mtu
adapter.driver.ble_cfg_set(BLEConfig.conn_gatt, gatt_cfg)
adapter.driver.ble_enable()


And to use the adapter.att_mtu_exchange function to but for no avail.
when i execute tyhe command : 
self.ble_adapter.att_mtu_exchange(self.conn_handler, 23)
 

it's running fine but when i try to increece the mtu to a different level like:
self.ble_adapter.att_mtu_exchange(self.conn_handler, 247)
 (or any number greater then 23)

it allways raise the folowing exception:

NordicSemiException: MTU exchange request failed. Common causes are: missing att_mtu setting in ble_cfg_set, different config tags used in ble_cfg_set and connect.

Is there any way to overcome this hurdle?

Thanks,
Uri


Parents
  • Hi uri_ee,

    I will support you with this case. However, I will need to do some investigation, while there is a bit too much on my schedule at the moment; so I cannot give you an answer right away.

    I'm sorry for the inconvenience. Unless someone from the community already helped you then, I will return by the end of Friday Mar 17

    Hieu

  • Hi uri_ee,

    My apology but I have still been occupied and haven't been able to start looking into this yet. I will try to get to it within next week, likely before Wednesday.

    Hieu

  • Hello Hieu.

    After consulting the device manager, it appears that there is no reliable method to connect to the internal logs of the device.

    I want to reiterate that when using the GUI provided by Nordic, the MTU can be updated once.

    Are there any alternative solutions we can explore to address the MTU updating this issue?

  • Hello Uri,

    If you can update MTU once, and not again, then the behavior is expected. Please refer to Bluetooth Core Spec Version 4.0/5.0/5.4 | Vol 3, Part G, Section 4.3.1 Exchange MTU

    This sub-procedure is used by the client to set the ATT_MTU to the maximum possible value that can be supported by both devices when the client supports a value greater than the default ATT_MTU for the Attribute Protocol. This subprocedure shall only be initiated once during a connection.
  • Hello Hieu.

    The Problem is that I can only update the MTU from the GUI not from Python script.

  • Hi Uri,

    I looked into it finally understood (maybe) everything. 

    On the Peripheral/nRF device side, the ble_app_hrs example by default initiates the MTU exchange first because NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED is set.

    If you set that config to 0, then the Peripheral will not initiate the negotiation, and from the Python side, you can initiate the negotiation. I did this with:

        if conn is not None:
            try:
                adapter.driver.ble_gattc_exchange_mtu_req(conn_handle=conn, mtu=129)
            except Exception as ex:
                logger.exception("Exception ble_gattc_exchange_mtu_req: {}".format(ex))

    You cannot see the final MTU, but you can derive it by looking into parameters of certain functions using breakpoints.

    Note that breakpoints can break a connection depends on where it is set. If you don't want to have to think too much about it, just restart the experiment from the beginning after each "sampling" using breakpoints.

    If the nRF device side initiates the negotiation,

    If the Python side initiates the negotiation,

    Then the MTU will be decided as the minimal between both sides' preferred MTUs. 

  • Hello Hieu,

    Unfortunately, we are unable to modify or access the code and configuration of the Peripheral device.

    I've already went over all the functions you mentioned. I examined the values and also tried to manipulate then with no avail.

    We are still in need for a solution.

    As a reminder, using the GUI app we manage to change the MTU and get the full notification. we need to be able to do the same from a python script.

    Thank you.

Reply
  • Hello Hieu,

    Unfortunately, we are unable to modify or access the code and configuration of the Peripheral device.

    I've already went over all the functions you mentioned. I examined the values and also tried to manipulate then with no avail.

    We are still in need for a solution.

    As a reminder, using the GUI app we manage to change the MTU and get the full notification. we need to be able to do the same from a python script.

    Thank you.

Children
  • Hi Uri,

    uri_ee said:
    I've already went over all the functions you mentioned. I examined the values and also tried to manipulate then with no avail.

    The functions I mentioned is a part of the library and should not be manipulated. I just asked you to examine what the parameter values of those functions are.

    What values did you see?

    uri_ee said:
    As a reminder, using the GUI app we manage to change the MTU and get the full notification. we need to be able to do the same from a python script.

    Is your issue that MTU exchange did not happen, or is it something about the notification?

    If your issue is with the notification, are you certain that the cause is with MTU?

    All this time, we have been so invested into checking if MTU is exchanged, but are we certain that the full notification wasn't sent successfully, and the problem isn't somewhere else?

    Could the problem be in your notification handling code?

    From what we have seen, I think the MTU should be exchanged correctly if you are setting things up similar to the Heart Rate example. Furthermore, if the MTU is insufficient, it usually resulted in the message just cannot be sent.

    Can you get me a sniffer trace of a test? It will reveal whether MTU was successfully exchanged, and whether the notification was sent in full or shortened.

    If you need instruction on getting a sniffer trace, please refer to Lesson 6 of our BLE Fundamentals online course.

    Hieu

  • Hi Hieu,

    Following the teams conversation we purchased and installed the BLE sniffer. Attached below is the wireshark trace logs. We connected to the device and changed the MTU. Once connected we see nothing else from this device.


    GodHelpMe_Two.pcapng

    You can filter with out MAC address that we are trying to connect to.

    C6:D8:48:B4:61:7C

    Thanks Slight smile
  • Hi Uri,

    uri_ee said:
    GodHelpMe_Two.pcapng

    Haha, unfortunately, I am no god. But the reason I cannot provide help with this file is not because of that, but because there is no connection in your sniffer trace. There are only ADV_NONCONN_IND packets in the trace, which is non-connectable advertising. There is also no scan request or response, no connection establishment packet, no sign of the central in the trace. The device c6:d8:48:b4:61:7c is not in the trace at all.

    Please go over the Bluetooth Low Energy Fundamentals lesson I linked earlier for details on how to run a sniffer properly.

    By the way, here is a sample project from me. I made it two months ago, so I don't remember the details very well. However, I am fairly certain that it should be able to negotiate MTU successfully whether the peripheral initiate the negotiation or not. It is made to work with the ble_app_uart example.

    main.py_230503_01.zip

    Regards,

    Hieu

  • Hi Hieu!

    We went over the exercises and ran it successfully. Please find attached files "three" and "four" where we connected to an nRF52840DK over a mobile phone and nRF52840 Dongle.

    "five" file is trying to connect with the pc-ble-drive-py code with our peripheral device.

    HieuHelpMe_Four.pcapngHieuHelpMe_Three.pcapngHieuHelpMe_Five.pcapng

  • Hi Uri,

    Did you try the sample I sent in my last reply?

    I am out of office now, but I will check the traces when I return next week. Meanwhile, please give the sample I sent a try.

Related