aboutsummaryrefslogtreecommitdiff
path: root/tools/EventClients
diff options
context:
space:
mode:
authorelupus <elupus@xbmc.org>2011-10-27 22:26:07 +0200
committerelupus <elupus@xbmc.org>2011-10-27 22:26:42 +0200
commit4fd9254f9ca67342ff197bea4472ad0e25adbc3f (patch)
treec399ad820b098114b7370852573f8ffa24753f69 /tools/EventClients
parent1e015aa0e97628c7fa91fc5b4bf7dd4d51ce6e9c (diff)
ps3d.py: automatically pair sixaxis with bluetooth dongle when connected over usb
Diffstat (limited to 'tools/EventClients')
-rwxr-xr-xtools/EventClients/Clients/PS3 Sixaxis Controller/ps3d.py32
-rw-r--r--tools/EventClients/lib/python/bt/hid.py10
-rwxr-xr-xtools/EventClients/lib/python/ps3/sixpair.py102
-rwxr-xr-xtools/EventClients/lib/python/ps3/sixwatch.py31
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))
+