gap: add connection handler to be called on adapter connect/disconnect
Signed-off-by: deadprogram <ron@hybridgroup.com>
This commit is contained in:
parent
6d20fc6472
commit
6dc1dff711
10 changed files with 84 additions and 15 deletions
|
@ -2,3 +2,10 @@ package bluetooth
|
||||||
|
|
||||||
// Set this to true to print debug messages, for example for unknown events.
|
// Set this to true to print debug messages, for example for unknown events.
|
||||||
const debug = false
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,8 @@ type Adapter struct {
|
||||||
scanChan chan error
|
scanChan chan error
|
||||||
poweredChan chan error
|
poweredChan chan error
|
||||||
connectChan chan cbgo.Peripheral
|
connectChan chan cbgo.Peripheral
|
||||||
|
|
||||||
|
connectHandler func(device Addresser, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the system.
|
// DefaultAdapter is the default adapter on the system.
|
||||||
|
@ -28,6 +30,9 @@ var DefaultAdapter = &Adapter{
|
||||||
cm: cbgo.NewCentralManager(nil),
|
cm: cbgo.NewCentralManager(nil),
|
||||||
pm: cbgo.NewPeripheralManager(nil),
|
pm: cbgo.NewPeripheralManager(nil),
|
||||||
connectChan: make(chan cbgo.Peripheral),
|
connectChan: make(chan cbgo.Peripheral),
|
||||||
|
connectHandler: func(device Addresser, connected bool) {
|
||||||
|
return
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enable configures the BLE stack. It must be called before any
|
// Enable configures the BLE stack. It must be called before any
|
||||||
|
|
|
@ -15,13 +15,19 @@ type Adapter struct {
|
||||||
id string
|
id string
|
||||||
cancelChan chan struct{}
|
cancelChan chan struct{}
|
||||||
defaultAdvertisement *Advertisement
|
defaultAdvertisement *Advertisement
|
||||||
|
|
||||||
|
connectHandler func(device Addresser, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the system. On Linux, it is the
|
// DefaultAdapter is the default adapter on the system. On Linux, it is the
|
||||||
// first adapter available.
|
// first adapter available.
|
||||||
//
|
//
|
||||||
// Make sure to call Enable() before using it to initialize the adapter.
|
// 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
|
// Enable configures the BLE stack. It must be called before any
|
||||||
// Bluetooth-related calls (unless otherwise indicated).
|
// Bluetooth-related calls (unless otherwise indicated).
|
||||||
|
|
|
@ -47,6 +47,7 @@ func handleEvent() {
|
||||||
switch id {
|
switch id {
|
||||||
case C.BLE_GAP_EVT_CONNECTED:
|
case C.BLE_GAP_EVT_CONNECTED:
|
||||||
currentConnection.Reg = gapEvent.conn_handle
|
currentConnection.Reg = gapEvent.conn_handle
|
||||||
|
DefaultAdapter.connectHandler(nil, true)
|
||||||
case C.BLE_GAP_EVT_DISCONNECTED:
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
||||||
if defaultAdvertisement.isAdvertising.Get() != 0 {
|
if defaultAdvertisement.isAdvertising.Get() != 0 {
|
||||||
// The advertisement was running but was automatically stopped
|
// The advertisement was running but was automatically stopped
|
||||||
|
@ -58,6 +59,7 @@ func handleEvent() {
|
||||||
defaultAdvertisement.start()
|
defaultAdvertisement.start()
|
||||||
}
|
}
|
||||||
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
|
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
|
||||||
|
DefaultAdapter.connectHandler(nil, false)
|
||||||
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
|
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
|
||||||
// Respond with the default PPCP connection parameters by passing
|
// Respond with the default PPCP connection parameters by passing
|
||||||
// nil:
|
// nil:
|
||||||
|
|
|
@ -64,12 +64,14 @@ func handleEvent() {
|
||||||
println("evt: connected in peripheral role")
|
println("evt: connected in peripheral role")
|
||||||
}
|
}
|
||||||
currentConnection.Reg = gapEvent.conn_handle
|
currentConnection.Reg = gapEvent.conn_handle
|
||||||
|
DefaultAdapter.connectHandler(nil, true)
|
||||||
case C.BLE_GAP_ROLE_CENTRAL:
|
case C.BLE_GAP_ROLE_CENTRAL:
|
||||||
if debug {
|
if debug {
|
||||||
println("evt: connected in central role")
|
println("evt: connected in central role")
|
||||||
}
|
}
|
||||||
connectionAttempt.connectionHandle = gapEvent.conn_handle
|
connectionAttempt.connectionHandle = gapEvent.conn_handle
|
||||||
connectionAttempt.state.Set(2) // connection was successful
|
connectionAttempt.state.Set(2) // connection was successful
|
||||||
|
DefaultAdapter.connectHandler(nil, true)
|
||||||
}
|
}
|
||||||
case C.BLE_GAP_EVT_DISCONNECTED:
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
||||||
if debug {
|
if debug {
|
||||||
|
@ -92,6 +94,7 @@ func handleEvent() {
|
||||||
// necessary.
|
// necessary.
|
||||||
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
|
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:
|
case C.BLE_GAP_EVT_ADV_REPORT:
|
||||||
advReport := gapEvent.params.unionfield_adv_report()
|
advReport := gapEvent.params.unionfield_adv_report()
|
||||||
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {
|
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {
|
||||||
|
|
|
@ -39,13 +39,18 @@ type Adapter struct {
|
||||||
isDefault bool
|
isDefault bool
|
||||||
scanning bool
|
scanning bool
|
||||||
charWriteHandlers []charWriteHandler
|
charWriteHandlers []charWriteHandler
|
||||||
|
|
||||||
|
connectHandler func(device Addresser, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the current system. On Nordic chips,
|
// DefaultAdapter is the default adapter on the current system. On Nordic chips,
|
||||||
// it will return the SoftDevice interface.
|
// it will return the SoftDevice interface.
|
||||||
//
|
//
|
||||||
// Make sure to call Enable() before using it to initialize the adapter.
|
// 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
|
// Enable configures the BLE stack. It must be called before any
|
||||||
// Bluetooth-related calls (unless otherwise indicated).
|
// Bluetooth-related calls (unless otherwise indicated).
|
||||||
|
|
|
@ -7,12 +7,18 @@ import (
|
||||||
|
|
||||||
type Adapter struct {
|
type Adapter struct {
|
||||||
watcher *winbt.IBluetoothLEAdvertisementWatcher
|
watcher *winbt.IBluetoothLEAdvertisementWatcher
|
||||||
|
|
||||||
|
connectHandler func(device Addresser, connected bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultAdapter is the default adapter on the system.
|
// DefaultAdapter is the default adapter on the system.
|
||||||
//
|
//
|
||||||
// Make sure to call Enable() before using it to initialize the adapter.
|
// 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
|
// Enable configures the BLE stack. It must be called before any
|
||||||
// Bluetooth-related calls (unless otherwise indicated).
|
// Bluetooth-related calls (unless otherwise indicated).
|
||||||
|
|
|
@ -26,13 +26,31 @@ var (
|
||||||
|
|
||||||
var neo machine.Pin = machine.NEOPIXELS
|
var neo machine.Pin = machine.NEOPIXELS
|
||||||
var led machine.Pin = machine.LED
|
var led machine.Pin = machine.LED
|
||||||
|
var ws ws2812.Device
|
||||||
|
var rg bool
|
||||||
|
|
||||||
|
var connected bool
|
||||||
|
var disconnected bool = true
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
println("starting")
|
println("starting")
|
||||||
|
|
||||||
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
led.Configure(machine.PinConfig{Mode: machine.PinOutput})
|
||||||
neo.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())
|
must("enable BLE stack", adapter.Enable())
|
||||||
adv := adapter.DefaultAdvertisement()
|
adv := adapter.DefaultAdvertisement()
|
||||||
|
@ -62,20 +80,11 @@ func main() {
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
rg := false
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
rg = !rg
|
rg = !rg
|
||||||
for i := range leds {
|
if connected {
|
||||||
rg = !rg
|
writeLEDS()
|
||||||
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[:])
|
|
||||||
led.Set(rg)
|
led.Set(rg)
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(100 * time.Millisecond)
|
||||||
}
|
}
|
||||||
|
@ -86,3 +95,24 @@ func must(action string, err error) {
|
||||||
panic("failed to " + action + ": " + 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[:])
|
||||||
|
}
|
||||||
|
|
|
@ -116,6 +116,8 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
|
||||||
d.delegate = &peripheralDelegate{d: d}
|
d.delegate = &peripheralDelegate{d: d}
|
||||||
p.SetDelegate(d.delegate)
|
p.SetDelegate(d.delegate)
|
||||||
|
|
||||||
|
a.connectHandler(nil, true)
|
||||||
|
|
||||||
return d, nil
|
return d, nil
|
||||||
case <-time.NewTimer(10 * time.Second).C:
|
case <-time.NewTimer(10 * time.Second).C:
|
||||||
return nil, errors.New("timeout on Connect")
|
return nil, errors.New("timeout on Connect")
|
||||||
|
|
|
@ -259,6 +259,9 @@ func (a *Adapter) Connect(address Addresser, params ConnectionParams) (*Device,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: a proper async callback.
|
||||||
|
a.connectHandler(nil, true)
|
||||||
|
|
||||||
return &Device{
|
return &Device{
|
||||||
device: dev,
|
device: dev,
|
||||||
}, nil
|
}, nil
|
||||||
|
|
Loading…
Reference in a new issue