Add Berger LFP BLE command notes and client
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build Berger/JBD BLE frames observed in the Android app."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
|
||||
def checksum(command: int, payload: bytes = b"") -> int:
|
||||
"""JBD two's-complement checksum over command, length, and payload."""
|
||||
total = (command + len(payload) + sum(payload)) & 0xFFFF
|
||||
return ((total ^ 0xFFFF) + 1) & 0xFFFF
|
||||
|
||||
|
||||
def frame(mode: int, command: int, payload: bytes = b"") -> bytes:
|
||||
check = checksum(command, payload)
|
||||
return bytes([0xDD, mode, command, len(payload), *payload, check >> 8, check & 0xFF, 0x77])
|
||||
|
||||
|
||||
def read_frame(command: int) -> bytes:
|
||||
return frame(0xA5, command)
|
||||
|
||||
|
||||
def write_frame(command: int, payload: bytes) -> bytes:
|
||||
return frame(0x5A, command, payload)
|
||||
|
||||
|
||||
def name_frame(command: int, payload: bytes = b"") -> bytes:
|
||||
check = (command + len(payload) + sum(payload)) & 0xFF
|
||||
return bytes([0xFF, 0xAA, command, len(payload), *payload, check])
|
||||
|
||||
|
||||
def parse_hex_bytes(value: str) -> bytes:
|
||||
clean = value.replace(" ", "").replace(":", "")
|
||||
return bytes.fromhex(clean)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser()
|
||||
sub = parser.add_subparsers(dest="cmd", required=True)
|
||||
|
||||
p_read = sub.add_parser("read")
|
||||
p_read.add_argument("command", type=lambda x: int(x, 0))
|
||||
|
||||
p_write = sub.add_parser("write")
|
||||
p_write.add_argument("command", type=lambda x: int(x, 0))
|
||||
p_write.add_argument("payload_hex", nargs="?", default="")
|
||||
|
||||
p_name = sub.add_parser("name")
|
||||
p_name.add_argument("value")
|
||||
|
||||
args = parser.parse_args()
|
||||
if args.cmd == "read":
|
||||
print(read_frame(args.command).hex().upper())
|
||||
elif args.cmd == "write":
|
||||
print(write_frame(args.command, parse_hex_bytes(args.payload_hex)).hex().upper())
|
||||
elif args.cmd == "name":
|
||||
print(name_frame(0x07, args.value.encode("ascii")).hex().upper())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user