Documentation
¶
Overview ¶
Package canbus is the transport-neutral core of go-canbus: CAN and CAN FD frames, identifiers, data length codes, filters, error frames, the Transport interface and the Bus, which shares one transport among many subscribers.
Transports live in subpackages: socketcan (Linux SocketCAN raw sockets) and virtual (a deterministic in-memory bus for tests and simulation). Higher layers build on a Bus: isotp (ISO 15765-2), capture (candump, JSON Lines and pcap traces, replay), and candb with dbc, kcd and codegen (message and signal databases).
A CAN identifier names a message, not a device: nothing in this module infers which physical node sent a frame.
Index ¶
- Constants
- Variables
- func DLCToLen(dlc uint8, fd bool) int
- func IsXLText(s string) bool
- func KernelID(fr *Frame) uint32
- func LenToDLC(n int) uint8
- func PadFD(data []byte, pad byte) []byte
- func RoundUpFDLen(n int) int
- func ValidFDLen(n int) bool
- func XLKernelID(x *XLFrame) uint32
- type Bus
- func (b *Bus) Close() error
- func (b *Bus) Done() <-chan struct{}
- func (b *Bus) Err() error
- func (b *Bus) Name() string
- func (b *Bus) Send(ctx context.Context, f *Frame) error
- func (b *Bus) SendXL(ctx context.Context, x *XLFrame) error
- func (b *Bus) State() State
- func (b *Bus) Stats() Stats
- func (b *Bus) Subscribe(opts ...SubscribeOption) (*Subscription, error)
- func (b *Bus) Transport() Transport
- type Capabilitier
- type Capabilities
- type ControllerStatus
- type DropCounter
- type DropReason
- type ErrorClass
- type ErrorInfo
- type Filter
- type FilterSet
- type Filterer
- type Flags
- type Format
- type Frame
- type FrameError
- type ID
- type Metrics
- type Namer
- type NopMetrics
- func (NopMetrics) OnDrop(string, DropReason, uint64)
- func (NopMetrics) OnError(string, string, error)
- func (NopMetrics) OnFrameReceived(string, *Frame)
- func (NopMetrics) OnFrameSent(string, *Frame)
- func (NopMetrics) OnQueue(string, int, int)
- func (NopMetrics) OnStateChange(string, State, State)
- func (NopMetrics) OnXLFrameReceived(string, *XLFrame)
- func (NopMetrics) OnXLFrameSent(string, *XLFrame)
- type OpError
- type Option
- type Overflow
- type ProtocolViolation
- type RemoteMatch
- type State
- type Stats
- type Statser
- type SubscribeOption
- type Subscription
- func (s *Subscription) Close() error
- func (s *Subscription) Done() <-chan struct{}
- func (s *Subscription) Dropped() uint64
- func (s *Subscription) Err() error
- func (s *Subscription) Frames() <-chan Frame
- func (s *Subscription) Receive(ctx context.Context) (Frame, error)
- func (s *Subscription) ReceiveAny(ctx context.Context, f *Frame, x *XLFrame) (xl bool, err error)
- func (s *Subscription) ReceiveXL(ctx context.Context) (XLFrame, error)
- func (s *Subscription) Received() uint64
- type Transport
- type XLFlags
- type XLFrame
- type XLMetrics
- type XLTransport
Constants ¶
const ( MaxClassicalLen = 8 // largest classical CAN payload MaxFDLen = 64 // largest CAN FD payload )
Payload size limits.
const ( MaxXLPriority = 0x7FF // largest 11-bit CAN XL priority MinXLLen = 1 // smallest CAN XL payload MaxXLLen = 2048 // largest CAN XL payload )
CAN XL limits.
const DefaultQueueSize = 1024
DefaultQueueSize is the queue capacity of a subscription that does not set one.
Variables ¶
var ( // ErrClosed reports an operation on a bus, subscription or transport // that was closed. ErrClosed = errors.New("canbus: closed") // ErrTimeout reports an operation that did not complete in time. A // context deadline is reported as the context's error instead. ErrTimeout = errors.New("canbus: timeout") // ErrInvalidFrame reports a frame that cannot be represented or sent: // see [Frame.Validate]. A *[FrameError] carries the detail. ErrInvalidFrame = errors.New("canbus: invalid frame") // ErrUnsupported reports an operation or frame type the transport // does not support: SocketCAN on a system other than Linux, a CAN FD // frame on a socket not opened for CAN FD, a kernel filter on a // virtual port. ErrUnsupported = errors.New("canbus: unsupported") // ErrQueueFull reports a frame that could not be queued because a // bounded queue was full and its policy is to reject. ErrQueueFull = errors.New("canbus: queue full") // ErrInvalidOption reports an option value a bus, transport or // connection cannot be constructed with. ErrInvalidOption = errors.New("canbus: invalid option") // ErrInterfaceDown reports an interface that is down or does not // exist. ErrInterfaceDown = errors.New("canbus: interface down") // ErrBufferOverflow reports frames lost because a receive buffer // overflowed (the kernel's socket queue, a transmit queue that is // full: ENOBUFS). ErrBufferOverflow = errors.New("canbus: buffer overflow") )
Sentinel errors. They are usually wrapped with detail; test with errors.Is.
Functions ¶
func DLCToLen ¶
DLCToLen returns the payload length of a data length code (only its low 4 bits are used). fd selects the CAN FD table: codes 9..15 mean 12, 16, 20, 24, 32, 48 and 64 bytes. For classical CAN they all mean 8 bytes.
func IsXLText ¶ added in v0.5.0
IsXLText reports whether s looks like a CAN XL frame in can-utils notation (a CAN XL header after the first "#"), as opposed to a classical or CAN FD frame.
func KernelID ¶
KernelID returns the Linux can_id of a frame: the identifier with CAN_EFF_FLAG, CAN_RTR_FLAG and CAN_ERR_FLAG.
func LenToDLC ¶
LenToDLC returns the smallest data length code whose CAN FD length holds n bytes: 0..8 map to themselves, 9..12 to 9, ..., 49..64 to 15. Lengths above 64 return 15.
func PadFD ¶
PadFD returns data padded with pad to the next valid CAN FD length. data is returned unchanged when its length is already valid.
func RoundUpFDLen ¶
RoundUpFDLen returns the smallest valid CAN FD length of at least n bytes, or 64 when n exceeds 64.
func ValidFDLen ¶
ValidFDLen reports whether n is a payload length a CAN FD frame can carry: 0..8, 12, 16, 20, 24, 32, 48 or 64.
func XLKernelID ¶ added in v0.7.0
XLKernelID returns the identifier Linux's CAN_RAW_FILTER matches for a CAN XL frame: the priority with the VCID in bits 16..23, without any flag (a standard data frame identifier).
Types ¶
type Bus ¶
type Bus struct {
// contains filtered or unexported fields
}
Bus shares one Transport between many users. A single reader goroutine receives every frame and hands a copy to each Subscription whose filters it passes; Send may be called from any goroutine.
The Bus owns the transport: Close closes it. Subscriptions can be added and closed at any time, also while frames arrive. A frame read while no subscription exists reaches nobody: to receive from the first frame on, create the bus with WithStartOnSubscribe.
On an XLTransport the bus also carries CAN XL frames: Bus.SendXL sends them and subscriptions opened WithXL receive them.
func NewBus ¶
NewBus starts a bus on t. The reader goroutine starts at once and keeps draining the transport even while there are no subscriptions, so that a transport's own receive queue does not overflow.
func (*Bus) Close ¶
Close stops the reader, closes every subscription and the transport. It waits for the reader to stop and is safe to call more than once.
func (*Bus) Done ¶
func (b *Bus) Done() <-chan struct{}
Done returns a channel closed when the bus reader has stopped.
func (*Bus) Err ¶
Err returns why the reader stopped: nil while it runs, ErrClosed after Close, or the transport error that ended it.
func (*Bus) SendXL ¶ added in v0.7.0
SendXL validates a CAN XL frame and transmits it. It fails with ErrUnsupported when the transport does not carry CAN XL (is not an XLTransport). It is safe for concurrent use.
func (*Bus) Subscribe ¶
func (b *Bus) Subscribe(opts ...SubscribeOption) (*Subscription, error)
Subscribe adds a subscription. It returns ErrClosed when the bus is closed.
type Capabilitier ¶
type Capabilitier interface {
Capabilities() Capabilities
}
Capabilitier is implemented by transports that describe themselves.
type Capabilities ¶
type Capabilities struct {
FD bool // sends and receives CAN FD frames
XL bool // sends and receives CAN XL frames ([XLFrame])
ErrorFrames bool // can deliver error frames
KernelFilters bool // filters before delivery (Filterer)
Timestamps bool // frames carry receive timestamps
RecvOwn bool // can deliver its own transmissions
Physical bool // attached to a real or virtual network device, not simulated in process
}
Capabilities describes what a transport supports.
type ControllerStatus ¶
type ControllerStatus uint8
ControllerStatus is Data[1] of a controller error frame.
const ( CtrlRxOverflow ControllerStatus = 0x01 // RX buffer overflow CtrlTxOverflow ControllerStatus = 0x02 // TX buffer overflow CtrlRxWarning ControllerStatus = 0x04 // reached warning level for RX errors CtrlTxWarning ControllerStatus = 0x08 // reached warning level for TX errors CtrlRxPassive ControllerStatus = 0x10 // reached error passive status RX CtrlTxPassive ControllerStatus = 0x20 // reached error passive status TX CtrlActive ControllerStatus = 0x40 // recovered to error active state )
Controller status bits.
func (ControllerStatus) String ¶
func (s ControllerStatus) String() string
String lists the status bits.
type DropCounter ¶
type DropCounter interface {
Drops() (total uint64, reason DropReason)
}
DropCounter is implemented by transports that lose frames before Receive returns them, for example to a kernel receive queue overflow. Drops returns the running total and the reason; a Bus reports the increments to its Metrics.
type DropReason ¶
type DropReason uint8
DropReason says why frames were lost.
const ( DropQueueFull DropReason = iota + 1 // a subscription's queue was full DropKernelOverflow // the kernel's socket receive queue overflowed DropFault // an injected fault (virtual bus) DropFiltered // not delivered because of the port's format (FD frame to a classical port) )
Drop reasons.
type ErrorClass ¶
type ErrorClass uint32
ErrorClass is the class bit set of an error frame: the identifier of a frame with FlagError, with the values of Linux's can/error.h. It is also the mask that selects which error frames a socket receives.
const ( ErrClassTxTimeout ErrorClass = 0x001 // TX timeout (by netdevice driver) ErrClassLostArbitration ErrorClass = 0x002 // lost arbitration; bit in Data[0] ErrClassController ErrorClass = 0x004 // controller problems; Data[1] ErrClassProtocol ErrorClass = 0x008 // protocol violation; Data[2], Data[3] ErrClassTransceiver ErrorClass = 0x010 // transceiver status; Data[4] ErrClassNoAck ErrorClass = 0x020 // no acknowledgement on transmission ErrClassBusOff ErrorClass = 0x040 // bus off ErrClassBusError ErrorClass = 0x080 // bus error (may flood) ErrClassRestarted ErrorClass = 0x100 // controller restarted ErrClassCounters ErrorClass = 0x200 // TX/RX error counters in Data[6], Data[7] // ErrClassAll selects every error class. ErrClassAll ErrorClass = 0x1FFFFFFF )
Error classes.
func (ErrorClass) String ¶
func (c ErrorClass) String() string
String lists the classes, for example "controller|bus-off".
type ErrorInfo ¶
type ErrorInfo struct {
Class ErrorClass
// ArbitrationBit is the bit in which arbitration was lost (0 =
// unspecified), for ErrClassLostArbitration.
ArbitrationBit uint8
// Controller is the controller status, for ErrClassController.
Controller ControllerStatus
// Protocol and ProtocolLocation describe a protocol violation, for
// ErrClassProtocol. The location is the Linux CAN_ERR_PROT_LOC_*
// code (for example 0x08 = data section).
Protocol ProtocolViolation
ProtocolLocation uint8
// Transceiver is the Linux CAN_ERR_TRX_* status, for
// ErrClassTransceiver.
Transceiver uint8
// ControllerSpecific is Data[5], whose meaning depends on the driver.
ControllerSpecific uint8
// TxErrors and RxErrors are the error counters, valid when
// CountersValid (ErrClassCounters) is set.
TxErrors, RxErrors uint8
CountersValid bool
}
ErrorInfo is the decoded content of an error frame.
func ParseError ¶
ParseError decodes an error frame. It reports false for a frame without FlagError.
type Filter ¶
type Filter struct {
ID ID
Mask ID
Format Format
Remote RemoteMatch
Invert bool
}
Filter selects frames by identifier: a frame matches when (frameID & Mask) == (ID & Mask), restricted by Format and Remote, and negated by Invert.
The semantics are those of Linux's CAN_RAW_FILTER: Filter.Kernel returns the can_filter the kernel would be given, and the software matcher evaluates exactly that expression on the kernel's flag-encoded identifier. In particular, with FormatAny a mask of 0x7FF also matches extended identifiers whose low 11 bits agree, as in the kernel.
func ExactExtended ¶
ExactExtended returns a filter for one 29-bit identifier.
func ExactStandard ¶
ExactStandard returns a filter for one 11-bit identifier.
func ParseFilter ¶
ParseFilter parses the notation of Filter.String and candump's: "<id>:<mask>" or "<id>~<mask>" (inverted), hexadecimal; an identifier of more than 3 digits selects extended identifiers. Suffixes ",std", ",ext", ",any", ",data" and ",rtr" set Format and Remote explicitly.
func (Filter) Match ¶
Match reports whether a data or remote frame passes the filter. Error frames are selected by an error mask instead; Match reports false for them.
func (Filter) MatchXL ¶ added in v0.7.0
MatchXL reports whether a CAN XL frame passes the filter, as the kernel decides it: on XLKernelID, so a filter for a standard identifier selects the CAN XL frames of that priority (and any VCID unless the mask covers bits 16..23), and a filter for an extended identifier selects none.
func (Filter) String ¶
String formats the filter as candump does: "123:7FF", "12345678:1FFFFFFF" for extended (with an 8-digit identifier), "123~7FF" when inverted, with ",std" / ",any" / ",data" / ",rtr" for what candump's notation cannot spell. ParseFilter reads it back unchanged.
type FilterSet ¶
type FilterSet struct {
Filters []Filter
Join bool
ErrorMask ErrorClass
}
FilterSet is a list of filters with the combination rule of CAN_RAW_FILTER: a frame passes when it matches any filter, or, with Join (CAN_RAW_JOIN_FILTERS), all of them. An empty set passes every data and remote frame. ErrorMask selects the error frames that pass (CAN_RAW_ERR_FILTER); zero passes none.
type Filterer ¶
Filterer is implemented by transports that filter in the kernel, in hardware or as frames arrive. Frames that do not pass are never delivered to Receive.
type Flags ¶
type Flags uint8
Flags carries the frame format bits of a Frame.
const ( // FlagExtended marks a 29-bit (CAN 2.0B) identifier. FlagExtended Flags = 1 << iota // FlagRemote marks a remote transmission request (classical CAN only). FlagRemote // FlagFD marks a CAN FD frame. FlagFD // FlagBRS marks a CAN FD frame sent with bit rate switching. FlagBRS // FlagESI marks a CAN FD frame whose transmitter was error passive. FlagESI // FlagError marks an error frame: a report of the local controller or // driver, never sent on the bus. See [ParseError]. FlagError )
Frame flags.
type Frame ¶
type Frame struct {
// ID is the identifier without flag bits. For error frames it holds
// the Linux error class bits (CAN_ERR_*).
ID ID
// Flags holds the format bits.
Flags Flags
// Len is the payload length in bytes: 0..8 for classical frames, one
// of 0..8, 12, 16, 20, 24, 32, 48, 64 for CAN FD frames. For remote
// frames it is the requested data length (the DLC), and no data is
// carried.
Len uint8
// Len8DLC preserves a classical frame's raw DLC of 9..15, which also
// means 8 data bytes. It is 0 otherwise.
Len8DLC uint8
// Data is the payload; only the first Len bytes are meaningful.
Data [MaxFDLen]byte
// Timestamp is the receive time reported by the transport (the
// kernel's for SocketCAN), or the zero time.
Timestamp time.Time
// Interface names the interface the frame was received on, if known.
Interface string
// Echo reports that the frame is the receiving socket's own
// transmission, delivered back because receive-own-messages is on.
Echo bool
}
Frame is one CAN or CAN FD frame with its receive metadata.
The payload is a fixed array so that a Frame is a plain value: sending and receiving frames does not allocate. Bytes of Data beyond Len are zero in frames produced by this module. Use Frame.Payload for the valid bytes.
func NewErrorFrame ¶
NewErrorFrame builds an error frame from info, as a driver would report it. Virtual transports use it to inject controller errors.
func NewExtended ¶
NewExtended returns a classical data frame with a 29-bit identifier.
func NewFD ¶
NewFD returns a CAN FD frame. extended selects a 29-bit identifier, brs bit rate switching. A payload whose length is not a valid CAN FD length is rejected: pad it with PadFD first.
func NewStandard ¶
NewStandard returns a classical data frame with an 11-bit identifier.
func (*Frame) DLC ¶
DLC returns the data length code of the frame as transmitted on the bus: for classical frames Len, or Len8DLC when set; for CAN FD frames the code of Len (see LenToDLC).
func (*Frame) IsExtended ¶
IsExtended reports a 29-bit identifier.
func (*Frame) Payload ¶
Payload returns the valid payload bytes, a slice of f.Data. A remote frame carries no data: its payload is empty whatever its Len.
func (*Frame) SetPayload ¶
SetPayload copies data into the frame, sets Len and clears the bytes beyond it. It does not validate the length against the frame type.
func (Frame) String ¶
String formats the frame in candump's compact notation: "123#A1B2C3", "12345678#" for extended identifiers, "123#R" (remote), "123##1A1B2" (CAN FD with its flags nibble).
func (*Frame) Validate ¶
Validate checks that the frame can be transmitted or represented: the identifier fits its format, the length is valid for the frame type, the flags are consistent (no remote CAN FD frame, no BRS/ESI without FD, Len8DLC only with Len 8) and the bytes beyond Len are zero. Error frames are only checked for their length. The returned error is a *FrameError wrapping ErrInvalidFrame.
type FrameError ¶
FrameError reports a frame that failed validation. It wraps ErrInvalidFrame.
func (*FrameError) Error ¶
func (e *FrameError) Error() string
Error describes the problem, for example "canbus: invalid frame 800#: standard identifier 0x800 exceeds 11 bits".
type ID ¶
type ID uint32
ID is a CAN identifier without flag bits: 11 bits for a standard frame, 29 bits for an extended frame. Whether an identifier is standard or extended is recorded in Frame.Flags, not in the ID, because 0x123 as a standard and as an extended identifier are different identifiers on the bus.
type Metrics ¶
type Metrics interface {
// OnFrameSent is called after a frame was handed to the transport.
OnFrameSent(iface string, f *Frame)
// OnFrameReceived is called for every frame read from the transport,
// before filtering by subscriptions.
OnFrameReceived(iface string, f *Frame)
// OnDrop is called when n frames were lost.
OnDrop(iface string, reason DropReason, n uint64)
// OnError is called when a send or receive failed.
OnError(iface, op string, err error)
// OnQueue is called after a frame was queued for a subscription with
// the queue's depth and capacity.
OnQueue(iface string, depth, capacity int)
// OnStateChange is called when the bus state changes.
OnStateChange(iface string, from, to State)
}
Metrics is an optional callback interface for observing a Bus. A nil Metrics disables collection.
The methods are called synchronously, possibly from several goroutines at once; implementations must be safe for concurrent use and must not block. Frames passed to them must not be retained or modified. Embed NopMetrics to implement only some callbacks and to stay compatible when methods are added.
type Namer ¶
type Namer interface {
Name() string
}
Namer is implemented by transports bound to a named interface.
type NopMetrics ¶
type NopMetrics struct{}
NopMetrics is a Metrics that does nothing. Embed it in your own type.
func (NopMetrics) OnDrop ¶
func (NopMetrics) OnDrop(string, DropReason, uint64)
OnDrop does nothing.
func (NopMetrics) OnFrameReceived ¶
func (NopMetrics) OnFrameReceived(string, *Frame)
OnFrameReceived does nothing.
func (NopMetrics) OnFrameSent ¶
func (NopMetrics) OnFrameSent(string, *Frame)
OnFrameSent does nothing.
func (NopMetrics) OnStateChange ¶
func (NopMetrics) OnStateChange(string, State, State)
OnStateChange does nothing.
func (NopMetrics) OnXLFrameReceived ¶ added in v0.7.0
func (NopMetrics) OnXLFrameReceived(string, *XLFrame)
OnXLFrameReceived does nothing.
func (NopMetrics) OnXLFrameSent ¶ added in v0.7.0
func (NopMetrics) OnXLFrameSent(string, *XLFrame)
OnXLFrameSent does nothing.
type OpError ¶
type OpError struct {
Op string // "open", "send", "receive", "close", "filter", ...
Interface string // interface name, or "" when unknown
Err error // underlying error
}
OpError reports a failed transport operation with the interface it was performed on.
type Option ¶
Option configures a Bus.
func WithInterfaceName ¶
WithInterfaceName sets the name reported to logs and metrics. By default it is the transport's Namer name, if any.
func WithLogger ¶
WithLogger logs bus events (state changes, receive errors, drops) to l. A nil logger, the default, logs nothing.
func WithMetrics ¶
WithMetrics reports frames, drops, errors and state changes to m.
func WithStartOnSubscribe ¶ added in v0.2.2
func WithStartOnSubscribe() Option
WithStartOnSubscribe defers the bus's reader until the first Bus.Subscribe (or Bus.Close). Until then frames wait in the transport (a SocketCAN socket's receive buffer), so the first subscription sees them all; without this option the reader starts in NewBus and frames that arrive before the first subscription are lost. Error state (Bus.State) is tracked once the reader runs.
type Overflow ¶
type Overflow uint8
Overflow is the policy of a subscription whose queue is full.
const ( // DropNewest discards the frame that does not fit (the default). The // reader never waits for a slow subscriber. DropNewest Overflow = iota // DropOldest discards the oldest queued frame to make room. DropOldest // Block makes the bus reader wait until the subscriber takes the // frame. A slow subscriber then delays every other subscription and // lets the transport's own queue overflow instead: use it only when // losing frames in this process is worse. Block )
Overflow policies.
type ProtocolViolation ¶
type ProtocolViolation uint8
ProtocolViolation is Data[2] of a protocol error frame.
const ( ProtBit ProtocolViolation = 0x01 // single bit error ProtForm ProtocolViolation = 0x02 // frame format error ProtStuff ProtocolViolation = 0x04 // bit stuffing error ProtBit0 ProtocolViolation = 0x08 // unable to send dominant bit ProtBit1 ProtocolViolation = 0x10 // unable to send recessive bit ProtOverload ProtocolViolation = 0x20 // bus overload ProtActive ProtocolViolation = 0x40 // active error announcement ProtTx ProtocolViolation = 0x80 // error occurred on transmission )
Protocol violation types.
func (ProtocolViolation) String ¶
func (p ProtocolViolation) String() string
String lists the violation bits.
type RemoteMatch ¶
type RemoteMatch uint8
RemoteMatch selects data or remote frames in a Filter.
const ( RemoteAny RemoteMatch = iota // data and remote frames RemoteDataOnly // data frames only RemoteOnly // remote frames only )
Remote frame selection.
type State ¶
type State uint8
State is the state of a bus as far as the library can tell: whether it runs, and the controller's error state reported by error frames.
const ( StateUnknown State = iota StateActive // running; controller error active (or no report) StateWarning // error warning (an error counter reached 96) StatePassive // error passive (an error counter reached 128) StateBusOff // bus off StateDown // the interface is down StateClosed // closed by the application )
Bus states.
type Stats ¶
type Stats struct {
TxFrames uint64 // frames sent
TxBytes uint64 // payload bytes sent
RxFrames uint64 // frames received
RxBytes uint64 // payload bytes received
RxErrors uint64 // error frames received
Dropped uint64 // frames lost: kernel receive queue overflow, full subscription queues, injected faults
TxErrors uint64 // failed send attempts
RxFailure uint64 // failed receive attempts other than cancellation
}
Stats are frame counters of a transport or bus.
type Statser ¶
type Statser interface {
Stats() Stats
}
Statser is implemented by transports that keep counters.
type SubscribeOption ¶
type SubscribeOption func(*Subscription)
SubscribeOption configures a Subscription.
func WithFilters ¶
func WithFilters(fs FilterSet) SubscribeOption
WithFilters selects the frames the subscription receives. Without it, every data and remote frame is received and no error frame.
func WithOverflow ¶
func WithOverflow(o Overflow) SubscribeOption
WithOverflow sets the policy when the queue is full (default DropNewest).
func WithQueueSize ¶
func WithQueueSize(n int) SubscribeOption
WithQueueSize sets the queue capacity (default DefaultQueueSize).
func WithXL ¶ added in v0.7.0
func WithXL() SubscribeOption
WithXL makes the subscription receive CAN XL frames too: CAN, CAN FD and CAN XL frames share its queue in arrival order and are read with Subscription.ReceiveAny (Subscription.Receive and Subscription.ReceiveXL skip the other kind; Subscription.Frames is nil). The subscription's filters select CAN XL frames as Linux's CAN_RAW_FILTER does (FilterSet.MatchXL). Without it, CAN XL frames are not delivered, as to a SocketCAN socket without CAN_RAW_XL_FRAMES.
func WithoutEcho ¶
func WithoutEcho() SubscribeOption
WithoutEcho drops frames the transport marks as this socket's own transmissions (Frame.Echo).
type Subscription ¶
type Subscription struct {
// contains filtered or unexported fields
}
Subscription receives the frames of a Bus that pass its filters, through a bounded queue. Its receive methods and Frames may be used from one goroutine at a time; Close and the counters from any.
func (*Subscription) Close ¶
func (s *Subscription) Close() error
Close ends the subscription. Frames still queued can be read with Receive until it returns ErrClosed.
func (*Subscription) Done ¶
func (s *Subscription) Done() <-chan struct{}
Done returns a channel closed when the subscription ends.
func (*Subscription) Dropped ¶
func (s *Subscription) Dropped() uint64
Dropped returns the number of frames lost because the queue was full.
func (*Subscription) Err ¶
func (s *Subscription) Err() error
Err returns why the subscription ended, or nil while it is open.
func (*Subscription) Frames ¶
func (s *Subscription) Frames() <-chan Frame
Frames returns the queue as a channel, for use in select statements together with Subscription.Done. The channel is never closed. A subscription opened WithXL has none (nil): use Subscription.ReceiveAny.
func (*Subscription) Receive ¶
func (s *Subscription) Receive(ctx context.Context) (Frame, error)
Receive returns the next frame. It returns the context's error when ctx ends first, and, once the queue is empty, ErrClosed after Close or the error that stopped the bus. On a subscription opened WithXL it skips CAN XL frames: use Subscription.ReceiveAny.
func (*Subscription) ReceiveAny ¶ added in v0.7.0
ReceiveAny returns the next frame of any kind, in the order the bus received them: a CAN or CAN FD frame in f (xl false) or a CAN XL frame in x (xl true; x.Data is the subscription's copy, owned by the caller afterwards). Without WithXL it is Subscription.Receive into f.
func (*Subscription) ReceiveXL ¶ added in v0.7.0
func (s *Subscription) ReceiveXL(ctx context.Context) (XLFrame, error)
ReceiveXL returns the next CAN XL frame of a subscription opened WithXL, like Subscription.Receive, skipping CAN and CAN FD frames. Without WithXL it returns ErrUnsupported.
func (*Subscription) Received ¶
func (s *Subscription) Received() uint64
Received returns the number of frames queued so far.
type Transport ¶
type Transport interface {
Send(ctx context.Context, f *Frame) error
Receive(ctx context.Context, f *Frame) error
Close() error
}
Transport is one endpoint on a CAN bus: a SocketCAN socket, a port of a virtual bus, or a future hardware adapter.
Send transmits a frame and Receive waits for the next one; neither retains the frame after it returns. Implementations allow Send from several goroutines at once and one Receive at a time. Both honour the context: a cancelled or expired context ends a blocked call with the context's error. Close ends blocked calls with ErrClosed; later calls return ErrClosed too.
type XLFlags ¶ added in v0.5.0
type XLFlags uint8
XLFlags are the flags of a CAN XL frame (struct canxl_frame's flags without CANXL_XLF, which every CAN XL frame carries).
type XLFrame ¶ added in v0.5.0
type XLFrame struct {
// Priority is the 11-bit arbitration priority.
Priority uint16
// VCID is the virtual CAN network identifier (0 = none).
VCID uint8
// Flags are the frame's flags other than the XL format bit.
Flags XLFlags
// SDT is the SDU (service data unit) type of the payload.
SDT uint8
// AF is the 32-bit acceptance field.
AF uint32
// Data is the payload, 1..2048 bytes.
Data []byte
// Timestamp is the receive time reported by the transport, or the
// zero time.
Timestamp time.Time
// Interface names the interface the frame was received on, if known.
Interface string
// Echo reports that the frame is the receiving socket's own
// transmission.
Echo bool
}
XLFrame is one CAN XL frame (ISO 11898-1:2024) with its receive metadata, laid out like Linux's struct canxl_frame.
Unlike Frame, the payload is a slice: it holds up to 2048 bytes. Transports copy it; they do not keep it after Send returns.
func ParseXLFrame ¶ added in v0.5.0
ParseXLFrame parses a CAN XL frame in can-utils notation: "<vcid><prio>#<flags>:<sdt>:<af>#<data>" (five hex digits before the first "#") or "<prio>#<flags>:<sdt>:<af>#<data>" (three digits, VCID 0). Data bytes may be separated by dots. The XL format bit 0x80 in the flags is implied, as cansend implies it.
type XLMetrics ¶ added in v0.7.0
type XLMetrics interface {
// OnXLFrameSent is called after a CAN XL frame was handed to the
// transport.
OnXLFrameSent(iface string, x *XLFrame)
// OnXLFrameReceived is called for every CAN XL frame read from the
// transport, before filtering by subscriptions.
OnXLFrameReceived(iface string, x *XLFrame)
}
XLMetrics is implemented by Metrics that also observe CAN XL frames. A Bus calls these instead of OnFrameSent and OnFrameReceived for CAN XL frames; Metrics without them see CAN XL frames only in the counters of Bus.Stats. NopMetrics implements it.
type XLTransport ¶ added in v0.7.0
type XLTransport interface {
Transport
SendXL(ctx context.Context, x *XLFrame) error
ReceiveAny(ctx context.Context, f *Frame, x *XLFrame) (xl bool, err error)
}
XLTransport is implemented by transports that carry CAN XL frames: a SocketCAN socket opened with CAN XL, a virtual bus port. SendXL transmits a CAN XL frame (copying its payload). ReceiveAny waits for the next frame of any kind, a CAN or CAN FD frame in f (xl false) or a CAN XL frame in x (xl true), reusing x.Data's storage; Receive skips CAN XL frames. A Bus on an XLTransport receives with ReceiveAny.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package arxml reads the CAN part of AUTOSAR 4.x system descriptions (ARXML) into the format-independent model of package candb.
|
Package arxml reads the CAN part of AUTOSAR 4.x system descriptions (ARXML) into the format-independent model of package candb. |
|
Package candb is the format-independent model of a CAN message database and its signal codec.
|
Package candb is the format-independent model of a CAN message database and its signal codec. |
|
bits
Package bits extracts and inserts bit fields of CAN payloads in the two layouts of CAN databases.
|
Package bits extracts and inserts bit fields of CAN payloads in the two layouts of CAN databases. |
|
Package capture reads and writes CAN traces and replays them.
|
Package capture reads and writes CAN traces and replays them. |
|
Package chaos injects faults between two CAN transports.
|
Package chaos injects faults between two CAN transports. |
|
Package codegen generates Go code from a candb.Database: one struct per message with typed raw fields, identifier and length constants, enum types for value descriptions, physical-value accessors, and multiplexer-aware Encode, Decode and Frame methods.
|
Package codegen generates Go code from a candb.Database: one struct per message with typed raw fields, identifier and length constants, enum types for value descriptions, physical-value accessors, and multiplexer-aware Encode, Decode and Frame methods. |
|
Package dbc reads and writes DBC files into the format-independent model of package candb.
|
Package dbc reads and writes DBC files into the format-independent model of package candb. |
|
Package e2e holds end-to-end tests that combine the packages of go-canbus the way an application does: simulated ECUs from generated code, a gateway decoding with a database, recording into every trace format, replaying and decoding again, ISO-TP diagnostics alongside, on the virtual bus everywhere and on vcan with the kernel on Linux; code generated from DBC, KCD and ARXML compiled and exercised in a separate module; several processes on vcan.
|
Package e2e holds end-to-end tests that combine the packages of go-canbus the way an application does: simulated ECUs from generated code, a gateway decoding with a database, recording into every trace format, replaying and decoding again, ISO-TP diagnostics alongside, on the virtual bus everywhere and on vcan with the kernel on Linux; code generated from DBC, KCD and ARXML compiled and exercised in a separate module; several processes on vcan. |
|
examples
|
|
|
canxl
command
Command canxl sends a 512-byte CAN XL frame and prints every frame on the interface, CAN, CAN FD and CAN XL alike, in can-utils notation.
|
Command canxl sends a 512-byte CAN XL frame and prints every frame on the interface, CAN, CAN FD and CAN XL alike, in can-utils notation. |
|
capture-replay
command
Command capture-replay records traffic of a virtual bus into a candump log, replays it at double speed onto another bus and compares.
|
Command capture-replay records traffic of a virtual bus into a candump log, replays it at double speed onto another bus and compares. |
|
dbc-decode
command
Command dbc-decode parses a DBC database and decodes and encodes a frame with it.
|
Command dbc-decode parses a DBC database and decodes and encodes a frame with it. |
|
dbc-generate
command
Command dbc-generate generates typed Go from a DBC database and shows the generated API, using the package generated from the repository's test database (internal/golden/full).
|
Command dbc-generate generates typed Go from a DBC database and shows the generated API, using the package generated from the repository's test database (internal/golden/full). |
|
isotp-exchange
command
Command isotp-exchange sends a 1000-byte ISO-TP message between two endpoints on a virtual bus, with block size and STmin, and prints the frames on the bus.
|
Command isotp-exchange sends a 1000-byte ISO-TP message between two endpoints on a virtual bus, with block size and STmin, and prints the frames on the bus. |
|
monitor
command
Command monitor prints every frame on a SocketCAN interface (Linux), passively: it never transmits.
|
Command monitor prints every frame on a SocketCAN interface (Linux), passively: it never transmits. |
|
send
command
Command send transmits one classical CAN frame on a SocketCAN interface (Linux).
|
Command send transmits one classical CAN frame on a SocketCAN interface (Linux). |
|
send-fd
command
Command send-fd transmits a 64-byte CAN FD frame with bit rate switching on a SocketCAN interface with the CAN FD MTU (Linux).
|
Command send-fd transmits a 64-byte CAN FD frame with bit rate switching on a SocketCAN interface with the CAN FD MTU (Linux). |
|
slcan
command
Command slcan prints every frame received by a serial-line CAN adapter (CANable, CANtact, USBtin, LAWICEL CANUSB) on any operating system, listen-only: the adapter neither transmits nor acknowledges frames.
|
Command slcan prints every frame received by a serial-line CAN adapter (CANable, CANtact, USBtin, LAWICEL CANUSB) on any operating system, listen-only: the adapter neither transmits nor acknowledges frames. |
|
vcan-pingpong
command
Command vcan-pingpong shows two processes talking over a Linux vcan interface: start the responder, then the requester.
|
Command vcan-pingpong shows two processes talking over a Linux vcan interface: start the responder, then the requester. |
|
virtual-bus
command
Command virtual-bus simulates two nodes on an in-memory bus with injected faults and shows how a receiver detects loss with sequence numbers.
|
Command virtual-bus simulates two nodes on an in-memory bus with injected faults and shows how a receiver detects loss with sequence numbers. |
|
internal
|
|
|
cmd/gengolden
command
Command gengolden regenerates the code generator's golden output, internal/golden/*, from the DBC fixtures (go generate ./...).
|
Command gengolden regenerates the code generator's golden output, internal/golden/*, from the DBC fixtures (go generate ./...). |
|
golden/full
Package full encodes and decodes the messages of full.dbc.
|
Package full encodes and decodes the messages of full.dbc. |
|
leakcheck
Package leakcheck checks tests for goroutines they leave behind.
|
Package leakcheck checks tests for goroutines they leave behind. |
|
Package isotp implements ISO 15765-2 (ISO-TP), the transport protocol that carries messages of up to 4095 bytes (or 4 GiB with the escape sequence) over CAN frames, in userspace on top of a canbus.Bus.
|
Package isotp implements ISO 15765-2 (ISO-TP), the transport protocol that carries messages of up to 4095 bytes (or 4 GiB with the escape sequence) over CAN frames, in userspace on top of a canbus.Bus. |
|
Package kcd reads KCD files, the XML CAN database format of the Kayak project (namespace http://kayak.2codeornot2code.org/1.0), into the format-independent model of package candb.
|
Package kcd reads KCD files, the XML CAN database format of the Kayak project (namespace http://kayak.2codeornot2code.org/1.0), into the format-independent model of package candb. |
|
Package slcan is a CAN transport over the serial-line CAN protocol (LAWICEL ASCII, "slcan") of USB-to-CAN adapters such as the CANable, CANtact, USBtin and LAWICEL CANUSB, without the Linux slcan driver: it works on every operating system go-serial supports and over any byte stream (a pseudo-terminal, a TCP connection to a serial server).
|
Package slcan is a CAN transport over the serial-line CAN protocol (LAWICEL ASCII, "slcan") of USB-to-CAN adapters such as the CANable, CANtact, USBtin and LAWICEL CANUSB, without the Linux slcan driver: it works on every operating system go-serial supports and over any byte stream (a pseudo-terminal, a TCP connection to a serial server). |
|
Package socketcan is the Linux SocketCAN transport: CAN_RAW sockets with CAN FD, kernel filters, error frames, loopback control, kernel timestamps and drop accounting, and kernel ISO-TP sockets (CAN_ISOTP).
|
Package socketcan is the Linux SocketCAN transport: CAN_RAW sockets with CAN FD, kernel filters, error frames, loopback control, kernel timestamps and drop accounting, and kernel ISO-TP sockets (CAN_ISOTP). |
|
link
Package link reads and changes the configuration of Linux CAN network interfaces through rtnetlink, the interface ip-link(8) uses: listing CAN interfaces, their state, bit timing, CAN FD data bit timing, control modes, error counters and statistics; bringing them up and down; setting bit rates, CAN FD mode, restart-ms and MTU; restarting a bus-off controller; creating and deleting vcan and vxcan interfaces.
|
Package link reads and changes the configuration of Linux CAN network interfaces through rtnetlink, the interface ip-link(8) uses: listing CAN interfaces, their state, bit timing, CAN FD data bit timing, control modes, error counters and statistics; bringing them up and down; setting bit rates, CAN FD mode, restart-ms and MTU; restarting a bus-off controller; creating and deleting vcan and vxcan interfaces. |
|
Package virtual is a deterministic in-memory CAN bus for tests and simulation, on every operating system.
|
Package virtual is a deterministic in-memory CAN bus for tests and simulation, on every operating system. |