m17

package module
v0.9.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

README

M17 library, gateway and clients, written in Go

M17 Packet Mode is defined in the spec, and messaging is one obvious application. This project started as a set of tools to jump-start messaging and data communications using the M17 ham radio mode. It has evolved to provide more general tool and library support for M17.

There are several tools and a library here:

Tools

M17 Messaging Bridge

m17-bridge is an experimental network service that bridges M17 SMS messages to and from other messaging protocols. It speaks the M17 Internet protocol, so it looks like a reflector to hotspots/repeaters that connect to it.

It bridges to these systems:

  • Discord: An M17 module letter is connected to a Discord channel. All M17 messages are send to the channel and all channel messages are sent to connected hotspots/repeaters. Since all received traffic is sent over the air, membertship in the Discord channels should be restricted to licensed hams.
  • IRC: An M17 module letter is connected to an IRC server and allows sending and receiving private messages via M17 SMS. Because received traffic is sent over the air, accounts on the server should probably be restricted to licensed hams.
  • APRS: An M17 module letter is connected to an APRS-IS server. Radios can use M17 SMS messaging to send APRS messages. When it sees M17 GNSS data, the bridge will also send periodiic APRS position reports. The bridge will send APRS messages to connected radios. A radio must send a message in order to register to receive APRS messages.
M17 Gateway

m17-gateway allows a computer and modem to act as a repeater/hotspot. It also connects RF clients to Internet services such as reflectors. It currently supports the CC1200 Pi HAT, the SX1255 Pi HAT and MMDVM-compatible hotspots and modems. When run on a Raspberry Pi with a compatible HAT or modem, it can forward M17 voice and packet traffic to and from a reflector, making it an M17 voice and packet hotspot. When used with the SX1255 HAT or an MMDVM modem it can form the heart of an M17 repeater.

Current M17 reflectors (mrefd 1.0.0 and later) forward each stream and packet to its real destination, so the gateway sends them with the destination unchanged. Legacy reflectors (urfd, and mrefd before 1.0.0) forward only streams addressed to their reflector and module, and support neither PARROT nor packet mode. Each time it links, the gateway sends the reflector a short test packet to PARROT; a reflector that doesn't send it back within a few seconds is treated as legacy. On a legacy reflector, a broadcast stream (to @ALL, ALL or #ALL) is addressed to the reflector and module instead, a stream to PARROT or a callsign is sent unchanged (the reflector will probably drop it, and the gateway logs that), and packets are not sent.

The easiest way to get a working hotspot, including m17-gateway and a web dashboard is using DK1MI's excellent installer script. Highly recommended!

Another way to install just the gateway is using the APT package from a release on Github. To install it:

  1. Copy the URL for the latest deb package from https://github.com/jancona/m17/releases
  2. From a shell on the Pi do:
wget <latest deb URL>
sudo dpkg -i m17-gateway_<version>_arm64.deb

To build it just run go build in the m17-gateway directory. Because Go natively supports cross-compilation, you can build a Raspberry Pi executable on any machine by running GOOS=linux GOARCH=arm64 go build, the using scp to copy the resulting executable to the Pi.

Usage of gateway:
  -config string
    	Configuration file (default "./gateway.ini")
  -h	Print arguments
  -in string
    	M17 symbol input (default stdin)
  -out string
    	M17 symbol output (default stdout)
Configuration

Bu default, the gateway looks for configuration in gateway.ini in the working directory. See m17-gateway/gateway.ini.sample for details.

GUI Messaging Client

m17-message is a cross-platform GUI network messaging client. It's based on Fybro, a messaging app built using Fyne, a framework for building multi-platform GUI apps in Go. To build the client just run go build in the m17-message directory. For more packaging options, see the Fyne docs.

CLI Messaging Client

m17-text-cli is a rudimentary network messaging client--think Droidstar but for text messages (and not nearly as nice looking). Note that since I started writing this a number of tools (including DroidStar) have added M17 messaging support.

To build the client just run go build in the m17-text-cli directory.

Example: ./m17-text-cli -server m17.openquad.net -callsign N1ADJ

The program will respond with a prompt > . To send a message, enter callsign: message. Incoming messages for you will appear starting with < . To quit, enter /quit.

Sample session:

$ ./m17-text-cli -server m17.openquad.net
> N1ADJ: Hi from my other window!
>
2025-02-06 14:45:45 N0CALL>@ALL: Hi back
> /quit

Command line arguments:

Usage of ./m17-text-cli:
  -callsign string
    	User's callsign (default "N0CALL")
  -h	Print arguments
  -module string
      Module to connect to (default "P")
  -port uint
    	Port the reflector listens on (default 17000)
  -server string
    	Reflector server
Reflector Traffic Monitor

m17-inet connects to an M17 reflector and monitors voice stream traffic, reporting per-stream packet rate and packet loss (detected by gaps in frame numbers).

To build it just run go build in the m17-inet directory.

Example: ./m17-inet -host m17.kansascitywide.com:17000 -module A

Sample output:

Connected to m17.kansascitywide.com:17000 module A, monitoring traffic...
Stream 0x1A2B started: W1ABC > @ALL
Stream 0x1A2B  W1ABC > @ALL  Duration: 12.3s  Frames (received/expected): 305/308  Rate: 24.8/s  Loss: 0.97%

Command line arguments:

Usage of ./m17-inet:
  -host string
    	Reflector address with port (e.g. 172.234.217.28:17000)
  -module string
    	Module to connect to (A-Z) (default "A")
  -callsign string
    	Callsign to identify to the reflector (default "N0CALL")
CC1200 Modem Emulator

This program emulates the CC1200 Modem firmware. It accepts samples from the gateway and echos them back. It was used for development of the gateway until I had a real CC1200 hat to test with.

Library

The library is split so that the protocol can be imported without pulling in device drivers:

Package What it holds Depends on
github.com/jancona/m17 The M17 protocol: callsign encoding, LSF, packets, stream datagrams, CRC, and channel coding (convolutional code, Golay, interleaving, randomization, frame decoder). standard library only
github.com/jancona/m17/inet The M17_inet reflector protocol: Client for linking to a reflector, Server for being one, and the hosts file reader. m17
github.com/jancona/m17/modem Modem drivers (CC1200, MMDVM, SX1255, and a dummy), GPIO and SPI access, and the DSP chain. m17, device libraries
github.com/jancona/m17/dashboard The JSON dashboard logger used by the gateway. m17
github.com/jancona/m17/server Bridge modules (APRS, Discord, IRC) for m17-bridge. m17, inet, their services

It's pretty rough right now, but I hope to improve it and make it more general and useful over time. See docs/core-split.md for the reasoning behind the layout.

Documentation

Index

Constants

View Source
const (
	SymbolsPerSyncword = 8   //symbols per syncword
	SymbolsPerPayload  = 184 //symbols per payload in a frame
	SymbolsPerFrame    = 192 //symbols per whole 40 ms frame, 40ms * 4800 = 192
	BytesPerFrame      = SymbolsPerFrame * BitsPerSymbol / 8
	BitsPerSymbol      = 2
	BitsPerPayload     = SymbolsPerPayload * BitsPerSymbol
	FrameTime          = 40 * time.Millisecond
	FramesPerSecond    = time.Second / FrameTime
)
View Source
const (
	PacketModeFinalBit = 5 // use 6 bits of final byte
	LSFFinalBit        = 7 // use entire final byte
)
View Source
const (
	ConvolutionK      = 5                         //constraint length K=5
	ConvolutionStates = (1 << (ConvolutionK - 1)) //number of states of the convolutional encoder
)
View Source
const (
	SoftTrue  = 0xFFFF
	SoftMaybe = SoftTrue / 2
	SoftFalse = 0
)
View Source
const (
	LSFSync    = uint16(0x55F7)
	StreamSync = uint16(0xFF5D)
	PacketSync = uint16(0x75FF)
	BERTSync   = uint16(0xDF55)
	EOTMarker  = uint16(0x555D)
)
View Source
const (
	EncodedCallsignLen    = 6
	MaxCallsignLen        = 9
	DestinationAll        = "@ALL"
	EncodedDestinationAll = 0xFFFFFFFFFFFF
	MaxEncodedCallsign    = 0xEE6B27FFFFFF
	SpecialEncodedRange   = 268697600000000 //40^9+40^8
)
View Source
const (
	// SoftZero represents a confident 0 bit
	SoftZero = 0x0000
	// SoftOne represents a confident 1 bit
	SoftOne = 0xFFFF
	// SoftErasure represents an uncertain/erased bit
	SoftErasure = 0x7FFF
	// SoftThreshold is the decision boundary
	SoftThreshold = 0x7FFF
)

Constants for soft-decision logic

View Source
const (
	LSFLen = 30
	LSDLen = 28
)
View Source
const (
	MagicLen = 4

	MagicACKN      = "ACKN"
	MagicCONN      = "CONN"
	MagicDISC      = "DISC"
	MagicLSTN      = "LSTN"
	MagicNACK      = "NACK"
	MagicPING      = "PING"
	MagicPONG      = "PONG"
	MagicM17Stream = "M17 "
	MagicM17Packet = "M17P"
)

M17_inet datagram magics. They are part of the wire format of StreamDatagram, so they live with the protocol.

View Source
const CRCLen = 2
View Source
const ErrorDetectionFailed = 0xFFFFFFFF

ErrorDetectionFailed indicates the decoder could not correct the errors

Variables

View Source
var (
	// TX symbols
	SymbolMap = []Symbol{+1, +3, -1, -3}

	// symbol list (RX)
	SymbolList = []Symbol{-3, -1, +1, +3}

	// End of Transmission symbol pattern
	EOTSymbols = []Symbol{+3, +3, +3, +3, +3, +3, -3, +3}
)
View Source
var (
	LSFPreambleSymbols = []float64{+3, -3, +3, -3, +3, -3, +3, -3}

	LSFSyncSymbols    = []float64{+3, +3, +3, +3, -3, -3, +3, -3} // 0x55F7
	ExtLSFSyncSymbols = append(LSFPreambleSymbols, LSFSyncSymbols...)
	StreamSyncSymbols = []float64{-3, -3, -3, -3, +3, +3, -3, +3} // 0xFF5D
	PacketSyncSymbols = []float64{+3, -3, +3, +3, -3, -3, -3, -3} // 0x75FF
	BERTSyncSymbols   = []float64{-3, +3, -3, -3, +3, +3, +3, +3} // 0xDF55
	EOTMarkerSymbols  = []float64{+3, +3, +3, +3, +3, +3, -3, +3} // 0x555D
)
View Source
var (
	LSFSyncBytes    = []byte{0x55, 0xF7}
	StreamSyncBytes = []byte{0xFF, 0x5D}
	PacketSyncBytes = []byte{0x75, 0xFF}
	BERTSyncBytes   = []byte{0xDF, 0x55}
	EOTMarkerBytes  = []byte{0x55, 0x5D}
)
View Source
var CallsignRegex = regexp.MustCompile(`([a-zA-Z0-9]{1,3}/)?[a-zA-Z0-9]{1,3}[0-9][a-zA-Z0-9]{0,3}[a-zA-Z](/[a-zA-Z0-9]{1,3})?`)
View Source
var EncodedDestinationAllBytes = EncodedCallsign{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
View Source
var PacketPuncturePattern = PuncturePattern{true, true, true, true, true, true, true, false}
View Source
var StreamPuncturePattern = PuncturePattern{true, true, true, true, true, true, true, true, true, true, true, false}

Functions

func CRC

func CRC(in []byte) uint16

CRC calculates the M17 CRC of in.

func CalculateHammingDistance

func CalculateHammingDistance(a, b uint32) int

CalculateHammingDistance calculates the Hamming distance between two codewords

func CalculateSyndrome

func CalculateSyndrome(codeword uint32) uint16

CalculateSyndrome calculates the syndrome for error detection

func DecodeCallsign

func DecodeCallsign(encoded []byte) (string, error)

func DecodeLICH

func DecodeLICH(inp []SoftBit) []byte

DecodeLICH decodes LICH into a 6-byte array inp: pointer to an array of 96 soft bits

func Encode24

func Encode24(data uint16) uint32

Encode24 encodes a 12-bit value with Golay(24, 12) data: 12-bit input value (right justified) returns: 24-bit Golay codeword

func EncodeLICH

func EncodeLICH(inp []uint8) []byte

EncodeLICH encodes 6 bytes into 12 bytes using Golay encoding

func EuclNorm

func EuclNorm(s1, s2 []Symbol, n int) float64

func GetErrorCorrectionCapability

func GetErrorCorrectionCapability() int

GetErrorCorrectionCapability returns the maximum number of errors that can be corrected

func GetMinimumDistance

func GetMinimumDistance() int

GetMinimumDistance returns the minimum Hamming distance of the code

func HardDecode24

func HardDecode24(codeword uint32) (uint16, error)

HardDecode24 performs hard-decision decoding of a Golay(24,12) codeword This is a simpler version that works with hard bits (0 or 1)

func IntToSoft

func IntToSoft(out []SoftBit, value uint16, size uint8)

IntToSoft converts an integer to soft-valued bit array

func IsBroadcast added in v0.8.0

func IsBroadcast(dst EncodedCallsign) bool

IsBroadcast reports whether dst is a broadcast: the broadcast address (@ALL), or the callsigns ALL or #ALL.

func IsParrot added in v0.8.0

func IsParrot(dst EncodedCallsign) bool

IsParrot reports whether dst is PARROT. Like mrefd, any callsign containing PARROT counts.

func IsValidCodeword

func IsValidCodeword(codeword uint32) bool

IsValidCodeword checks if a 24-bit word is a valid Golay codeword

func NormalizeCallsignModule

func NormalizeCallsignModule(callsign string) string

For regular callsigns, if the callsign ends with a space followed by a module letter, put the module letter in position 9 (the convention) with spaces preceding it

func SoftCalcChecksum

func SoftCalcChecksum(out, value []SoftBit)

SoftCalcChecksum calculates checksum for soft-valued data This follows the C implementation exactly

func SoftDecode24

func SoftDecode24(codeword [24]SoftBit) uint16

SoftDecode24 performs soft decode of Golay(24, 12) codeword

func SoftDetectErrors

func SoftDetectErrors(codeword []SoftBit) uint32

SoftDetectErrors detects errors in a soft-valued Golay(24, 12) codeword

func SoftPopCount

func SoftPopCount(in []uint16, size uint8) uint32

SoftPopCount performs soft-valued equivalent of popcount

func SoftToInt

func SoftToInt(in []SoftBit, size uint8) uint16

SoftToInt converts soft-valued bit array to integer

func SoftXOR

func SoftXOR(out, a, b []SoftBit, size uint8)

SoftXOR performs XOR operation on arrays of soft-valued bits

func SyncDistance added in v0.6.0

func SyncDistance(symbols []Symbol, offset int, sps int) (float32, uint16)

Calculate distance between recent samples and sync patterns. sps is the number of samples per symbol (5 for CC1200, 1 for SX1255).

Types

type Bit

type Bit bool

func ConvolutionalEncode

func ConvolutionalEncode(in []byte, puncturePattern PuncturePattern, finalBit byte) ([]Bit, error)

ConvolutionalEncode takes a slice of bytes and a puncture pattern and returns an a slice of bool with each element representing one bit in the encoded message

in Input bytes puncturePattern the puncture pattern to use finalBit The last bit of the final byte to encode. A number between 0 and 7. (That is, the number of bits from the last byte to use minus one.)

func ConvolutionalEncodeStream

func ConvolutionalEncodeStream(lichBits []Bit, sd StreamDatagram) ([]Bit, error)

func (*Bit) Byte

func (b *Bit) Byte() byte

func (*Bit) Set

func (b *Bit) Set(by byte)

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

func NewDecoder

func NewDecoder(
	receivedRFLSF func(lsf LSF, ber float64) error,
	receivedRFStream func(lsf LSF, payload []byte, sid, fn uint16, ber float64) error,
	receivedRFStreamLICH func(lsf LSF, ber float64) error,
	receivedRFStreamEOT func(lsf LSF, sid, fn uint16, ber float64) error,
	receivedRFPacket func(lsf LSF, payload []byte, ber float64) error,
) *Decoder

func (*Decoder) DecodeFrame added in v0.2.0

func (d *Decoder) DecodeFrame(typ uint16, softBits []SoftBit)

type ECD added in v0.1.21

type ECD struct {
	Callsign1 *EncodedCallsign
	Callsign2 *EncodedCallsign
}

func NewECDFromMeta added in v0.1.21

func NewECDFromMeta(meta [14]byte) ECD

func (ECD) String added in v0.1.21

func (e ECD) String() string

type EncodedCallsign

type EncodedCallsign [EncodedCallsignLen]byte

func EncodeCallsign

func EncodeCallsign(callsign string) (*EncodedCallsign, error)

func (EncodedCallsign) Callsign

func (e EncodedCallsign) Callsign() string

type GNSS added in v0.1.21

type GNSS struct {
	DataSource        byte
	StationType       byte
	Radius            byte
	Bearing           uint16
	Latitude          float32
	Longitude         float32
	Altitude          float32
	Speed             float32
	ValidLatLon       bool
	ValidAltitude     bool
	ValidBearingSpeed bool
	ValidRadius       bool
}

func NewGNSSFromMeta added in v0.1.21

func NewGNSSFromMeta(meta [14]byte) *GNSS

func (GNSS) String added in v0.1.21

func (g GNSS) String() string

type LSF

type LSF struct {
	Dst  EncodedCallsign
	Src  EncodedCallsign
	Type [typeLen]byte
	Meta [metaLen]byte
	CRC  [CRCLen]byte
}

Link Setup Frame

func NewEmptyLSF

func NewEmptyLSF() LSF

func NewLSF

func NewLSF(destCall, sourceCall string, t LSFType, dt LSFDataType, can byte) (LSF, error)

func NewLSFFromBytes

func NewLSFFromBytes(buf []byte) *LSF

func NewLSFFromLSD

func NewLSFFromLSD(lsd []byte) *LSF

func (*LSF) CAN

func (l *LSF) CAN() byte

CAN returns the Channel Access Number: Type[0] bits 2–0, then Type[1] bit 7 (spec 2.0; the 3.0 draft moves it to the low nibble of Type[1]).

func (*LSF) CalcCRC

func (l *LSF) CalcCRC() uint16

Calculate CRC for this LSF

func (*LSF) CheckCRC

func (l *LSF) CheckCRC() bool

Check if the CRC is correct

func (*LSF) DataType added in v0.1.21

func (l *LSF) DataType() LSFDataType

func (*LSF) ECD added in v0.1.21

func (l *LSF) ECD() *ECD

func (*LSF) EncryptionSubtype added in v0.1.21

func (l *LSF) EncryptionSubtype() byte

func (*LSF) EncryptionType added in v0.1.21

func (l *LSF) EncryptionType() LSFEncryptionType

func (*LSF) GNSS added in v0.1.21

func (l *LSF) GNSS() *GNSS

func (*LSF) LSFType

func (l *LSF) LSFType() LSFType

func (*LSF) SetCAN added in v0.9.0

func (l *LSF) SetCAN(can byte)

SetCAN puts the low four bits of can where CAN reads them, keeping the other TYPE bits, and updates the CRC.

func (*LSF) SetECD added in v0.2.11

func (l *LSF) SetECD(slot1, slot2 *EncodedCallsign)

Replace META with Extended Callsign Data

func (LSF) String

func (l LSF) String() string

func (*LSF) ToBytes

func (l *LSF) ToBytes() []byte

Convert this LSF to a byte slice suitable for transmission

func (*LSF) ToLSDBytes

func (l *LSF) ToLSDBytes() []byte

Convert this LSF to a byte slice suitable for transmission

type LSFDataType

type LSFDataType byte
const (
	LSFDataTypeReserved LSFDataType = iota
	LSFDataTypeData
	LSFDataTypeVoice
	LSFDataTypeVoiceData
)

func (LSFDataType) String added in v0.1.21

func (t LSFDataType) String() string

type LSFEncryptionType

type LSFEncryptionType byte
const (
	LSFEncryptionTypeNone LSFEncryptionType = iota
	LSFEncryptionTypeScrambler
	LSFEncryptionTypeAES
	LSFEncryptionTypeOther
)

func (LSFEncryptionType) String added in v0.1.21

func (t LSFEncryptionType) String() string

type LSFType

type LSFType byte
const (
	LSFTypePacket LSFType = iota
	LSFTypeStream
)

func (LSFType) String added in v0.1.21

func (t LSFType) String() string

type Packet

type Packet struct {
	LSF     *LSF
	Type    PacketType
	Payload []byte
	CRC     uint16
}

M17 packet

func NewPacket

func NewPacket(dst, src string, t PacketType, data []byte) (*Packet, error)

func NewPacketFromBytes

func NewPacketFromBytes(buf []byte) (Packet, error)

NewPacketFromBytes parses an LSF followed by a packet type, payload and CRC. The input comes from RF or the network, so its length is checked before slicing: a short buffer would otherwise panic and take the process down.

func ParrotReply added in v0.8.0

func ParrotReply(pkt Packet) Packet

ParrotReply returns a reflector's reply to a packet sent to PARROT: the same packet readdressed to broadcast, as mrefd sends it. pkt is not changed.

func (*Packet) CalcCRC added in v0.2.20

func (p *Packet) CalcCRC() uint16

Calculate CRC

func (*Packet) CheckCRC

func (p *Packet) CheckCRC() bool

Check if the CRC is correct

func (*Packet) Encode

func (p *Packet) Encode() ([]Symbol, error)

func (*Packet) PayloadBytes

func (p *Packet) PayloadBytes() []byte

Convert the payload (type, message and CRC) to a byte slice suitable for transmission

func (Packet) SMSText added in v0.7.1

func (p Packet) SMSText() string

SMSText returns the text of an SMS packet without its NUL terminator.

func (Packet) String

func (p Packet) String() string

func (*Packet) ToBytes

func (p *Packet) ToBytes() []byte

Convert this Packet to a byte slice suitable for transmission

type PacketType

type PacketType rune
const (
	PacketTypeRAW     PacketType = 0x00
	PacketTypeAX25    PacketType = 0x01
	PacketTypeAPRS    PacketType = 0x02
	PacketType6LoWPAN PacketType = 0x03
	PacketTypeIPv4    PacketType = 0x04
	PacketTypeSMS     PacketType = 0x05
	PacketTypeWinlink PacketType = 0x06
)

type PayloadBits added in v0.2.0

type PayloadBits [BitsPerPayload]Bit

func InterleaveBits

func InterleaveBits(in *PayloadBits) *PayloadBits

Interleave payload bits.

func NewPayloadBits added in v0.2.0

func NewPayloadBits(bs []Bit) *PayloadBits

func RandomizeBits

func RandomizeBits(bits *PayloadBits) *PayloadBits

type Preamble

type Preamble byte

Preamble type (0 for LSF, 1 for BERT).

const (
	LSFPreamble Preamble = iota
)

type Probe added in v0.8.0

type Probe struct {
	// contains filtered or unexported fields
}

A Probe is a raw packet to PARROT carrying a random tag.

func NewProbe added in v0.8.0

func NewProbe() Probe

NewProbe returns a probe with a new random tag.

func (Probe) IsReply added in v0.8.0

func (p Probe) IsReply(pkt Packet) bool

IsReply reports whether pkt is the reply to the probe. Only the payload is compared: the reflector readdresses the reply to broadcast.

func (Probe) Packet added in v0.8.0

func (p Probe) Packet(src EncodedCallsign) Packet

Packet returns the probe as a packet from src, with valid LSF and payload CRCs (mrefd answers a packet with a bad CRC with an SMS saying so, not an echo).

type PuncturePattern

type PuncturePattern []Bit

type SoftBit

type SoftBit uint16

func CalcSoftbits added in v0.6.0

func CalcSoftbits(pld []Symbol) []SoftBit

func DeinterleaveSoftBits

func DeinterleaveSoftBits(softBits []SoftBit) []SoftBit

func DerandomizeSoftBits

func DerandomizeSoftBits(softBits []SoftBit) []SoftBit

func SoftBitXOR

func SoftBitXOR(a, b SoftBit) SoftBit

SoftBitXOR performs XOR operation on soft-valued bits This should match the C test expectations exactly

func (SoftBit) String added in v0.2.0

func (b SoftBit) String() string

type StreamDatagram

type StreamDatagram struct {
	StreamID    uint16
	FrameNumber uint16
	LastFrame   bool
	LSF         *LSF
	Payload     [16]byte
}

func NewStreamDatagram

func NewStreamDatagram(streamID uint16, frameNumber uint16, lsf *LSF, payload []byte) StreamDatagram

func NewStreamDatagramFromBytes added in v0.1.23

func NewStreamDatagramFromBytes(buffer []byte) (StreamDatagram, error)

func (StreamDatagram) String added in v0.1.23

func (sd StreamDatagram) String() string

func (StreamDatagram) ToBytes added in v0.1.23

func (sd StreamDatagram) ToBytes() []byte

type Symbol

type Symbol float32

func AppendBits

func AppendBits(out []Symbol, data *PayloadBits) []Symbol

func AppendEOT

func AppendEOT(out []Symbol) []Symbol

Generate symbol stream for the End of Transmission marker.

func AppendPreamble

func AppendPreamble(out []Symbol, typ Preamble) []Symbol

AppendPreamble generates symbol stream for a preamble.

func AppendSyncwordSymbols added in v0.2.0

func AppendSyncwordSymbols(out []Symbol, syncword uint16) []Symbol

AppendSyncwordSymbols generates the symbol stream for a syncword.

type ViterbiDecoder

type ViterbiDecoder struct {
	// contains filtered or unexported fields
}

func (*ViterbiDecoder) DecodePunctured

func (v *ViterbiDecoder) DecodePunctured(puncturedSoftBits []SoftBit, puncturePattern PuncturePattern) ([]byte, int)

DecodePunctured depunctures and decodes soft bits. It returns the decoded bytes and the path cost in bits: how far the received soft bits sat from the decoded path, summed over the bits actually received. A punctured bit is filled with SoftMaybe, which adds half a bit to every path whatever was sent, so that is subtracted here, as libm17 does.

func (*ViterbiDecoder) Init

func (v *ViterbiDecoder) Init(l int)

Directories

Path Synopsis
cmd
m17-bridge command
m17-gateway command
m17-inet command
m17-message command
m17-text-cli command
modem-emulator command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL