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 Reply Children
  • Hello Jørgen

    First question was to know how to switch advertised packet type between connectable and non-connectable ?
    Yes, I can advertise correctly but I don't want the advertisements to be connectable

    Regards, the second question .. I start with adv/scan and then switch to the scan/adv and get Failed to ble_gap_adv/scan_start

                self.driver      = BLEDriver(serial_port="COM8", auto_flash=False)
                adv_data    = BLEAdvData(flags=flags_data,manufacturer_specific_data=manu_data)
                self.driver.observer_register(self)
                self.adapter.driver.observer_register(self)
                self.driver.open()
                self.driver.ble_enable()
                self.driver.ble_gap_adv_data_set(adv_data)
                self.driver.ble_gap_adv_start()
                time.sleep(2)
                self.driver.ble_gap_adv_stop()
                time.sleep(4)
                self.adapter.driver.ble_gap_scan_start() #here I get the error failed to start scan
                

    I have pc-ble-driver-py 0.11.4 with connectivity_1.2.0_115k2_with_s132_3.0.hex and nrf52 dev kit.

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

Related