oep-client-python 0.0.33__py3-none-any.whl → 0.0.34__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- oep_client/__init__.py +1 -1
- oep_client/__main__.py +8 -0
- oep_client/config.py +23 -0
- oep_client/endpoint.py +48 -7
- oep_client/registry.py +6 -6
- oep_client/riscv.py +14 -1
- oep_client/virtual_attach_model.py +3 -2
- oep_client/virtual_bench.py +3 -1
- oep_client/virtual_oep_declaration_model.py +3 -3
- oep_client/virtual_registered_ops_model.py +1 -1
- oep_client/virtual_scan_options_model.py +1 -1
- {oep_client_python-0.0.33.dist-info → oep_client_python-0.0.34.dist-info}/METADATA +1 -1
- {oep_client_python-0.0.33.dist-info → oep_client_python-0.0.34.dist-info}/RECORD +16 -16
- {oep_client_python-0.0.33.dist-info → oep_client_python-0.0.34.dist-info}/WHEEL +0 -0
- {oep_client_python-0.0.33.dist-info → oep_client_python-0.0.34.dist-info}/entry_points.txt +0 -0
- {oep_client_python-0.0.33.dist-info → oep_client_python-0.0.34.dist-info}/licenses/LICENSE +0 -0
oep_client/__init__.py
CHANGED
oep_client/__main__.py
CHANGED
|
@@ -359,6 +359,12 @@ def _config_parser(sub) -> None:
|
|
|
359
359
|
rest.add_argument("channel", type=int, help="the port's SWCLK channel")
|
|
360
360
|
rest.add_argument("mode", choices=sorted(config.REST_MODE))
|
|
361
361
|
rest.add_argument("--save", action="store_true")
|
|
362
|
+
hold = cs.add_parser("wire-hold", help="whether a debug wire's lines stay held at their rest after a close "
|
|
363
|
+
"(on, the default) or go free at once (off; debug §2)")
|
|
364
|
+
hold.add_argument("probe")
|
|
365
|
+
hold.add_argument("channel", type=int, help="the port's SWDIO channel")
|
|
366
|
+
hold.add_argument("mode", choices=sorted(config.HOLD_MODE))
|
|
367
|
+
hold.add_argument("--save", action="store_true")
|
|
362
368
|
dis = cs.add_parser("disable", help="channels the probe never drives or sets up (not on this board)")
|
|
363
369
|
dis.add_argument("probe")
|
|
364
370
|
dis.add_argument("channels", type=int, nargs="+")
|
|
@@ -441,6 +447,8 @@ def _config(args) -> int:
|
|
|
441
447
|
_change(hst, cfg, [config.Label(channel=args.channel, text=args.text)], args.save)
|
|
442
448
|
elif args.action == "idle":
|
|
443
449
|
_change(hst, cfg, [config.Idle(channel=args.channel, mode=args.mode)], args.save)
|
|
450
|
+
elif args.action == "wire-hold":
|
|
451
|
+
_change(hst, cfg, [config.WireHold(channel=args.channel, mode=args.mode)], args.save)
|
|
444
452
|
elif args.action == "rvswd-rest":
|
|
445
453
|
_change(hst, cfg, [config.RvswdRest(channel=args.channel, mode=args.mode)], args.save)
|
|
446
454
|
elif args.action == "disable":
|
oep_client/config.py
CHANGED
|
@@ -37,6 +37,7 @@ ITEM = {k.replace("-", "_"): i + 1 for i, k in enumerate(NAMES)}
|
|
|
37
37
|
DESCRIBE = _CFG.tlv["describe"]
|
|
38
38
|
IDLE = {k.replace("_", "-"): v for k, v in _CFG.enum["idle_mode"].items()}
|
|
39
39
|
REST_MODE = dict(_CFG.enum["rvswd_rest_mode"]) # rvswd-rest: auto / high / low (debug §3.1)
|
|
40
|
+
HOLD_MODE = dict(_CFG.enum["wire_hold_mode"]) # wire-hold: off / on (debug §2)
|
|
40
41
|
STORAGE_STATE = {v: k for k, v in _CFG.enum["storage_state"].items()}
|
|
41
42
|
UNREADABLE = {v: k for k, v in _CFG.enum["storage_unreadable"].items()}
|
|
42
43
|
FORM = _CFG.enum["setting_form"]
|
|
@@ -162,6 +163,26 @@ class RvswdRest:
|
|
|
162
163
|
return bytes([REST_MODE[self.mode]])
|
|
163
164
|
|
|
164
165
|
|
|
166
|
+
@dataclass
|
|
167
|
+
class WireHold:
|
|
168
|
+
"""Whether a debug wire's lines on the port whose SWDIO is `channel` stay held at their rest after its connection
|
|
169
|
+
closes (debug §2): on - also with no item - or off (back to the free state at once)."""
|
|
170
|
+
channel: int
|
|
171
|
+
mode: str = "on"
|
|
172
|
+
NAME = "wire-hold"
|
|
173
|
+
|
|
174
|
+
def key(self) -> int:
|
|
175
|
+
return self.channel
|
|
176
|
+
|
|
177
|
+
def value(self) -> bytes:
|
|
178
|
+
return struct.pack("<H", self.key()) + self.data()
|
|
179
|
+
|
|
180
|
+
def data(self) -> bytes:
|
|
181
|
+
if self.mode not in HOLD_MODE:
|
|
182
|
+
raise ValueError(f"wire-hold mode {self.mode!r}: one of {', '.join(HOLD_MODE)}")
|
|
183
|
+
return bytes([HOLD_MODE[self.mode]])
|
|
184
|
+
|
|
185
|
+
|
|
165
186
|
@dataclass(kw_only=True)
|
|
166
187
|
class ConsolePassthrough:
|
|
167
188
|
"""Serial port `port` carries the target's debug console - read by the probe itself over `wire_fn` on (swdio, swclk)
|
|
@@ -315,6 +336,8 @@ def decode(name: str, key: int, d: bytes, setting: Setting | None = None, netifs
|
|
|
315
336
|
try:
|
|
316
337
|
if name == "label":
|
|
317
338
|
return Label(channel=key, text=d.decode("utf-8", "replace"))
|
|
339
|
+
if name == "wire-hold" and len(d) == 1 and d[0] in HOLD_MODE.values():
|
|
340
|
+
return WireHold(channel=key, mode={v: k for k, v in HOLD_MODE.items()}[d[0]])
|
|
318
341
|
if name == "rvswd-rest" and len(d) == 1 and d[0] in REST_MODE.values():
|
|
319
342
|
return RvswdRest(channel=key, mode={v: k for k, v in REST_MODE.items()}[d[0]])
|
|
320
343
|
if name == "idle" and len(d) == 1:
|
oep_client/endpoint.py
CHANGED
|
@@ -117,7 +117,8 @@ RESET_MODE = _RV.enum["reset_mode"]
|
|
|
117
117
|
READ_FROM = reg.COMMON.enum["read_from"] # position, oldest, now, last_mark (common §1.2)
|
|
118
118
|
STEP_LEFT = _RV.tlv["step_answer"]["step_left"] # step's answer: the hart could not be halted again (§4.2)
|
|
119
119
|
ITEM = {k.replace("-", "_"): k for k in cfgmod.NAMES} # the standard items by name (probe.config §1, core §7.7)
|
|
120
|
-
CHANNEL_ITEMS = (ITEM["label"], ITEM["idle"], ITEM["disable"], ITEM["rvswd_rest"]) # keyed by a channel
|
|
120
|
+
CHANNEL_ITEMS = (ITEM["label"], ITEM["idle"], ITEM["disable"], ITEM["rvswd_rest"], ITEM["wire_hold"]) # keyed by a channel
|
|
121
|
+
HOLD_MODE = cfgmod.HOLD_MODE
|
|
121
122
|
REST_MODE = cfgmod.REST_MODE
|
|
122
123
|
IDLE_MODE = _CFG.enum["idle_mode"]
|
|
123
124
|
CFG_DESCRIBE = cfgmod.DESCRIBE
|
|
@@ -327,6 +328,7 @@ class VirtualTarget:
|
|
|
327
328
|
havereset: bool = True
|
|
328
329
|
resume_misses: int = 0 # resumes that do not take (status state, dpc unchanged)
|
|
329
330
|
present: bool = True # something answers on this pin pair (scan, attach)
|
|
331
|
+
needs_drive: bool = False # loses its halt once the probe stops driving the line (a CH32L103)
|
|
330
332
|
target_id: int | None = None # the dmi_7f target_id attach reports (None: none)
|
|
331
333
|
# run(pc, regs) -> (stopped, dpc, elapsed_us); default: halts 0x10 past the start
|
|
332
334
|
run_hook: Callable | None = None
|
|
@@ -554,7 +556,7 @@ class Connection:
|
|
|
554
556
|
|
|
555
557
|
|
|
556
558
|
ITEM_SIZES = {ITEM["idle"]: 1, ITEM["disable"]: 0, ITEM["passthrough"]: 9, # the data of a fixed length (probe.config §1)
|
|
557
|
-
ITEM["console_passthrough"]: 13, ITEM["ipv4"]: 14, ITEM["rvswd_rest"]: 1}
|
|
559
|
+
ITEM["console_passthrough"]: 13, ITEM["ipv4"]: 14, ITEM["rvswd_rest"]: 1, ITEM["wire_hold"]: 1}
|
|
558
560
|
PASSTHROUGHS = (ITEM["passthrough"], ITEM["console_passthrough"])
|
|
559
561
|
|
|
560
562
|
|
|
@@ -784,6 +786,7 @@ class Endpoint:
|
|
|
784
786
|
self.session_ports: set[int] = set() # the transports the lock holder's requests came on (probe.config §1.1)
|
|
785
787
|
self.passthrough_out: dict[int, bytearray] = {} # a serial port's pass-through bytes not sent yet
|
|
786
788
|
self.resident: dict[int, bool] = {} # console_passthrough's own connection per port: attached (config §1.2)
|
|
789
|
+
self.holds: dict[tuple[int, tuple[int, int]], int] = {} # (wire fn, pair) -> rest: lines held after a close (debug §2)
|
|
787
790
|
self.last: int | None = None # S: the id that holds or last held the lock (the resend table's, §5.2)
|
|
788
791
|
self.owner: bytes | None = None # the holder's owner, while the lock is held (core §6.4)
|
|
789
792
|
self.lease_ms = self.lease_default_ms
|
|
@@ -1561,7 +1564,7 @@ class Endpoint:
|
|
|
1561
1564
|
connections closed (an unknown `cid`: none)."""
|
|
1562
1565
|
gone = [c for c in (list(self.conns) if cid is None else [cid]) if c in self.conns]
|
|
1563
1566
|
for c in gone:
|
|
1564
|
-
self._close_conn(c)
|
|
1567
|
+
self._close_conn(c, lost=True)
|
|
1565
1568
|
return gone
|
|
1566
1569
|
|
|
1567
1570
|
# ---- core -----------------------------------------------------------------------------------
|
|
@@ -2334,6 +2337,11 @@ class Endpoint:
|
|
|
2334
2337
|
raise wrong_kind() # another wire's connection
|
|
2335
2338
|
self._close_conn(cid)
|
|
2336
2339
|
return m.COMPLETED, m.SUCCESS, b""
|
|
2340
|
+
if op == O["holds"]: # lock-free, paged by first (debug §2.2)
|
|
2341
|
+
first = t.take("B")
|
|
2342
|
+
t.tail()
|
|
2343
|
+
rows = [struct.pack("<HHB", *pair, rest) for pair, rest in self.held_ports(fn)]
|
|
2344
|
+
return m.COMPLETED, m.SUCCESS, self._paged(rows, first)
|
|
2337
2345
|
if op == O["connections"]: # lock-free, paged by first (debug §2.1)
|
|
2338
2346
|
first = t.take("B")
|
|
2339
2347
|
t.tail()
|
|
@@ -2409,14 +2417,45 @@ class Endpoint:
|
|
|
2409
2417
|
self.conns[cid] = Connection(fn, pair, self._order, speed, tid)
|
|
2410
2418
|
return cid
|
|
2411
2419
|
|
|
2412
|
-
def _close_conn(self, cid: int) -> None:
|
|
2413
|
-
"""The connection goes, its console streams first (common §2)
|
|
2420
|
+
def _close_conn(self, cid: int, lost: bool = False) -> None:
|
|
2421
|
+
"""The connection goes, its console streams first (common §2). Its lines stay held at its rest unless the line
|
|
2422
|
+
was lost, the port's wire-hold is off or a pin has an idle / disable item (debug §2); else to their idle state,
|
|
2423
|
+
and a target that needs the drive loses its halt."""
|
|
2414
2424
|
for sid in [k for k, st in self.streams.items() if st.conn == cid]:
|
|
2415
2425
|
self._close_stream(sid)
|
|
2416
2426
|
gone = self.conns.pop(cid, None)
|
|
2417
2427
|
self.resources.pop(cid, None)
|
|
2418
|
-
if gone is
|
|
2419
|
-
|
|
2428
|
+
if gone is None:
|
|
2429
|
+
return
|
|
2430
|
+
if not lost and self._may_hold(gone.pair):
|
|
2431
|
+
self.holds[(gone.fn, gone.pair)] = gone.idle_clock if self.names[gone.fn] == "oep.wire.rvswd" else 0
|
|
2432
|
+
return
|
|
2433
|
+
self._park(gone.pair)
|
|
2434
|
+
tg = self.targets.get((gone.fn, gone.pair))
|
|
2435
|
+
if tg is not None and tg.needs_drive:
|
|
2436
|
+
tg.halted = False # its debug module dropped the link: the hart runs
|
|
2437
|
+
|
|
2438
|
+
def _may_hold(self, pair: tuple[int, int]) -> bool:
|
|
2439
|
+
"""debug §2: wire-hold on (no item: on) for the port's SWDIO, and no idle / disable item on its pins."""
|
|
2440
|
+
mode = self.config.get((ITEM["wire_hold"], pair[0]), bytes([HOLD_MODE["on"]]))[0]
|
|
2441
|
+
pins = [p for p in pair if p != 0xFFFF]
|
|
2442
|
+
return (mode == HOLD_MODE["on"] and not any((ITEM["idle"], p) in self.config for p in pins)
|
|
2443
|
+
and not any(p in self.disabled for p in pins))
|
|
2444
|
+
|
|
2445
|
+
def held_ports(self, fn: int) -> list[tuple[tuple[int, int], int]]:
|
|
2446
|
+
"""The ports wire `fn` holds now (debug §2.2): a hold ends once its pins are taken (a plan, a connection), its
|
|
2447
|
+
wire-hold goes off or an idle / disable item lands on them; an ended hold's pins go to their free state."""
|
|
2448
|
+
busy = {a[2] for a in self.plan if not self._listens(a[0])} | {p for c in self.conns.values() for p in c.pair}
|
|
2449
|
+
for key in list(self.holds):
|
|
2450
|
+
hfn, pair = key
|
|
2451
|
+
if any(p in busy for p in pair if p != 0xFFFF) or not self._may_hold(pair):
|
|
2452
|
+
del self.holds[key]
|
|
2453
|
+
if not any(p in busy for p in pair if p != 0xFFFF):
|
|
2454
|
+
self._park(pair)
|
|
2455
|
+
tg = self.targets.get(key)
|
|
2456
|
+
if tg is not None and tg.needs_drive:
|
|
2457
|
+
tg.halted = False
|
|
2458
|
+
return [(pair, rest) for (hfn, pair), rest in self.holds.items() if hfn == fn]
|
|
2420
2459
|
|
|
2421
2460
|
def _cleanup_failed(self, cid: int, done: int, payload: bytes) -> tuple[int, int, bytes]:
|
|
2422
2461
|
"""A block op whose restore of DATA0 / DATA1 failed: partial when done > 0 (all words included), else failed,
|
|
@@ -3301,6 +3340,8 @@ class Endpoint:
|
|
|
3301
3340
|
return True
|
|
3302
3341
|
if name == ITEM["rvswd_rest"] and d[0] not in REST_MODE.values():
|
|
3303
3342
|
return True # a mode the definition leaves unused (§1)
|
|
3343
|
+
if name == ITEM["wire_hold"] and d[0] not in HOLD_MODE.values():
|
|
3344
|
+
return True
|
|
3304
3345
|
return False
|
|
3305
3346
|
|
|
3306
3347
|
def _shown(self, name: str, d: bytes) -> bytes:
|
oep_client/registry.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
from types import SimpleNamespace as _NS
|
|
5
5
|
|
|
6
|
-
REGISTRY_HASH = "
|
|
6
|
+
REGISTRY_HASH = "32b9f952338089a5"
|
|
7
7
|
SCHEMA = 1
|
|
8
8
|
PROTOCOL_REVISION = 1
|
|
9
9
|
CONFIRM_REQUEST_MAGIC = 'OEP?'
|
|
@@ -41,15 +41,15 @@ PROBE_LINK = _NS(name="oep.probe.link", revision=1, target=None, op={"source": 0
|
|
|
41
41
|
tlv={}, event={}, enum={"port_speed_step": {"try": 0x00, "commit": 0x01, "revert": 0x02}, "port_state": {"boot": 0x00, "trying": 0x01, "committed": 0x02, "recovery_pending": 0x03}}, own={},
|
|
42
42
|
line_names={}, names={})
|
|
43
43
|
INTERFACES["oep.probe.link"] = PROBE_LINK
|
|
44
|
-
WIRE_RVSWD = _NS(name="oep.wire.rvswd", revision=1, target="RISC-V targets whose debug module is reached over the two-wire RVSWD line", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13}, lock_free={0x13},
|
|
44
|
+
WIRE_RVSWD = _NS(name="oep.wire.rvswd", revision=1, target="RISC-V targets whose debug module is reached over the two-wire RVSWD line", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13, "holds": 0x14}, lock_free={0x13, 0x14},
|
|
45
45
|
tlv={"describe": {"max_connections": 0x40}, "scan": {"max_speed": 0x01, "idle_clock": 0x03}, "attach": {"idle_clock": 0x03, "reset": 0x04}, "attach_answer": {"target_id": 0x01, "dpc": 0x02, "idle_clock": 0x03}, "connections_answer": {"idle_clock": 0x02}, "unavailable_payload": {"index": 0x40}, "unsupported_payload": {"index": 0x40}}, event={}, enum={"scan_kind": {"riscv_dm": 0x01}, "attach_flags": {"havereset_acked": 0x01, "halted": 0x08}, "features": {"attach_halt": 0x01}, "attach_method": {"run": 0x00, "halt": 0x01}, "pin_role": {"swdio": 0x01, "swclk": 0x02, "reset": 0x03}, "idle_clock": {"high": 0x00, "low": 0x01}, "target_id_family": {"shift": 0x14}, "idle_low_family": {"ch32l103": 0x103}}, own={},
|
|
46
46
|
line_names={}, names={})
|
|
47
47
|
INTERFACES["oep.wire.rvswd"] = WIRE_RVSWD
|
|
48
|
-
WIRE_SWIO = _NS(name="oep.wire.swio", revision=1, target="RISC-V targets whose debug module is reached over the one-wire SWIO line", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13}, lock_free={0x13},
|
|
48
|
+
WIRE_SWIO = _NS(name="oep.wire.swio", revision=1, target="RISC-V targets whose debug module is reached over the one-wire SWIO line", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13, "holds": 0x14}, lock_free={0x13, 0x14},
|
|
49
49
|
tlv={"describe": {"max_connections": 0x40}, "scan": {"max_speed": 0x01}, "attach": {"reset": 0x04}, "attach_answer": {"target_id": 0x01, "dpc": 0x02}, "unavailable_payload": {"index": 0x40}, "unsupported_payload": {"index": 0x40}}, event={}, enum={"scan_kind": {"riscv_dm": 0x01}, "attach_flags": {"havereset_acked": 0x01, "halted": 0x08}, "features": {"attach_halt": 0x01}, "attach_method": {"run": 0x00, "halt": 0x01}, "pin_role": {"swdio": 0x01, "reset": 0x03}}, own={},
|
|
50
50
|
line_names={}, names={})
|
|
51
51
|
INTERFACES["oep.wire.swio"] = WIRE_SWIO
|
|
52
|
-
WIRE_SWD = _NS(name="oep.wire.swd", revision=1, target="ARM targets with an SWD debug port", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13}, lock_free={0x13},
|
|
52
|
+
WIRE_SWD = _NS(name="oep.wire.swd", revision=1, target="ARM targets with an SWD debug port", op={"scan": 0x10, "attach": 0x11, "detach": 0x12, "connections": 0x13, "holds": 0x14}, lock_free={0x13, 0x14},
|
|
53
53
|
tlv={"describe": {"max_connections": 0x40}, "scan": {"max_speed": 0x01, "targetsel": 0x02}, "attach": {"targetsel": 0x02, "reset": 0x04}, "attach_answer": {"target_id": 0x01}, "connections_answer": {"selected_target": 0x01}, "unavailable_payload": {"index": 0x40}, "unsupported_payload": {"index": 0x40}}, event={}, enum={"scan_kind": {"arm_adi": 0x02}, "attach_flags": {"dormant_woken": 0x04}, "features": {}, "attach_method": {"run": 0x00}, "pin_role": {"swdio": 0x01, "swclk": 0x02, "reset": 0x03}}, own={},
|
|
54
54
|
line_names={}, names={})
|
|
55
55
|
INTERFACES["oep.wire.swd"] = WIRE_SWD
|
|
@@ -94,6 +94,6 @@ FIXTURE_CAPTURE_GROUP = _NS(name="oep.fixture.capture-group", revision=1, target
|
|
|
94
94
|
line_names={}, names={})
|
|
95
95
|
INTERFACES["oep.fixture.capture-group"] = FIXTURE_CAPTURE_GROUP
|
|
96
96
|
PROBE_CONFIG = _NS(name="oep.probe.config", revision=1, target=None, op={"get": 0x10, "set": 0x11, "save": 0x12, "erase": 0x13, "unset": 0x14, "state": 0x15, "network": 0x16}, lock_free={0x10, 0x15, 0x16},
|
|
97
|
-
tlv={"describe": {"storage": 0x40, "setting": 0x41, "netif": 0x42}}, event={}, enum={"idle_mode": {"hi_z": 0x00, "pull_up": 0x01, "pull_down": 0x02, "output_low": 0x03, "output_high": 0x04}, "rvswd_rest_mode": {"auto": 0x00, "high": 0x01, "low": 0x02}, "ipv4_mode": {"dhcp": 0x00, "static": 0x01}, "network_state": {"off": 0x00, "connecting": 0x01, "up": 0x02, "waiting": 0x03}, "network_reason": {"none": 0x00, "not_found": 0x01, "auth": 0x02, "no_address": 0x03, "other": 0x04}, "setting_form": {"named": 0x00, "bytes": 0x01, "text": 0x02, "u32": 0x03, "ipv4": 0x04, "bool": 0x05}, "setting_flag": {"secret": 0x01, "restart": 0x02}, "storage_state": {"none": 0x00, "applied": 0x01, "unreadable": 0x02, "partial": 0x03}, "storage_unreadable": {"none": 0x00, "form": 0x01, "item": 0x02, "capacity": 0x03}}, own={},
|
|
98
|
-
line_names={'swdio': 'the debug data line (2 wires: rvswd, swd) (Host only)', 'swclk': 'the debug clock line (2 wires: rvswd, swd) (Host only)', 'swio': 'the one debug wire (swio) (Host only)', 'rx': 'the fixture UART receive, wired to the target TX (Host only)', 'tx': 'the fixture UART transmit, wired to the target RX (Host only)', 'nrst': 'the target reset line (Host only)', 'power_hi': 'target power on when high (Host only)', 'power_lo': 'target power on when low (Host only)'}, names={'setting': {'label': 'key channel; text 1-32 bytes', 'idle': 'key channel; mode(u8)', 'disable': 'key channel; no data', 'passthrough': 'key port; fn(u16) rx(u16) baud(u32) format(u8)', 'console-passthrough': 'key port; wire_fn(u16) swdio(u16) swclk(u16) max_speed(u32) console_fn(u16) mechanism(u8)', 'wifi': 'key entry; ssid_len(u8) ssid pass_len(u8) passphrase; passphrase write-only', 'ipv4': 'key netif; mode(u8) address(4) prefix(u8) gateway(4) dns(4)', 'rvswd-rest': "key channel (the port's SWCLK); mode(u8): rvswd_rest_mode"}, 'netif': {'wifi': 'Wi-Fi station', 'ethernet': 'wired Ethernet'}})
|
|
97
|
+
tlv={"describe": {"storage": 0x40, "setting": 0x41, "netif": 0x42}}, event={}, enum={"idle_mode": {"hi_z": 0x00, "pull_up": 0x01, "pull_down": 0x02, "output_low": 0x03, "output_high": 0x04}, "rvswd_rest_mode": {"auto": 0x00, "high": 0x01, "low": 0x02}, "wire_hold_mode": {"off": 0x00, "on": 0x01}, "ipv4_mode": {"dhcp": 0x00, "static": 0x01}, "network_state": {"off": 0x00, "connecting": 0x01, "up": 0x02, "waiting": 0x03}, "network_reason": {"none": 0x00, "not_found": 0x01, "auth": 0x02, "no_address": 0x03, "other": 0x04}, "setting_form": {"named": 0x00, "bytes": 0x01, "text": 0x02, "u32": 0x03, "ipv4": 0x04, "bool": 0x05}, "setting_flag": {"secret": 0x01, "restart": 0x02}, "storage_state": {"none": 0x00, "applied": 0x01, "unreadable": 0x02, "partial": 0x03}, "storage_unreadable": {"none": 0x00, "form": 0x01, "item": 0x02, "capacity": 0x03}}, own={},
|
|
98
|
+
line_names={'swdio': 'the debug data line (2 wires: rvswd, swd) (Host only)', 'swclk': 'the debug clock line (2 wires: rvswd, swd) (Host only)', 'swio': 'the one debug wire (swio) (Host only)', 'rx': 'the fixture UART receive, wired to the target TX (Host only)', 'tx': 'the fixture UART transmit, wired to the target RX (Host only)', 'nrst': 'the target reset line (Host only)', 'power_hi': 'target power on when high (Host only)', 'power_lo': 'target power on when low (Host only)'}, names={'setting': {'label': 'key channel; text 1-32 bytes', 'idle': 'key channel; mode(u8)', 'disable': 'key channel; no data', 'passthrough': 'key port; fn(u16) rx(u16) baud(u32) format(u8)', 'console-passthrough': 'key port; wire_fn(u16) swdio(u16) swclk(u16) max_speed(u32) console_fn(u16) mechanism(u8)', 'wifi': 'key entry; ssid_len(u8) ssid pass_len(u8) passphrase; passphrase write-only', 'ipv4': 'key netif; mode(u8) address(4) prefix(u8) gateway(4) dns(4)', 'rvswd-rest': "key channel (the port's SWCLK); mode(u8): rvswd_rest_mode", 'wire-hold': "key channel (the port's SWDIO); mode(u8): wire_hold_mode"}, 'netif': {'wifi': 'Wi-Fi station', 'ethernet': 'wired Ethernet'}})
|
|
99
99
|
INTERFACES["oep.probe.config"] = PROBE_CONFIG
|
oep_client/riscv.py
CHANGED
|
@@ -188,7 +188,7 @@ class WireBase(Interface):
|
|
|
188
188
|
"""oep.wire.<link>: scan / attach / detach / connections (oep-if-debug §0-§2). The shared part; each link's attach
|
|
189
189
|
takes its own arguments. A failed scan, attach or detach is completed failed with `status(u8) [TLV]` (common §3).
|
|
190
190
|
attach names its pins in the fixed part (§1): `pins` None takes the wire's one candidate pair (candidate_pairs)."""
|
|
191
|
-
SCAN, ATTACH, DETACH, CONNECTIONS = (_WIRE.op[k] for k in ("scan", "attach", "detach", "connections"))
|
|
191
|
+
SCAN, ATTACH, DETACH, CONNECTIONS, HOLDS = (_WIRE.op[k] for k in ("scan", "attach", "detach", "connections", "holds"))
|
|
192
192
|
REVISION = 1
|
|
193
193
|
TAG_RESET = _WIRE.tlv["attach"]["reset"] # channel(u16) hold_ms(u16), critical: attach under reset (§3)
|
|
194
194
|
TAG_SCAN_MAX_SPEED = _WIRE.tlv["scan"]["max_speed"]
|
|
@@ -299,6 +299,19 @@ class WireBase(Interface):
|
|
|
299
299
|
"""Close the connection and its streams (oep-if-debug §2)."""
|
|
300
300
|
self._call(self.DETACH, struct.pack("<I", conn))
|
|
301
301
|
|
|
302
|
+
def holds(self) -> list[tuple[tuple[int, int], int]]:
|
|
303
|
+
"""The ports this wire holds at their rest after a close (oep-if-debug §2.2, lock-free; paged like connections):
|
|
304
|
+
[((swdio, swclk), rest)] - rest: rvswd's idle_clock value (0 high, 1 low), 0 on other wires. Not connections."""
|
|
305
|
+
out: list[tuple[tuple[int, int], int]] = []
|
|
306
|
+
while True:
|
|
307
|
+
rd = m.Reader(self._call(self.HOLDS, bytes([len(out)]), locked=False).payload)
|
|
308
|
+
more, count = rd.take("BB")
|
|
309
|
+
page = [((d, c), r) for d, c, r in (rd.take("HHB") for _ in range(count))]
|
|
310
|
+
rd.tail()
|
|
311
|
+
out += page
|
|
312
|
+
if not more or not count or len(out) > 0xFF:
|
|
313
|
+
return out
|
|
314
|
+
|
|
302
315
|
def connections(self) -> list["ConnectionInfo"]:
|
|
303
316
|
"""The wire's live connections, in the order they were made (oep-if-debug §2.1, lock-free; paged: the request
|
|
304
317
|
is first(u8), the answer more count entries [TLV], followed until more is 0). swd's selected_target TLVs
|
|
@@ -36,7 +36,7 @@ class Attachments(Dependencies):
|
|
|
36
36
|
return bytes(page)
|
|
37
37
|
def describe(self,fn):
|
|
38
38
|
if fn==4:return (tlv(DC['ops'],pack_ops(set(COP.values()))),*(tlv(CD['mechanism'],name.encode()) for name in self.mechanisms))
|
|
39
|
-
rows=[tlv(DC['ops'],pack_ops({WOP['attach'],WOP['detach'],WOP['connections']})),tlv(WT['describe']['max_connections'],b'\x02'),tlv(DC['min_clock_hz'],struct.pack('<I',1000))]
|
|
39
|
+
rows=[tlv(DC['ops'],pack_ops({WOP['attach'],WOP['detach'],WOP['connections'],WOP['holds']})),tlv(WT['describe']['max_connections'],b'\x02'),tlv(DC['min_clock_hz'],struct.pack('<I',1000))]
|
|
40
40
|
for index,pair in enumerate(self.pairs[fn]):
|
|
41
41
|
members=[(WE['pin_role']['swdio'],pair[0])] if fn==2 else [(WE['pin_role']['swdio'],pair[0]),(WE['pin_role']['swclk'],pair[1])]
|
|
42
42
|
rows.append(tlv(DC['channel_group'],bytes((index,len(members)))+b''.join(struct.pack('<BH',*row) for row in members)))
|
|
@@ -79,6 +79,7 @@ class Attachments(Dependencies):
|
|
|
79
79
|
def dispatch_request(self,fn,op,payload,tags):
|
|
80
80
|
if fn<=3:
|
|
81
81
|
if op==WOP['connections']:return self.connection_page(fn,payload[0])
|
|
82
|
+
if op==WOP['holds']:return b'\0\0'+extension() # no port held in this model (debug §2.2)
|
|
82
83
|
if op==WOP['detach']:
|
|
83
84
|
rid=struct.unpack('<I',payload)[0];self.resource(rid,'connection')
|
|
84
85
|
if self.connections[rid]['fn']!=fn:raise Reject(R['unavailable'],cause('wrong_state'))
|
|
@@ -131,7 +132,7 @@ class AttachModel(DependencyModel):
|
|
|
131
132
|
if len(request)>=6 and struct.unpack_from('<H',request,3)[0]==4:
|
|
132
133
|
e.fixed={COP['open']:5,COP['read']:15,COP['marks']:8,COP['clear']:4,COP['mark']:5,COP['write']:6,COP['close']:4,COP['streams']:2};e.free={COP['read'],COP['marks'],COP['streams']}
|
|
133
134
|
if request[5]==COP['write'] and len(request)>=16:e.fixed[COP['write']]=6+struct.unpack_from('<H',request,14)[0]
|
|
134
|
-
else:e.fixed={WOP['attach']:9,WOP['detach']:4,WOP['connections']:1};e.free={WOP['connections']}
|
|
135
|
+
else:e.fixed={WOP['attach']:9,WOP['detach']:4,WOP['connections']:1,WOP['holds']:1};e.free={WOP['connections'],WOP['holds']}
|
|
135
136
|
try:return self.ep.handle(request)
|
|
136
137
|
finally:e.fixed,e.free=fixed,free
|
|
137
138
|
def restart_fixture(self):
|
oep_client/virtual_bench.py
CHANGED
|
@@ -262,7 +262,7 @@ def _setting(name: str, keys: int, form: int = 0, max_len: int = 0, flags: int =
|
|
|
262
262
|
|
|
263
263
|
|
|
264
264
|
def _config(fn: int, instance: int, storage: int = 4096, *, channels: int = 64, ports: int = 4, netifs=(), wifi_entries: int = 4,
|
|
265
|
-
own=(), rvswd: bool = False) -> Offered:
|
|
265
|
+
own=(), rvswd: bool = False, hold: bool = True) -> Offered:
|
|
266
266
|
"""oep.probe.config's declarations (probe.config §4): the standard items label / idle / disable (keys: the
|
|
267
267
|
channels), passthrough / console-passthrough (keys: the transports), with `netifs` (names) wifi / ipv4 and the
|
|
268
268
|
network op; `own`: the probe's own items as (name, form, keys, max_len, flags) (§1.6). storage 0 = none - no storage
|
|
@@ -276,6 +276,8 @@ def _config(fn: int, instance: int, storage: int = 4096, *, channels: int = 64,
|
|
|
276
276
|
settings.append(_setting("ipv4", len(netifs) + 1))
|
|
277
277
|
if rvswd: # its automatic rest can be turned off per port (debug §3.1)
|
|
278
278
|
settings.append(_setting("rvswd-rest", channels))
|
|
279
|
+
if hold: # a debug wire's hold after a close, per port (debug §2)
|
|
280
|
+
settings.append(_setting("wire-hold", channels))
|
|
279
281
|
settings += [_setting(name, keys, form, max_len, flags) for name, form, keys, max_len, flags in own]
|
|
280
282
|
return Offered(fn, instance, "oep.probe.config", ops_of("oep.probe.config", *drop)
|
|
281
283
|
+ ((catalog.u32(_CFG["storage"], storage),) if storage else ()) + tuple(settings)
|
|
@@ -24,7 +24,7 @@ class OepDeclarations(Resources):
|
|
|
24
24
|
|
|
25
25
|
def describe(self, fn):
|
|
26
26
|
if fn==4:return (tlv(DC['ops'],pack_ops(set(COP.values()))),tlv(CD['mechanism'],b'dmdata'))
|
|
27
|
-
rows=[tlv(DC['ops'],pack_ops({WOP['attach'],WOP['detach'],WOP['connections']}))]
|
|
27
|
+
rows=[tlv(DC['ops'],pack_ops({WOP['attach'],WOP['detach'],WOP['connections'],WOP['holds']}))]
|
|
28
28
|
if fn==1:rows.append(tlv(WT['describe']['max_connections'],b'\x02'))
|
|
29
29
|
if fn==2:rows.append(tlv(DC['min_clock_hz'],struct.pack('<I',1000000)))
|
|
30
30
|
role=WE['pin_role']
|
|
@@ -35,7 +35,7 @@ class OepDeclarations(Resources):
|
|
|
35
35
|
return tuple(rows)
|
|
36
36
|
|
|
37
37
|
def dispatch(self, fn, op, payload):
|
|
38
|
-
if (fn!=4 and op
|
|
38
|
+
if (fn!=4 and op in (WOP['connections'],WOP['holds'])) or (fn==4 and op==COP['streams']):return b'\0\0'+extension()
|
|
39
39
|
raise Reject(R['no_resource']) # declarations only: no simulated attach or target work
|
|
40
40
|
|
|
41
41
|
|
|
@@ -50,6 +50,6 @@ class OepDeclarationModel(ResourceModel):
|
|
|
50
50
|
if len(request)>=6:
|
|
51
51
|
fn=struct.unpack_from('<H',request,3)[0]
|
|
52
52
|
if fn==4:e.fixed={COP['open']:5,COP['read']:15,COP['marks']:8,COP['clear']:4,COP['mark']:5,COP['write']:6,COP['close']:4,COP['streams']:2};e.free={COP['read'],COP['marks'],COP['streams']}
|
|
53
|
-
else:e.fixed={WOP['attach']:9,WOP['detach']:4,WOP['connections']:1};e.free={WOP['connections']}
|
|
53
|
+
else:e.fixed={WOP['attach']:9,WOP['detach']:4,WOP['connections']:1,WOP['holds']:1};e.free={WOP['connections'],WOP['holds']}
|
|
54
54
|
try:return super().handle(request)
|
|
55
55
|
finally:e.fixed,e.free=fixed,free
|
|
@@ -8,7 +8,7 @@ from . import registry as _reg
|
|
|
8
8
|
# Each interface's mandatory ops, by name (looked up in the registry: never literal numbers).
|
|
9
9
|
_MANDATORY={
|
|
10
10
|
'oep.probe.plan':('plan_apply','plan_release'),'oep.probe.restart':('restart',),'oep.probe.link':('source','sink'),
|
|
11
|
-
**{w:('attach','detach','connections') for w in ('oep.wire.rvswd','oep.wire.swio','oep.wire.swd')},
|
|
11
|
+
**{w:('attach','detach','connections','holds') for w in ('oep.wire.rvswd','oep.wire.swio','oep.wire.swd')},
|
|
12
12
|
'oep.target.riscv-dm':('dmi',),'oep.target.arm-adi':('transfer',),
|
|
13
13
|
'oep.target.console':('open','read','close','streams'),
|
|
14
14
|
'oep.fixture.gpio':('set','read'),'oep.fixture.uart':('configure','read','status'),
|
|
@@ -14,7 +14,7 @@ KIND = _reg.WIRE_RVSWD.enum["scan_kind"] | _reg.WIRE_SWD.enum["scan_kind"]
|
|
|
14
14
|
|
|
15
15
|
class ScanOptions(WireOptions):
|
|
16
16
|
def __init__(self,ep):super().__init__(ep);self.scan_limit=2;self.identities={};self.scan_live=set();self.scan_events=[]
|
|
17
|
-
def describe(self,fn):return tuple(tlv(DC['ops'],pack_ops({WOP['scan'],WOP['attach'],WOP['detach'],WOP['connections']})) if fn<=3 and row[0]==DC['ops'] else row for row in super().describe(fn))
|
|
17
|
+
def describe(self,fn):return tuple(tlv(DC['ops'],pack_ops({WOP['scan'],WOP['attach'],WOP['detach'],WOP['connections'],WOP['holds']})) if fn<=3 and row[0]==DC['ops'] else row for row in super().describe(fn))
|
|
18
18
|
def request_tags(self,fn,op,data):
|
|
19
19
|
if fn>3 or op!=WOP['scan']:return super().request_tags(fn,op,data)
|
|
20
20
|
known={SC['max_speed']:4}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: oep-client-python
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.34
|
|
4
4
|
Summary: Open Embedded Probe (OEP) v1 host: serial / USB / TCP transports, the session rules, the standard interfaces, and a virtual bench
|
|
5
5
|
Project-URL: Homepage, https://github.com/Open-Embedded-Probe/oep-client-python
|
|
6
6
|
Project-URL: Repository, https://github.com/Open-Embedded-Probe/oep-client-python
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
oep_client/__init__.py,sha256=
|
|
2
|
-
oep_client/__main__.py,sha256=
|
|
1
|
+
oep_client/__init__.py,sha256=WV8YLSlZH0QElGgErRZN3FX_Ujze1gxUJA5gNUbc0M4,164
|
|
2
|
+
oep_client/__main__.py,sha256=7NYC9SZWd7M17YhOpjj15nu7_7-mEF_cQMfXJVkg53c,33449
|
|
3
3
|
oep_client/arm.py,sha256=SszSLae8zErD4T-a1uQ6s6o3Lz7pe2SR8d3Qy-wi5rY,15633
|
|
4
4
|
oep_client/capture.py,sha256=AFyJ-_DRb3ztYlvmFCDh9siNaKrwChOx8xvoNH6CKsI,48884
|
|
5
5
|
oep_client/catalog.py,sha256=WkaksNn9cFvkTRnvtX4I9g1AvkFoldEiNQaKiyPQ7_E,10772
|
|
6
6
|
oep_client/ch32_flash.py,sha256=lY_HKxf2foSfhNda91lcWefgRnY9ebTljsg4zJEj-Ks,12885
|
|
7
7
|
oep_client/cobs.py,sha256=RbdPrqgzD3SukxOIXX9m2dZpVTud8xAYYEhm3rcW2nA,2513
|
|
8
|
-
oep_client/config.py,sha256=
|
|
8
|
+
oep_client/config.py,sha256=1X66HIrT9WCvj7MjhPDET-jIrNyaQU1AM-wGq8BHpp8,30487
|
|
9
9
|
oep_client/conformance.py,sha256=phKkP_vT_8b9MyQiJU0p7JoCnkrPbPdkolcEqaD61TI,62859
|
|
10
10
|
oep_client/conformance_allocator.py,sha256=83xXiJ7c-6-M86615Kvq6yDD0sf0Z6lIOKDtbYcKeyM,6274
|
|
11
11
|
oep_client/conformance_allocator_sample.py,sha256=GGv43xbDNSPjQ8_flNXe-QbkLOr-NCbPpWPOfbD_wH8,879
|
|
@@ -178,7 +178,7 @@ oep_client/core.py,sha256=VPtgaVe2K5-HJMi72DDbIpIirATAXjcJSKautKUFgOM,22677
|
|
|
178
178
|
oep_client/decode.py,sha256=6pTFVBT0MLAKedZLVKyd5yT8hjrRw4fdDjnoDiE9XRs,2380
|
|
179
179
|
oep_client/discovery.py,sha256=OS6c4Qa8N32zbOHmw75e1y6ff3SQrL0uLtyPi7BWKUA,20187
|
|
180
180
|
oep_client/dump.py,sha256=31v4Hg27Het3cu3joCm6ttTWxQHSvvNryyGo8pwHXO4,12788
|
|
181
|
-
oep_client/endpoint.py,sha256=
|
|
181
|
+
oep_client/endpoint.py,sha256=Fqo5nSsWoqRulnwVujMhpNn4Uux57oZiuLrTKx5kcbk,229246
|
|
182
182
|
oep_client/fixture.py,sha256=GbAPXAk9GQ0qG6STL-rY4-EqXftmKfNKVI2xZZUiFzA,18108
|
|
183
183
|
oep_client/frames.py,sha256=OrvoNugGB4ewfmILhwBiJfI9sQ09i-RzO47LESVbWXw,4800
|
|
184
184
|
oep_client/hardware.py,sha256=RboxkRxkQJ3DbNJEXyyiOFYlLFKGxrlcSwHho8zFC1U,30256
|
|
@@ -192,8 +192,8 @@ oep_client/message.py,sha256=-WgnHcmnhJ6pozYvZP_FS8dr0ZMg2Wp9rTdRReGvogU,13116
|
|
|
192
192
|
oep_client/names.py,sha256=ohrRvQNURraYyJ-BtjHRwxGt_GLq-t8IO0aOji9Dhe0,3531
|
|
193
193
|
oep_client/pins.py,sha256=YVM0JXjCKcMMMWChtWsQoSKU4-OTOnDbZjo_mo_5hD0,32574
|
|
194
194
|
oep_client/pytest_conformance.py,sha256=-bcJU2E1UE4xjQ7HZjaIgtp0l65cIibBTNFnaW2tews,2929
|
|
195
|
-
oep_client/registry.py,sha256=
|
|
196
|
-
oep_client/riscv.py,sha256=
|
|
195
|
+
oep_client/registry.py,sha256=8ynarYyjC54IuD45PgXAzxIkpEs9ly-QAX2uZWIk1qI,16869
|
|
196
|
+
oep_client/riscv.py,sha256=_98qwqnxUIj9vitWIz6iJfJKsT63FNsQH9eZrZnqB4g,59939
|
|
197
197
|
oep_client/rp2350.py,sha256=7OMyj270k3AY1e3-ljicPwOjf9jOlokbT6QNkA0b0yY,4227
|
|
198
198
|
oep_client/speed_record.py,sha256=6THUKbN7gQKpfIdUO2551P8mXiAFqbFDky72Xbki7L0,7229
|
|
199
199
|
oep_client/targets.py,sha256=zFekSr76NVO7tzdgyQsLDHLWRvkgylfwvGNTz_hQGf8,5041
|
|
@@ -202,8 +202,8 @@ oep_client/usb_stream.py,sha256=pFbQexircX88eV8MZG7ECfUtRXCboBr-4-dtahvF6ro,1135
|
|
|
202
202
|
oep_client/virtual_allocator_model.py,sha256=XBrbjG2Zupf0P28gjUhQVDw6UzO2jQXsYZ1E1qAIKc8,1570
|
|
203
203
|
oep_client/virtual_analog_model.py,sha256=iV5pyJ1sy37D6VMy4qVmgzsmq4gLwEPMcdOGXPIin1Q,13872
|
|
204
204
|
oep_client/virtual_arm_adi_model.py,sha256=xlqhjr_QCF6MNVOnVelTanlNWpmaCJ5uWXf6V9WkqUM,8121
|
|
205
|
-
oep_client/virtual_attach_model.py,sha256=
|
|
206
|
-
oep_client/virtual_bench.py,sha256=
|
|
205
|
+
oep_client/virtual_attach_model.py,sha256=YhGYz4X2IcdBMsBb0vjkV2UWUst6tSVieZHUwQZ89gA,10433
|
|
206
|
+
oep_client/virtual_bench.py,sha256=6wJNW5odjS5UpeLfUTOIgKfWM_aXdPcqIrtTHGnZbFI,36137
|
|
207
207
|
oep_client/virtual_bench_capture.py,sha256=hIIOUOqKcSxBnsCb9rcyzYFqSsBmuic7sAkF7zsBAIs,52208
|
|
208
208
|
oep_client/virtual_bench_mdns.py,sha256=cnJNBKg5zTduXUcH-wqN_ZBDGl7DyL-tL3CBn2jro0E,13305
|
|
209
209
|
oep_client/virtual_bench_serial.py,sha256=EvbdOYeGrM6CRti2b90I0PzpmmherfoJRaAg4v7Iq9Y,13205
|
|
@@ -238,12 +238,12 @@ oep_client/virtual_logic_model.py,sha256=_a4z_BLYWaoPS2o4NqWiNEElFBWI2pkCc0psf4h
|
|
|
238
238
|
oep_client/virtual_mailbox_model.py,sha256=VNjwg-_E_djPwpys95RIWg26_DctS6uqo16Kg5i5ckA,2996
|
|
239
239
|
oep_client/virtual_names.py,sha256=p72ME65R9Jy56xmVYnVCtapK3Id8iFpAdI5xLe2tNZ0,1449
|
|
240
240
|
oep_client/virtual_notification_model.py,sha256=iUYcQidlUq2DJ6emd5VXwuPMRw2bOKuSa0A_fc2_OVM,2673
|
|
241
|
-
oep_client/virtual_oep_declaration_model.py,sha256=
|
|
241
|
+
oep_client/virtual_oep_declaration_model.py,sha256=LrhcsEAnG-hwyrXaio9owpOEZj6oC2gGK5HIl9kwwPk,2951
|
|
242
242
|
oep_client/virtual_outcome_model.py,sha256=cmMiM9XqhqCZ523YShkWFDKAn6NPMM6hnWNxqBGPxVc,3704
|
|
243
243
|
oep_client/virtual_pipeline_model.py,sha256=3XHOQAB1pm5wOxfVBtIK60L_N_d-fUpSgVX0S_5-V7E,4063
|
|
244
244
|
oep_client/virtual_port_speed_execution_model.py,sha256=vgUSHHmMNFC1UL6s1S_0t9wJg_dDUYXTJ7NXqM5lPfg,1676
|
|
245
245
|
oep_client/virtual_port_speed_model.py,sha256=1gI0tlN4ObTm3B1Ys1BsEJ02c6jYAqfIbaFFbVmn7cE,8680
|
|
246
|
-
oep_client/virtual_registered_ops_model.py,sha256=
|
|
246
|
+
oep_client/virtual_registered_ops_model.py,sha256=MRYX08hhfsY1IH3MHzdWz9uEiTN5OQBTU08fuEWUWVc,2730
|
|
247
247
|
oep_client/virtual_reset_model.py,sha256=mfIMxArHv7LRZjC9tjYkVJ0flYuZlOVrJChWmgiNh1Y,4303
|
|
248
248
|
oep_client/virtual_resource_model.py,sha256=XTYxvgIz371EQJ4-vKs3arqSf4kV8nNYKgFjFmRc6dk,3151
|
|
249
249
|
oep_client/virtual_restart_model.py,sha256=ZDHo4MCF1EuP1eo0utKqCZUOHTl6cIgFO8FOQqEqUGM,4651
|
|
@@ -252,7 +252,7 @@ oep_client/virtual_retry_model.py,sha256=2Vf7Seic2FX7Mwf3UR4UHBGJYHuqpKIaxgMmURy
|
|
|
252
252
|
oep_client/virtual_route_model.py,sha256=k3bWMKakWzDNnoaqK80LKWK5RTU2q1eYhAK_OSlgOLY,7299
|
|
253
253
|
oep_client/virtual_run_model.py,sha256=qYFb1vmhbJFnoM00Tq1Kj0x3T8GVlY5Nb4rsBxGG3Nw,6464
|
|
254
254
|
oep_client/virtual_scan_model.py,sha256=9Q5h4hRfFdPzEKwjgIPFa0vl5OYax08AVa4JJDsnMeI,4330
|
|
255
|
-
oep_client/virtual_scan_options_model.py,sha256=
|
|
255
|
+
oep_client/virtual_scan_options_model.py,sha256=_aFpSL5wXzicZSflniaov5G3NABeTqstEE8yLmbnIk4,6214
|
|
256
256
|
oep_client/virtual_selected_metadata_model.py,sha256=uKUy73sAqVHt1xPuY3LgjYbq-BMLZ_jnU70VYGfDo9g,934
|
|
257
257
|
oep_client/virtual_spi_model.py,sha256=uKcA0bG1v4tMCm8IFOmlCzC9CN3d2MFPSUf4wP0jS88,10258
|
|
258
258
|
oep_client/virtual_step_model.py,sha256=g-CfAloAktuf3oB9eR8wB291Pnh0leezaP1Drqrbr_Q,4200
|
|
@@ -261,8 +261,8 @@ oep_client/virtual_tlv_request_model.py,sha256=gp-eiN784NnloQBANG_4TnM6oUCmrj046
|
|
|
261
261
|
oep_client/virtual_uart_model.py,sha256=Sd_MWLjl1-6_bemsCuI2at9zpVJRBehFQgZ6By97PdQ,9386
|
|
262
262
|
oep_client/virtual_wire_options_model.py,sha256=1QNF16hRWmdFt0J7Zd1WKZdEc07vns6osMQLetMBlXw,9206
|
|
263
263
|
oep_client/virtual_writer_lease_model.py,sha256=E1MAQsGuShqONVdIeLubun7Cop0URNUSk8wicPicbt4,1728
|
|
264
|
-
oep_client_python-0.0.
|
|
265
|
-
oep_client_python-0.0.
|
|
266
|
-
oep_client_python-0.0.
|
|
267
|
-
oep_client_python-0.0.
|
|
268
|
-
oep_client_python-0.0.
|
|
264
|
+
oep_client_python-0.0.34.dist-info/METADATA,sha256=epM_SIcto4RoFOoLl3JP7ZRYwMi5lf-XBvU9n2Ufzi4,52711
|
|
265
|
+
oep_client_python-0.0.34.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
266
|
+
oep_client_python-0.0.34.dist-info/entry_points.txt,sha256=XEt39Jz7oQyU9Hfg_tV6eDGofNxWYrjSfslxKP-fh70,135
|
|
267
|
+
oep_client_python-0.0.34.dist-info/licenses/LICENSE,sha256=ntlalztb3L1OaNAxmQdHlubu5fVhjMc9oRZi3PeQhXg,1076
|
|
268
|
+
oep_client_python-0.0.34.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|