playbit / docs

Networking

The Playbit networking APIs allow for communication between apps via Playbit's own data protocols and infrastructure. These APIs are currently available as a technical preview, and are not yet well suited for sensitive information as encryption is not yet implemented.


#include <playbit/net.h>

PBNet

typedef struct PBNet {
    PBSysHandle handle;
} PBNet;

PBNet is a general network capability

PBNetSession

typedef struct PBNetSession {
    PBSysHandle handle;
} PBNetSession;

PBNetSession is a Playbit network session

PBNetChannelOpenFlags

typedef u64 PBNetChannelOpenFlags;

PBNetChannelOpenFlags are flags for PBNetChannelOpenEx

PBNetChannelOpenFlag

enum PBNetChannelOpenFlag PB_ENUM_TYPE(u64){
    /*
    PBNetChannelOpenFlag_SUBSCRIBE causes the PBNetChannel to automatically send SUBSCRIBE messages whenever the underlying access point connection is established, or re-established. If this flag is not set, nothing will be delivered to the opened PBNetChannel, until you send a SUBSCRIBE message yourself. Not setting this flag can be useful if you are only writing to a channel.
    */
    PBNetChannelOpenFlag_SUBSCRIBE = 1u << 0,

    /*
    PBNetChannelOpenFlag_TRACK_SUBSCRIBERS enables reception of SUBSCRIBE and UNSUBSCRIBE messages as other peers join and leave the channel. It can be used for participation discovery. PBNetChannelOpenFlag_SUBSCRIBE must be set if PBNetChannelOpenFlag_TRACK_SUBSCRIBERS is set.

    Corresponds to setting PBApFrameFlag_TRACK in the AP protocol on outgoing SUBSCRIBE message.
    */
    PBNetChannelOpenFlag_TRACK_SUBSCRIBERS = 1u << 1,
};

PBNetChannelPublishFlags

typedef u64 PBNetChannelPublishFlags;

PBNetChannelPublishFlags are flags for PBNetChannelPublishCommit et al

PBNetChannelPublishFlag

enum PBNetChannelPublishFlag PB_ENUM_TYPE(u64){
    /*
    PBNetChannelPublishFlag_ECHO makes the message delivered back to the sender, in addition to being sent to everyone else in a channel. It corresponds to PBApFrameFlag_ECHO in the AP protocol.
    */
    PBNetChannelPublishFlag_ECHO = 1u << 0,

    /*
    PBNetChannelPublishFlag_DEFER disables sending of the message on publish. Useful if you are sending many small messages in rapid succession: set PBNetChannelPublishFlag_DEFER for the first N-1 publish calls and don't set this flag for the last.

    Note that a call to PBNetChannelProcessIO will cause queued messages to be sent regardless of this flag, granted the underlying stream is writable.
    */
    PBNetChannelPublishFlag_DEFER = 1u << 1,
};

PBNetChannelFrameType

typedef enum PBNetChannelFrameType PB_ENUM_TYPE(u8){
    PBNetChannelFrameType_DIRECT = PBApFrameType_DIRECT,
    PBNetChannelFrameType_PUBLISH = PBApFrameType_PUBLISH,
    PBNetChannelFrameType_SUBSCRIBE = PBApFrameType_SUBSCRIBE,
    PBNetChannelFrameType_UNSUBSCRIBE = PBApFrameType_UNSUBSCRIBE,
    PBNetChannelFrameType_ERROR = PBApFrameType_ERROR,
    PBNetChannelFrameType_ERROR_CHAN = PBApFrameType_ERROR_CHAN,
    PBNetChannelFrameType_ERROR_SUB = PBApFrameType_ERROR_SUB,
    PBNetChannelFrameType_ERROR_PEER = PBApFrameType_ERROR_PEER,
    PBNetChannelFrameType_ERROR_DIRECT = PBApFrameType_ERROR_DIRECT,
} PBNetChannelFrameType;

PBNetChannelFrameType identifies frames delivered on a NetSession channel stream.

PBNetChannelFrame

typedef struct PBNetChannelFrame {
    u32                   bodyLen;     // Size of body in bytes.
    PBNetChannelFrameType type;        // Frame type.
    u8                    flags;       // Type-specific AP frame flags.
    u8                    senderIdLen; // Number of bytes at senderId.
    u8                    _reserved;
    const u8*             body;       // Pointer to the frame body. Always 16-byte aligned.
    u8                    senderId[]; // Sender peer ID bytes. May be empty.
} PBNetChannelFrame;

PBNetChannelFrame is a frame of information received via a PBNetChannel

PBNetDefault

PBNet PBNetDefault();

PBNetDefault returns the default/initial network capability provided to the current thread when it was started.

Note: You can check .handle == PBSysHandle_INVALID on the return value to check if the current thread has a default network capability, or use PBExpectValidHandle to get a panic if not. All functions that take a PBNet as an argument will check its validity and panic if invalid, so for programs what want to simply crash if no networking is available, it's easier to just do no checking at all.

PBNetSessionOpen

PBSysErr PBNetSessionOpen(PBNet                        net,
                          PBNetSession*                netSession,
                          PBStrSlice                   sessionId,
                          const PBSysNetSessionConfig* config);

PBNetSessionOpen opens a logical Playbit network session.

A Playbit network session allows communication between multiple playbit programs participating in the same session. A session houses "channels" (see PBNetChannelOpen and PBNetChannel).

PBNetSessionClose

PBSysErr PBNetSessionClose(PBNetSession* netSession);

PBNetSessionClose closes a network session

PBNetChannelOpen

PBSysErr PBNetChannelOpen(PBNetChannel*       netChannelOut,
                          const PBNetSession* netSession,
                          PBStrSlice          channelId,
                          PBMem               ma);

PBNetChannelOpen opens a stream to channel identified by channelId, and queues a SUBSCRIBE message.

PBNetChannelOpen is equivalent to calling PBNetChannelOpenEx with PBNetChannelOpenFlag_SUBSCRIBE.

PBNetChannelOpenEx

PBSysErr PBNetChannelOpenEx(PBNetChannel*         netChannelOut,
                            const PBNetSession*   netSession,
                            PBStrSlice            channelId,
                            PBMem                 ma,
                            PBNetChannelOpenFlags flags);

PBNetChannelOpen opens a stream to channel identified by channelId.

PBNetChannelClose

void PBNetChannelClose(PBNetChannel* netChannel);

PBNetChannelClose closes the underlying stream, frees buffers owned by netChannel, and frees the channel object itself. The caller should discard any saved pointer after calling.

PBNetChannelHandle

PBSysHandle PBNetChannelHandle(const PBNetChannel* netChannel);

PBNetChannelHandle returns the underlying stream handle for a channel

PBNetChannelPublish

PBSysErr PBNetChannelPublish(PBNetChannel* netChannel,
                             const u8*     body,
                             u32           bodyLen);

PBNetChannelPublish queues one complete PUBLISH frame by copying body into an internal buffer.

Equivalent to calling PBNetChannelPublishBegin with 0 flags, copying body and then calling PBNetChannelPublishCommit with 0 flags.

PBNetChannelPublishEx

PBSysErr PBNetChannelPublishEx(PBNetChannel*            netChannel,
                               const u8*                body,
                               u32                      bodyLen,
                               PBNetChannelPublishFlags flags);

PBNetChannelPublishEx queues one complete PUBLISH frame with explicit AP frame flags.

Equivalent to calling PBNetChannelPublishBegin with flags, copying body and then calling PBNetChannelPublishCommit with flags.

PBNetChannelPublishBegin

PBSysErr PBNetChannelPublishBegin(PBNetChannel*            netChannel,
                                  u32                      bodyLen,
                                  u8*                      bodyOut,
                                  PBNetChannelPublishFlags flags);

PBNetChannelPublishBegin allocates one outgoing PUBLISH frame.

On success, reserves space in the send buffer, stores the body pointer in bodyOut, and expects a matching call to PBNetChannelPublishCommit.

PBNetChannelPublishCommit

PBSysErr PBNetChannelPublishCommit(PBNetChannel*            netChannel,
                                   u8*                      body,
                                   PBNetChannelPublishFlags flags);

PBNetChannelPublishCommit commits a draft PUBLISH frame previously started with PBNetChannelPublishBegin.

PBNetChannelProcessIO

PBSysErr PBNetChannelProcessIO(PBNetChannel*      netChannel,
                               PBSysSignals       signals,
                               PBNetChannelFrame* frameOut);

PBNetChannelProcessIO processes stream IO for a channel.

PBNetChannelReleaseFrame

void PBNetChannelReleaseFrame(PBNetChannel*      netChannel,
                              PBNetChannelFrame* frame);

PBNetChannelReleaseFrame releases a frame previously returned by PBNetChannelProcessIO. Frames must be released in the order they were received.

PBNetChannelRecvDiscardCount

u32 PBNetChannelRecvDiscardCount(const PBNetChannel* netChannel);

PBNetChannelRecvDiscardCount returns the number of received messages which were discarded because they exceeded size limit set by PBNetChannelSetRecvLimit

PBNetChannelSetRecvLimit

u32 PBNetChannelSetRecvLimit(PBNetChannel* netChannel,
                             u32           nbytes);

PBNetChannelSetRecvLimit limits the size of received messages (body, not including protocol header.)

PBNetChannelSetSendLimit

u32 PBNetChannelSetSendLimit(PBNetChannel* netChannel,
                             u32           nbytes);

PBNetChannelSetSendLimit limits the size of published messages (body, not including protocol header.)


#include <playbit/ap.h>

Playbit Access Point protocol

PBApFrameType

typedef enum PBApFrameType PB_ENUM_TYPE(u8){
    PBApFrameType_HELLO = 0,          // 'src' is peer ID on recv, body=auth_tok
    PBApFrameType_REGISTER = 1,       // 'flags' holds APRegisterResStatus
    PBApFrameType_DIRECT = 2,         // 'dst' is peer ID,    'flags' is unused
    PBApFrameType_PUBLISH = 3,        // 'dst' is channel ID, 'flags' may have ECHO
    PBApFrameType_SUBSCRIBE = 4,      // 'dst' is channel ID, 'flags' may have TRACK
    PBApFrameType_UNSUBSCRIBE = 5,    // 'dst' is channel ID, 'flags' is unused
    PBApFrameType_ERROR = 200,        // generic error (text description in data)
    PBApFrameType_ERROR_CHAN = 201,   // operation on non-existing channel
    PBApFrameType_ERROR_SUB = 202,    // already subscribed or not subscribed
    PBApFrameType_ERROR_PEER = 203,   // no route to peer
    PBApFrameType_ERROR_DIRECT = 204, // failed to deliver direct message
} PBApFrameType;

PBApFrameFlags

typedef u8 PBApFrameFlags;

PBApFrameFlag

enum PBApFrameFlag PB_ENUM_TYPE(u8){
    PBApFrameFlag_ECHO = 1u << 0,
    PBApFrameFlag_TRACK = 1u << 0,
};

PBApFrameHeaderSize

const int PBApFrameHeaderSize = 8;

PBApFrameBodyAlign

const int PBApFrameBodyAlign = 16;