def add_descriptor(self, uuid: Uuid, properties: GattsAttributeProperties, initial_value=b"", string_encoding="utf8") -> GattsAttribute: """ Creates and adds a descriptor to the characteristic .. note:: Due to limitations of the BLE stack, the CCCD, SCCD, User Description, Extended Properties, and Presentation Format descriptors cannot be added through this method. They must be added through the ``GattsCharacteristicProperties`` fields when creating the characteristic. :param uuid: The UUID of the descriptor to add, and cannot be the UUIDs of any of the reserved descriptor UUIDs in the note :param properties: The properties of the descriptor :param initial_value: The initial value to set the descriptor to :param string_encoding: The string encoding to use, if a string is set :return: the descriptor that was created and added to the characteristic """ if isinstance(initial_value, str): initial_value = initial_value.encode(string_encoding) self.ble_device.uuid_manager.register_uuid(uuid) security = _security_mapping[properties.security_level] read_perm = security if properties.read else nrf_types.BLEGapSecModeType.NO_ACCESS write_perm = security if properties.write else nrf_types.BLEGapSecModeType.NO_ACCESS max_len = max(len(initial_value), properties.max_len) metadata = nrf_types.BLEGattsAttrMetadata(read_perm, write_perm, properties.variable_length, read_auth=properties.read_auth, write_auth=properties.write_auth) attr = nrf_types.BLEGattsAttribute(uuid.nrf_uuid, metadata, max_len, initial_value) self.ble_device.ble_driver.ble_gatts_descriptor_add(self._value_attr.handle, attr) attr = GattsAttribute(self.ble_device, self.peer, self, uuid, attr.handle, properties, initial_value, string_encoding) self._attrs.append(attr) return attr
def add_characteristic(self, uuid, properties, initial_value=""): """ Adds a new characteristic to the service :param: The UUID of the characteristic to add :type uuid: blatann.uuid.Uuid :param properties: The characteristic's properties :type properties: GattsCharacteristicProperties :param initial_value: The initial value of the characteristic. May be a string, bytearray, or list of ints :type initial_value: str or list or bytearray :return: The characteristic just added to the service :rtype: GattsCharacteristic """ c = GattsCharacteristic(self.ble_device, self.peer, uuid, properties, self._notification_manager, initial_value) # Register UUID self.ble_device.uuid_manager.register_uuid(uuid) # Create property structure props = nrf_types.BLEGattCharacteristicProperties(properties.broadcast, properties.read, False, properties.write, properties.notify, properties.indicate, False) # Create cccd metadata if notify/indicate enabled if properties.notify or properties.indicate: cccd_metadata = nrf_types.BLEGattsAttrMetadata(read_auth=False, write_auth=False) else: cccd_metadata = None char_md = nrf_types.BLEGattsCharMetadata(props, cccd_metadata=cccd_metadata) security = _security_mapping[properties.security_level] attr_metadata = nrf_types.BLEGattsAttrMetadata(security, security, properties.variable_length, read_auth=True, write_auth=True) attribute = nrf_types.BLEGattsAttribute(uuid.nrf_uuid, attr_metadata, properties.max_len, initial_value) handles = nrf_types.BLEGattsCharHandles() # Populated in call self.ble_device.ble_driver.ble_gatts_characteristic_add(self.start_handle, char_md, attribute, handles) c.value_handle = handles.value_handle c.cccd_handle = handles.cccd_handle if c.cccd_handle != gatt.BLE_GATT_HANDLE_INVALID: self.end_handle = c.cccd_handle else: self.end_handle = c.value_handle self.characteristics.append(c) return c
def add_characteristic(self, uuid: Uuid, properties: GattsCharacteristicProperties, initial_value=b"", prefer_indications=True, string_encoding="utf8"): """ Adds a new characteristic to the service :param uuid: The UUID of the characteristic to add :param properties: The characteristic's properties :param initial_value: The initial value of the characteristic. May be a string, bytearray, or list of ints :type initial_value: str or list or bytearray :param prefer_indications: Flag for choosing indication/notification if a characteristic has both indications and notifications available :param string_encoding: The encoding method to use when a string value is provided (utf8, ascii, etc.) :return: The characteristic just added to the service :rtype: GattsCharacteristic """ if isinstance(initial_value, str): initial_value = initial_value.encode(string_encoding) # Register UUID self.ble_device.uuid_manager.register_uuid(uuid) # Create property structure props = nrf_types.BLEGattCharacteristicProperties( broadcast=properties.broadcast, read=properties.read, write_wo_resp=properties.write_no_response, write=properties.write, notify=properties.notify, indicate=properties.indicate, auth_signed_wr=False) char_md = nrf_types.BLEGattsCharMetadata(props) # Create cccd metadata if notify/indicate enabled if properties.notify or properties.indicate: char_md.cccd_metadata = nrf_types.BLEGattsAttrMetadata() if properties.sccd: char_md.sccd_metadata = nrf_types.BLEGattsAttrMetadata() if properties.presentation: pf = nrf_types.BLEGattsPresentationFormat( properties.presentation.format, properties.presentation.exponent, properties.presentation.unit, properties.presentation.namespace, properties.presentation.description) char_md.presentation_format = pf if properties.user_description: user_desc = properties.user_description user_desc_sec = _security_mapping[user_desc.security_level] user_desc_sec_w = user_desc_sec if user_desc.write else nrf_types.BLEGapSecModeType.NO_ACCESS char_md.user_desc_metadata = nrf_types.BLEGattsAttrMetadata( user_desc_sec, user_desc_sec_w, user_desc.variable_length, user_desc.read_auth, user_desc.write_auth) char_md.user_description = user_desc.value char_md.user_description_max_len = user_desc.max_len char_md.extended_props.writable_aux = user_desc.write security = _security_mapping[properties.security_level] attr_metadata = nrf_types.BLEGattsAttrMetadata( security, security, properties.variable_length, read_auth=True, write_auth=True) attribute = nrf_types.BLEGattsAttribute(uuid.nrf_uuid, attr_metadata, properties.max_len, initial_value) handles = nrf_types.BLEGattsCharHandles() # Populated in call self.ble_device.ble_driver.ble_gatts_characteristic_add( self.start_handle, char_md, attribute, handles) c = GattsCharacteristic(self.ble_device, self.peer, uuid, properties, handles.value_handle, handles.cccd_handle, handles.sccd_handle, handles.user_desc_handle, self._notification_manager, initial_value, prefer_indications, string_encoding) self.characteristics.append(c) return c
def add_characteristic(self, uuid: Uuid, properties: GattsCharacteristicProperties, initial_value=b"", prefer_indications=True, string_encoding="utf8"): """ Adds a new characteristic to the service :param uuid: The UUID of the characteristic to add :param properties: The characteristic's properties :param initial_value: The initial value of the characteristic. May be a string, bytearray, or list of ints :type initial_value: str or list or bytearray :param prefer_indications: Flag for choosing indication/notification if a characteristic has both indications and notifications available :param string_encoding: The encoding method to use when a string value is provided (utf8, ascii, etc.) :return: The characteristic just added to the service :rtype: GattsCharacteristic """ if isinstance(initial_value, str): initial_value = initial_value.encode(string_encoding) c = GattsCharacteristic(self.ble_device, self.peer, uuid, properties, self._notification_manager, initial_value, prefer_indications, string_encoding) # Register UUID self.ble_device.uuid_manager.register_uuid(uuid) # Create property structure props = nrf_types.BLEGattCharacteristicProperties( broadcast=properties.broadcast, read=properties.read, write_wo_resp=properties.write_no_response, write=properties.write, notify=properties.notify, indicate=properties.indicate, auth_signed_wr=False) # Create cccd metadata if notify/indicate enabled if properties.notify or properties.indicate: cccd_metadata = nrf_types.BLEGattsAttrMetadata(read_auth=False, write_auth=False) else: cccd_metadata = None char_md = nrf_types.BLEGattsCharMetadata(props, cccd_metadata=cccd_metadata) security = _security_mapping[properties.security_level] attr_metadata = nrf_types.BLEGattsAttrMetadata( security, security, properties.variable_length, read_auth=True, write_auth=True) attribute = nrf_types.BLEGattsAttribute(uuid.nrf_uuid, attr_metadata, properties.max_len, initial_value) handles = nrf_types.BLEGattsCharHandles() # Populated in call self.ble_device.ble_driver.ble_gatts_characteristic_add( self.start_handle, char_md, attribute, handles) c.value_handle = handles.value_handle c.cccd_handle = handles.cccd_handle if c.cccd_handle != gatt.BLE_GATT_HANDLE_INVALID: self.end_handle = c.cccd_handle else: self.end_handle = c.value_handle self.characteristics.append(c) return c