-
Notifications
You must be signed in to change notification settings - Fork 174
/
vial_device.py
105 lines (80 loc) · 2.77 KB
/
vial_device.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# SPDX-License-Identifier: GPL-2.0-or-later
import time
from hidproxy import hid
from protocol.keyboard_comm import Keyboard
from protocol.dummy_keyboard import DummyKeyboard
from util import MSG_LEN, pad_for_vibl
class VialDevice:
def __init__(self, dev):
self.desc = dev
self.dev = None
self.sideload = False
self.via_stack = False
def open(self, override_json=None):
self.dev = hid.device()
for x in range(10):
try:
self.dev.open_path(self.desc["path"])
return
except OSError:
time.sleep(1)
raise RuntimeError("unable to open the device")
def send(self, data):
# add 00 at start for hidapi report id
return self.dev.write(b"\x00" + data)
def recv(self, length, timeout_ms=0):
return bytes(self.dev.read(length, timeout_ms=timeout_ms))
def close(self):
self.dev.close()
class VialKeyboard(VialDevice):
def __init__(self, dev, sideload=False, via_stack=False):
super().__init__(dev)
self.via_id = str(dev["vendor_id"] * 65536 + dev["product_id"])
self.sideload = sideload
self.via_stack = via_stack
self.keyboard = None
def open(self, override_json=None):
super().open(override_json)
self.keyboard = Keyboard(self.dev)
self.keyboard.reload(override_json)
def title(self):
s = "{} {}".format(self.desc["manufacturer_string"], self.desc["product_string"]).strip()
if self.sideload:
s += " [sideload]"
elif self.via_stack:
s += " [VIA]"
return s
def get_uid(self):
try:
super().open()
except OSError:
return b""
self.send(b"\xFE\x00" + b"\x00" * 30)
data = self.recv(MSG_LEN, timeout_ms=500)
super().close()
return data[4:12]
class VialBootloader(VialDevice):
def title(self):
return "Vial Bootloader [{:04X}:{:04X}]".format(self.desc["vendor_id"], self.desc["product_id"])
def get_uid(self):
try:
super().open()
except OSError:
return b""
self.send(pad_for_vibl(b"VC\x01"))
data = self.recv(8, timeout_ms=500)
super().close()
return data
class VialDummyKeyboard(VialKeyboard):
def __init__(self):
self.sideload = True
self.desc = {"path": "/dummy/keyboard"}
def open(self, override_json=None):
self.keyboard = DummyKeyboard(None, usb_send=self.raise_usb_send)
self.keyboard.reload(override_json)
def title(self):
return "[Dummy Keyboard]"
def raise_usb_send(self, *args, **kwargs):
raise RuntimeError("usb_send - should not be called!")
def close(self):
pass