#!/usr/bin/python3 # Copyright (C) 2026 Danilo M. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as # published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. """Run: /usr/bin/python3 desktop/island/test_sonyctl.py The frame codec and state parsing only; never touches Bluetooth. The bytes are ones captured from a WH-CH720N. """ import sys sys.dont_write_bytecode = True # importing sonyctl must not leave a __pycache__ import importlib.machinery import importlib.util from pathlib import Path path = str(Path(__file__).resolve().parent / "sonyctl") loader = importlib.machinery.SourceFileLoader("sonyctl", path) spec = importlib.util.spec_from_loader("sonyctl", loader) s = importlib.util.module_from_spec(spec) loader.exec_module(s) # Init request as sent, and the CH720N's init reply as received. assert s.encode(0x0C, 0, [0x00, 0x00]) == bytes.fromhex("3e0c000000000200000e3c") reply = s.encode(0x0C, 0, bytes.fromhex("0100030010020000")) assert s.decode(reply[:-1]) == (0x0C, 0, bytes.fromhex("0100030010020000")) # Escaping: a 3c, 3d or 3e in the body round-trips and never appears raw. for b in (0x3C, 0x3D, 0x3E): f = s.encode(0x0C, 1, [0x68, b]) assert 0x3C not in f[1:-1] and 0x3E not in f[1:-1] assert s.decode(f[:-1]) == (0x0C, 1, bytes([0x68, b])) # A bad checksum and a short frame are rejected, not misread. bad = bytearray(reply[:-1]); bad[-1] ^= 1 assert s.decode(bytes(bad)) is None assert s.decode(b"\x3e\x0c") is None assert s.state(bytes.fromhex("6717010100000c")) == {"mode": "nc", "level": 12, "voice": False} assert s.state(bytes.fromhex("67170101010010")) == {"mode": "ambient", "level": 16, "voice": False} assert s.state(bytes.fromhex("6717010101010c")) == {"mode": "ambient", "level": 12, "voice": True} assert s.state(bytes.fromhex("69170100000010")) == {"mode": "off", "level": 16, "voice": False} assert not s.main(["sonyctl", "00:00:00:00:00:00", "ambient", "21"])["ok"] assert not s.main(["sonyctl"])["ok"] assert not s.main(["sonyctl", "00:00:00:00:00:00", "voice", "maybe"])["ok"] print("ok")