summaryrefslogtreecommitdiff
path: root/devices
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2020-07-15 09:46:13 -0400
committerDan Halbert <halbert@halwitz.org>2020-07-15 09:46:13 -0400
commitb08b0264cce3fae379035da4d53b8e96174405aa (patch)
tree4028de3ec53b9585417e87fc07e579272b89a30e /devices
parentf6869c69c5fda701b57fbfca0eaf1aa03a2d164b (diff)
back to working; check for extended advertising support
Diffstat (limited to 'devices')
-rw-r--r--devices/ble_hci/common-hal/_bleio/Adapter.c66
-rw-r--r--devices/ble_hci/common-hal/_bleio/Adapter.h1
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_api.c30
-rw-r--r--devices/ble_hci/common-hal/_bleio/hci_api.h2
4 files changed, 58 insertions, 41 deletions
diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.c b/devices/ble_hci/common-hal/_bleio/Adapter.c
index 7817ea470..92eb42ee0 100644
--- a/devices/ble_hci/common-hal/_bleio/Adapter.c
+++ b/devices/ble_hci/common-hal/_bleio/Adapter.c
@@ -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;
diff --git a/devices/ble_hci/common-hal/_bleio/Adapter.h b/devices/ble_hci/common-hal/_bleio/Adapter.h
index 8e34f8663..10a398b24 100644
--- a/devices/ble_hci/common-hal/_bleio/Adapter.h
+++ b/devices/ble_hci/common-hal/_bleio/Adapter.h
@@ -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;
diff --git a/devices/ble_hci/common-hal/_bleio/hci_api.c b/devices/ble_hci/common-hal/_bleio/hci_api.c
index 4901ffeed..ece06f169 100644
--- a/devices/ble_hci/common-hal/_bleio/hci_api.c
+++ b/devices/ble_hci/common-hal/_bleio/hci_api.c
@@ -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.
diff --git a/devices/ble_hci/common-hal/_bleio/hci_api.h b/devices/ble_hci/common-hal/_bleio/hci_api.h
index 23e45375c..3e53a3775 100644
--- a/devices/ble_hci/common-hal/_bleio/hci_api.h
+++ b/devices/ble_hci/common-hal/_bleio/hci_api.h
@@ -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);