zwischenstand

This commit is contained in:
2026-03-21 13:49:05 +01:00
parent b863b04505
commit 01448223ad
30 changed files with 1446 additions and 295 deletions

View File

@@ -3,7 +3,7 @@
Stand: 2026-03-18
Quelle: aktueller Implementierungsstand aus Firmware (`buzz_proto`, `fs_mgmt`, `ble_mgmt`) und Web-Client (`transport`, `parser`).
## 1. Ziel und Scope
## Ziel und Scope
Das Buzzer Protocol ist ein binäres Frame-Protokoll für Host <-> Device Kommunikation.
@@ -19,7 +19,7 @@ Nicht produktiv implementiert:
- `DEVICE_INFO` (`0x02`)
- Firmware-Update (`FW_*`, `FW_UPDATE`)
## 2. Transport und Grundregeln
## Transport und Grundregeln
- Alle Integer-Felder sind Little Endian.
- Jedes Frame hat einen 3-Byte Header.
@@ -32,9 +32,9 @@ BLE Service UUIDs:
- RX: `e517d988-bab5-4574-8479-97c6cb115ca1`
- TX: `e517d988-bab5-4574-8479-97c6cb115ca2`
## 3. Frame-Format
## Frame-Format
### 3.1 Header
### Header
```c
uint8_t frame_type;
@@ -42,7 +42,7 @@ uint16_t payload_length; // LE
```
### 3.2 Paketstruktur
### Paketstruktur
```mermaid
---
@@ -54,7 +54,7 @@ packet
+40: "Payload (variable length)"
```
### 3.3 Maximalgröße
### Maximalgröße
Firmware-Buffer ist slab-basiert (`CONFIG_BUZZ_PROTO_SLAB_SIZE`).
Der effektive Chunk für Transfers wird zusätzlich durch den Transport limitiert. Bei Bluetooth sind das zum Beispiel 3 Bytes:
@@ -65,7 +65,7 @@ Der effektive Chunk für Transfers wird zusätzlich durch den Transport limitier
Das Protokoll ist so ausgelegt, dass es mit mindestens 100 Bytes auskommen sollte.
## 4. Frame-Typen
## Frame-Typen
| Wert | Name | Richtung | Bedeutung |
|---|---|---|---|
@@ -84,13 +84,14 @@ Das Protokoll ist so ausgelegt, dass es mit mindestens 100 Bytes auskommen sollt
| `0x41` | `LS_ENTRY` | Device -> Host | Verzeichniseintrag |
| `0x42` | `LS_END` | Device -> Host | Ende Verzeichnis-Stream |
## 5. Data-Typen (`REQUEST`)
## Data-Typen (`REQUEST`)
| Wert | Name | Status | Beschreibung |
|---|---|---|---|
| `0x01` | `PROTO_INFO` | aktiv | Protokollversion + max Chunkgröße |
| `0x02` | `DEVICE_INFO` | reserviert | aktuell nicht bedient |
| `0x02` | `DEVICE_INFO` | aktiv | Device-Infos (Board, Revision, SOC, ID) |
| `0x03` | `FS_INFO` | aktiv | Dateisystem- und Pfadinfos |
| `0x04` | `FW_INFO` | aktiv | Info über Firmware-Status und -Version sowie Kernelversion |
| `0x20` | `FILE_GET` | aktiv | Datei vom Device streamen |
| `0x21` | `FILE_PUT` | aktiv | Datei zum Device hochladen |
| `0x22` | `TAGS_GET` | aktiv | nur Tag-Bereich streamen |
@@ -100,9 +101,9 @@ Das Protokoll ist so ausgelegt, dass es mit mindestens 100 Bytes auskommen sollt
| `0x30` | `FW_UPDATE` | reserviert | aktuell nicht bedient |
| `0x40` | `LS` | aktiv | Verzeichnisliste starten |
## 6. Request/Response-Formate
## Request/Response-Formate
## 6.1 Generischer Request
### Generischer Request
```c
uint8_t data_type;
@@ -126,7 +127,7 @@ packet
+32: "Optional payload (variable length)"
```
## 6.2 `PROTO_INFO` (`0x01`)
### `PROTO_INFO` (`0x01`)
Request: keine Zusatzdaten.
@@ -150,7 +151,24 @@ packet
+16: "Max Chunk Size (LE)"
```
## 6.3 `FS_INFO` (`0x03`)
### `DEVICE_INFO` (`0x02`)
Request: keine Zusatzdaten.
Respone-Payload:
```c
uint8_t data_type; // 0x02
uint8_t[8] device_id;
uint8_t board_len;
uint8_t rev_len;
uint8_t soc_len;
uint8_t data[]; // board, rev und soc, ohne Nullterminierung
```
***Hinweis:*** In der aktuellen implementierung werden die Strings auf eine maximale Länge von 32 Zeichen beschränkt. Dies sollte für alle Fälle genügen.
### `FS_INFO` (`0x03`)
Request: keine Zusatzdaten.
@@ -163,7 +181,7 @@ uint32_t free_size; // LE
uint8_t max_path_length;
uint8_t sys_path_length;
uint8_t audio_path_length;
uint8_t data[]; // sys_path + audio_path (beide nicht nullterminiert)
uint8_t data[]; // sys_path + audio_path ohne Nullterminierung
```
Im `data` folgen sich System- und Audiopfad ohne Abstand, und ohne 0-Terminierung (`\0`). Beispiel für Systempfad `/lfs/sys`und Audiopfad `/lfs/a`:
@@ -213,7 +231,23 @@ Das Beispiel schaut in HEX so aus:
0x2F 0x6C 0x66 0x73 0x2F 0x73 0x79 0x73 0x2F 0x6C 0x66 0x73 0x2F 0x61
```
## 6.4 `LS` (`0x40`)
### `FW_INFO` (`0x04`)
Request: keine Zusatzdaten
Response:
```c
uint8_t fw_status; /* 0x00: Confirmed, 0x01: Pending, 0x02: Testing, 0xFF: Unbekannt */
uint32_t slot1_size; /* (LE) Grösse des Firmware Update Slots */
uint8_t fw_version_len; /* Länge des Firmware-Versionsstring */
uint8_t kernel_version_len; /* Länge des Kernel-Versionsstrings */
uint8_t data[]; /* FW-Version und Kernelversion, ohne Nullterminierung */
```
***Hinweis:*** in der Aktuellen implementierung werden die Versionen auf 32 Zeichen limitiert.
### `LS` (`0x40`)
Request-Payload:
@@ -222,7 +256,7 @@ uint8_t data_type; // 0x40
char path[]; // ohne Nullterminierung
```
## 6.5 `FILE_GET` (`0x20`) und `TAGS_GET` (`0x22`)
### `FILE_GET` (`0x20`) und `TAGS_GET` (`0x22`)
Request-Payload:
@@ -233,7 +267,7 @@ char path[]; // ohne Nullterminierung
Antwort ist ein Stream aus `FILE_START` -> `FILE_CHUNK`* -> `FILE_END`.
## 6.6 `FILE_PUT` (`0x21`) und `TAGS_PUT` (`0x23`)
### `FILE_PUT` (`0x21`) und `TAGS_PUT` (`0x23`)
Request-Payload:
@@ -247,7 +281,7 @@ Danach sendet der Host:
- `FILE_CHUNK` Frames
- abschließend `FILE_END` mit CRC32
## 6.7 `RM_FILE` (`0x24`)
### `RM_FILE` (`0x24`)
Request-Payload:
@@ -257,7 +291,7 @@ uint8_t path_length;
char path[]; // ohne Nullterminierung
```
## 6.8 `RENAME_FILE` (`0x25`)
### `RENAME_FILE` (`0x25`)
Request-Payload:
@@ -268,9 +302,9 @@ uint8_t new_path_length;
char paths[]; // old_path + new_path (jeweils ohne Nullterminierung)
```
## 7. ACK / ERROR / SUCCESS
## ACK / ERROR / SUCCESS
## 7.1 ACK (`0x11`)
### ACK (`0x11`)
Payload:
@@ -285,7 +319,7 @@ Wichtig: Es gibt zwei Semantiken je nach Richtung.
- Upload (`FILE_PUT`, `TAGS_PUT`):
Device -> Host, Credits sind zusätzlich gewährte Tokens (Host addiert sie).
## 7.2 ERROR (`0x12`)
### ERROR (`0x12`)
Payload:
@@ -310,7 +344,7 @@ Häufige Codes:
| `116` | `ETIMEDOUT` | Credit-/Stream-Timeout |
| `134` | `ENOTSUP` | nicht unterstützt |
## 7.3 SUCCESS (`0x13`)
### SUCCESS (`0x13`)
Payload:
@@ -320,9 +354,7 @@ uint8_t data_type; // erfolgreich abgeschlossener Befehl
Wird derzeit u.a. für `FILE_PUT`, `TAGS_PUT`, `RM_FILE`, `RENAME_FILE` genutzt.
## 8. Stream-Sequenzen (Mermaid)
## 8.1 Verzeichnisliste (`LS`)
## Verzeichnisliste (`LS`)
```mermaid
sequenceDiagram
@@ -346,7 +378,7 @@ sequenceDiagram
Hinweis zum aktuellen Web-Client (März 2026): Für `LS` wird initial `ACK(64)` gesendet, ein dynamisches Nachfüllen ist noch nicht implementiert. Große Verzeichnisse können deshalb in `ETIMEDOUT` laufen.
## 8.2 Datei-/Tag-Download (`FILE_GET`, `TAGS_GET`)
## Datei-/Tag-Download (`FILE_GET`, `TAGS_GET`)
```mermaid
sequenceDiagram
@@ -369,7 +401,7 @@ sequenceDiagram
Note over Host: CRC prüfen
```
## 8.3 Datei-/Tag-Upload (`FILE_PUT`, `TAGS_PUT`)
## Datei-/Tag-Upload (`FILE_PUT`, `TAGS_PUT`)
```mermaid
sequenceDiagram
@@ -395,9 +427,9 @@ sequenceDiagram
end
```
## 9. Payload-Frames im Detail
## Payload-Frames im Detail
## 9.1 `LS_ENTRY` (`0x41`)
### `LS_ENTRY` (`0x41`)
```c
uint8_t type; // 0x00 file, 0x01 dir
@@ -406,13 +438,13 @@ uint8_t name_length;
char name[]; // ohne Nullterminierung
```
## 9.2 `LS_END` (`0x42`)
### `LS_END` (`0x42`)
```c
uint32_t total_entries; // LE
```
## 9.3 `FILE_START` (`0x20`)
### `FILE_START` (`0x20`)
```c
uint32_t total_size; // LE
@@ -421,19 +453,19 @@ uint32_t total_size; // LE
`FILE_GET`: komplette Dateigröße.
`TAGS_GET`: nur Tag-Teil der Datei.
## 9.4 `FILE_CHUNK` (`0x21`)
### `FILE_CHUNK` (`0x21`)
Payload sind rohe Nutzdatenbytes.
## 9.5 `FILE_END` (`0x22`)
### `FILE_END` (`0x22`)
```c
uint32_t crc32; // LE, IEEE CRC32
```
## 10. Beispiel-Frames (Hex)
## Beispiel-Frames (Hex)
## 10.1 `PROTO_INFO` Request/Response
### `PROTO_INFO` Request/Response
Request:
@@ -454,7 +486,7 @@ Interpretation:
- `01 00`: Version 1
- `FD 00`: max_chunk_size = 253
## 10.2 `LS` Request für `/a`
### `LS` Request für `/a`
```text
00 03 00 40 2F 61
@@ -466,7 +498,7 @@ Interpretation:
- `40`: data_type LS
- `2F 61`: `/a`
## 11. Implementierungsnotizen
### Implementierungsnotizen
- Unknown `REQUEST.data_type` wird aktuell mit `ERROR(EINVAL)` beantwortet.
- Unbekannte/unerwartete `frame_type` im aktiven Protokollthread führen zu `ERROR(EPROTO)`.