# rasuir protocol spec
rasuir is a simple protocol for semi-dumb remotes to retrieve menus and informational displays from a server. it is a stateless protocol; connections are ephemeral

%author lexi hale
%toc

## client and server state
a client uses two state variables when communicating with a server. these are [$mode] and [$ref]. [$mode] is an [!int<16>] menu number, where 0 is the root menu. [$ref] is an [!int<64>] opaque value.
a server is not required to store any state, but may do so in order to implement sessions if complex behavior is absolutely required

## definitions

an italicized form indicates a formally specified sequence of bytes. parameters (e.g. the length of an integer form) are placed in angle brackets after the identifier. if the form is bound to a name in context, it is followed by a [`:] and a name in variable notation.
* [*byte], [*byte<1>] ==> one octet
* [*byte<[$N]>] ==> [!byte] [!byte<[=N-1]>]
* [*int<[$N]>] ==>  [!byte<[=N / 8]>] interpreted as a little-endian unsigned integer (e.g. [!int<32>] represents an unsigned little-endian 32-bit integer)
* [*sigint<[$N]>] ==> like the above, but interpreted as a two's-complement signed integer
* [*byte-sequence<[$L]>] ==> [!int<[$L]>:[$N]] [!byte<[$N]>], with no specific semantics. that is, a variable-length byte sequence whose size prefix is [$L] bits long
* [*string] ==> [!byte-sequence<8>] interpreted as a UTF-8 string
* [*text] ==> [!byte-sequence<16>] interpreted as a UTF-8 string
* [*bitmap] ==> [!int<16>:[$pxl-width]] [!byte-sequence<8>:[$map]]
* [*state] ==>
*: if on the root menu: [`0x00]
*: if on a menu with an ID between [`1]~[`127] and the opaque [$ref] value is [`0] ("null"): the menu number cast to [!int<8>] (e.g. [`0x00 4A] --> [`0x4A])
*: if on a menu between [`128]~[`383] with a null [$ref] value: [`0x80] [!int<8>:[=mode - 128]]
*: if on a menu greater than [`383] with a null [$ref]: [`0x81] [!int<16>:[$mode]]. this form is also valid if the number is lower than [`383], and can be used where logical simplicity is more important than compact signalling
*: otherwise:
*:: let [$ref-len] be the length in bytes of the [$ref] value, maximum 8 (0 is valid, in which case no [$ref] sequence is sent)
*:: let [$mode-range] be [`0] if [$mode] is between [`0] and [`255], [`1] otherwise
*:: let [$signal-byte] be [`([$ref-len] << 1) | [$mode-range]]
*:: send [!int<8>:[$signal-byte]] [!int<[`8 + 8*[$mode-range]]>:[$mode]] [!int<[`[$ref-len]*8]>:[$ref]]
* [*link] ==> [!int<8>:[$role]] [!state:[$target]]

## outline
: client connects to server
: client transmits {m.n con-ack}
: server responds {m.n status-ok}
: client and server authenticate using the [>nimtas authentication protocol]. for an anonymous connection, this is as simple as the dialogue “C: [`0x00] / S: {m.n status-ok}”
: client transmits a command
:: {m.n cmd-get} retrieves a menu. it takes the form [!state] [!action]
:: {m.n cmd-hint} transmits a hint to the server. it takes the form [!int<8>:[$hint]] [!byte-sequence<16>]
:: {m.n cmd-meta} requests metadata from the server. it takes the form [!int<16>]
:: {m.n cmd-end} closes the connection. it takes no arguments
: server issues [>rep reply]
: while command was not {m.n cmd-end}, previous two steps repeat
: peers disconnect
	nimtas: file:nimtas.ct


##rep server replies
all replies begin with a one-byte status code.

### cmd-get reply
the get reply code may be:
* {m.n status-ok}: the request was valid but the current display should not be changed
* {m.n status-fail}: the request was not valid
* {m.n status-ignore}: the action did nothing
* {m.n status-data}: the request was valid and a form is being returned to display.

if the reply is {m.n status-data}, it is followed by the header [!byte:[$flags]] [!int<16>:[$widget-count]]
* [$flags] is a bitmask
** [`0x01] = [*passthrough]: all actions should be passed through raw, instead of being used to select a choice in a device-dependent way
** [`0x02] = [*refresh]: client should poll the server for periodic updates on this screen. the header should be followed by an additional parameter [!int<16>:[$refresh]] where refresh time is [=10ms * refresh]

[$widget-count] widgets then follow. a widget takes the form [!byte:[$wid]] [!byte-sequence<18>:[$data]]. [$wid] identifies the widget type. [$data] holds the widget contents. it is widget-dependent; this value is given as sequence so it can be skipped over by clients that don't implement [$wid]; e.g. images on text displays (though a hint should be sent to disable images instead, in order to save bandwidth).

### cmd-hint reply
the hint reply code may be:
* {m.n status-ok}: the hint was understood and applied
* {m.n status-fail}: the hint was invalid
* {m.n status-ignore}: the hint was not understood and was ignored
* {m.n status-data}: the hint was understood, and metadata is being returned
if the reply is {m.n status-data}, the code must be followed by a [!byte-sequence<16>]. the meaning of this sequence is hint-dependent.

### cmd-meta reply
the meta reply code may be:
* {m.n status-ok}: the metadata request was understood but the field is empty/blank
* {m.n status-fail}: the data requested could not be retrieved
* {m.n status-ignore}: the request was not understood and was ignored
* {m.n status-data}: the request was understood, and metadata is being returned
if the reply is {m.n status-data}, the code must be followed by a [!byte-sequence<16>]. the meaning of this sequence is hint-dependent.


## widgets
* {m.n w-section} =  [`0x00] [!string] / inserts a heading
* {m.n w-paragraph} = [`0x02] [!text] / shows a block of text
* {m.n w-rule} = [`0x03] / inserts a horizontal line that stretches across the screen
* {m.n w-define} = [`0x04] [!string:[$name]] [!text:[$val]] / shows a definition (e.g. [`[*Name]: Value]); sequential definitions may be arranged into a table
* {m.n w-bitmap} = [`0x05] [!bitmap] / shows an image
* {m.n w-bitdef} = [`0x06] [!string:[$name]] [!text:[$val]] [!bitmap] / like {m.n w-define}, but the value is characterized by an image rather than the [$name] string where possible
* {m.n w-pbar} = [`0x07] [!int<8>:[$progress]] / shows a progress bar; [`0] means empty, [`255] means full
* {m.n wi-bitmap} = [`0x08] [!link] [!string] [!bitmap] / shows an image that can be activated as an option, along with caption that may be displayed as a substitute for the image in text-only displays
* {m.n wi-bitmap-l} = [`0x09] [!link] [!string] [!bitmap] / like {m.n wi-bitmap} except the label is not omitted on devices with image support
* {m.n wi-choice} = [`0x01] [!link:[$target]] [!string:[$label]] / adds an option that can be selected from the menu, causing the client for query for [$target].
* {m.n wl-horiz} = [`0x80] [!int<8>:[$N]] / the next [$N] widgets will be arranged horizontally into a grid if possible

## roles
a role is a small piece of metadata that alters the appearance of an object, for example by changing color or applying an icon. defined roles consist of:
: generic
: accept
: abort
: cancel
: next
: back
: delete
: pause
: play
: stop

## hints
* {m.n device-kind}: [!int<8>:[$kind]] where [$kind] denotes the kind of device the client is running on. can be repeated to add additional characteristics
*: miniscreen: tiny embedded screen
*: midscreen: phone-sized screen
*: bigscreen: tablet- or larger-sized screen
*: e-ink: the display device uses e-ink (implies bw unless color is also sent)
*: bw: display is black and white
*: color: display supports color
*: slow: device refreshes slowly
*: no-img: do not send bitmap images

## meta requests
* {m.n server-name} = [`0x00 00]: returns the hostname of the server as a UTF-8 string, or {m.n status-fail} if the hostname is not known
* {m.n server-desc} = [`0x00 01]: returns a textual description of the server, or {m.n status-ok} if no description is set

##m magic numbers
	n: ‹[*[#1]]›

+ ID + value +
| con-ack | [`0x7A] |
| status-ok | [`0xFF] |
| status-data | [`0xF0] |
| status-ignore | [`0x0F] |
| status-fail | [`0x00] |
| cmd-get  | [`0x01] |
| cmd-hint | [`0x02] |
| cmd-meta | [`0x03] |
| cmd-end | [`0x00] |
| w-paragraph | [`0x00] |
| w-section | [`0x02] |
| w-pbar | [`0x04] |
| w-define | [`0x03] |
| w-rule | [`0x07] |
| w-bitmap | [`0x05] |
| wi-bitmap | [`0x06] |
| wi-choice | [`0x01] |
| wl-horiz | [`0x80] |
