Skip to content

ahoi Packet Format

The ahoi modem communicates with other modems and with its host via packets using the same packet format. Normal packets carry a header and an optional payload. Extended packets feature an additional footer. The packet structure is given below. Whenever needed, network byte order is used.

Figure 1

General Aspects

The definition of the header is:

typedef struct __attribute__ ((__packed__)) {
  mm_addr_t   src;     // source address
  mm_addr_t   dst;     // destination address
  mm_type_t   type;    // packet type
  mm_status_t status;  // statusflags
  mm_seq_t    dsn;     // sequence numbers
  mm_length_t len;     // payload length in bytes
} mm_header_t;
with the following meaning:

  • The fields src and dst carry the address (ID) of the sending modem and the intended receiving modem (not the host). The broadcast address is 0xFF, and it may only be used in the dst field, behavior for the src field is unspecified (and discouraged).

  • The field type specifies the packet type

  • The field status contains the following flags:

    • A-flag: hardware ACK request
      The receiver will send an auto-ACK, if the dst field of the packet matches the receiver's address.

    • R-flag: hardware ACK request with ranging information
      The receiver will send an auto-ack with ranging information (also referred to as ranging ACK), if the dst field of the packet matches the receiver's address or is the broadcast address. Upon reception of the ranging ACK, the original sender attaches ranging information to the received ACK before forwarding it to the host.

    • E-flag: encoding select
      The modem supports two different FEC (forward error correction) strategies. If the E-bit is set, the modem will use a lower redundancy FEC for the packet payload in order to increase data rate (up to 37.5% for long packets). This setting may, however, increase packet error rates, so that it is only advisable in good channel conditions.

    The remaining 5 bits are reserved for future used and must be unset (null / unused).

  • The field dsn contains the packet sequence number, which is currently user-defined (it is suggested that the dsn field is incremented for each new acoustic packet).

  • The field len determines the size of the following payload in bytes; i.e., the size of the payload must match the value provided in the len field. Packet length is restricted to values from 0 to MM_PAYLOAD_MAXLEN (see firmware sources).

Packet Types

Packets are split in two categories: acoustic packets and commands. The category is determinedby the MSB (most significant bit) of the type field:

  • A set MSB (type \(\ge\) 128) indicates a command
  • an unset MSB (type \(<\) 128) indicates an acoustic packet.

Acoustic Packets

Acoustic packets are forwarded transparently on the acoustic channel. The packet type is user-defined with allowed values from 0 to 126. The value 127 (0x7F, all bits but MSB set) is reserved for ACKs (acknowledgments, see below). The host may request an auto-ACK (created by the receiving modem upon a match of its ID and the dst field of the received packet) by setting the A-flag in the header. The receiver prepares an ACK, which is a normal packet with

  • type 127 (0x7F),
  • no payload (len set to 0),
  • the src field set to the ID of the receiver (itself),
  • the dst field set to the ID of the sender (of the data packet) requesting the ACK,
  • and the dsn field copied from the received packet.

ACKs have cleared A- and R-flags. On the receiving side, ACKs are treated as (acoustic) packets and are forwarded to the host. The host may request a ranging ACK (created by the receiving modem upon a match of its ID and the dst field of the received packet, or if dst was the broadcast address) by setting the R-flag in the header.

If both A- and R-flag are set, a ranging ACK will be sent. A ranging ACK is an auto-ACK with the difference that it will carry a payload (the time elapsed between reception of the packet and the transmission of the ACK in micro-seconds, currently 4 byte). On the receiving side, ranging ACKs are treated as ACKs, but the receiving modem rewrites the payload before forwarding the ranging ACK to the host. A ranging ACK (as forwarded to the host) contains 4 32-bit unsigned integers (len\(=\)16), of which the first integer is half of the cumulated propagation delay of packet and ranging ACK in micro-seconds. Distance information can be obtained by multiplying this value by the speed of sound.

Command Packets

Command packets are processed by the receiving modem directly. They are not sent as acoustic packets. For each command, there will be a reply by the modem with same packet type but (possibly) different payload structure. Please see src/aci/acitypes.lst (in the firmware repository) for all available commands. Here, all packet types (and payload structures) are defined. Packet types for commands range from 128 (0x80) to 253 (0xFD).

Communication from Host to Modem

Packets sent from host to modem always have a header, and they may have a payload of size len as defined in the header. As of now, excess payload bytes will be stripped, and too short packets will be discarded. Packets sent from host to modem never have a footer (which will betreated as excess payload).

Communication from Modem to Host

The modem replies to command packets with a packet of same type but potentially different payload structure. Details can be found in the subfolder src/aci. If the modem receives an acoustic packet, it forwards the packet to the host (regardless of addressing information in the dst field of the packet). The host is required to filter out snooped packets, if they shall not be handled. As an exception to the previous packet format, the modem always attaches additional footer information (type footer_t) to all acoustic packets and ACKs that were received on the acoustic channel before forwarding them to the host. The size of this footer is fixed and not part of the len field of the header. Footer information is only present for packet types 0 (0x00) to 127 (0x7F).

The footer has the format

typedef struct __attribute__ ((__packed__)) {
  rssi_t   power;
  rssi_t   rssi;
  uint8_t  biterrors;
  uint8_t  agcMean;
  uint8_t  agcMin;
  uint8_t  agcMax;
} mm_footer_t;

where the meanings of the fields are as follows:

  • power: The receive level (RMSE) of the packet (header and payload) vs. a perfect packet in percent (values above 100 indicated signal clipping).

  • rssi: The receive-signal-strength-indication (RSSI) of the packet (header and payload) vs. a perfect packet in percent (values above 100 indicated signal clipping).

  • biterrors: the number of repaired bit errors during reception.

  • agcMean: mean gain value set by AGC (automatic gain control) during reception of the corresponding packet (if AGC is disabled, the behavior is undefined).

  • agcMin: minimum gain value set by AGC during reception of the corresponding packet (if AGC is disabled, the behavior is undefined).

  • agcMax: maximum gain value set by AGC during reception of the corresponding packet (if AGC is disabled, the behavior is undefined)