Skip to content

Commit

Permalink
remove global clients: use callback to avoid nesting import
Browse files Browse the repository at this point in the history
dido18 committed Jan 24, 2025
1 parent f07103e commit ef94d97
Showing 5 changed files with 116 additions and 62 deletions.
60 changes: 41 additions & 19 deletions hub.go
Original file line number Diff line number Diff line change
@@ -19,7 +19,6 @@ import (
"encoding/json"
"fmt"
"html"
"io"
"os"
"runtime"
"runtime/debug"
@@ -46,19 +45,41 @@ type hub struct {
// Unregister requests from connections.
unregister chan *connection

//TODO globals clients
// Serial hub to communicate with serial ports
serialHub *serialhub

serialPortList *SerialPortList
}

func NewHub() *hub {
return &hub{
broadcast: make(chan []byte, 1000),
broadcastSys: make(chan []byte, 1000),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
serialHub: NewSerialHub(),
func NewHub(serialhub *serialhub, serialList *SerialPortList) *hub {

Check failure on line 55 in hub.go

GitHub Actions / check-style (./)

exported function NewHub should have comment or be unexported

Check failure on line 55 in hub.go

GitHub Actions / check-style (./)

exported func NewHub returns unexported type *main.hub, which can be annoying to use

Check failure on line 55 in hub.go

GitHub Actions / check-style (./)

exported function NewHub should have comment or be unexported

Check failure on line 55 in hub.go

GitHub Actions / check-style (./)

exported func NewHub returns unexported type *main.hub, which can be annoying to use
hub := &hub{
broadcast: make(chan []byte, 1000),
broadcastSys: make(chan []byte, 1000),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
serialHub: serialhub,
serialPortList: serialList,
}

hub.serialHub.OnRegister = func(port *serport) {
hub.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}")
}

hub.serialHub.OnUnregister = func(port *serport) {
hub.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
}

hub.serialPortList.OnList = func(data []byte) {
hub.broadcastSys <- data
}

hub.serialPortList.OnErr = func(err string) {
hub.broadcastSys <- []byte("{\"Error\":\"" + err + "\"}")
}

return hub
}

const commands = `{
@@ -138,18 +159,18 @@ func (h *hub) checkCmd(m []byte) {

args := strings.Split(s, " ")
if len(args) < 3 {
go spErr("You did not specify a port and baud rate in your open cmd")
go h.spErr("You did not specify a port and baud rate in your open cmd")
return
}
if len(args[1]) < 1 {
go spErr("You did not specify a serial port")
go h.spErr("You did not specify a serial port")
return
}

baudStr := strings.Replace(args[2], "\n", "", -1)
baud, err := strconv.Atoi(baudStr)
if err != nil {
go spErr("Problem converting baud rate " + args[2])
go h.spErr("Problem converting baud rate " + args[2])
return
}
// pass in buffer type now as string. if user does not
@@ -166,9 +187,9 @@ func (h *hub) checkCmd(m []byte) {

args := strings.Split(s, " ")
if len(args) > 1 {
go spClose(args[1])
go h.spClose(args[1])
} else {
go spErr("You did not specify a port to close")
go h.spErr("You did not specify a port to close")
}

} else if strings.HasPrefix(sl, "killupload") {
@@ -181,9 +202,9 @@ func (h *hub) checkCmd(m []byte) {

} else if strings.HasPrefix(sl, "send") {
// will catch send and sendnobuf and sendraw
go spWrite(s)
go h.spWrite(s)
} else if strings.HasPrefix(sl, "list") {
go serialPorts.List()
go h.serialPortList.List()
} else if strings.HasPrefix(sl, "downloadtool") {
go func() {
args := strings.Split(s, " ")
@@ -242,15 +263,16 @@ func (h *hub) checkCmd(m []byte) {
} else if strings.HasPrefix(sl, "version") {
h.getVersion()
} else {
go spErr("Could not understand command.")
go h.spErr("Could not understand command.")
}
}

func logAction(sl string) {
if strings.HasPrefix(sl, "log on") {
*logDump = "on"
multiWriter := io.MultiWriter(&loggerWs, os.Stderr)
log.SetOutput(multiWriter)
//TODO: pass the loggerSw in the constructor and enable again the log e
// multiWriter := io.MultiWriter(&loggerWs, os.Stderr)
// log.SetOutput(multiWriter)
} else if strings.HasPrefix(sl, "log off") {
*logDump = "off"
log.SetOutput(os.Stderr)
4 changes: 2 additions & 2 deletions info.go
Original file line number Diff line number Diff line change
@@ -41,12 +41,12 @@ func infoHandler(c *gin.Context) {
})
}

func PauseHandler(s *systray.Systray) func(c *gin.Context) {
func PauseHandler(h *hub, s *systray.Systray) func(c *gin.Context) {

Check failure on line 44 in info.go

GitHub Actions / check-style (./)

exported function PauseHandler should have comment or be unexported

Check failure on line 44 in info.go

GitHub Actions / check-style (./)

exported function PauseHandler should have comment or be unexported
return func(c *gin.Context) {
go func() {
ports, _ := serial.GetPortsList()
for _, element := range ports {
spClose(element)
h.spClose(element)
}
*hibernate = true
s.Pause()
12 changes: 8 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
@@ -115,8 +115,6 @@ var (
// return len(p), nil
// }

// var loggerWs logWriter

func homeHandler(c *gin.Context) {
homeTemplate.Execute(c.Writer, c.Request.Host)
}
@@ -192,7 +190,13 @@ func loop(stray *systray.Systray, configPath *paths.Path) {
os.Exit(0)
}

h := NewHub()
// serialPorts contains the ports attached to the machine
serialPorts := NewSerialPortList()
serialHub := NewSerialHub()

// var loggerWs logWriter

h := NewHub(serialHub, serialPorts)

logger := func(msg string) {
mapD := map[string]string{"DownloadStatus": "Pending", "Msg": msg}
@@ -438,7 +442,7 @@ func loop(stray *systray.Systray, configPath *paths.Path) {
r.Handle("WS", "/socket.io/", socketHandler)
r.Handle("WSS", "/socket.io/", socketHandler)
r.GET("/info", infoHandler)
r.POST("/pause", PauseHandler(stray))
r.POST("/pause", PauseHandler(h, stray))
r.POST("/update", UpdateHandler(stray))

// Mount goa handlers
48 changes: 27 additions & 21 deletions serial.go
Original file line number Diff line number Diff line change
@@ -19,8 +19,8 @@ package main

import (
"encoding/json"
"fmt"
"slices"
"strconv"
"strings"
"sync"
"time"
@@ -33,6 +33,9 @@ type serialhub struct {
// Opened serial ports.
ports map[*serport]bool
mu sync.Mutex

OnRegister func(port *serport)
OnUnregister func(port *serport)
}

func NewSerialHub() *serialhub {

Check failure on line 41 in serial.go

GitHub Actions / check-style (./)

exported function NewSerialHub should have comment or be unexported

Check failure on line 41 in serial.go

GitHub Actions / check-style (./)

exported func NewSerialHub returns unexported type *main.serialhub, which can be annoying to use

Check failure on line 41 in serial.go

GitHub Actions / check-style (./)

exported function NewSerialHub should have comment or be unexported

Check failure on line 41 in serial.go

GitHub Actions / check-style (./)

exported func NewSerialHub returns unexported type *main.serialhub, which can be annoying to use
@@ -45,6 +48,13 @@ func NewSerialHub() *serialhub {
type SerialPortList struct {
Ports []*SpPortItem
portsLock sync.Mutex

OnList func([]byte) `json:"-"`
OnErr func(string) `json:"-"`
}

func NewSerialPortList() *SerialPortList {

Check failure on line 56 in serial.go

GitHub Actions / check-style (./)

exported function NewSerialPortList should have comment or be unexported

Check failure on line 56 in serial.go

GitHub Actions / check-style (./)

exported function NewSerialPortList should have comment or be unexported
return &SerialPortList{}
}

// SpPortItem is the serial port item
@@ -61,14 +71,11 @@ type SpPortItem struct {
ProductID string
}

// serialPorts contains the ports attached to the machine
var serialPorts SerialPortList

// Register serial ports from the connections.
func (sh *serialhub) Register(port *serport) {
sh.mu.Lock()
//log.Print("Registering a port: ", p.portConf.Name)
sh.hub.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}")
sh.OnRegister(port)
sh.ports[port] = true
sh.mu.Unlock()
}
@@ -77,7 +84,7 @@ func (sh *serialhub) Register(port *serport) {
func (sh *serialhub) Unregister(port *serport) {
sh.mu.Lock()
//log.Print("Unregistering a port: ", p.portConf.Name)
sh.hub.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
sh.OnUnregister(port)
delete(sh.ports, port)
close(port.sendBuffered)
close(port.sendNoBuf)
@@ -105,11 +112,9 @@ func (sp *SerialPortList) List() {
sp.portsLock.Unlock()

if err != nil {
//log.Println(err)
sh.hub.broadcastSys <- []byte("Error creating json on port list " +
err.Error())
sp.OnErr("Error creating json on port list " + err.Error())
} else {
sh.hub.broadcastSys <- ls
sp.OnList(ls)
}
}

@@ -196,6 +201,7 @@ func (sp *SerialPortList) add(addedPort *discovery.Port) {

// If the port is already in the list, just update the metadata...
for _, oldPort := range sp.Ports {
fmt.Println("oldPort.Name: ", oldPort.Name)
if oldPort.Name == addedPort.Address {
oldPort.SerialNumber = props.Get("serialNumber")
oldPort.VendorID = vid
@@ -256,22 +262,22 @@ func (sp *SerialPortList) getPortByName(portname string) *SpPortItem {
return nil
}

func spErr(err string) {
func (h *hub) spErr(err string) {
//log.Println("Sending err back: ", err)
//sh.hub.broadcastSys <- []byte(err)
sh.hub.broadcastSys <- []byte("{\"Error\" : \"" + err + "\"}")
h.broadcastSys <- []byte("{\"Error\" : \"" + err + "\"}")
}

func spClose(portname string) {
if myport, ok := sh.FindPortByName(portname); ok {
sh.hub.broadcastSys <- []byte("Closing serial port " + portname)
func (h *hub) spClose(portname string) {
if myport, ok := h.serialHub.FindPortByName(portname); ok {
h.broadcastSys <- []byte("Closing serial port " + portname)
myport.Close()
} else {
spErr("We could not find the serial port " + portname + " that you were trying to close.")
h.spErr("We could not find the serial port " + portname + " that you were trying to close.")
}
}

func spWrite(arg string) {
func (h *hub) spWrite(arg string) {
// we will get a string of comXX asdf asdf asdf
//log.Println("Inside spWrite arg: " + arg)
arg = strings.TrimPrefix(arg, " ")
@@ -280,7 +286,7 @@ func spWrite(arg string) {
if len(args) != 3 {
errstr := "Could not parse send command: " + arg
//log.Println(errstr)
spErr(errstr)
h.spErr(errstr)
return
}
bufferingMode := args[0]
@@ -291,10 +297,10 @@ func spWrite(arg string) {
//log.Println("The data is:" + data + "---")

// See if we have this port open
port, ok := sh.FindPortByName(portname)
port, ok := h.serialHub.FindPortByName(portname)
if !ok {
// we couldn't find the port, so send err
spErr("We could not find the serial port " + portname + " that you were trying to write to.")
h.spErr("We could not find the serial port " + portname + " that you were trying to write to.")
return
}

@@ -303,7 +309,7 @@ func spWrite(arg string) {
case "send", "sendnobuf", "sendraw":
// valid buffering mode, go ahead
default:
spErr("Unsupported send command:" + args[0] + ". Please specify a valid one")
h.spErr("Unsupported send command:" + args[0] + ". Please specify a valid one")
return
}

Loading

0 comments on commit ef94d97

Please sign in to comment.