back to working; check for extended advertising support

This commit is contained in:
Dan Halbert 2020-07-15 09:46:13 -04:00
parent f6869c69c5
commit b08b0264cc
5 changed files with 62 additions and 43 deletions

View File

@ -68,26 +68,6 @@
#define BLE_SLAVE_LATENCY 0
#define BLE_CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
#ifndef BLEIO_VS_UUID_COUNT
#define BLEIO_VS_UUID_COUNT 75
#endif
#ifndef BLEIO_HVN_TX_QUEUE_SIZE
#define BLEIO_HVN_TX_QUEUE_SIZE 9
#endif
#ifndef BLEIO_CENTRAL_ROLE_COUNT
#define BLEIO_CENTRAL_ROLE_COUNT 4
#endif
#ifndef BLEIO_PERIPH_ROLE_COUNT
#define BLEIO_PERIPH_ROLE_COUNT 4
#endif
#ifndef BLEIO_ATTR_TAB_SIZE
#define BLEIO_ATTR_TAB_SIZE (BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 5)
#endif
bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT];
// 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) {
// Get various values and limits set by the adapter.
STATIC void bleio_adapter_get_info(bleio_adapter_obj_t *self) {
// Get supported features.
if (hci_le_read_local_supported_features(self->features) != HCI_OK) {
mp_raise_bleio_BluetoothError(translate("Could not read BLE features"));
}
// Get ACL buffer info.
uint16_t le_max_len;
uint8_t le_max_num;
@ -212,26 +197,28 @@ STATIC void bleio_adapter_get_info(bleio_adapter_obj_t *self) {
self->max_acl_num_buffers = acl_max_num;
}
// Get max advertising length.
uint16_t max_adv_data_len;
if (hci_le_read_maximum_advertising_data_length(&max_adv_data_len) != HCI_OK) {
mp_raise_bleio_BluetoothError(translate("Could not get max advertising length"));
// Get max advertising length if extended advertising is supported.
if (BT_FEAT_LE_EXT_ADV(self->features)) {
uint16_t max_adv_data_len;
if (hci_le_read_maximum_advertising_data_length(&max_adv_data_len) != HCI_OK) {
mp_raise_bleio_BluetoothError(translate("Could not get max advertising length"));
}
self->max_adv_data_len = max_adv_data_len;
} else {
self->max_adv_data_len = 31;
}
self->max_adv_data_len = max_adv_data_len;
}
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) {
self->hci_uart = uart;
self->rts_digitalinout = rts;
self->cts_digitalinout = cts;
// Advertising-related fields are initialized by common_hal_bleio_adapter_set_enabled().
self->enabled = false;
self->now_advertising = false;
self->circuitpython_advertising = false;
self->extended_advertising = false;
self->advertising_timeout_msecs = 0;
common_hal_bleio_adapter_set_enabled(self, true);
bleio_adapter_get_info(self);
bleio_adapter_reset_name(self);
}
@ -243,15 +230,14 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable
return;
}
//FIX enable/disable HCI adapter, but don't reset it, since we don't know how.
self->enabled = enabled;
if (!enabled) {
// Stop any current activity.
check_hci_error(hci_reset());
self->now_advertising = false;
self->extended_advertising = false;
self->circuitpython_advertising = false;
}
// Stop any current activity; reset to known state.
check_hci_error(hci_reset());
self->now_advertising = false;
self->extended_advertising = false;
self->circuitpython_advertising = false;
self->advertising_timeout_msecs = 0;
}
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,
advertising_data_len > self->max_adv_data_len || scan_response_data_len > self->max_adv_data_len;
if (extended) {
if (!BT_FEAT_LE_EXT_ADV(self->features)) {
mp_raise_bleio_BluetoothError(translate("Data length needs extended advertising, but this adapter does not support it"));
}
uint16_t props = 0;
if (connectable) {
props |= BT_HCI_LE_ADV_PROP_CONN;

View File

@ -65,6 +65,7 @@ typedef struct _bleio_adapter_obj_t {
uint16_t max_acl_buffer_len;
uint16_t max_acl_num_buffers;
uint16_t max_adv_data_len;
uint8_t features[8]; // Supported BLE features.
} bleio_adapter_obj_t;

View File

@ -628,9 +628,19 @@ hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_
if (result == HCI_OK) {
struct bt_hci_rp_le_read_max_adv_data_len *response =
(struct bt_hci_rp_le_read_max_adv_data_len *) cmd_response_data;
if (response->status == BT_HCI_ERR_SUCCESS) {
*max_adv_data_len = response->max_adv_data_len;
}
*max_adv_data_len = response->max_adv_data_len;
}
return result;
}
hci_result_t hci_le_read_local_supported_features(uint8_t features[8]) {
int result = send_command(BT_HCI_OP_LE_READ_LOCAL_FEATURES, 0, NULL);
if (result == HCI_OK) {
struct bt_hci_rp_le_read_local_features *response =
(struct bt_hci_rp_le_read_local_features *) cmd_response_data;
memcpy(features, response->features,
sizeof_field(struct bt_hci_rp_le_read_local_features, features));
}
return result;
@ -649,6 +659,20 @@ hci_result_t hci_le_set_advertising_data(uint8_t len, uint8_t data[]) {
return send_command(BT_HCI_OP_LE_SET_ADV_DATA, sizeof(params), &params);
}
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[]) {
const uint8_t max_len = sizeof_field(struct bt_hci_cp_le_set_ext_adv_data, data);
uint8_t valid_len = MIN(len, max_len);
struct bt_hci_cp_le_set_ext_adv_data params = {
.handle = handle,
.op = op,
.frag_pref = frag_pref,
.len = valid_len,
};
memcpy(params.data, data, valid_len);
return send_command(BT_HCI_OP_LE_SET_EXT_ADV_DATA, sizeof(params) - (max_len - valid_len), &params);
}
hci_result_t hci_le_set_scan_response_data(uint8_t len, uint8_t data[]) {
struct bt_hci_cp_le_set_scan_rsp_data params = {
// Zero out unused data bytes.

View File

@ -47,11 +47,13 @@ hci_result_t hci_le_create_conn(uint16_t scan_interval, uint16_t scan_window, ui
hci_result_t hci_le_read_buffer_size(uint16_t *le_max_len, uint8_t *le_max_num);
hci_result_t hci_le_read_maximum_advertising_data_length(uint16_t *max_adv_data_len);
hci_result_t hci_le_read_local_supported_features(uint8_t features[8]);
hci_result_t hci_le_set_advertising_data(uint8_t length, uint8_t data[]);
hci_result_t hci_le_set_advertising_enable(uint8_t enable);
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);
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[]);
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[]);
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);

View File

@ -83,6 +83,8 @@ STATIC void check_enabled(bleio_adapter_obj_t *self) {
//| The `uart`, `rts`, and `cts` objects are used to
//| communicate with the HCI co-processor in HCI mode.
//|
//| The `_bleio.adapter` object is enabled during this call.
//|
mp_obj_t bleio_adapter_hci_uart_init(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
#if CIRCUITPY_BLEIO_HCI
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,
!MP_OBJ_IS_TYPE(cts, &digitalio_digitalinout_type)) {
mp_raise_ValueError(translate("Expected a DigitalInOut"));
}
check_enabled(self);
// Will enable the adapter.
common_hal_bleio_adapter_hci_uart_init(self, uart, rts, cts);
common_hal_bleio_adapter_set_enabled(self, true);
return mp_const_none;
#else