Some ideas: Maybe I should call my layer 1 options blocks and call layer 0 the frame header. Possibly follow every block identifier with a 16 bit block size so that any block may be skipped-over by software which doesn't understand it RDTP/AX.25 Protocol Specification Heise / Luther http://www.k9nl.net/radar radar@k9nl.net Copyright (C) 2004 Nick Luther and Aaron Heise Version 0.3 Begin: 26 Feb 04 Current version release: 25 April 2006 ------------------------------------------------------------------------------------ This document is the official specification of the RDTP/AX.25 protocol. *** THIS IS A DRAFT *** *** THIS DRAFT IS INCOMPLETE *** DOCUMENT FORMAT Notes are in parenthesis. The terminating "NOTES" section is not considered part of this specification. Numerical values are decimal unless preceded by a 0x, in which case they are hexadecimal. Values should be handled as unsigned unless specified. The word literal in a byte definition indicates the following value should always be used for that byte. Characters in singles quotes ('') are ASCII values. Compliant software MUST specify them numerically, coded in ASCII. This assures portability to EBCDIC machines. REQUIREMENTS AND ABSTRACTION OF PROTOCOL RDTP/AX.25 is the Radar data Datagram Transport Protocol for use over AX.25. RDTP/AX.25 data is contained in AX.25 UI frames. One frame of RDTP/AX.25 data may not be split over multiple AX.25 UI frames. The RDTP/AX.25 transmit software must determine the maximum data size for the packets it will transmit. The AX.25 PID must be 0xF0 (text). Server-to-client data must be sent from the server's actual callsign to the callsign "RDTPC". Client-to-server data must be sent from the client's actual callsign to the callsign "RDTPS". These callsigns are used at the AX.25 level, real callsigns should be used at the RDTP level. Because of problems with the linux AX.25 implementation which I have experienced, a from callsign has been added to RDTP level 0. RDTP/AX.25 data consists of multiple layers. All RDTP/AX.25 frames include Layer 0 and one type of Layer 1 data. The layers are defined in the next section. Certain types of Layer 1 frames are given official names in parenthesis. Implementation notes are also provided in parenthesis. Layer 0, byte 2 is a transmitting-host-specific message sequence number. Hosts should increment this number with each message. Layer 0, byte 3 is a frame-specific sequence number. It MUST be 0 for the first frame of a message, then be incremented by 1 for each subsequent frame if and only if the specific message is broken into frames. In the case of the message being broken into frames, each frame must contain a Layer 0 header, but the Layer 1 information MUST be continued from where the preceding frame ended. The initial Layer 1 heading bytes will not be repeated. Multiple Layer 1 frames may be concatenated and sent in a single Layer 0 message. Callsigns MUST be specified as CCCCCCS. Where S is the station's SSID, with four 0 bits inserted before it, which must lie on [0,15]. Digipeating is not supported in this version of the protocol definition. CCCCCC is the ASCII callsign. It must use upper case letters. The end should be padded with 0x00 bytes if necessary. This specification does not define the use of the system message codes. This may be system-specific. However, if they are shorter than 7 bytes they should be padded with 0x00 bytes at the end. Access levels are 4 bit unsigned integers (on [0,15]). 15 is the highest access level, 0 the lowest. If a client does not have an access level preprogrammed for a system then its access level is presumed 0. A server may send the client a server-client-access-level-is frame at any time, in which case the client must use that access level until it receives a new one from the server or determines that the "quasi-connection" is terminated. This determination may be made with any algorithm the programmer chooses. A client should not respond to a level poll for an access level higher than its own. It should respond if it is polled individually, but include 0 codes if it cannot request any additional codes. No client should request a code which has already been requested. A request is cleared when its message is transmitted by the server. The product may then be requested again for the next time when it becomes available. Integer values are little-endian ordering unless they are marked NBO. Defined compression codes are: 0 - No compression 1 - Modified Bzip2 (deprecated) 2 - Normal Bzip2 [see ] The modified bzip2 format used in this specification consists of a 16-bit integer, little-endian ordering, which is the length in bytes of the uncompressed data, followed by the bzip2 compressed version of the data. For the frame header only, the length of the integer is reduced to 8 bits. If using normal bzip2, code 2, there is no need to worry about this. In fact, new software should not even support code 1. A nonzero compression code in the layer 0 header means that all data under the layer 0 header in this frame is compressed. A nonzero compression code in layer 1 (data) means that the chunk of data in the layer 1 (data) block is compressed. A N+1 parity frame is never required. If used, it is implemented at the layer 0 level. The data chunks of the layer 0 frames in a message are combined by logical XOR. If necessary, a frame may have any number of null 0x00 bytes appended to it. The parity frame contains no layer 1 data itself. The data of layer 0 is the logical XOR result. The parity frame should have the same message sequence number as the rest of the message. The frame sequence number is irrelevant, and should be set to 0x00. LAYER DEFINITIONS Layer 0: (frame header) Bytes 0-3: Literal ASCII 'R' 'D' 'T' 'P' (identifier for this protocol) Byte 4: Literal 0x00 (protocol version code) Byte 5: Bit 7: From call/ssid present flag Bit 6: N+1 parity data flag Bits 5-4: not used, literal FALSE Bits 3-0: From SSID if bit 7 is set [Optional six bytes (6-11): From callsign (w/o SSID)] (only if call present flag set) Byte 6: Transmitting host message sequence no. (unsigned, may be byte 12) Byte 7: Frame sequence number w/in the message (unsigned) Byte 8: Number of frames in this message - 1 (unsigned) Byte 9: Compression code Byte 10: Frame data length (unsigned) Layer 1 (data): Byte 0: Literal 0x00 (identifier for this frame type) Bytes 1-7: system message code (used in requests, 7 bytes) Byte 8: compression code (0, none; 1, m-bzip2; etc.) Bytes 9-10: length of data (unsigned) Bytes 11-n: chunk of data for this packet Layer 1 (server-announce): Byte 0: Literal 0x02 (identifier for this frame type) Byte 1: control protocol identifier Byte 2: minimum protocol version code supported Byte 3: maximum protocol version code supported Note: It may be a good idea to concatenate a server-free-text-message. Layer 1 (server-shutdown-announce): Byte 0: Literal 0x03 (identifier) Bytes 1-2: Seconds to shutdown (unsigned, 0 for immediate) Layer 1 (server-reset): (notice: the server has been restarted) Byte 0: Literal 0x0D (identifier) Layer 1 (free-text-message): Byte 0: Literal 0x04 (identifier) Bytes 1-2: Length of message (unsigned) Bytes 3-n: Message text Layer 1 (application-data): Byte 0: literal 0xff (identifier) Bytes 1-2: size of this block minus 5 for the headers (unsigned, NBO) Bytes 3-4: application identifier code (This block provides the possibility of adding to the protocol with special software while still maintaining compliance with this specification) The following frames represent Layer 1, server-announce, byte 1, control protocol identifier zero, literal 0x00. At this time this is the only control protocol which will be specified in this document. Other control protocols may be developed. Their developers should contact the authors of this document to register a control protocol identifier. Layer 1 (codes-available): Byte 0: Literal 0x05 (identifier for this frame type) Byte 1: Number of message codes listed here (unsigned) Bytes 2-n: System message codes, array, 7 bytes each Layer 1 (poll): Byte 0: Literal 0x06 (identifier for this frame type) Byte 1, bits 7-4: Poll type (specific callsign = 1, level = 0, wide open = 2) bits 3-0: the level in a level poll, otherwise 0 Bytes 2-8: callsign being polled if a callsign poll, other polls will not contain these bytes Layer 1 (data-request): Byte 0: Literal 0x01 Bytes 1-7: Callsign of server this message is intended for Byte 8: number of system message codes Bytes 9-n: system message codes, array, 7 bytes each Layer 1 (request-ack): Byte 0: Literal 0x07 (identifier for this frame type) Bytes 1-7: callsign being ack'ed Byte 8: number of system message codes requested Bytes 9 to 9+(7*n): list of the codes Layer 1 (request-denied): Byte 0: Literal 0x0C (identifier for this frame type) Bytes 1-7: callsign being ack'ed Byte 8: number of system message codes requested Bytes 9 to 9+(7*n): list of the codes Layer 1 (request-access-level): Byte 0: Literal 0x08 (identifier for this frame type) Bytes 1-7: callsign of server being queried Layer 1 (access-level-is): Byte 0: Literal 0x09 (identifier for this frame type) Bytes 1-7: client callsign Bytes 8: access level (4 bits are wasted) Layer 1 (request-fill): Byte 0: Literal 0x0A (identifier for this frame type) Bytes 1-7: Addressed callsign Byte 8: Message number of requested frame(s) Byte 9: Number of individual frames requested Byte 10-n: Array of frame sequence numbers Layer 1 (fill-denied): Byte 0: Literal 0x0B (identifier for this frame type) Bytes 1-7: Requestor's callsign Byte 8: Message number of requested frame(s) Byte 9: Number of individual frame requests denied Bytes 10-n: Array of frame sequence numbers denied NOTES *** THE FOLLOWING INFORMATION SHALL NOT BE CONSIDERED PART OF THE *** *** RDTP/AX.25 SPECIFICATION *** Notes from my 26 February 2004 message to Aaron Heise: As for a data protocol within AX.25 UI I have typed an idea. Remember that each host gets the callsign of the sender when it reads a packet. Therefore you never need to identify yourself. However, we may consider addressing who you're talking to in certain cases. I have to think about that. You don't get the to callsign when you read a packet. I also suggest that the control section be option 1, you have a more efficient control protocol in mind. Perhaps the control system being used by the server should be given in a server-announce layer or something like that. Then the client can just be quiet if it doesn't understand the control protocol. This does implement your idea of polling clients individually but it doesn't use connected mode. I want to start with the simple system and then we can play with fancier stuff. I solve the doubling problem with access levels. Each client has an access level on [0,15] (four bits). The ROC would be 15, stations without assigned numbers would be zero. The server's poll would be sequential, starting with 15, ending at 0. The algorithm could be designed to skip two, three, four, or more access levels with each poll, and it would probably only wait a second or so for a response (15 might get extra time). The server would ack the first client it hears and poll that level again (with a server-ack-and-poll frame). The server may also consider sending a client a server-client-access-level-is frame the first time it hears a client so that the client can adjust its access level if necessary. This whole thing would be implemented in a weighted queue within the transmit thread of the server. Data frames would move to the front of the queue. Other frames the back. The transmit thread would then progress through the frames, waiting a second or two after poll frames. A client would never "check in". But once it has responded to a poll the server may want to query it individually. If the products it wants have already been requested but it wants to stay in the poll sequence the client could send a poll response requesting 0 products (system message codes here). If a server is individually polling clients it would probably drop a client from the poll list as soon as that client is not heard responding to a poll. To make everything work, when the server reaches the clients access level, it will individually poll all clients at that access level, then issue an open access level poll for that access level. The server should probably include control scheme modules. One could be loaded to read requests emailed to it by a cell phone.