From ad792a9dcce93170a4259d1fd3d4269c6be822d7 Mon Sep 17 00:00:00 2001 From: Aaron Fischer Date: Wed, 28 Sep 2016 20:56:31 +0200 Subject: [PATCH] Make the serial communication work --- agent.go | 81 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/agent.go b/agent.go index 7acc8cd..01eb80c 100644 --- a/agent.go +++ b/agent.go @@ -1,36 +1,44 @@ package main -// Create a new virtual serial device: -// socat PTY,link=/dev/ttyS10 PTY,link=/dev/ttyS11 - import ( "log" "os" "path" + "errors" "github.com/fsnotify/fsnotify" - "github.com/tarm/serial" "github.com/mkideal/cli" + "github.com/tarm/serial" ) -// TODO: Make the error code optional (as a parameter) -func stop() { +func stop(exitCode int) { log.Println("Have a nice day.") - os.Exit(0) + os.Exit(exitCode) } -func waitAndExecuteCommandsFromDevice(device string) { - config := &serial.Config{Name: device, Baud: 115200} - serial, err := serial.OpenPort(config) +type message struct { + msgType byte + data []byte +} - if err != nil { - log.Fatal(err) +const ( + MSG_TYPE_ANSWER_OK = 0x01 + MSG_TYPE_ANSWER_NOOK = 0x02 + MSG_TYPE_AGENTID = 0x03 + MSG_TYPE_CONFIG = 0x04 +) + +func decodeByteString(bytes []byte, num int) (msg message, err error) { + if bytes[0] == 0x3c && bytes[1] == 0x3e && + bytes[num-1] == 0x0A && bytes[num-2] == 0x0D { + return message{msgType: bytes[2], data: bytes[3:num-2]}, nil } - log.Printf("Open the connection to the n3rdpad over %s", device) + return message{msgType: 0x00, data: make([]byte, 1)}, errors.New("Can't decode the byte array.") +} - // Read from serial - buffer := make([]byte, 128) +func waitAndExecuteCommandsFromDevice(serial *serial.Port) { + buffer := make([]byte, 40) for { num, err := serial.Read(buffer) @@ -38,12 +46,21 @@ func waitAndExecuteCommandsFromDevice(device string) { log.Fatal(err) } - // TODO: Do something with the incomind commands - log.Printf("%q", buffer[:num]) + input, err := decodeByteString(buffer, num) + if err != nil { + log.Fatal(err) + } else { + switch (input.msgType) { + case MSG_TYPE_AGENTID: + log.Printf("Key pressed: %d", input.data[0]) + default: + log.Fatal("Can't recognize the message type.") + } + } } } -func watchForConfigChanges(configFile string) { +func watchForConfigChanges(configFile string, serial *serial.Port) { watcher, err := fsnotify.NewWatcher() if err != nil { log.Fatal(err) @@ -72,7 +89,7 @@ func watchForConfigChanges(configFile string) { } } - // Some editors have a feature calles "swap save" (like vim), which + // Some editors have a feature called "swap save" (like vim), which // will trigger a simple WRITE event, instead it wil trigger RENAME // -> CHMOD -> REMOVE in that order. So we lost track of the file. // To prevent this, we add the file again, if it exist after a @@ -82,13 +99,13 @@ func watchForConfigChanges(configFile string) { watcher.Add(event.Name) } else { log.Fatal("Lost the configuration file. We stop now.") - stop() + stop(1) } } case err := <-watcher.Errors: log.Println("We have the following problem with the configuration file: ", err) log.Println("Try the fix this problem by yourself and restart the agent.") - stop() + stop(2) } } }() @@ -103,7 +120,7 @@ func watchForConfigChanges(configFile string) { type argT struct { cli.Helper ConfigFile string `cli:"c,config" usage:"specify a keymap config file"` - Device string `cli:"d,device" usage:"specify the serial port, the n3rdpad is hooked to"` + Device string `cli:"d,device" usage:"specify the serial port, the n3rdpad is hooked to"` } func main() { @@ -117,16 +134,28 @@ func main() { } if args.Device == "" { log.Fatal("You need to specify the serial device with the --device parameter.") - stop(); + stop(3) } if !args.Help { // Start up the application log.Println("Using the configuration file", configFile) - go watchForConfigChanges(configFile) - waitAndExecuteCommandsFromDevice(args.Device) - stop() + // Open the serial connection + config := &serial.Config{Name: args.Device, Baud: 115200} + serial, err := serial.OpenPort(config) + + if err != nil { + log.Fatal(err) + return nil + } + + log.Printf("Open the connection to the n3rdpad over %s", args.Device) + + go watchForConfigChanges(configFile, serial) + waitAndExecuteCommandsFromDevice(serial) + + stop(0) } return nil