mirror of https://github.com/tuhiproject/tuhi.git
dbus: implement StartPairing/StopPairing on the manager
Triggers a StartDiscovery()/StopDiscovery() on the bluetooth adapters, but with a fixed timeout of 30s.pull/4/head
parent
3871fc1d58
commit
0beb225a2e
8
tuhi.py
8
tuhi.py
|
@ -138,6 +138,8 @@ class Tuhi(GObject.Object):
|
|||
GObject.Object.__init__(self)
|
||||
self.server = TuhiDBusServer()
|
||||
self.server.connect('bus-name-acquired', self._on_tuhi_bus_name_acquired)
|
||||
self.server.connect('pairing-start-requested', self._on_start_pairing_requested)
|
||||
self.server.connect('pairing-stop-requested', self._on_stop_pairing_requested)
|
||||
self.bluez = BlueZDeviceManager()
|
||||
self.bluez.connect('device-added', self._on_bluez_device_added)
|
||||
|
||||
|
@ -146,6 +148,12 @@ class Tuhi(GObject.Object):
|
|||
def _on_tuhi_bus_name_acquired(self, dbus_server):
|
||||
self.bluez.connect_to_bluez()
|
||||
|
||||
def _on_start_pairing_requested(self, dbus_server, stop_handler, device_handler):
|
||||
self.bluez.start_discovery(stop_handler=stop_handler, timeout=30)
|
||||
|
||||
def _on_stop_pairing_requested(self, dbus_server):
|
||||
self.bluez.stop_discovery()
|
||||
|
||||
def _on_bluez_device_added(self, manager, bluez_device):
|
||||
if bluez_device.vendor_id != WACOM_COMPANY_ID:
|
||||
return
|
||||
|
|
44
tuhi/ble.py
44
tuhi/ble.py
|
@ -11,7 +11,7 @@
|
|||
# GNU General Public License for more details.
|
||||
|
||||
import logging
|
||||
from gi.repository import GObject, Gio
|
||||
from gi.repository import GObject, Gio, GLib
|
||||
|
||||
logger = logging.getLogger('tuhi.ble')
|
||||
|
||||
|
@ -285,6 +285,48 @@ class BlueZDeviceManager(GObject.Object):
|
|||
for obj in self._om.get_objects():
|
||||
self._process_object(obj)
|
||||
|
||||
def _discovery_timeout_expired(self, stop_handler):
|
||||
self.stop_discovery()
|
||||
|
||||
if stop_handler is not None:
|
||||
stop_handler(0) # always Success, because we don't really have an error path anywhere
|
||||
|
||||
return False
|
||||
|
||||
def start_discovery(self, stop_handler=None, timeout=0):
|
||||
"""
|
||||
Start discovery mode, terminating after the specified timeout (in
|
||||
seconds). If timeout is 0, no timeout is imposed and the discovery
|
||||
mode stays on.
|
||||
"""
|
||||
for obj in self._om.get_objects():
|
||||
i = obj.get_interface(ORG_BLUEZ_ADAPTER1)
|
||||
if i is None:
|
||||
continue
|
||||
|
||||
objpath = obj.get_object_path()
|
||||
i.StartDiscovery()
|
||||
logger.debug('{}: Discovery started (timeout {})'.format(objpath, timeout))
|
||||
|
||||
if timeout > 0:
|
||||
GObject.timeout_add_seconds(timeout, self._discovery_timeout_expired, stop_handler)
|
||||
|
||||
def stop_discovery(self):
|
||||
"""
|
||||
Stop an ongoing discovery mode. Any errors are logged but ignored.
|
||||
"""
|
||||
for obj in self._om.get_objects():
|
||||
i = obj.get_interface(ORG_BLUEZ_ADAPTER1)
|
||||
if i is None:
|
||||
continue
|
||||
|
||||
objpath = obj.get_object_path()
|
||||
try:
|
||||
i.StopDiscovery()
|
||||
logger.debug('{}: Discovery stopped'.format(objpath))
|
||||
except GLib.Error as e:
|
||||
logger.debug('{}: Failed to stop discovery ({})'.format(objpath, e))
|
||||
|
||||
def _on_om_object_added(self, om, obj):
|
||||
"""Callback for ObjectManager's object-added"""
|
||||
objpath = obj.get_object_path()
|
||||
|
|
|
@ -23,6 +23,19 @@ INTROSPECTION_XML = """
|
|||
<property type='ao' name='Devices' access='read'>
|
||||
<annotation name='org.freedesktop.DBus.Property.EmitsChangedSignal' value='true'/>
|
||||
</property>
|
||||
|
||||
<method name='StartPairing'>
|
||||
<annotation name='org.freedesktop.DBus.Method.NoReply' value='true'/>
|
||||
</method>
|
||||
|
||||
<method name='StopPairing'>
|
||||
<annotation name='org.freedesktop.DBus.Method.NoReply' value='true'/>
|
||||
</method>
|
||||
|
||||
<signal name='PairingStopped'>
|
||||
<arg name='status' type='i' />
|
||||
</signal>
|
||||
|
||||
</interface>
|
||||
|
||||
<interface name='org.freedesktop.tuhi1.Device'>
|
||||
|
@ -131,6 +144,20 @@ class TuhiDBusServer(GObject.Object):
|
|||
__gsignals__ = {
|
||||
"bus-name-acquired":
|
||||
(GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||
|
||||
# Signal arguments:
|
||||
# pairing_stop_handler(status)
|
||||
# to be called when the pairing process has terminated, with
|
||||
# an integer status code (0 == success, negative errno)
|
||||
# paired_device_handler(dict)
|
||||
# to be called when a pairable device has been detected
|
||||
# the argument is a dictionary of string keys, at least
|
||||
# "name" and "address" must be present
|
||||
"pairing-start-requested":
|
||||
(GObject.SIGNAL_RUN_FIRST, None,
|
||||
(GObject.TYPE_PYOBJECT, GObject.TYPE_PYOBJECT,)),
|
||||
"pairing-stop-requested":
|
||||
(GObject.SIGNAL_RUN_FIRST, None, ()),
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
|
@ -161,8 +188,16 @@ class TuhiDBusServer(GObject.Object):
|
|||
def _bus_name_lost(self, connection, name):
|
||||
pass
|
||||
|
||||
def _method_cb(self):
|
||||
pass
|
||||
def _method_cb(self, connection, sender, objpath, interface, methodname, args, invocation):
|
||||
if interface != INTF_MANAGER:
|
||||
return None
|
||||
|
||||
if methodname == 'StartPairing':
|
||||
self._start_pairing()
|
||||
invocation.return_value()
|
||||
elif methodname == 'StopPairing':
|
||||
self._stop_pairing()
|
||||
invocation.return_value()
|
||||
|
||||
def _property_read_cb(self, connection, sender, objpath, interface, propname):
|
||||
if interface != INTF_MANAGER:
|
||||
|
@ -176,6 +211,29 @@ class TuhiDBusServer(GObject.Object):
|
|||
def _property_write_cb(self):
|
||||
pass
|
||||
|
||||
def _start_pairing(self):
|
||||
self.emit("pairing-start-requested", self._on_pairing_stop,
|
||||
self._on_pairable_device)
|
||||
|
||||
def _stop_pairing(self):
|
||||
self.emit("pairing-stop-requested")
|
||||
|
||||
def _on_pairing_stop(self, status):
|
||||
"""
|
||||
Called by whoever handles the pairing-start-requested signal
|
||||
"""
|
||||
logger.debug("Pairing has stopped")
|
||||
status = GLib.Variant.new_int32(status)
|
||||
status = GLib.Variant.new_tuple(status)
|
||||
self._connection.emit_signal(None, BASE_PATH, INTF_MANAGER,
|
||||
"PairingStopped", status)
|
||||
|
||||
def _on_pairable_device(self, device):
|
||||
"""
|
||||
Called by whoever handles the pairing-start-requested signal
|
||||
"""
|
||||
logger.DEBUG("Pairable device: {}".format(device))
|
||||
|
||||
def cleanup(self):
|
||||
Gio.bus_unown_name(self._dbus)
|
||||
|
||||
|
|
Loading…
Reference in New Issue