└── README.md /README.md: -------------------------------------------------------------------------------- 1 | # FT8Call Design Document 2 | 3 | Author: Jordan Sherer (KN4CRD) 4 | Created: March 4, 2018 5 | 6 | --- 7 | 8 | FT8 has taken over the airwaves as _the_ digital communication mode for making QSOs over HF/VHF/UHF. The mode has been widely popular as the latest mode offered in the WSJT-X application. It stands on the shoulders of JT65, JT9, and WSPR modes for weak signal communication, but much faster. 9 | 10 | While FT8 is an incredibly robust weak signal mode, it only offers a minimal QSO operation framework, designed heavily to take advantage of short band openings on VHF/UHF. However, many operators are using these weak signal properties successfully on the HF bands. 11 | 12 | The idea here is to take the robustness of FT8 mode and layer on a messaging and network protocol for weak signal _communication_. 13 | 14 | ## Goals 15 | 16 | 1. Create a network of manned and automated stations communicating over FT8 mode 17 | 2. Offer intutive and short commands for passing messages within the network 18 | 3. Use efficient message packing to send vital information over the airwaves in a minimal amount of time 19 | 4. Allow keyboard to keyboard chat between stations with minimal overhead 20 | 5. Optionally allow reliable transmission of messages with automatic retransmission of failed message frames. 21 | 22 | ## Channel Allocation 23 | 24 | Modes like FSQ and HFAPRS allocate a single channel for their communication. This is useful for keeping the bandwidth of transmissions restricted to a reasonable range. However, stations within a single channel may cause each other interference when transmitting over top of each other. 25 | 26 | On the other hand, FT8 mode transmissions are sent in a 50Hz bandwidth. What we can do is leverage this small bandwidth to allot several channels for multiple, parallel in-network transmissions. We can leverage the FT8 multi-decoder to allow for synchronized transmissions for multiple stations without overlapping / competing signals. 27 | 28 | How? We'll use 1500Hz as the center of the passband for our frequency, then use 50Hz channels above and below the center frequency spaced 10Hz apart. 29 | 30 | ``` 31 | | 1500Hz | 32 | | | | 33 | | [ 1355Hz ] [ 1415Hz ] [ 1475Hz ] [ 15685z ] [ 1640Hz ] | 34 | | | 35 | | | 36 | ``` 37 | 38 | Each station will randomly choose one of these slots as their default (or maybe they are assigned one based on a hash of their callsign?) Or maybe they choose even or odd and can synchronize that way. Each station sounding could include this information about channel usage. 39 | 40 | We could also set channels lower than 1500Hz for message sending (directed, sounding, etc) and channels higher could be for replies. Or, replies could just stick to the channel on which the message was received. 41 | 42 | Each station would maintain a preferred list of channels for each station heard (i.e., which channel the station heard them on). 43 | 44 | Up to 25 channels could fit in a 1500Hz segment of the passband (1500Hz / (50+10Hz)). Each new station sounding would be trying to fill in the gaps to avoid broadcasting over top of each other. 45 | 46 | Alternatively, we could just rely on the operator to select a free channel in the passband. 47 | 48 | One neat thing about this (mostly related to the FT8 modes fantastic decoder) is that multiple messages could be delievered simultaneously from multiple operators without interference. 49 | 50 | ## Messages 51 | 52 | There will be two primary types of messages, each with sub-types: 53 | 54 | 1. Sounding / beacon messages (station to all) 55 | 56 | * Ping 57 | * Ping-Req 58 | 59 | 2. Directed messages (station to station) 60 | 61 | * Command Requests 62 | * Acks (automated) 63 | * Free Text 64 | * Free Text Relays (automated) 65 | 66 | Sounding messages would be used to announce a station to all listeners. Directed messages would be used to send commands or messages back and forth between stations. 67 | 68 | ### Sounding 69 | 70 | We could use the SWIM protocol [3] for managing the network membership list. Basically, an efficient gossip mechanism to announce joins to the network. 71 | 72 | We wouldn't need to worry about dead links for the most part unless we wanted to clean up the heard list over time. Displaying time since last heard would be a nice to have. 73 | 74 | We could piggyback on periodic sounding for disseminating any known membership changes. Sounding could occur on a random channel in the passband at a random minute offset if network membership changed. 75 | 76 | Receiving sounding with membership information could allow us to include 2-hop stations in the "heard" list. 77 | 78 | ### Directed 79 | 80 | Directed messages would be used to send information across the network. These could be commands to other stations, messages to other stations, or relays through other stations. 81 | 82 | ### Structure 83 | 84 | FT8 transmissions carry 75-bits of information. This information is transmitted redundantly using forward error correction. Normal FT8 transmissions are 72-bits long with 3-bits left unused. FT8 free text transmissions are 13 characters long at 5 bits per character, for a total of 65 bits. 85 | 86 | We know that the EME 2000 paper [1] describes an efficient way to encode all known amateur radio callsigns in 28-bits of information. This is what JT65 [2] (and FT8) uses for their minimal QSO message packing. With this in mind, we can develop a simple command message protocol where most non-freetext messages are passed with only one 15-second FT8 transmission. 87 | 88 | #### Base Message 89 | 90 | ``` 91 | +----------+------------+--------------+ 92 | | Head (1) | Type (1-2) | Data (72/73) | 93 | +----------+------------+--------------+ 94 | | 0 | 00 | 0000....0000 | 95 | +----------+------------+--------------+ 96 | ``` 97 | 98 | **Head:** Identify if there are any more frames to the message. 99 | 100 | * `|0|` = This is the last frame of the message 101 | * `|1|` = There is at least one more frame to the message 102 | 103 | **Type:** Identify the type of message. Type is a variable bit flag and can be 1 or 2 bits long. 104 | 105 | * `|1|` = Type 1 (Directed Data) 106 | * `|01|` = Type 2 (Sounding) 107 | * `|00|` = Type 3 (Directed Header) 108 | 109 | **Data:** The data in the message (depending on the message type) 110 | 111 | #### Sounding Message 112 | 113 | ``` 114 | +----------+----------+---------------+-----------+ 115 | | Head (1) | Type (2) | Callsign (28) | Data (44) | 116 | +----------+----------+---------------+-----------+ 117 | | 0 | 01 | 0000....0000 | 000...000 | 118 | +----------+----------+---------------+-----------+ 119 | ``` 120 | 121 | **Data:** Can _technically_ encode any information that can fit in 44-bits. 122 | 123 | Here are some likely candidates: 124 | 125 | * Sounding Type (3 bits) 126 | * 8 text characters (40 bits) 127 | * Another Callsign (28 bits) 128 | * Call command (3 bits) 129 | * REQ, SEEN 130 | * Grid (15 bits) 131 | * Or a high precision grid locator (30 bits) [6] 132 | * Signal Report (4 bits) 133 | * 0-12 = -2dB * bits = SNR 134 | * 0001 = -2dB * 1 = -2dB 135 | * 0010 = -2dB * 2 = -4dB 136 | * 1100 = -2dB * 12 = -24dB 137 | * 13-15 = 3dB * (16 - bits) 138 | * 1111 = 15 = 3*(16-15) = +3dB 139 | * 1110 = 14 = 3*(16-14) = +6dB 140 | * 1101 = 13 = 3*(16-13) = +9dB 141 | * Power (3 bits) 142 | 0. 0-500mW 143 | 1. 1W 144 | 2. 2W 145 | 3. 5W 146 | 4. 10W 147 | 5. 50W 148 | 6. 100W 149 | 7. 1KW 150 | 151 | Sounding messages should include a sounding command when another callsign is sent along to identify if the sounding is a request or is a notification. 152 | 153 | 154 | #### Directed Header 155 | 156 | Message stream (Frame 1): 157 | ``` 158 | +----------+----------+---------------+------------------+ 159 | | Head (1) | Type (2) | Callsign (28) | To Callsign (28) | 160 | +----------+----------+---------------+------------------+ 161 | | 0 | 00 | 0000.....0000 | 0000........0000 | 162 | +----------+----------+---------------+------------------+ 163 | +-----------------+-------------+----------+ 164 | | Frame Count (4) | Command (4) | Args (8) | 165 | +-----------------+-------------+----------+ 166 | | 0000 | 0000 | 0000 | 167 | +-----------------+-------------+----------+ 168 | ``` 169 | 170 | **Pad:** Identifies the number of pad bits at the end of the message (0-7 bits) 171 | 172 | **Frame Count:** Number of frames to follow 173 | 174 | **Command:** Directed command 175 | 176 | **Args:** Arguments to the directed command, likely 8 bit int 177 | 178 | #### Directed Data 179 | 180 | Message stream continuations (Frames 2 through n): 181 | ``` 182 | +----------+----------+---------+-----------+ 183 | | Head (1) | Type (1) | Pad (3) | Data (70) | 184 | +----------+----------+---------+-----------+ 185 | | 1 | 1 | 000 | 000...000 | 186 | +----------+----------+---------+-----------+ 187 | ``` 188 | 189 | **Pad:** Identifies the number of pad bits at the end of the message (0-7 bits) 190 | 191 | **Data:** Huffman encoded varicode data 192 | 193 | **CRC:** The last frame of the message should include a CRC of the message to ensure it was correctly assembled. 194 | 195 | ### Message Examples 196 | 197 | * Sounding 198 | * ping - here is my station info 199 | * ping [callsign] seen - i saw this callsign 200 | * ping [callsign] req - has anyone heard this callsign? 201 | * ack [callsign] [bitflag] - i've received your messages (and may be missing some in the bit flag) 202 | * Directed 203 | * allcall [message] - broadcasting this message to all stations in network 204 | * cqcqcq [message] - broadcasting this message to those with cq enabled 205 | * [callsign]:? - what is my signal report 206 | * [callsign]:![message] - relay this message 207 | * [callsign]:@ - what is your station qth (location)? 208 | * [callsign]:& - what is your station qtc (message)? 209 | * [callsign]:$ - what stations have you heard? 210 | * [callsign]:% - what is your station information? 211 | 212 | #### Example Encodings 213 | 214 | 215 | Sounding: 216 | ``` 217 | 1 2 28 3 15 15 3 218 | ->[0][01][KN4CRD][PING][EM73][TU00][5W] = 67 219 | ``` 220 | 221 | Sounding Request & Reply: 222 | ``` 223 | 1 2 28 3 28 224 | ->[0][01][KN4CRD][PINGREQ][OH8STN] = 62 225 | 1 2 28 3 28 4 226 | <-[0][01][VA3OSO][SEEN][OH8STN][-15dB] = 66 227 | ``` 228 | 229 | Membership Change: 230 | ``` 231 | 1 2 28 3 28 4 232 | ->[0][01][KN4CRD][SEEN][OH8STN][-15dB] = 66 233 | ``` 234 | 235 | Direct Free Text (2 frames): 236 | ``` 237 | 1 2 28 28 4 4 8 238 | ->[1][00][KN4CRD][KN4CRD][1 FRAME][MSG][00000000] = 75 239 | 1 1 3 63 240 | ->[0][1][111][how are you??] = 75 241 | ``` 242 | 243 | Direct Command (report): 244 | ``` 245 | 1 2 28 28 4 4 8 246 | ->[0][00][KN4CRD][OH8STN][0 FRAMES][CMD ?][00000000] = 75 247 | 1 2 28 3 28 4 248 | <-[0][01][OH8STN][SEEN][KN4CRD][-15dB] = 66 249 | ``` 250 | 251 | Direct Command (heard list) 252 | ``` 253 | 1 1 28 28 4 4 8 254 | ->[0][1][KN4CRD][OH8STN][3 FRAMES][CMD $][000000000] = 75 255 | 1 2 28 3 28 4 256 | <-[1][01][OH8STN][SEEN][KN4CRD][-16dB] = 66 257 | <-[1][01][OH8STN][SEEN][ K1JT ][-12dB] = 66 258 | <-[0][01][OH8STN][SEEN][ K4YY ][-02dB] = 66 259 | 260 | -- but, we _could_ also encode this in freetext if we omit the sender -- 261 | 262 | 1 2 28 28 4 4 8 263 | ->[1][00][KN4CRD][OH8STN][0 FRAMES][CMD $][000000000] = 75 264 | 1 2 28 28 4 4 8 265 | <-[1][00][OH8STN][KN4CRD][1 FRAMES][LIST][000000000] = 75 266 | 1 2 3 28 4 28 4 267 | <-[0][01][110][K4YY][-16dB][K1JT][-12dB] = 69 268 | 269 | ``` 270 | 271 | Direct Command (station info): 272 | ``` 273 | 1 2 28 28 4 4 8 274 | ->[0][00][KN4CRD][OH8STN][0 FRAMES][CMD %][00000000] = 75 275 | 1 2 28 4 15 15 3 276 | <-[0][01][OH8STN][PING][EM73][TU00][5W] = 67 277 | ``` 278 | 279 | 280 | ### SRARQ - selective repeat - automatic repeat requests 281 | 282 | > When used as the protocol for the delivery of subdivided messages SRARQ works somewhat differently. In non-continuous channels where messages may be variable in length, standard ARQ or Hybrid ARQ protocols may treat the message as a single unit. Alternately selective retransmission may be employed in conjunction with the basic ARQ mechanism where the message is first subdivided into sub-blocks (typically of fixed length) in a process called packet segmentation. The original variable length message is thus represented as a concatenation of a variable number of sub-blocks. While in standard ARQ the message as a whole is either acknowledged (ACKed) or negatively acknowledged (NAKed), in ARQ with selective transmission the ACK response would additionally carry a bit flag indicating the identity of each sub-block successfully received. In ARQ with selective retransmission of sub-divided messages each retransmission diminishes in length, needing to only contain the sub-blocks that were linked. [5] 283 | 284 | ## References 285 | 286 | - [1]: EME 2000 - http://www.ka9q.net/papers/eme-2000.ps.gz 287 | - [2]: The JT65 Communications Protocol - http://www.arrl.org/files/file/18JT65.pdf 288 | - [3]: SWIM: Scalable Weakly-consistent Infection-style Process Group Membership Protocol - https://pdfs.semanticscholar.org/8712/3307869ac84fc16122043a4a313604bd948f.pdf 289 | - [4]: WSPR Coding Process - http://www.g4jnt.com/Coding/WSPR_Coding_Process.pdf 290 | - [5]: ARQ - https://en.m.wikipedia.org/wiki/Selective_Repeat_ARQ 291 | - [6]: Maidenhead Grid - http://www.jidanni.org/geo/maidenhead/index.html 292 | --------------------------------------------------------------------------------