gateway

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jul 19, 2026 License: MIT Imports: 17 Imported by: 0

Documentation

Overview

Package gateway parses the wire formats spoken by NMEA 2000 network gateways: the Yacht Devices RAW ASCII line protocol and the Actisense binary stream protocol.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncodeSend

func EncodeSend(m N2KMessage) ([]byte, error)

EncodeSend renders an assembled N2K message as an Actisense transmit command (0x94). The payload layout is priority (1), PGN (3, little-endian), destination (1), data length (1), data. There is no source-address byte: the gateway transmits under its own claimed bus address, so m.Source is not carried on the wire. The gateway also performs fast-packet fragmentation itself, which is why sends are whole messages rather than CAN frames.

func EncodeStartup

func EncodeStartup() []byte

EncodeStartup renders the gateway initialization command (0xA1 with operating-mode payload 11 02 00) that clears the gateway's transmit filter list so all PGNs flow in both directions. Send it once after connecting; gateways that do not require it ignore it.

func FormatYDRawTX

func FormatYDRawTX(frame can.Frame) []byte

FormatYDRawTX renders a CAN frame as a Yacht Devices RAW transmit line. Application-to-gateway lines carry no time or direction field — just the 29-bit identifier and the data bytes, CRLF-terminated:

19F51323 01 02<CR><LF>

Once the gateway transmits the frame onto the bus it echoes the line back with a timestamp and direction T, which ParseYDRaw accepts like any other frame. Filtered or malformed lines get no echo.

func ParseYDRaw

func ParseYDRaw(line string) (can.Frame, bool)

ParseYDRaw parses one line of the Yacht Devices RAW protocol (YDWG-02 and compatible gateways), e.g.

17:33:21.107 R 09F11201 01 5C 3D FF 7F FF 7F FC

The direction field is R (received from the bus) or T (transmitted to the bus); both carry frames. Returns ok=false for service messages, blank lines, and anything else that does not carry a CAN data frame.

func ParseYDRawObservation added in v1.0.0

func ParseYDRawObservation(line string) (raw.Observation, bool)

ParseYDRawObservation preserves the gateway's relative timestamp and receive/transmit direction in addition to the CAN frame.

func ReadActisense added in v0.2.0

func ReadActisense(r io.Reader, handler func(can.Frame)) error

ReadActisense reassembles Actisense messages from r and emits them as re-framed CAN frames until EOF or a read error. It is the single reader for the Actisense protocol, shared by the TCP bus and the read-only network sources.

func ReadActisenseObservations added in v1.0.0

func ReadActisenseObservations(r io.Reader, handler func(raw.Observation)) error

ReadActisenseObservations preserves the gateway-relative timestamp on every CAN frame reconstructed from an assembled message.

func ReadYDRaw added in v0.2.0

func ReadYDRaw(r io.Reader, handler func(can.Frame)) error

ReadYDRaw delivers Yacht Devices RAW lines from r as CAN frames until EOF or a read error. It is the single reader for the RAW protocol, shared by the TCP bus and the read-only network sources.

func ReadYDRawObservations added in v1.0.0

func ReadYDRawObservations(r io.Reader, handler func(raw.Observation)) error

ReadYDRawObservations preserves direction and gateway-relative timestamps.

func Reframe

func Reframe(m N2KMessage, seq uint8) ([]can.Frame, error)

Reframe converts an assembled N2K message back into wire CAN frames: a single frame for non-fast PGNs up to 8 bytes, fast-packet frames for fast PGNs up to 223 bytes. PGNs absent from the metadata tables are framed by size (fast iff the payload exceeds 8 bytes). seq is the fast-packet sequence ID (0-7).

func ReframeEmitter

func ReframeEmitter(handler func(can.Frame)) func(N2KMessage)

ReframeEmitter adapts a CAN-frame handler into an assembled-message consumer: each message is re-framed into wire CAN frames (rotating the fast-packet sequence ID per message) and fed to the handler. Messages that cannot be re-framed are dropped.

Types

type ActisenseReader

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

ActisenseReader is an incremental decoder for the Actisense binary stream protocol. It tolerates arbitrary buffer boundaries: bytes are fed as they arrive and complete messages are emitted as they are recognized.

func NewActisenseReader

func NewActisenseReader() *ActisenseReader

NewActisenseReader returns a reader ready to consume stream bytes.

func (*ActisenseReader) Feed

func (r *ActisenseReader) Feed(buf []byte, emit func(N2KMessage))

Feed consumes raw stream bytes; emit is called once per complete, checksum-valid N2K message (command 0x93). Garbage between messages is skipped and messages that fail their checksum are dropped silently.

type ActisenseTCPBus

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

ActisenseTCPBus is a read/write bus over a TCP connection speaking the Actisense binary stream protocol (W2K-1 gateways, or an NGT-1 behind a TCP bridge). The protocol is message-level: incoming messages arrive assembled and are re-framed for the frame-based decode pipeline, and outgoing messages are sent whole via WriteMessage — the gateway performs fast-packet fragmentation and stamps its own claimed source address, so the client's source address is not authoritative on the wire.

func NewActisenseTCPBus

func NewActisenseTCPBus(log *slog.Logger, addr string, reconnect *ReconnectPolicy) *ActisenseTCPBus

NewActisenseTCPBus returns an unconnected bus; Run dials and sends the gateway initialization command. A non-nil reconnect policy makes Run re-dial dropped connections, re-sending the initialization command each time.

func (*ActisenseTCPBus) Close

func (b *ActisenseTCPBus) Close() error

Close releases the connection.

func (*ActisenseTCPBus) Run

func (b *ActisenseTCPBus) Run(ctx context.Context, handler func(can.Frame)) error

Run connects, initializes the gateway, and delivers incoming messages to handler as re-framed CAN frames until ctx is cancelled or (without a reconnect policy) the connection fails.

func (*ActisenseTCPBus) RunObservations added in v1.0.0

func (b *ActisenseTCPBus) RunObservations(ctx context.Context, handler func(raw.Observation)) error

RunObservations preserves gateway transport context.

func (*ActisenseTCPBus) SetConnectionObserver added in v1.0.0

func (b *ActisenseTCPBus) SetConnectionObserver(observer func(bool, uint64))

SetConnectionObserver installs reconnect lifecycle observation for Client.

func (*ActisenseTCPBus) WriteFrame

func (b *ActisenseTCPBus) WriteFrame(frame can.Frame) error

WriteFrame transmits one CAN frame as a whole message. This is correct for single-frame PGNs (address claims, ISO requests, transport-protocol frames); fast-packet payloads must go through WriteMessage instead, which the client's write path does automatically.

func (*ActisenseTCPBus) WriteMessage

func (b *ActisenseTCPBus) WriteMessage(pgnNum uint32, priority, _, destination uint8, payload []byte) error

WriteMessage transmits an assembled PGN payload (up to 223 bytes). The source address is accepted for interface symmetry but not transmitted: the gateway substitutes its own claimed address.

type Backoff added in v0.2.0

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

Backoff is a re-armable exponential backoff sequencer. It is not safe for concurrent use; a single reconnect loop owns one Backoff.

func NewBackoff added in v0.2.0

func NewBackoff(policy ReconnectPolicy) *Backoff

NewBackoff returns a Backoff seeded from policy, substituting defaults for any non-positive field.

func (*Backoff) Reset added in v0.2.0

func (b *Backoff) Reset()

Reset returns the sequencer to its initial delay, so the next Wait sleeps for InitialBackoff again. Call it after a connection is successfully established so a brief reconnect does not inherit a long prior backoff.

func (*Backoff) Wait added in v0.2.0

func (b *Backoff) Wait(ctx context.Context) bool

Wait sleeps for the next backoff interval, doubling it up to MaxBackoff on each successive call, and returns true. It returns false immediately if ctx is cancelled before the interval elapses.

type N2KMessage

type N2KMessage struct {
	Priority    uint8
	PGN         uint32
	Destination uint8
	Source      uint8
	Data        []byte
	// Timestamp is the gateway's relative millisecond clock.
	Timestamp    time.Duration
	HasTimestamp bool
}

N2KMessage is one NMEA 2000 message carried by an Actisense stream. Data is the assembled PGN payload (fast-packet PGNs arrive already assembled).

type ReconnectPolicy added in v0.2.0

type ReconnectPolicy struct {
	// InitialBackoff is the delay before the first reconnect attempt after a
	// drop, and the delay restored after any successful connection.
	InitialBackoff time.Duration
	// MaxBackoff caps the exponentially growing delay between attempts while a
	// connection cannot be re-established.
	MaxBackoff time.Duration
}

ReconnectPolicy configures automatic re-dialing of a dropped gateway connection. A nil *ReconnectPolicy means reconnection is disabled: a dropped connection ends the read loop (the historical behavior).

type YDRawTCPBus

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

YDRawTCPBus is a read/write bus over a TCP gateway speaking the Yacht Devices RAW line protocol (YDWG-02 RAW server mode and compatibles). RAW mode is frame-level in both directions, so the full client stack — address claiming included — works exactly as it does on CAN hardware. The gateway echoes transmitted frames back with direction T, so the client also observes its own traffic.

func NewYDRawTCPBus

func NewYDRawTCPBus(log *slog.Logger, addr string, reconnect *ReconnectPolicy) *YDRawTCPBus

NewYDRawTCPBus returns an unconnected bus; Run dials. A non-nil reconnect policy makes Run re-dial dropped connections.

func (*YDRawTCPBus) Close

func (b *YDRawTCPBus) Close() error

Close releases the connection.

func (*YDRawTCPBus) Run

func (b *YDRawTCPBus) Run(ctx context.Context, handler func(can.Frame)) error

Run connects and delivers incoming frames to handler until ctx is cancelled or (without a reconnect policy) the connection fails.

func (*YDRawTCPBus) RunObservations added in v1.0.0

func (b *YDRawTCPBus) RunObservations(ctx context.Context, handler func(raw.Observation)) error

RunObservations preserves gateway transport context.

func (*YDRawTCPBus) SetConnectionObserver added in v1.0.0

func (b *YDRawTCPBus) SetConnectionObserver(observer func(bool, uint64))

SetConnectionObserver installs reconnect lifecycle observation for Client.

func (*YDRawTCPBus) WriteFrame

func (b *YDRawTCPBus) WriteFrame(frame can.Frame) error

WriteFrame transmits one CAN frame as a RAW line.

Jump to

Keyboard shortcuts

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