feat: add per-second GCP-format trials with history, watch and HTTP access (FPGA v10)
This commit is contained in:
parent
d821b77d3b
commit
6bee626b7f
12 changed files with 475 additions and 29 deletions
|
|
@ -99,6 +99,25 @@ def main() -> None:
|
|||
device.serial.reset_input_buffer()
|
||||
check(trials == sorted(trials) and len(set(trials)) == 3, f"watch stats pushed trials {trials}")
|
||||
|
||||
check(device.json("watch gcp") == {"ok": True}, "watch gcp")
|
||||
seconds = [json.loads(device.serial.readline()) for _ in range(3)]
|
||||
device.json("watch off")
|
||||
device.serial.reset_input_buffer()
|
||||
numbers = [r.get("second") for r in seconds]
|
||||
last = seconds[-1]
|
||||
check(numbers == list(range(numbers[0], numbers[0] + 3)), f"watch gcp pushed consecutive seconds {numbers}")
|
||||
check(last["healthy"] == 15 and last["sample"]["bits"] == 200
|
||||
and all(0 <= s <= 200 for s in last["sample"]["sums"]),
|
||||
f"gcp sample: sums {last['sample']['sums']}, Stouffer {last['sample']['stouffer']}")
|
||||
check(abs(last["full"]["bits"] - 24_000_000) <= 1,
|
||||
f"gcp full: {last['full']['bits']} bits, z {last['full']['z']}, Stouffer {last['full']['stouffer']}")
|
||||
device.entropy_bin(65536)
|
||||
time.sleep(1.1)
|
||||
records = device.json(f"gcp {numbers[-1]}").get("records", [])
|
||||
after = [r["second"] for r in records]
|
||||
check(len(after) >= 1 and after == list(range(numbers[-1] + 1, numbers[-1] + 1 + len(after))),
|
||||
f"gcp {numbers[-1]}: no gap across an entropy transfer, seconds {after}")
|
||||
|
||||
if args.onod.exists():
|
||||
sample = Path("captures/api_entropy.bin")
|
||||
sample.parent.mkdir(exist_ok=True)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Checks the STRIX firmware's Bluetooth LE API (arduino/strix/API.md) from this computer:
|
||||
finds the device, sends commands over the command characteristic, reads the replies from the
|
||||
reply notifications, and reads and streams the entropy characteristic."""
|
||||
reply notifications (including `watch gcp` output), and reads and streams the entropy characteristic."""
|
||||
|
||||
import argparse
|
||||
import asyncio
|
||||
|
|
@ -57,6 +57,15 @@ async def main() -> None:
|
|||
print(f"{'stats':<12} -> trial {stats.get('trial')}, combined total z "
|
||||
f"{stats['channels'][-1]['total']['z'] if 'channels' in stats else None}")
|
||||
|
||||
print(f"{'watch gcp':<12} -> {await command(client, replies, 'watch gcp')}")
|
||||
records = [json.loads(await asyncio.wait_for(replies.lines.get(), timeout=3)) for _ in range(2)]
|
||||
await client.write_gatt_char(COMMAND, b"watch off", response=True)
|
||||
await asyncio.sleep(1.5)
|
||||
while not replies.lines.empty():
|
||||
replies.lines.get_nowait() # the watch reply and any second pushed before it
|
||||
print(f"{'gcp seconds':<12} -> {[r['second'] for r in records]}, healthy {records[-1]['healthy']}, "
|
||||
f"sample sums {records[-1]['sample']['sums']}")
|
||||
|
||||
first = await client.read_gatt_char(ENTROPY)
|
||||
second = await client.read_gatt_char(ENTROPY)
|
||||
print(f"entropy read -> {len(first)} bytes, then {len(second)} bytes, "
|
||||
|
|
|
|||
|
|
@ -82,8 +82,8 @@ class Board:
|
|||
while self.serial.readline():
|
||||
pass
|
||||
self.serial.timeout = 200
|
||||
if not identity.startswith("STRX v9"):
|
||||
sys.exit(f"unexpected board identity: {identity!r} (needs the v9 FPGA image)")
|
||||
if not identity.startswith("STRX v10"):
|
||||
sys.exit(f"unexpected board identity: {identity!r} (needs the v10 FPGA image)")
|
||||
self.generators = self.read(REG_GENERATORS)
|
||||
self.rings = self.read(REG_RINGS)
|
||||
print(f"board: {identity}, {self.generators} generators x {self.rings} rings")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue