Using pc_ble_driver_py (version 0.15.0) to create a peripheral with a specific Device Name in characteristic 0x2A00 (Generic access service), the resulting device name is garbage. The class "BLEConfigGapDeviceName" is used to try setting the device name in the following way:
configName = BLEConfigGapDeviceName(device_name="0000000000",device_name_read_only=False) ble_driver.ble_cfg_set(BLEConfig(driver.BLE_GAP_CFG_DEVICE_NAME), configName) ble_driver.ble_enable()
This is the result in nRF Connect:
In the log window the following is seen:
Attribute value read, handle: 0x03, value (0x): D4-03-00-20-00-00-00-00-D0-1C
This is the complete file:
import logging import sys import time from threading import Condition, Lock from pc_ble_driver_py.observers import BLEDriverObserver BASE_UUID_DICT = {'BV_BASE_UUID': [0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB]} SERVICE1 = (("MyService1" , 0x3000), (("Char1" , 0x3001, 1, [0x00], "Desc"), ("Char2" , 0x3002, 2, [0x00], "Desc"),)) DEVICE_INFORMATION_SERVICE = (("Device Information" , 0x180A), (("Manufacturer name" , 0x2A29, 20, b"Name", None), ("Model name" , 0x2A24, 20, b"Model1", None), ("Firmware version" , 0x2A26, 20, b"v_0.0.1", None),)) SERVICES_CONFIG = ( DEVICE_INFORMATION_SERVICE, SERVICE1, ) logger = logging.getLogger(__name__) def init(conn_ic_id): # noinspection PyGlobalUndefined global BLEAdapter, BLEDriver, BLEAdvData, BLEConfigGapDeviceName, BLEEvtID, BLEEnableParams, config, driver, BLEAdvData, BLEGattsHVXParams, BLEService, BLEUUIDBase, BLEUUID, BLEGattsAttr, BLEGattsAttrMD, BLEGattHandle, BLEGattsCharHandles, BLEGattsCharMD, BLEGattCharProps, BLEConfig, BLEConfigCommon from pc_ble_driver_py import config config.__conn_ic_id__ = conn_ic_id # noinspection PyUnresolvedReferences from pc_ble_driver_py.ble_driver import ( BLEDriver, BLEAdvData, BLEConfigGapDeviceName, BLEEvtID, BLEEnableParams, BLEGattsHVXParams, BLEService, BLEUUIDBase, BLEUUID, BLEGattHandle, BLEGattsAttr, BLEGattsAttrMD, BLEGattsCharHandles, BLEGattsCharMD, BLEGattCharProps, BLEConfig, BLEConfigCommon, driver, ) # noinspection PyUnresolvedReferences from pc_ble_driver_py.ble_adapter import BLEAdapter class Peripheral: def __init__(self, adapter): self.adapter = adapter logger.info( "Peripheral adapter is %d", self.adapter.driver.rpc_adapter.internal, ) self.char_128_handles_dict = {} self.serv_128_handle_dict = {} self.uuid_128_base_dict = {} self.serv_128_uuid_dict = {} def _add_char(self, base_uuid, service_uuid, char_uuid, max_len, value, user_desc_str): """Add characteristic""" char_128_handles = BLEGattsCharHandles() char_128_uuid = BLEUUID(char_uuid, self.uuid_128_base_dict[base_uuid] ) max_len=16 props = BLEGattCharProps(notify=True, read=True, write=True) if user_desc_str: # user_desc = list(user_desc_str.encode()) # desc_md = BLEGattCharProps(read=True) # char_md = BLEGattsCharMD(char_props=props, user_desc=user_desc, desc_md=desc_md) char_md = BLEGattsCharMD(char_props=props) else: char_md = BLEGattsCharMD(char_props=props) attr_md = BLEGattsAttrMD() attr = BLEGattsAttr(uuid=char_128_uuid, attr_md=attr_md, max_len=max_len, value=value) self.adapter.driver.ble_gatts_characteristic_add( self.serv_128_handle_dict[service_uuid].handle, char_md, attr, char_128_handles) self.char_128_handles_dict[char_uuid] = char_128_handles def _add_service(self, base_uuid, service_uuid): """Add specific service""" if not base_uuid in self.uuid_128_base_dict: uuid_128_base = BLEUUIDBase(BASE_UUID_DICT[base_uuid]) self.uuid_128_base_dict[base_uuid] = uuid_128_base self.adapter.driver.ble_vs_uuid_add(self.uuid_128_base_dict[base_uuid]) self.serv_128_handle_dict[service_uuid]= BLEGattHandle() self.serv_128_uuid_dict[service_uuid] = BLEUUID(service_uuid, self.uuid_128_base_dict[base_uuid]) self.adapter.driver.ble_gatts_service_add( driver.BLE_GATTS_SRVC_TYPE_PRIMARY, self.serv_128_uuid_dict[service_uuid], self.serv_128_handle_dict[service_uuid]) def setup_services_128bit(self): """Setup services""" for (_, service_uuid), chars in SERVICES_CONFIG: self._add_service(base_uuid='BV_BASE_UUID', service_uuid=service_uuid) for (_, char_uuid, max_len, value, user_desc_str) in chars: self._add_char(base_uuid='BV_BASE_UUID', service_uuid=service_uuid, char_uuid=char_uuid, max_len=max_len, value=value, user_desc_str=user_desc_str) def main(serial_port): print("Serial port used: {}".format(serial_port)) ble_driver = BLEDriver(serial_port=serial_port, baud_rate=1000000, auto_flash=True, log_severity_level="debug") adapter = BLEAdapter(ble_driver) observer = TimeoutObserver() adv_data = BLEAdvData(short_local_name="MyDevice") ble_driver.observer_register(observer) ble_driver.open() if config.__conn_ic_id__.upper() == "NRF51": ble_driver.ble_enable( BLEEnableParams( vs_uuid_count=0, service_changed=0, periph_conn_count=1, central_conn_count=0, central_sec_count=0, ) ) elif config.__conn_ic_id__.upper() == "NRF52": # configCommon = BLEConfigCommon() # configCommon.vs_uuid_count = 1 # driver.ble_cfg_set(BLEConfig.uuid_count, configCommon) # cfg = BLEConfigGap() # cfg.device_name = "test123" # cfg.device_name_read_only = False # ble_tester.driver.ble_cfg_set(BLEConfig.device_name, cfg) configName = BLEConfigGapDeviceName(device_name="0000000000",device_name_read_only=False) ble_driver.ble_cfg_set(BLEConfig(driver.BLE_GAP_CFG_DEVICE_NAME), configName) # ble_driver.ble_cfg_set(BLEConfig.device_name, cfg) #sd_ble_gap_device_name_set() ble_driver.ble_enable() peripheral = Peripheral(adapter) peripheral.setup_services_128bit() ble_driver.ble_gap_adv_data_set(adv_data) ble_driver.ble_gap_adv_start() observer.wait_for_timeout() while(True): time.sleep(10) print("Closing") ble_driver.close() class TimeoutObserver(BLEDriverObserver): def __init__(self, *args, **kwargs): super(BLEDriverObserver, self).__init__(*args, **kwargs) self.cond = Condition(Lock()) def on_gap_evt_timeout(self, ble_driver, conn_handle, src): with self.cond: self.cond.notify_all() def on_gap_evt_disconnected(self, ble_driver, conn_handle, reason): with self.cond: self.cond.notify_all() def wait_for_timeout(self): with self.cond: self.cond.wait() if __name__ == "__main__": logFormatter = logging.Formatter("%(asctime)s [%(levelname)-7s][%(name)s] %(message)s") rootLogger = logging.getLogger() fileHandler = logging.FileHandler("ble_test.log") fileHandler.setFormatter(logFormatter) rootLogger.addHandler(fileHandler) consoleHandler = logging.StreamHandler(sys.stdout) consoleHandler.setFormatter(logFormatter) rootLogger.addHandler(consoleHandler) rootLogger.setLevel(logging.DEBUG) id = "NRF52" serial_port = "/dev/ttyACM0" init(id) main(serial_port)
What am I doing wrong?