DPRK-ARQ Protocol
North Korean diplomatic communications utilize a proprietary ARQ modem of unknown name, unofficially known as DPRK-ARQ. Depending on which stations on the diplomatic network are involved, the modem can be observed to operate in three different regional variants:
- the Moscow variant, used for links between an embassy and the Moscow hub (modem ID: 0xA5)
- the Pyongyang variant, used for links between an embassy and the Pyongyang hub (modem ID: 0xD3)
- the relay variant, used for links involving neither Moscow nor Pyongyang hubs
The Moscow and relay variants differ only by some command codes, and slightly quicker-paced bursts for the relay variant; whereas the Pyongyang variant differs majorly from them in flow control and ARQ sequencing. Due to lack of data, understanding of some implementation details of the Pyongyang variant is still tentative.
Waveform
The modem is based on BFSK bursts transmitted in lower sideband mode. There are two possible waveforms: 600Bd/600Hz as the default, and 1200Bd/600Hz as an option. The nominal center frequency is 1500 Hz, although it is frequently slightly modified by the operators for unknown reasons. When demodulated in LSB, the upper frequency is space (0), and the lower frequency is mark (1).
The bursts are packets of synchronous data whose structure follow a similar pattern in 600Bd and 1200Bd modes, the 1200Bd waveform basically extending the 600Bd one with double the elements:
1200Bd only | 600Bd and 1200Bd | 1200Bd only | |||||||
---|---|---|---|---|---|---|---|---|---|
1010101010 | 10101010101 | B53C6161 | D5AFDBA | 61616161 | 9327A3A | 61616161 | 9327A3A | 61616161 | 9327A3A |
Bit reversals, up to 11 bits |
Bit reversals, up to 11 bits |
32-bit data section 1 |
28-bit checksum |
32-bit data section 2 |
28-bit checksum |
32-bit data section 3 |
28-bit checksum |
32-bit data section 4 |
28-bit checksum |
Whether in 600Bd or 1200Bd mode, the packet bursts have the same approximate duration, between 200 and 218 ms. These packets are paced and sent every 540 ms for the Moscow and Pyongyang variants; the relay variant instead uses a shorter, variable frame duration between 500 and 540 ms. Links operate between station pairs, each station synchronized to transmit between the frame gap of the other one.
Packet structure
The data sections are simply joined together to form a packet: the length of a packet is 8 bytes in 600Bd mode, or 16 bytes in 1200Bd mode. The checksumming mechanism is not well understood, although collisions are easy to observe, and the second and further checksum sections seem to depend on at least the first one. Packet data follows this generic structure:
Peer station modem ID |
Packet type / ARQ sequencing |
Payload | 1200Bd extra payload |
---|---|---|---|
B5 | 3C | 61 61 61 61 61 61 | 61 61 61 61 61 61 61 61 |
The first byte is the modem ID of the peer station on the link - the destination of the packet rather than their source. Known modem IDs, some identified with and located to given embassies, are listed here.
The second byte of each packet indicates the packet type, and is modulated by ARQ sequencing information used to manage packet retransmission. This modem uses stop-and-wait ARQ, realized in this case by treating new packets from the other station as acknowledgements, and repeats as non-acknowledgements.
ARQ sequencing
The ARQ sequencing method used is a major difference between the Moscow/relay and Pyongyang variants.
The Moscow and relay variants split the packet type byte into two 4-bit sections, which may take only 0, 3, C, or F as valid values. There are six pairs of valid request-response packet type bytes, corresponding to three packet categories. The modem alternates between the two variants for consecutive packets of the same kind. The 3_ variant follows C_, and vice versa.
Category | Request | Response |
---|---|---|
Commands | CF | FC |
3F | F3 | |
Chat/idle traffic |
C0 | 0C |
30 | 03 | |
Data traffic |
CC | 3C |
33 | C3 |
The Pyongyang variant splits the packet type byte into four 2-bit sections, the outer two being the packet type, and the inner two being ARQ counters:
Pyongyang variant | |||
---|---|---|---|
00 | 01 | 10 | 00 |
First 2 bits of packet type |
ARQ ack. counter |
ARQ seq. counter |
Last 2 bits of packet type |
The two counters may take 00, 01, 10, 11 as values, in that order; the initial state of both is 00. The sequence counter increments with each new (not retransmitted) packet. The other counter is an acknowledgement counter. Correct reception of a packet from the peer station is acknowledged by sending a new packet with both acknowledgement and sequence counters incremented. Non-acknowledgement is indicated by sending a new packet with an increased sequence counter, but unmodified acknowledgement counter, which causes the other station to repeat its last packet.
Packet types
The packet type is indicated by the bits of the second byte that are not used for ARQ sequencing. In the following table, "_" is used to denote bits used for ARQ.
Packet type |
Moscow / relay variants | Pyongyang variant | Payload type |
||
---|---|---|---|---|---|
Bit field | Possible values | Bit field | Possible values | ||
Traffic modes | |||||
Data | ________ | 33 / CC, C3 / 3C | 00____11 | 03 / 17 / 2B / 3F, ... | Byte stream |
Chat | ____0000 | C0 / 30 | 00____10 | 02 / 16 / 2A / 3E, ... | Byte stream |
Idle | 0000____ | 0C / 03 | 00____00 | 00 / 14 / 28 / 3C, ... | Filler |
Commands | |||||
Command | ____1111 | CF / 3F | 01____11 | 43 / 57 / 6B / 7F, ... | Parameters |
Command ACK | 1111____ | FC / F3 | Filler | ||
CQ | 00____01 | 01 / 15 / 29 / 3D, ... | Parameters (custom) | ||
CQ ACK | 01____01 | 41 / 55 / 69 / 7D, ... | Parameters |
Traffic mode packets are sent continuously while a station is in the corresponding mode. Individual command packets are used to switch between modes and set up the link and transmission. All packet types will be described in detail later below.
Transmission overview
A typical simple, trouble-free DPRK-ARQ link follows this basic structure:
- CQ stage and link establishment
- Default chat/idle phase
- Data transmission in full duplex
- Reverting to a chat/idle phase with sign-off operator chatter
- Shutting down the link
Here is a transcript of a representative sample transmission where the Moscow hub (0xA5) is calling the embassy with modem ID 0xB3:
B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [B3 off] B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [Retransmit] [B3 off] B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [Retransmit] [B3 off] B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [Retransmit] A5 FC 04 04 A5 FC 05 05 [B3 command: CQ ACK] B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [Retransmit] A5 FC 04 04 A5 FC 05 05 [B3 command: CQ ACK] [Retransmit] B3 CF 01 14 75 00 00 00 [A5 command: CQ 14750kHz] [Retransmit] A5 FC 04 04 A5 FC 05 05 [B3 command: CQ ACK] [Retransmit] B3 3F 03 00 00 00 00 00 [A5 command: chat mode] A5 F3 0C 0C A5 F3 0D 0D [B3 command: chat mode ACK] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] [Retransmit] B3 C0 00 00 00 00 00 00 [A5 chat: ""] [Retransmit] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] B3 CF 06 0C 97 00 00 00 [A5 command: data mode, TX ID "0C97", position 0] A5 3F 07 60 00 00 00 00 [B3 command: data mode response, QRU] B3 C3 30 03 6B 05 00 00 [A5 data] A5 3C 60 61 61 61 61 61 [B3 data: end-of-data marker] B3 33 11 02 00 00 DF 00 [A5 data] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 00 00 19 00 01 11 [A5 data] A5 3C 61 61 61 61 61 61 [B3 data: padding] B3 33 41 01 2C 01 4B 00 [A5 data] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 00 00 00 31 77 14 [A5 data] A5 3C 61 61 61 61 61 61 [B3 data: padding] B3 33 83 52 54 44 48 70 [A5 data] A5 3C 61 61 61 61 61 61 [B3 data: padding] [Retransmit] B3 33 83 52 54 44 48 70 [A5 data] [Retransmit] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 35 81 78 74 65 62 [A5 data] A5 3C 61 61 61 61 61 61 [B3 data: padding] [Skipping data transmission...] B3 33 07 40 83 66 38 00 [A5 data] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 14 14 54 53 56 12 [A5 data] A5 3C 61 61 61 61 61 61 [B3 data: padding] B3 33 29 10 C8 18 58 1A [A5 data] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 50 3D 60 61 61 61 [A5 data: end-of-data marker] A5 3C 61 61 61 61 61 61 [B3 data: padding] B3 33 61 61 61 61 61 61 [A5 data: padding] A5 C3 61 61 61 61 61 61 [B3 data: padding] B3 CC 61 61 61 61 61 61 [A5 data: padding] A5 CF 08 00 00 00 00 00 [B3 command: end of data] B3 3F 03 00 00 00 00 00 [A5 command: chat mode] A5 F3 0C 0C A5 F3 0D 0D [B3 command: chat mode ACK] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] [Skipping empty chat/idling...] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] [Retransmit] B3 C0 00 00 00 00 00 00 [A5 chat: ""] [Retransmit] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 72 74 20 6F 6B 20 [A5 chat: "rt ok "] A5 03 00 00 A5 03 01 01 [B3 idle] B3 C0 73 6B 00 00 00 00 [A5 chat: "sk"] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] [Skipping empty chat/idling...] B3 C0 00 00 00 00 00 00 [A5 chat: ""] A5 0C 00 00 A5 0C 01 01 [B3 idle] B3 30 00 00 00 00 00 00 [A5 chat: ""] A5 03 00 00 A5 03 01 01 [B3 idle] B3 CF 02 00 00 00 00 00 [A5 command: idle mode] A5 3F 03 00 00 00 00 00 [B3 command: chat mode] B3 F3 0C 0C B3 F3 0D 0D [A5 command: chat mode ACK] A5 C0 00 00 00 00 00 00 [B3 chat: ""] B3 0C 00 00 B3 0C 01 01 [A5 idle] A5 30 00 00 00 00 00 00 [B3 chat: ""] B3 03 00 00 B3 03 01 01 [A5 idle] A5 C0 00 00 00 00 00 00 [B3 chat: ""] B3 0C 00 00 B3 0C 01 01 [A5 idle] A5 30 33 20 72 74 20 6F [B3 chat: "3 rt o"] B3 03 00 00 B3 03 01 01 [A5 idle] A5 C0 6B 20 73 6B 00 00 [B3 chat: "k sk"] B3 0C 00 00 B3 0C 01 01 [A5 idle] A5 30 00 00 00 00 00 00 [B3 chat: ""] B3 03 00 00 B3 03 01 01 [A5 idle] A5 C0 00 00 00 00 00 00 [B3 chat: ""] [Skipping empty chat/idling...] B3 0C 00 00 B3 0C 01 01 [A5 idle] A5 30 00 00 00 00 00 00 [B3 chat: ""] B3 03 00 00 B3 03 01 01 [A5 idle] A5 30 00 00 00 00 00 00 [B3 chat: ""] 00 00 00 00 00 00 00 00 [A5 shutdown] A5 30 00 00 00 00 00 00 [B3 chat: ""] [Retransmit] [A5 off] A5 30 00 00 00 00 00 00 [B3 chat: ""] [Retransmit] [A5 off] A5 30 00 00 00 00 00 00 [B3 chat: ""] [Retransmit] [A5 off] A5 30 00 00 00 00 00 00 [B3 chat: ""] [Retransmit] [A5 off] [B3 off]
In all the various packet examples in the descriptions below, the packet type / ARQ byte shown is only one among two or more possible values when taking ARQ sequencing into account.
Byte stream payload
Transmission data and operator chatter each take the form of byte streams, which are sent segment by segment inside traffic packets. The payload of a data or chat packet is a segment of the corresponding byte stream: 6 bytes in 600Bd mode, or 14 bytes in 1200Bd mode. If, when sending a packet, not enough data is available from the byte stream to fill the whole payload, a shorter segment containing whatever data is available is included, followed by padding.
Peer station |
Type / ARQ |
Byte stream segment | 1200Bd extra byte stream |
---|---|---|---|
CE | CC | 30 01 9B 01 00 00 | 9B 00 00 00 B6 01 00 00 |
Parameter payload
Many command packets use the following format to carry a command in their payload. The third byte of the packet is a command code, which may be followed by corresponding command parameters. The rest of the payload after the parameters is padded with 0x00 bytes. Often, the command has no parameters, so the parameters section is simply filled with 0x00. In 1200Bd mode, the extra payload is always padded with 0x00 bytes.
Peer station |
Type / ARQ |
Code | Parameters | 1200Bd padding |
---|---|---|---|---|
AA | CF | 01 | 11 77 70 00 00 | 00 00 00 00 00 00 00 00 |
Filler payload
Some other packets that don't need to carry much information follow a particular filler structure. As in parameter payloads, the third byte is a command code; it is repeated in the 4th byte. This first segment of the packet is then repeated: the first 2, header bytes appear again, identical, then the command code appears again for 2 bytes, its value either identical too (relay variant of the protocol) or incremented by 1 (Moscow and Pyongyang variants). In 1200Bd mode, this pattern also follows in the rest of the packet.
Peer station |
Type / ARQ |
Code | Filler | 1200Bd filler | |||
---|---|---|---|---|---|---|---|
Code repeat |
Header repeat |
Code variant |
|||||
Moscow / Pyongyang variants | |||||||
A5 | FC | 04 | 04 | A5 FC | 05 05 | A5 FC 06 06 | A5 FC 07 07 |
Relay variant | |||||||
D2 | FC | 21 | 21 | D2 FC | 21 21 | D2 FC 21 21 | D2 FC 21 21 |
Data packets
Peer station |
Type / ARQ |
TX data segment | 1200Bd extra data |
---|---|---|---|
CE | CC | 30 01 9B 01 00 00 | 9B 00 00 00 B6 01 00 00 |
Data packets contain segments of the main transmission data. When the transmission contains actual traffic, the transmission data byte stream follows a structured message format. The data stream is then ended by one 0x60 byte acting as an end-of-data marker. When there is no traffic, the data stream is reduced to the single 0x60 end-of-data byte. In either case, the end-of-data marker is followed by whatever necessary amount of padding bytes: 0x61 bytes for the Moscow and relay variants, 0x00 bytes for the Pyongyang variant. When there is no traffic or after finishing transmitting messages, the Moscow and relay variants go on and keep sending data packets filled with 0x61 padding bytes, until leaving data mode (the Pyongyang variant automatically switches to idle after sending the last data segment, containing the 0x60 end-of-data marker).
Chat packets
Peer station |
Type / ARQ |
Chat text segment | 1200Bd extra text |
---|---|---|---|
CE | C0 | 31 72 74 20 6F 6B | 20 73 6B 00 00 00 00 00 |
Chat packets contain text messages sent live from one station operator to the other. The text is encoded using the North Korean KPS 9566 character encoding. 0x00 bytes are used as padding: when text segments do not fill the whole payload, they are followed by 0x00 padding; when the station is in chat mode but there is no message text available to send (the operator has not typed in anything yet, or everything he typed was already transmitted), chat packets full of 0x00 padding are sent.
Message text contains no CR or LF new line characters; "//" is sometimes used as a separator instead. Furthermore, typos and inconsistencies in following message conventions suggest that chat messages are hand-typed by operators, using an IME to enter Korean, and pressing the enter key on the keyboard to send out messages. Routine uses of chat packets include QRU, QRT and sign-off chatter, as well as coordination of modem settings such as power, sensitivity and 600Bd/1200Bd mode toggling. Chat is also occasionally used for scheduling later links, or discussion of any operational issue, which sometimes reveals interesting insights on DPRK-ARQ operations.
Idle packets
Idle packets are traffic packets simply containing filler payload with the command code 0x00. The Moscow and relay variants send these when in idle mode, while the other station is in chat mode. The Pyongyang variant sends these when the station does not have something else to send, for example after finishing sending all the messages in the transmission.
Peer station |
Type / ARQ |
Code | Filler | 1200Bd filler |
---|---|---|---|---|
Moscow / Pyongyang variants | ||||
A5 | 0C | 00 | 00 A5 0C 01 01 | A5 0C 02 02 A5 0C 03 03 |
Relay variant | ||||
D2 | 0C | 00 | 00 D2 0C 00 00 | D2 0C 00 00 D2 0C 00 00 |
Command packets
Command packets each contain one command, mainly identified by the command code in the third byte. Command ACK packets correspond to a matching command: in the relay variant, they share the same command code, while in the Moscow variant, the command ACK apparently uses the command code value from its corresponding command, shifted by two bits to the left.
There are many different commands, and each protocol variant uses its own, different set of command codes for them.
Command | Packet type |
Example packet | Payload type |
||||
---|---|---|---|---|---|---|---|
Peer station |
Type / ARQ |
Code | Payload | 1200Bd padding / filler | |||
Moscow variant | |||||||
CQ | Command | AA | CF | 01 | 11 77 70 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
CQ ACK | Command ACK | A5 | FC | 04 | 04 A5 FC 05 05 | A5 FC 06 06 A5 FC 07 07 | Filler |
Idle mode | Command | A5 | CF | 02 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Chat mode | Command | AA | CF | 03 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Chat mode ACK | Command ACK | A5 | FC | 0C | 0C A5 FC 0D 0D | A5 FC 0E 0E A5 FC 0F 0F | Filler |
Data mode | Command | AA | CF | 06 | 60 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
Data mode response | Command | A5 | CF | 07 | 60 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
End of data | Command | A5 | CF | 08 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Relay variant | |||||||
CQ | Command | D2 | CF | 21 | 16 08 50 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
CQ ACK | Command ACK | CE | FC | 21 | 21 CE FC 21 21 | CE FC 21 21 CE FC 21 21 | Filler |
Idle mode | Command | D2 | CF | 41 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Chat mode | Command | D2 | CF | 47 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Chat mode ACK | Command ACK | CE | FC | 47 | 47 CE FC 47 47 | CE FC 47 47 CE FC 47 47 | Filler |
Data mode | Command | D2 | CF | 72 | 60 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
Data mode response | Command | CE | CF | 74 | 60 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
End of data | Command | D2 | CF | 74 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Empty parameters |
Pyongyang variant | |||||||
CQ | Custom | C8 | 01 | 16 31 80 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters (custom) | |
CQ ACK | Custom | D3 | 41 | 00 | C8 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
Data init 1 | Command | C8 | 43 | 01 | 01 2C E2 08 00 | 00 00 00 00 00 00 00 00 | Parameters (unknown) |
Data init 2 | Command | C8 | 43 | 02 | 00 00 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters (unknown) |
Data start 3 | Command | C8 | 43 | 03 | 5B F7 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
Data start 4 | Command | C8 | 43 | 04 | 98 2F 00 00 00 | 00 00 00 00 00 00 00 00 | Parameters |
CQ command parameters
This type of parameters appears in CQ commands of Moscow (code 0x01) and relay (code 0x21) variants. The QSX frequency, on which the peer station is expected to reply, is encoded using basic packed binary-coded decimal, 4 bits per digit (hexadecimal A..F is never used). Frequencies lower than 10 MHz are encoded with a leading zero. The QSX frequency is intended for LSB mode.
Peer station |
Type / ARQ |
Code | QSX frequency |
Padding | 1200Bd padding | Decode |
---|---|---|---|---|---|---|
D2 | CF | 21 | 16 08 5 | 0 00 00 | 00 00 00 00 00 00 00 00 | 16085 kHz LSB |
A4 | CF | 01 | 09 75 5 | 0 00 00 | 00 00 00 00 00 00 00 00 | 9755 kHz LSB |
The Pyongyang variant uses a custom packet type for CQ commands, without command code, but using the same encoding for the QSX frequency:
Peer station |
Type / ARQ |
QSX frequency |
Padding | 1200Bd padding | Decode |
---|---|---|---|---|---|
C8 | 01 | 16 31 8 | 0 00 00 00 | 00 00 00 00 00 00 00 00 | 16318 kHz LSB |
The Pyongyang variant also uses a custom packet type for CQ ACK, which contains as a parameter the modem ID of the station replying to the CQ:
Peer station |
Type / ARQ |
Code | Source station |
Padding | 1200Bd padding |
---|---|---|---|---|---|
D3 | 41 | 00 | C8 | 00 00 00 00 | 00 00 00 00 00 00 00 00 |
Data mode command parameters
This type of parameters appears in data mode and data mode response commands of Moscow (codes 0x06 and 0x07) and relay (codes 0x72 and 0x74) variants, as well as in data start 3 and 4 commands of the Pyongyang variant (codes 0x03 and 0x04). They contain information about the data stream going to be transmitted.
Peer station |
Type / ARQ |
Code | Transmission ID |
Position | Padding | 1200Bd padding | Decode |
---|---|---|---|---|---|---|---|
AA | CF | 06 | 78 4A | 00 00 | 00 | 00 00 00 00 00 00 00 00 | Starting TX "784A" |
D2 | CF | 72 | 60 00 | 00 00 | 00 | 00 00 00 00 00 00 00 00 | Starting QRU TX |
C8 | 43 | 03 | 5B F7 | 4A 01 | 00 | 00 00 00 00 00 00 00 00 | Resuming TX "5BF7" from 330 bytes |
A4 | CF | 06 | 60 00 | CE 01 | 00 | 00 00 00 00 00 00 00 00 | Resuming QRU TX from 462 bytes |
The transmission ID is a random-looking binary value. In the Pyongyang variant, it also appears in the transmission header at the beginning, inside of the data stream. It identifies that data payload: it remains the same in every data mode command resuming the same data stream on a given side of the link, however each station on the link uses a different transmission ID. When there is no traffic and the transmission is reduced to the single 0x60 end-of-data marker, it is identified by transmission ID "60 00".
The position field is a little-endian number of bytes which represents the point in the data stream from which the transmission is starting or resumed. It is 0 when the transmission is starting; when resumed, the value in the field is lower than the actual resuming position, by a small offset (apparently 6 bytes). If data mode is resumed after one side already reached the end of the stream, the further padding bytes are still counted towards the position field.
Flow control
Flow control is an area where the Pyongyang variant of the protocol departs majorly from the Moscow and relay variants. The Moscow and relay variants are based on traffic modes, flow state and command packets to manage it and transition between them - the Pyongyang variant is radically different.
In the Moscow and relay variants, when the link is established, each station is in a given traffic mode: data, chat or idle. While in a mode, stations send only traffic packets of the corresponding type, continuously; or command packets to transition out of that mode. Both stations enter, leave and are in data mode at the same time, exchanging transmission data contents in at the same time in full duplex. Chat and idle modes are always paired: when one station is in chat mode - and may send text messages to the other one, the other station is always in idle mode, listening without replying. The only reasons a station enters idle mode is either as a response to the other station entering chat mode, or when switching from chat to idle mode to hand off chat mode to the other station so it can reply. Either station can interrupt data mode at any time and switch the link to chat/idle mode. Chat/idle mode is also used as a default state after the link is established and before the data transmission is started; and also after the data transmission is ended, to exchange sign-off chatter before shutting down the link.
The mode transitions are codified in the protocol, and some commands always receive a given other command as a reply from the other station.
Command | Destination mode | Customary response |
---|---|---|
CQ | - | CQ ACK |
CQ ACK | - | Chat mode |
Idle mode | Idle | Chat mode |
Chat mode | Chat | Chat mode ACK |
Chat mode ACK | Idle | - |
Data mode | Data | Data mode response |
Data mode response | Data | - |
End of data | - | Chat mode |
For example, the sequence of commands CQ - CQ ACK - chat mode - chat mode ACK is always followed, going back and forth between the two stations, when establishing the link; and the sequence end of data - chat mode - chat mode ACK always followed after the data transmission is finished on both sides.
The Pyongyang variant is drastically different from this. There is no notion of mode or state, and most commands used to transition between them by other variants are inexistant in this one. Chat and idle are not paired, and each station can send chat packets at any time without interrupting the data transmission. Stations simply send idle packets whenever they are not sending something else: after the link is established and before data transmission starts, and also after the transmission reached the end of the data stream - at this point, contrary to the other variants, a station isn't bound to data mode having to send packets filled with 0x61 padding bytes while the other station is still transmitting data: instead it automatically switches to idle right away, without any command packet.
The most flow control in the Pyongyang variant is a sequence of commands when starting the data transmission. This sequence is believed to involve data init 1 or 2 commands (codes 0x01 or 0x02), followed by one of data start 3 or 4 commands (code 0x03 or 0x04). The station then starts sending data packets (if there is no traffic, it sends a single packet containing the 0x60 end-of-data marker). After reaching the end of the data stream (if any) and sending the last data segment, containing the 0x60 end-of-data marker, the station sends no further padding data packets and starts sending idle packets right away.
Link establishment
The link is first established when the calling station starts sending CQ commands for the other station, on a scheduled time and frequency. The other station, once it's up, ready, listening for and receiving the CQ commands, replies with CQ ACK packets. Once the calling station receives these packets back, the link is established. If propagation conditions are poor, this may take several attempts on different frequencies.
Conversely, when properly shutting down a link, one station sends as its last packet a special, invalid burst starting with the normal reversal bits, but containing only 0 bits, as many as a normal packet would; and then powers down. The other station on the link doesn't automatically power down, it usually keeps sending a few packets before being turned off.
When one station has lost reception of the other one, because link quality degraded too badly or the other station stopped transmitting, it omits sending every sixth packet, causing a noticeable skip in the signal bursts. This presumably serves as a feedback signal to the unhearable station. This condition may get reversed and cleared by itself if signal quality and reception are restored - the station then stops skipping packets; it also often happens in the context of switching link frequencies.
Contrary to power and sensitivity modem settings, which can be adjusted on the fly, toggling between 600Bd and 1200Bd or changing link frequencies (due to poor or degrading propagation conditions for example) require restarting the link: the calling station sends a shutdown burst and powers down, then after a few seconds restarts from the CQ stage, indicating a new QSX frequency, or transmitting from a different frequency, or using the other baud rate.
See also the conventions page for more information around the protocol concerning link establishment, frequencies and modem settings.