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:
+12
-11
@@ -11,14 +11,18 @@ import (
|
||||
// errUARTBusy is returned when the port is held for OTA (poller should not treat as unplug).
|
||||
var errUARTBusy = errors.New("uart busy (OTA in progress)")
|
||||
|
||||
// errOTAInProgress is returned when a second OTA upload is attempted while one is running.
|
||||
var errOTAInProgress = errors.New("OTA upload already in progress")
|
||||
|
||||
// managedSerial keeps the UART open and reconnects after I/O failures or unplug.
|
||||
type managedSerial struct {
|
||||
portName string
|
||||
baud int
|
||||
quiet bool
|
||||
|
||||
mu sync.Mutex
|
||||
sp *serialPort
|
||||
mu sync.Mutex
|
||||
sp *serialPort
|
||||
otaActive bool // UART held for firmware upload; poll/API must not interleave
|
||||
}
|
||||
|
||||
func newManagedSerial(portName string, baud int) *managedSerial {
|
||||
@@ -76,20 +80,17 @@ func (m *managedSerial) withPort(fn func(*serialPort) error) error {
|
||||
return m.withPortLocked(false, fn)
|
||||
}
|
||||
|
||||
// withPortPoll is like withPort but returns errUARTBusy instead of blocking during OTA.
|
||||
// withPortPoll is like withPort but returns errUARTBusy during OTA (no TryLock race).
|
||||
func (m *managedSerial) withPortPoll(fn func(*serialPort) error) error {
|
||||
return m.withPortLocked(true, fn)
|
||||
}
|
||||
|
||||
func (m *managedSerial) withPortLocked(try bool, fn func(*serialPort) error) error {
|
||||
if try {
|
||||
if !m.mu.TryLock() {
|
||||
return errUARTBusy
|
||||
}
|
||||
} else {
|
||||
m.mu.Lock()
|
||||
}
|
||||
func (m *managedSerial) withPortLocked(poll bool, fn func(*serialPort) error) error {
|
||||
m.mu.Lock()
|
||||
defer m.mu.Unlock()
|
||||
if m.otaActive {
|
||||
return errUARTBusy
|
||||
}
|
||||
|
||||
if m.sp == nil {
|
||||
if err := m.openLocked(); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user