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.
This commit is contained in:
Ayke van Laethem 2023-12-25 14:52:10 +01:00 committed by Ron Evans
parent c9eafaff20
commit 5d805a929c
15 changed files with 65 additions and 32 deletions

View file

@ -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
}

View file

@ -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

View file

@ -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) {
},
}

View file

@ -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),

View file

@ -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:

View file

@ -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.

View file

@ -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.

View file

@ -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
}}

View file

@ -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
},
}

View file

@ -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 {

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

15
gap_sd.go Normal file
View file

@ -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
}