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

how to use sd_ble_uuid_vs_add in python

Hello,

I am programing a central role device in Python, with nRF51-BLE-Driver for windows. I want to discover custom 128 UUID services. For that i need to call the sd_ble_uuid_vs_add function ( base on this topic devzone.nordicsemi.com/.../ ) But how should I use it?

If I try this

uuid_list = [213, 127, 254, 99, 205, 147, 235, 163, 14, 74, 172, 83, 1, 0, 162, 186]
uuid_pointer = 0
ble_driver.sd_ble_uuid_vs_add(uuid_array, uuid_pointer)

I get: TypeError: in method 'sd_ble_uuid_vs_add', argument 1 of type 'ble_uuid128_t const *'

If I try to create ble_uuid128_t const *

srvc_uuid128 = ble_driver.ble_uuid128_t()
srvc_uuid128.uuid128 = util.list_to_uint8_array(uuid_list)

I get: TypeError: in method 'ble_uuid128_t_uuid128_set', argument 2 of type 'unsigned char [16]'

What is the correct way to use sd_ble_uuid_vs_add function in python?

  • Hi!

    Calling sd_ble_uuid_vs_add() can be done like this:

    uuid_list = [213, 127, 254, 99, 205, 147, 235, 163, 14, 74, 172, 83, 1, 0, 162, 186]
    uuid_array = util.list_to_uint8_array(uuid_list)
    
    srvc_uuid128 = ble_driver.ble_uuid128_t()
    srvc_uuid128.uuid128 = uuid_array.cast()
    
    uuid_type_pointer = ble_driver.new_uint8()
    
    ble_driver.sd_ble_uuid_vs_add(srvc_uuid128, uuid_type_pointer)
    
    uuid_type = ble_driver.uint8_value(uuid_type_pointer)
    

    Converting to the correct argument types might be a somewhat tricky. The examples in the release are for now the best source for information regarding how to pass different argument types.

  • This no longer seems to work like this. When I change the heart_rate_collector.py example:

    def connect_and_discover(self):
    
    uuid_list = [ 0x12, 0x34, 0x56, 0x78, 0xe4, 0x2f, 0x42, 0x98, 0xd6, 0x44, 0xb6, 0x1b, 0x00, 0x00, 0xdf, 0xc8 ]
    uuid_array = util.list_to_uint8_array(uuid_list)
    
    srvc_uuid128 = self.adapter.driver.ble_uuid128_t()
    srvc_uuid128.uuid128 = uuid_array.cast()
    
    uuid_type_pointer = self.adapter.driver.new_uint8()
    
    bself.adapter.driver.sd_ble_uuid_vs_add(srvc_uuid128, uuid_type_pointer)
    
    uuid_type = self.adapter.driver.uint8_value(uuid_type_pointer)
    
    
    self.adapter.driver.ble_gap_scan_start()
    

    I get:

      File "./my_file.py", line 80, in connect_and_discover
        srvc_uuid128 = self.adapter.driver.ble_uuid128_t()
    AttributeError: 'BLEDriver' object has no attribute 'ble_uuid128_t'
    

    Also, I see another function ble_vs_uuid_add:

    def ble_vs_uuid_add(self, uuid):
    
    assert isinstance(uuid, BLEUUID), 'Invalid argument type'
    uuid_type = driver.new_uint8()
    
    err_code = driver.sd_ble_uuid_vs_add(self.rpc_adapter,
                                         uuid.uuid128_to_c(),
                                         uuid_type)
    if err_code == driver.NRF_SUCCESS:
        uuid.type = driver.uint8_value(uuid_type)
    return err_code 
    

    but I am still figuring out how that expects the UUID to be given. My current best estimate (I am not a Python programmer) is this:

    uuid_list = [ 0x12, 0x34, 0x56, 0x78, 0xe4, 0x2f, 0x42, 0x98, 0xd6, 0x44, 0xb6, 0x1b, 0x00, 0x00, 0xdf, 0xc8 ]
    
    self.adapter.driver.ble_vs_uuid_add(BLEUUID(uuid_list))
    
  • Hi,
    the original explanation is not incorrect, though there has been done major changes to the structure of the python bindings. Previously there was only one layer and that was the swig generated bindings file s130_nrf51_ble_driver.py. Now there are two layers:

    1. ble_driver.py: a more abstracted and more pythonic API that is used in the examples
    2. lib///pc_ble_driver.py: swig generated bindings, softdevice API

    The explanation in my original post did and still does apply to the swig generated bindings. However, when you use the abstracted API, ble_driver.py, you do not need to handle conversion between c and python types. It is handled inside the API.

    The usage of driver.ble_vs_uuid_is like you correctly describe, pass BLEUUID as argument, and BLEUUID takes a list of byte values as argument.

  • Hi Bjørn, could you please elaborate on your last comment, I mean:

    1. how to use the "new" python bindings (pc-ble-driver-py; which revision?) to register a custom 128 bit UUID. Furthermore:
    2. has the adapter a way (method?) to register a custom UUID? In 0.9.1, I do not see any.
    3. Using driver.ble_vs_uuid_add() seems to work for me (able to discover custom Services and Chars); but after adapter.service_discovery(conn, myuuid) with myuuid a instance of BLEUUID with custom BLEUUIDBase, the object a=adapter.db_conns[conn].services[x].uuid.base returns a instance BLEUUIDBase but attribute a.base is None. In all, does the driver update a.base at all? Please, enumerate answers 1),2) and 3). Thanks
Related