Send large BLE host frames across multiple notifies.
Prefer ATT MTU 517 and chunk oversized responses so CLIENT_INFO/BATTERY work with many pods; reset the goTool parser after timeouts so partial frames do not poison the next exchange. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -22,6 +22,7 @@ type bleLink struct {
|
||||
device bluetooth.Device
|
||||
char bluetooth.DeviceCharacteristic
|
||||
mu sync.Mutex
|
||||
parserMu sync.Mutex
|
||||
parser *uartframe.Parser
|
||||
respCh chan []byte
|
||||
streamCh chan []byte
|
||||
@@ -162,6 +163,8 @@ func connectBLEDevice(addr bluetooth.Address, settle time.Duration) (*bleLink, e
|
||||
}
|
||||
|
||||
func (b *bleLink) onNotify(buf []byte) {
|
||||
b.parserMu.Lock()
|
||||
defer b.parserMu.Unlock()
|
||||
for _, by := range buf {
|
||||
payload, ok, err := b.parser.Feed(by)
|
||||
if err != nil || !ok {
|
||||
@@ -195,6 +198,12 @@ func (b *bleLink) onNotify(buf []byte) {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *bleLink) resetParser() {
|
||||
b.parserMu.Lock()
|
||||
b.parser = uartframe.NewParser()
|
||||
b.parserMu.Unlock()
|
||||
}
|
||||
|
||||
func (b *bleLink) Close() error {
|
||||
return b.device.Disconnect()
|
||||
}
|
||||
@@ -243,6 +252,9 @@ sent:
|
||||
for {
|
||||
remain := time.Until(deadline)
|
||||
if remain <= 0 {
|
||||
// Drop a half-parsed frame (e.g. aborted multi-notify) so the next
|
||||
// exchange does not treat a new 0xAA as payload data.
|
||||
b.resetParser()
|
||||
return nil, fmt.Errorf("BLE read timeout for %s (check DIP8=BLE / -ble)", cmdName)
|
||||
}
|
||||
timer := time.NewTimer(remain)
|
||||
@@ -264,6 +276,7 @@ sent:
|
||||
}
|
||||
return resp, nil
|
||||
case <-timer.C:
|
||||
b.resetParser()
|
||||
return nil, fmt.Errorf("BLE read timeout for %s (check DIP8=BLE / -ble)", cmdName)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user