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:
parent
c9eafaff20
commit
5d805a929c
15 changed files with 65 additions and 32 deletions
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
}}
|
||||
|
||||
|
|
|
@ -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
|
||||
},
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
15
gap_sd.go
Normal 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
|
||||
}
|
Loading…
Reference in a new issue