| 64 | |
| 65 | |
| 66 | def send_rpc( |
| 67 | s: "serial.Serial", |
| 68 | method: str, |
| 69 | args: dict[str, Any] | None = None, |
| 70 | request_id: int = 1, |
| 71 | timeout: float = 10.0, |
| 72 | ) -> dict[str, Any] | None: |
| 73 | params = [args] if args is not None else [{}] |
| 74 | req = {"method": method, "params": params, "id": request_id} |
| 75 | s.write((json.dumps(req, separators=(",", ":")) + "\n").encode("ascii")) |
| 76 | s.flush() |
| 77 | deadline = time.time() + timeout |
| 78 | buf = b"" |
| 79 | while time.time() < deadline: |
| 80 | chunk = s.read(s.in_waiting or 1) |
| 81 | if not chunk: |
| 82 | continue |
| 83 | buf += chunk |
| 84 | while b"\n" in buf: |
| 85 | line, _, buf = buf.partition(b"\n") |
| 86 | text = line.decode("ascii", errors="replace").strip() |
| 87 | for prefix in ("REMOTE: ", "RESULT: "): |
| 88 | if text.startswith(prefix): |
| 89 | text = text[len(prefix) :] |
| 90 | break |
| 91 | if not (text.startswith("{") and text.endswith("}")): |
| 92 | continue |
| 93 | try: |
| 94 | msg = json.loads(text) |
| 95 | except json.JSONDecodeError: |
| 96 | continue |
| 97 | if isinstance(msg, dict) and msg.get("id") == request_id: |
| 98 | return msg |
| 99 | return None |
| 100 | |
| 101 | |
| 102 | def evaluate(case: BenchCase, result: dict[str, Any]) -> tuple[bool, str]: |