def _on_notification_received(self, success, result, failure_reason):
        """Callback function called when a notification has been received.
        It is executed in the baBLE working thread: should not be blocking.

        Args:
            success (bool): A bool indicating that the operation is successful or not
            result (dict): The notification information
              - value (bytes): Data notified
            failure_reason (any): An object indicating the reason why the operation is not successful (else None)
        """
        if not success:
            self._logger.info("Notification received with failure failure_reason=%s", failure_reason)

        notification_id = (result['connection_handle'], result['attribute_handle'])

        callback = None
        with self.notification_callbacks_lock:
            if notification_id in self.notification_callbacks:
                callback, once = self.notification_callbacks[notification_id]

                if once:
                    del self.notification_callbacks[notification_id]

        if callback is not None:
            callback(result['value'])