3.7 KiB
Protokoll
Hamnet70 implementiert die untersten beiden Schichten des ISO/OSI-Modells: Bitübertragungsschicht und Sicherungsschicht.
Schichtenmodell
Bitübertrangunsschicht
TODO: Modulation (OFDM? QAM16?)
Sicherungsschicht
Ein Faltungscode wird zur Fehlerkorrektur angewendet. Zusätzlich wird eine CRC32 über das komplette Paket berechnet und bei Fehlern das Paket verworfen (wenn der Faltungscode diese Fehler nicht korrigieren konnte).
Headerformat:
Word | Bits 31..24 | 23..16 | 15..8 | 7..0 |
---|---|---|---|---|
0 | Absender-Rufzeichen (47..16) [1] | |||
1 | Absender-Rufzeichen (15..0) [1] | Absender-Stations-ID | Empfänger-Stations-ID | |
2 | Empfänger-Rufzeichen (47..16) [1] | |||
3 | Empfänger-Rufzeichen (15..0) [1] | Next Protocol | Flags |
[1] verwendet Base40-Codierung, siehe unten
Stations-ID
Wird verwendet, um mehrere Stationen mit dem selben Rufzeichen zu unterscheiden (analog zu APRS/Packet Radio).
Next Protocol
Im Paket enthaltenes Protokoll:
Wert | Protokoll |
---|---|
0x00 | Steuerpaket / Fülldaten |
0x10 | IPv4 |
0x20 | IPv6 |
0x30 | IPX |
Flags
Flags dienen zur Steuerung des Kontrollflusses. In normalen Datenpaketen sind keine Flags gesetzt.
Dieses Feld ist eine Oder-Verknüpfung der folgenden Werte:
Wert | Information |
---|---|
0x01 | Anmeldung am Zugangspunkt |
0x02 | Abmeldung vom Zugangspunkt |
0x04 | Datenabfrage an verbundene Station |
0x08 | Leere Bestätigung von verbundener Station |
sonstige | reserviert |
0x80 | Paket abgelehnt (Station nicht angemeldet) |
Höhere Schichten
Höhere Schichten enthalten meistens das Internet Protocol (IP).
Verwendete Codierung
Base40-Codierung für Rufzeichen
Rufzeichen werden in Base40 codiert. Diese ermöglicht es, gemäß folgendem
Schema 9 Zeichen in 48 Bit unterzubringen, nachdem c0
bis c8
entsprechend
der nachfolgenden Tabelle codiert wurden:
uint16_t word0 = c0 * 1600 + c1 * 40 + c2;
uint16_t word1 = c3 * 1600 + c4 * 40 + c5;
uint16_t word2 = c6 * 1600 + c7 * 40 + c8;
uint64_t addr = (word0 << 32) | (word1 << 16) | word3;
Zeichen | NULL | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Code | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
Zeichen | T | U | V | W | X | Y | Z | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | / | reserved |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Code | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38-39 |
Das NULL-Zeichen markiert das Ende der Zeichenkette.
Das Rufzeichen DL5TKL/P würde beispielsweise wie folgt in 48 bit codiert:
c0 = 4; c1 = 12; c2 = 32;
c3 = 20; c4 = 11; c5 = 12;
c6 = 37; c7 = 16; c8 = 0;
word0 = 4 * 1600 + 12 * 40 + 32 = 6912 = 0x1b00;
word1 = 20 * 1600 + 11 * 40 + 12 = 32452 = 0x7ec4;
word2 = 37 * 1600 + 16 * 40 + 0 = 59840 = 0xe9c0;
addr = 0x1b007ec4e9c0;
Die Decodierung kann mit Hilfe der Modulo-Operation erfolgen, z.B.:
uint16_t word0 = (addr >> 32) & 0xFFFF;
c0 = word0 % 40;
c1 = (word0 / 40) % 40;
c2 = word0 / 1600;
// entsprechend für die anderen Wörter/Zeichen