Add dynamic UART/BLE host connect for serve, dashboard, and WS.
Serve starts without a required port; REST/WS/UI can scan and switch transports, with BLE live ticks and UART-only OTA. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+51
-12
@@ -37,15 +37,6 @@ func openBLE(name string, settle time.Duration) (*bleLink, error) {
|
||||
return nil, fmt.Errorf("enable bluetooth adapter: %w (check BlueZ / permissions)", err)
|
||||
}
|
||||
|
||||
svcUUID, err := bluetooth.ParseUUID(bleServiceUUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chrUUID, err := bluetooth.ParseUUID(bleCharUUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Printf("BLE scanning for %q…", name)
|
||||
var foundAddr bluetooth.Address
|
||||
var found bool
|
||||
@@ -53,7 +44,7 @@ func openBLE(name string, settle time.Duration) (*bleLink, error) {
|
||||
time.Sleep(15 * time.Second)
|
||||
_ = adapter.StopScan()
|
||||
}()
|
||||
err = adapter.Scan(func(a *bluetooth.Adapter, result bluetooth.ScanResult) {
|
||||
err := adapter.Scan(func(a *bluetooth.Adapter, result bluetooth.ScanResult) {
|
||||
if result.LocalName() != name {
|
||||
return
|
||||
}
|
||||
@@ -67,9 +58,57 @@ func openBLE(name string, settle time.Duration) (*bleLink, error) {
|
||||
if !found {
|
||||
return nil, fmt.Errorf("device %q not found (check DIP8=BLE and advertising)", name)
|
||||
}
|
||||
return connectBLEDevice(foundAddr, settle)
|
||||
}
|
||||
|
||||
log.Printf("BLE connecting…")
|
||||
device, err := adapter.Connect(foundAddr, bluetooth.ConnectionParams{})
|
||||
func openBLEAddress(addrStr string, settle time.Duration) (*bleLink, error) {
|
||||
adapter := bluetooth.DefaultAdapter
|
||||
if err := adapter.Enable(); err != nil {
|
||||
return nil, fmt.Errorf("enable bluetooth adapter: %w (check BlueZ / permissions)", err)
|
||||
}
|
||||
if mac, err := bluetooth.ParseMAC(addrStr); err == nil {
|
||||
var addr bluetooth.Address
|
||||
addr.Set(mac.String())
|
||||
return connectBLEDevice(addr, settle)
|
||||
}
|
||||
// Fallback: scan until address string matches
|
||||
log.Printf("BLE resolving address %s via scan…", addrStr)
|
||||
var foundAddr bluetooth.Address
|
||||
var found bool
|
||||
go func() {
|
||||
time.Sleep(15 * time.Second)
|
||||
_ = adapter.StopScan()
|
||||
}()
|
||||
err := adapter.Scan(func(a *bluetooth.Adapter, result bluetooth.ScanResult) {
|
||||
if result.Address.String() != addrStr {
|
||||
return
|
||||
}
|
||||
foundAddr = result.Address
|
||||
found = true
|
||||
_ = a.StopScan()
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("scan for address: %w", err)
|
||||
}
|
||||
if !found {
|
||||
return nil, fmt.Errorf("BLE address %s not found", addrStr)
|
||||
}
|
||||
return connectBLEDevice(foundAddr, settle)
|
||||
}
|
||||
|
||||
func connectBLEDevice(addr bluetooth.Address, settle time.Duration) (*bleLink, error) {
|
||||
svcUUID, err := bluetooth.ParseUUID(bleServiceUUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
chrUUID, err := bluetooth.ParseUUID(bleCharUUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
adapter := bluetooth.DefaultAdapter
|
||||
log.Printf("BLE connecting to %s…", addr.String())
|
||||
device, err := adapter.Connect(addr, bluetooth.ConnectionParams{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("connect: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user