From 168ee1a6634c3fc9652c38f2c32dbb67b7c0a16d Mon Sep 17 00:00:00 2001 From: saji <9110284+kschamplin@users.noreply.github.com> Date: Sun, 14 May 2023 16:19:57 -0500 Subject: [PATCH] more skylab work --- cmd/gotelem/cli/server.go | 15 ++++--- frame.go | 2 +- skylab/gen_skylab.go | 91 ++++++++++++++++++++++++++++++++------- skylab/skylab.go | 36 ++++++++++++++++ 4 files changed, 123 insertions(+), 21 deletions(-) create mode 100644 skylab/skylab.go diff --git a/cmd/gotelem/cli/server.go b/cmd/gotelem/cli/server.go index 904481c..eebc241 100644 --- a/cmd/gotelem/cli/server.go +++ b/cmd/gotelem/cli/server.go @@ -96,7 +96,10 @@ func serve(cCtx *cli.Context) error { func handleCon(conn net.Conn, broker *gotelem.Broker, l *slog.Logger, done <-chan struct{}) { // reader := msgp.NewReader(conn) - subname := fmt.Sprint("hi", conn.RemoteAddr().String()) + + subname := fmt.Sprint("tcp", conn.RemoteAddr().String()) + + l.Info("started handling", "name", subname) rxCh := broker.Subscribe(subname) defer broker.Unsubscribe(subname) @@ -105,14 +108,16 @@ func handleCon(conn net.Conn, broker *gotelem.Broker, l *slog.Logger, done <-cha for { select { case msg := <-rxCh: + l.Info("got packet") // FIXME: poorly optimized - buf := make([]byte, 0, 8) - binary.LittleEndian.AppendUint32(buf, msg.Id) + buf := make([]byte, 0) + buf = binary.BigEndian.AppendUint32(buf, msg.Id) buf = append(buf, msg.Data...) _, err := conn.Write(buf) if err != nil { - l.Warn("error writing tcp packet", "err", err) + l.Error("error writing tcp packet", "err", err) + return } case <-done: return @@ -227,7 +232,7 @@ func XBeeSend(broker *gotelem.Broker, l *slog.Logger, done <-chan struct{}, trsp l.Info("got msg", "msg", msg) buf := make([]byte, 0) - binary.LittleEndian.AppendUint32(buf, msg.Id) + buf = binary.BigEndian.AppendUint32(buf, msg.Id) buf = append(buf, msg.Data...) _, err := xb.Write(buf) diff --git a/frame.go b/frame.go index 0fe07cd..71a845b 100644 --- a/frame.go +++ b/frame.go @@ -72,7 +72,7 @@ type CanWriter struct { func (cw *CanWriter) Send(f *Frame) error { ts := time.Now().Unix() - _, err := fmt.Fprintf(cw.output, "%d %X %X", ts, f.Id, f.Data) + _, err := fmt.Fprintf(cw.output, "%d %X %X\n", ts, f.Id, f.Data) return err } diff --git a/skylab/gen_skylab.go b/skylab/gen_skylab.go index 0b753a3..5321aef 100644 --- a/skylab/gen_skylab.go +++ b/skylab/gen_skylab.go @@ -5,7 +5,6 @@ package main import ( - "encoding/binary" "fmt" "os" "strings" @@ -94,8 +93,10 @@ packets: endian: little frequency: 10 data: + - name: blah_blah + type: uint32_t - name: accel_pedal_value - type: uint8_t + type: float - name: brake_pedal_value type: uint8_t ` @@ -140,9 +141,44 @@ func (d *DataField) ToStructMember() string { return "" } +func (d *DataField) MakeMarshal(offset int) string { + + if d.Type == "uint8_t" || d.Type == "int8_t" { + return fmt.Sprintf("b[%d] = p.%s", offset, toCamelInitCase(d.Name, true)) + } else if d.Type == "bitfield" { + return "panic(\"bitfields don't work\")" + } else if d.Type == "float" { + + return fmt.Sprintf("float32ToBytes(b[%d:], p.%s, false)", offset, toCamelInitCase(d.Name, true)) + + } else if t ,ok := typeMap[d.Type]; ok { + // it's uint or int of some kind, use endian to write it. + return fmt.Sprintf("binary.LittleEndian.Put%s(b[%d:], p.%s)", toCamelInitCase(t, true), offset, toCamelInitCase(d.Name, true)) + } + return "panic(\"failed to do it\")\n" +} -func (p PacketDef) Size() int { +func (d *DataField) MakeUnmarshal(offset int) string { + + if d.Type == "uint8_t" || d.Type == "int8_t" { + return fmt.Sprintf("p.%s = b[%d]", toCamelInitCase(d.Name, true), offset) + } else if d.Type == "bitfield" { + + } else if d.Type == "float" { + + return fmt.Sprintf("p.%s = float32FromBytes(b[%d:], false)", toCamelInitCase(d.Name, true), offset) + + } else if t ,ok := typeMap[d.Type]; ok { + // it's uint or int of some kind, use endian to write it. + return fmt.Sprintf("p.%s = binary.LittleEndian.%s(b[%d:])", toCamelInitCase(d.Name, true), toCamelInitCase(t, true), offset) + } + panic("unhandled type") +} + + + +func (p PacketDef) CalcSize() int { // makes a function that returns the size of the code. var size int = 0 @@ -161,21 +197,33 @@ func (p PacketDef) MakeMarshal() string { // we have a b []byte as the correct-size byte array to store in. // and the packet itself is represented as `p` for _, val := range p.Data { - if val.Type == "uint8_t" || val.Type == "int8_t" { - buf.WriteString(fmt.Sprintf("b[%d] = p.%s\n", offset, toCamelInitCase(val.Name, true))) - } else if val.Type == "bitfield" { - - } else if val.Type == "float" { - - } else if name,ok := typeMap[val.Type]; ok { - - } + buf.WriteRune('\t') + buf.WriteString(val.MakeMarshal(offset)) + buf.WriteRune('\n') + // shift our offset so that our next write is good. offset += int(typeSizeMap[val.Type]) } - return "" + + return buf.String() +} + +func (p PacketDef) MakeUnmarshal() string { + var buf strings.Builder + + + var offset int = 0 + for _, val := range p.Data { + + buf.WriteRune('\t') + buf.WriteString(val.MakeUnmarshal(offset)) + buf.WriteRune('\n') + offset += int(typeSizeMap[val.Type]) + } + + return buf.String() } var templ = ` @@ -189,11 +237,21 @@ type {{$structName}} struct { } func (p *{{$structName}}) Id() uint32 { - return {{.Id}} + return {{printf "0x%X" .Id}} } func (p *{{$structName}}) Size() int { - return {{.Size}} + return {{.CalcSize}} +} + +func (p *{{$structName}}) Marshal() []byte { + b = make([]byte, {{ .Size }}) +{{.MakeMarshal}} + return b +} + +func (p *{{$structName}}) Unmarshal(b []byte) { + {{.MakeUnmarshal}} } ` @@ -235,6 +293,9 @@ func toCamelInitCase(s string, initCase bool) string { return n.String() } + +// stolen float32 to bytes code + func main() { v := &SkylabFile{} diff --git a/skylab/skylab.go b/skylab/skylab.go new file mode 100644 index 0000000..be650b4 --- /dev/null +++ b/skylab/skylab.go @@ -0,0 +1,36 @@ +package skylab + +import ( + "math" + "encoding/binary" +) + + +func float32ToBytes(b []byte, f float32, bigEndian bool) { + bits := math.Float32bits(f) + if bigEndian { + binary.BigEndian.PutUint32(b, bits) + } else { + binary.LittleEndian.PutUint32(b, bits) + } + return +} + +func float32FromBytes(b []byte, bigEndian bool) (f float32) { + var bits uint32 + if bigEndian { + binary.BigEndian.Uint32(b) + } else { + binary.LittleEndian.Uint32(b) + } + return math.Float32frombits(bits) +} + + +type Packet interface { + MarshalPacket() ([]byte, error) + UnmarshalPacket(p []byte) error + Id() uint32 + Size() int + String() +}