Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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
Esempio n. 4
0
    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