diff options
author | elupus <elupus@xbmc.org> | 2011-10-27 22:26:07 +0200 |
---|---|---|
committer | elupus <elupus@xbmc.org> | 2011-10-27 22:26:42 +0200 |
commit | 4fd9254f9ca67342ff197bea4472ad0e25adbc3f (patch) | |
tree | c399ad820b098114b7370852573f8ffa24753f69 /tools/EventClients | |
parent | 1e015aa0e97628c7fa91fc5b4bf7dd4d51ce6e9c (diff) |
ps3d.py: automatically pair sixaxis with bluetooth dongle when connected over usb
Diffstat (limited to 'tools/EventClients')
-rwxr-xr-x | tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py | 32 | ||||
-rw-r--r-- | tools/EventClients/lib/python/bt/hid.py | 10 | ||||
-rwxr-xr-x | tools/EventClients/lib/python/ps3/sixpair.py | 102 | ||||
-rwxr-xr-x | tools/EventClients/lib/python/ps3/sixwatch.py | 31 |
4 files changed, 175 insertions, 0 deletions
diff --git a/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py b/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py index dfc2c11fd5..cc6450327e 100755 --- a/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py +++ b/tools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py @@ -33,6 +33,12 @@ if os.path.exists("../../lib/python"): from ps3 import sixaxis from ps3_remote import process_keys as process_remote try: + from ps3 import sixwatch + except Exception, e: + print "Failed to import sixwatch now disabled: " + str(e) + sixwatch = None + + try: import zeroconf except: zeroconf = None @@ -46,6 +52,11 @@ else: from xbmc.ps3_remote import process_keys as process_remote from xbmc.defs import * try: + from xbmc.ps3 import sixwatch + except Exception, e: + print "Failed to import sixwatch now disabled: " + str(e) + sixwatch = None + try: import xbmc.zeroconf as zeroconf except: zeroconf = None @@ -235,6 +246,18 @@ class PS3RemoteThread ( StoppableThread ): pass return +class SixWatch(threading.Thread): + def __init__(self, mac): + threading.Thread.__init__(self) + self.mac = mac + self.daemon = True + self.start() + def run(self): + try: + sixwatch.main(self.mac) + except Exception, e: + print "Exception caught in sixwatch, aborting: " + str(e) + pass class ZeroconfThread ( threading.Thread ): """ @@ -294,6 +317,15 @@ def start_hidd(bdaddr=None, ipaddr="127.0.0.1"): devices = [ 'PLAYSTATION(R)3 Controller', 'BD Remote Control' ] hid = HID(bdaddr) + watch = None + if sixwatch: + try: + print "Starting USB sixwatch" + watch = SixWatch(hid.get_local_address()) + except Exception, e: + print "Failed to initialize sixwatch" + str(e) + pass + while True: if hid.listen(): (csock, addr) = hid.get_control_socket() diff --git a/tools/EventClients/lib/python/bt/hid.py b/tools/EventClients/lib/python/bt/hid.py index 7a4999b506..7cdf1529bc 100644 --- a/tools/EventClients/lib/python/bt/hid.py +++ b/tools/EventClients/lib/python/bt/hid.py @@ -16,6 +16,9 @@ # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. from bluetooth import * +import fcntl +import bluetooth._bluetooth as _bt +import array class HID: def __init__(self, bdaddress=None): @@ -56,6 +59,13 @@ class HID: self.connected = False return False + def get_local_address(self): + hci = BluetoothSocket( HCI ) + fd = hci.fileno() + buf = array.array('B', [0] * 96) + fcntl.ioctl(fd, _bt.HCIGETDEVINFO, buf, 1) + data = struct.unpack_from("H8s6B", buf.tostring()) + return data[2:8][::-1] def get_control_socket(self): if self.connected: diff --git a/tools/EventClients/lib/python/ps3/sixpair.py b/tools/EventClients/lib/python/ps3/sixpair.py new file mode 100755 index 0000000000..c9b2bbb8c4 --- /dev/null +++ b/tools/EventClients/lib/python/ps3/sixpair.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import sys +import usb + +vendor = 0x054c +product = 0x0268 +timeout = 5000 +passed_value = 0x03f5 + +def find_sixaxes(): + res = [] + for bus in usb.busses(): + print bus.dirname + for dev in bus.devices: + print "-" + dev.filename + if dev.idVendor == vendor and dev.idProduct == product: + res.append(dev) + return res + +def find_interface(dev): + for cfg in dev.configurations: + for itf in cfg.interfaces: + for alt in itf: + if alt.interfaceClass == 3: + return alt + raise Exception("Unable to find interface") + +def mac_to_string(mac): + return "%02x:%02x:%02x:%02x:%02x:%02x" % (mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) + +def set_pair_filename(dirname, filename, mac): + for bus in usb.busses(): + if int(bus.dirname) == int(dirname): + for dev in bus.devices: + if int(dev.filename) == int(filename): + if dev.idVendor == vendor and dev.idProduct == product: + update_pair(dev, mac) + return + else: + raise Exception("Device is not a sixaxis") + raise Exception("Device not found") + + +def set_pair(dev, mac): + itf = find_interface(dev) + handle = dev.open() + + msg = (0x01, 0x00) + mac; + + try: + handle.detachKernelDriver(itf.interfaceNumber) + except usb.USBError: + pass + + handle.claimInterface(itf.interfaceNumber) + try: + handle.controlMsg(usb.ENDPOINT_OUT | usb.TYPE_CLASS | usb.RECIP_INTERFACE + , usb.REQ_SET_CONFIGURATION, msg, passed_value, itf.interfaceNumber, timeout) + finally: + handle.releaseInterface() + + +def get_pair(dev): + itf = find_interface(dev) + handle = dev.open() + + try: + handle.detachKernelDriver(itf.interfaceNumber) + except usb.USBError: + pass + + handle.claimInterface(itf.interfaceNumber) + try: + msg = handle.controlMsg(usb.ENDPOINT_IN | usb.TYPE_CLASS | usb.RECIP_INTERFACE + , usb.REQ_CLEAR_FEATURE, 8, passed_value, itf.interfaceNumber, timeout) + finally: + handle.releaseInterface() + return msg[2:8] + +def set_pair_all(mac): + devs = find_sixaxes() + for dev in devs: + update_pair(dev, mac) + +def update_pair(dev, mac): + old = get_pair(dev) + if old != mac: + print "Reparing sixaxis from:" + mac_to_string(old) + " to:" + mac_to_string(mac) + set_pair(dev, mac) + +if __name__=="__main__": + devs = find_sixaxes() + + for dev in devs: + msg = get_pair(dev) + print "Found sixaxis paired to: %02x:%02x:%02x:%02x:%02x:%02x" % (msg[0], msg[1], msg[2], msg[3], msg[4], msg[5]); msg + + + + diff --git a/tools/EventClients/lib/python/ps3/sixwatch.py b/tools/EventClients/lib/python/ps3/sixwatch.py new file mode 100755 index 0000000000..b5b7b3be7d --- /dev/null +++ b/tools/EventClients/lib/python/ps3/sixwatch.py @@ -0,0 +1,31 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +import pyudev +import sixpair +import threading + +vendor = 0x054c +product = 0x0268 + + +def main(mac): + context = pyudev.Context() + monitor = pyudev.Monitor.from_netlink(context) + monitor.filter_by(subsystem="usb") + for action, device in monitor: + if 'ID_VENDOR_ID' in device and 'ID_MODEL_ID' in device: + if device['ID_VENDOR_ID'] == '054c' and device['ID_MODEL_ID'] == '0268': + if action == 'add': + print "Detected sixaxis connected by usb" + try: + sixpair.set_pair_filename(device.attributes['busnum'], device.attributes['devnum'], mac) + except Exception, e: + print "Failed to check pairing of sixaxis: " + str(e) + pass + + + +if __name__=="__main__": + main((0,0,0,0,0,0)) + |