cli fixes
This commit is contained in:
parent
2b130ecc17
commit
8727dc43c7
57
broker.go
57
broker.go
|
@ -1,6 +1,10 @@
|
||||||
package gotelem
|
package gotelem
|
||||||
|
|
||||||
import "fmt"
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
)
|
||||||
|
|
||||||
type BrokerRequest struct {
|
type BrokerRequest struct {
|
||||||
Source string // the name of the sender
|
Source string // the name of the sender
|
||||||
|
@ -82,4 +86,53 @@ func (b *Broker) Unsubscribe(name string) {
|
||||||
b.unsubCh <- bc
|
b.unsubCh <- bc
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: don't use channels for everything to avoid using a mutex
|
|
||||||
|
|
||||||
|
|
||||||
|
type JBroker struct {
|
||||||
|
subs map[string] chan CANDumpJSON // contains the channel for each subsciber
|
||||||
|
|
||||||
|
lock sync.RWMutex
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *JBroker) Subscribe(name string) (ch chan CANDumpJSON, err error) {
|
||||||
|
// get rw lock.
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
_, ok := b.subs[name]
|
||||||
|
if ok {
|
||||||
|
return nil, errors.New("name already in use")
|
||||||
|
}
|
||||||
|
ch = make(chan CANDumpJSON, 10)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *JBroker) Unsubscribe(name string) {
|
||||||
|
// if the channel is in use, close it, else do nothing.
|
||||||
|
b.lock.Lock()
|
||||||
|
defer b.lock.Unlock()
|
||||||
|
ch, ok := b.subs[name]
|
||||||
|
if ok {
|
||||||
|
close(ch)
|
||||||
|
}
|
||||||
|
delete(b.subs, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *JBroker) Publish(sender string, message CANDumpJSON) {
|
||||||
|
go func() {
|
||||||
|
b.lock.RLock()
|
||||||
|
defer b.lock.RUnlock()
|
||||||
|
for name, ch := range b.subs {
|
||||||
|
if name == sender {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// non blocking send.
|
||||||
|
select {
|
||||||
|
case ch <- message:
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package cli
|
package cli
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
@ -20,6 +21,8 @@ func Execute() {
|
||||||
Commands: subCmds,
|
Commands: subCmds,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fmt.Println(serveFlags)
|
||||||
|
|
||||||
if err := app.Run(os.Args); err != nil {
|
if err := app.Run(os.Args); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kschamplin/gotelem"
|
"github.com/kschamplin/gotelem"
|
||||||
|
@ -15,8 +16,8 @@ import (
|
||||||
|
|
||||||
var serveFlags = []cli.Flag{
|
var serveFlags = []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "device",
|
Name: "xbee",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"x"},
|
||||||
Usage: "The XBee to connect to. Leave blank to not use XBee",
|
Usage: "The XBee to connect to. Leave blank to not use XBee",
|
||||||
EnvVars: []string{"XBEE_DEVICE"},
|
EnvVars: []string{"XBEE_DEVICE"},
|
||||||
},
|
},
|
||||||
|
@ -75,10 +76,13 @@ func serve(cCtx *cli.Context) error {
|
||||||
go broker.Start()
|
go broker.Start()
|
||||||
|
|
||||||
|
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
for _, svc := range serveThings {
|
for _, svc := range serveThings {
|
||||||
svcLogger := deriveLogger(logger, svc)
|
svcLogger := deriveLogger(logger, svc)
|
||||||
logger.Info("starting service", "svc", svc.String())
|
logger.Info("starting service", "svc", svc.String())
|
||||||
go func(mySvc service) {
|
go func(mySvc service) {
|
||||||
|
wg.Add(1)
|
||||||
|
defer wg.Done()
|
||||||
err := mySvc.Start(cCtx, broker, svcLogger)
|
err := mySvc.Start(cCtx, broker, svcLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("service stopped!", "err", err, "svc", mySvc.String())
|
logger.Error("service stopped!", "err", err, "svc", mySvc.String())
|
||||||
|
@ -86,6 +90,10 @@ func serve(cCtx *cli.Context) error {
|
||||||
}(svc)
|
}(svc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wg.Wait()
|
||||||
|
|
||||||
|
|
||||||
// tcp listener server.
|
// tcp listener server.
|
||||||
ln, err := net.Listen("tcp", ":8082")
|
ln, err := net.Listen("tcp", ":8082")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -110,7 +118,6 @@ func tcpSvc(ctx *cli.Context, broker *gotelem.Broker, logger *slog.Logger) error
|
||||||
// TODO: extract port/ip from cli context.
|
// TODO: extract port/ip from cli context.
|
||||||
ln, err := net.Listen("tcp", ":8082")
|
ln, err := net.Listen("tcp", ":8082")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error listening: %v\n", err)
|
|
||||||
logger.Warn("error listening", "err", err)
|
logger.Warn("error listening", "err", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -195,6 +202,9 @@ func (c *CanLoggerService) Start(cCtx *cli.Context, broker *gotelem.Broker, l *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// XBeeService provides data over an Xbee device, either by serial or TCP
|
||||||
|
// based on the url provided in the xbee flag. see the description for details.
|
||||||
type XBeeService struct {
|
type XBeeService struct {
|
||||||
session *xbee.Session
|
session *xbee.Session
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,25 +20,25 @@ var canDevFlag = &cli.StringFlag{
|
||||||
Aliases: []string{"c"},
|
Aliases: []string{"c"},
|
||||||
Usage: "CAN device string",
|
Usage: "CAN device string",
|
||||||
EnvVars: []string{"CAN_DEVICE"},
|
EnvVars: []string{"CAN_DEVICE"},
|
||||||
DefaultText: "vcan0",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// this function sets up the `serve` flags and services that use socketCAN
|
// this function sets up the `serve` flags and services that use socketCAN
|
||||||
func init() {
|
func init() {
|
||||||
serveFlags = append(serveFlags, &cli.BoolFlag{Name: "test", Usage: "use vcan0 test"})
|
// add the CAN flags to the serve command
|
||||||
serveFlags = append(serveFlags, canDevFlag)
|
serveCmd.Flags = append(serveCmd.Flags, &cli.BoolFlag{Name: "test", Usage: "use vcan0 test"})
|
||||||
// add services for server
|
serveCmd.Flags = append(serveCmd.Flags, canDevFlag)
|
||||||
|
|
||||||
|
// add services for server
|
||||||
serveThings = append(serveThings, &socketCANService{})
|
serveThings = append(serveThings, &socketCANService{})
|
||||||
|
|
||||||
// add can subcommand/actions
|
// add can subcommand/actions
|
||||||
// TODO: make socketcan utility commands.
|
// TODO: make more utility commands.
|
||||||
subCmds = append(subCmds, socketCANCmd)
|
subCmds = append(subCmds, socketCANCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: add logging back in since it's missing rn
|
|
||||||
|
|
||||||
type socketCANService struct {
|
type socketCANService struct {
|
||||||
|
name string
|
||||||
sock socketcan.CanSocket
|
sock socketcan.CanSocket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,23 +47,37 @@ func (s *socketCANService) Status() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *socketCANService) String() string {
|
func (s *socketCANService) String() string {
|
||||||
return ""
|
if s.name == "" {
|
||||||
|
return "socketCAN"
|
||||||
|
}
|
||||||
|
return s.name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *socketCANService) Start(cCtx *cli.Context, broker *gotelem.Broker, logger *slog.Logger) (err error) {
|
func (s *socketCANService) Start(cCtx *cli.Context, broker *gotelem.Broker, logger *slog.Logger) (err error) {
|
||||||
// vcan0 demo
|
// vcan0 demo
|
||||||
|
|
||||||
|
if cCtx.String("can") == "" {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(cCtx.String("can"), "v") {
|
if strings.HasPrefix(cCtx.String("can"), "v") {
|
||||||
go vcanTest(cCtx.String("can"))
|
go vcanTest(cCtx.String("can"))
|
||||||
}
|
}
|
||||||
|
|
||||||
rxCh := broker.Subscribe("socketCAN")
|
|
||||||
sock, err := socketcan.NewCanSocket(cCtx.String("can"))
|
sock, err := socketcan.NewCanSocket(cCtx.String("can"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("error opening socket", "err", err)
|
logger.Error("error opening socket", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
defer sock.Close()
|
||||||
|
s.name = sock.Name()
|
||||||
|
|
||||||
|
// connect to the broker
|
||||||
|
rxCh := broker.Subscribe("socketCAN")
|
||||||
|
defer broker.Unsubscribe("socketCAN")
|
||||||
|
|
||||||
|
|
||||||
|
// make a channel to receive socketCAN frames.
|
||||||
rxCan := make(chan gotelem.Frame)
|
rxCan := make(chan gotelem.Frame)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
"syscall"
|
||||||
|
|
||||||
"github.com/kschamplin/gotelem/xbee"
|
"github.com/kschamplin/gotelem/xbee"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
|
@ -22,14 +23,13 @@ const (
|
||||||
keyIODevice ctxKey = iota
|
keyIODevice ctxKey = iota
|
||||||
)
|
)
|
||||||
|
|
||||||
var xbeeDeviceFlag = &cli.StringFlag{
|
var xbeeDeviceFlag = &cli.StringFlag{
|
||||||
Name: "device",
|
Name: "device",
|
||||||
Aliases: []string{"d"},
|
Aliases: []string{"d"},
|
||||||
Usage: "The XBee to connect to",
|
Usage: "The XBee to connect to",
|
||||||
Required: true,
|
Required: true,
|
||||||
EnvVars: []string{"XBEE_DEVICE"},
|
EnvVars: []string{"XBEE_DEVICE"},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var xbeeCmd = &cli.Command{
|
var xbeeCmd = &cli.Command{
|
||||||
Name: "xbee",
|
Name: "xbee",
|
||||||
|
@ -92,7 +92,6 @@ writtend to stdout.
|
||||||
}
|
}
|
||||||
|
|
||||||
func xbeeInfo(ctx *cli.Context) error {
|
func xbeeInfo(ctx *cli.Context) error {
|
||||||
|
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stderr))
|
logger := slog.New(slog.NewTextHandler(os.Stderr))
|
||||||
transport := ctx.Context.Value(keyIODevice).(*xbee.Transport)
|
transport := ctx.Context.Value(keyIODevice).(*xbee.Transport)
|
||||||
xb, err := xbee.NewSession(transport, logger.With("device", transport.Type()))
|
xb, err := xbee.NewSession(transport, logger.With("device", transport.Type()))
|
||||||
|
@ -106,14 +105,14 @@ func xbeeInfo(ctx *cli.Context) error {
|
||||||
}
|
}
|
||||||
fmt.Printf("Network ID: %X\n", binary.BigEndian.Uint16(b))
|
fmt.Printf("Network ID: %X\n", binary.BigEndian.Uint16(b))
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func netcat(ctx *cli.Context) error {
|
func netcat(ctx *cli.Context) error {
|
||||||
if ctx.Args().Len() < 1 {
|
if ctx.Args().Len() < 1 {
|
||||||
|
|
||||||
cli.ShowSubcommandHelp(ctx)
|
cli.ShowSubcommandHelp(ctx)
|
||||||
|
|
||||||
return cli.Exit("missing [addr] argument", 1)
|
return cli.Exit("missing [addr] argument", int(syscall.EINVAL))
|
||||||
|
|
||||||
}
|
}
|
||||||
logger := slog.New(slog.NewTextHandler(os.Stderr))
|
logger := slog.New(slog.NewTextHandler(os.Stderr))
|
||||||
|
@ -141,4 +140,3 @@ func netcat(ctx *cli.Context) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/kschamplin/gotelem"
|
||||||
"github.com/kschamplin/gotelem/skylab"
|
"github.com/kschamplin/gotelem/skylab"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
|
@ -91,7 +92,7 @@ func run(ctx *cli.Context) (err error) {
|
||||||
|
|
||||||
segments := strings.Split(dumpLine, " ")
|
segments := strings.Split(dumpLine, " ")
|
||||||
|
|
||||||
var cd candumpJSON
|
var cd gotelem.CANDumpJSON
|
||||||
// this is cursed but easiest way to get a float from a string.
|
// this is cursed but easiest way to get a float from a string.
|
||||||
fmt.Sscanf(segments[0], "(%g)", &cd.Timestamp)
|
fmt.Sscanf(segments[0], "(%g)", &cd.Timestamp)
|
||||||
|
|
||||||
|
@ -122,9 +123,3 @@ func run(ctx *cli.Context) (err error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type candumpJSON struct {
|
|
||||||
Timestamp float64 `json:"ts"`
|
|
||||||
Id uint64 `json:"id"`
|
|
||||||
Data skylab.Packet `json:"data"`
|
|
||||||
}
|
|
||||||
|
|
83
frame_gen.go
83
frame_gen.go
|
@ -159,89 +159,6 @@ func (z CanFilter) Msgsize() (s int) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DecodeMsg implements msgp.Decodable
|
|
||||||
func (z *CanWriter) DecodeMsg(dc *msgp.Reader) (err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zb0001 uint32
|
|
||||||
zb0001, err = dc.ReadMapHeader()
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zb0001 > 0 {
|
|
||||||
zb0001--
|
|
||||||
field, err = dc.ReadMapKeyPtr()
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
default:
|
|
||||||
err = dc.Skip()
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// EncodeMsg implements msgp.Encodable
|
|
||||||
func (z CanWriter) EncodeMsg(en *msgp.Writer) (err error) {
|
|
||||||
// map header, size 0
|
|
||||||
err = en.Append(0x80)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// MarshalMsg implements msgp.Marshaler
|
|
||||||
func (z CanWriter) MarshalMsg(b []byte) (o []byte, err error) {
|
|
||||||
o = msgp.Require(b, z.Msgsize())
|
|
||||||
// map header, size 0
|
|
||||||
o = append(o, 0x80)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// UnmarshalMsg implements msgp.Unmarshaler
|
|
||||||
func (z *CanWriter) UnmarshalMsg(bts []byte) (o []byte, err error) {
|
|
||||||
var field []byte
|
|
||||||
_ = field
|
|
||||||
var zb0001 uint32
|
|
||||||
zb0001, bts, err = msgp.ReadMapHeaderBytes(bts)
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
for zb0001 > 0 {
|
|
||||||
zb0001--
|
|
||||||
field, bts, err = msgp.ReadMapKeyZC(bts)
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch msgp.UnsafeString(field) {
|
|
||||||
default:
|
|
||||||
bts, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
err = msgp.WrapError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
o = bts
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
|
|
||||||
func (z CanWriter) Msgsize() (s int) {
|
|
||||||
s = 1
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// DecodeMsg implements msgp.Decodable
|
// DecodeMsg implements msgp.Decodable
|
||||||
func (z *Frame) DecodeMsg(dc *msgp.Reader) (err error) {
|
func (z *Frame) DecodeMsg(dc *msgp.Reader) (err error) {
|
||||||
var field []byte
|
var field []byte
|
||||||
|
|
|
@ -122,119 +122,6 @@ func BenchmarkDecodeCanFilter(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMarshalUnmarshalCanWriter(t *testing.T) {
|
|
||||||
v := CanWriter{}
|
|
||||||
bts, err := v.MarshalMsg(nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
left, err := v.UnmarshalMsg(bts)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(left) > 0 {
|
|
||||||
t.Errorf("%d bytes left over after UnmarshalMsg(): %q", len(left), left)
|
|
||||||
}
|
|
||||||
|
|
||||||
left, err = msgp.Skip(bts)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if len(left) > 0 {
|
|
||||||
t.Errorf("%d bytes left over after Skip(): %q", len(left), left)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkMarshalMsgCanWriter(b *testing.B) {
|
|
||||||
v := CanWriter{}
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
v.MarshalMsg(nil)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkAppendMsgCanWriter(b *testing.B) {
|
|
||||||
v := CanWriter{}
|
|
||||||
bts := make([]byte, 0, v.Msgsize())
|
|
||||||
bts, _ = v.MarshalMsg(bts[0:0])
|
|
||||||
b.SetBytes(int64(len(bts)))
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
bts, _ = v.MarshalMsg(bts[0:0])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkUnmarshalCanWriter(b *testing.B) {
|
|
||||||
v := CanWriter{}
|
|
||||||
bts, _ := v.MarshalMsg(nil)
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.SetBytes(int64(len(bts)))
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_, err := v.UnmarshalMsg(bts)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestEncodeDecodeCanWriter(t *testing.T) {
|
|
||||||
v := CanWriter{}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
msgp.Encode(&buf, &v)
|
|
||||||
|
|
||||||
m := v.Msgsize()
|
|
||||||
if buf.Len() > m {
|
|
||||||
t.Log("WARNING: TestEncodeDecodeCanWriter Msgsize() is inaccurate")
|
|
||||||
}
|
|
||||||
|
|
||||||
vn := CanWriter{}
|
|
||||||
err := msgp.Decode(&buf, &vn)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
buf.Reset()
|
|
||||||
msgp.Encode(&buf, &v)
|
|
||||||
err = msgp.NewReader(&buf).Skip()
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkEncodeCanWriter(b *testing.B) {
|
|
||||||
v := CanWriter{}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
msgp.Encode(&buf, &v)
|
|
||||||
b.SetBytes(int64(buf.Len()))
|
|
||||||
en := msgp.NewWriter(msgp.Nowhere)
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
v.EncodeMsg(en)
|
|
||||||
}
|
|
||||||
en.Flush()
|
|
||||||
}
|
|
||||||
|
|
||||||
func BenchmarkDecodeCanWriter(b *testing.B) {
|
|
||||||
v := CanWriter{}
|
|
||||||
var buf bytes.Buffer
|
|
||||||
msgp.Encode(&buf, &v)
|
|
||||||
b.SetBytes(int64(buf.Len()))
|
|
||||||
rd := msgp.NewEndlessReader(buf.Bytes(), b)
|
|
||||||
dc := msgp.NewReader(rd)
|
|
||||||
b.ReportAllocs()
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
err := v.DecodeMsg(dc)
|
|
||||||
if err != nil {
|
|
||||||
b.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMarshalUnmarshalFrame(t *testing.T) {
|
func TestMarshalUnmarshalFrame(t *testing.T) {
|
||||||
v := Frame{}
|
v := Frame{}
|
||||||
bts, err := v.MarshalMsg(nil)
|
bts, err := v.MarshalMsg(nil)
|
||||||
|
|
|
@ -11,8 +11,8 @@ import (
|
||||||
|
|
||||||
// CanWriter
|
// CanWriter
|
||||||
type CanWriter struct {
|
type CanWriter struct {
|
||||||
output *os.File
|
output *os.File
|
||||||
cd candumpJSON
|
cd CANDumpJSON
|
||||||
jsonBuf []byte
|
jsonBuf []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ func OpenCanWriter(name string) (*CanWriter, error) {
|
||||||
return cw, nil
|
return cw, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type candumpJSON struct {
|
type CANDumpJSON struct {
|
||||||
Timestamp float64 `json:"ts"`
|
Timestamp float64 `json:"ts"`
|
||||||
Id uint64 `json:"id"`
|
Id uint64 `json:"id"`
|
||||||
Data skylab.Packet `json:"data"`
|
Data skylab.Packet `json:"data"`
|
||||||
|
|
Loading…
Reference in a new issue