actisense

package
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 20, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package actisense implements the bounded BDTP, BST, BEM, and EBL wire protocols used by Actisense-format gateways. Transport adapters live in internal/gateway; this package owns protocol framing and session state.

Index

Constants

View Source
const (
	DLE = 0x10
	STX = 0x02
	ETX = 0x03

	// MaxDatagramLength bounds an unframed BST datagram excluding its checksum.
	// It covers a 1785-byte NMEA 2000 transport payload plus the 13-byte BST-D0
	// header, while remaining within the EBL tag capacity used by field captures.
	MaxDatagramLength = 1800
)
View Source
const (
	BEMOperatingMode    = 0x11
	BEMTxPGNEnable      = 0x47
	BEMActivatePGNLists = 0x4B
	BEMStartupStatus    = 0xF0
	BEMErrorReport      = 0xF1
	BEMSystemStatus     = 0xF2
	BEMNegativeAck      = 0xF4
)
View Source
const (
	BSTN2KReceive  = 0x93
	BSTN2KTransmit = 0x94
	BSTCANFrame    = 0x95
	BSTBEMResponse = 0xA0
	BSTBEMCommand  = 0xA1
	BSTN2KMessage  = 0xD0

	MaxNMEA2000Payload = 1785
)

Variables

View Source
var (
	ErrSessionClosed   = errors.New("actisense: session closed")
	ErrRequestInFlight = errors.New("actisense: request already in flight")
)

Functions

func EncodeBEMRequest

func EncodeBEMRequest(command byte, data []byte) ([]byte, error)

EncodeBEMRequest renders a local BEM command using BST-A1.

func EncodeCANFrame

func EncodeCANFrame(frame can.Frame, direction Direction, timestamp time.Duration, resolution uint8) ([]byte, error)

EncodeCANFrame renders a source-authoritative raw CAN frame as BST-95.

func EncodeDatagram

func EncodeDatagram(id byte, payload []byte) ([]byte, error)

EncodeDatagram wraps a BST ID and payload in BDTP framing with the applicable Type 1 or Type 2 length field and zero-sum checksum.

func EncodeMessage94

func EncodeMessage94(message Message) ([]byte, error)

EncodeMessage94 renders one legacy gateway-owned assembled message.

func EncodeMessageD0

func EncodeMessageD0(message Message) ([]byte, error)

EncodeMessageD0 renders an assembled NMEA 2000 message using BST Type 2.

func IsType2

func IsType2(id byte) bool

IsType2 reports whether id uses the BST Type 2 16-bit total-length field.

func OperatingModeRequest

func OperatingModeRequest() []byte

func OperatingModeSet

func OperatingModeSet(mode OperatingMode) []byte

func TxPGNEnableGet

func TxPGNEnableGet(pgn uint32) []byte

func TxPGNEnableSet

func TxPGNEnableSet(pgn uint32, enabled bool) []byte

Types

type BEMResponse

type BEMResponse struct {
	BSTID        byte
	BEMID        byte
	Sequence     uint8
	ModelID      uint16
	SerialNumber uint32
	ErrorCode    int32
	Data         []byte
}

BEMResponse is the common local gateway response envelope. Data is owned.

func DecodeBEMResponse

func DecodeBEMResponse(d Datagram) (response BEMResponse, ok bool, err error)

DecodeBEMResponse decodes the 12-byte response header carried by local BEM response BST IDs. ok is false when d is not a BEM response datagram.

type CANFrame

type CANFrame struct {
	Frame        can.Frame
	Timestamp    time.Duration
	HasTimestamp bool
	Direction    Direction
	Resolution   uint8
}

CANFrame is one raw CAN Frame plus BST-95 transport metadata.

func DecodeCANFrame

func DecodeCANFrame(d Datagram) (decoded CANFrame, ok bool, err error)

DecodeCANFrame decodes BST-95. ok is false for other BST IDs.

type CANStatus

type CANStatus struct {
	ReceiveErrors  uint8
	TransmitErrors uint8
	Flags          uint8
}

type Datagram

type Datagram struct {
	ID      byte
	Payload []byte
	Raw     []byte
}

Datagram is an owned, checksum-validated BST record. Raw contains the BST ID, length field, and payload without BDTP markers or the checksum byte.

func DecodeRaw

func DecodeRaw(raw []byte) (Datagram, error)

DecodeRaw decodes one unframed BST datagram without a checksum. This is the representation stored in EBL BSTRawFrame records.

func (Datagram) Clone

func (d Datagram) Clone() Datagram

type DecodeError

type DecodeError struct {
	Kind DecodeErrorKind
	ID   byte
	Err  error
}

DecodeError describes one discarded datagram. A Parser remains usable after reporting it and continues hunting for the next DLE/STX marker.

func (DecodeError) Error

func (e DecodeError) Error() string

func (DecodeError) Unwrap

func (e DecodeError) Unwrap() error

type DecodeErrorKind

type DecodeErrorKind string

DecodeErrorKind identifies a recoverable BDTP/BST stream defect.

const (
	DecodeFraming  DecodeErrorKind = "framing"
	DecodeChecksum DecodeErrorKind = "checksum"
	DecodeLength   DecodeErrorKind = "length"
	DecodeOversize DecodeErrorKind = "oversize"
)

type DeviceError

type DeviceError struct {
	Command byte
	Code    int32
}

DeviceError reports a command that reached the gateway but was rejected.

func (*DeviceError) Error

func (e *DeviceError) Error() string

type Diagnostic

type Diagnostic struct {
	Kind        DiagnosticKind
	Response    BEMResponse
	Startup     *StartupStatus
	ErrorReport *ErrorReport
	System      *SystemStatus
	NegativeAck *NegativeAck
}

Diagnostic retains the common response origin alongside one typed payload.

func DecodeDiagnostic

func DecodeDiagnostic(response BEMResponse) (diagnostic Diagnostic, ok bool, err error)

DecodeDiagnostic decodes F0/F1/F2/F4. ok is false for ordinary solicited responses.

type DiagnosticKind

type DiagnosticKind string

DiagnosticKind identifies an unsolicited local BEM event.

const (
	DiagnosticStartup     DiagnosticKind = "startup_status"
	DiagnosticError       DiagnosticKind = "error_report"
	DiagnosticSystem      DiagnosticKind = "system_status"
	DiagnosticNegativeAck DiagnosticKind = "negative_ack"
)

type Direction

type Direction uint8

Direction is the direction encoded by BST-95 and BST-D0.

const (
	DirectionReceived Direction = iota
	DirectionTransmitted
)

type ErrorReport

type ErrorReport struct {
	Variant     uint32
	ErrorCode   uint32
	Timestamp   *uint32
	ContextData []byte
}

type IndividualBufferStatus

type IndividualBufferStatus struct {
	ReceiveBandwidth  uint8
	ReceiveLoading    uint8
	ReceiveFiltered   uint8
	ReceiveDropped    uint8
	TransmitBandwidth uint8
	TransmitLoading   uint8
}

type Message

type Message struct {
	Priority       uint8
	PGN            uint32
	Destination    uint8
	Source         uint8
	HasSource      bool
	Data           []byte
	Timestamp      time.Duration
	HasTimestamp   bool
	Direction      Direction
	Type           MessageType
	InternalSource bool
	FastSequence   uint8
}

Message is one assembled NMEA 2000 payload carried in BST-93, BST-94, or BST-D0. Data is always owned.

func DecodeMessage

func DecodeMessage(d Datagram) (message Message, ok bool, err error)

DecodeMessage decodes an NMEA 2000 BST datagram. ok is false when the BST ID carries another protocol record.

type MessageType

type MessageType uint8

MessageType identifies the NMEA 2000 transfer form reported by BST-D0.

const (
	MessageSingle MessageType = iota
	MessageFast
	MessageTransport
	MessageUnknown
)

type NegativeAck

type NegativeAck struct {
	UniqueCommandID uint32
	ErrorCode       int32
}

type NegativeAckError

type NegativeAckError struct {
	Command         byte
	UniqueCommandID uint32
	DeviceCode      int32
}

NegativeAckError reports an asynchronous F4 rejection correlated to an in-flight command.

func (*NegativeAckError) Error

func (e *NegativeAckError) Error() string

type OperatingMode

type OperatingMode uint16

OperatingMode is an Actisense gateway operating-mode wire value.

const (
	ModeUndefined          OperatingMode = 0
	ModeTransferNormal     OperatingMode = 1
	ModeTransferReceiveAll OperatingMode = 2
	ModeCANPacket          OperatingMode = 5
	ModeCANPacketASCII     OperatingMode = 6
)

func DecodeOperatingMode

func DecodeOperatingMode(response BEMResponse) (OperatingMode, error)

type Parser

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

Parser incrementally decodes a BDTP byte stream. Its retained state is bounded by MaxDatagramLength plus one checksum byte.

func NewParser

func NewParser() *Parser

NewParser returns a parser ready for one connection epoch.

func (*Parser) BufferedBytes

func (p *Parser) BufferedBytes() int

BufferedBytes reports retained partial-frame bytes for diagnostics and bounded-state tests.

func (*Parser) End

func (p *Parser) End(report func(DecodeError))

End reports and discards an incomplete candidate at an input boundary such as connection close or end-of-file.

func (*Parser) Feed

func (p *Parser) Feed(buf []byte, emit func(Datagram), report func(DecodeError))

Feed consumes arbitrary stream chunks. Complete datagrams and recoverable errors are delivered synchronously in wire order.

type Session

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

Session serializes one Actisense connection epoch. It owns the sole wire writer and a bounded BEM correlation table with at most one request per response/BEM key.

func NewSession

func NewSession(config SessionConfig) *Session

func (*Session) ActivatePGNLists

func (s *Session) ActivatePGNLists(ctx context.Context) error

func (*Session) Close

func (s *Session) Close(err error)

Close marks the session terminal and releases pending requests. The owner of the underlying transport remains responsible for closing it to unblock Run.

func (*Session) GetOperatingMode

func (s *Session) GetOperatingMode(ctx context.Context) (OperatingMode, error)

func (*Session) GetTxPGN

func (s *Session) GetTxPGN(ctx context.Context, pgn uint32) (TxPGNState, error)

func (*Session) Request

func (s *Session) Request(ctx context.Context, command byte, data []byte) (BEMResponse, error)

Request sends one local BEM command and waits for its A0 response. The correlation key intentionally excludes the response sequence byte: gateway firmware uses the response BST group, BEM verb, and origin, and local A1/A0 sessions permit one in-flight request per verb.

func (*Session) Run

func (s *Session) Run(reader io.Reader) error

Run reads one connection until EOF or failure. It must be called once.

func (*Session) SetOperatingMode

func (s *Session) SetOperatingMode(ctx context.Context, mode OperatingMode) error

func (*Session) SetTxPGN

func (s *Session) SetTxPGN(ctx context.Context, pgn uint32, enabled bool) error

func (*Session) Write

func (s *Session) Write(buf []byte) error

Write serializes one already-framed BDTP unit with all BEM and bus traffic.

type SessionConfig

type SessionConfig struct {
	Write         func([]byte) error
	OnDatagram    func(Datagram)
	OnDiagnostic  func(Diagnostic)
	OnDecodeError func(DecodeError)
}

type StartupStatus

type StartupStatus struct {
	Legacy      bool
	StartupMode uint16
	ErrorCode   uint32
}

type SystemStatus

type SystemStatus struct {
	Individual    []IndividualBufferStatus
	Unified       []UnifiedBufferStatus
	CAN           *CANStatus
	OperatingMode *OperatingMode
}

type TxPGNState

type TxPGNState struct {
	PGN      uint32
	Enabled  uint8
	Rate     uint32
	Timeout  uint32
	Priority uint8
}

TxPGNState is the complete 14-byte Tx PGN enable response.

func DecodeTxPGNState

func DecodeTxPGNState(response BEMResponse) (TxPGNState, error)

type UnifiedBufferStatus

type UnifiedBufferStatus struct {
	Bandwidth      uint8
	Deleted        uint8
	Loading        uint8
	PointerLoading uint8
}

Jump to

Keyboard shortcuts

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