Inital Working Dummy for basic Serial Communication
This commit is contained in:
commit
4d992ef9be
139
MessageHandler/handler.go
Normal file
139
MessageHandler/handler.go
Normal file
@ -0,0 +1,139 @@
|
|||||||
|
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, ";")
|
||||||
|
}
|
||||||
47
SerialInteraction/serial.go
Normal file
47
SerialInteraction/serial.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package serialinteraction
|
||||||
|
|
||||||
|
import (
|
||||||
|
"go.bug.st/serial"
|
||||||
|
"log"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SerialConnection struct {
|
||||||
|
port serial.Port
|
||||||
|
portPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) ListComports() []string {
|
||||||
|
ports, err := serial.GetPortsList()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return ports
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) GetPortPath() string {
|
||||||
|
return sc.portPath
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) Connect(portPath string) error {
|
||||||
|
mode := &serial.Mode{
|
||||||
|
BaudRate: 115200,
|
||||||
|
}
|
||||||
|
port, err := serial.Open(portPath, mode)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
sc.port = port
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) Disconnect() {
|
||||||
|
sc.port.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) Write(data []byte) (int, error) {
|
||||||
|
return sc.port.Write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialConnection) Read(data []byte) (int, error) {
|
||||||
|
return sc.port.Read(data)
|
||||||
|
}
|
||||||
30
SerialInteraction/serialMock.go
Normal file
30
SerialInteraction/serialMock.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package serialinteraction
|
||||||
|
|
||||||
|
type SerialMockConnection struct {
|
||||||
|
portPath string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) ListComports() []string {
|
||||||
|
return []string{"/dev/ttyUSB0", "/dev/ttyUSB1"}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) GetPortPath() string {
|
||||||
|
return "/dev/ttyUSB0"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) Connect(portPath string) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) Disconnect() {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) Write(data []byte) (int, error) {
|
||||||
|
return 10, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sc *SerialMockConnection) Read(data []byte) (int, error) {
|
||||||
|
msg := "Viele Lustige Daten"
|
||||||
|
data = []byte(msg)
|
||||||
|
return len(msg), nil
|
||||||
|
}
|
||||||
13
go.mod
Normal file
13
go.mod
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
module serialToWebsocket
|
||||||
|
|
||||||
|
go 1.23.6
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/gorilla/websocket v1.5.3
|
||||||
|
go.bug.st/serial v1.6.2
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/creack/goselect v0.1.2 // indirect
|
||||||
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 // indirect
|
||||||
|
)
|
||||||
16
go.sum
Normal file
16
go.sum
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
github.com/creack/goselect v0.1.2 h1:2DNy14+JPjRBgPzAd1thbQp4BSIihxcBf0IXhQXDRa0=
|
||||||
|
github.com/creack/goselect v0.1.2/go.mod h1:a/NhLweNvqIYMuxcMOuWY516Cimucms3DglDzQP3hKY=
|
||||||
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||||
|
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
go.bug.st/serial v1.6.2 h1:kn9LRX3sdm+WxWKufMlIRndwGfPWsH1/9lCWXQCasq8=
|
||||||
|
go.bug.st/serial v1.6.2/go.mod h1:UABfsluHAiaNI+La2iESysd9Vetq7VRdpxvjx7CmmOE=
|
||||||
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261 h1:v6hYoSR9T5oet+pMXwUWkbiVqx/63mlHjefrHmxwfeY=
|
||||||
|
golang.org/x/sys v0.0.0-20220829200755-d48e67d00261/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
44
main.go
Normal file
44
main.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"serialToWebsocket/MessageHandler"
|
||||||
|
serialinteraction "serialToWebsocket/SerialInteraction"
|
||||||
|
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var upgrader = websocket.Upgrader{
|
||||||
|
CheckOrigin: func(r *http.Request) bool {
|
||||||
|
return true // for debuggin allow all
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
type Main struct {
|
||||||
|
handle *MessageHandler.MessageHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Main) websock(w http.ResponseWriter, r *http.Request) {
|
||||||
|
c, err := upgrader.Upgrade(w, r, nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("upgrade: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
|
m.handle.WebsocketHandle(w, r, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
handlerOb := MessageHandler.MessageHandler{
|
||||||
|
Serial: &serialinteraction.SerialConnection{},
|
||||||
|
}
|
||||||
|
ma := Main{
|
||||||
|
handle: &handlerOb,
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/ws", ma.websock)
|
||||||
|
log.Printf("Server gestaret auf :8080")
|
||||||
|
log.Fatal(http.ListenAndServe(":8080", nil))
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user