"""BLE identifiers and protocol constants for the Shining Mask. References: * Shining-Mask-stuff/ble-protocol.md (community protocol documentation) * mask-go/mask/mask.go (canonical, field-tested Go implementation) """ from __future__ import annotations # --- GATT identifiers --------------------------------------------------------- # Vendor service that carries every mask characteristic. SERVICE_UUID = "0000fff0-0000-1000-8000-00805f9b34fb" # Command characteristic: AES-encrypted 16-byte command frames (write). CMD_CHAR_UUID = "d44bc439-abfd-45a2-b575-925416129600" # Notify characteristic: AES-encrypted responses (notify). Drives the upload # handshake (DATSOK / REOK / DATCPOK). NOTIFY_CHAR_UUID = "d44bc439-abfd-45a2-b575-925416129601" # Upload characteristic: raw (UNencrypted) image/bitmap data chunks (write). UPLOAD_CHAR_UUID = "d44bc439-abfd-45a2-b575-92541612960a" # Audio-visualization characteristic: AES-encrypted 16-byte frames (write). AUDIO_CHAR_UUID = "d44bc439-abfd-45a2-b575-92541612960b" # The mask advertises a local name like "MASK-02A711"; everyone scans by prefix. DEVICE_NAME_PREFIX = "MASK" # --- Protocol sizing ---------------------------------------------------------- # Mask display is 16 pixels tall (arbitrarily wide for scrolling text). MASK_HEIGHT = 16 # Command/notify frames are AES blocks padded to this size. FRAME_SIZE = 16 # Upload packets carry at most this many data bytes (the mask rejects packets # whose total on-air size exceeds 100 bytes; 2 bytes are header, so 98 remain). UPLOAD_MAX_DATA = 98 # --- Text scroll modes (MODE command argument) -------------------------------- class TextMode: """Text display modes for the MODE command. Values confirmed by decrypting real app traffic (mask-controller/codes.js) and cross-checked with mask-go:: 1 = steady / solid (text shown, no scroll animation) 2 = blink 3 = scroll right-to-left 4 = scroll left-to-right The protocol doc mislabels 1 as "off" and declares 5..255 as n/a (the firmware reverts them to mode 1); the official app only ever sends 1..4. """ STEADY = 1 SOLID = 1 # alias for STEADY BLINK = 2 SCROLL_LEFT = 3 # scroll right-to-left SCROLL_RIGHT = 4 # scroll left-to-right # --- DATS upload toggle byte -------------------------------------------------- class UploadKind: BITMAP = 0 # text bitmap + per-column color array IMAGE = 1 # full-color DIY image (raw RGB)