This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

pc-ble-driver-py - sd_ble_gap_sec_params_reply fails

I have been using the pc-ble-driver Python bindings to implement a peripheral. I have extended BLEDriver to support sd_ble_gatts_* the functions. I now have a working peripheral, however I have a problem when trying to support bonding.

When the central tries to bond, my code receives a BLE_GAP_EVT_SEC_PARAMS_REQUEST event. I then call BleDriver.ble_gap_sec_params_reply. However the driver appears to hang at this point, as sd_ble_gap_sec_params_reply never returns (I don't even get an error code). I'm using the latest pc-ble-driver-py module on Linux with connectivity_1.0.1_115k2_with_s130_2.0.1.hex on a NRF51 development board.

UPDATE: I've changed the code to call sd_ble_gap_sec_params_reply on the main thread, as suggested by below. The call now returns instead of hanging, but fails with error code 3 (Internal Error). I've updated the below code to show this:

import sys
import time 
import logging
import threading

from pc_ble_driver_py.observers import BLEDriverObserver

logging.basicConfig(level=logging.DEBUG)

def init(conn_ic_id):
    global BLEDriver, BLEAdvData, BLEGapSecStatus, BLEGapSecParams, BLEGapIOCaps, BLEGapSecKDist
    from pc_ble_driver_py import config
    config.__conn_ic_id__ = conn_ic_id
    from pc_ble_driver_py.ble_driver import BLEDriver, BLEAdvData, BLEGapSecStatus, BLEGapSecParams, BLEGapIOCaps, BLEGapSecKDist

class PeripheralTest(BLEDriverObserver):

    def on_gap_evt_connected(self, ble_driver, conn_handle, peer_addr, role, conn_params):
        print('on_gap_evt_connected - conn_handle: {} role: {}'.format(conn_handle, role))

    def on_gap_evt_disconnected(self, ble_driver, conn_handle, reason):
        print('on_gap_evt_disconnected - conn_handle: {} reason: {}'.format(conn_handle, reason))

    def on_gap_evt_sec_params_request(self, ble_driver, conn_handle, peer_params):
        print('on_gap_evt_sec_params_request - conn_handle'.format('conn_handle'))
        for k in ('bond', 'mitm', 'lesc', 'keypress', 'io_caps', 'oob', 'min_key_size', 'max_key_size'):
            val = getattr(peer_params, k)
            print('\t{}: {}'.format(k, val))
        self.sec_params_requested = (ble_driver, conn_handle)
        
    def do_sec_params_reply(self):
        ble_driver, conn_handle = self.sec_params_requested
        self.sec_params_requested = None
        sec_params = BLEGapSecParams(bond = 1, mitm = 0, lesc = 0,keypress = 0, io_caps = BLEGapIOCaps.none, oob = 0, 
            min_key_size = 7, max_key_size = 16,
            kdist_own = BLEGapSecKDist(enc=1, id=1, sign=0, link=0),
            kdist_peer = BLEGapSecKDist(enc=1, id=1, sign=0, link=0))
        
        # this is now called on the main thread, but returns error code 3 - NRF_ERROR_INTERNAL
        ble_driver.ble_gap_sec_params_reply(conn_handle, BLEGapSecStatus.success, sec_params, None, None)

    def loop(self):
        self.sec_params_requested = None
        while True:
            if self.sec_params_requested:
                self.do_sec_params_reply()
            time.sleep(0.1)

def main(serial_port):
    print('Serial port used: {}'.format(serial_port))
    driver = BLEDriver(serial_port=serial_port, auto_flash=False)
    periph = PeripheralTest()
    driver.observer_register(periph)
    driver.open()
    driver.ble_enable()
    driver.ble_gap_adv_data_set(BLEAdvData(complete_local_name='Bond Test'))
    driver.ble_gap_adv_start()
    print('Started advertising')
    try:
        periph.loop()
    except KeyboardInterrupt:
        pass
    print('Closing')
    driver.close()

if __name__ == '__main__':
    serial_port = None
    if len(sys.argv) < 3:
        print("Please specify connectivity IC identifier (NRF51, NRF52) and serial port")
        exit(1)
    init(sys.argv[1])
    serial_port = sys.argv[2]
    main(serial_port)
    quit()
Parents
  • If others experience this error (0x03), with the pc-ble-driver on Linux/OSX, you can try this:

    There is an issue with the Segger firmware when using long packets over UART on Linux/OSX. The solutions is to disable the Mass Storage Device (MSD). The procedure to disable it is described in Workareound 2 on this page.

    I know the page say that the issue is not present on Linux, but it solved this exact problem for another user, so it might be worth trying.

    Best regards,

    Jørgen

Reply
  • If others experience this error (0x03), with the pc-ble-driver on Linux/OSX, you can try this:

    There is an issue with the Segger firmware when using long packets over UART on Linux/OSX. The solutions is to disable the Mass Storage Device (MSD). The procedure to disable it is described in Workareound 2 on this page.

    I know the page say that the issue is not present on Linux, but it solved this exact problem for another user, so it might be worth trying.

    Best regards,

    Jørgen

Children
Related