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

  • 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.

  • Hi Hieu,

    Yes I tried the sample and I have managed to get the full length message from the peripheral device. At this time I am trying to update my code to match the sample you provided. Now I am having a new problem. When I try any other value than 23 I get this error:

    NordicSemiException ble_gattc_exchange_mtu_req: Failed to ble_gattc_exchange_mtu_req. Error code: NRF_ERROR_INVALID_PARAM

  • Hi Uri,

    Have you noted the comments I wrote in the code? Duplicating it here for reference:

            # If the peer (peripheral device) initiates the MTU exchange, this value will be automatically used
            # as this device (Python/interface device) preferred MTU.
            # By default, the Heart Rate Collector example also uses this value to configure the
            # SoftDevice/interface device. See further notes in open()
            self.adapter.default_mtu = 111
    
            self.mtu_exchanged = False
            self.nus_tx_uuid = None
            self.peer_mtu = 0
    
        def open(self):
            self.adapter.driver.open()
            if config.__conn_ic_id__.upper() == "NRF51":
                raise AssertionError ("NOT SUPPORTED: config.__conn_ic_id__.upper() == ""NRF51""")
            elif config.__conn_ic_id__.upper() == "NRF52":
                gatt_cfg = BLEConfigConnGatt()
    
                # In this configuration, we are configuring the MAXIMUM value that the SoftDevice/interface device can
                # ever support. It can only be reconfigured after driver.ble_disable().
                # See: https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s140.api.v7.2.0/structble__gatt__conn__cfg__t.html#a3fac0ed97a3a75cf21e9ed8432b95193
                gatt_cfg.att_mtu = self.adapter.default_mtu
                gatt_cfg.tag = CFG_TAG
                self.adapter.driver.ble_cfg_set(BLEConfig.conn_gatt, gatt_cfg)
    
                self.adapter.driver.ble_enable()

    Another source of that error is, as we explained before, if the negotiation already happened. Which brings us to the sniffer traces.

    Are you certain that the device in trace Three and Four is the same as in trace Five?

    In trace Three and Four, we can see that the peripheral device initiate the MTU negotiation:

    However, that didn't happen in trace Five.

Reply
  • Hi Uri,

    Have you noted the comments I wrote in the code? Duplicating it here for reference:

            # If the peer (peripheral device) initiates the MTU exchange, this value will be automatically used
            # as this device (Python/interface device) preferred MTU.
            # By default, the Heart Rate Collector example also uses this value to configure the
            # SoftDevice/interface device. See further notes in open()
            self.adapter.default_mtu = 111
    
            self.mtu_exchanged = False
            self.nus_tx_uuid = None
            self.peer_mtu = 0
    
        def open(self):
            self.adapter.driver.open()
            if config.__conn_ic_id__.upper() == "NRF51":
                raise AssertionError ("NOT SUPPORTED: config.__conn_ic_id__.upper() == ""NRF51""")
            elif config.__conn_ic_id__.upper() == "NRF52":
                gatt_cfg = BLEConfigConnGatt()
    
                # In this configuration, we are configuring the MAXIMUM value that the SoftDevice/interface device can
                # ever support. It can only be reconfigured after driver.ble_disable().
                # See: https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.s140.api.v7.2.0/structble__gatt__conn__cfg__t.html#a3fac0ed97a3a75cf21e9ed8432b95193
                gatt_cfg.att_mtu = self.adapter.default_mtu
                gatt_cfg.tag = CFG_TAG
                self.adapter.driver.ble_cfg_set(BLEConfig.conn_gatt, gatt_cfg)
    
                self.adapter.driver.ble_enable()

    Another source of that error is, as we explained before, if the negotiation already happened. Which brings us to the sniffer traces.

    Are you certain that the device in trace Three and Four is the same as in trace Five?

    In trace Three and Four, we can see that the peripheral device initiate the MTU negotiation:

    However, that didn't happen in trace Five.

Children
No Data
Related