bb8767730c
This SoftDevice is used by default on the BBC micro:bit v2 so it's a good idea to add support here. Unfortunately this SoftDevice does not support scanning and connecting to other devices. This means that I unfortunately had to duplicate the event handler. I managed to refactor most other code to avoid duplicating much more. (This is when macros would have been useful in Go...)
97 lines
3.2 KiB
Go
97 lines
3.2 KiB
Go
// +build softdevice,s113v7
|
|
|
|
package bluetooth
|
|
|
|
// This file implements the event handler for SoftDevices with only peripheral
|
|
// mode support. This includes the S113.
|
|
|
|
/*
|
|
// Define SoftDevice functions as regular function declarations (not inline
|
|
// static functions).
|
|
#define SVCALL_AS_NORMAL_FUNCTION
|
|
|
|
#include "nrf_sdm.h"
|
|
#include "nrf_nvic.h"
|
|
#include "ble.h"
|
|
#include "ble_gap.h"
|
|
*/
|
|
import "C"
|
|
|
|
import (
|
|
"unsafe"
|
|
)
|
|
|
|
func handleEvent() {
|
|
id := eventBuf.header.evt_id
|
|
switch {
|
|
case id >= C.BLE_GAP_EVT_BASE && id <= C.BLE_GAP_EVT_LAST:
|
|
gapEvent := eventBuf.evt.unionfield_gap_evt()
|
|
switch id {
|
|
case C.BLE_GAP_EVT_CONNECTED:
|
|
if debug {
|
|
println("evt: connected in peripheral role")
|
|
}
|
|
currentConnection.Reg = gapEvent.conn_handle
|
|
DefaultAdapter.connectHandler(nil, true)
|
|
case C.BLE_GAP_EVT_DISCONNECTED:
|
|
if debug {
|
|
println("evt: disconnected")
|
|
}
|
|
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
|
|
// Auto-restart advertisement if needed.
|
|
if defaultAdvertisement.isAdvertising.Get() != 0 {
|
|
// The advertisement was running but was automatically stopped
|
|
// by the connection event.
|
|
// Note that it cannot be restarted during connect like this,
|
|
// because it would need to be reconfigured as a non-connectable
|
|
// advertisement. That's left as a future addition, if
|
|
// necessary.
|
|
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
|
|
}
|
|
DefaultAdapter.connectHandler(nil, 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.
|
|
C.sd_ble_gap_data_length_update(gapEvent.conn_handle, nil, nil)
|
|
default:
|
|
if debug {
|
|
println("unknown GAP event:", id)
|
|
}
|
|
}
|
|
case id >= C.BLE_GATTS_EVT_BASE && id <= C.BLE_GATTS_EVT_LAST:
|
|
gattsEvent := eventBuf.evt.unionfield_gatts_evt()
|
|
switch id {
|
|
case C.BLE_GATTS_EVT_WRITE:
|
|
writeEvent := gattsEvent.params.unionfield_write()
|
|
len := writeEvent.len - writeEvent.offset
|
|
data := (*[255]byte)(unsafe.Pointer(&writeEvent.data[0]))[:len:len]
|
|
handler := DefaultAdapter.getCharWriteHandler(writeEvent.handle)
|
|
if handler != nil {
|
|
handler.callback(Connection(gattsEvent.conn_handle), int(writeEvent.offset), data)
|
|
}
|
|
case C.BLE_GATTS_EVT_SYS_ATTR_MISSING:
|
|
// This event is generated when reading the Generic Attribute
|
|
// service. It appears to be necessary for bonded devices.
|
|
// From the docs:
|
|
// > If the pointer is NULL, the system attribute info is
|
|
// > initialized, assuming that the application does not have any
|
|
// > previously saved system attribute data for this device.
|
|
// Maybe we should look at the error, but as there's not really a
|
|
// way to handle it, ignore it.
|
|
C.sd_ble_gatts_sys_attr_set(gattsEvent.conn_handle, nil, 0, 0)
|
|
case C.BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
|
|
// This event is generated by some devices. While we could support
|
|
// larger MTUs, this default MTU is supported everywhere.
|
|
C.sd_ble_gatts_exchange_mtu_reply(gattsEvent.conn_handle, C.BLE_GATT_ATT_MTU_DEFAULT)
|
|
default:
|
|
if debug {
|
|
println("unknown GATTS event:", id, id-C.BLE_GATTS_EVT_BASE)
|
|
}
|
|
}
|
|
default:
|
|
if debug {
|
|
println("unknown event:", id)
|
|
}
|
|
}
|
|
}
|