Packet and Message Spec
Runtimes, Links and Ports
Each module in an OSAP System has a runtime (normally corresponding to the root osap.
object), a list of links (data transport modules), and a list of ports (software interfaces).
Routing
Ports and Links each have a unique index within their runtime, and we make routes between modules by enumerating ‘hops’ across links. Each hop is an instruction, and packet headers contain lists of these instructions as byte-codes.
Within a system, there is one unique route between any port to any other port.
Naming
Using index-based routes at the functional level makes OSAP fast and small, but enumerating lists of numbers is semantically meaningless for most system programmers.
So, OSAP includes a naming scheme and resolves human-readable strings to machine-readable routes during operation. These names (and routes) are all discoverable.
Each module has a runtime-editable, nonvolatile name that is meant to be unique to that instance. They also have a typename and version number, which are immutable during runtime.
Ports and Links in each module also each have a name (unique throughout the module), and a typename.
This means that any port or link is also addressable by a unique set of semantically meaningful strings, and systems assembly typically resolves to calls like osap.send(payload, "moduleName", "portName")
Overall Packet Structure
The packet’s first 5 bytes encode a pointer (to the currently relevant instruction), as well as fields for the packet’s Time To Live (TTL) and Maximum Segment Size (MSS) that are required for packet prioritization / timeouts and for chunking replies.
The pointer is arranged such that packet[packet[0]]
resolves to the currently-relevant packet instruction.
I am also reserving the very first bit in cases where we want to modify this structure, perhaps to shrink or enlarge the TTL and MSS fields to save packet space, or operate on much larger modules.
B0 [0] | B0 [1:7] | B1 | B2 | B3 | B4 | B5 ... | ... BN |
R | PTR | TTL: 0-65535 Microseconds | MSS: 0-65535 Bytes | ... Instructions | ... Payload |
Packet Instructions
Packet headers encode instructions, which are operated on by the distributed system as the packet traverses through modules.
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
B0 | B1 | B2 | |||||||||||||||||||||
System Message: OSAP Internal Messages for Discovery, etc. | |||||||||||||||||||||||
SMSG (0) | R | MSG KEY (0-31) | | | ||||||||||||||||||||
Point Forward: Send the packet along a simple link. | |||||||||||||||||||||||
LFWD (1) | R | Link Index (0-31) | | | ||||||||||||||||||||
Bus Forward: Send the packet along a bus link. | |||||||||||||||||||||||
BFWD (2) | R | Link Index (0-31) | Rx Addr (0-255) | | | |||||||||||||||||||
Port Datagram: The packet is a datagram for a port in this module. Source port provided for replies. | |||||||||||||||||||||||
(PKEY_DGRM << 6 | source >> 6) | (source << 2 | destination >> 8) | (destination & 255) | |||||||||||||||||||||
DGRM (3) | R | R | Source Index (0-1023) | Destination Index (0-1023) |
System Messages
We’d like to have a minimum of these messages in order to return a full map of the transport layer, while also keeping maximum messages sizes under 16 bytes each.
The MSG ID is a tag used across system messages to disambiguate responses to requests, a they are collected at the request issuer. Basically a callback tag, they let us issue up to 255 messages to an individual module at a time.
Runtime Info Request / Response
This is the initial poke into a module, getting link, bus and port counts, as well as the module’s name, type and version.
The Trace Session ID is a stateful tag for graph traversals. When a module recieves an RTINFO_REQ from another module, it stores the transmitted session ID and replies with the most-recently stored session ID. This is required in order for graph traversals to function when there are loops in the system’s connectivity; it allows the tracer to identify when it is starting to recurse back through sections of the graph that it has already discovered.
B0[0:1] | B0[2] | B0[3:7] | B1 | B2, B3, B4, B5 |
SMSG | R | RTINFO_REQ (0) | MSG ID | Trace Session ID |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2, B3, B4, B5 | B6 | B7 | B8 | B9 | B10, B11 | B12[0:2] | B12[3:7] | B13[0:5] | B13[6:7], B14[0:7] |
SMSG | R | RTINFO_RES (1) | MSG ID | Prior Trace Session ID | Runtime Type | OSAP Ver. Major | OSAP Ver. Mid | OSAP Ver. Minor | Instruction of Arrival | R | Point Link Count (0-31) | Bus Link Count (0-31) | Port Count (0-1023) |
Module Type Get
B0[0:1] | B0[2] | B0[3:7] | B1 |
SMSG | R | MTYPEGET_REQ (2) | MSG ID |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2 | B3 | B4 | B5[0:1] | B5[2:7] | B6 ... BN |
SMSG | R | MTYPEGET_RES (3) | MSG ID | Module Ver. Major | Module Ver. Mid | Module Ver. Minor | R | Type Name Len (0-63) | Type Name |
Module Name Get
B0[0:1] | B0[2] | B0[3:7] | B1 |
SMSG | R | MNAMEGET_REQ (4) | MSG ID |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0:1] | B2[2:7] | B3 ... BN |
SMSG | R | MNAMEGET_RES (5) | MSG ID | R - | Module Name Len (0-63) | Module Name |
Module Name Set
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0:1] | B2[2:7] | B3 ... BN |
SMSG | R | MNAMESET_REQ (6) | MSG ID | R | Module Name Len (0-63) | Module Name |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2 |
SMSG | R | MNAMESET_RES (7) | MSG ID | ACK / NACK |
Link Info Collection
Once we have a port count, we can scan each individual for its state (open/closed/opening/closing), typename, and a proper name (very similar to ports).
‘typelen = 0’ is the null point-link !
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0:2] | B2[3:7] |
SMSG | R | LINKINFO_REQ (8) | MSG ID | R | Index (0-31) |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0] | B2[1:2] | B2[3:7] | B3 ... BN | BN+1[0:1] | BN+1[2:7] | ... BM |
SMSG | R | LINKINFO_RES (13) | MSG ID | R | State (0-3) | Type Len (0-32) | Type Name | R | Name Len (0-64) | Name |
Port Info Collection
- ‘typelen = 0’ is the null port… ?
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0:5] | B2[6:7], B3[0:7] |
SMSG | R | PORTINFO_REQ (12) | MSG ID | R | Index (0-1023) |
B0[0:1] | B0[2] | B0[3:7] | B1 | B2[0:2] | B2[3:7] | B3 ... BN | BN+1[0:1] | BN+1[2:7] | ... BM |
SMSG | R | PORTINFO_RES (13) | MSG ID | R | Type Len (0-32) | Type Name | R | Name Len (0-64) | Name |
TBD: Bus Link Info Collection
// get bus-link info
BUSINFO_REQ: 10,
BUSINFO_RES: 11,
- TBD: we need to get a state mask (~ 33 bytes, each bit 0-255 on/off) and then get more detail of
- we also want to get the type and name…
- maybe three msgs for busses: names, states (overview), states (detail)
TODO
- it would be rad to have hover-over for each field w/ alt description, etc, for i.e. ‘MSS’ or ‘TTL’ … lil in-context explainers