forked from johnlauer/serial-port-json-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hub.go
169 lines (146 loc) · 4.05 KB
/
hub.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
package main
import (
"log"
"strconv"
"strings"
)
type hub struct {
// Registered connections.
connections map[*connection]bool
// Inbound messages from the connections.
broadcast chan []byte
// Inbound messages from the system
broadcastSys chan []byte
// Register requests from the connections.
register chan *connection
// Unregister requests from connections.
unregister chan *connection
}
var h = hub{
broadcast: make(chan []byte),
broadcastSys: make(chan []byte),
register: make(chan *connection),
unregister: make(chan *connection),
connections: make(map[*connection]bool),
}
func (h *hub) run() {
for {
select {
case c := <-h.register:
h.connections[c] = true
// send supported commands
c.send <- []byte("{\"Version\" : \"" + version + "\"} ")
c.send <- []byte("{\"Commands\" : [\"list\", \"open [portName] [baud] [bufferAlgorithm (optional)]\", \"send [portName] [cmd]\", \"sendnobuf [portName] [cmd]\", \"close [portName]\", \"bufferalgorithms\", \"baudrates\"]} ")
case c := <-h.unregister:
delete(h.connections, c)
// put close in func cuz it was creating panics and want
// to isolate
func() {
// this method can panic if websocket gets disconnected
// from users browser and we see we need to unregister a couple
// of times, i.e. perhaps from incoming data from serial triggering
// an unregister. (NOT 100% sure why seeing c.send be closed twice here)
defer func() {
if e := recover(); e != nil {
log.Println("Got panic: ", e)
}
}()
close(c.send)
}()
case m := <-h.broadcast:
//log.Print("Got a broadcast")
//log.Print(m)
//log.Print(len(m))
if len(m) > 0 {
//log.Print(string(m))
//log.Print(h.broadcast)
checkCmd(m)
//log.Print("-----")
for c := range h.connections {
select {
case c.send <- m:
//log.Print("did broadcast to ")
//log.Print(c.ws.RemoteAddr())
//c.send <- []byte("hello world")
default:
delete(h.connections, c)
close(c.send)
go c.ws.Close()
}
}
}
case m := <-h.broadcastSys:
log.Printf("Got a system broadcast: %v\n", string(m))
//log.Print(string(m))
//log.Print("-----")
for c := range h.connections {
select {
case c.send <- m:
//log.Print("did broadcast to ")
//log.Print(c.ws.RemoteAddr())
//c.send <- []byte("hello world")
default:
delete(h.connections, c)
close(c.send)
go c.ws.Close()
}
}
}
}
}
func checkCmd(m []byte) {
//log.Print("Inside checkCmd")
s := string(m[:])
log.Print(s)
sl := strings.ToLower(s)
if strings.HasPrefix(sl, "open") {
args := strings.Split(s, " ")
if len(args) < 3 {
go 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")
return
}
baudStr := strings.Replace(args[2], "\n", "", -1)
baud, err := strconv.Atoi(baudStr)
if err != nil {
go spErr("Problem converting baud rate " + args[2])
return
}
// pass in buffer type now as string. if user does not
// ask for a buffer type pass in empty string
bufferAlgorithm := ""
if len(args) > 3 {
// cool. we got a buffer type request
buftype := strings.Replace(args[3], "\n", "", -1)
bufferAlgorithm = buftype
}
go spHandlerOpen(args[1], baud, bufferAlgorithm)
} else if strings.HasPrefix(sl, "close") {
args := strings.Split(s, " ")
if len(args) > 1 {
go spClose(args[1])
} else {
go spErr("You did not specify a port to close")
}
} else if strings.HasPrefix(sl, "sendjson") {
// will catch sendjson
go spWriteJson(s)
} else if strings.HasPrefix(sl, "send") {
// will catch send and sendnobuf
//args := strings.Split(s, "send ")
go spWrite(s)
} else if strings.HasPrefix(sl, "list") {
go spList()
//go getListViaWmiPnpEntity()
} else if strings.HasPrefix(sl, "bufferalgorithm") {
go spBufferAlgorithms()
} else if strings.HasPrefix(sl, "baudrate") {
go spBaudRates()
} else {
go spErr("Could not understand command.")
}
//log.Print("Done with checkCmd")
}