Files
home-assistant-arkteos/docs/frame_protocol_analysis.md
T

168 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Analyse observable du flux Arkteos REG3
## Périmètre et méthode
Cette analyse porte exclusivement sur :
- `captures/stream_normal.bin` ;
- `references/arkteos_nodered_flow.json` ;
- `AGENTS.md`.
Les offsets sont relatifs au début d'une trame présumée, indexés à zéro, et
exprimés en décimal puis en hexadécimal. Les conclusions portant sur le
découpage sont établies à partir des octets de la capture, pas à partir de
limites de lectures TCP.
## Résumé
| Élément | Observation |
|---|---:|
| Taille totale de la capture | 43 165 octets (`0xA89D`) |
| Occurrences de `55 00` | 267 |
| Occurrences de chaque taille | 95 : 89 ; 163 : 89 ; 227 : 89 |
| Cycles complets observés | 89 |
| Ordre | `227 → 163 → 95`, sans exception dans cette capture |
La capture commence par `55 00` à l'offset global 0 (`0x0000`). Toutes les
occurrences suivantes sont séparées de la précédente par 227, 163 ou 95
octets. La dernière occurrence commence à l'offset global 43 070 (`0xA83E`) ;
les 95 octets restants terminent exactement la capture. Ces positions
partitionnent donc entièrement cette capture en 267 segments.
## Types et tailles observés
| Taille totale | Taille hex. | Occurrences | Nom dans le flow | Valeur observée à 8 (`0x08`) |
|---:|---:|---:|---|---:|
| 95 | `0x005F` | 89 | aucune branche de parsing | `0x0C` |
| 163 | `0x00A3` | 89 | `frigo` | `0x0A` |
| 227 | `0x00E3` | 89 | `regulation` | `0x0B` |
Le flow identifie `frigo` et `regulation` uniquement à partir de la taille du
buffer reçu (163 ou 227). Il ne contient pas de parsing pour 95 octets. Le nom
fonctionnel du type de 95 octets n'est donc pas déterminé par les trois fichiers
analysés.
## Signatures et en-têtes
Les 16 premiers octets sont invariants pour les 89 occurrences de chaque taille
dans cette capture :
| Taille | Octets 015 (`0x000x0F`) |
|---:|---|
| 95 | `55 00 58 FF A7 40 02 02 0C 00 50 00 00 00 00 00` |
| 163 | `55 00 9C FF 63 40 02 04 0A 00 94 00 00 00 00 00` |
| 227 | `55 00 DC FF 23 40 02 04 0B 00 D4 00 01 00 00 00` |
### Différences observables dans l'en-tête
| Offset déc. | Offset hex. | 95 octets | 163 octets | 227 octets | Observation |
|---:|---:|---:|---:|---:|---|
| 0 | `0x00` | `55` | `55` | `55` | commun |
| 1 | `0x01` | `00` | `00` | `00` | commun |
| 2 | `0x02` | `58` | `9C` | `DC` | distingue les trois tailles dans cette capture |
| 3 | `0x03` | `FF` | `FF` | `FF` | commun |
| 4 | `0x04` | `A7` | `63` | `23` | distingue les trois tailles dans cette capture |
| 5 | `0x05` | `40` | `40` | `40` | commun |
| 6 | `0x06` | `02` | `02` | `02` | commun |
| 7 | `0x07` | `02` | `04` | `04` | 95 distinct de 163 et 227 |
| 8 | `0x08` | `0C` | `0A` | `0B` | valeur distincte par taille dans cette capture |
| 9 | `0x09` | `00` | `00` | `00` | commun |
| 1011 | `0x0A0x0B` | `50 00` | `94 00` | `D4 00` | entier little-endian corrélé à la taille |
| 12 | `0x0C` | `00` | `00` | `01` | 227 distinct dans cette capture |
| 1315 | `0x0D0x0F` | `00 00 00` | `00 00 00` | `00 00 00` | commun |
Les octets 2 (`0x02`) et 4 (`0x04`) ont aussi la relation observée
`octet[2] + octet[4] = 0xFF` pour les trois signatures. Cette relation ne
démontre ni checksum ni signification fonctionnelle.
## Hypothèse de détection de longueur
L'entier non signé little-endian aux offsets 1011 (`0x0A0x0B`) a les valeurs
suivantes pour toutes les occurrences de chaque type :
| Taille totale observée | Valeur de `octets[10:12]` LE | Écart |
|---:|---:|---:|
| 95 | 80 (`0x0050`) | 15 (`0x000F`) |
| 163 | 148 (`0x0094`) | 15 (`0x000F`) |
| 227 | 212 (`0x00D4`) | 15 (`0x000F`) |
**Hypothèse probable :** dans cette capture, après lecture de 12 octets à
partir de `55 00`, la taille totale peut être calculée comme
`little_endian_u16(offset 10) + 15`.
Cette corrélation est vérifiée sur les 267 segments observés. Elle n'établit
pas le nom ou la sémantique de ce champ, ni sa validité pour d'autres versions,
types ou états de la PAC. Elle ne constitue pas une preuve d'un champ longueur
défini par le protocole.
La valeur à l'offset 8 (`0x08`) est une seconde signature probable de type :
`0x0A → 163`, `0x0B → 227`, `0x0C → 95` dans cette capture. Elle n'est pas une
preuve qu'il s'agit d'un identifiant de trame documenté.
## Séquence observée
Les 267 segments suivent exactement le motif répété :
```text
227, 163, 95, 227, 163, 95, … (89 répétitions)
```
Il n'y a ni répétition, ni inversion, ni omission dans la capture. Cela rend la
séquence régulière **pour cet échantillon**. Il n'est pas déterminé si elle est
obligatoire dans le protocole, si elle peut varier avec l'état de la PAC, ou si
des trames supplémentaires peuvent être intercalées.
## Ce qui est observé, probable et non déterminé
### Observé
- `55 00` apparaît 267 fois et permet une partition complète de cette capture.
- Les trois distances entre signatures sont exclusivement 95, 163 et 227.
- Chaque taille apparaît 89 fois, dans l'ordre cyclique indiqué.
- Les 16 octets d'en-tête listés sont constants pour chaque taille dans cet
échantillon.
- Le flow décode des champs aux offsets connus pour les segments de 163 et 227
octets ; il écarte les autres tailles.
### Probable, mais non spécifié
- `55 00` est une signature de début de segment dans ce flux.
- L'entier little-endian aux offsets 1011 permet de calculer la taille totale
observée par addition de 15.
- L'octet à l'offset 8 distingue les trois catégories observées.
### Non déterminé
- La signification des octets d'en-tête, y compris 2, 4, 7, 8, 1012.
- L'existence, la position ou l'algorithme d'un checksum.
- L'existence d'un champ longueur officiellement défini.
- La sémantique du segment de 95 octets.
- La stabilité des signatures, tailles et de l'ordre avec d'autres PAC,
versions logicielles ou états de fonctionnement.
- La relation entre les limites de cette capture et les lectures effectuées par
une socket TCP.
## Conséquences pour un extracteur TCP incrémental
TCP fournit un flux d'octets : une lecture peut contenir une fraction de
segment, un segment complet ou plusieurs segments. Le nœud Node-RED est réglé
en mode `stream`, mais son parser teste directement la taille de chaque message
reçu ; cette capture ne prouve pas que ce comportement soit sûr pour toutes les
segmentations TCP.
Un extracteur doit donc :
1. conserver les octets reçus dans un tampon persistant ;
2. rechercher `55 00` sans présumer que le début du tampon est une frontière ;
3. attendre au moins 12 octets avant d'évaluer l'hypothèse de taille ;
4. n'extraire un segment que lorsque la taille attendue est entièrement présente
dans le tampon ;
5. traiter les signatures ou tailles non observées comme non déterminées, sans
les faire passer au parser connu ;
6. prévoir une resynchronisation prudente si l'en-tête observé ne correspond
pas aux signatures documentées ici.
L'extracteur ne doit pas dépendre du cycle `227 → 163 → 95` pour délimiter les
segments : cette régularité est observée, mais non démontrée comme une règle de
protocole.