gap: implement basic event handling: connect/disconnect

This commit is contained in:
Ayke van Laethem 2019-11-09 13:07:07 +01:00
parent 62131e4c55
commit 1d44126ac9
No known key found for this signature in database
GPG key ID: E97FF5335DFDFDED
4 changed files with 72 additions and 2 deletions

12
adapter.go Normal file
View file

@ -0,0 +1,12 @@
package bluetooth
// SetEventHandler sets the callback that gets called on incoming events.
//
// Warning: must only be called when the Bluetooth stack has not yet been
// initialized!
func (a *Adapter) SetEventHandler(handler func(Event)) {
a.handler = handler
}
// Event is a global Bluetooth stack event.
type Event interface{}

View file

@ -18,9 +18,14 @@ import "C"
import (
"device/arm"
"device/nrf"
"errors"
"unsafe"
)
var (
ErrNotDefaultAdapter = errors.New("bluetooth: not the default adapter")
)
//export assertHandler
func assertHandler() {
println("SoftDevice assert")
@ -52,15 +57,21 @@ func init() {
// Adapter is a dummy adapter: it represents the connection to the (only)
// SoftDevice on the chip.
type Adapter struct {
isDefault bool
handler func(Event)
}
// DefaultAdapter is an adapter to the default Bluetooth stack on a given
// target.
var DefaultAdapter = &Adapter{}
var DefaultAdapter = &Adapter{isDefault: true}
// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).
func (a *Adapter) Enable() error {
if !a.isDefault {
return ErrNotDefaultAdapter
}
// Enable the IRQ that handles all events.
arm.EnableIRQ(nrf.IRQ_SWI2)
arm.SetPriority(nrf.IRQ_SWI2, 192)
@ -96,7 +107,23 @@ func (a *Adapter) Enable() error {
}
func handleEvent() {
// TODO: do something with the events.
handler := DefaultAdapter.handler
if handler == nil {
return
}
id := eventBuf.header.evt_id
switch {
case id >= C.BLE_GAP_EVT_BASE && id <= C.BLE_GAP_EVT_LAST:
gapEvent := GAPEvent{
Connection: Connection(eventBuf.evt.unionfield_gap_evt().conn_handle),
}
switch id {
case C.BLE_GAP_EVT_CONNECTED:
handler(&ConnectEvent{GAPEvent: gapEvent})
case C.BLE_GAP_EVT_DISCONNECTED:
handler(&DisconnectEvent{GAPEvent: gapEvent})
}
}
}
//go:export SWI2_EGU2_IRQHandler

View file

@ -12,6 +12,7 @@ var advPayload = []byte("\x02\x01\x06" + "\x07\x09TinyGo")
func main() {
println("starting")
adapter := bluetooth.DefaultAdapter
adapter.SetEventHandler(handleBluetoothEvents)
must("enable SD", adapter.Enable())
adv := adapter.NewAdvertisement()
options := &bluetooth.AdvertiseOptions{
@ -45,3 +46,15 @@ func must(action string, err error) {
panic("failed to " + action + ": " + err.Error())
}
}
// handleBluetoothEvents prints BLE events as they happen.
func handleBluetoothEvents(evt bluetooth.Event) {
switch evt := evt.(type) {
case *bluetooth.ConnectEvent:
println("evt: connected", evt.Connection)
case *bluetooth.DisconnectEvent:
println("evt: disconnected", evt.Connection)
default:
println("evt: unknown")
}
}

18
gap.go
View file

@ -19,3 +19,21 @@ func NewAdvertiseInterval(intervalMillis uint32) AdvertiseInterval {
// Convert an interval to units of
return AdvertiseInterval(intervalMillis * 8 / 5)
}
// Connection is a numeric identifier that indicates a connection handle.
type Connection uint16
// GAPEvent is a base (embeddable) event for all GAP events.
type GAPEvent struct {
Connection Connection
}
// ConnectEvent occurs when a remote device connects to this device.
type ConnectEvent struct {
GAPEvent
}
// DisconnectEvent occurs when a remote device disconnects from this device.
type DisconnectEvent struct {
GAPEvent
}