prototooth/adapter_sd.go

100 lines
2.6 KiB
Go
Raw Normal View History

// +build softdevice
2019-06-02 17:12:36 +00:00
package bluetooth
import (
"device/nrf"
"errors"
"runtime/interrupt"
2019-06-02 17:12:36 +00:00
"unsafe"
)
var (
ErrNotDefaultAdapter = errors.New("bluetooth: not the default adapter")
)
2019-06-02 17:12:36 +00:00
var (
secModeOpen C.ble_gap_conn_sec_mode_t // No security is needed (aka open link).
2019-06-02 17:12:36 +00:00
defaultDeviceName = [6]byte{'T', 'i', 'n', 'y', 'G', 'o'}
)
// Globally allocated buffer for incoming SoftDevice events.
var eventBuf struct {
C.ble_evt_t
buf [23]byte
}
func init() {
secModeOpen.set_bitfield_sm(1)
secModeOpen.set_bitfield_lv(1)
}
// Adapter is a dummy adapter: it represents the connection to the (only)
// SoftDevice on the chip.
type Adapter struct {
isDefault bool
scanning bool
handler func(Event)
charWriteHandlers []charWriteHandler
2019-06-02 17:12:36 +00:00
}
// defaultAdapter is an adapter to the default Bluetooth stack on a given
2019-06-02 17:12:36 +00:00
// target.
var defaultAdapter = Adapter{isDefault: true}
// DefaultAdapter returns the default adapter on the current system. On Nordic
// chips, it will return the SoftDevice interface.
func DefaultAdapter() (*Adapter, error) {
return &defaultAdapter, nil
}
2019-06-02 17:12:36 +00:00
// 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
}
2019-06-02 17:12:36 +00:00
// Enable the IRQ that handles all events.
intr := interrupt.New(nrf.IRQ_SWI2, func(interrupt.Interrupt) {
for {
eventBufLen := uint16(unsafe.Sizeof(eventBuf))
errCode := C.sd_ble_evt_get((*uint8)(unsafe.Pointer(&eventBuf)), &eventBufLen)
if errCode != 0 {
// Possible error conditions:
// * NRF_ERROR_NOT_FOUND: no events left, break
// * NRF_ERROR_DATA_SIZE: retry with a bigger data buffer
// (currently not handled, TODO)
// * NRF_ERROR_INVALID_ADDR: pointer is not aligned, should
// not happen.
// In all cases, it's best to simply stop now.
break
}
handleEvent()
}
})
intr.Enable()
intr.SetPriority(192)
// Do more specific initialization of this SoftDevice (split out for nrf52*
// and nrf51 chips because of the different API).
err := a.enable()
if err != nil {
return err
2019-06-02 17:12:36 +00:00
}
errCode := C.sd_ble_gap_device_name_set(&secModeOpen, &defaultDeviceName[0], uint16(len(defaultDeviceName)))
2019-06-02 17:12:36 +00:00
if errCode != 0 {
return Error(errCode)
}
var gapConnParams C.ble_gap_conn_params_t
gapConnParams.min_conn_interval = C.BLE_GAP_CP_MIN_CONN_INTVL_MIN
gapConnParams.max_conn_interval = C.BLE_GAP_CP_MIN_CONN_INTVL_MAX
gapConnParams.slave_latency = 0
gapConnParams.conn_sup_timeout = C.BLE_GAP_CP_CONN_SUP_TIMEOUT_NONE
errCode = C.sd_ble_gap_ppcp_set(&gapConnParams)
return makeError(errCode)
2019-06-02 17:12:36 +00:00
}