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

How to select Packet type in pc-ble-driver-py and to switch between scan and adv mode

Hello

I used the pc-ble-driver-py to advertise Apple ibeacons, but it seems that they're advertised as connectable undirected packets which is not good in my case, as I filter in NRF52 firmware packets based on packet type (1- not scan response 2- not connectable packet).

ble_gap_adv_start() method do have adv_params argument but it's just for interval and timeout. while the packet type is specified as following (I think)

    def ble_gap_adv_start(self, adv_params=None):
        if not adv_params:
            adv_params = self.adv_params_setup()
        assert isinstance(adv_params, BLEGapAdvParams), 'Invalid argument type'
        return driver.sd_ble_gap_adv_start(self.rpc_adapter, adv_params.to_c())

....

    def to_c(self):
        adv_params              = driver.ble_gap_adv_params_t()
        adv_params.type         = BLEGapAdvType.connectable_undirected.value
        adv_params.p_peer_addr  = None  # Undirected advertisement.
        adv_params.fp           = driver.BLE_GAP_ADV_FP_ANY
        adv_params.p_whitelist  = None
        adv_params.interval     = util.msec_to_units(self.interval_ms,
                                                                util.UNIT_0_625_MS)
        adv_params.timeout      = self.timeout_s

My other question is regards how to switch between scan and adv in pc-ble-driver-py. When I do setup like:

self.driver      = BLEDriver(serial_port=self.serial_port, auto_flash=False)
self.driver.observer_register(self)
self.adapter.driver.observer_register(self)
self.driver.open()
self.driver.ble_enable()

When I do scan alone it works, and when I do adv alone it works, but when the same program change from scan<->adv based on same setup, I get errors like

pc_ble_driver_py.exceptions.NordicSemiException: Failed to ble_gap_adv_start. Error code: 18

or can't start scan according to switch case.

Parents
  • Hi,

    I'm not sure that I understand your first question. Are you asking if this is the correct way of defining packet type? Have you tested if it works?

    Regarding your second question, which version of pc-ble-driver-py are you using, and on which chip? Error code 18 typically means NRF_ERROR_CONN_COUNT, which indicate that you have reached the number of allowed connections and that advertising can therefore not be started.

    Best regards,
    Jørgen

  • Yes, you can change the advertising type there, but you can also extend the driver with a parameter for type in BLEGapAdvParams, that can be configured in the application:

    class BLEGapAdvParams(object):
        def __init__(self, interval_ms, timeout_s, adv_type):
            self.interval_ms    = interval_ms
            self.timeout_s      = timeout_s
            self.adv_type       = adv_type
    
    
        def to_c(self):
            adv_params              = driver.ble_gap_adv_params_t()
            adv_params.type         = self.adv_type
            adv_params.p_peer_addr  = None  # Undirected advertisement.
            adv_params.fp           = driver.BLE_GAP_ADV_FP_ANY
            adv_params.p_whitelist  = None
            adv_params.interval     = util.msec_to_units(self.interval_ms,
                                                                    util.UNIT_0_625_MS)
            adv_params.timeout      = self.timeout_s
    
            return adv_params

    You would then also have to modify the setup function:

        def adv_params_setup(self):
            return BLEGapAdvParams(interval_ms = 40,
                                   timeout_s   = 180,
    							   adv_type    = BLEGapAdvType.connectable_undirected.value)

    It should then be possible to set the type directly in the application (this is from modified advertising.py example):

    def init(conn_ic_id):
        global BLEDriver, BLEAdvData, BLEEvtID, BLEGapAdvParams, BLEGapAdvType
        from pc_ble_driver_py import config
        config.__conn_ic_id__ = conn_ic_id
        from pc_ble_driver_py.ble_driver    import BLEDriver, BLEAdvData, BLEEvtID, BLEGapAdvParams, BLEGapAdvType
    
    def main(serial_port):
        print("Serial port used: {}".format(serial_port))
        driver      = BLEDriver(serial_port=serial_port, auto_flash=True)
        observer    = TimeoutObserver()
        adv_data    = BLEAdvData(complete_local_name='Example')
        adv_params  = BLEGapAdvParams(interval_ms=40, timeout_s=180, adv_type=BLEGapAdvType.non_connectable_undirected)
    
        driver.observer_register(observer)
        driver.open()
        driver.ble_enable()
        driver.ble_gap_adv_data_set(adv_data)
        driver.ble_gap_adv_start()
        observer.wait_for_timeout()
    
        print("Closing")
        driver.close()

    Is there any specific reason that you start scanning with 'self.adapter.driver.ble_gap_scan_start()' and not 'self.driver.ble_gap_scan_start()'? I think this will call functions directly in the C library.

    Best regards,
    Jørgen

  • Thanks Jorgen

    I already did that as a change inside the driver, but it will be very helpful to add this option originally in your package.

    About the other problem, There is no special reason behind that, I will try using the other way soon and let you know if could solve it.

Reply Children
No Data
Related