bus

package
v1.2.2 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: Apache-2.0 Imports: 15 Imported by: 0

Documentation

Overview

Package bus owns one n2k.Client per physical CAN endpoint. NMEA 2000 address claiming allows one bus participant per interface, so sources and sinks on the same interface share a client via refcounted handles.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotEncodable = errors.New("envelope cannot be encoded for CAN transmission")

ErrNotEncodable marks an envelope that cannot be re-encoded onto a CAN bus — most commonly a PGN with no cataloged decoder (an UnknownPGN envelope, which beacon always produces since sources run with n2k.IncludeUnknown()). Callers (see sink.canSink.Push) treat this as skippable rather than a transient write failure worth retrying forever.

Functions

func StreamFormat

func StreamFormat(f string) (n2k.StreamFormat, error)

StreamFormat maps beacon's config stream-format string to n2k's enum, shared by the tcp endpoint here and the read-only tcp/udp sources in internal/source.

Types

type DeviceInfo

type DeviceInfo struct {
	Endpoint                 string    `json:"endpoint"`
	Address                  uint8     `json:"address"`
	Name                     uint64    `json:"name"`
	NameHex                  string    `json:"name_hex"`
	LastSeen                 time.Time `json:"last_seen"`
	IdentityNumber           uint32    `json:"identity_number"`
	ManufacturerCode         uint16    `json:"manufacturer_code"`
	Manufacturer             string    `json:"manufacturer,omitempty"`
	DeviceInstance           uint8     `json:"device_instance"`
	SystemInstance           uint8     `json:"system_instance"`
	DeviceClass              uint8     `json:"device_class"`
	DeviceClassName          string    `json:"device_class_name,omitempty"`
	DeviceFunction           uint8     `json:"device_function"`
	DeviceFunctionName       string    `json:"device_function_name,omitempty"`
	IndustryGroup            uint8     `json:"industry_group"`
	IndustryGroupName        string    `json:"industry_group_name,omitempty"`
	ArbitraryAddressCapable  bool      `json:"arbitrary_address_capable"`
	N2KVersion               uint64    `json:"n2k_version,omitempty"`
	ProductCode              uint64    `json:"product_code,omitempty"`
	Model                    string    `json:"model,omitempty"`
	SoftwareVersion          string    `json:"software_version,omitempty"`
	ModelVersion             string    `json:"model_version,omitempty"`
	Serial                   string    `json:"serial,omitempty"`
	CertificationLevel       uint64    `json:"certification_level,omitempty"`
	LoadEquivalency          uint64    `json:"load_equivalency,omitempty"`
	InstallationDescription1 string    `json:"installation_description_1,omitempty"`
	InstallationDescription2 string    `json:"installation_description_2,omitempty"`
	ManufacturerInformation  string    `json:"manufacturer_information,omitempty"`
	TransmitPGNs             []uint32  `json:"transmit_pgns,omitempty"`
	ReceivePGNs              []uint32  `json:"receive_pgns,omitempty"`
}

DeviceInfo is one device observed on a CAN endpoint's bus. n2k v0.3.0's client tracks every claimed NAME automatically (from address-claim traffic), so this data comes for free once a bus client is running.

type Endpoint

type Endpoint struct {
	Kind   string // "socketcan" | "usbcan" | "tcp" (NMEA-2000 gateway)
	Name   string // interface name, serial port path, or gateway host:port
	Format string // tcp only: model.StreamFormatYDRaw / model.StreamFormatActisense
}

type EndpointStatus

type EndpointStatus struct {
	Endpoint           string `json:"endpoint"`
	Kind               string `json:"kind"`
	Name               string `json:"name"`
	State              string `json:"state"`
	Err                string `json:"err,omitempty"`
	Address            uint8  `json:"address"`
	AddressClaimed     bool   `json:"address_claimed"`
	Closed             bool   `json:"closed"`
	WriteQueueDepth    int    `json:"write_queue_depth"`
	WriteQueueCapacity int    `json:"write_queue_capacity"`
	ReceiveSubscribers int    `json:"receive_subscribers"`
}

EndpointStatus is a point-in-time health snapshot for one shared n2k client. Queue and subscriber fields come directly from n2k.Client.Status; they make bounded-runtime pressure visible without performing bus I/O.

type Handle

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

func (*Handle) Release

func (h *Handle) Release()

Release decrements the handle's reference on the shared client. The last Release for an endpoint cancels the receive loop, closes the client, and blocks until the run goroutine has fully exited.

func (*Handle) State

func (h *Handle) State() (state string, lastErr error)

State reports the shared client's current connection state ("up", "degraded", or "error") and the last error observed, if any.

func (*Handle) Subscribe

func (h *Handle) Subscribe(buf int) (<-chan *msg.Envelope, func())

Subscribe returns a channel of decoded envelopes received on the shared client, and an unsubscribe function that removes it. buf sets the channel's buffer size; a full subscriber has envelopes dropped rather than blocking the shared receive loop.

unsub does NOT close the channel (envelopes may be in flight from the broadcast loop when it runs). Consumers must select on their own context/done signal alongside the channel — never bare-range over it.

func (*Handle) SubscribeNamed

func (h *Handle) SubscribeNamed(label string, buf int) (<-chan *msg.Envelope, func())

func (*Handle) Write

func (h *Handle) Write(ctx context.Context, e *msg.Envelope) error

Write re-encodes the envelope onto the bus. Requires Raw bytes. It blocks until the write completes or ctx is done; cancellation abandons the wait but does not retract a write already handed to the client.

type Manager

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

func NewManager

func NewManager(log *slog.Logger, met *metrics.Set, extraOpts ...n2k.Option) *Manager

func NewManagerWithBus

func NewManagerWithBus(log *slog.Logger, met *metrics.Set, customBus n2k.Bus, extraOpts ...n2k.Option) *Manager

NewManagerWithBus builds a manager over a caller-supplied n2k Bus. It is useful for deterministic simulations and embedded transports; unlike a physical endpoint, n2k v0.3.0 does not permit WithBus to be combined with CAN/USB/TCP source options.

func (*Manager) Acquire

func (m *Manager) Acquire(ctx context.Context, ep Endpoint) (*Handle, error)

Acquire returns a refcounted handle on the endpoint's shared client, starting it if this is the first reference.

ctx bounds only the acquisition itself; it does NOT bound the client's lifetime. The shared client runs on its own background context because it is shared between acquirers with independent lifecycles — it lives until the last Handle is Released.

func (*Manager) Devices

func (m *Manager) Devices() []DeviceInfo

Devices returns every device currently known across all running bus endpoints, newest activity first. Safe to call concurrently with Acquire/ Release; it snapshots the client set under mgr.mu, then reads each client's registry without holding the manager lock.

func (*Manager) SetStatsRegistry

func (m *Manager) SetStatsRegistry(st *stats.Registry)

func (*Manager) Statuses

func (m *Manager) Statuses() []EndpointStatus

Statuses returns a stable, sorted snapshot of every shared n2k client. It exposes the bounded runtime state added in n2k v0.3.0 and is safe to call concurrently with endpoint acquisition, reconnect, and release.

type SupportedPGNs

type SupportedPGNs struct {
	Transmit []uint32
	Receive  []uint32
}

Directories

Path Synopsis
Package busfake provides an in-memory fake implementing n2k.Bus for tests: frames written by the client are recorded, and test-injected frames are delivered to the client's registered handler.
Package busfake provides an in-memory fake implementing n2k.Bus for tests: frames written by the client are recorded, and test-injected frames are delivered to the client's registered handler.

Jump to

Keyboard shortcuts

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