Sml.Transport (SmlEx v0.1.0)

Copy Markdown View Source

SML transport protocol version 1 (framing of SML files).

A telegram on the wire looks like this:

1B 1B 1B 1B  01 01 01 01   start sequence
...                        SML messages, padded with 00 to a multiple of 4
1B 1B 1B 1B  1A PP CC CC   end sequence, PP = padding bytes, CCCC = CRC

Inside the payload a literal 1B 1B 1B 1B block is escaped by doubling it. The CRC (see Sml.CRC16) covers everything from the start sequence up to and including the padding count byte.

Use unwrap/2 to get the raw message bytes out of one telegram and extract/1 to split a byte stream (e.g. read from a serial IR head) into complete telegrams.

Summary

Functions

Splits a byte stream into complete telegrams.

Returns true if data contains an SML transport start sequence.

Extracts the payload (the SML messages) from the first telegram in data.

Types

unwrap_error()

@type unwrap_error() ::
  :no_start_sequence
  | :incomplete
  | :invalid_escape
  | :invalid_padding
  | :invalid_crc

Functions

extract(buffer)

@spec extract(binary()) :: {[binary()], binary()}

Splits a byte stream into complete telegrams.

Returns the complete telegrams found (still framed, ready for Sml.decode/2) and the remaining bytes, which should be prepended to the next chunk read from the stream. Garbage between telegrams and frames that are interrupted by a new start sequence are dropped.

{telegrams, buffer} = Sml.Transport.extract(buffer <> chunk)

framed?(data)

@spec framed?(binary()) :: boolean()

Returns true if data contains an SML transport start sequence.

unwrap(data, opts \\ [])

@spec unwrap(binary(), keyword()) :: {:ok, binary()} | {:error, unwrap_error()}

Extracts the payload (the SML messages) from the first telegram in data.

Bytes before the start sequence are ignored. Escaped sequences are unescaped and padding is removed.

Options

  • :crc - checksum algorithm to verify: :auto (default, X-25 or Kermit), :x25, :kermit, or false to skip the check