The M-o-a-T protocol

The MoaT message structure

MoaT messages are small data structures.

If bit 8 of the first byte is clear, the message is destined for this slave and the byte is a function code. If it's set, the message needs to be forwarded (if sent towards a slave) / has been forwarded (if sent towards a master), and the remaining 7 bits contain the slave's ID.

Message types

A MoaT device is expected to be able to implement multiple distinct features, i.e. "things it can do". These features are numbered.

0x00 Console

Sent to a slave, this message contains plaintext Forth commands.

Sent to a master, this message contains plaintext Forth output.

If a slave receives this message from another slave, it must be discarded.

Config

One byte. Bit 0…2 are the verbosity level (trace debug info note warn error fatal dead). Bit 3 controls whether console messages should be packaged (true) or sent directly (false), if a serial link is used.

0x01 ping

This is a liveness detection message. The device thus addressed shall reply with a "pong" message; the payload shall be identical.

Config

Must always be included in the feature bitmap.

0x02 pong

Sent only as a reply to a "ping".

Config

Include in the feature bitmap if you send 0x01 ping requests yourself.

Configuration: a byte detailing how often you send a Ping. Zero: not at all. Otherwise the upper 6 bytes say how far the pings are apart (2^n seconds, except that 0x3f is one week and 0x3e is one day). The lower two bits convey the range of allowed variance:

Value Range
0 none
1 1 second
2 6.25% of the interval (4-bit shift)
3 25% of the interval (2-bit shift)

The interval is reset when receiving a config message.

0x03 address assignment

Sent to the master, the payload is the slave's unique serial number.

Sent to the slave, the payload consists of the slave's new link address, followed by a copy of its serial number.

The length of the link address is determined by the network layer.

When an intermediate system receives this message, it allocates the first free slave address to the slave and replies. It then forwards this message to its master system as usual, i.e. prefixed with the slave's address.

An intermediate system doesn't need to remember the serial numbers of its slaves: the master will clear the old address when it notices a duplicate.

A config inquiry transmits the serial number.

0x04 Feature discovery and configuration

This message inquires about, describes, or configures the feature in question.

Direction Length Use
Master > Slave zero request config bitmap
one request config data of this feature
more configure this feature
Slave > Master zero request full configuration
one request configuration of this feature
more config data of this feature

A named feature's configuration data starts with the feature name, followed by a NUL byte. If the master echoes the data after the name back to the slave, the slave shall not change its internal state.

Features numbered 0x00 through 0x07 are fixed and do not have names.

Config

A "which features are available" bitmap is returned as the configuration data of the feature x04 itself. If the master sends such a bitmap, features whose bit is set shall be reset.

0x05 Network discovery

Master > Slave

If the next byte is <0x80, request information about the slave with this ID (no following bytes), or set slave flags. Specifically, setting bit 0 to zero disables a slave.

If the next byte is x80, requests a bitmap of allocated slave IDs.

Other values are reserved.

Slave > Master

If the next byte is <0x80, the following bytes contain information about this slave. The first byte is a flag byte. The only defined flag bit is bit 0 which shall be set if the slave is active. Other bits and bytes are reserved.

If the next byte is 0x80, the following data contain a bitmap of allocated slaves' seqnums.

Other values are reserved.

Config

TBD

0x06 Error

Sent to the master, this message starts with a text describing the problem. The text should not include any variable elements. It is terminated by a NUL byte. When sent to the slave, this element is omitted. If the slave doesn't have an appropriately-specific message text, it shall send a single NUL byte instead of a text like "unknown problem" or "generic error". In any case, words like "error" or "problem" shall be omitted because that's implied by the fact that this is an error message.

The following data bytes replicate the message causing the problem, up to and including the erroneous byte(s).

If more information is required, the message replication shall be a two-part element as described in 0x07 Nested messages. The first part is the erroneous message in question, the second part is a 0x06 Error message containing additional feature+error-specific data.

When sending an unsolicited error message, the slave shall use that part of the original message as the error that's been assembled up to that point.

Config

The feature bit is set if the slave is able to process error messages.

0x07 Nested messages

Multiple messages for this slave. The rest of the message is a sequence of length bytes and sub-messages. A nested message inside another nested message is forbidden.

There are two errors that can be caused by a 0x07 message:

  • the overall message is shorter than the last sub-part
  • nested messages are not supported in the first place

The ambiguity is resolved by nesting the erroneous message in another 0x07 message, as per more information above. The part with additional information may then be omitted.

Config

If available, indicates support for nested messages.

0x08 … 0x7F

reserved for individual features

0x80 … 0xFF

This address range is used for message forwarding; see the next section.

Network layer

Packets with a function code >= x80 are network packets. Sent to a slave, the first byte will be removed and the data is forwarded to the appropriate sub-device. Sent to a master, the intermediate slave will prefix the source system's local address and forward it.

If more than 128 slaves are required, the intermediate slave is free to use more than one byte; each must have its high bit set.

Intermediate devices must perform limited address assignment,

Minimal slave implementation

First, think of a descriptive short name for your feature.

There will be a MoaT feature registry.

Boot

Randomly delay for 0.5…2 seconds.

Broadcast a 0x03 address assignment message with your serial number.

Wait for x01 messages, set your own address to the address in the packet if the transmitted serial number matches. Save the source address, because that's the master.

Repeat if there was no reply for ten seconds or so.

Send x04 x08 if you do not have non-volatile storage for your feature's configuration and need reconfiguration by the master.

Operation

Send a 0x02 Pong if you receive a 0x01 Ping.

Send x04 x02 x01 when you receive a message x04 x04. (The last byte depends on your features.)

Send your serial number if you receive x04 x03.

Send x04 x08 Hello x00 if you receive x04 x08.

Do whatever your "Hello" function is supposed to do when you receive a message starting with x08.