#ifndef BUZZ_PROTO_H #define BUZZ_PROTO_H #include #include #include #define BUZZ_PROTO_VERSION 1 /* --- Enums für Protokoll-Typen --- */ enum buzz_frame_type { BUZZ_FRAME_REQUEST = 0x00, BUZZ_FRAME_RESPONSE = 0x10, BUZZ_FRAME_ACK = 0x11, BUZZ_FRAME_ERROR = 0x12, BUZZ_FRAME_SUCCESS = 0x13, BUZZ_FRAME_FILE_START = 0x20, BUZZ_FRAME_FILE_CHUNK = 0x21, BUZZ_FRAME_FILE_END = 0x22, BUZZ_FRAME_FW_START = 0x30, BUZZ_FRAME_FW_CHUNK = 0x31, BUZZ_FRAME_FW_END = 0x32, BUZZ_FRAME_LS_START = 0x40, BUZZ_FRAME_LS_ENTRY = 0x41, BUZZ_FRAME_LS_END = 0x42, }; enum buzz_data_type { BUZZ_DATA_PROTO_INFO = 0x01, BUZZ_DATA_DEVICE_INFO = 0x02, BUZZ_DATA_FS_INFO = 0x03, BUZZ_DATA_FILE_GET = 0x20, BUZZ_DATA_FILE_PUT = 0x21, BUZZ_DATA_TAGS_GET = 0x22, BUZZ_DATA_TAGS_PUT = 0x23, BUZZ_DATA_RM_FILE = 0x24, BUZZ_DATA_RENAME_FILE = 0x25, BUZZ_DATA_FW_UPDATE = 0x30, BUZZ_DATA_LS = 0x40, }; enum buzz_fs_entry_type { BUZZ_FS_ENTRY_FILE = 0x00, BUZZ_FS_ENTRY_DIR = 0x01, }; /* --- Wire Protocol Structs (Packed) --- */ /* Generischer Header für alle Frames */ struct __attribute__((packed)) buzz_proto_header { uint8_t frame_type; /* Nutzt enum buzz_frame_type */ uint16_t payload_length; /* Länge der folgenden Daten (Little Endian) */ }; /* Payload für einen Error-Frame */ struct __attribute__((packed)) buzz_resp_error { uint16_t error_code; /* Bis 0xFF reserviert für Standard-Fehler, 0x100+ für spezifische Fehler */ }; struct __attribute__((packed)) buzz_resp_success { uint8_t data_type; /* Der Befehl, der erfolgreich war (z.B. BUZZ_DATA_FILE_PUT) */ }; /* Payload für eine Standard-Anfrage (Request) */ struct __attribute__((packed)) buzz_request_payload { uint8_t data_type; /* Nutzt enum buzz_data_type */ }; /* Payload für die Protokollversions-Antwort */ struct __attribute__((packed)) buzz_resp_proto_version { uint8_t data_type; /* BUZZ_DATA_PROTO_INFO */ uint16_t version; /* Little Endian */ uint16_t max_chunk_size; /* Little Endian */ }; /* Payload für die Dateisystem-Informationen */ struct __attribute__((packed)) buzz_resp_fs_info { uint8_t data_type; /* BUZZ_DATA_FS_INFO */ uint32_t total_size; /* Little Endian */ uint32_t free_size; /* Little Endian */ uint8_t max_path_length; /* Maximale Pfadlänge (z.B. 32) */ uint8_t sys_path_length; /* Länge des System-Ordners (z.B. 2 für "/s") */ uint8_t audio_path_length; /* Länge des Audio-Ordners (z.B. 2 für "/a") */ uint8_t data[]; /* Pfadnamen */ }; /* Payload für das Entfernen einer Datei */ struct __attribute__((packed)) buzz_rm_file_payload { uint8_t data_type; /* BUZZ_DATA_RM_FILE */ uint8_t path_length; char path[]; /* Variabler String ohne Null-Terminierung */ }; /* Payload für das Umbenennen einer Datei */ struct __attribute__((packed)) buzz_rename_file_payload { uint8_t data_type; /* BUZZ_DATA_RENAME_FILE */ uint8_t old_path_length; uint8_t new_path_length; char paths[]; /* Variabler String ohne Null-Terminierung */ }; /* Payload für das Credit-System (ACK) */ struct __attribute__((packed)) buzz_ack_payload { uint16_t credits; /* Little Endian */ }; /* Payload für einen einzelnen Verzeichniseintrag */ struct __attribute__((packed)) buzz_ls_entry_payload { uint8_t type; /* enum buzz_fs_entry_type */ uint32_t size; /* Little Endian */ uint8_t name_length; char name[]; /* Variabler String ohne Null-Terminierung */ }; /* Payload für das Ende der Liste */ struct __attribute__((packed)) buzz_ls_end_payload { uint32_t total_entries; /* Little Endian */ }; /* Payload für FILE_START */ struct __attribute__((packed)) buzz_file_start_payload { uint32_t total_size; /* Little Endian */ }; /* Payload für FILE_END */ struct __attribute__((packed)) buzz_file_end_payload { uint32_t crc32; /* Little Endian */ }; /* --- System API --- */ /* Callback-Signatur für den Transport-Layer (BLE/UART) */ typedef int (*buzz_transport_reply_fn)(const uint8_t *data, uint16_t len); /* Struktur für die interne Message Queue */ struct buzz_frame_msg { uint8_t *data_ptr; uint16_t length; buzz_transport_reply_fn reply_cb; uint16_t max_payload; /* NEU: Maximales Limit für ausgehende Frames dieses Transports */ }; /* Allokation und Freigabe von Memory Slabs */ int buzz_proto_buf_alloc(uint8_t **buf); void buzz_proto_buf_free(uint8_t **buf); /* Übergabe eines empfangenen Frames an den Protokoll-Thread */ int buzz_proto_submit_frame(struct buzz_frame_msg *msg); /* Gibt die Anzahl der freien Slabs zurück (abzüglich Reserve) */ uint16_t buzz_proto_get_free_rx_slabs(void); /* Baut und sendet ein ACK Frame */ void buzz_proto_send_ack(buzz_transport_reply_fn reply_cb, uint16_t credits); /* Sendet einen Success-Frame unter Wiederverwendung eines bestehenden Slabs (Zero-Copy) */ void buzz_proto_send_success_reusing_slab(buzz_transport_reply_fn reply_cb, uint8_t data_type, uint8_t *slab); /* Sendet einen Error-Frame unter Wiederverwendung eines bestehenden Slabs (Zero-Copy) */ void buzz_proto_send_error_reusing_slab(buzz_transport_reply_fn reply_cb, uint16_t error_code, uint8_t *slab); #endif /* BUZZ_PROTO_H */