Skip to content

Commit 58cefb4

Browse files
committed
MTU exchange
1 parent 8503b6b commit 58cefb4

7 files changed

+118
-7
lines changed

adapter_nrf528xx-full.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ import (
1717
"unsafe"
1818
)
1919

20+
// TODO: @rdnt cleanup
21+
//var (
22+
// dataLenParams = &C.ble_gap_data_length_params_t{}
23+
// dataLenLimitation = &C.ble_gap_data_length_limitation_t{}
24+
//)
25+
2026
func handleEvent() {
2127
id := eventBuf.header.evt_id
2228
switch {
@@ -63,7 +69,7 @@ func handleEvent() {
6369
// because it would need to be reconfigured as a non-connectable
6470
// advertisement. That's left as a future addition, if
6571
// necessary.
66-
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
72+
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, connCfgTag)
6773
}
6874
device := Device{
6975
connectionHandle: gapEvent.conn_handle,
@@ -159,7 +165,16 @@ func handleEvent() {
159165
case C.BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
160166
// This event is generated by some devices. While we could support
161167
// larger MTUs, this default MTU is supported everywhere.
162-
C.sd_ble_gatts_exchange_mtu_reply(gattsEvent.conn_handle, C.BLE_GATT_ATT_MTU_DEFAULT)
168+
rsp := gattsEvent.params.unionfield_exchange_mtu_request()
169+
effectiveMtu := min(DefaultAdapter.cfg.Gatt.AttMtu, uint16(rsp.client_rx_mtu))
170+
if debug {
171+
println("mtu exchange requested. self:", DefaultAdapter.cfg.Gatt.AttMtu, ", peer:", rsp.client_rx_mtu, ", effective:", effectiveMtu)
172+
}
173+
174+
var errCode = C.sd_ble_gatts_exchange_mtu_reply(gattsEvent.conn_handle, C.uint16_t(effectiveMtu))
175+
if debug {
176+
println("mtu exchange replied, err:", Error(errCode).Error())
177+
}
163178
case C.BLE_GATTS_EVT_HVN_TX_COMPLETE:
164179
// ignore confirmation of a notification successfully sent
165180
default:
@@ -255,6 +270,12 @@ func handleEvent() {
255270
}
256271
}
257272
}
273+
274+
case C.BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
275+
if debug {
276+
rsp := gattcEvent.params.unionfield_exchange_mtu_rsp()
277+
println("mtu exchanged, effective mtu:", rsp.server_rx_mtu)
278+
}
258279
default:
259280
if debug {
260281
println("unknown GATTC event:", id, id-C.BLE_GATTC_EVT_BASE)
@@ -266,3 +287,10 @@ func handleEvent() {
266287
}
267288
}
268289
}
290+
291+
func min(a, b uint16) uint16 {
292+
if a < b {
293+
return a
294+
}
295+
return b
296+
}

adapter_nrf528xx-peripheral.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func handleEvent() {
4747
// because it would need to be reconfigured as a non-connectable
4848
// advertisement. That's left as a future addition, if
4949
// necessary.
50-
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
50+
C.sd_ble_gap_adv_start(defaultAdvertisement.handle, connCfgTag)
5151
}
5252
device := Device{
5353
connectionHandle: gapEvent.conn_handle,

adapter_nrf528xx.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ var clockConfigXtal C.nrf_clock_lf_cfg_t = C.nrf_clock_lf_cfg_t{
3131
accuracy: C.NRF_CLOCK_LF_ACCURACY_250_PPM,
3232
}
3333

34+
const connCfgTag uint8 = 1
35+
3436
//go:extern __app_ram_base
3537
var appRAMBase [0]uint32
3638

@@ -47,6 +49,41 @@ func (a *Adapter) enable() error {
4749

4850
// Enable the BLE stack.
4951
appRAMBase := C.uint32_t(uintptr(unsafe.Pointer(&appRAMBase)))
52+
53+
bleCfg := C.ble_cfg_t{}
54+
55+
connCfg := bleCfg.unionfield_conn_cfg()
56+
connCfg.conn_cfg_tag = connCfgTag
57+
58+
gattCfg := connCfg.params.unionfield_gatt_conn_cfg()
59+
gattCfg.att_mtu = a.cfg.Gatt.AttMtu
60+
61+
errCode = C.sd_ble_cfg_set(C.uint32_t(C.BLE_CONN_CFG_GATT), &bleCfg, appRAMBase)
62+
if debug {
63+
println("gatt config updated, err:", Error(errCode).Error())
64+
}
65+
66+
l2capCfg := connCfg.params.unionfield_l2cap_conn_cfg()
67+
l2capCfg.rx_mps = a.cfg.L2cap.RxMps
68+
l2capCfg.tx_mps = a.cfg.L2cap.TxMps
69+
l2capCfg.rx_queue_size = a.cfg.L2cap.RxQueueSize
70+
l2capCfg.tx_queue_size = a.cfg.L2cap.TxQueueSize
71+
l2capCfg.ch_count = a.cfg.L2cap.ChCount // TODO: @rdnt max 18? 20 crashes
72+
73+
errCode = C.sd_ble_cfg_set(C.uint32_t(C.BLE_CONN_CFG_L2CAP), &bleCfg, appRAMBase)
74+
if debug {
75+
println("l2cap config updated, err:", Error(errCode).Error())
76+
}
77+
78+
gapCfg := connCfg.params.unionfield_gap_conn_cfg()
79+
gapCfg.conn_count = a.cfg.Gapp.ConnCount
80+
gapCfg.event_length = a.cfg.Gapp.EventLength
81+
82+
errCode = C.sd_ble_cfg_set(C.uint32_t(C.BLE_CONN_CFG_GAP), &bleCfg, appRAMBase)
83+
if debug {
84+
println("gap config updated, err:", Error(errCode).Error())
85+
}
86+
5087
errCode = C.sd_ble_enable(&appRAMBase)
5188
return makeError(errCode)
5289
}

adapter_sd.go

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ var currentConnection = volatileHandle{handle: volatile.Register16{C.BLE_CONN_HA
3333
// Globally allocated buffer for incoming SoftDevice events.
3434
var eventBuf struct {
3535
C.ble_evt_t
36-
buf [23]byte
36+
buf [247]byte
3737
}
3838

3939
func init() {
@@ -49,6 +49,8 @@ type Adapter struct {
4949
charWriteHandlers []charWriteHandler
5050

5151
connectHandler func(device Device, connected bool)
52+
53+
cfg Config
5254
}
5355

5456
// DefaultAdapter is the default adapter on the current system. On Nordic chips,
@@ -62,6 +64,39 @@ var DefaultAdapter = &Adapter{isDefault: true,
6264

6365
var eventBufLen C.uint16_t
6466

67+
type Config struct {
68+
Gapp GapConfig
69+
Gatt GattConfig
70+
L2cap L2capConfig
71+
}
72+
73+
type GapConfig struct {
74+
ConnCount uint8
75+
EventLength uint16
76+
}
77+
78+
type GattConfig struct {
79+
AttMtu uint16
80+
}
81+
82+
type L2capConfig struct {
83+
RxMps uint16
84+
TxMps uint16
85+
RxQueueSize uint8
86+
TxQueueSize uint8
87+
ChCount uint8
88+
}
89+
90+
func (a *Adapter) Configure(cfg Config) error {
91+
if cfg.Gatt.AttMtu < 23 || cfg.Gatt.AttMtu > 247 {
92+
cfg.Gatt.AttMtu = 23
93+
}
94+
95+
a.cfg = cfg
96+
97+
return nil
98+
}
99+
65100
// Enable configures the BLE stack. It must be called before any
66101
// Bluetooth-related calls (unless otherwise indicated).
67102
func (a *Adapter) Enable() error {
@@ -75,6 +110,10 @@ func (a *Adapter) Enable() error {
75110
eventBufLen = C.uint16_t(unsafe.Sizeof(eventBuf))
76111
errCode := C.sd_ble_evt_get((*C.uint8_t)(unsafe.Pointer(&eventBuf)), &eventBufLen)
77112
if errCode != 0 {
113+
// TODO: @rdnt remove
114+
//if debug {
115+
// println("sd_ble_evt_get failed, err:", Error(errCode).Error())
116+
//}
78117
// Possible error conditions:
79118
// * NRF_ERROR_NOT_FOUND: no events left, break
80119
// * NRF_ERROR_DATA_SIZE: retry with a bigger data buffer

gap_nrf528xx-advertisement.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func (a *Advertisement) Configure(options AdvertisementOptions) error {
7474
// Start advertisement. May only be called after it has been configured.
7575
func (a *Advertisement) Start() error {
7676
a.isAdvertising.Set(1)
77-
errCode := C.sd_ble_gap_adv_start(a.handle, C.BLE_CONN_CFG_TAG_DEFAULT)
77+
errCode := C.sd_ble_gap_adv_start(a.handle, connCfgTag)
7878
return makeError(errCode)
7979
}
8080

gap_nrf528xx-central.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
/*
1414
#include "ble_gap.h"
15+
#include "ble_gattc.h"
1516
*/
1617
import "C"
1718

@@ -162,7 +163,7 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
162163
connectionAttempt.state.Set(1)
163164

164165
// Start the connection attempt. We'll get a signal in the event handler.
165-
errCode := C.sd_ble_gap_connect(&addr, &scanParams, &connectionParams, C.BLE_CONN_CFG_TAG_DEFAULT)
166+
errCode := C.sd_ble_gap_connect(&addr, &scanParams, &connectionParams, connCfgTag)
166167
if errCode != 0 {
167168
connectionAttempt.state.Set(0)
168169
return Device{}, Error(errCode)
@@ -175,6 +176,12 @@ func (a *Adapter) Connect(address Address, params ConnectionParams) (Device, err
175176
// Successfully connected.
176177
connectionAttempt.state.Set(0)
177178
connectionHandle := connectionAttempt.connectionHandle
179+
180+
errCode = C.sd_ble_gattc_exchange_mtu_request(connectionHandle, C.uint16_t(a.cfg.Gatt.AttMtu))
181+
if debug {
182+
println("mtu requested, self:", a.cfg.Gatt.AttMtu, " err:", Error(errCode).Error())
183+
}
184+
178185
return Device{
179186
connectionHandle: connectionHandle,
180187
}, nil

gatts_sd.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (a *Adapter) AddService(service *Service) error {
6363
},
6464
init_len: C.uint16_t(len(char.Value)),
6565
init_offs: 0,
66-
max_len: 20, // This is a conservative maximum length.
66+
max_len: C.BLE_GATTS_FIX_ATTR_LEN_MAX,
6767
}
6868
if len(char.Value) != 0 {
6969
value.p_value = (*C.uint8_t)(unsafe.Pointer(&char.Value[0]))

0 commit comments

Comments
 (0)