Example #1
0
def init(daemon, config):
	""" Registers hotplug callback for controller dongle """
	def cb(device, handle):
		return SCByCable(device, handle, daemon)
	
	register_hotplug_device(cb, VENDOR_ID, PRODUCT_ID)
	return True
Example #2
0
def init(daemon, config):
    """ Registers hotplug callback for controller dongle """
    def cb(device, handle):
        return SCByCable(device, handle, daemon)

    register_hotplug_device(cb, VENDOR_ID, PRODUCT_ID)
    return True
Example #3
0
def init(daemon, config):
    """ Registers hotplug callback for ds4 device """
    def hid_callback(device, handle):
        return DS4Controller(device, daemon, handle, None, None)

    def evdev_make_device_callback(daemon, evdevdevices):
        # With kernel 4.10 or later, PS4 controller pretends to be 3 different devices.
        # 1st, determining which one is actual controller is needed
        controllerdevice = None
        for device in evdevdevices:
            count = len(get_axes(device))
            if count == 8:
                # 8 axes - Controller
                controllerdevice = device
        if not controllerdevice:
            log.warning("Failed to determine controller device")
            return
        # 2nd, find motion sensor and touchpad with physical address matching
        # controllerdevice
        gyro, touchpad = None, None
        phys = device.phys.split("/")[0]
        for device in evdevdevices:
            if device.phys.startswith(phys):
                count = len(get_axes(device))
                if count == 6:
                    # 6 axes - gyro sensor
                    gyro = device
                elif count == 4:
                    # 4 axes - Touchpad
                    touchpad = device
        # 3rd, do a magic
        return DS4EvdevController(daemon, controllerdevice, gyro, touchpad)

    def fail_cb(vid, pid):
        if HAVE_EVDEV:
            log.warning(
                "Failed to acquire USB device, falling back to evdev driver. This is far from optimal."
            )
            make_new_device(vid, pid, evdev_make_device_callback)
        else:
            log.error(
                "Failed to acquire USB device and evdev is not available. Everything is lost and DS4 support disabled."
            )
            # TODO: Maybe add_error here, but error reporting needs little rework so it's not threated as fatal
            # daemon.add_error("ds4", "No access to DS4 device")

    if config["drivers"].get("hiddrv") or (HAVE_EVDEV and
                                           config["drivers"].get("evdevdrv")):
        register_hotplug_device(hid_callback,
                                VENDOR_ID,
                                PRODUCT_ID,
                                on_failure=fail_cb)
        return True
    else:
        log.warning(
            "Neither HID nor Evdev driver is enabled, DS4 support cannot be enabled."
        )
        return False
Example #4
0
class HIDDrv(object):
	
	def __init__(self, daemon):
		self.registered = set()
		self.config_files = {}
		self.configs = {}
		self.scan_files()
		self.daemon = daemon
	
	
	def hotplug_cb(self, device, handle):
		vid, pid = device.getVendorID(), device.getProductID()
		if (vid, pid) in self.configs:
			controller = HIDController(device, self.daemon, handle,
				self.config_files[vid, pid], self.configs[vid, pid])
			return controller
		return None
	
	
	def scan_files(self):
		"""
		Goes through ~/.config/scc/devices and enables hotplug callback for
		every known HID device
		"""
		path = os.path.join(get_config_path(), "devices")
		if not os.path.exists(path):
			# Nothing to do
			return
		
		known = set()
		for name in os.listdir(path):
			if name.startswith("hid-") and name.endswith(".json"):
				vid, pid = name.split("-", 2)[1].split(":")[0:2]
				vid = int(vid, 16)
				pid = int(pid, 16)
				config_file = os.path.join(path, name)
				try:
					config = json.loads(open(config_file, "r").read())
				except Exception, e:
					log.warning("Ignoring file that cannot be parsed: %s", name)
					continue
				
				self.config_files[vid, pid] = config_file
				self.configs[vid, pid] = config
				known.add((vid, pid))
		
		for new in known - self.registered:
			vid, pid = new
			register_hotplug_device(self.hotplug_cb, vid, pid)
			self.registered.add(new)
		
		for removed in self.registered - known:
			vid, pid = removed
			unregister_hotplug_device(self.hotplug_cb, vid, pid)
			self.registered.remove(removed)
			if (vid, pid) in self.config_files:
				del self.config_files[vid, pid]
			if (vid, pid) in self.configs:
				del self.configs[vid, pid]
    def scan_files(self):
        """
		Goes through ~/.config/scc/devices and enables hotplug callback for
		every known HID device
		"""
        path = os.path.join(get_config_path(), "devices")
        if not os.path.exists(path):
            # Nothing to do
            return

        known = set()
        for name in os.listdir(path):
            if name.startswith("hid-") and name.endswith(".json"):
                vid, pid = name.split("-", 2)[1].split(":")[0:2]
                vid = int(vid, 16)
                pid = int(pid, 16)
                config_file = os.path.join(path, name)
                try:
                    config = json.loads(open(config_file, "r").read())
                except Exception:
                    log.warning("Ignoring file that cannot be parsed: %s",
                                name)
                    continue

                self.config_files[vid, pid] = config_file.decode("utf-8")
                self.configs[vid, pid] = config
                known.add((vid, pid))

        for new in known - self.registered:
            vid, pid = new
            register_hotplug_device(self.hotplug_cb, vid, pid)
            self.registered.add(new)

        for removed in self.registered - known:
            vid, pid = removed
            unregister_hotplug_device(self.hotplug_cb, vid, pid)
            self.registered.remove(removed)
            if (vid, pid) in self.config_files:
                del self.config_files[vid, pid]
            if (vid, pid) in self.configs:
                del self.configs[vid, pid]
Example #6
0
	def scan_files(self):
		"""
		Goes through ~/.config/scc/devices and enables hotplug callback for
		every known HID device
		"""
		path = os.path.join(get_config_path(), "devices")
		if not os.path.exists(path):
			# Nothing to do
			return
		
		known = set()
		for name in os.listdir(path):
			if name.startswith("hid-") and name.endswith(".json"):
				vid, pid = name.split("-", 2)[1].split(":")[0:2]
				vid = int(vid, 16)
				pid = int(pid, 16)
				config_file = os.path.join(path, name)
				try:
					config = json.loads(open(config_file, "r").read())
				except Exception:
					log.warning("Ignoring file that cannot be parsed: %s", name)
					continue
				
				self.config_files[vid, pid] = config_file
				self.configs[vid, pid] = config
				known.add((vid, pid))
		
		for new in known - self.registered:
			vid, pid = new
			register_hotplug_device(self.hotplug_cb, vid, pid)
			self.registered.add(new)
		
		for removed in self.registered - known:
			vid, pid = removed
			unregister_hotplug_device(self.hotplug_cb, vid, pid)
			self.registered.remove(removed)
			if (vid, pid) in self.config_files:
				del self.config_files[vid, pid]
			if (vid, pid) in self.configs:
				del self.configs[vid, pid]
Example #7
0
	
	def cb(device, handle):
		try:
			return cls(device, None, handle, None, None, test_mode=True)
		except NotHIDDevice:
			print >>sys.stderr, "%.4x:%.4x is not a HID device" % (vid, pid)
			fake_daemon.exitcode = 3
		except UnparsableDescriptor, e:
			print >>sys.stderr, "Invalid or unparsable HID descriptor", str(e)
			fake_daemon.exitcode = 4
		except Exception, e:
			print >>sys.stderr, "Failed to open device:", str(e)
			fake_daemon.exitcode = 2
	
	_usb.set_daemon(fake_daemon)
	register_hotplug_device(cb, vid, pid)
	fake_daemon.dev_monitor.start()
	_usb.start()
	fake_daemon.dev_monitor.rescan()
	
	if fake_daemon.exitcode < 0:
		print "Ready"
	sys.stdout.flush()
	while fake_daemon.exitcode < 0:
		fake_daemon.poller.poll()
		_usb.mainloop()
	
	return fake_daemon.exitcode

def init(daemon, config):
	""" Called from scc-daemon """
Example #8
0
	fake_daemon = FakeDaemon()
	
	def cb(device, handle):
		try:
			return cls(device, None, handle, None, None, test_mode=True)
		except NotHIDDevice:
			print >>sys.stderr, "%.4x:%.4x is not a HID device" % (vid, pid)
			fake_daemon.exitcode = 3
		except UnparsableDescriptor, e:
			print >>sys.stderr, "Invalid or unparsable HID descriptor", str(e)
			fake_daemon.exitcode = 4
		except Exception, e:
			print >>sys.stderr, "Failed to open device:", str(e)
			fake_daemon.exitcode = 2
	
	register_hotplug_device(cb, vid, pid)
	_usb._daemon = fake_daemon
	_usb.start()
	
	if fake_daemon.exitcode < 0:
		print "Ready"
	sys.stdout.flush()
	while fake_daemon.exitcode < 0:
		fake_daemon.poller.poll()
		_usb.mainloop()
	
	return fake_daemon.exitcode


def init(daemon, config):
	""" Called from scc-daemon """
Example #9
0
def init(daemon, config):
	""" Registers hotplug callback for ds4 device """
		
	def hid_callback(device, handle):
		return DS4Controller(device, daemon, handle, None, None)
	
	def make_evdev_device(syspath, *whatever):
		devices = get_evdev_devices_from_syspath(syspath)
		# With kernel 4.10 or later, PS4 controller pretends to be 3 different devices.
		# 1st, determining which one is actual controller is needed
		controllerdevice = None
		for device in devices:
			count = len(get_axes(device))
			if count == 8:
				# 8 axes - Controller
				controllerdevice = device
		if not controllerdevice:
			log.warning("Failed to determine controller device")
			return None
		# 2nd, find motion sensor and touchpad with physical address matching controllerdevice
		gyro, touchpad = None, None
		phys = device.phys.split("/")[0]
		for device in devices:
			if device.phys.startswith(phys):
				axes = get_axes(device)
				count = len(axes)
				if count == 6:
					# 6 axes
					if EvdevController.ECODES.ABS_MT_POSITION_X in axes:
						# kernel 4.17+ - touchpad
						touchpad = device
					else:
						# gyro sensor
						gyro = device
					pass
				elif count == 4:
					# 4 axes - Touchpad
					touchpad = device
		# 3rd, do a magic
		if controllerdevice and gyro and touchpad:
			return make_new_device(DS4EvdevController, controllerdevice, gyro, touchpad)
	
	
	def fail_cb(syspath, vid, pid):
		if HAVE_EVDEV:
			log.warning("Failed to acquire USB device, falling back to evdev driver. This is far from optimal.")
			make_evdev_device(syspath)
		else:
			log.error("Failed to acquire USB device and evdev is not available. Everything is lost and DS4 support disabled.")
			# TODO: Maybe add_error here, but error reporting needs little rework so it's not threated as fatal
			# daemon.add_error("ds4", "No access to DS4 device")
	
	if config["drivers"].get("hiddrv") or (HAVE_EVDEV and config["drivers"].get("evdevdrv")):
		register_hotplug_device(hid_callback, VENDOR_ID, PRODUCT_ID, on_failure=fail_cb)
		if HAVE_EVDEV and config["drivers"].get("evdevdrv"):
			daemon.get_device_monitor().add_callback("bluetooth",
							VENDOR_ID, PRODUCT_ID, make_evdev_device, None)
		return True
	else:
		log.warning("Neither HID nor Evdev driver is enabled, DS4 support cannot be enabled.")
		return False