diff options
| author | Dan Halbert <halbert@halwitz.org> | 2020-07-15 09:46:13 -0400 |
|---|---|---|
| committer | Dan Halbert <halbert@halwitz.org> | 2020-07-15 09:46:13 -0400 |
| commit | b08b0264cce3fae379035da4d53b8e96174405aa (patch) | |
| tree | 4028de3ec53b9585417e87fc07e579272b89a30e /devices | |
| parent | f6869c69c5fda701b57fbfca0eaf1aa03a2d164b (diff) | |
back to working; check for extended advertising support
Diffstat (limited to 'devices')
| -rw-r--r-- | devices/ble_hci/common-hal/_bleio/Adapter.c | 66 | ||||
| -rw-r--r-- | devices/ble_hci/common-hal/_bleio/Adapter.h | 1 | ||||
| -rw-r--r-- | devices/ble_hci/common-hal/_bleio/hci_api.c | 30 | ||||
| -rw-r--r-- | devices/ble_hci/common-hal/_bleio/hci_api.h | 2 |
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), ¶ms); } +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), ¶ms); +} + + 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); |
