diff --git a/README.md b/README.md index 1cbdd74..5442b66 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,22 @@ org.freedesktop.tuhi1.Device on behalf of another client. In this case, this client should wait for the Listening property to change and StartListening() once the property is set to False. + + If the error is -EBADE, the device is not in pairing/listening mode + and pairing/listening was requested. In this case, the client should + indicate to the user that the device needs to be paired first or + switched to listening mode. + + If the error is -EACCES, the device is not paired with the daemon or + incorrectly paired. This may happen when the device was paired with + another host since the last connection. + + The following other errnos may be sent by the daemon: + -EPROTO: the daemon has encountered a protocol error with the device. + -ETIME: timeout while communicating with the device. + + These errnos indicate a bug in the daemon, and the client should + display a message to that effect. ``` JSON File Format diff --git a/tools/tuhi-kete.py b/tools/tuhi-kete.py index 99b993b..6be3299 100755 --- a/tools/tuhi-kete.py +++ b/tools/tuhi-kete.py @@ -14,6 +14,7 @@ from gi.repository import GObject, Gio, GLib import sys import argparse +import os import json import logging import select @@ -133,6 +134,9 @@ class TuhiKeteDevice(_DBusObject): if signal == 'ButtonPressRequired': print("{}: Press button on device now".format(self)) elif signal == 'ListeningStopped': + err = parameters[0] + if err < 0: + print("{}: an error occured: {}".format(self, os.strerror(err))) self.notify('listening') def _on_properties_changed(self, proxy, changed_props, invalidated_props): diff --git a/tuhi/base.py b/tuhi/base.py index c7239b3..2cec947 100644 --- a/tuhi/base.py +++ b/tuhi/base.py @@ -76,6 +76,12 @@ class TuhiDevice(GObject.Object): real device) with the frontend DBusServer object that exports the device over Tuhi's DBus interface """ + __gsignals__ = { + # Signal sent when an error occurs on the device itself. + # Argument is a Wacom*Exception + 'device-error': + (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), + } def __init__(self, bluez_device, config, uuid=None, paired=True): GObject.Object.__init__(self) @@ -177,8 +183,11 @@ class TuhiDevice(GObject.Object): self._tuhi_dbus_device.add_drawing(d) - def _on_fetching_finished(self, device, bluez_device): + def _on_fetching_finished(self, device, exception, bluez_device): bluez_device.disconnect_device() + if exception is not None: + logger.info(exception) + self.emit('device-error', exception) def _on_button_press_required(self, device): self._tuhi_dbus_device.notify_button_press_required() diff --git a/tuhi/dbusserver.py b/tuhi/dbusserver.py index ec47b9d..fe767ce 100755 --- a/tuhi/dbusserver.py +++ b/tuhi/dbusserver.py @@ -147,6 +147,7 @@ class TuhiDBusDevice(_TuhiDBus): self._listening_client = None self._dbusid = self._register_object(connection) device.connect('notify::paired', self._on_device_paired) + device.connect('device-error', self._on_device_error) @GObject.Property def listening(self): @@ -231,6 +232,12 @@ class TuhiDBusDevice(_TuhiDBus): return self.paired = device.paired + def _on_device_error(self, device, exception): + logger.info('An error occured while synching the device') + if self.listening: + self._stop_listening(self.connection, self._listening_client[0], + -exception.errno) + def _start_listening(self, connection, sender): if self.listening: logger.debug("{} - already listening".format(self)) @@ -265,7 +272,7 @@ class TuhiDBusDevice(_TuhiDBus): self._stop_listening(connection, user_data) - def _stop_listening(self, connection, sender): + def _stop_listening(self, connection, sender, errno=0): if not self.listening or sender != self._listening_client[0]: return @@ -275,7 +282,7 @@ class TuhiDBusDevice(_TuhiDBus): self.notify('listening') - status = GLib.Variant.new_int32(0) + status = GLib.Variant.new_int32(errno) self.signal('ListeningStopped', status, dest=sender) self.listening = False self.notify('listening') diff --git a/tuhi/wacom.py b/tuhi/wacom.py index 840b207..1443980 100644 --- a/tuhi/wacom.py +++ b/tuhi/wacom.py @@ -17,6 +17,7 @@ import logging import threading import time import uuid +import errno from gi.repository import GObject logger = logging.getLogger('tuhi.wacom') @@ -86,27 +87,27 @@ class Drawing(list): class WacomException(Exception): - pass + errno = errno.ENOSYS class WacomEEAGAINException(WacomException): - pass + errno = errno.EAGAIN class WacomWrongModeException(WacomException): - pass + errno = errno.EBADE class WacomNotPairedException(WacomException): - pass + errno = errno.EACCES class WacomTimeoutException(WacomException): - pass + errno = errno.ETIME class WacomCorruptDataException(WacomException): - pass + errno = errno.EPROTO class WacomDevice(GObject.Object): @@ -121,7 +122,7 @@ class WacomDevice(GObject.Object): "drawing": (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT,)), "done": - (GObject.SIGNAL_RUN_FIRST, None, ()), + (GObject.SIGNAL_RUN_FIRST, None, (GObject.TYPE_PYOBJECT, )), "button-press-required": (GObject.SIGNAL_RUN_FIRST, None, ()), } @@ -643,15 +644,19 @@ class WacomDevice(GObject.Object): logger.debug('{}: starting'.format(self.device.address)) self._is_running = True + exception = None try: if self._pairing_mode: self.pair_device() else: self.retrieve_data() + except WacomException as e: + logger.error(f'**** Exception: {e} ****') + exception = e finally: self._pairing_mode = False self._is_running = False - self.emit("done") + self.emit("done", exception) def start(self, pairing_mode): self._pairing_mode = pairing_mode