gotelem/frame.go

94 lines
2.1 KiB
Go
Raw Normal View History

2023-04-22 07:48:04 +00:00
// Package can provides generic CAN interfaces and types.
//
// It has a generic can Frame (packet), as well as a filter type.
// we also define standard interfaces for objects that can accept
// can frames. We can use this pattern to easily extend the capabiltiies of the program
// by writing "adapters" to various devices/formats (xbee, sqlite, network socket, socketcan)
package gotelem
2023-04-15 15:03:35 +00:00
2023-05-09 15:25:29 +00:00
import (
"fmt"
"os"
"time"
)
2023-04-22 07:48:04 +00:00
// Frame represents a protocol-agnostic CAN frame. The Id can be standard or extended,
// but if it is extended, the Kind should be EFF.
2023-04-15 15:03:35 +00:00
type Frame struct {
Id uint32
Data []byte
2023-04-15 15:03:35 +00:00
Kind Kind
}
2023-05-03 15:38:37 +00:00
type CANFrame interface {
Id() uint32
Data() []byte
Type() Kind
}
2023-04-15 15:03:35 +00:00
//go:generate stringer -output=frame_kind.go -type Kind
2023-04-22 07:48:04 +00:00
// Kind is the type of the can Frame
2023-04-15 15:03:35 +00:00
type Kind uint8
const (
2023-05-09 15:25:29 +00:00
CanSFFFrame Kind = iota // Standard ID Frame
CanEFFFrame // Extended ID Frame
CanRTRFrame // Remote Transmission Request Frame
CanErrFrame // Error Frame
2023-04-15 15:03:35 +00:00
)
2023-04-22 07:48:04 +00:00
// CanFilter is a basic filter for masking out data. It has an Inverted flag
// which indicates opposite behavior (reject all packets that match Id and Mask).
// The filter matches when (packet.Id & filter.Mask) == filter.Id
type CanFilter struct {
Id uint32
Mask uint32
Inverted bool
}
2023-04-15 15:03:35 +00:00
2023-04-22 07:48:04 +00:00
// CanSink is an object that can accept Frames to transmit.
2023-04-15 15:03:35 +00:00
type CanSink interface {
Send(*Frame) error
2023-04-15 15:03:35 +00:00
}
2023-04-22 07:48:04 +00:00
// CanSource is an object that can receive Frames.
2023-04-15 15:03:35 +00:00
type CanSource interface {
2023-04-15 20:41:51 +00:00
Recv() (*Frame, error)
2023-04-15 15:03:35 +00:00
}
2023-04-20 20:26:29 +00:00
2023-04-22 07:48:04 +00:00
// CanTransciever is an object that can both send and receive Frames.
2023-04-20 20:26:29 +00:00
type CanTransciever interface {
CanSink
CanSource
}
2023-05-09 15:25:29 +00:00
// CanWriter
type CanWriter struct {
output *os.File
}
// send writes the frame to the file.
func (cw *CanWriter) Send(f *Frame) error {
ts := time.Now().Unix()
_, err := fmt.Fprintf(cw.output, "%d %X %X", ts, f.Id, f.Data)
return err
}
func (cw *CanWriter) Close() error {
return cw.output.Close()
}
func OpenCanWriter(name string) (*CanWriter, error) {
f, err := os.Create(name)
if err != nil {
return nil, err
}
cw := &CanWriter{
output: f,
}
return cw, nil
}