Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Chat Rooms

A chat room is a special node that provides limited store-and-forward capability for text messages and potentially other types of data. Chat rooms may be polled or can push updates to joined members.

Action Types

The first byte of the payload identifies the action type.

ValueActionDirection
0Get Room InfoUser → Room
1Room InfoRoom → User
2LoginUser → Room
3LogoutUser → Room
5Fetch MessagesUser → Room
6Fetch UsersUser → Room
7Admin CommandsUser → Room
8Room UpdateRoom → User

Regular message exchange — including system events — does not use a dedicated action type. Users send messages to the room as plain text message payloads (unicast to the room node), and the room distributes them to members the same way. Action types are reserved for room management operations. Room Update (action 8) is used only for batch history delivery.

Get Room Info / Room Info

A user may send a Get Room Info action to a room node without being logged in. The room responds with a Room Info action containing CoAP-option-encoded metadata:

NumberNameNotes
0Room NameUTF-8 string
1Owner Information
2AdministratorUser ID; may appear more than once. May only be included for logged-in users
3Active User Count
4Max User Count
5Message Queue Depth
6Most Recent Message Timestamp
7Oldest Retrievable Message Timestamp

If the options are terminated with a 0xFF byte, the remainder of the response is a UTF-8 description of the room.

Login

The login payload is CoAP-option-encoded:

NumberNameNotes
0HandleIf omitted, the room uses the previous handle or assigns one
1Last Message TimestampIf present, the room sends up to 10 missed messages since this time
2Session TimeoutRequested inactivity timeout in minutes (1 byte)
3PasswordRequired only if the room is password-protected and the user’s public key is not already known

All options are optional. Behavior details:

  • If a last-message timestamp is provided and more than 10 messages have been received since then, only the 10 most recent are sent automatically. Older messages can be retrieved with Fetch Messages.
  • If the room is password-protected but already recognizes the user’s public key, the password is ignored. A room may forget a public key after prolonged inactivity, requiring a password on the next login.
  • First-time logins must include the full 32-byte public key (S flag set).

Logout

Logging out unsubscribes the user from push updates and removes them from the active user list. Previously sent messages remain stored and retrievable by other users up to the history limit.

If the user is currently logged in, the room sends a final text message to all members using the User Left message type (see System Events).

Send Message

To send a message to a chat room, a user sends a standard text message unicast to the room node. The Sender Handle option is ignored — the room fills it in from the sender’s registered handle when distributing the message to members.

The Message Sequence option SHOULD be included, using the sender’s own per-sender message ID counter. The room uses this to detect duplicate submissions and to order rapid messages from the same user. The sender’s per-sender ID is separate from the canonical room-assigned ID that the room assigns when distributing the message.

Fetch Messages

Retrieves previous messages posted to the room, which may include system messages.

FieldSizeDescription
Timestamp4 bytesFetch messages up to and including this time
Max Count1 byteMaximum number of messages to return

Fetch Users

Retrieves the currently active user list, possibly including their public keys.

Admin Commands

TBD.

Message Distribution

When the room receives a message from a user, it assigns a monotonically increasing canonical Message Sequence ID from a single room-wide counter and distributes the message to each logged-in member as a text message. System events (user join/leave, admin messages) are distributed the same way, using room-specific message types. This gives the room a single unified message ordering across all activity — a Regarding option referencing a room message ID is unambiguous without a source prefix (see Regarding).

All timestamps are managed by the room and are relative to its own clock — typically a UTC UNIX timestamp, though accuracy depends on whether the room’s clock is synchronized.

Sender Sequence

When the room echoes a message back to the original sender, it faces a correlation problem: the sender showed the message optimistically in their UI the moment they sent it, but the echoed copy arrives with a room-assigned ID the client has never seen. Without some way to link them, the client cannot reliably identify which pending outbound message the echo corresponds to — matching by content alone fails if the user sends identical messages in quick succession.

To solve this, the room includes a Sender Sequence option on the echo it sends back to the original sender. This option is not included in copies sent to other members.

NumberNameValue
12Timestamp Received4 bytes, UTC UNIX timestamp
13Sender Sequence1 byte — the sender’s original Message Sequence ID

The Sender Sequence value is the per-sender Message Sequence ID the user included in their outbound message. The client matches this against its pending outbound messages to identify the echo, then updates its local record to use the canonical room-assigned ID for future Regarding references.

System Events

The room delivers system notifications as text messages to all logged-in members, using message types reserved for room use:

ValueName
32User Joined
33User Left
34Admin Message

The Sender Handle option is automatically populated by the room for all distributed messages, including system events.

Room Update

Room Update is used exclusively for batch delivery: the history sent on login (via the Last Message Timestamp login option) and the response to Fetch Messages. It contains a list of length-prefixed text messages in chronological order, each carrying the room-injected options defined above (Timestamp Received, and Sender Sequence where applicable). This batching avoids the per-packet overhead of sending history as individual unicast messages on LoRa.

ValueActionDirection
8Room UpdateRoom → User