Add serial protocol code
This commit is contained in:
commit
a7c21e8147
2 changed files with 161 additions and 0 deletions
20
protocol/main.go
Normal file
20
protocol/main.go
Normal file
|
@ -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)
|
||||
}
|
141
protocol/tbm.go
Normal file
141
protocol/tbm.go
Normal file
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue