Radix 16 (live-verified), universal reply splitter, golden capture vectors, host_probe6
This commit is contained in:
1 parent
0cd6b34a2e
commit
62e0fd649b
10 files changed
+418
-82
No files matched your search
@@ -29,6 +29,7 @@ from .protocol import (
|
||||
SocketFrameDecoder,
|
||||
decrypt_data,
|
||||
decrypt_request,
|
||||
decrypt_wire,
|
||||
direct_connect_request,
|
||||
encrypt_object,
|
||||
frame_socket_payload,
|
||||
@@ -64,8 +65,8 @@ class LocalDeviceClient:
|
||||
:param socket_port: local TCP socket port (candidate 18000).
|
||||
:param verify: TLS verification for the device API (device likely serves a
|
||||
self-signed cert, so ``False`` is the practical default).
|
||||
:param key_radix: key parse radix for the envelope cipher (32, per the
|
||||
``int.tryParse(key, radix: 32)`` call in both directions).
|
||||
:param key_radix: key parse radix for the envelope cipher (16 —
|
||||
default ``int.tryParse`` radix, verified against live captures).
|
||||
:param timeout: per-request timeout in seconds.
|
||||
"""
|
||||
|
||||
@@ -77,7 +78,7 @@ class LocalDeviceClient:
|
||||
scheme: str = "https",
|
||||
verify: Optional[bool] = False,
|
||||
socket_port: Optional[int] = None,
|
||||
key_radix: int = 32,
|
||||
key_radix: int = 16,
|
||||
timeout: float = 10.0,
|
||||
extra_headers: Optional[Dict[str, str]] = None,
|
||||
session: Optional[requests.Session] = None,
|
||||
@@ -185,7 +186,7 @@ class LocalDeviceClient:
|
||||
"""
|
||||
if envelope is None:
|
||||
envelope = direct_connect_request(
|
||||
cmd, equip_no or self.sn, data=data,
|
||||
cmd, self.sn if equip_no is None else equip_no, data=data,
|
||||
snno=self._sn_seq.next(),
|
||||
)
|
||||
return self.send_envelope(envelope)
|
||||
@@ -194,8 +195,9 @@ class LocalDeviceClient:
|
||||
wire = encrypt_object(envelope.to_json_string(), self.key,
|
||||
radix=self.key_radix)
|
||||
raw = self._socket_roundtrip(frame_socket_payload(wire))
|
||||
reply = decrypt_data(raw, radix=self.key_radix)
|
||||
if not reply:
|
||||
try:
|
||||
reply = decrypt_wire(raw, radix=self.key_radix)
|
||||
except ValueError:
|
||||
raise ConnectionError(
|
||||
f"undecodable reply ({len(raw)} bytes) from "
|
||||
f"{self.socket_host}:{self.socket_port}"
|
||||
@@ -224,7 +226,10 @@ class LocalDeviceClient:
|
||||
)
|
||||
reply: Optional[Dict[str, Any]] = None
|
||||
if reply_raw:
|
||||
decoded = decrypt_data(reply_raw, radix=self.key_radix)
|
||||
try:
|
||||
decoded = decrypt_wire(reply_raw, radix=self.key_radix)
|
||||
except ValueError:
|
||||
decoded = ""
|
||||
if decoded:
|
||||
try:
|
||||
reply = json.loads(decoded)
|
||||
@@ -268,11 +273,13 @@ class LocalDeviceClient:
|
||||
break
|
||||
if collect_only:
|
||||
return bytes(received)
|
||||
if decrypt_data(bytes(received), radix=self.key_radix):
|
||||
return bytes(received)
|
||||
raise ConnectionError(
|
||||
f"no reply frame from {self.socket_host}:{self.socket_port}"
|
||||
)
|
||||
try:
|
||||
decrypt_wire(bytes(received), radix=self.key_radix)
|
||||
except ValueError:
|
||||
raise ConnectionError(
|
||||
f"no reply frame from {self.socket_host}:{self.socket_port}"
|
||||
)
|
||||
return bytes(received)
|
||||
|
||||
# ------------------------------------------------------- convenience RPCs
|
||||
def query_device_info(self) -> Dict[str, Any]:
|
||||
|
||||
Reference in new issue
Block a user