# 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 0–15 (`0x00–0x0F`) | |---:|---| | 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 | | 10–11 | `0x0A–0x0B` | `50 00` | `94 00` | `D4 00` | entier little-endian corrélé à la taille | | 12 | `0x0C` | `00` | `00` | `01` | 227 distinct dans cette capture | | 13–15 | `0x0D–0x0F` | `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 10–11 (`0x0A–0x0B`) 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 10–11 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, 10–12. - 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.