Skip to content

Commit

Permalink
sd: update to prepare for changes in the TinyGo CGo implementation
Browse files Browse the repository at this point in the history
For details, see: tinygo-org/tinygo#3927

I ran the smoke tests and the binaries are exactly identical to what
they were before, so this change cannot have had an effect on these
smoke tests (which is expected, as this is mostly just changing some
types without changing the machine data type).
  • Loading branch information
aykevl authored and deadprogram committed Oct 5, 2023
1 parent d0c7887 commit 0124318
Show file tree
Hide file tree
Showing 14 changed files with 127 additions and 107 deletions.
6 changes: 3 additions & 3 deletions adapter_nrf51.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ func handleEvent() {
gapEvent := eventBuf.evt.unionfield_gap_evt()
switch id {
case C.BLE_GAP_EVT_CONNECTED:
currentConnection.Reg = gapEvent.conn_handle
currentConnection.handle.Reg = uint16(gapEvent.conn_handle)
DefaultAdapter.connectHandler(Address{}, true)
case C.BLE_GAP_EVT_DISCONNECTED:
if defaultAdvertisement.isAdvertising.Get() != 0 {
Expand All @@ -54,7 +54,7 @@ func handleEvent() {
// necessary.
defaultAdvertisement.start()
}
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID
DefaultAdapter.connectHandler(Address{}, false)
case C.BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
// Respond with the default PPCP connection parameters by passing
Expand Down Expand Up @@ -109,5 +109,5 @@ func (a *Adapter) Address() (MACAddress, error) {
if errCode != 0 {
return MACAddress{}, Error(errCode)
}
return MACAddress{MAC: addr.addr}, nil
return MACAddress{MAC: makeAddress(addr.addr)}, nil
}
10 changes: 5 additions & 5 deletions adapter_nrf528xx-full.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func handleEvent() {
if debug {
println("evt: connected in peripheral role")
}
currentConnection.Reg = gapEvent.conn_handle
currentConnection.handle.Reg = uint16(gapEvent.conn_handle)
DefaultAdapter.connectHandler(Address{}, true)
case C.BLE_GAP_ROLE_CENTRAL:
if debug {
Expand All @@ -46,11 +46,11 @@ func handleEvent() {
}
// Clean up state for this connection.
for i, cb := range gattcNotificationCallbacks {
if cb.connectionHandle == currentConnection.Reg {
if uint16(cb.connectionHandle) == currentConnection.handle.Reg {
gattcNotificationCallbacks[i].valueHandle = 0 // 0 means invalid
}
}
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID
// Auto-restart advertisement if needed.
if defaultAdvertisement.isAdvertising.Get() != 0 {
// The advertisement was running but was automatically stopped
Expand All @@ -64,7 +64,7 @@ func handleEvent() {
DefaultAdapter.connectHandler(Address{}, false)
case C.BLE_GAP_EVT_ADV_REPORT:
advReport := gapEvent.params.unionfield_adv_report()
if debug && &scanReportBuffer.data[0] != advReport.data.p_data {
if debug && &scanReportBuffer.data[0] != (*byte)(unsafe.Pointer(advReport.data.p_data)) {
// Sanity check.
panic("scanReportBuffer != advReport.p_data")
}
Expand All @@ -73,7 +73,7 @@ func handleEvent() {
scanReportBuffer.len = byte(advReport.data.len)
globalScanResult.RSSI = int16(advReport.rssi)
globalScanResult.Address = Address{
MACAddress{MAC: advReport.peer_addr.addr,
MACAddress{MAC: makeAddress(advReport.peer_addr.addr),
isRandom: advReport.peer_addr.bitfield_addr_type() != 0},
}
globalScanResult.AdvertisementPayload = &scanReportBuffer
Expand Down
4 changes: 2 additions & 2 deletions adapter_nrf528xx-peripheral.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,13 @@ func handleEvent() {
if debug {
println("evt: connected in peripheral role")
}
currentConnection.Reg = gapEvent.conn_handle
currentConnection.handle.Reg = uint16(gapEvent.conn_handle)
DefaultAdapter.connectHandler(Address{}, true)
case C.BLE_GAP_EVT_DISCONNECTED:
if debug {
println("evt: disconnected")
}
currentConnection.Reg = C.BLE_CONN_HANDLE_INVALID
currentConnection.handle.Reg = C.BLE_CONN_HANDLE_INVALID
// Auto-restart advertisement if needed.
if defaultAdvertisement.isAdvertising.Get() != 0 {
// The advertisement was running but was automatically stopped
Expand Down
4 changes: 2 additions & 2 deletions adapter_nrf528xx.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (a *Adapter) enable() error {
}

// Enable the BLE stack.
appRAMBase := uint32(uintptr(unsafe.Pointer(&appRAMBase)))
appRAMBase := C.uint32_t(uintptr(unsafe.Pointer(&appRAMBase)))
errCode = C.sd_ble_enable(&appRAMBase)
return makeError(errCode)
}
Expand All @@ -57,5 +57,5 @@ func (a *Adapter) Address() (MACAddress, error) {
if errCode != 0 {
return MACAddress{}, Error(errCode)
}
return MACAddress{MAC: addr.addr}, nil
return MACAddress{MAC: makeAddress(addr.addr)}, nil
}
52 changes: 45 additions & 7 deletions adapter_sd.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var (
)

// There can only be one connection at a time in the default configuration.
var currentConnection = volatile.Register16{C.BLE_CONN_HANDLE_INVALID}
var currentConnection = volatileHandle{handle: volatile.Register16{C.BLE_CONN_HANDLE_INVALID}}

// Globally allocated buffer for incoming SoftDevice events.
var eventBuf struct {
Expand Down Expand Up @@ -60,7 +60,7 @@ var DefaultAdapter = &Adapter{isDefault: true,
return
}}

var eventBufLen uint16
var eventBufLen C.uint16_t

// Enable configures the BLE stack. It must be called before any
// Bluetooth-related calls (unless otherwise indicated).
Expand All @@ -72,8 +72,8 @@ func (a *Adapter) Enable() error {
// 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)
eventBufLen = C.uint16_t(unsafe.Sizeof(eventBuf))
errCode := C.sd_ble_evt_get((*C.uint8_t)(unsafe.Pointer(&eventBuf)), &eventBufLen)
if errCode != 0 {
// Possible error conditions:
// * NRF_ERROR_NOT_FOUND: no events left, break
Expand All @@ -97,7 +97,7 @@ func (a *Adapter) Enable() error {
return err
}

errCode := C.sd_ble_gap_device_name_set(&secModeOpen, &defaultDeviceName[0], uint16(len(defaultDeviceName)))
errCode := C.sd_ble_gap_device_name_set(&secModeOpen, (*C.uint8_t)(unsafe.Pointer(&defaultDeviceName[0])), C.uint16_t(len(defaultDeviceName)))
if errCode != 0 {
return Error(errCode)
}
Expand All @@ -116,7 +116,7 @@ func (a *Adapter) Enable() error {
// play well with the SoftDevice. Restore interrupts to the previous state with
// RestoreInterrupts.
func DisableInterrupts() uintptr {
var is_nested_critical_region uint8
var is_nested_critical_region C.uint8_t
C.sd_nvic_critical_region_enter(&is_nested_critical_region)
return uintptr(is_nested_critical_region)
}
Expand All @@ -125,5 +125,43 @@ func DisableInterrupts() uintptr {
// DisableInterrupts. The mask parameter must be the value returned by
// DisableInterrupts.
func RestoreInterrupts(mask uintptr) {
C.sd_nvic_critical_region_exit(uint8(mask))
C.sd_nvic_critical_region_exit(C.uint8_t(mask))
}

// Wrapper for volatile.Register16 that uses C.uint16_t instead of uint16, for
// easier interoperability with C.
type volatileHandle struct {
handle volatile.Register16
}

func (a *volatileHandle) Set(handle C.uint16_t) {
a.handle.Set(uint16(handle))
}

func (a *volatileHandle) Get() C.uint16_t {
return C.uint16_t(a.handle.Get())
}

// Convert a SoftDevice MAC address into a Go MAC address.
func makeAddress(mac [6]C.uint8_t) MAC {
return MAC{
uint8(mac[0]),
uint8(mac[1]),
uint8(mac[2]),
uint8(mac[3]),
uint8(mac[4]),
uint8(mac[5]),
}
}

// Convert a Go MAC address into a SoftDevice MAC Address.
func makeSDAddress(mac MAC) [6]C.uint8_t {
return [6]C.uint8_t{
C.uint8_t(mac[0]),
C.uint8_t(mac[1]),
C.uint8_t(mac[2]),
C.uint8_t(mac[3]),
C.uint8_t(mac[4]),
C.uint8_t(mac[5]),
}
}
3 changes: 2 additions & 1 deletion error_sd.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

package bluetooth

// #include <stdint.h>
// #include "nrf_error.h"
// #include "nrf_error_sdm.h"
import "C"
Expand Down Expand Up @@ -83,7 +84,7 @@ func (e Error) Error() string {

// makeError returns an error (using the Error type) if the error code is
// non-zero, otherwise it returns nil. It is used with internal API calls.
func makeError(code uint32) error {
func makeError(code C.uint32_t) error {
if code != 0 {
return Error(code)
}
Expand Down
7 changes: 4 additions & 3 deletions gap_nrf51.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import "C"
import (
"runtime/volatile"
"time"
"unsafe"
)

// Address contains a Bluetooth MAC address.
Expand Down Expand Up @@ -52,7 +53,7 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error {
return errAdvertisementPacketTooBig
}

errCode := C.sd_ble_gap_adv_data_set(&payload.data[0], payload.len, nil, 0)
errCode := C.sd_ble_gap_adv_data_set((*C.uint8_t)(unsafe.Pointer(&payload.data[0])), C.uint8_t(payload.len), nil, 0)
a.interval = options.Interval
return makeError(errCode)
}
Expand All @@ -73,11 +74,11 @@ func (a *Advertisement) Stop() error {

// Low-level version of Start. Used to restart advertisement when a connection
// is lost.
func (a *Advertisement) start() uint32 {
func (a *Advertisement) start() C.uint32_t {
params := C.ble_gap_adv_params_t{
_type: C.BLE_GAP_ADV_TYPE_ADV_IND,
fp: C.BLE_GAP_ADV_FP_ANY,
interval: uint16(a.interval),
interval: C.uint16_t(a.interval),
timeout: 0, // no timeout
}
return C.sd_ble_gap_adv_start_noescape(params)
Expand Down
9 changes: 5 additions & 4 deletions gap_nrf528xx-advertisement.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package bluetooth
import (
"runtime/volatile"
"time"
"unsafe"
)

/*
Expand All @@ -19,7 +20,7 @@ type Address struct {

// Advertisement encapsulates a single advertisement instance.
type Advertisement struct {
handle uint8
handle C.uint8_t
isAdvertising volatile.Register8
payload rawAdvertisementPayload
}
Expand Down Expand Up @@ -57,14 +58,14 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error {

data := C.ble_gap_adv_data_t{}
data.adv_data = C.ble_data_t{
p_data: &a.payload.data[0],
len: uint16(a.payload.len),
p_data: (*C.uint8_t)(unsafe.Pointer(&a.payload.data[0])),
len: C.uint16_t(a.payload.len),
}
params := C.ble_gap_adv_params_t{
properties: C.ble_gap_adv_properties_t{
_type: C.BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
},
interval: uint32(options.Interval),
interval: C.uint32_t(options.Interval),
}
errCode := C.sd_ble_gap_adv_set_configure(&a.handle, &data, &params)
return makeError(errCode)
Expand Down
25 changes: 13 additions & 12 deletions gap_nrf528xx-central.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"errors"
"runtime/volatile"
"time"
"unsafe"
)

/*
Expand Down Expand Up @@ -40,12 +41,12 @@ func (a *Adapter) Scan(callback func(*Adapter, ScanResult)) error {
scanParams := C.ble_gap_scan_params_t{}
scanParams.set_bitfield_extended(0)
scanParams.set_bitfield_active(0)
scanParams.interval = uint16(NewDuration(40 * time.Millisecond))
scanParams.window = uint16(NewDuration(30 * time.Millisecond))
scanParams.interval = C.uint16_t(NewDuration(40 * time.Millisecond))
scanParams.window = C.uint16_t(NewDuration(30 * time.Millisecond))
scanParams.timeout = C.BLE_GAP_SCAN_TIMEOUT_UNLIMITED
scanReportBufferInfo := C.ble_data_t{
p_data: &scanReportBuffer.data[0],
len: uint16(len(scanReportBuffer.data)),
p_data: (*C.uint8_t)(unsafe.Pointer(&scanReportBuffer.data[0])),
len: C.uint16_t(len(scanReportBuffer.data)),
}
errCode := C.sd_ble_gap_scan_start(&scanParams, &scanReportBufferInfo)
if errCode != 0 {
Expand Down Expand Up @@ -93,13 +94,13 @@ func (a *Adapter) StopScan() error {

// Device is a connection to a remote peripheral.
type Device struct {
connectionHandle uint16
connectionHandle C.uint16_t
}

// In-progress connection attempt.
var connectionAttempt struct {
state volatile.Register8 // 0 means unused, 1 means connecting, 2 means ready (connected or timeout)
connectionHandle uint16
connectionHandle C.uint16_t
}

// Connect starts a connection attempt to the given peripheral device address.
Expand All @@ -111,7 +112,7 @@ var connectionAttempt struct {
func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, error) {
// Construct an address object as used in the SoftDevice.
var addr C.ble_gap_addr_t
addr.addr = address.MAC
addr.addr = makeSDAddress(address.MAC)
if address.IsRandom() {
switch address.MAC[5] >> 6 {
case 0b11:
Expand Down Expand Up @@ -142,13 +143,13 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (*Device, er
scanParams := C.ble_gap_scan_params_t{}
scanParams.set_bitfield_extended(0)
scanParams.set_bitfield_active(0)
scanParams.interval = uint16(NewDuration(40 * time.Millisecond))
scanParams.window = uint16(NewDuration(30 * time.Millisecond))
scanParams.timeout = uint16(params.ConnectionTimeout)
scanParams.interval = C.uint16_t(NewDuration(40 * time.Millisecond))
scanParams.window = C.uint16_t(NewDuration(30 * time.Millisecond))
scanParams.timeout = C.uint16_t(params.ConnectionTimeout)

connectionParams := C.ble_gap_conn_params_t{
min_conn_interval: uint16(params.MinInterval) / 2,
max_conn_interval: uint16(params.MaxInterval) / 2,
min_conn_interval: C.uint16_t(params.MinInterval) / 2,
max_conn_interval: C.uint16_t(params.MaxInterval) / 2,
slave_latency: 0, // mostly relevant to connected keyboards etc
conn_sup_timeout: 200, // 2 seconds (in 10ms units), the minimum recommended by Apple
}
Expand Down
Loading

0 comments on commit 0124318

Please sign in to comment.