Skip to content

Commit b08b026

Browse files
committed
back to working; check for extended advertising support
1 parent f6869c6 commit b08b026

5 files changed

Lines changed: 62 additions & 43 deletions

File tree

devices/ble_hci/common-hal/_bleio/Adapter.c

Lines changed: 28 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -68,26 +68,6 @@
6868
#define BLE_SLAVE_LATENCY 0
6969
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
7070

71-
#ifndef BLEIO_VS_UUID_COUNT
72-
#define BLEIO_VS_UUID_COUNT 75
73-
#endif
74-
75-
#ifndef BLEIO_HVN_TX_QUEUE_SIZE
76-
#define BLEIO_HVN_TX_QUEUE_SIZE 9
77-
#endif
78-
79-
#ifndef BLEIO_CENTRAL_ROLE_COUNT
80-
#define BLEIO_CENTRAL_ROLE_COUNT 4
81-
#endif
82-
83-
#ifndef BLEIO_PERIPH_ROLE_COUNT
84-
#define BLEIO_PERIPH_ROLE_COUNT 4
85-
#endif
86-
87-
#ifndef BLEIO_ATTR_TAB_SIZE
88-
#define BLEIO_ATTR_TAB_SIZE (BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 5)
89-
#endif
90-
9171
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
9272

9373
// STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) {
@@ -193,6 +173,11 @@ STATIC void bleio_adapter_reset_name(bleio_adapter_obj_t *self) {
193173
// Get various values and limits set by the adapter.
194174
STATIC void bleio_adapter_get_info(bleio_adapter_obj_t *self) {
195175

176+
// Get supported features.
177+
if (hci_le_read_local_supported_features(self->features) != HCI_OK) {
178+
mp_raise_bleio_BluetoothError(translate("Could not read BLE features"));
179+
}
180+
196181
// Get ACL buffer info.
197182
uint16_t le_max_len;
198183
uint8_t le_max_num;
@@ -212,26 +197,28 @@ STATIC void bleio_adapter_get_info(bleio_adapter_obj_t *self) {
212197
self->max_acl_num_buffers = acl_max_num;
213198
}
214199

215-
// Get max advertising length.
216-
uint16_t max_adv_data_len;
217-
if (hci_le_read_maximum_advertising_data_length(&max_adv_data_len) != HCI_OK) {
218-
mp_raise_bleio_BluetoothError(translate("Could not get max advertising length"));
200+
// Get max advertising length if extended advertising is supported.
201+
if (BT_FEAT_LE_EXT_ADV(self->features)) {
202+
uint16_t max_adv_data_len;
203+
if (hci_le_read_maximum_advertising_data_length(&max_adv_data_len) != HCI_OK) {
204+
mp_raise_bleio_BluetoothError(translate("Could not get max advertising length"));
205+
}
206+
self->max_adv_data_len = max_adv_data_len;
207+
} else {
208+
self->max_adv_data_len = 31;
219209
}
220-
self->max_adv_data_len = max_adv_data_len;
221210
}
222211

223212
void common_hal_bleio_adapter_hci_uart_init(bleio_adapter_obj_t *self, busio_uart_obj_t *uart, digitalio_digitalinout_obj_t *rts, digitalio_digitalinout_obj_t *cts) {
224213
self->hci_uart = uart;
225214
self->rts_digitalinout = rts;
226215
self->cts_digitalinout = cts;
216+
217+
// Advertising-related fields are initialized by common_hal_bleio_adapter_set_enabled().
227218
self->enabled = false;
228-
self->now_advertising = false;
229-
self->circuitpython_advertising = false;
230-
self->extended_advertising = false;
231-
self->advertising_timeout_msecs = 0;
232219

220+
common_hal_bleio_adapter_set_enabled(self, true);
233221
bleio_adapter_get_info(self);
234-
235222
bleio_adapter_reset_name(self);
236223
}
237224

@@ -243,15 +230,14 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
243230
return;
244231
}
245232

246-
//FIX enable/disable HCI adapter, but don't reset it, since we don't know how.
247233
self->enabled = enabled;
248-
if (!enabled) {
249-
// Stop any current activity.
250-
check_hci_error(hci_reset());
251-
self->now_advertising = false;
252-
self->extended_advertising = false;
253-
self->circuitpython_advertising = false;
254-
}
234+
235+
// Stop any current activity; reset to known state.
236+
check_hci_error(hci_reset());
237+
self->now_advertising = false;
238+
self->extended_advertising = false;
239+
self->circuitpython_advertising = false;
240+
self->advertising_timeout_msecs = 0;
255241
}
256242

257243
bool common_hal_bleio_adapter_get_enabled(bleio_adapter_obj_t *self) {
@@ -506,6 +492,10 @@ uint32_t _common_hal_bleio_adapter_start_advertising(bleio_adapter_obj_t *self,
506492
advertising_data_len > self->max_adv_data_len || scan_response_data_len > self->max_adv_data_len;
507493

508494
if (extended) {
495+
if (!BT_FEAT_LE_EXT_ADV(self->features)) {
496+
mp_raise_bleio_BluetoothError(translate("Data length needs extended advertising, but this adapter does not support it"));
497+
}
498+
509499
uint16_t props = 0;
510500
if (connectable) {
511501
props |= BT_HCI_LE_ADV_PROP_CONN;

devices/ble_hci/common-hal/_bleio/Adapter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ typedef struct _bleio_adapter_obj_t {
6565
uint16_t max_acl_buffer_len;
6666
uint16_t max_acl_num_buffers;
6767
uint16_t max_adv_data_len;
68+
uint8_t features[8]; // Supported BLE features.
6869

6970
} bleio_adapter_obj_t;
7071

devices/ble_hci/common-hal/_bleio/hci_api.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -628,9 +628,19 @@ hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_
628628
if (result == HCI_OK) {
629629
struct bt_hci_rp_le_read_max_adv_data_len *response =
630630
(struct bt_hci_rp_le_read_max_adv_data_len *) cmd_response_data;
631-
if (response->status == BT_HCI_ERR_SUCCESS) {
632-
*max_adv_data_len = response->max_adv_data_len;
633-
}
631+
*max_adv_data_len = response->max_adv_data_len;
632+
}
633+
634+
return result;
635+
}
636+
637+
hci_result_t hci_le_read_local_supported_features(uint8_t features[8]) {
638+
int result = send_command(BT_HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
639+
if (result == HCI_OK) {
640+
struct bt_hci_rp_le_read_local_features *response =
641+
(struct bt_hci_rp_le_read_local_features *) cmd_response_data;
642+
memcpy(features, response->features,
643+
sizeof_field(struct bt_hci_rp_le_read_local_features, features));
634644
}
635645

636646
return result;
@@ -649,6 +659,20 @@ hci_result_t hci_le_set_advertising_data(uint8_t len, uint8_t data[]) {
649659
return send_command(BT_HCI_OP_LE_SET_ADV_DATA, sizeof(params), &params);
650660
}
651661

662+
hci_result_t hci_le_set_extended_advertising_data(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len, uint8_t data[]) {
663+
const uint8_t max_len = sizeof_field(struct bt_hci_cp_le_set_ext_adv_data, data);
664+
uint8_t valid_len = MIN(len, max_len);
665+
struct bt_hci_cp_le_set_ext_adv_data params = {
666+
.handle = handle,
667+
.op = op,
668+
.frag_pref = frag_pref,
669+
.len = valid_len,
670+
};
671+
memcpy(params.data, data, valid_len);
672+
return send_command(BT_HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(params) - (max_len - valid_len), &params);
673+
}
674+
675+
652676
hci_result_t hci_le_set_scan_response_data(uint8_t len, uint8_t data[]) {
653677
struct bt_hci_cp_le_set_scan_rsp_data params = {
654678
// Zero out unused data bytes.

devices/ble_hci/common-hal/_bleio/hci_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@ hci_result_t hci_le_create_conn(uint16_t scan_interval, uint16_t scan_window, ui
4747

4848
hci_result_t hci_le_read_buffer_size(uint16_t *le_max_len, uint8_t *le_max_num);
4949
hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_len);
50+
hci_result_t hci_le_read_local_supported_features(uint8_t features[8]);
5051

5152
hci_result_t hci_le_set_advertising_data(uint8_t length, uint8_t data[]);
5253
hci_result_t hci_le_set_advertising_enable(uint8_t enable);
5354
hci_result_t hci_le_set_advertising_parameters(uint16_t min_interval, uint16_t max_interval, uint8_t type, uint8_t own_addr_type, bt_addr_le_t *direct_addr, uint8_t channel_map, uint8_t filter_policy);
5455

56+
hci_result_t hci_le_set_extended_advertising_data(uint8_t handle, uint8_t op, uint8_t frag_pref, uint8_t len, uint8_t data[]);
5557
hci_result_t hci_le_set_extended_advertising_enable(uint8_t enable, uint8_t set_num, uint8_t handle[], uint16_t duration[], uint8_t max_ext_adv_evts[]);
5658
hci_result_t hci_le_set_extended_advertising_parameters(uint8_t handle, uint16_t props, uint32_t prim_min_interval, uint32_t prim_max_interval, uint8_t prim_channel_map, uint8_t own_addr_type, bt_addr_le_t *peer_addr, uint8_t filter_policy, int8_t tx_power, uint8_t prim_adv_phy, uint8_t sec_adv_max_skip, uint8_t sec_adv_phy, uint8_t sid, uint8_t scan_req_notify_enable);
5759

shared-bindings/_bleio/Adapter.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ STATIC void check_enabled(bleio_adapter_obj_t *self) {
8383
//| The `uart`, `rts`, and `cts` objects are used to
8484
//| communicate with the HCI co-processor in HCI mode.
8585
//|
86+
//| The `_bleio.adapter` object is enabled during this call.
87+
//|
8688
mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
8789
#if CIRCUITPY_BLEIO_HCI
8890
bleio_adapter_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
@@ -108,9 +110,9 @@ mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *pos_args,
108110
!MP_OBJ_IS_TYPE(cts, &digitalio_digitalinout_type)) {
109111
mp_raise_ValueError(translate("Expected a DigitalInOut"));
110112
}
111-
check_enabled(self);
113+
114+
// Will enable the adapter.
112115
common_hal_bleio_adapter_hci_uart_init(self, uart, rts, cts);
113-
common_hal_bleio_adapter_set_enabled(self, true);
114116

115117
return mp_const_none;
116118
#else

0 commit comments

Comments
 (0)