gap: add connection handler to be called on adapter connect/disconnect

Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
Ron Evans 2020-09-10 17:17:45 +02:00 committed by GitHub
parent 6d20fc6472
commit 6dc1dff711
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 84 additions and 15 deletions

View File

@ -2,3 +2,10 @@ package bluetooth
// Set this to true to print debug messages, for example for unknown events.
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 Addresser, connected bool)) {
a.connectHandler = c
}

View File

@ -19,6 +19,8 @@ type Adapter struct {
scanChan chan error
poweredChan chan error
connectChan chan cbgo.Peripheral
connectHandler func(device Addresser, connected bool)
}
// DefaultAdapter is the default adapter on the system.
@ -28,6 +30,9 @@ var DefaultAdapter = &Adapter{
cm: cbgo.NewCentralManager(nil),
pm: cbgo.NewPeripheralManager(nil),
connectChan: make(chan cbgo.Peripheral),
connectHandler: func(device Addresser, connected bool) {
return
},
}
// Enable configures the BLE stack. It must be called before any

View File

@ -15,13 +15,19 @@ type Adapter struct {
id string
cancelChan chan struct{}
defaultAdvertisement *Advertisement
connectHandler func(device Addresser, connected bool)
}
// DefaultAdapter is the default adapter on the system. On Linux, it is the
// first adapter available.
//
// Make sure to call Enable() before using it to initialize the adapter.
var DefaultAdapter = &Adapter{}
var DefaultAdapter = &Adapter{
connectHandler: func(device Addresser, connected bool) {
return
},
}
// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).

View File

@ -47,6 +47,7 @@ func handleEvent() {
switch id {
case C.BLE_GAP_EVT_CONNECTED:
currentConnection.Reg = gapEvent.conn_handle
DefaultAdapter.connectHandler(nil, true)
case C.BLE_GAP_EVT_DISCONNECTED:
if defaultAdvertisement.isAdvertising.Get() != 0 {
// The advertisement was running but was automatically stopped
@ -58,6 +59,7 @@ func handleEvent() {
defaultAdvertisement.start()
}
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
DefaultAdapter.connectHandler(nil, false)
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
// Respond with the default PPCP connection parameters by passing
// nil:

View File

@ -64,12 +64,14 @@ func handleEvent() {
println("evt: connected in peripheral role")
}
currentConnection.Reg = gapEvent.conn_handle
DefaultAdapter.connectHandler(nil, 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(nil, true)
}
case C.BLE_GAP_EVT_DISCONNECTED:
if debug {
@ -92,6 +94,7 @@ func handleEvent() {
// necessary.
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
}
DefaultAdapter.connectHandler(nil, false)
case C.BLE_GAP_EVT_ADV_REPORT:
advReport := gapEvent.params.unionfield_adv_report()
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {

View File

@ -39,13 +39,18 @@ type Adapter struct {
isDefault bool
scanning bool
charWriteHandlers []charWriteHandler
connectHandler func(device Addresser, connected bool)
}
// DefaultAdapter is the default adapter on the current system. On Nordic chips,
// it will return the SoftDevice interface.
//
// Make sure to call Enable() before using it to initialize the adapter.
var DefaultAdapter = &Adapter{isDefault: true}
var DefaultAdapter = &Adapter{isDefault: true,
connectHandler: func(device Addresser, connected bool) {
return
}}
// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).

View File

@ -7,12 +7,18 @@ import (
type Adapter struct {
watcher *winbt.IBluetoothLEAdvertisementWatcher
connectHandler func(device Addresser, 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{}
var DefaultAdapter = &Adapter{
connectHandler: func(device Addresser, connected bool) {
return
},
}
// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).

View File

@ -26,13 +26,31 @@ var (
var neo machine.Pin = machine.NEOPIXELS
var led machine.Pin = machine.LED
var ws ws2812.Device
var rg bool
var connected bool
var disconnected bool = true
func main() {
println("starting")
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
neo.Configure(machine.PinConfig{Mode: machine.PinOutput})
ws := ws2812.New(neo)
ws = ws2812.New(neo)
adapter.SetConnectHandler(func(d bluetooth.Addresser, c bool) {
connected = c
if !connected && !disconnected {
clearLEDS()
disconnected = true
}
if connected {
disconnected = false
}
})
must("enable BLE stack", adapter.Enable())
adv := adapter.DefaultAdvertisement()
@ -62,20 +80,11 @@ func main() {
},
}))
rg := false
for {
rg = !rg
for i := range leds {
rg = !rg
if rg {
leds[i] = color.RGBA{R: ledColor[0], G: ledColor[1], B: ledColor[2]}
} else {
leds[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00}
}
if connected {
writeLEDS()
}
ws.WriteColors(leds[:])
led.Set(rg)
time.Sleep(100 * time.Millisecond)
}
@ -86,3 +95,24 @@ func must(action string, err error) {
panic("failed to " + action + ": " + err.Error())
}
}
func writeLEDS() {
for i := range leds {
rg = !rg
if rg {
leds[i] = color.RGBA{R: ledColor[0], G: ledColor[1], B: ledColor[2]}
} else {
leds[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00}
}
}
ws.WriteColors(leds[:])
}
func clearLEDS() {
for i := range leds {
leds[i] = color.RGBA{R: 0x00, G: 0x00, B: 0x00}
}
ws.WriteColors(leds[:])
}

View File

@ -116,6 +116,8 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
d.delegate = &peripheralDelegate{d: d}
p.SetDelegate(d.delegate)
a.connectHandler(nil, true)
return d, nil
case <-time.NewTimer(10 * time.Second).C:
return nil, errors.New("timeout on Connect")

View File

@ -259,6 +259,9 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
}
}
// TODO: a proper async callback.
a.connectHandler(nil, true)
return &Device{
device: dev,
}, nil