From a7c21e81476b7565e46a378403ec0d4129446538 Mon Sep 17 00:00:00 2001 From: Merlijn Wajer Date: Tue, 25 Jul 2017 12:30:51 +0200 Subject: [PATCH] Add serial protocol code --- protocol/main.go | 20 ++++++++ protocol/tbm.go | 141 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 161 insertions(+) create mode 100644 protocol/main.go create mode 100644 protocol/tbm.go diff --git a/protocol/main.go b/protocol/main.go new file mode 100644 index 0000000..3352527 --- /dev/null +++ b/protocol/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "log" +) + +func main() { + t := &TBM{} + err := t.Connect("/dev/ttyUSB0") + if err != nil { + log.Fatal(err) + } + t.Handle() + defer t.Close() + + //cmd := &Command{"Hi", []string{"v20170802 testing"}} + //t.Commands <- cmd + res := <-t.Results + log.Printf("Got result: %q", res) +} diff --git a/protocol/tbm.go b/protocol/tbm.go new file mode 100644 index 0000000..9242efe --- /dev/null +++ b/protocol/tbm.go @@ -0,0 +1,141 @@ +package main + +import ( + "fmt" + "io" + "strings" + + "github.com/tarm/serial" +) + +type TBM struct { + Commands chan *Command + Results chan *Result + Port *serial.Port +} + +type Command struct { + command string + args []string +} + +type Result struct { + output []byte + errcode []byte +} + +func (t *TBM) Connect(device string) error { + t.Commands = make(chan *Command) + t.Results = make(chan *Result) + + serialconfig := &serial.Config{Name: device, Baud: 9600} + + port, err := serial.OpenPort(serialconfig) + if err != nil { + return err + } + + t.Port = port + + return nil +} + +func (t *TBM) Handle() error { + go handleResults(t.Port, t.Results) + go handleCommands(t.Port, t.Commands) + + return nil +} + +func (t *TBM) Close() { + t.Port.Close() +} + +func deserialise(in io.Reader, init []byte) (*Result, []byte, error) { + var ( + output, errorcode []byte + data, rest []byte + ) + + want_output := true + _ = copy(data, init) + + for { + buf := make([]byte, 4096) + n, err := in.Read(buf) + if err != nil { + return nil, nil, err + } + + n2 := n + len(data) + + data = append(data, buf[:n]...) + + for i := 0; i < n2; i++ { + if data[i] == 0x4 { + if want_output { + want_output = false + output = data[:i] + data = data[i+1:] + break + } else { + errorcode = data[:i] + rest = data[i+1:] + return &Result{output, errorcode}, rest, nil + } + } + } + + } + +} + +func handleResults(in io.Reader, c chan *Result) { + var ( + res *Result + rest []byte + err error + ) + + for { + res, rest, err = deserialise(in, rest) + + if err != nil { + log.Fatal(err) + } + + c <- res + } +} + +func serialise(out io.Writer, command string, args []string) error { + var quoted_args []string + + quoted_args = append(quoted_args, command) + + for _, arg := range args { + quoted_args = append(quoted_args, fmt.Sprintf("\"%s\"", arg)) + } + + out_string := strings.Join(quoted_args, " ") + + output := []byte(out_string) + output = append(output, 0x4) + + _, err := out.Write(output) + // err is non nil if n != len(output) + if err != nil { + return err + } + + return nil +} + +func handleCommands(out io.Writer, c chan *Command) { + for command := range c { + err := serialise(out, command.command, command.args) + if err != nil { + log.Fatal(err) + } + } +}