Skip to content

Commit ef94d97

Browse files
committedJan 24, 2025·
remove global clients: use callback to avoid nesting import
1 parent f07103e commit ef94d97

File tree

5 files changed

+116
-62
lines changed

5 files changed

+116
-62
lines changed
 

‎hub.go

Lines changed: 41 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"encoding/json"
2020
"fmt"
2121
"html"
22-
"io"
2322
"os"
2423
"runtime"
2524
"runtime/debug"
@@ -46,19 +45,41 @@ type hub struct {
4645
// Unregister requests from connections.
4746
unregister chan *connection
4847

48+
//TODO globals clients
4949
// Serial hub to communicate with serial ports
5050
serialHub *serialhub
51+
52+
serialPortList *SerialPortList
5153
}
5254

53-
func NewHub() *hub {
54-
return &hub{
55-
broadcast: make(chan []byte, 1000),
56-
broadcastSys: make(chan []byte, 1000),
57-
register: make(chan *connection),
58-
unregister: make(chan *connection),
59-
connections: make(map[*connection]bool),
60-
serialHub: NewSerialHub(),
55+
func NewHub(serialhub *serialhub, serialList *SerialPortList) *hub {
56+
hub := &hub{
57+
broadcast: make(chan []byte, 1000),
58+
broadcastSys: make(chan []byte, 1000),
59+
register: make(chan *connection),
60+
unregister: make(chan *connection),
61+
connections: make(map[*connection]bool),
62+
serialHub: serialhub,
63+
serialPortList: serialList,
64+
}
65+
66+
hub.serialHub.OnRegister = func(port *serport) {
67+
hub.broadcastSys <- []byte("{\"Cmd\":\"Open\",\"Desc\":\"Got register/open on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + ",\"BufferType\":\"" + port.BufferType + "\"}")
68+
}
69+
70+
hub.serialHub.OnUnregister = func(port *serport) {
71+
hub.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
6172
}
73+
74+
hub.serialPortList.OnList = func(data []byte) {
75+
hub.broadcastSys <- data
76+
}
77+
78+
hub.serialPortList.OnErr = func(err string) {
79+
hub.broadcastSys <- []byte("{\"Error\":\"" + err + "\"}")
80+
}
81+
82+
return hub
6283
}
6384

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

139160
args := strings.Split(s, " ")
140161
if len(args) < 3 {
141-
go spErr("You did not specify a port and baud rate in your open cmd")
162+
go h.spErr("You did not specify a port and baud rate in your open cmd")
142163
return
143164
}
144165
if len(args[1]) < 1 {
145-
go spErr("You did not specify a serial port")
166+
go h.spErr("You did not specify a serial port")
146167
return
147168
}
148169

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

167188
args := strings.Split(s, " ")
168189
if len(args) > 1 {
169-
go spClose(args[1])
190+
go h.spClose(args[1])
170191
} else {
171-
go spErr("You did not specify a port to close")
192+
go h.spErr("You did not specify a port to close")
172193
}
173194

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

182203
} else if strings.HasPrefix(sl, "send") {
183204
// will catch send and sendnobuf and sendraw
184-
go spWrite(s)
205+
go h.spWrite(s)
185206
} else if strings.HasPrefix(sl, "list") {
186-
go serialPorts.List()
207+
go h.serialPortList.List()
187208
} else if strings.HasPrefix(sl, "downloadtool") {
188209
go func() {
189210
args := strings.Split(s, " ")
@@ -242,15 +263,16 @@ func (h *hub) checkCmd(m []byte) {
242263
} else if strings.HasPrefix(sl, "version") {
243264
h.getVersion()
244265
} else {
245-
go spErr("Could not understand command.")
266+
go h.spErr("Could not understand command.")
246267
}
247268
}
248269

249270
func logAction(sl string) {
250271
if strings.HasPrefix(sl, "log on") {
251272
*logDump = "on"
252-
multiWriter := io.MultiWriter(&loggerWs, os.Stderr)
253-
log.SetOutput(multiWriter)
273+
//TODO: pass the loggerSw in the constructor and enable again the log e
274+
// multiWriter := io.MultiWriter(&loggerWs, os.Stderr)
275+
// log.SetOutput(multiWriter)
254276
} else if strings.HasPrefix(sl, "log off") {
255277
*logDump = "off"
256278
log.SetOutput(os.Stderr)

‎info.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ func infoHandler(c *gin.Context) {
4141
})
4242
}
4343

44-
func PauseHandler(s *systray.Systray) func(c *gin.Context) {
44+
func PauseHandler(h *hub, s *systray.Systray) func(c *gin.Context) {
4545
return func(c *gin.Context) {
4646
go func() {
4747
ports, _ := serial.GetPortsList()
4848
for _, element := range ports {
49-
spClose(element)
49+
h.spClose(element)
5050
}
5151
*hibernate = true
5252
s.Pause()

‎main.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,6 @@ var (
115115
// return len(p), nil
116116
// }
117117

118-
// var loggerWs logWriter
119-
120118
func homeHandler(c *gin.Context) {
121119
homeTemplate.Execute(c.Writer, c.Request.Host)
122120
}
@@ -192,7 +190,13 @@ func loop(stray *systray.Systray, configPath *paths.Path) {
192190
os.Exit(0)
193191
}
194192

195-
h := NewHub()
193+
// serialPorts contains the ports attached to the machine
194+
serialPorts := NewSerialPortList()
195+
serialHub := NewSerialHub()
196+
197+
// var loggerWs logWriter
198+
199+
h := NewHub(serialHub, serialPorts)
196200

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

444448
// Mount goa handlers

‎serial.go

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ package main
1919

2020
import (
2121
"encoding/json"
22+
"fmt"
2223
"slices"
23-
"strconv"
2424
"strings"
2525
"sync"
2626
"time"
@@ -33,6 +33,9 @@ type serialhub struct {
3333
// Opened serial ports.
3434
ports map[*serport]bool
3535
mu sync.Mutex
36+
37+
OnRegister func(port *serport)
38+
OnUnregister func(port *serport)
3639
}
3740

3841
func NewSerialHub() *serialhub {
@@ -45,6 +48,13 @@ func NewSerialHub() *serialhub {
4548
type SerialPortList struct {
4649
Ports []*SpPortItem
4750
portsLock sync.Mutex
51+
52+
OnList func([]byte) `json:"-"`
53+
OnErr func(string) `json:"-"`
54+
}
55+
56+
func NewSerialPortList() *SerialPortList {
57+
return &SerialPortList{}
4858
}
4959

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

64-
// serialPorts contains the ports attached to the machine
65-
var serialPorts SerialPortList
66-
6774
// Register serial ports from the connections.
6875
func (sh *serialhub) Register(port *serport) {
6976
sh.mu.Lock()
7077
//log.Print("Registering a port: ", p.portConf.Name)
71-
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 + "\"}")
78+
sh.OnRegister(port)
7279
sh.ports[port] = true
7380
sh.mu.Unlock()
7481
}
@@ -77,7 +84,7 @@ func (sh *serialhub) Register(port *serport) {
7784
func (sh *serialhub) Unregister(port *serport) {
7885
sh.mu.Lock()
7986
//log.Print("Unregistering a port: ", p.portConf.Name)
80-
sh.hub.broadcastSys <- []byte("{\"Cmd\":\"Close\",\"Desc\":\"Got unregister/close on port.\",\"Port\":\"" + port.portConf.Name + "\",\"Baud\":" + strconv.Itoa(port.portConf.Baud) + "}")
87+
sh.OnUnregister(port)
8188
delete(sh.ports, port)
8289
close(port.sendBuffered)
8390
close(port.sendNoBuf)
@@ -105,11 +112,9 @@ func (sp *SerialPortList) List() {
105112
sp.portsLock.Unlock()
106113

107114
if err != nil {
108-
//log.Println(err)
109-
sh.hub.broadcastSys <- []byte("Error creating json on port list " +
110-
err.Error())
115+
sp.OnErr("Error creating json on port list " + err.Error())
111116
} else {
112-
sh.hub.broadcastSys <- ls
117+
sp.OnList(ls)
113118
}
114119
}
115120

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

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

259-
func spErr(err string) {
265+
func (h *hub) spErr(err string) {
260266
//log.Println("Sending err back: ", err)
261267
//sh.hub.broadcastSys <- []byte(err)
262-
sh.hub.broadcastSys <- []byte("{\"Error\" : \"" + err + "\"}")
268+
h.broadcastSys <- []byte("{\"Error\" : \"" + err + "\"}")
263269
}
264270

265-
func spClose(portname string) {
266-
if myport, ok := sh.FindPortByName(portname); ok {
267-
sh.hub.broadcastSys <- []byte("Closing serial port " + portname)
271+
func (h *hub) spClose(portname string) {
272+
if myport, ok := h.serialHub.FindPortByName(portname); ok {
273+
h.broadcastSys <- []byte("Closing serial port " + portname)
268274
myport.Close()
269275
} else {
270-
spErr("We could not find the serial port " + portname + " that you were trying to close.")
276+
h.spErr("We could not find the serial port " + portname + " that you were trying to close.")
271277
}
272278
}
273279

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

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

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

‎serialport.go

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ type serport struct {
6161
BufferType string
6262
//bufferwatcher *BufferflowDummypause
6363
bufferwatcher Bufferflow
64+
65+
// TODO: to remove global
66+
OnMessage func([]byte)
67+
OnClose func(*serport)
6468
}
6569

6670
// SpPortMessage is the serial port message
@@ -89,7 +93,8 @@ func (p *serport) reader(buftype string) {
8993
if p.isClosing.Load() {
9094
strmsg := "Shutting down reader on " + p.portConf.Name
9195
log.Println(strmsg)
92-
h.broadcastSys <- []byte(strmsg)
96+
// h.broadcastSys <- ([]byte(strmsg)
97+
p.OnMessage([]byte(strmsg))
9398
break
9499
}
95100

@@ -143,15 +148,19 @@ func (p *serport) reader(buftype string) {
143148
if err == io.EOF || err == io.ErrUnexpectedEOF {
144149
// hit end of file
145150
log.Println("Hit end of file on serial port")
146-
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got EOF (End of File) on port which usually means another app other than Serial Port JSON Server is locking your port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
151+
// h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got EOF (End of File) on port which usually means another app other than Serial Port JSON Server is locking your port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
152+
p.OnMessage([]byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got EOF (End of File) on port which usually means another app other than Serial Port JSON Server is locking your port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}"))
147153

148154
}
149155

150156
if err != nil {
151157
log.Println(err)
152-
h.broadcastSys <- []byte("Error reading on " + p.portConf.Name + " " +
153-
err.Error() + " Closing port.")
154-
h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got error reading on port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
158+
// h.broadcastSys <- []byte("Error reading on " + p.portConf.Name + " " +
159+
// err.Error() + " Closing port.")
160+
p.OnMessage([]byte("Error reading on " + p.portConf.Name + " " + err.Error() + " Closing port."))
161+
162+
// h.broadcastSys <- []byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got error reading on port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}")
163+
p.OnMessage([]byte("{\"Cmd\":\"OpenFail\",\"Desc\":\"Got error reading on port. " + err.Error() + "\",\"Port\":\"" + p.portConf.Name + "\",\"Baud\":" + strconv.Itoa(p.portConf.Baud) + "}"))
155164
p.isClosingDueToError = true
156165
break
157166
}
@@ -209,7 +218,8 @@ func (p *serport) writerBuffered() {
209218
}
210219
msgstr := "writerBuffered just got closed. make sure you make a new one. port:" + p.portConf.Name
211220
log.Println(msgstr)
212-
h.broadcastSys <- []byte(msgstr)
221+
// h.broadcastSys <- []byte(msgstr)
222+
p.OnMessage([]byte(msgstr))
213223
}
214224

215225
// this method runs as its own thread because it's instantiated
@@ -230,15 +240,18 @@ func (p *serport) writerNoBuf() {
230240
if err != nil {
231241
errstr := "Error writing to " + p.portConf.Name + " " + err.Error() + " Closing port."
232242
log.Print(errstr)
233-
h.broadcastSys <- []byte(errstr)
243+
// h.broadcastSys <- []byte(errstr)
244+
p.OnMessage([]byte(errstr))
234245
break
235246
}
236247
}
237248
msgstr := "Shutting down writer on " + p.portConf.Name
238249
log.Println(msgstr)
239-
h.broadcastSys <- []byte(msgstr)
250+
// h.broadcastSys <- []byte(msgstr)
251+
p.OnMessage([]byte(msgstr))
240252
p.portIo.Close()
241-
serialPorts.List()
253+
// TODO: is this needed ?
254+
// serialPorts.List()
242255
}
243256

244257
// this method runs as its own thread because it's instantiated
@@ -270,7 +283,8 @@ func (p *serport) writerRaw() {
270283
}
271284
msgstr := "writerRaw just got closed. make sure you make a new one. port:" + p.portConf.Name
272285
log.Println(msgstr)
273-
h.broadcastSys <- []byte(msgstr)
286+
// h.broadcastSys <- []byte(msgstr)
287+
p.OnMessage([]byte(msgstr))
274288
}
275289

276290
func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
@@ -312,7 +326,16 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
312326
portConf: conf,
313327
portIo: sp,
314328
portName: portname,
315-
BufferType: buftype}
329+
BufferType: buftype,
330+
}
331+
332+
p.OnMessage = func(msg []byte) {
333+
h.broadcastSys <- msg
334+
}
335+
p.OnClose = func(port *serport) {
336+
h.serialPortList.MarkPortAsClosed(p.portName)
337+
h.serialPortList.List()
338+
}
316339

317340
var bw Bufferflow
318341

@@ -333,8 +356,8 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
333356
h.serialHub.Register(p)
334357
defer h.serialHub.Unregister(p)
335358

336-
serialPorts.MarkPortAsOpened(portname)
337-
serialPorts.List()
359+
h.serialPortList.MarkPortAsOpened(portname)
360+
h.serialPortList.List()
338361

339362
// this is internally buffered thread to not send to serial port if blocked
340363
go p.writerBuffered()
@@ -345,14 +368,13 @@ func (h *hub) spHandlerOpen(portname string, baud int, buftype string) {
345368

346369
p.reader(buftype)
347370

348-
serialPorts.List()
371+
h.serialPortList.List()
349372
}
350373

351374
func (p *serport) Close() {
352375
p.isClosing.Store(true)
353376

354377
p.bufferwatcher.Close()
355378
p.portIo.Close()
356-
serialPorts.MarkPortAsClosed(p.portName)
357-
serialPorts.List()
379+
p.OnClose(p)
358380
}

0 commit comments

Comments
 (0)
Please sign in to comment.