Skip to content

Commit

Permalink
softdevice: return an error on a connection timeout
Browse files Browse the repository at this point in the history
This makes sure an error is reported on a connection timeout. Previously
it would just block forever.
  • Loading branch information
aykevl authored and deadprogram committed Jan 12, 2024
1 parent d74f6a1 commit 3f8f8a6
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 12 deletions.
15 changes: 15 additions & 0 deletions adapter_nrf528xx-full.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,21 @@ func handleEvent() {
C.sd_ble_gap_phy_update(gapEvent.conn_handle, &phyUpdateRequest.peer_preferred_phys)
case C.BLE_GAP_EVT_PHY_UPDATE:
// ignore confirmation of phy successfully updated
case C.BLE_GAP_EVT_TIMEOUT:
timeoutEvt := gapEvent.params.unionfield_timeout()
switch timeoutEvt.src {
case C.BLE_GAP_TIMEOUT_SRC_CONN:
// Failed to connect to a peripheral.
if debug {
println("gap timeout: conn")
}
connectionAttempt.state.Set(3) // connection timed out
default:
// For example a scan timeout.
if debug {
println("gap timeout: other")
}
}
default:
if debug {
println("unknown GAP event:", id)
Expand Down
32 changes: 20 additions & 12 deletions gap_nrf528xx-central.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
import "C"

var errAlreadyConnecting = errors.New("bluetooth: already in a connection attempt")
var errConnectionTimeout = errors.New("bluetooth: timeout while connecting")

// Memory buffers needed by sd_ble_gap_scan_start.
var (
Expand Down Expand Up @@ -94,7 +95,7 @@ func (a *Adapter) StopScan() error {

// In-progress connection attempt.
var connectionAttempt struct {
state volatile.Register8 // 0 means unused, 1 means connecting, 2 means ready (connected or timeout)
state volatile.Register8 // 0 means unused, 1 means connecting, 2 means connected, 3 means timeout
connectionHandle C.uint16_t
}

Expand Down Expand Up @@ -165,18 +166,25 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
}

// Wait until the connection is established.
// TODO: use some sort of condition variable once the scheduler supports
// them.
for connectionAttempt.state.Get() != 2 {
arm.Asm("wfe")
for {
state := connectionAttempt.state.Get()
if state == 2 {
// Successfully connected.
connectionAttempt.state.Set(0)
connectionHandle := connectionAttempt.connectionHandle
return Device{
connectionHandle: connectionHandle,
}, nil
} else if state == 3 {
// Timeout while connecting.
connectionAttempt.state.Set(0)
return Device{}, errConnectionTimeout
} else {
// TODO: use some sort of condition variable once the scheduler
// supports them.
arm.Asm("wfe")
}
}
connectionHandle := connectionAttempt.connectionHandle
connectionAttempt.state.Set(0)

// Connection has been established.
return Device{
connectionHandle: connectionHandle,
}, nil
}

// Disconnect from the BLE device.
Expand Down

0 comments on commit 3f8f8a6

Please sign in to comment.