This specification describes the stream device of the Bedrock computer system.
The stream device provides access to two bi-directional bytestreams for exchanging data with other systems.
Ports
Port | Name | Description | Read | Write |
---|---|---|---|---|
0x80 |
Input connection | Connection state of local input channel. | ✓ | ✗ |
0x81 |
Output connection | Connection state of local output channel. | ✓ | ✗ |
0x82 |
Input transmission | Transmission state of local input channel. | ✓ | ✓ |
0x83 |
Output transmission | Transmission state of local output channel. | ✓ | ✓ |
0x84 |
Input length | Bytes waiting in local input queue. | ✓ | ✓ |
0x85 |
Output length | Bytes free in local output queue. | ✓ | ✗ |
0x86 |
Head | Read and write to local bytestream. | ✓ | ✓ |
0x87 |
aliased | aliased | ✓ | ✓ |
0x88 |
Input connection | Connection state of remote input channel. | ✓ | ✓ |
0x89 |
Output connection | Connection state of remote output channel. | ✓ | ✓ |
0x8A |
Input transmission | Transmission state of remote input channel. | ✓ | ✓ |
0x8B |
Output transmission | Transmission state of remote output channel. | ✓ | ✓ |
0x8C |
Input length | Bytes waiting in remote input queue. | ✓ | ✓ |
0x8D |
Output length | Bytes free in remote output queue. | ✓ | ✗ |
0x8E |
Head | Read and write to remote bytestream. | ✓ | ✓ |
0x8F |
aliased | aliased | ✓ | ✓ |
Input connection
Each input connection port is associated with the input channel of a bytestream.
Reading from an input connection port will return 0xFF
if the associated input channel is connected to another system, otherwise it will return zero.
Writing a byte to the input connection port associated with the remote bytestream will write that byte to the remote path buffer.
Output connection
Each output connection port is associated with the output channel of a bytestream.
Reading from an output connection port will return 0xFF
if the associated output channel is connected to another system, otherwise it will return zero.
Writing a byte to the output connection port associated with the remote bytestream will write that byte to the remote path buffer.
Input transmission
Each input transmission port is associated with the input channel of a bytestream.
Reading from an input transmission port will return 0xFF
if the transmission control flag of the associated input channel is set, otherwise it will return zero.
Writing a value to an input transmission port will remove all bytes from the buffer queue of the associated input channel, and then will set the transmission control flag of that channel.
Output transmission
Each output transmission port is associated with the output channel of a bytestream.
Reading from an output transmission port will return 0xFF
if the transmission control flag of the associated output channel is set, otherwise it will return zero.
Writing a value to an output transmission port will clear the transmission control flag of the associated output channel.
Input length
Each input length port is associated with the input channel of a bytestream.
Reading from an input length port will return the number of bytes waiting in the buffer queue of the associated input channel. If the queue contains more than 255 bytes, the value 0xFF
will be returned.
Writing to an input length port will drop the incoming transmission, removing all bytes from the buffer queue of the associated input channel and then dropping and ignoring all new bytes until the transmission control flag of the associated input channel is clear.
Output length
Each output length port is associated with the output channel of a bytestream.
Reading from an output length port will return the number of bytes of free space in the buffer queue of the associated output channel. If the queue has space for more than 255 additional bytes, the value 0xFF
will be returned.
Head
Each head port is associated with a bytestream.
Reading from a head port will remove and return a byte from the front of the input queue of the associated bytestream. If the queue is empty, the value zero will be returned.
Writing a byte to a head port will push that byte to the back of the output queue of the associated bytestream. The byte will not be pushed if the output channel is disconnected, the queue is full, or the transmission control flag for the associated output channel is not set.
Data structures
Bytestream
A bytestream is a bi-directional communications link that contains two uni-directional channels, an input channel and an output channel. Each bytestream can connect this Bedrock system to another system, called the connected system.
The input channel is used to receive data from the connected system, and the output channel is used to send data to the connected system.
This device contains two bytestreams: the local bytestream, controlled by the first eight ports, and the remote bytestream, controlled by the last eight.
Channel
A channel is a uni-directional link used to send bytes from a transmitting system to a receiving system. Each channel contains a buffer queue and a transmission control flag.
Bytes are sent through the channel by the transmitting system, are buffered in the queue, and then are received and processed by the receiving system. Bytes cannot be sent through a channel if the transmission control flag is not set.
Buffer queue
A buffer queue is a first-in first-out byte queue used to buffer transmitted data. The maximum size of each queue is implementation defined.
If a queue is full, all new bytes will be dropped.
Transmission control flag
A transmission control flag is a flag that indicates when a system is ready to receive a transmission. A transmission is a sequence of zero or more bytes. The initial state of each transmission control flag is cleared.
The receiving system on a channel will set the transmission control flag to indicate that it is ready to receive a transmission. The transmitting system can then begin a new transmission at any time. Once a transmission has completed, the transmitting system will clear the flag to indicate that the transmission has ended and that no more bytes will be sent.
The flag can only be cleared by the transmitting system, and can only be set by the receiving system.
Local bytestream
The local bytestream is used to connect the Bedrock system to a local system, such as a serial device or another program. A system must be connected to the local bytestream manually by the user, outside of the Bedrock system.
Remote bytestream
The remote bytestream is used to connect the Bedrock system to a remote system over an addressed network. A system can be connected to the remote bytestream by writing the network address of that system to the remote path buffer.
The remote connection will open in either server mode or client mode, depending on the port used to terminate the remote path buffer. The connection will open in server mode if the input connection port is used, or client mode if the output connection port is used.
In server mode, the remote bytestream will bind to an address. Each incoming transmission represents a request, and each outgoing transmission represents a response. A remote system can connect to this system if the transmission control flag is set and no other system is currently connected. The connection will be closed automatically when this system sets the input control flag, clears the output control flag, or drops the transmission, freeing the line so that another system can connect.
In client mode, the remote bytestream will connect to a remote system. Transmissions can be sent and received until either system closes the connection.
Remote path buffer
The remote path buffer is a 256-byte block of writeable memory with an associated pointer. The initial value of each byte of the buffer is zero. The initial value of the pointer is zero.
Writing a non-zero byte to the remote path buffer will write the byte to the buffer address referenced by the pointer, and then will increment the pointer by 1, wrapping to zero after 255.
Writing a zero byte to the remote path buffer will close the current remote connection, then will attempt to open a connection with a remote system if the final byte of the buffer is zero, and then will set the pointer and every byte of the buffer to zero. The buffer contents up to the first null byte are interpreted as a UTF-8 encoded string representing the network address of the remote system. The address format is implementation defined.
The remote connection will be opened in server mode if the zero byte was received from the input connection port, or client mode if the zero byte was received from the output connection port.
Implementation
Standard streams
If this Bedrock system is running inside a host operating system, the local bytestream should connect to the standard input and output streams provided by the operating system.
Encoded transmissions
There are a few different ways of encoding transmissions when communicating with systems that send data as unbroken streams. It is the role of the user, not the program, to select a format that will work well for the connected system.
If the connected system transmits and receives line-oriented text data, an incoming newline character 0x0A
should end each transmission and the character should be dropped. Likewise, when an output transmission is ended by the program, a newline character 0x0A
should be transmitted to the connected system.
To send binary transmissions as line-oriented text data, each byte should be encoded as a pair of uppercase hexadecimal digits followed by a space. A newline character 0x0A
should mark the end of each transmission.
For some use-cases, it could be desirable to send binary transmissions on such a system as raw bytes, with all transmissions concatenated together as a single stream.
Buffer flushing
If a connected system is buffered and needs to be flushed manually, it should be flushed at the end of every transmission.
Simultaneous requests
If the remote bytestream is bound to an address in server mode, incoming requests should be collected and queued in order to support multiple simultaneous requests.
Address formats
The remote bytestream should support URLs (RFC 1738, RFC 3986, and RFC 3987) as an address format.
Safety
Access to the remote bytestream could allow a malicious program to make excessive transmissions to a remote system or to exfiltrate sensitive data.
To mitigate this, a notification could be displayed every time the program tries to connect to a remote system, showing the address of the remote system so that the user can allow or block the connection.
Wake
This device will send a wake request to the system device when any of the following events occur:
- A byte is pushed to an empty read queue
- A byte is removed from a full write queue
- The transmission control flag on an input channel is cleared.
- The transmission control flag on an output channel is set.
- The local bytestream is connected or disconnected.
- The remote bytestream is disconnected.