diff options
author | Stany MARCEL <stanypub@gmail.com> | 2016-12-02 02:11:49 +0300 |
---|---|---|
committer | Stany MARCEL <stanypub@gmail.com> | 2016-12-02 02:11:49 +0300 |
commit | 6a6eeec5d4b87d3e5c5a1edc748ec49c4055d1da (patch) | |
tree | 3979d8980200d4f0eaac8af4b2c50041a46404fa | |
parent | f9a26acea1bcbd7a604cb304d156335e2ec27df7 (diff) |
Add Multiple wireless controller support
This commit permits to start multiple daemon, to manage multiple
controller connected to the same dongle.
use for example:
sc-xbox.py start -i0
sc-xbox.py start -i1
Multiple wired controler is not yet implemented.
Issue #25 partially solved.
Signed-off-by: Stany MARCEL <stanypub@gmail.com>
-rwxr-xr-x | scripts/sc-desktop.py | 6 | ||||
-rwxr-xr-x | scripts/sc-xbox.py | 6 | ||||
-rw-r--r-- | src/__init__.py | 79 |
3 files changed, 61 insertions, 30 deletions
diff --git a/scripts/sc-desktop.py b/scripts/sc-desktop.py index 6b0947c..fcbc51c 100755 --- a/scripts/sc-desktop.py +++ b/scripts/sc-desktop.py @@ -75,8 +75,12 @@ if __name__ == '__main__': def _main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('command', type=str, choices=['start', 'stop', 'restart', 'debug']) + parser.add_argument('-i', '--index', type=int, choices=[0,1,2,3], default=None) args = parser.parse_args() - daemon = SCDaemon('/tmp/steamcontroller.pid') + if args.index != None: + daemon = SCDaemon('/tmp/steamcontroller{:d}.pid'.format(args.index)) + else: + daemon = SCDaemon('/tmp/steamcontroller.pid') if 'start' == args.command: daemon.start() diff --git a/scripts/sc-xbox.py b/scripts/sc-xbox.py index 80e5d58..d25668b 100755 --- a/scripts/sc-xbox.py +++ b/scripts/sc-xbox.py @@ -74,8 +74,12 @@ if __name__ == '__main__': def _main(): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('command', type=str, choices=['start', 'stop', 'restart', 'debug']) + parser.add_argument('-i', '--index', type=int, choices=[0,1,2,3], default=None) args = parser.parse_args() - daemon = SCDaemon('/tmp/steamcontroller.pid') + if args.index != None: + daemon = SCDaemon('/tmp/steamcontroller{:d}.pid'.format(args.index)) + else: + daemon = SCDaemon('/tmp/steamcontroller.pid') if 'start' == args.command: daemon.start() diff --git a/src/__init__.py b/src/__init__.py index dc5d3e6..eebb073 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -27,9 +27,9 @@ from threading import Timer import time VENDOR_ID = 0x28de -PRODUCT_ID = [0x1102, 0x1142] -ENDPOINT = [3, 2] -CONTROLIDX = [2, 1] +PRODUCT_ID = [0x1102, 0x1142, 0x1142, 0x1142, 0x1142] +ENDPOINT = [3, 2, 3, 4, 5] +CONTROLIDX = [2, 1, 2, 3, 4] HPERIOD = 0.02 LPERIOD = 0.5 @@ -116,40 +116,63 @@ class SteamController(object): self._cmsg = [] self._ctx = usb1.USBContext() - + handle = [] + pid = [] + endpoint = [] + ccidx = [] for i in range(len(PRODUCT_ID)): - pid = PRODUCT_ID[i] - endpoint = ENDPOINT[i] - ccidx = CONTROLIDX[i] + _pid = PRODUCT_ID[i] + _endpoint = ENDPOINT[i] + _ccidx = CONTROLIDX[i] - self._handle = self._ctx.openByVendorIDAndProductID( - VENDOR_ID, pid, + _handle = self._ctx.openByVendorIDAndProductID( + VENDOR_ID, _pid, skip_on_error=True, ) - if self._handle is not None: - break + if _handle != None: + handle.append(_handle) + pid.append(_pid) + endpoint.append(_endpoint) + ccidx.append(_ccidx) - if self._handle is None: - raise ValueError('SteamControler Device not found') + if len(handle) == 0: + raise ValueError('No SteamControler Device found') - self._ccidx = ccidx - dev = self._handle.getDevice() - cfg = dev[0] + claimed = False + for i in range(len(handle)): - for inter in cfg: - for setting in inter: - number = setting.getNumber() - if self._handle.kernelDriverActive(number): - self._handle.detachKernelDriver(number) - if (setting.getClass() == 3 and - setting.getSubClass() == 0 and - setting.getProtocol() == 0): - self._handle.claimInterface(number) + self._ccidx = ccidx[i] + self._handle = handle[i] + self._pid = pid[i] + self._endpoint = endpoint[i] + dev = handle[i].getDevice() + cfg = dev[0] + + try: + for inter in cfg: + for setting in inter: + number = setting.getNumber() + if self._handle.kernelDriverActive(number): + self._handle.detachKernelDriver(number) + if (setting.getClass() == 3 and + setting.getSubClass() == 0 and + setting.getProtocol() == 0 and + number == i+1): + self._handle.claimInterface(number) + claimed = True + except usb1.USBErrorBusy: + claimed = False + + if claimed: + break + + if not claimed: + raise ValueError('All SteamControler are busy') self._transfer_list = [] transfer = self._handle.getTransfer() transfer.setInterrupt( - usb1.ENDPOINT_IN | endpoint, + usb1.ENDPOINT_IN | self._endpoint, 64, callback=self._processReceivedData, ) @@ -158,7 +181,7 @@ class SteamController(object): self._period = LPERIOD - if pid == 0x1102: + if self._pid == 0x1102: self._timer = Timer(LPERIOD, self._callbackTimer) self._timer.start() else: @@ -220,7 +243,7 @@ class SteamController(object): tup = SteamControllerInput._make(struct.unpack('<' + ''.join(_FORMATS), data)) if tup.status == SCStatus.INPUT: self._tup = tup - + self._callback() transfer.submit() |