puter/src/puter-wisp
KernelDeimos 4589ed95be dev: handle pty close
Return to phoenix shell when a pty stream is closed by twisp.

Pipes in phoenix with commands from the emulator do not appear to be
working properly, but something in there is working.
2024-09-18 16:21:07 -04:00
..
devlog/unit_test_usefulness dev: puter-wisp 2024-08-27 22:20:32 -04:00
src dev: handle pty close 2024-09-18 16:21:07 -04:00
test fix: simplify callback listener and fix async bug 2024-09-18 16:21:07 -04:00
basic.html dev: puter-wisp 2024-08-27 22:20:32 -04:00
package.json tweak: update license for puter-wisp 2024-08-27 22:40:27 -04:00
README.md dev: puter-wisp 2024-08-27 22:20:32 -04:00

Wisp Utilities

This is still a work in progress. Thes utilities use my own stream interface to avoid browser/node compatibility issues and because I found it more convenient. These streams can by used as async iterator objects just like other conventional implementations. Currently there is no logic for closing streams or knowing if a stream has been closed, but this is planned.

Classes and Factory Functions

WispPacket (class)

Wraps a Uint8Array containing a Wisp packet. data should be a Uint8Array containing only the Wisp frame, starting at the Packet Type and ending at the last byte of the payload (inclusive).

const packet = new WispPacket({
    data: new Uint8Array(...),
    direction: WispPacket.SEND, // or RECV

    // `extra` is optional, for debugging
    extra: { some: 'value', },
});

packet.type; // ex: WispPacket.CONTINUE

Methods

  • describe() - outputs a summary string
    packet.describe();
    // ex: "INFO v2.0 f000000000"
    
  • toVirtioFrame - prepends the size of the Wisp frame (u32LE)
  • log() - prints a collapsed console group
  • reflect() - returns a reflected version of the packet (flips SEND and RECV)

NewCallbackByteStream (function)

Returns a stream for values that get passed through a callback interface. The stream object (an async iterator object) has a property called listener which can be passed as a listener or called directly. This listener expects only one argument which is the data to pass through the stream (typically a value of type Uint8Array).

const byteStream = NewCallbackByteStream();
emulator.add_listener('virtio-console0-output-bytes',
    byteStream.listener);

NewVirtioFrameStream (function)

Takes in a byte stream (stream of Uint8Array) and assumes that this byte stream contains integers (u32LE) describing the length (in bytes) of data, followed by the data. Returns a stream which outputs a complete chunk of data (as per the specified length) as each value, excluding the bytes that describe the length.

const virtioStream = NewVirtioFrameStream(byteStream);

NewWispPacketStream (function)

Takes in a stream of Uint8Arrays, each containing a complete Wisp packet, and outputs a stream of instances of WispPacket

Example Use with v86

const emulator = new V86(...);

// Get a byte stream for /dev/hvc0
const byteStream = NewCallbackByteStream();
emulator.add_listener('virtio-console0-output-bytes',
    byteStream.listener);

// Get a stream of frames with prepended byte lengths
// (for example, `twisp` uses this format)
const virtioStream = NewVirtioFrameStream(byteStream);

// Get a stream of WispPacket objects
const wispStream = NewWispPacketStream(virtioStream);

// Async iterator
(async () => {
    for ( const packet of wispStream ) {
        console.log('Wisp packet!', packet.describe());
        
        // Let's send back a reflected packet for INFO!
        if ( packet.type === WispPacket.INFO ) {
            emulator.bus.send(
                'virtio-console0-input-bytes',
                packet.toVirtioFrame(),
            );
        }
    }
})();