new: can.dump reader will now sleep for the correct amount of time

This commit is contained in:
Simone Margaritelli 2024-08-26 16:37:06 +02:00
commit bb847fcf8a

View file

@ -3,8 +3,12 @@ package can
import ( import (
"bufio" "bufio"
"context" "context"
"fmt"
"os" "os"
"regexp" "regexp"
"strconv"
"strings"
"time"
"github.com/evilsocket/islazy/str" "github.com/evilsocket/islazy/str"
"go.einride.tech/can" "go.einride.tech/can"
@ -14,11 +18,30 @@ import (
var dumpLineParser = regexp.MustCompile(`(?m)^\(([\d\.]+)\)\s+([^\s]+)\s+(.+)`) var dumpLineParser = regexp.MustCompile(`(?m)^\(([\d\.]+)\)\s+([^\s]+)\s+(.+)`)
type dumpEntry struct { type dumpEntry struct {
Time string Time time.Time
Device string Device string
Frame string Frame string
} }
func parseTimeval(timeval string) (time.Time, error) {
parts := strings.Split(timeval, ".")
if len(parts) != 2 {
return time.Time{}, fmt.Errorf("invalid timeval format")
}
seconds, err := strconv.ParseInt(parts[0], 10, 64)
if err != nil {
return time.Time{}, fmt.Errorf("invalid seconds value: %v", err)
}
microseconds, err := strconv.ParseInt(parts[1], 10, 64)
if err != nil {
return time.Time{}, fmt.Errorf("invalid microseconds value: %v", err)
}
return time.Unix(seconds, microseconds*1000), nil
}
func (mod *CANModule) startDumpReader() error { func (mod *CANModule) startDumpReader() error {
mod.Info("loading CAN dump from %s ...", mod.dumpName) mod.Info("loading CAN dump from %s ...", mod.dumpName)
@ -36,9 +59,11 @@ func (mod *CANModule) startDumpReader() error {
if line != "" { if line != "" {
if m := dumpLineParser.FindStringSubmatch(line); len(m) != 4 { if m := dumpLineParser.FindStringSubmatch(line); len(m) != 4 {
mod.Warning("unexpected line: '%s' -> %d matches", line, len(m)) mod.Warning("unexpected line: '%s' -> %d matches", line, len(m))
} else if timeval, err := parseTimeval(m[1]); err != nil {
mod.Warning("can't parse (seconds.microseconds) from line: '%s': %v", line, err)
} else { } else {
entries = append(entries, dumpEntry{ entries = append(entries, dumpEntry{
Time: m[1], Time: timeval,
Device: m[2], Device: m[2],
Frame: m[3], Frame: m[3],
}) })
@ -50,12 +75,15 @@ func (mod *CANModule) startDumpReader() error {
return err return err
} }
mod.Info("loaded %d entries from candump log", len(entries)) numEntries := len(entries)
lastEntry := numEntries - 1
mod.Info("loaded %d entries from candump log", numEntries)
go func() { go func() {
mod.Info("candump reader started ...") mod.Info("candump reader started ...")
for _, entry := range entries { for i, entry := range entries {
frame := can.Frame{} frame := can.Frame{}
if err := frame.UnmarshalString(entry.Frame); err != nil { if err := frame.UnmarshalString(entry.Frame); err != nil {
mod.Error("could not unmarshal CAN frame: %v", err) mod.Error("could not unmarshal CAN frame: %v", err)
@ -69,6 +97,13 @@ func (mod *CANModule) startDumpReader() error {
} else { } else {
mod.onFrame(frame) mod.onFrame(frame)
} }
// compute delay before the next frame
if i < lastEntry {
next := entries[i+1]
diff := next.Time.Sub(entry.Time)
time.Sleep(diff)
}
} }
}() }()