From 3f8f8a66223cf3e664a1372b6c9c8fb6adc28c18 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Fri, 5 Jan 2024 16:33:51 +0100 Subject: [PATCH] softdevice: return an error on a connection timeout This makes sure an error is reported on a connection timeout. Previously it would just block forever. --- adapter_nrf528xx-full.go | 15 +++++++++++++++ gap_nrf528xx-central.go | 32 ++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 12 deletions(-) diff --git a/adapter_nrf528xx-full.go b/adapter_nrf528xx-full.go index 73b0171..bdeaacf 100644 --- a/adapter_nrf528xx-full.go +++ b/adapter_nrf528xx-full.go @@ -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) diff --git a/gap_nrf528xx-central.go b/gap_nrf528xx-central.go index 085e7d0..5ec2968 100644 --- a/gap_nrf528xx-central.go +++ b/gap_nrf528xx-central.go @@ -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 ( @@ -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 } @@ -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.