From 5d805a929cf384d59e49c54dbc209fa1e5e31b09 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Mon, 25 Dec 2023 14:52:10 +0100 Subject: [PATCH] all: use Device instead of Address in SetConnectHandler This makes it possible to discover services on a connected central while in peripheral mode, for example. --- adapter.go | 2 +- adapter_darwin.go | 6 +++--- adapter_linux.go | 4 ++-- adapter_ninafw.go | 4 ++-- adapter_nrf51.go | 12 +++++++++--- adapter_nrf528xx-full.go | 14 ++++++++++---- adapter_nrf528xx-peripheral.go | 11 +++++++++-- adapter_sd.go | 4 ++-- adapter_windows.go | 4 ++-- examples/circuitplay/main.go | 2 +- examples/stop-advertisement/main.go | 2 +- gap_darwin.go | 7 +++++-- gap_linux.go | 5 +++-- gap_nrf528xx-central.go | 5 ----- gap_sd.go | 15 +++++++++++++++ 15 files changed, 65 insertions(+), 32 deletions(-) create mode 100644 gap_sd.go diff --git a/adapter.go b/adapter.go index f3f4528..b18aa35 100644 --- a/adapter.go +++ b/adapter.go @@ -6,6 +6,6 @@ const debug = false // SetConnectHandler sets a handler function to be called whenever the adaptor connects // or disconnects. You must call this before you call adaptor.Connect() for centrals // or adaptor.Start() for peripherals in order for it to work. -func (a *Adapter) SetConnectHandler(c func(device Address, connected bool)) { +func (a *Adapter) SetConnectHandler(c func(device Device, connected bool)) { a.connectHandler = c } diff --git a/adapter_darwin.go b/adapter_darwin.go index 06c7ffc..292d168 100644 --- a/adapter_darwin.go +++ b/adapter_darwin.go @@ -24,7 +24,7 @@ type Adapter struct { // used to allow multiple callers to call Connect concurrently. connectMap sync.Map - connectHandler func(device Address, connected bool) + connectHandler func(device Device, connected bool) } // DefaultAdapter is the default adapter on the system. @@ -35,7 +35,7 @@ var DefaultAdapter = &Adapter{ pm: cbgo.NewPeripheralManager(nil), connectMap: sync.Map{}, - connectHandler: func(device Address, connected bool) { + connectHandler: func(device Device, connected bool) { return }, } @@ -106,7 +106,7 @@ func (cmd *centralManagerDelegate) DidDisconnectPeripheral(cmgr cbgo.CentralMana addr := Address{} uuid, _ := ParseUUID(id) addr.UUID = uuid - cmd.a.connectHandler(addr, false) + cmd.a.connectHandler(Device{Address: addr}, false) // like with DidConnectPeripheral, check if we have a chan allocated for this and send through the peripheral // this will only be true if the receiving side is still waiting for a connection to complete diff --git a/adapter_linux.go b/adapter_linux.go index 0ea9b45..8eac708 100644 --- a/adapter_linux.go +++ b/adapter_linux.go @@ -23,7 +23,7 @@ type Adapter struct { address string defaultAdvertisement *Advertisement - connectHandler func(device Address, connected bool) + connectHandler func(device Device, connected bool) } // DefaultAdapter is the default adapter on the system. On Linux, it is the @@ -32,7 +32,7 @@ type Adapter struct { // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{ id: defaultAdapter, - connectHandler: func(device Address, connected bool) { + connectHandler: func(device Device, connected bool) { }, } diff --git a/adapter_ninafw.go b/adapter_ninafw.go index 5ae4eec..c55e6c2 100644 --- a/adapter_ninafw.go +++ b/adapter_ninafw.go @@ -19,7 +19,7 @@ type Adapter struct { isDefault bool scanning bool - connectHandler func(device Address, connected bool) + connectHandler func(device Device, connected bool) connectedDevices []Device notificationsStarted bool @@ -30,7 +30,7 @@ type Adapter struct { // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{ isDefault: true, - connectHandler: func(device Address, connected bool) { + connectHandler: func(device Device, connected bool) { return }, connectedDevices: make([]Device, 0, maxConnections), diff --git a/adapter_nrf51.go b/adapter_nrf51.go index 9f38dcc..2208ecc 100644 --- a/adapter_nrf51.go +++ b/adapter_nrf51.go @@ -44,8 +44,11 @@ func handleEvent() { case C.BLE_GAP_EVT_CONNECTED: currentConnection.handle.Reg = uint16(gapEvent.conn_handle) connectEvent := gapEvent.params.unionfield_connected() - address := Address{makeMACAddress(connectEvent.peer_addr)} - DefaultAdapter.connectHandler(address, true) + device := Device{ + Address: Address{makeMACAddress(connectEvent.peer_addr)}, + connectionHandle: gapEvent.conn_handle, + } + DefaultAdapter.connectHandler(device, true) case C.BLE_GAP_EVT_DISCONNECTED: if defaultAdvertisement.isAdvertising.Get() != 0 { // The advertisement was running but was automatically stopped @@ -57,7 +60,10 @@ func handleEvent() { defaultAdvertisement.start() } currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID - DefaultAdapter.connectHandler(Address{}, false) + device := Device{ + connectionHandle: gapEvent.conn_handle, + } + DefaultAdapter.connectHandler(device, false) case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST: // Respond with the default PPCP connection parameters by passing // nil: diff --git a/adapter_nrf528xx-full.go b/adapter_nrf528xx-full.go index bd4f4c1..73b0171 100644 --- a/adapter_nrf528xx-full.go +++ b/adapter_nrf528xx-full.go @@ -25,21 +25,24 @@ func handleEvent() { switch id { case C.BLE_GAP_EVT_CONNECTED: connectEvent := gapEvent.params.unionfield_connected() - address := Address{makeMACAddress(connectEvent.peer_addr)} + device := Device{ + Address: Address{makeMACAddress(connectEvent.peer_addr)}, + connectionHandle: gapEvent.conn_handle, + } switch connectEvent.role { case C.BLE_GAP_ROLE_PERIPH: if debug { println("evt: connected in peripheral role") } currentConnection.handle.Reg = uint16(gapEvent.conn_handle) - DefaultAdapter.connectHandler(address, true) + DefaultAdapter.connectHandler(device, true) case C.BLE_GAP_ROLE_CENTRAL: if debug { println("evt: connected in central role") } connectionAttempt.connectionHandle = gapEvent.conn_handle connectionAttempt.state.Set(2) // connection was successful - DefaultAdapter.connectHandler(address, true) + DefaultAdapter.connectHandler(device, true) } case C.BLE_GAP_EVT_DISCONNECTED: if debug { @@ -62,7 +65,10 @@ func handleEvent() { // necessary. C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) } - DefaultAdapter.connectHandler(Address{}, false) + device := Device{ + connectionHandle: gapEvent.conn_handle, + } + DefaultAdapter.connectHandler(device, false) case C.BLE_GAP_EVT_CONN_PARAM_UPDATE: if debug { // Print connection parameters for easy debugging. diff --git a/adapter_nrf528xx-peripheral.go b/adapter_nrf528xx-peripheral.go index d26d392..00860df 100644 --- a/adapter_nrf528xx-peripheral.go +++ b/adapter_nrf528xx-peripheral.go @@ -29,7 +29,11 @@ func handleEvent() { } currentConnection.handle.Reg = uint16(gapEvent.conn_handle) connectEvent := gapEvent.params.unionfield_connected() - DefaultAdapter.connectHandler(Address{makeMACAddress(connectEvent.peer_addr)}, true) + device := Device{ + Address: Address{makeMACAddress(connectEvent.peer_addr)}, + connectionHandle: gapEvent.conn_handle, + } + DefaultAdapter.connectHandler(device, true) case C.BLE_GAP_EVT_DISCONNECTED: if debug { println("evt: disconnected") @@ -45,7 +49,10 @@ func handleEvent() { // necessary. C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT) } - DefaultAdapter.connectHandler(Address{}, false) + device := Device{ + connectionHandle: gapEvent.conn_handle, + } + DefaultAdapter.connectHandler(device, false) case C.BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: // We need to respond with sd_ble_gap_data_length_update. Setting // both parameters to nil will make sure we send the default values. diff --git a/adapter_sd.go b/adapter_sd.go index 44590ab..4037ed9 100644 --- a/adapter_sd.go +++ b/adapter_sd.go @@ -48,7 +48,7 @@ type Adapter struct { scanning bool charWriteHandlers []charWriteHandler - connectHandler func(device Address, connected bool) + connectHandler func(device Device, connected bool) } // DefaultAdapter is the default adapter on the current system. On Nordic chips, @@ -56,7 +56,7 @@ type Adapter struct { // // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{isDefault: true, - connectHandler: func(device Address, connected bool) { + connectHandler: func(device Device, connected bool) { return }} diff --git a/adapter_windows.go b/adapter_windows.go index 2211cab..747c973 100644 --- a/adapter_windows.go +++ b/adapter_windows.go @@ -12,14 +12,14 @@ import ( type Adapter struct { watcher *advertisement.BluetoothLEAdvertisementWatcher - connectHandler func(device Address, connected bool) + connectHandler func(device Device, connected bool) } // DefaultAdapter is the default adapter on the system. // // Make sure to call Enable() before using it to initialize the adapter. var DefaultAdapter = &Adapter{ - connectHandler: func(device Address, connected bool) { + connectHandler: func(device Device, connected bool) { return }, } diff --git a/examples/circuitplay/main.go b/examples/circuitplay/main.go index 213e676..a299fde 100644 --- a/examples/circuitplay/main.go +++ b/examples/circuitplay/main.go @@ -38,7 +38,7 @@ func main() { neo.Configure(machine.PinConfig{Mode: machine.PinOutput}) ws = ws2812.New(neo) - adapter.SetConnectHandler(func(d bluetooth.Address, c bool) { + adapter.SetConnectHandler(func(d bluetooth.Device, c bool) { connected = c if !connected && !disconnected { diff --git a/examples/stop-advertisement/main.go b/examples/stop-advertisement/main.go index ea60c6e..d5c5a9b 100644 --- a/examples/stop-advertisement/main.go +++ b/examples/stop-advertisement/main.go @@ -21,7 +21,7 @@ func main() { must("config adv", adv.Configure(bluetooth.AdvertisementOptions{ LocalName: "Go Bluetooth", })) - adapter.SetConnectHandler(func(device bluetooth.Address, connected bool) { + adapter.SetConnectHandler(func(device bluetooth.Device, connected bool) { if connected { println("connected, not advertising...") advState = false diff --git a/gap_darwin.go b/gap_darwin.go index 5b7fd5d..c87db05 100644 --- a/gap_darwin.go +++ b/gap_darwin.go @@ -85,6 +85,8 @@ func (a *Adapter) StopScan() error { // Device is a connection to a remote peripheral. type Device struct { + Address Address + *deviceInternal } @@ -137,7 +139,8 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err } d := Device{ - &deviceInternal{ + Address: address, + deviceInternal: &deviceInternal{ cm: a.cm, prph: p, servicesChan: make(chan error), @@ -148,7 +151,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err d.delegate = &peripheralDelegate{d: d} p.SetDelegate(d.delegate) - a.connectHandler(address, true) + a.connectHandler(d, true) return d, nil diff --git a/gap_linux.go b/gap_linux.go index c469708..2c77c36 100644 --- a/gap_linux.go +++ b/gap_linux.go @@ -292,9 +292,10 @@ func makeScanResult(props map[string]dbus.Variant) ScanResult { // Device is a connection to a remote peripheral. type Device struct { + Address Address // the MAC address of the device + device dbus.BusObject // bluez device interface adapter *Adapter // the adapter that was used to form this device connection - address Address // the address of the device } // Connect starts a connection attempt to the given peripheral device address. @@ -303,9 +304,9 @@ type Device struct { func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, error) { devicePath := dbus.ObjectPath(string(a.adapter.Path()) + "/dev_" + strings.Replace(address.MAC.String(), ":", "_", -1)) device := Device{ + Address: address, device: a.bus.Object("org.bluez", devicePath), adapter: a, - address: address, } // Already start watching for property changes. We do this before reading diff --git a/gap_nrf528xx-central.go b/gap_nrf528xx-central.go index 148a2cb..b451573 100644 --- a/gap_nrf528xx-central.go +++ b/gap_nrf528xx-central.go @@ -92,11 +92,6 @@ func (a *Adapter) StopScan() error { return nil } -// Device is a connection to a remote peripheral. -type Device struct { - connectionHandle C.uint16_t -} - // In-progress connection attempt. var connectionAttempt struct { state volatile.Register8 // 0 means unused, 1 means connecting, 2 means ready (connected or timeout) diff --git a/gap_sd.go b/gap_sd.go new file mode 100644 index 0000000..2147db4 --- /dev/null +++ b/gap_sd.go @@ -0,0 +1,15 @@ +//go:build softdevice + +package bluetooth + +/* +#include "ble_gap.h" +*/ +import "C" + +// Device is a connection to a remote peripheral or central. +type Device struct { + Address Address + + connectionHandle C.uint16_t +}