Stream device

This is the specification for the stream device of the Bedrock computer system.

This document is aimed at people who are implementing the Bedrock system from scratch. For people who are learning about or writing program for the Bedrock system, the stream device manual will generally be more useful.

Concepts

Bytestream

A bytestream is a bi-directional communications link that connects this system to another sytem, called the connected system. Each bytestream contains two channels, called the input channel and the output channel. The input channel receives transmissions from the connected system, and the output channel sends transmissions to the connected system.

This device contains two bytestreams: the local bytestream is controlled by the first eight ports, and the remote bytestream is controlled by the last eight.

Channel

A channel is a uni-directional communications link that connects a transmitting system to a receiving system. Each channel contains a buffer queue and a transmission control flag.

Bytes are sent through a channel by the transmitting system, are buffered in the queue, and then are received and processed by the receiving system. Bytes can only be sent while the transmission control flag is set.

Buffer queue

A buffer queue is a first-in first-out byte queue that buffers the bytes sent through a channel. The maximum size of each queue is determined by the implementation. If a queue is full, all new bytes will be dropped.

Transmission control flag

A transmission control flag is a flag that controls whether bytes can be sent through a channel. The initial state of each transmission control flag is unset.

The receiving system on a channel can set the transmission control flag. The transmitting system can send bytes while the flag is set, and can clear the flag to end the transmission. A collection of bytes sent through a channel while the transmission control flag is set is called a transmission.

Local bytestream

The local bytestream connects to a local system. This connection is performed by the user.

Remote bytestream

The remote bytestream connects to a remote system via a network address. The remote bytestream can be connected to an address in server mode by writing to the remote input connection port, or in client mode by writing to the remote output connection port.

When the remote bytestream connects to an address in server mode, the stream device will bind to that address and listen for incoming connections from other systems. This system acts as a server, and the other systems will act as clients. Each incoming transmission represents a request from a remote system. A response can be sent to that remote system by making an outgoing transmission. The remote system will be disconnected after a response is sent, or after writing to the remote input transmission or input queue port.

When the remote bytestream connects to an address in client mode, the stream device will connect to the remote system at that address. Both systems can send and receive transmissions until either system disconnects.

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 is zero. The initial value of the pointer is zero.

Writing a non-zero byte to the remote path buffer will write that byte to the 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 remote connection, then will attempt to open a connection if the final byte of the buffer is zero, and then will set the pointer and every byte of the buffer to zero. Writing to the remote input connection port will connect in server mode, and writing to the remote output connection port will connect in client mode.

The buffer contents up to the first zero byte are interpreted as a UTF-8 encoded string representing the network address to connect to. The address format is determined by the implementation.

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 queue Bytes waiting in the local input queue.
0x85 Output queue Bytes free in the local output queue.
0x86 Head Read and write to the 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 queue Bytes waiting in the remote input queue.
0x8D Output queue Bytes free in the remote output queue.
0x8E Head Read and write to the remote bytestream.
0x8F aliased aliased

Input connection

Each input connection port is associated with the input channel of a bytestream.

Reading from one of these ports will return 0xFF if the associated input channel is connected to another system, or 0x00 otherwise. Writing a byte to the remote input connection port 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 one of these ports will return 0xFF if the associated output channel is connected to another system, or 0x00 otherwise. Writing a byte to the remote output connection port 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 one of these ports will return 0xFF if the transmission control flag of the associated input channel is set, or 0x00 otherwise. Writing any value to one of these ports will clear the buffer queue and then set the transmission control flag of the associated input channel.

Output transmission

Each output transmission port is associated with the output channel of a bytestream.

Reading from one of these ports will return 0xFF if the transmission control flag of the associated output channel is set, or 0x00 otherwise. Writing any value to one of these ports will clear the transmission control flag of the associated output channel.

Input queue

Each input queue port is associated with the input channel of a bytestream.

Reading from one of these ports will return the number of bytes waiting in the buffer queue of the associated input channel. Reading while the queue contains more than 255 bytes will return 0xFF.

Writing any value to one of these ports 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 is clear.

Output queue

Each output queue port is associated with the output channel of a bytestream.

Reading from one of these ports will return the number of bytes of free space in the buffer queue of the associated output channel. Reading while the queue has more than 255 bytes of free space will return 0xFF.

Each head port is associated with a bytestream.

Reading from one of these ports will remove and return a byte from the front of the input queue of the associated bytestream. Reading while the queue is empty will return zero.

Writing a byte to one of these ports will push that byte to the back of the output queue of the associated bytestream. The byte will be dropped if the output channel is disconnected, the output queue is full, or the transmission control flag of the output channel is not set.

Implementation

Standard streams

If this Bedrock system is running on an operating system that provides standard input and output streams, the local bytestream should be connected to those streams.

Encoded transmissions

There are a few different ways of encoding transmissions when communicating with systems that send data as unbroken streams. The user should select a format that will work best for the connected system.

If the connected system transmits and receives line-oriented text data, an incoming newline character 0x0A should mark the end of 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 best to send binary transmissions through a text stream as raw bytes, concatenating all transmissions into one continuous stream.

Flushing a buffer

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 by the system to increase throughput.

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: