Skip to content

Commit

Permalink
gap: add connection handler to be called on adapter connect/disconnect
Browse files Browse the repository at this point in the history
Signed-off-by: deadprogram <[email protected]>
  • Loading branch information
deadprogram authored Sep 10, 2020
1 parent 6d20fc6 commit 6dc1dff
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 15 deletions.
7 changes: 7 additions & 0 deletions adapter.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
5 changes: 5 additions & 0 deletions adapter_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
Expand Down
8 changes: 7 additions & 1 deletion adapter_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
2 changes: 2 additions & 0 deletions adapter_nrf51.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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:
Expand Down
3 changes: 3 additions & 0 deletions adapter_nrf528xx.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
7 changes: 6 additions & 1 deletion adapter_sd.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
8 changes: 7 additions & 1 deletion adapter_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
54 changes: 42 additions & 12 deletions examples/circuitplay/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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)
}
Expand All @@ -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[:])
}
2 changes: 2 additions & 0 deletions gap_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
3 changes: 3 additions & 0 deletions gap_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 6dc1dff

Please sign in to comment.