Fix web OTA upload and isolate OTA sessions across firmware and goTool.
Split ESP-NOW into core/master/slave modules, block non-OTA UART traffic during updates, and hold the host serial port exclusively so dashboard polling cannot interleave with firmware uploads. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+37
-19
@@ -101,7 +101,7 @@ func (h *wsHub) setState(st DashboardState) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,7 @@ func (h *wsHub) register(c *websocket.Conn) {
|
||||
h.mu.Unlock()
|
||||
|
||||
if data, err := json.Marshal(snap); err == nil {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -122,6 +122,30 @@ func (h *wsHub) unregister(c *websocket.Conn) {
|
||||
h.mu.Unlock()
|
||||
}
|
||||
|
||||
// writeJSON sends to one client; removes it on error or panic (closed connection).
|
||||
func (h *wsHub) writeJSON(c *websocket.Conn, data []byte) {
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
h.unregister(c)
|
||||
}
|
||||
}()
|
||||
if err := c.WriteMessage(websocket.TextMessage, data); err != nil {
|
||||
h.unregister(c)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *wsHub) broadcastJSON(data []byte) {
|
||||
h.mu.RLock()
|
||||
conns := make([]*websocket.Conn, 0, len(h.clients))
|
||||
for c := range h.clients {
|
||||
conns = append(conns, c)
|
||||
}
|
||||
h.mu.RUnlock()
|
||||
for _, c := range conns {
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
func applyAccelSamples(clients []ClientView, samples []*pb.AccelSample) []ClientView {
|
||||
if len(samples) == 0 {
|
||||
return clients
|
||||
@@ -338,7 +362,7 @@ func (h *wsHub) patchClientAccelStream(clientID uint32, enabled bool) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +421,7 @@ func (h *wsHub) patchLiveStream(enabled bool) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -430,7 +454,7 @@ func (h *wsHub) patchClientTapNotify(clientID uint32, single, doubleTap, triple
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -455,7 +479,7 @@ func (h *wsHub) mergeAccel(samples []*pb.AccelSample) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,25 +503,16 @@ func (h *wsHub) mergeTap(events []*pb.TapEvent) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
func (h *wsHub) broadcastRaw(v any) {
|
||||
h.mu.RLock()
|
||||
conns := make([]*websocket.Conn, 0, len(h.clients))
|
||||
for c := range h.clients {
|
||||
conns = append(conns, c)
|
||||
}
|
||||
h.mu.RUnlock()
|
||||
|
||||
data, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
}
|
||||
h.broadcastJSON(data)
|
||||
}
|
||||
|
||||
func pollDashboard(link *managedSerial, portName string, last *DashboardState, streamCtl *accelStreamCtl, tapCtl *tapNotifyCtl) DashboardState {
|
||||
@@ -575,6 +590,9 @@ func pollDashboard(link *managedSerial, portName string, last *DashboardState, s
|
||||
|
||||
func applyBatteryToState(link *managedSerial, st *DashboardState) {
|
||||
bat, err := link.BatteryStatusPoll(&pb.BatteryStatusRequest{AllClients: true})
|
||||
if errors.Is(err, errUARTBusy) {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
log.Printf("battery poll: %v", err)
|
||||
return
|
||||
@@ -602,7 +620,7 @@ func (h *wsHub) mergeBattery(samples []batterySampleJSON) {
|
||||
return
|
||||
}
|
||||
for _, c := range conns {
|
||||
_ = c.WriteMessage(websocket.TextMessage, data)
|
||||
h.writeJSON(c, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -619,7 +637,7 @@ func runBatteryPoller(link *managedSerial, hub *wsHub, interval time.Duration, s
|
||||
continue
|
||||
}
|
||||
bat, err := link.BatteryStatusPoll(&pb.BatteryStatusRequest{AllClients: true})
|
||||
if err != nil {
|
||||
if errors.Is(err, errUARTBusy) || err != nil {
|
||||
continue
|
||||
}
|
||||
hub.mergeBattery(batterySamplesFromPB(bat.GetSamples()))
|
||||
|
||||
Reference in New Issue
Block a user