Documentation
¶
Overview ¶
Package safety provides end-to-end data protection and deterministic queuing primitives for safety-oriented DDS deployments.
E2EPublisher prepends an 18-byte protection header to every payload before writing. E2ESubscriber strips the header and validates CRC, sequence counter, and sample freshness on every received sample.
Wire format (little-endian, 18 bytes followed by original payload):
Bytes 0–1 DataID (uint16) Bytes 2–3 SourceID (uint16) Bytes 4–7 SequenceCounter (uint32, monotonically increasing per publisher) Bytes 8–15 Timestamp (int64, Unix nanoseconds at time of Write) Bytes 16–17 CRC-16/CCITT-FALSE over bytes 0–15 plus the original payload Bytes 18+ Original payload
The CRC slot is treated as zero when computing the CRC.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrQueueFull = errors.New("safety: queue full")
ErrQueueFull is returned by Enqueue when the DeterministicQueue has no remaining capacity.
Functions ¶
This section is empty.
Types ¶
type DeterministicQueue ¶
type DeterministicQueue struct {
// contains filtered or unexported fields
}
DeterministicQueue is a bounded FIFO that decouples application writes from the underlying publisher. It contains the publisher's panic (converting it to an error on the Errors channel) and provides non-blocking back-pressure via ErrQueueFull.
Typical use:
q := safety.NewDeterministicQueue(pub, 128).Start()
defer q.Stop()
if err := q.Enqueue(payload); err != nil {
// handle back-pressure
}
func NewDeterministicQueue ¶
func NewDeterministicQueue(pub dds.Publisher, depth int) *DeterministicQueue
NewDeterministicQueue creates a queue with the given channel depth that drains into pub. Call Start to begin delivery. A depth of ≤ 0 uses 64.
func (*DeterministicQueue) Enqueue ¶
func (q *DeterministicQueue) Enqueue(payload []byte) error
Enqueue adds payload to the queue without blocking. Returns ErrQueueFull if the queue is at capacity.
func (*DeterministicQueue) Errors ¶
func (q *DeterministicQueue) Errors() <-chan error
Errors returns a channel that receives errors from the drain goroutine, including publisher errors and panics wrapped as errors.
func (*DeterministicQueue) Start ¶
func (q *DeterministicQueue) Start() *DeterministicQueue
Start launches the drain goroutine. Returns q for chaining.
func (*DeterministicQueue) Stop ¶
func (q *DeterministicQueue) Stop()
Stop signals the drain goroutine to exit and waits for it to finish. Safe to call more than once.
type E2EConfig ¶
type E2EConfig struct {
// DataID identifies the logical data element (0–65535).
DataID uint16
// SourceID identifies the sender (0–65535).
SourceID uint16
// MaxAge is the maximum permitted age of a received sample, measured from
// the timestamp written by the publisher. Zero disables freshness checking.
MaxAge time.Duration
}
E2EConfig configures end-to-end protection parameters shared by a publisher and subscriber pair.
type E2EError ¶
type E2EError struct {
Kind E2EErrorKind
Counter uint32
Message string
}
E2EError is sent over the Errors channel when a safety check fails.
type E2EErrorKind ¶
type E2EErrorKind int
E2EErrorKind categorises safety check failures reported by E2ESubscriber.
const ( // ErrCRCMismatch means the CRC in the frame header did not match. ErrCRCMismatch E2EErrorKind = iota // ErrSequenceGap means one or more sequence numbers were skipped. ErrSequenceGap // ErrStaleSample means the sample's timestamp is older than MaxAge. ErrStaleSample // ErrHeaderTooShort means the payload is shorter than the 18-byte header. ErrHeaderTooShort )
type E2EPublisher ¶
type E2EPublisher struct {
// contains filtered or unexported fields
}
E2EPublisher wraps a dds.Publisher and prepends an E2E protection header to every Write payload. It satisfies dds.Publisher.
func NewE2EPublisher ¶
func NewE2EPublisher(pub dds.Publisher, cfg E2EConfig) *E2EPublisher
NewE2EPublisher wraps pub with end-to-end protection configured by cfg.
func (*E2EPublisher) Close ¶
func (p *E2EPublisher) Close() error
Close closes the underlying publisher.
func (*E2EPublisher) Write ¶
func (p *E2EPublisher) Write(payload []byte) error
Write prepends an E2E header to payload and writes the frame to the underlying publisher.
type E2ESubscriber ¶
type E2ESubscriber struct {
// contains filtered or unexported fields
}
E2ESubscriber wraps a dds.Subscriber, strips the E2E header from each received sample, and validates CRC, sequence counter, and freshness. Valid samples are forwarded to C(); failures are reported on Errors().
The background pump goroutine starts on construction and exits when Close is called or the underlying subscriber channel is closed.
func NewE2ESubscriber ¶
func NewE2ESubscriber(sub dds.Subscriber, cfg E2EConfig) *E2ESubscriber
NewE2ESubscriber wraps sub with E2E validation using cfg.
func (*E2ESubscriber) C ¶
func (s *E2ESubscriber) C() <-chan dds.Sample
C returns the channel that delivers validated, header-stripped samples. It satisfies dds.Subscriber.
func (*E2ESubscriber) Close ¶
func (s *E2ESubscriber) Close() error
Close stops the pump goroutine and closes the underlying subscriber.
func (*E2ESubscriber) Errors ¶
func (s *E2ESubscriber) Errors() <-chan E2EError
Errors returns a channel that receives E2EError values for every safety check failure. The channel is buffered (32); overflows are silently dropped.