pc-ble-driver-py, mtu size, data length extensions and connectivity firmware

Hi,

I'm trying to develop an application that uses an nrf52840-dk board and the pc-ble-driver-py. The dk is supposed to be a central device.

Using the python driver library, I've got it to connect to another custom board (supposed to be a peripheral), that also uses an nrf52840 MCU. When it connects however, the custom board is supposed to negotiate a higher MTU size, packet data length extensions, and connection interval. It always does this when I connect to nRF connect on my smartphone, or anything else. But I can't seem to get it to do this with the dk and ble-driver-py. It connects, but never seems to negotiate anything. Should I make the dk (the central) try and negotiate?

The dk is flashed with connectivity firmware version: 4.1.4. SoftDevice API version: 5.

Is this a limitation of the driver and connectivity firwmare version? I can't find anything in the driver code relating to it. 

I'm also quite confused with the state of the pc-ble-driver and connectivity firmware. Can you confirm if the following is correct?:

  • pc-ble-driver-py supports up to SD api v5 only, and s132 SD only
  • Is there any way I can use SD s140 and v6 API? that's what my custom peripheral MCU is programmed with

Parents
  • Hi Savvn, 

    As far as I know the pc-ble-driver should support longer MTU size. Could you have a look at the workaround mentioned in this ticket and check if it work for you ? 
    pc-ble-driver-py is a pretty old tool and will not have further update. But it should work with S140 with v6 API. Could you point me to where you got the information about: 

    pc-ble-driver-py supports up to SD api v5 only, and s132 SD only

    I would suggest to capture a sniffer trace so we know what exactly over the air. 

Reply
  • Hi Savvn, 

    As far as I know the pc-ble-driver should support longer MTU size. Could you have a look at the workaround mentioned in this ticket and check if it work for you ? 
    pc-ble-driver-py is a pretty old tool and will not have further update. But it should work with S140 with v6 API. Could you point me to where you got the information about: 

    pc-ble-driver-py supports up to SD api v5 only, and s132 SD only

    I would suggest to capture a sniffer trace so we know what exactly over the air. 

Children
  • When I connect to my peripheral device, no MTU negotiation happens, only PHY update request. This is when I call the connect() function inside ble_adapter.py.

    I'll take a look at that ticket now, it must have missed me when I was searching for similar posts on this topic.
    I do realize it's an older tool, but we want to work in Python as its quicker for us currently to get this up and running with python. 

    If you look inside pc-ble-driver-py/pc_ble_driver_py/hex/ only folders sd_api_v2 and sd_api_v5 are listed. 
    Inside pc_ble_driver_py/lib you will find only nrf_ble_driver_sd_api_v2.py and nrf_ble_driver_sd_api_v5.py. Inside the code only references to 'v2' and 'v5' can be found.
    On top of that, I've tried to flash my dk with connectivity fw that contains SD S140 and v6.1.1 API from here:
    And it wouldn't work, pc-ble-driver-py would report timeout
     
  • Hi again Savvn,

    Did you request MTU from the peripheral side ? If not, you may need to implement the request on the central's side. 

    You are right that pc-ble-driver-py doesn't support API v6. You can have a look here.

    But it's supported on pc-ble-driver C++ library. So you may consider use the pc-ble-driver instead. 

  • Hi Hung,

    Yes the peripherals firmware is configured to negotiate higher MTU, correct conn. interval etc.

    It always does this when connected to, say my smartphone running nRF connect app, or my machine's internal bluetooth adapter etc.

    I tried the jlink workaround #2 with disabling mass storage, but no avail.

    I'm going to look into wireshark now and sniff to see what is going on upon connection.

  • Did you follow the workaround mentioned in the case I pointed to ? 
    Of setting self.adapter.default_mtu = 247 manually ? 

    Please capture a sniffer trace. If you have added in the code that the slave should request ATT MTU update, it should do that when connected, regardless which central it connects to. 

  • Ok I think I've gotten to the bottom of this.

    I followed the OP's code in that other post.

    This is what the adapter open code looks like:

    self.adapter.driver.open()
    self.adapter.default_mtu = 547
    
    gatt_cfg = BLEConfigConnGatt()
    gatt_cfg.att_mtu = 547
    gatt_cfg.tag = CFG_TAG
    self.adapter.driver.ble_cfg_set(BLEConfig.conn_gatt, gatt_cfg)
    
    cfg = BLEConfigGapRoleCount(central_role_count=1, periph_role_count=0, central_sec_count=0)
    cfg.conn_cfg_tag = CFG_TAG
    self.adapter.driver.ble_cfg_set(BLEConfig.role_count, cfg)
    
    cfg = BLEConfigConnGap(event_length=251)
    cfg.conn_cfg_tag = CFG_TAG
    self.adapter.driver.ble_cfg_set(BLEConfig.conn_gap, cfg)
    
    self.adapter.driver.ble_enable()

    After scanning, and discovering, I simply did something like this to connect:

    self.adapter.connect(device_adv_data.peer_addr,conn_params=None, tag=CFG_TAG)

    Now with this, it communicates the event data length and PHY (the max - 251. But NOT MTU size or conn. interval. This can be seen from wireshark:

    I would have thought, like when connecting to anything else, the peripheral (server) should initiate these negotiations? I was wrong actually, it's the master that starts the MTU size negotiation. I saw this when comparing that trace, to another trace where I connect my peripheral to an iPhone X. So from OP's example in other post I added this code after the adapter connect.

    logging.info('Requesting MTU exchange')
    self.att_mtu = self.adapter.att_mtu_exchange(new_conn_handle, 517)

    And now it negotiates the right size. So actually my knowledge of the connection process was not quite correct. But at least now I know how it's meant to go.

Related