Ejemplo n.º 1
0
def run(receivers, args, find_receiver, _ignore):
	assert receivers

	if args.receiver:
		receiver_name = args.receiver.lower()
		receiver = find_receiver(receiver_name)
		if not receiver:
			raise Exception("no receiver found matching '%s'" % receiver_name)
	else:
		receiver = receivers[0]

	assert receiver
	receiver.status = _status.ReceiverStatus(receiver, lambda *args, **kwargs: None)

	# check if it's necessary to set the notification flags
	old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
	if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
		_hidpp10.set_notification_flags(receiver, old_notification_flags | _hidpp10.NOTIFICATION_FLAG.wireless)

	# get all current devices
	known_devices = [dev.number for dev in receiver]

	class _HandleWithNotificationHook(int):
		def notifications_hook(self, n):
			assert n
			if n.devnumber == 0xFF:
				_notifications.process(receiver, n)
			elif n.sub_id == 0x41 and n.address == 0x04:
				if n.devnumber not in known_devices:
					receiver.status.new_device = receiver[n.devnumber]

	timeout = 20  # seconds
	receiver.handle = _HandleWithNotificationHook(receiver.handle)

	receiver.set_lock(False, timeout=timeout)
	print ('Pairing: turn your new device on (timing out in', timeout, 'seconds).')

	# the lock-open notification may come slightly later, wait for it a bit
	pairing_start = _timestamp()
	patience = 5  # seconds

	while receiver.status.lock_open or _timestamp() - pairing_start < patience:
		n = _base.read(receiver.handle)
		if n:
			n = _base.make_notification(*n)
			if n:
				receiver.handle.notifications_hook(n)

	if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
		# only clear the flags if they weren't set before, otherwise a
		# concurrently running Solaar app might stop working properly
		_hidpp10.set_notification_flags(receiver, old_notification_flags)

	if receiver.status.new_device:
		dev = receiver.status.new_device
		print ('Paired device %d: %s (%s) [%s:%s]' % (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
	else:
		error = receiver.status.get(_status.KEYS.ERROR) or 'no device detected?'
		raise Exception("pairing failed: %s" % error)
Ejemplo n.º 2
0
def pair_device(receiver, args):
	# get all current devices
	known_devices = [dev.number for dev in receiver]

	from logitech_receiver import base, hidpp10, status, notifications
	receiver.status = status.ReceiverStatus(receiver, lambda *args, **kwargs: None)

	# check if it's necessary to set the notification flags
	old_notification_flags = hidpp10.get_notification_flags(receiver) or 0
	if not (old_notification_flags & hidpp10.NOTIFICATION_FLAG.wireless):
		hidpp10.set_notification_flags(receiver, old_notification_flags | hidpp10.NOTIFICATION_FLAG.wireless)

	class HandleWithNotificationHook(int):
		def notifications_hook(self, n):
			assert n
			if n.devnumber == 0xFF:
				notifications.process(receiver, n)
			elif n.sub_id == 0x41 and n.address == 0x04:
				if n.devnumber not in known_devices:
					receiver.status.new_device = receiver[n.devnumber]

	timeout = 20  # seconds
	receiver.handle = HandleWithNotificationHook(receiver.handle)
	receiver.set_lock(False, timeout=timeout)
	print ("Pairing: turn your new device on (timing out in", timeout, "seconds).")

	# the lock-open notification may come slightly later, wait for it a bit
	from time import time as timestamp
	pairing_start = timestamp()
	patience = 5  # seconds

	while receiver.status.lock_open or timestamp() - pairing_start < patience:
		n = base.read(receiver.handle)
		if n:
			n = base.make_notification(*n)
			if n:
				receiver.handle.notifications_hook(n)

	if not (old_notification_flags & hidpp10.NOTIFICATION_FLAG.wireless):
		# only clear the flags if they weren't set before, otherwise a
		# concurrently running Solaar app might stop working properly
		hidpp10.set_notification_flags(receiver, old_notification_flags)

	if receiver.status.new_device:
		dev = receiver.status.new_device
		print ("Paired device %d: %s [%s:%s:%s]" % (dev.number, dev.name, dev.wpid, dev.codename, dev.serial))
	else:
		error = receiver.status[status.KEYS.ERROR] or 'no device detected?'
		_fail(error)
Ejemplo n.º 3
0
def run(receivers, args, find_receiver, _ignore):
    assert receivers

    if args.receiver:
        receiver_name = args.receiver.lower()
        receiver = find_receiver(receivers, receiver_name)
        if not receiver:
            raise Exception("no receiver found matching '%s'" % receiver_name)
    else:
        receiver = receivers[0]

    assert receiver
    receiver.status = _status.ReceiverStatus(receiver,
                                             lambda *args, **kwargs: None)

    # check if it's necessary to set the notification flags
    old_notification_flags = _hidpp10.get_notification_flags(receiver) or 0
    if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
        _hidpp10.set_notification_flags(
            receiver,
            old_notification_flags | _hidpp10.NOTIFICATION_FLAG.wireless)

    # get all current devices
    known_devices = [dev.number for dev in receiver]

    class _HandleWithNotificationHook(int):
        def notifications_hook(self, n):
            nonlocal known_devices
            assert n
            if n.devnumber == 0xFF:
                _notifications.process(receiver, n)
            elif n.sub_id == 0x41 and len(
                    n.data) == _base._SHORT_MESSAGE_SIZE - 4:
                kd, known_devices = known_devices, None  # only process one connection notification
                if kd is not None:
                    if n.devnumber not in kd:
                        receiver.status.new_device = receiver.register_new_device(
                            n.devnumber, n)
                    elif receiver.re_pairs:
                        del receiver[
                            n.
                            devnumber]  # get rid of information on device re-paired away
                        receiver.status.new_device = receiver.register_new_device(
                            n.devnumber, n)

    timeout = 30  # seconds
    receiver.handle = _HandleWithNotificationHook(receiver.handle)

    if receiver.receiver_kind == 'bolt':  # Bolt receivers require authentication to pair a device
        receiver.discover(timeout=timeout)
        print(
            'Bolt Pairing: long-press the pairing key or button on your device (timing out in',
            timeout, 'seconds).')
        pairing_start = _timestamp()
        patience = 5  # the discovering notification may come slightly later, so be patient
        while receiver.status.discovering or _timestamp(
        ) - pairing_start < patience:
            if receiver.status.device_address and receiver.status.device_authentication and receiver.status.device_name:
                break
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)
        address = receiver.status.device_address
        name = receiver.status.device_name
        authentication = receiver.status.device_authentication
        kind = receiver.status.device_kind
        print(f'Bolt Pairing: discovered {name}')
        receiver.pair_device(
            address=address,
            authentication=authentication,
            entropy=20 if kind == _hidpp10.DEVICE_KIND.keyboard else 10)
        pairing_start = _timestamp()
        patience = 5  # the discovering notification may come slightly later, so be patient
        while receiver.status.lock_open or _timestamp(
        ) - pairing_start < patience:
            if receiver.status.device_passkey:
                break
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)
        if authentication & 0x01:
            print(
                f'Bolt Pairing: type passkey {receiver.status.device_passkey} and then press the enter key'
            )
        else:
            passkey = f'{int(receiver.status.device_passkey):010b}'
            passkey = ', '.join(
                ['right' if bit == '1' else 'left' for bit in passkey])
            print(f'Bolt Pairing: press {passkey}')
            print('and then press left and right buttons simultaneously')
        while receiver.status.lock_open:
            n = _base.read(receiver.handle)
            n = _base.make_notification(*n) if n else None
            if n:
                receiver.handle.notifications_hook(n)

    else:
        receiver.set_lock(False, timeout=timeout)
        print('Pairing: turn your new device on (timing out in', timeout,
              'seconds).')
        pairing_start = _timestamp()
        patience = 5  # the lock-open notification may come slightly later, wait for it a bit
        while receiver.status.lock_open or _timestamp(
        ) - pairing_start < patience:
            n = _base.read(receiver.handle)
            if n:
                n = _base.make_notification(*n)
                if n:
                    receiver.handle.notifications_hook(n)

    if not (old_notification_flags & _hidpp10.NOTIFICATION_FLAG.wireless):
        # only clear the flags if they weren't set before, otherwise a
        # concurrently running Solaar app might stop working properly
        _hidpp10.set_notification_flags(receiver, old_notification_flags)

    if receiver.status.new_device:
        dev = receiver.status.new_device
        print('Paired device %d: %s (%s) [%s:%s]' %
              (dev.number, dev.name, dev.codename, dev.wpid, dev.serial))
    else:
        error = receiver.status.get(_status.KEYS.ERROR)
        if error:
            raise Exception('pairing failed: %s' % error)
        else:
            print('Paired device')  # this is better than an error