1
0
Эх сурвалжийг харах

Add cli interactive shell

zvecr 4 жил өмнө
parent
commit
cc851142fa

+ 74 - 28
lib/python/qmk/cli/xap/xap.py

@@ -1,5 +1,6 @@
 """Interactions with compatible XAP devices
 """
+import cmd
 import json
 import random
 import gzip
@@ -7,6 +8,14 @@ from platform import platform
 
 from milc import cli
 
+KEYCODE_MAP = {
+    # TODO: this should be data driven...
+    0x04: 'KC_A',
+    0x05: 'KC_B',
+    0x29: 'KC_ESCAPE',
+    0xF9: 'KC_MS_WH_UP',
+}
+
 
 def _is_xap_usage(x):
     return x['usage_page'] == 0xFF51 and x['usage'] == 0x0058
@@ -170,26 +179,12 @@ def xap_dump_keymap(device):
     keycode = _xap_transaction(device, 0x05, 0x02, b"\x00\x00\x00")
 
     keycode = int.from_bytes(keycode, "little")
-    keycode_map = {
-        # TODO: this should be data driven...
-        0x04: 'KC_A',
-        0x05: 'KC_B',
-        0x29: 'KC_ESCAPE',
-        0xF9: 'KC_MS_WH_UP',
-    }
-    print(f'keycode:{keycode_map.get(keycode, "unknown")}[{keycode}]')
+    print(f'keycode:{KEYCODE_MAP.get(keycode, "unknown")}[{keycode}]')
 
     # set encoder [layer:0, index:0, clockwise:0, keycode:KC_A]
     _xap_transaction(device, 0x05, 0x03, b"\x00\x00\x00\x04\00")
 
 
-def xap_doit():
-    print("xap_doit")
-    # Reboot
-    # _xap_transaction(device, 0x01, 0x07)
-    exit(1)
-
-
 def xap_broadcast_listen(device):
     try:
         cli.log.info("Listening for XAP broadcasts...")
@@ -208,9 +203,67 @@ def xap_unlock(device):
     _xap_transaction(device, 0x00, 0x04)
 
 
+class XAPShell(cmd.Cmd):
+    intro = 'Welcome to the XAP shell.  Type help or ? to list commands.\n'
+    prompt = 'Ψ> '
+
+    def __init__(self, device):
+        cmd.Cmd.__init__(self)
+        self.device = device
+
+    def do_about(self, arg):
+        """Prints out the current version of QMK with a build date
+        """
+        data = _query_device(self.device)
+        print(data)
+
+    def do_unlock(self, arg):
+        """Initiate secure unlock
+        """
+        xap_unlock(self.device)
+        print("Done")
+
+    def do_listen(self, arg):
+        """Log out XAP broadcast messages
+        """
+        xap_broadcast_listen(self.device)
+
+    def do_keycode(self, arg):
+        """Prints out the keycode value of a certain layer, row, and column
+        """
+        data = bytes(map(int, arg.split()))
+        if len(data) != 3:
+            cli.log.error("Invalid args")
+            return
+
+        keycode = _xap_transaction(self.device, 0x04, 0x02, data)
+        keycode = int.from_bytes(keycode, "little")
+        print(f'keycode:{KEYCODE_MAP.get(keycode, "unknown")}[{keycode}]')
+
+    def do_exit(self, line):
+        """Quit shell
+        """
+        return True
+
+    def do_EOF(self, line):  # noqa: N802
+        """Quit shell (ctrl+D)
+        """
+        return True
+
+    def loop(self):
+        """Wrapper for cmdloop that handles ctrl+C
+        """
+        try:
+            self.cmdloop()
+            print('')
+        except KeyboardInterrupt:
+            print('^C')
+        return False
+
+
 @cli.argument('-d', '--device', help='device to select - uses format <pid>:<vid>.')
-@cli.argument('-i', '--index', default=0, help='device index to select.')
 @cli.argument('-l', '--list', arg_only=True, action='store_true', help='List available devices.')
+@cli.argument('-i', '--interactive', arg_only=True, action='store_true', help='Start interactive shell.')
 @cli.argument('action', nargs='?', arg_only=True)
 @cli.subcommand('Acquire debugging information from usb XAP devices.', hidden=False if cli.config.user.developer else True)
 def xap(cli):
@@ -233,16 +286,9 @@ def xap(cli):
     device = hid.Device(path=dev['path'])
     cli.log.info("Connected to:%04x:%04x %s %s", dev['vendor_id'], dev['product_id'], dev['manufacturer_string'], dev['product_string'])
 
-    # xap_doit(device)
-    if cli.args.action == 'unlock':
-        xap_unlock(device)
-        cli.log.info("Done")
-
-    elif cli.args.action == 'dump':
-        xap_dump_keymap(device)
-
-    elif cli.args.action == 'listen':
-        xap_broadcast_listen(device)
+    # shell?
+    if cli.args.interactive:
+        XAPShell(device).loop()
+        return True
 
-    elif not cli.args.action:
-        xap_broadcast_listen(device)
+    XAPShell(device).onecmd(cli.args.action or 'listen')