diff --git a/_config.yml b/_config.yml new file mode 100644 index 0000000..c741881 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/pages/02.part-1/02.glossary/docs.md b/pages/02.part-1/02.glossary/docs.md index 9b25e06..3d67baa 100644 --- a/pages/02.part-1/02.glossary/docs.md +++ b/pages/02.part-1/02.glossary/docs.md @@ -14,8 +14,8 @@ Forward Error Correction ### Frame The individual components of a stream, each of which contains payload data interleaved with frame signalling. -### Link Information Frame -The first frame of any transmission. It contains full LICH data. +### Link Setup Frame +The first frame of any transmission. It contains full link information data. ### LICH Link Information Channel. The LICH contains all information needed to establish an M17 link. The first frame of a transmission contains full LICH data, and subsequent frames each contain one sixth of the LICH data so that late-joiners can obtain the LICH. diff --git a/pages/02.part-1/03.physical-layer/docs.md b/pages/02.part-1/03.physical-layer/docs.md index 8df72ca..a3666a6 100644 --- a/pages/02.part-1/03.physical-layer/docs.md +++ b/pages/02.part-1/03.physical-layer/docs.md @@ -5,45 +5,37 @@ taxonomy: - docs simple-responsive-tables: active: true -media_order: 'convolutional.svg,frame_encoding.svg,link_setup_frame_encoding.svg,packet_frame_encoding.svg' +media_order: --- -### 4FSK generation +This section describes the M17 standard radio physical layer suitable for use where a transmission bandwidth of 9 KHz is permitted. -M17 standard uses 4FSK modulation running at 4800 symbols/s (9600 -bits/s) with a deviation index h=0.33 for transmission in 9 kHz -channel bandwidth. Channel spacing is 12.5 kHz. The symbol stream is -converted (upsampled) to a series of impulses which pass through a -root-raised-cosine (alpha=0.5) shaping filter before frequency modulation -at the transmitter and again after frequency demodulation at the -receiver. +### 4-level Frequency-shift Keying Modulation (4FSK) -[mermaid] -graph LR - id1[Dibits Input] --> id2[Upsampler] --> id3[RRC Filter] --> id4[Frequency Modulation] --> id5[4FSK Output] - style id1 fill:#ffffffff,stroke:#ffffffff,stroke-width:0px - style id2 fill:#fff,stroke:#000,stroke-width:2px - style id3 fill:#fff,stroke:#000,stroke-width:2px - style id4 fill:#fff,stroke:#000,stroke-width:2px - style id5 fill:#ffffffff,stroke:#ffffffff,stroke-width:0px -[/mermaid] +The M17 standard uses 4FSK at 4800 symbols/s (9600 +bits/s) with a deviation index h=0.33 for transmission in a 9 kHz +channel bandwidth. Minimum channel spacing is 12.5 kHz. -The bit-to-symbol mapping is shown in the table below. +#### Dibit, Symbol, and Frequency-shift + +Each of the 4-level frequency-shifts can be represented by dibits (2-bit values) or symbols, as shown in Table 1 below. + +In the case of dibits, the most significant bit is sent first. When four dibits are grouped into a byte, the most significant dibit of the byte is sent first. For example, the four dibits contained in the byte 0xB4 (0b 10 11 01 00) would be sent as the symbols (-1, -3, +3, +1). - + - - - + + + - - + + - + @@ -71,204 +63,133 @@ The bit-to-symbol mapping is shown in the table below.
Table 1 Dibit symbol mapping to 4FSK deviationTable 1 Dibit symbol mapping to 4FSK deviation
Information bitsSymbol4FSK deviationDibitSymbol4FSK deviation
Bit 1Bit 0MSBLSB
0 1
-The most significant bits are sent first, meaning that the byte 0xB4 (= 0b10'11'01'00) in type 4 bits (see [bit types](#bit-types)) would be sent as the symbols -1 -3 +3 +1. All data fields utilize big-endian order of bytes unless specified otherwise. +#### 4FSK Generation + +
Figure 1 Dibit to 4FSK Generation
+[mermaid] +graph LR + id1[Dibit Input] --> sym[Dibit to Symbol] --> id2[Upsampler] --> id3[RRC Filter] --> id4[Frequency Modulation] --> id5[4FSK Output] + style id1 fill:#ffffffff,stroke:#ffffffff,stroke-width:0px + style sym fill:#fff,stroke:#000,stroke-width:2px + style id2 fill:#fff,stroke:#000,stroke-width:2px + style id3 fill:#fff,stroke:#000,stroke-width:2px + style id4 fill:#fff,stroke:#000,stroke-width:2px + style id5 fill:#ffffffff,stroke:#ffffffff,stroke-width:0px +[/mermaid] + +Dibits are converted to symbols. The symbol stream is upsampled to a series of impulses which pass through a +root-raised-cosine (alpha=0.5) shaping filter before frequency modulation +at the transmitter and again after frequency demodulation at the +receiver. + +Upsampling by a factor of 10 is recommended (48000 samples/s). + +The root-raised-cosine filter should span at least 8 symbols (81 taps at the recommended upsample rate). + +### Transmission + +A complete transmission shall consist of a [Preamble](#preamble), a [Synchronization Burst](#synchronization-burst-sync-burst), [Payload](#payload), and an [End of Transmission](#end-of-transmission-marker-eot) marker. + + + + + + + + + + + + + + + + + +
Figure 2 Physical Layer Transmission
PREAMBLESYNC BURSTPAYLOADEoT
40ms
(192 symbols)
16 bits
(8 symbols)
Multiples of 2 bits
(Multiples of 1 symbol)
40ms
(192 symbols)
+ +Transmissions may include more than one synchronization burst followed by a payload. + + + + + + + + + + + + + + + + +
Figure 3 Physical Layer Transmission with Multiple Synchronization Bursts
PREAMBLESYNC BURSTPAYLOADSYNC BURSTPAYLOAD•••SYNC BURSTPAYLOADEoT
### Preamble -Every transmission starts with a preamble, which shall consist of at least 40 ms of alternating outer symbols. This is equivalent to 40 milliseconds of a 2400 Hz tone. The last symbol transmitted within the preamble shall be -3 for all modes except BERT. This is to avoid unnecessary long constant symbol runs and increase zero-crossing rate. +Every transmission shall start with a preamble, which shall consist of 40 ms (192 symbols) of alternating outer symbols (+3, -3) or (-3, +3). To ensure a zero crossing prior to a synchronization burst, the last symbol transmitted within the preamble shall be opposite the first symbol transmitted in the synchronization burst. -### Bit types +### Synchronization Burst (Sync Burst) -The bits at different stages of the error correction coding are referred to with bit types, given in the following table. +A sync burst of 16 bits (8 symbols) shall be sent immediately after the preamble. The sync burst is constructed using only outer symbols, with +codings based on [Barker codes](https://en.wikipedia.org/wiki/Barker_code). Properly chosen sync burst coding assists in symbol clocking and alignment. +Different sync burst codes may also be used by the [Data Link Layer](../data-link-layer#synchronization-burst-sync-burst) to identify the type of payload to follow. -Type | Description ----- | ----------- -Type 1 | Data link layer bits -Type 2 | Bits after appropriate encoding -Type 3 | Bits after puncturing (only for convolutionally coded data, for other ECC schemes type 3 bits are the same as type 2 bits) -Type 4 | Decorrelated and interleaved (re-ordered) type 3 bits +### Payload -Type 4 bits are used for transmission over the RF. Incoming type 4 bits shall be decoded to type 1 bits, which are then used to extract all the frame fields. +Payload shall be transmitted in multiples of 2 bits (1 symbol). -### Error correction coding schemes and bit type conversion +### Randomizer -Two distinct ECC/FEC schemes are used for different parts of the transmission. +To avoid transmitting long sequences of constant symbols (e.g. +3, +3, +3, ...), a simple randomizing algorithm is used. At the transmitter, all payload bits shall be XORed with a pseudorandom predefined sequence before being converted to symbols. At the receiver, the randomized payload symbols are converted to bits and are +again passed through the same XOR algorithm to obtain the original payload bits. -#### Link setup frame (LSF) +The pseudorandom sequence is composed of the 46 bytes (368 bits) found in the appendix ([Decorrelator Sequence](../../appendix/decorrelator-sequence)). -![link_setup_frame_encoding](link_setup_frame_encoding.svg?classes=caption "ECC Link Setup Frame Encoding") +Before each bit of payload is converted to symbols for transmission, it is XORed with a bit from the pseudorandom sequence. The first payload bit is XORed with most significant bit (bit 7) of sequence byte 0 (0xD6), second payload bit with bit 6 of sequence byte 0, continuing to the eigth payload bit and bit 0 of sequence byte 0. The ninth payload bit is XORed with bit 7 of sequence byte 1 (0xB5), tenth payload bit with bit 6 of sequence byte 1, etc. -240 DST, SRC, TYPE, META and CRC type 1 bits are convolutionally coded using rate 1/2 coder with constraint K=5. 4 tail bits are used to flush the encoder’s state register, giving a total of 244 bits being encoded. Resulting 488 type 2 bits are retained for type 3 bits computation. Type 3 bits are computed by puncturing type 2 bits using a scheme shown in chapter 4.4. This results in 368 bits, which in conjunction with the synchronization burst gives 384 bits (384 bits / 9600bps = 40 ms). +When payload bits have XORed through sequence byte 45 (0xC3), the psuedorandom sequence is restarted at sequence byte 0 (0xD6) -Interleaving type 3 bits produce type 4 bits that are ready to be transmitted. Interleaving is used to combat error bursts. +On the receive side, symbols are converted to randomized payload bits. Each randomized payload bit is converted back to a payload bit by once again XORing each randomized bit with the corresponding pseudorandom sequence bit. -#### Subsequent frames +### End of Transmission marker (EoT) -![frame_encoding](frame_encoding.svg?classes=caption "ECC stages of subsequent frames") +Every transmission ends with a distinct symbol stream, which shall consist of of 40 ms (192 symbols) of a repeating 0x55 0x5D (+3, +3, +3, +3, +3, +3, -3, +3) pattern. -A 40-bit (type 1) chunk of the LSF along with a 3-bit modulo 6 counter (LICH_CNT) and 5 reserved bits (see Table 7) is partitioned into 4 12-bit parts and encoded using Golay (24, 12) code. This produces 96 encoded bits of type 2. These bits are used in the Link Information Channel (LICH). +### Carrier-sense Multiple Access (CSMA) -16-bit FN and 128 bits of payload (144 bits total) are convolutionally encoded in a manner analogous to that of the link setup frame. A total of 148 bits is being encoded resulting in 296 type 2 bits. These bits are punctured to generate 272 type 3 bits. +CSMA may be used to minimize collisions on a shared radio frequency by having the sender ensure the frequency is clear before transmitting. Higher layers (Data Link and Application) may require the use of CSMA, and may specify parameters other than the defaults. -96 type 2 bits of LICH are concatenated with 272 type 3 bits and re-ordered to form type 4 bits for transmission. This, along with 16-bit sync in the beginning of frame, gives a total of 384 bits +[P-persistent](https://en.wikipedia.org/wiki/Carrier-sense_multiple_access) access is used with a default probability of p = 0.25 and default slot time of 40 ms. -The LICH chunks allow for late listening and indepedent decoding to check destination address. The goal is to require less complexity to decode just the LICH and check if the full message should be decoded. +### Physical Layer Flow Summary -#### Packet Frame Encoding +
Figure 4 Physical Layer Flow
+[mermaid] +graph TD -![packet_frame_encoding](packet_frame_encoding.svg?classes=caption "Packet Frame Encoding") +payload["Payload"] +phy_randomizer["randomizer"] +phy_sync["prepend SYNC BURST"] +phy_chunk_dibit["chunk dibit"] +phy_dibit_to_symbol["dibit to symbol"] +phy_upsampler["upsampler"] +phy_filter["rrc filter"] +phy_frequency_modulation["frequency modulation"] +phy_rf["4FSK RF"] -#### End of Transmission marker (EoT) +classDef default fill:#fff,stroke:#000,stroke-width:2px -Every transmission ends with a distinct symbol stream, which shall consist of at least 40 ms of repeating +3, +3, +3, +3, +3, +3, -3, +3 pattern, or 0x555D in hexadecimal notation. +payload --> phy_randomizer +Preamble --> phy_chunk_dibit +phy_chunk_dibit --> phy_dibit_to_symbol --> phy_upsampler --> phy_filter --> phy_frequency_modulation --> phy_rf +phy_randomizer --> phy_sync --> phy_chunk_dibit +EoT --> phy_chunk_dibit +[/mermaid] -#### Extended Golay(24,12) code +### Issues to address... -The extended Golay(24,12) encoder uses generating polynomial g given below to generate the 11 check bits. The check bits and an additional parity bit are appended to the 12 bit data, resulting in a 24 bit codeword. The resulting code is systematic, meaning that the input data (message) is embedded in the codeword. +* Time limits for RF carrier and no symbol generation before the preamble and after the EoT. -\(g(x) = x^{11} + x^{10} + x^6 + x^5 + x^4 + x^2 + 1\) - -This is equivalent to 0xC75 in hexadecimal notation. Both the generating matrix \(G\) and parity check matrix \(H\) are shown below. - -\( -\begin{align} - G = \begin{bmatrix} I_k | P \end{bmatrix} = & \begin{bmatrix} - 1&0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&0&1\\ - 0&1&0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&1\\ - 0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0&0&0\\ - 0&0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0&0\\ - 0&0&0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0\\ - 0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&0&0&1\\ - 0&0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&0&1\\ - 0&0&0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&1\\ - 0&0&0&0&0&0&0&0&1&0&0&0&1&1&0&1&1&1&0&0&0&1&1&0\\ - 0&0&0&0&0&0&0&0&0&1&0&0&1&0&1&0&1&0&0&1&0&1&1&1\\ - 0&0&0&0&0&0&0&0&0&0&1&0&1&0&0&1&0&0&1&1&1&1&1&0\\ - 0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&0&1&1\\ - \end{bmatrix} -\newline\newline - H = \begin{bmatrix} P^T | I_k \end{bmatrix} = & \begin{bmatrix} - 1&0&1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&0\\ - 1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0&0&0\\ - 0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0&0\\ - 0&0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0\\ - 0&0&0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0\\ - 1&0&1&0&1&0&1&1&1&0&0&1&0&0&0&0&0&1&0&0&0&0&0&0\\ - 1&1&1&1&0&0&0&1&0&0&1&1&0&0&0&0&0&0&1&0&0&0&0&0\\ - 1&1&0&1&1&1&0&0&0&1&1&0&0&0&0&0&0&0&0&1&0&0&0&0\\ - 0&1&1&0&1&1&1&0&0&0&1&1&0&0&0&0&0&0&0&0&1&0&0&0\\ - 1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&1&0&0\\ - 0&1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&1&0\\ - 1&1&0&0&0&1&1&1&0&1&0&1&0&0&0&0&0&0&0&0&0&0&0&1\\ - \end{bmatrix} -\end{align} -\) - -The output of the Golay encoder is shown in the table below. - -Field | Data | Check bits | Parity ------ | ---- | ---------- | ------ -Position | 23..12 | 11..1 | 0 (LSB) -Length | 12 | 11 | 1 - -Four of these 24-bit blocks are used to reconstruct the LSF. - -Sample MATLAB/Octave code snippet for generating \(G\) and \(H\) matrices is shown below. - -``` - -P = hex2poly('0xC75'); -[H,G] = cyclgen(23, P); - -G_P = G(1:12, 1:11); -I_K = eye(12); -G = [I_K G_P P.']; -H = [transpose([G_P P.']) I_K]; -``` - -### Convolutional encoder - -The convolutional code shall encode the input bit sequence after appending 4 tail bits at the end of the sequence. Rate of the coder is R=½ with constraint length K=5. The encoder diagram and generating polynomials are shown below. - -\( -\begin{align} - G_1(D) =& 1 + D^3 + D^4 \\ - G_2(D) =& 1+ D + D^2 + D^4 -\end{align} -\) - -The output from the encoder must be read alternately. - -![convolutional](convolutional.svg?classes=caption "Convolutional coder diagram") - -### Code puncturing - -Removing some of the bits from the convolutional coder’s output is called code puncturing. The nominal coding rate of the encoder used in M17 is ½. This means the encoder outputs two bits for every bit of the input data stream. To get other (higher) coding rates, a puncturing scheme has to be used. - -Two different puncturing schemes are used in M17 stream mode: - -1. \(P_1\) leaving 46 from 61 encoded bits -2. \(P_2\) leaving 11 from 12 encoded bits - -Scheme \(P_1\) is used for the *link setup frame*, taking 488 bits of encoded data and selecting 368 bits. The \(gcd(368, 488)\) is 8 which, when used to divide, leaves 46 and 61 bits. However, a full puncture pattern requires the puncturing matrix entries count to be divisible by the number of encoding polynomials. For this case a partial puncture matrix is used. It has 61 entries with 46 of them being ones and shall be used 8 times, repeatedly. The construction of the partial puncturing pattern \(P_1\) is as follows: - -\( -\begin{align} - M = & \begin{bmatrix} - 1 & 0 & 1 & 1 - \end{bmatrix} \\ - P_{1} = & \begin{bmatrix} - 1 & M_{1} & \cdots & M_{15} - \end{bmatrix} -\end{align} -\) - -In which \(M\) is a standard 2/3 rate puncture matrix and is used 15 times, along with a leading \(1\) to form \(P_1\), an array of length 61. - -The first pass of the partial puncturer discards \(G_1\) bits only, second pass discards \(G_2\), third - \(G_1\) again, and so on. This ensures that both bits are punctured out evenly. - -Scheme \(P_2\) is for frames (excluding LICH chunks, which are coded differently). This takes 296 encoded bits and selects 272 of them. Every 12th bit is being punctured out, leaving 272 bits. The full matrix shall have 12 entries with 11 being ones. - -The puncturing scheme \(P_2\) is defined by its partial puncturing matrix: - -\( -\begin{align} - P_2 = & \begin{bmatrix} - 1 & 1 & 1 & 1 & 1 & 1 \\ - 1 & 1 & 1 & 1 & 1 & 0 - \end{bmatrix} -\end{align} -\) - -The linearized representations are: - -``` -P1 = [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, - 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, - 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1] - -P2 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0] -``` - -One additional puncturing scheme \(P_3\) is used in the packet mode. The puncturing scheme is defined by its puncturing matrix: - -\( -\begin{align} - P_3 = & \begin{bmatrix} - 1 & 1 & 1 & 1 \\ - 1 & 1 & 1 & 0 - \end{bmatrix} -\end{align} -\) - -The linearized representation is: - -``` -P3 = [1, 1, 1, 1, 1, 1, 1, 0] -``` - -### Interleaving - -For interleaving a Quadratic Permutation Polynomial (QPP) is used. The polynomial \(\pi(x)=(45x+92x^2)\mod 368\) is used for a 368 bit interleaving pattern QPP. See appendix sec-interleaver for pattern. - -To avoid transmitting long sequences of constant symbols (e.g. 010101…), a simple algorithm is used. All 46 bytes of type 4 bits shall be XORed with a pseudorandom, predefined stream. The same algorithm has to be used for incoming bits at the receiver to get the original data stream. See decorr-seq for sequence. diff --git a/pages/02.part-1/03.physical-layer/phy_layer.svg b/pages/02.part-1/03.physical-layer/phy_layer.svg new file mode 100644 index 0000000..6f32d14 --- /dev/null +++ b/pages/02.part-1/03.physical-layer/phy_layer.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/pages/02.part-1/03.physical-layer/phy_layer_multi.svg b/pages/02.part-1/03.physical-layer/phy_layer_multi.svg new file mode 100644 index 0000000..efb3a0e --- /dev/null +++ b/pages/02.part-1/03.physical-layer/phy_layer_multi.svg @@ -0,0 +1,207 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pages/02.part-1/03.physical-layer/convolutional.svg b/pages/02.part-1/04.data-link-layer/convolutional.svg similarity index 100% rename from pages/02.part-1/03.physical-layer/convolutional.svg rename to pages/02.part-1/04.data-link-layer/convolutional.svg diff --git a/pages/02.part-1/04.data-link-layer/docs.md b/pages/02.part-1/04.data-link-layer/docs.md index b748043..e34e81a 100644 --- a/pages/02.part-1/04.data-link-layer/docs.md +++ b/pages/02.part-1/04.data-link-layer/docs.md @@ -3,48 +3,80 @@ title: 'Data Link Layer' taxonomy: category: - docs -media_order: M17_stream.png +media_order: --- -The Data Link layer is split into three modes: +### Frame -* Packet mode - Data are sent in small bursts, on the order of 100s to 1000s of bytes at a time, after which the physical layer stops sending data. e.g. messages, beacons, etc. +A Frame shall be composed of a frame type specific [Synchronization Burst (Sync Burst)](#synchronization-burst-sync-burst) followed by 368 bits (184 symbols) of Payload. The combination of Sync Burst plus Payload results in a constant 384 bit (192 symbol) Frame. At the M17 data rate of 4800 symbols/s (9600 bits/s), each Frame is exactly 40ms in duration. -* Stream mode - Data are sent in a continuous stream for an indefinite amount of time, with no break in physical layer output, until the stream ends. e.g. voice data, bulk data transfers, etc. +There are four frame types each with their own specific Sync Burst: [Link Setup Frames (LSF)](#link-setup-frame-lsf), Bit Error Rate Test (BERT) Frames, [Stream Frames](#stream-frames), and [Packet Frames](#packet-frames). -* BERT mode + + + + + + + + +
Figure 5 Frame
SYNC BURST
(16 bits / 8 symbols)
PAYLOAD
(368 bits / 184 symbols)
+ +The Data Link Layer Contents of a specific frame are processed with techniques (forward error correction) that aid in error correction at the receiver. It is these forward error corrected contents that are inserted into the Payload portion of the Frame. The exact forward error correction techniques used vary by frame type. + +
Figure 1 Contents to Payload
+[mermaid] +graph LR + contents[Data Link Layer Contents] --> fec[Forward Error Correction] --> payload[Payload] + style contents fill:#ffffffff,stroke:#ffffffff,stroke-width:0px + style fec fill:#fff,stroke:#000,stroke-width:2px + style payload fill:#ffffffff,stroke:#ffffffff,stroke-width:0px +[/mermaid] + + +### Modes + +The Data Link layer shall operate in one of three modes during a [Transmission](../physical-layer#transmission). + +* [Stream Mode](#stream-mode) + Data are sent in a continuous stream for an indefinite amount of time, with no break in physical layer output, until the stream ends. e.g. voice data, bulk data transfers, etc. + Stream Mode shall start with an LSF and is followed by one or more Stream Frames. + +* [Packet Mode](#packet-mode) + Data are sent in small bursts, up to 798 bytes at a time, after which the physical layer stops sending data. e.g. messages, beacons, etc. + Packet Mode shall start with an LSF and is followed by one to 32 Packet Frames. + +* [BERT Mode](#bert-mode) PRBS9 is used to fill frames with a deterministic bit sequence. Frames are sent in a continuous sequence. + Bert Mode shall start with a BERT frame, and is followed by one or more BERT Frames. -When the physical layer is idle (no RF being transmitted or received), the data link defaults to packet mode. +**Note:** As is the convention with other networking protocols, all values and data structures are encoded in big endian byte order. -As is the convention with other networking protocols, all values are -encoded in big endian byte order. +### Synchronization Burst (Sync Burst) -### Stream Mode +All frames shall be preceded by 16 bits (8 symbols) of [Sync Burst](../physical-layer#synchronization-burst-sync-burst). The Sync Burst definition straddles both the Physical Layer and the Data Link Layer. -In Stream Mode, an *indefinite* amount of payload data is sent continuously without breaks in the physical layer. The *stream* is broken up into parts, called *frames* to not confuse them with *packets* sent in packet mode. Frames contain payload data interleaved with frame signalling (similar to packets). Frame signalling is contained within the **Link Information Channel (LICH)**. +Only LSF and BERT Sync Bursts may immediately follow the [Preamble](../physical-layer#preamble), and each requires a different Preamble symbol pattern as shown in the table below. -#### Sync Burst +During a [Transmission](../physical-layer#transmission), only one LSF Sync Burst may be present, and if present, it shall immediately follow the Preamble. -All frames are preceded by a 16-bit *synchronization burst*. +BERT Sync Bursts, if present, may only follow the Preamble or other BERT frames. -* Link setup frames shall be preceded with 0x55F7. -* Stream frames shall be preceeded with 0xFF5D. -* Packet frames shall be preceeded with 0x75FF. -* BERT frames shall be preceeded with 0xDF55. +Multiple Stream and Packet Sync Bursts may be present during a Transmission. -All syncwords are type 4 bits. +
Table 2 Frame Specific Sync Bursts
+Frame Type | Preamble | Sync Burst Bytes | Sync Burst Symbols +---------- | -------- | ---------------- | ------------------ +LSF | +3, -3 | 0x55 0xF7 | +3, +3, +3, +3, -3, -3, +3, -3 +BERT | -3, +3 | 0xDF 0x55 | -3, +3, -3, -3, +3, +3, +3, +3 +Stream | None | 0xFF 0x5D | -3, -3, -3, -3, +3, +3, -3, +3 +Packet | None | 0x75 0xFF | +3, -3, +3, +3, -3, -3, -3, -3 -These sync words are based on [Barker codes](https://en.wikipedia.org/wiki/Barker_code). +### Link Setup Frame (LSF) -#### Link setup frame - -First frame of the transmission contains full LSF data. It’s called the **Link Setup Frame (LSF)**, and is not part of any superframes. - -##### LSF Fields +The LSF is the intial frame for both Stream and Packet Modes and contains information needed to establish a link. +
Table 3 Link Setup Frame Contents
Field | Length | Description ----- | ------ | ----------- DST | 48 bits | Destination address - Encoded callsign or a special number (eg. a group) @@ -52,99 +84,32 @@ SRC | 48 bits | Source address - Encoded callsign of the originator or a spec TYPE | 16 bits | Information about the incoming data stream META | 112 bits | Metadata field, suitable for cryptographic metadata like IVs or single-use numbers, or non-crypto metadata like the sender’s GNSS position. CRC | 16 bits | CRC for the link setup data -TAIL | 4 bits | Flushing bits for the convolutional encoder that do not carry any information. Only included for RF frames, not included for IP purposes. +Total: 240 bits -##### Bitfields of Type Field +##### LSF DST and SRC +Destination and source addresses may be encoded amateur radio callsigns, or special numbers. See the [Address Encoding Appendix](../../appendix/address-encoding) for details. + +##### LSF TYPE + +The TYPE field contains information about the frames to follow LSF. The Packet/Stream indicator bit determines which mode (Packet or Stream) will be used during the transmission. +The remaining field meanings are defined by the specific application. + +
Table 4 LSF TYPE definition
Bits | Meaning ---- | ------- -0 | Packet/stream indicator, 0=packet, 1=stream -1..2 | Data type indicator, $01_2$ =data (D), $10_2$ =voice (V), $11_2$ =V+D, $00_2$ =reserved -3..4 | Encryption type, $00_2$ =none, $01_2$ =AES, $10_2$ =scrambling, $11_2$ =other/reserved -5..6 | Encryption subtype (meaning of values depends on encryption type) +0 | Packet/Stream indicator, 0=Packet Mode, 1=Stream Mode +1..2 | Data type indicator +3..4 | Encryption type +5..6 | Encryption subtype 7..10 | Channel Access Number (CAN) 11..15 | Reserved (don’t care) -The fields in Table 3 (except TAIL) form initial LSF. It contains all information needed to establish M17 link. Later in the transmission, the initial LSF is divided into 6 “chunks” and transmitted beside the payload data. This allows late-joiners to reconstruct the LICH after collecting all the pieces, and start decoding the stream even though they missed the beginning of the transmission. The process of collecting full LSF takes 6 frames or 6\*40 ms = 240 ms. Four TAIL bits are needed for the convolutional coder to go back to state 0, so the ending trellis position is also known. +##### LSF META -Voice coder rate is inferred from TYPE field, bits 1 and 2. +The LSF META field is defined by the specific application. -##### Voice Coder Rates - -Data Type Indicator | Voice Coder Rate -------------------- | ---------------- -$00_2$ | none / reserved -$01_2$ | no voice -$10_2$ | 3200 bps -$11_2$ | 1600 bps - -#### Subsequent Frames - -##### Fields for Frames other than LSF - -Field | Length | Description ------ | ------ | ----------- -LICH | 48 bits | LSF chunk, one of 6 -FN | 16 bits | Frame number, starts from 0 and increments every frame to a max of 0x7fff where it will then wrap back to 0. High bit set indicates this frame is the last of the stream -PAYLOAD | 128 bits | Payload/data, can contain arbitrary data -TAIL | 4 bits | Flushing bits for the convolutional encoder that don’t carry any information - -The most significant bit in the FN counter is used for transmission end signalling. When transmitting the last frame, it shall be set to 1 (one), and 0 (zero) in all other frames. - -The payload is used so that earlier data in the voice stream is sent first. For mixed voice and data payloads, the voice data is stored first, then the data. - -##### LSF Chunk Structure - -Bits | Content ----- | ------- -0..39 | 40 bits of full LSF -40..42 | A modulo 6 counter (LICH_CNT) for LSF re-assembly -43..47 | Reserved - -##### Payload Example 1 - -`Codec2 encoded frame t + 0 | Codec2 encoded frame t + 1` - -##### Payload Example 2 - -`Codec2 encoded frame t + 0 | Mixed data t + 0` - -#### Superframes - -Each frame contains a chunk of the LSF frame that was used to establish the stream. Frames are grouped into superframes, which is the group of 6 frames that contain everything needed to rebuild the original LSF packet, so that the user who starts listening in the middle of a stream (late-joiner) is eventually able to reconstruct the LSF message and understand how to receive the in-progress stream. - -![M17_stream](M17_stream.png?classes=caption "Stream consisting of one superframe") - -[mermaid] -graph TD -c0["conv. coder"] -p0["P_1 puncturer"] -i0["interleaver"] -w0["decorrelator"] -s0["prepend LSF_SYNC"] -l0["LICH combiner"] -chunker_40["chunk 40 bits"] -golay_24_12["Golay (24, 12)"] -c1["conv. coder"] -p1["P_2 puncturer"] -i1["interleaver"] -w1["decorrelator"] -s1["prepend FRAME_SYNC"] -fn["add FN"] -chunker_128["chunk 128 bits"] -framecomb["Frame Combiner"] -supercomb["Superframe Combiner"] - -counter --> l0 -LSF --> c0 --> p0 --> i0 --> w0 --> s0 --> supercomb -LSF --> chunker_40 --> l0 --> golay_24_12 --> framecomb -data --> chunker_128 --> fn --> c1 --> p1 --> framecomb -framecomb --> i1 --> w1 --> s1 --> supercomb -preamble --> supercomb -[/mermaid] -
An overview of the forward dataflow
- -#### CRC +##### LSF CRC M17 uses a non-standard version of 16-bit CRC with polynomial $x^{16} + x^{14} + x^{12} + x^{11} + x^8 + x^5 + x^4 + x^2 + 1$ or 0x5935 and initial value of 0xFFFF. This polynomial allows for detecting all errors up to hamming distance of 5 with payloads up to 241 bits, which is less than the amount of data in each frame. @@ -154,6 +119,7 @@ The input to the CRC algorithm consists of DST, SRC (each 48 bits), 16 bits of T The test vectors in the following table are calculated by feeding the given message and then 16 zero bits to the CRC algorithm. +
Table 5 CRC Test Vectors
Message | CRC Output ------- | ---------- (empty string) | 0xFFFF @@ -161,13 +127,668 @@ ASCII string "A" | 0x206E ASCII string "123456789" | 0x772B Bytes 0x00 to 0xFF | 0x1c31 +### Stream Mode + +In Stream Mode, an *indefinite* amount of data is sent continuously without breaks in the physical layer. Stream Mode shall always start with an LSF that has the LSF TYPE Packet/Stream indicator bit set to 1 (Stream Mode). Following the LSF, one or more Stream Frames may be sent. + + + + + + + + + + + + + + + + +
Figure 3 Stream Mode
PREAMBLELSF SYNC BURSTLSF FRAMESTREAM SYNC BURSTSTREAM FRAME•••STREAM SYNC BURSTSTREAM FRAMEEoT
+ +#### Stream Frames + +The stream data to be sent is broken into groups of 128 bits and combined with frame signalling information contained within the [Link Information Channel (LICH)](#link-information-channel-lich). + +
Table 6 Stream Frame Contents
+Field | Length | Description +----- | ------ | ----------- +LICH | 48 bits | LSF chunk, one of 6 +FN | 16 bits | Frame Number +PAYLOAD | 128 bits | Payload/data, can contain arbitrary data +Total: 192 bits + +The Frame Number (FN) starts from 0 and increments every frame to a maximum of 0x7fff where it will then wrap back to 0. The most significant bit in the FN is used for transmission end signalling. When transmitting the last frame, it shall be set to 1 (one), and 0 (zero) in all other frames. + +##### Link Information Channel (LICH) + +Each Stream Frame contains a 48-bit Link Information Channel (LICH). Each LICH within a Stream Frame includes a 40-bit chunk of the 240-bit LSF frame that was used to establish the stream. A 3-bit modulo 6 counter (LICH_CNT) is used to indicate which chunk of the LSF is present in the current Stream Frame. LICH_CNT starts at 0, increments to 5, then wraps back to 0. + +
Table 7 Link Information Channel
+Bits | Content +---- | ------- +0..39 | 40-bit chunk of full LSF +40..42 | LICH_CNT +43..47 | Reserved + +The 40-bit chunks start with the most significant byte of the LSF. + +
Table 8 LICH_CNT and LSF bits
+LICH_CNT | LSF bits +-------- | ------- +0 | 239:200 +1 | 199:160 +2 | 159:120 +3 | 119:80 +4 | 79:40 +5 | 39:0 + +#### Stream Superframes + +Stream Frames are grouped into **Stream Superframes**, which is the group of 6 frames that contain everything needed to rebuild the original LSF packet, so that the user who starts listening in the middle of a stream (late-joiner) is eventually able to reconstruct the LSF message and understand how to receive the in-progress stream. + +
Figure 6 Stream Superframes
+![M17_stream](M17_stream.png?classes=caption "Stream consisting of one superframe") + ### Packet Mode -In *packet mode*, a finite amount of payload data (for example – text messages or application layer data) is wrapped with a packet, sent over the physical layer, and is completed when done. ~~Any acknowledgement or retransmission is done at the application layer.~~ +In Packet Mode, up to 798 bytes of payload data (for example, text messages or application layer data) may be sent over the physical layer during one Transmission. Packet Mode shall always start with an LSF that has the LSF TYPE Packet/Stream indicator bit set to 0 (Packet Mode). Following the LSF, one or more Packet Frames may be sent. + +Packet Mode acheives a base throughput of 5 kbps, a net throughput of approximately 4.7 kbps for the largest data payload, and over 3 kbps for 100-byte payloads. Net throughput takes into account preamble and link setup overhead. + + + + + + + + + + + + + + + + +
Figure 3 Packet Mode
PREAMBLELSF SYNC BURSTLSF FRAMEPACKET SYNC BURSTPACKET FRAME•••PACKET SYNC BURSTPACKET FRAMEEoT
+ +#### Packet Superframes + +A **Packet Superframe** consists of 798 packet data bytes and a 2-byte CRC checksum (800 bytes total). The CRC used here is the same as described in [LSF CRC](#lsf-crc). + +
Table 9 Packet Superframe Contents
+Bytes | Meaning +----- | ------- +1..798 | Packet data +2 | CRC + +#### Packet Frames + +Packet Frame Contents has 200 bits (25 bytes) of payload data and 6 bits of frame metadata (note that it does not terminate on a byte boundary). + +The metadata field contains a 1-bit **End of Frame (EOF) indicator**, and a 5-bit **Packet Frame/Byte Counter**. + +Each Packet Frame Content payload contains up to a 25-byte chunk of the Packet Superframe. The 25-byte chunks start with the first byte of Packet data, and finally end with the 2 CRC bytes. If fewer than 25 bytes are able to be extracted from the Packet Superframe (i.e. for the last Packet Frame), the Packet Superframe chunk is padded with undefined bytes to reach 25 bytes total. This results in a minimum of one to a maximum of 32 Packet Frames per Transmission. The Packet Frame Counter is reset to zero at the start of Packet Mode. + +For each Packet Frame where there is at least 1 byte remaining in the Packet Superframe after removing a 25-byte chunk, the EOF metadata bit is set to zero, the Packet Frame Counter value is inserted into the Packet Frame/Byte Counter metadata field, and the Packet Frame Counter is incremented. + +When there are no bytes remaining in the Packet Superframe after removing a 25-byte (or less) chunk, the EOF metadata bit is set to one, the Packet Byte Counter is set to the number of valid bytes extracted in the last chunk (1 to 25), inserted into the Packet Frame/Byte Counter metadata field, and Packet Mode is ended. + +
Table 10 Packet Frame Contents
+Bits | Meaning +---- | ------- +0..199 | Packet payload +1 | End of Frame (EOF) indicator +5 | Packet Frame/Byte Counter +Total: 206 bits + +
+ +
Table 11 Metadata Field with EOF = 0
+Bits | Meaning +---- | ------- +0 | Set to 0, Not end of frame +1..5 | Frame number, 0..31 + +
+ +
Table 12 Metadata Field with EOF = 1
+Bits | Meaning +---- | ------- +0 | Set to 1, End of frame +1..5 | Number of bytes in frame, 1..25 + +### BERT Mode + +BERT mode is a standardized, interoperable mode for bit error rate testing. The preamble is +sent, followed by an indefinite sequence of BERT frames. Notably, a link setup frame must not +be sent in BERT mode. + +#### Purpose + +The primary purpose of defining a bit error rate testing standard for M17 is to enhance +interoperability testing across M17 hardware and software implementations, and to aid in the +configuration and tuning of ad hoc communications equipment common in amateur radio. + +#### BERT Frames + +Each BERT frame is preceeded by the BERT sync word, 0xDF55. + +The BERT frame consists of 197 bits from a `PRBS9 `_ +generator. This is 24 bytes and 5 bits of data. The next frame starts with the 198th bit from the PRBS9 +generator. The same generator is used for each subsequent frame without being reset. The number of bits +pulled from the generator, 197, is a prime number. This will produce a reasonably large number of unique +frames even with a PRBS generator with a relatively short period. + +The PRBS uses the ITU standard PRBS9 polynomial :math:`x^{9}+x^{5}+1` + +This is the traditional form for a linear feedback shift register (LFSR) used +to generate a psuedorandom binary sequence. + +.. figure:: ../images/m17-traditional-lfsr.png + +However, the M17 LFSR is a slightly different. The M17 PRBS9 uses the +generated bit as the output bit rather than the high-bit before the shift. + +.. figure:: ../images/m17-prbs9.png + +This will result in the same sequence, just shifted by nine bits. + +.. math:: {M17\_PRBS}_{n} = {PRBS9}_{n + 8} + +The reason for this is that it allows for easier synchronization. This is +equivalent to a multiplicative scrambler (a self-synchronizing scrambler) +fed with a stream of 0s. + +.. figure:: ../images/m17-equivalent-scrambler.png + +.. code-block:: c++ + + class PRBS9 { + static constexpr uint16_t MASK = 0x1FF; + static constexpr uint8_t TAP_1 = 8; // Bit 9 + static constexpr uint8_t TAP_2 = 4; // Bit 5 + + uint16_t state = 1; + + public: + bool generate() + { + bool result = ((state >> TAP_1) ^ (state >> TAP_2)) & 1; + state = ((state << 1) | result) & MASK; + return result; + } + ... + }; + +The PRBS9 SHOULD be initialized with a state of 1. + +.. list-table:: Bit fields of BERT frame + :header-rows: 1 + + * - Bits + - Meaning + * - 0-196 + - BERT PRBS9 payload + * - 4 + - Flush bits for convolutional coder + + +The 201 bits are convolutionally encoded to 402 type 2 bits. + +The 402 bits are punctured using the P2 puncture matrix to get 368 type 3 bits. + +The 368 punctured bits are interleaved and decorrelated to get the type 4 bits +to be transmitted. + +This provides the same error correction coding used for the stream payload. + +.. list-table:: BERT frame + :header-rows: 1 + + * - Bits + - Meaning + * - 16 bits + - Sync word 0xDF55 + * - 368 bits + - Payload + +#### BERT Receiver + +The receiver detects the frame is a BERT frame based on the sync word +received. If the PRBS9 generator is reset at this point, the sender and +receiver should be synchonized at the start. This, however, is not common +nor is it required. PRBS generators can be self-synchronizing. + +##### Synchronization + +The receiver will synchronize the PRBS by first XORing the received bit +with the LFSR taps. If the result of the XOR is a 1, it is an error (the +expected feedback bit and the input do not match) and the sync count is +reset. The received bit is then also shifted into the LFSR state register. +Once a sequence of eighteen (18) consecutive good bits are recovered (twice +the length of the LFSR), the stream is considered syncronized. + +.. figure:: ../images/m17-prbs9-sync.png + +During synchronization, bits received and bit errors are not counted towards +the overall bit error rate. + +.. code-block:: c++ + + class PRBS9 { + ... + static constexpr uint8_t LOCK_COUNT = 18; // 18 consecutive good bits. + ... + // PRBS Syncronizer. Returns 0 if the bit matches the PRBS, otherwise 1. + // When synchronizing the LFSR used in the PRBS, a single bad input bit + // will result in 3 error bits being emitted, one for each tap in the LFSR. + bool syncronize(bool bit) + { + bool result = (bit ^ (state >> TAP_1) ^ (state >> TAP_2)) & 1; + state = ((state << 1) | bit) & MASK; + if (result) { + sync_count = 0; // error + } else { + if (++sync_count == LOCK_COUNT) { + synced = true; + ... + } + } + return result; + } + ... + }; + +##### Counting Bit Errors + +After synchronization, BERT mode switches to error-counting mode, where the +received bits are compared to a free-running PRBS9 generator. Each bit that +does not match the output of the free-running LFSR is counted as a bit error. + +.. figure:: ../images/m17-prbs9-validation.png + +.. code-block:: c++ + + class PRBS9 { + ... + // PRBS validator. Returns 0 if the bit matches the PRBS, otherwise 1. + // The results are only valid when sync() returns true; + bool validate(bool bit) + { + bool result; + if (!synced) { + result = synchronize(bit); + } else { + // PRBS is now free-running. + result = bit ^ generate(); + count_errors(result); + } + return result; + } + ... + }; + +##### Resynchronization + +The receiver must keep track of the number of bit errors over a period of +128 bits. If more than 18 bit errors occur, the synchronization process +starts anew. This is necessary in the case of missed frames or other serious +synchronization issues. + +Bits received and errors which occur during resynchronization are not counted +towards the bit error rate. + +#### References + + - http://www.itu.int/rec/T-REC-O.150-199210-S + - http://www.pldworld.com/_hdl/5/-thorsten-gaertner.de/vhdl/PRBS.pdf + + + + + + + + + + + + +### Bit types + +The bits at different stages of the error correction coding are referred to with bit types, given in the following table. + +Type | Description +---- | ----------- +Type 1 | Data link layer bits +Type 2 | Bits after appropriate encoding +Type 3 | Bits after puncturing (only for convolutionally coded data, for other ECC schemes type 3 bits are the same as type 2 bits) +Type 4 | Decorrelated and interleaved (re-ordered) type 3 bits + +Type 4 bits are used for transmission over the RF. Incoming type 4 bits shall be decoded to type 1 bits, which are then used to extract all the frame fields. + +### Error correction coding schemes and bit type conversion + +Two distinct ECC/FEC schemes are used for different parts of the transmission. + +#### Link setup frame (LSF) + +![link_setup_frame_encoding](link_setup_frame_encoding.svg?classes=caption "ECC Link Setup Frame Encoding") + +240 DST, SRC, TYPE, META and CRC type 1 bits are convolutionally coded using rate 1/2 coder with constraint K=5. 4 tail bits are used to flush the encoder’s state register, giving a total of 244 bits being encoded. Resulting 488 type 2 bits are retained for type 3 bits computation. Type 3 bits are computed by puncturing type 2 bits using a scheme shown in chapter 4.4. This results in 368 bits, which in conjunction with the synchronization burst gives 384 bits (384 bits / 9600bps = 40 ms). + +Interleaving type 3 bits produce type 4 bits that are ready to be transmitted. Interleaving is used to combat error bursts. + +#### Subsequent frames + +![frame_encoding](frame_encoding.svg?classes=caption "ECC stages of subsequent frames") + +A 40-bit (type 1) chunk of the LSF along with a 3-bit modulo 6 counter (LICH_CNT) and 5 reserved bits (see Table 7) is partitioned into 4 12-bit parts and encoded using Golay (24, 12) code. This produces 96 encoded bits of type 2. These bits are used in the Link Information Channel (LICH). + +16-bit FN and 128 bits of payload (144 bits total) are convolutionally encoded in a manner analogous to that of the link setup frame. A total of 148 bits is being encoded resulting in 296 type 2 bits. These bits are punctured to generate 272 type 3 bits. + +96 type 2 bits of LICH are concatenated with 272 type 3 bits and re-ordered to form type 4 bits for transmission. This, along with 16-bit sync in the beginning of frame, gives a total of 384 bits + +The LICH chunks allow for late listening and indepedent decoding to check destination address. The goal is to require less complexity to decode just the LICH and check if the full message should be decoded. + +#### Packet Frame Encoding + +![packet_frame_encoding](packet_frame_encoding.svg?classes=caption "Packet Frame Encoding") + + +All data fields utilize big-endian order of bytes unless specified otherwise. + + +#### Extended Golay(24,12) code + +The extended Golay(24,12) encoder uses generating polynomial g given below to generate the 11 check bits. The check bits and an additional parity bit are appended to the 12 bit data, resulting in a 24 bit codeword. The resulting code is systematic, meaning that the input data (message) is embedded in the codeword. + +\(g(x) = x^{11} + x^{10} + x^6 + x^5 + x^4 + x^2 + 1\) + +This is equivalent to 0xC75 in hexadecimal notation. Both the generating matrix \(G\) and parity check matrix \(H\) are shown below. + +\( +\begin{align} + G = \begin{bmatrix} I_k | P \end{bmatrix} = & \begin{bmatrix} + 1&0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&0&1\\ + 0&1&0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&1\\ + 0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0&0&0\\ + 0&0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0&0\\ + 0&0&0&0&1&0&0&0&0&0&0&0&0&0&1&1&1&1&0&1&1&0&1&0\\ + 0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&0&0&1\\ + 0&0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&0&1\\ + 0&0&0&0&0&0&0&1&0&0&0&0&0&0&1&1&0&1&1&0&0&1&1&1\\ + 0&0&0&0&0&0&0&0&1&0&0&0&1&1&0&1&1&1&0&0&0&1&1&0\\ + 0&0&0&0&0&0&0&0&0&1&0&0&1&0&1&0&1&0&0&1&0&1&1&1\\ + 0&0&0&0&0&0&0&0&0&0&1&0&1&0&0&1&0&0&1&1&1&1&1&0\\ + 0&0&0&0&0&0&0&0&0&0&0&1&1&0&0&0&1&1&1&0&1&0&1&1\\ + \end{bmatrix} +\newline\newline + H = \begin{bmatrix} P^T | I_k \end{bmatrix} = & \begin{bmatrix} + 1&0&1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&0\\ + 1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0&0&0\\ + 0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0&0\\ + 0&0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0&0\\ + 0&0&0&1&1&1&1&0&1&1&0&1&0&0&0&0&1&0&0&0&0&0&0&0\\ + 1&0&1&0&1&0&1&1&1&0&0&1&0&0&0&0&0&1&0&0&0&0&0&0\\ + 1&1&1&1&0&0&0&1&0&0&1&1&0&0&0&0&0&0&1&0&0&0&0&0\\ + 1&1&0&1&1&1&0&0&0&1&1&0&0&0&0&0&0&0&0&1&0&0&0&0\\ + 0&1&1&0&1&1&1&0&0&0&1&1&0&0&0&0&0&0&0&0&1&0&0&0\\ + 1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&1&0&0\\ + 0&1&0&0&1&0&0&1&1&1&1&1&0&0&0&0&0&0&0&0&0&0&1&0\\ + 1&1&0&0&0&1&1&1&0&1&0&1&0&0&0&0&0&0&0&0&0&0&0&1\\ + \end{bmatrix} +\end{align} +\) + +The output of the Golay encoder is shown in the table below. + +Field | Data | Check bits | Parity +----- | ---- | ---------- | ------ +Position | 23..12 | 11..1 | 0 (LSB) +Length | 12 | 11 | 1 + +Four of these 24-bit blocks are used to reconstruct the LSF. + +Sample MATLAB/Octave code snippet for generating \(G\) and \(H\) matrices is shown below. + +``` + +P = hex2poly('0xC75'); +[H,G] = cyclgen(23, P); + +G_P = G(1:12, 1:11); +I_K = eye(12); +G = [I_K G_P P.']; +H = [transpose([G_P P.']) I_K]; +``` + +### Convolutional encoder + +The convolutional code shall encode the input bit sequence after appending 4 tail bits at the end of the sequence. Rate of the coder is R=½ with constraint length K=5. The encoder diagram and generating polynomials are shown below. + +\( +\begin{align} + G_1(D) =& 1 + D^3 + D^4 \\ + G_2(D) =& 1+ D + D^2 + D^4 +\end{align} +\) + +The output from the encoder must be read alternately. + +![convolutional](convolutional.svg?classes=caption "Convolutional coder diagram") + +### Code puncturing + +Removing some of the bits from the convolutional coder’s output is called code puncturing. The nominal coding rate of the encoder used in M17 is ½. This means the encoder outputs two bits for every bit of the input data stream. To get other (higher) coding rates, a puncturing scheme has to be used. + +Two different puncturing schemes are used in M17 stream mode: + +1. \(P_1\) leaving 46 from 61 encoded bits +2. \(P_2\) leaving 11 from 12 encoded bits + +Scheme \(P_1\) is used for the *link setup frame*, taking 488 bits of encoded data and selecting 368 bits. The \(gcd(368, 488)\) is 8 which, when used to divide, leaves 46 and 61 bits. However, a full puncture pattern requires the puncturing matrix entries count to be divisible by the number of encoding polynomials. For this case a partial puncture matrix is used. It has 61 entries with 46 of them being ones and shall be used 8 times, repeatedly. The construction of the partial puncturing pattern \(P_1\) is as follows: + +\( +\begin{align} + M = & \begin{bmatrix} + 1 & 0 & 1 & 1 + \end{bmatrix} \\ + P_{1} = & \begin{bmatrix} + 1 & M_{1} & \cdots & M_{15} + \end{bmatrix} +\end{align} +\) + +In which \(M\) is a standard 2/3 rate puncture matrix and is used 15 times, along with a leading \(1\) to form \(P_1\), an array of length 61. + +The first pass of the partial puncturer discards \(G_1\) bits only, second pass discards \(G_2\), third - \(G_1\) again, and so on. This ensures that both bits are punctured out evenly. + +Scheme \(P_2\) is for frames (excluding LICH chunks, which are coded differently). This takes 296 encoded bits and selects 272 of them. Every 12th bit is being punctured out, leaving 272 bits. The full matrix shall have 12 entries with 11 being ones. + +The puncturing scheme \(P_2\) is defined by its partial puncturing matrix: + +\( +\begin{align} + P_2 = & \begin{bmatrix} + 1 & 1 & 1 & 1 & 1 & 1 \\ + 1 & 1 & 1 & 1 & 1 & 0 + \end{bmatrix} +\end{align} +\) + +The linearized representations are: + +``` +P1 = [1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, + 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1] + +P2 = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0] +``` + +One additional puncturing scheme \(P_3\) is used in the packet mode. The puncturing scheme is defined by its puncturing matrix: + +\( +\begin{align} + P_3 = & \begin{bmatrix} + 1 & 1 & 1 & 1 \\ + 1 & 1 & 1 & 0 + \end{bmatrix} +\end{align} +\) + +The linearized representation is: + +``` +P3 = [1, 1, 1, 1, 1, 1, 1, 0] +``` + +### Interleaving + +For interleaving a Quadratic Permutation Polynomial (QPP) is used. The polynomial \(\pi(x)=(45x+92x^2)\mod 368\) is used for a 368 bit interleaving pattern QPP. See appendix sec-interleaver for pattern. + + + + + + +### Issues to address... + +* Nothing to consistently address loss of signal/fades/missing EoT +* No limit on transmission duration +* FN rollover - allowed or not? +* More details on Golay choice/performance +* Golay(24,12) matrix in C form (in appendix) + + +------ + +### Holding area + + +### Payload + +The Payload size varies depending on the frame type, but shall be in multiples of 2 bits. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 3Payload Size
Frame TypePayload BitsPayload Symbols
LSF244122
BERT-3, +3, -3, -3, +3, +3, +3, +3
StreamNone0xFF 0x5D-3, -3, -3, -3, +3, +3, -3, +3
PacketNone0x75 0xFF+3, -3, +3, +3, -3, -3, -3, -3
+ +TAIL | 4 bits | Flushing bits for the convolutional encoder that do not carry any information. Only included for RF frames, not included for IP purposes. +TAIL | 4 bits | Flushing bits for the convolutional encoder that don’t carry any information +4 | Flush bits for convolutional coder + +The fields in Table 3 (except TAIL) form initial LSF. It contains all information needed to establish M17 link. Later in the transmission, the initial LSF is divided into 6 “chunks” and transmitted beside the payload data. This allows late-joiners to reconstruct the LICH after collecting all the pieces, and start decoding the stream even though they missed the beginning of the transmission. The process of collecting full LSF takes 6 frames or 6\*40 ms = 240 ms. Four TAIL bits are needed for the convolutional coder to go back to state 0, so the ending trellis position is also known. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Sync Burst
Frame TypePreambleSync Burst BytesSync Burst Symbols
LSF+3, -30x55 0xF7+3, +3, +3, +3, -3, -3, +3, -3
BERT-3, +30xDF 0x55-3, +3, -3, -3, +3, +3, +3, +3
StreamNone0xFF 0x5D-3, -3, -3, -3, +3, +3, -3, +3
PacketNone0x75 0xFF+3, -3, +3, +3, -3, -3, -3, -3
+ + +##### Voice Coder Rates + +Voice coder rate is inferred from TYPE field, bits 1 and 2. + +Data Type Indicator | Voice Coder Rate +------------------- | ---------------- +$00_2$ | none / reserved +$01_2$ | no voice +$10_2$ | 3200 bps +$11_2$ | 1600 bps + +Bits | Meaning +---- | ------- +0 | Packet/Stream indicator, 0=Packet Mode, 1=Stream Mode +1..2 | Data type indicator, $01_2$ =data (D), $10_2$ =voice (V), $11_2$ =V+D, $00_2$ =reserved +3..4 | Encryption type, $00_2$ =none, $01_2$ =AES, $10_2$ =scrambling, $11_2$ =other/reserved +5..6 | Encryption subtype (meaning of values depends on encryption type) +7..10 | Channel Access Number (CAN) +11..15 | Reserved (don’t care) + + +The payload is used so that earlier data in the voice stream is sent first. For mixed voice and data payloads, the voice data is stored first, then the data. + +##### Payload Example 1 + +`Codec2 encoded frame t + 0 | Codec2 encoded frame t + 1` + +##### Payload Example 2 + +`Codec2 encoded frame t + 0 | Mixed data t + 0` + -#### Link Setup Frame -Packet mode uses the same link setup frame that has been defined for stream mode above. The packet/stream indicator is set to 0 in the type field. ##### Bitfields of Type Field @@ -188,70 +809,55 @@ Encryption type and subtype bits, including the plaintext data formats when not Currently the contents of the source and destination fields are arbitrary as no behavior is defined which depends on the content of these fields. The only requirement is that the content is base-40 encoded. -#### Packet Format -M17 packet mode can transmit up to 798 bytes of payload data within one transmission. It acheives a base throughput of 5 kbps, and a net throughput of about 4.7 kbps for the largest data payload, and over 3 kbps for 100-byte payloads. [^1] -[^1]: Net throughput takes into account preamble and link setup overhead. -The packet superframe consists of 798 payload data bytes and a 2-byte CCITT CRC-16 checksum. -##### Byte Fields of Packet Superframe -Bytes | Meaning ------ | ------- -1..798 | Packet payload -2 | CRC-16 -The CRC used here is the same as described in [Chapter 2.4](https://spec.m17project.org/part-1/data-link-layer#crc). + +[mermaid] +graph TD +c0["conv. coder"] +p0["P_1 puncturer"] +i0["interleaver"] +w0["randomizer"] +s0["prepend LSF_SYNC"] +l0["LICH combiner"] +chunker_40["chunk 40 bits"] +golay_24_12["Golay (24, 12)"] +c1["conv. coder"] +p1["P_2 puncturer"] +i1["interleaver"] +w1["randomizer"] +s1["prepend FRAME_SYNC"] +fn["add FN"] +chunker_128["chunk 128 bits"] +framecomb["Frame Combiner"] +supercomb["Superframe Combiner"] + +counter --> l0 +LSF --> c0 --> p0 --> i0 --> w0 --> s0 --> supercomb +LSF --> chunker_40 --> l0 --> golay_24_12 --> framecomb +data --> chunker_128 --> fn --> c1 --> p1 --> framecomb +framecomb --> i1 --> w1 --> s1 --> supercomb +preamble --> supercomb +[/mermaid] +
An overview of the forward dataflow
+ Packet data is split into frames of 368 type 4 bits preceded by a packet-specific 16-bit sync word (0xFF5D). This is the same size frame used by stream mode. -The packet frame starts with a 210 bit frame of type 1 data. It is noteworthy that it does not terminate on a byte boundary. -The frame has 200 bits (25 bytes) of payload data, 6 bits of frame metadata, and 4 bits to flush the convolutional coder. - -##### Bit Fields of Packet Frame - -Bits | Meaning ----- | ------- -0..199 | Packet payload -1 | EOF indicator -5 | Frame / Byte count -4 | Flush bits for convolutional coder - -The metadata field contains a 1 bit **end of frame (EOF)** indicator, and a 5-bit frame/byte counter. - -The **EOF** bit is 1 only on the last frame. The **counter** field is used to indicate the frame number when **EOF** is 0, and the number of bytes in the last frame when **EOF** is 1. This encodes the exact packet size, up to 800 bytes, in a 6-bit field. - -##### Metadata Field with EOF = 0 - -Bits | Meaning ----- | ------- -0 | Set to 0, Not end of frame -1..5 | Frame number, 0..31 - -##### Metadata Field with EOF = 1 - -Bits | Meaning ----- | ------- -0 | Set to 1, End of frame -1..5 | Number of bytes in frame, 1..25 - -Note that it is non-conforming to send a last frame with a length of 0 bytes. The number of bytes **includes** 2-byte CRC. - -#### Convolutional Coding +#### Packet Frame Convolutional Coding The entire frame is convolutionally coded, giving 420 bits of type 2 data. It is then punctured using a 7/8 puncture matrix (1,1,1,1,1,1,1,0) to give 368 type 3 bits. These are then interleaved and decorrelated to give 368 type 4 bits. -##### Packet Frame +##### zzzPacket Frame Bits | Meaning ---- | ------- 16 bits | Sync word 0xFF5D 368 bits | Payload -#### Carrier-sense Multiple Access -When sending packets, the sender is reponsible for ensuring the channel is clear before transmitting. CSMA is used to minimize collisions on a shared network. Specifically, P-persistent access is used. Each time slot is 40ms (one packet length) and the probability SHOULD default to 25%. In terms of the values used by the KISS protocol, these equate to a slot time of 4 and a P-persistence value of 63. -The benefit of this method is that it imposes no penalty on uncontested networks. diff --git a/pages/02.part-1/03.physical-layer/frame_encoding.svg b/pages/02.part-1/04.data-link-layer/frame_encoding.svg similarity index 100% rename from pages/02.part-1/03.physical-layer/frame_encoding.svg rename to pages/02.part-1/04.data-link-layer/frame_encoding.svg diff --git a/pages/02.part-1/03.physical-layer/link_setup_frame_encoding.svg b/pages/02.part-1/04.data-link-layer/link_setup_frame_encoding.svg similarity index 100% rename from pages/02.part-1/03.physical-layer/link_setup_frame_encoding.svg rename to pages/02.part-1/04.data-link-layer/link_setup_frame_encoding.svg diff --git a/pages/02.part-1/03.physical-layer/packet_frame_encoding.svg b/pages/02.part-1/04.data-link-layer/packet_frame_encoding.svg similarity index 100% rename from pages/02.part-1/03.physical-layer/packet_frame_encoding.svg rename to pages/02.part-1/04.data-link-layer/packet_frame_encoding.svg