asoma.dev · the C reference for libose
libose
the C library every o.se host is built on
Loading...
Searching...
No Matches
ose_slip.h File Reference

SLIP framing, for carrying OSC over a byte stream. More...

#include "ose.h"
Include dependency graph for ose_slip.h:

Go to the source code of this file.

Data Structures

struct  ose_SLIPBuf
 Decoder state. Make one with ose_initSLIPBuf(). More...

Macros

#define OSE_SLIP_END   0300
#define OSE_SLIP_ESC   0333
#define OSE_SLIP_ESC_END   0334
#define OSE_SLIP_ESC_ESC   0335

Functions

struct ose_SLIPBuf ose_initSLIPBuf (uint8_t *buf, int32_t buflen)
 Make a decoder over buf. Zeroes the buffer and every field; text mode starts off.
int ose_SLIPDecode (uint8_t c, struct ose_SLIPBuf *s)
 Feed one byte.
int32_t ose_SLIPEncode (const uint8_t *const src, int32_t srclen, uint8_t *dest, int32_t destlen)
 Encode srclen bytes of src into dest, terminated by END.

Detailed Description

SLIP framing, for carrying OSC over a byte stream.

A serial line hands you one byte at a time and never tells you where a message ends. SLIP (RFC 1055) is the usual answer: a frame ends with END (0xC0), and any END or ESC inside the payload is escaped so it cannot be mistaken for the delimiter. That is the whole protocol.

This lived in ose_util.c, which is where it landed rather than where it belongs – it touches no bundle and operates on plain bytes. It was written for OSC over USB serial to and from microcontrollers, and some of those serial conventions leaked into what should be pure framing. They are still here, because they are useful, but they are OPTIONAL and OFF by default. See ose_SLIPBuf::textmode.

Decoding

uint8_t buf[1024];
struct ose_SLIPBuf s = ose_initSLIPBuf(buf, sizeof(buf));
while(read_one_byte(&c))
{
switch(ose_SLIPDecode(c, &s))
{
case 0: handle(buf, s.count); break; // a complete frame
case -1: report_a_bad_frame(); break; // malformed; discarded
default: break; // still reading
}
}
int ose_SLIPDecode(uint8_t c, struct ose_SLIPBuf *s)
Feed one byte.
Definition ose_slip.c:71
struct ose_SLIPBuf ose_initSLIPBuf(uint8_t *buf, int32_t buflen)
Make a decoder over buf. Zeroes the buffer and every field; text mode starts off.
Definition ose_slip.c:53
Decoder state. Make one with ose_initSLIPBuf().
Definition ose_slip.h:81
int32_t count
Definition ose_slip.h:84
uint8_t * buf
Definition ose_slip.h:82

The buffer resets itself. count stays valid after a frame completes so the caller can read the length, and is cleared when the NEXT frame begins. Earlier this was the caller's job and nothing said so, which meant a second frame silently appended to the first.

Function Documentation

◆ ose_SLIPDecode()

int ose_SLIPDecode ( uint8_t c,
struct ose_SLIPBuf * s )

Feed one byte.

Returns
0 for a complete frame – read s->count for its length – -1 for a frame that was malformed and has been discarded, and 1 while still reading. A frame whose length is not a multiple of four is refused: OSC elements are always four-byte aligned, so that is a truncated frame rather than a short one.

◆ ose_SLIPEncode()

int32_t ose_SLIPEncode ( const uint8_t *const src,
int32_t srclen,
uint8_t * dest,
int32_t destlen )

Encode srclen bytes of src into dest, terminated by END.

Returns
The encoded length, or -1 if dest is NULL, src is NULL, or there is not room. Escaping can double the payload, so a safe destlen is 2 * srclen + 1.