import logging import sys, asyncio, struct, time from typing import Optional from ble.interface import BLEInterface, Advertisement from logger.logger import GiciskyLogger, LogCategory # Default UUIDs for Gicisky tags BASE_SERVICE = 0xFEF0 SERVICE_UUID = f"0000{BASE_SERVICE:04x}-0000-1000-8000-00805f9b34fb" CHAR_CMD_UUID = f"0000{BASE_SERVICE+1:04x}-0000-1000-8000-00805f9b34fb" CHAR_IMG_UUID = f"0000{BASE_SERVICE+2:04x}-0000-1000-8000-00805f9b34fb" # Constants CHUNK_SIZE = 240 # 480 hex chars (as seen in the JS uploader) MTU_WAIT = 0.03 # delay between chunks (adjustable) DEBUG = True def log(msg): if DEBUG: print(f"[LOG] {msg}", flush=True) class GiciskyProtocol: def __init__(self, ble: BLEInterface, logger: Optional[logging.Logger] = None): self.ble = ble self.packet_index = 0 self.ready_to_send = False self.img_hex = b"" self.upload_done = False self.logger = GiciskyLogger(logger) async def handle_notification(self, data): hx = data.hex() self.logger.debug(f"Notify: {hx}", LogCategory.NOTIFICATION) if hx.startswith("01f400"): # Step 2: ready to accept image size self.logger.info("Device ready to accept image size", LogCategory.PROTOCOL) await self.send_command(2, struct.pack("