140 lines
3.1 KiB
Go
140 lines
3.1 KiB
Go
package MessageHandler
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/gorilla/websocket"
|
|
)
|
|
|
|
type SerialInteraction interface {
|
|
ListComports() []string
|
|
Connect(string) error
|
|
Disconnect()
|
|
Write([]byte) (int, error)
|
|
Read([]byte) (int, error)
|
|
GetPortPath() string
|
|
}
|
|
|
|
type MessageHandler struct {
|
|
Serial SerialInteraction
|
|
socket *websocket.Conn
|
|
socketLock sync.Mutex
|
|
}
|
|
|
|
const (
|
|
VERSION = "1"
|
|
)
|
|
|
|
func (mh *MessageHandler) WebsocketHandle(w http.ResponseWriter, r *http.Request, c *websocket.Conn) {
|
|
for {
|
|
mt, message, err := c.ReadMessage()
|
|
if err != nil {
|
|
log.Printf("read: %v", err)
|
|
break
|
|
}
|
|
log.Printf("recv: %s", message)
|
|
answer := mh.messageDispatcher(string(message))
|
|
mh.socketLock.Lock()
|
|
err = c.WriteMessage(mt, []byte(answer))
|
|
mh.socketLock.Unlock()
|
|
if err != nil {
|
|
log.Printf("write: %v", err)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// message format, ";" seperated message version;command;argc;args....?
|
|
func (mh *MessageHandler) messageDispatcher(message string) string {
|
|
messageParts := strings.Split(message, ";")
|
|
|
|
if len(messageParts) < 3 {
|
|
log.Printf("Message to Short, %v", message)
|
|
return ""
|
|
}
|
|
|
|
switch messageParts[0] {
|
|
case VERSION:
|
|
break
|
|
default:
|
|
log.Printf("Unknow Version %v in Message %v", messageParts[0], message)
|
|
return ""
|
|
}
|
|
|
|
switch messageParts[1] {
|
|
case "listports":
|
|
return mh.ListComports()
|
|
case "connect":
|
|
return mh.Connect(messageParts[4])
|
|
case "disconnect":
|
|
return mh.Disconnect()
|
|
case "write":
|
|
return mh.Write(messageParts[4])
|
|
case "read":
|
|
return mh.Read()
|
|
default:
|
|
log.Printf("unknow command %v", message)
|
|
break
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func (mh *MessageHandler) ListComports() string {
|
|
ports := mh.Serial.ListComports()
|
|
message := MessageBuilder("portlist", ports...)
|
|
return message
|
|
}
|
|
|
|
func (mh *MessageHandler) Connect(portname string) string {
|
|
err := mh.Serial.Connect(portname)
|
|
message := ""
|
|
if err != nil {
|
|
message = MessageBuilder("error", "connection")
|
|
} else {
|
|
message = MessageBuilder("connected", "portname")
|
|
}
|
|
return message
|
|
}
|
|
|
|
func (mh *MessageHandler) Disconnect() string {
|
|
mh.Serial.Disconnect()
|
|
return MessageBuilder("disconnected")
|
|
}
|
|
|
|
func (mh *MessageHandler) Write(msg string) string {
|
|
_, err := mh.Serial.Write([]byte(msg))
|
|
if err != nil {
|
|
return MessageBuilder("write", fmt.Sprintf("write error %v", err))
|
|
}
|
|
return MessageBuilder("write")
|
|
}
|
|
|
|
func (mh *MessageHandler) Read() string {
|
|
buffer := make([]byte, 1024)
|
|
_, err := mh.Serial.Read(buffer)
|
|
if err != nil {
|
|
return MessageBuilder("read", fmt.Sprintf("read error %v", err))
|
|
}
|
|
return MessageBuilder("read", string(buffer))
|
|
}
|
|
|
|
// version;command;argc;argv;
|
|
// recv: 1;connect;1;/dev/ttyUSB0;
|
|
// send: 1;connected;0; // no args can be used as a acc command
|
|
// send: 1;connected;1;error: port not found;
|
|
// recv: 1;discoonect;0;
|
|
// send: 1;discoonect;0;
|
|
// recv: 1;write;1;viele viele bunte bytes;
|
|
// send: 1;write;0;
|
|
// send: 1;write;1;error: port not connected;
|
|
// send: 1:read:1;das hab ich gelesen junge;
|
|
|
|
func MessageBuilder(command string, args ...string) string {
|
|
return VERSION + ";" + command + ";" + strconv.Itoa(len(args)) + ";" + strings.Join(args, ";")
|
|
}
|