diff options
-rw-r--r-- | bta/dm/bta_dm_act.c | 7 | ||||
-rw-r--r-- | btif/src/btif_gatt_client.c | 4 | ||||
-rw-r--r-- | btif/src/btif_rc.c | 73 | ||||
-rw-r--r-- | device/include/interop_database.h | 5 | ||||
-rw-r--r-- | hci/src/hci_hal_h4.c | 43 | ||||
-rw-r--r-- | hci/test/hci_hal_h4_test.cpp | 7 | ||||
-rw-r--r-- | osi/src/alarm.c | 8 | ||||
-rw-r--r-- | stack/btm/btm_acl.c | 18 | ||||
-rw-r--r-- | stack/btm/btm_ble_gap.c | 3 | ||||
-rw-r--r-- | stack/gatt/gatt_auth.c | 5 | ||||
-rw-r--r-- | stack/gatt/gatt_utils.c | 2 | ||||
-rw-r--r-- | stack/include/bt_types.h | 1 | ||||
-rw-r--r-- | stack/include/hcidefs.h | 3 | ||||
-rw-r--r-- | stack/sdp/sdp_api.c | 13 | ||||
-rw-r--r-- | stack/smp/smp_act.c | 13 |
15 files changed, 111 insertions, 94 deletions
diff --git a/bta/dm/bta_dm_act.c b/bta/dm/bta_dm_act.c index 6b196c826..852426965 100644 --- a/bta/dm/bta_dm_act.c +++ b/bta/dm/bta_dm_act.c @@ -3557,7 +3557,6 @@ static void bta_dm_disable_conn_down_timer_cback (TIMER_LIST_ENT *p_tle) *******************************************************************************/ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, BD_ADDR peer_addr) { - UINT8 j; tBTA_PREF_ROLES role; tBTA_DM_PEER_DEVICE *p_dev; @@ -3611,7 +3610,11 @@ static void bta_dm_rm_cback(tBTA_SYS_CONN_STATUS status, UINT8 id, UINT8 app_id, APPL_TRACE_WARNING("bta_dm_rm_cback:%d, status:%d", bta_dm_cb.cur_av_count, status); } - bta_dm_adjust_roles(FALSE); + /* Don't adjust roles for each busy/idle state transition to avoid + excessive switch requests when individual profile busy/idle status + changes */ + if ((status != BTA_SYS_CONN_BUSY) && (status != BTA_SYS_CONN_IDLE)) + bta_dm_adjust_roles(FALSE); } /******************************************************************************* diff --git a/btif/src/btif_gatt_client.c b/btif/src/btif_gatt_client.c index 253ca2bd1..a959cdd73 100644 --- a/btif/src/btif_gatt_client.c +++ b/btif/src/btif_gatt_client.c @@ -458,8 +458,6 @@ static void btif_gattc_update_properties ( btif_gattc_cb_t *p_btif_cb ) btif_dm_update_ble_remote_properties( p_btif_cb->bd_addr.address, bdname.name, p_btif_cb->device_type); } - - btif_storage_set_remote_addr_type( &p_btif_cb->bd_addr, p_btif_cb->addr_type); } static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) @@ -646,6 +644,8 @@ static void btif_gattc_upstreams_evt(uint16_t event, char* p_param) BT_PROPERTY_TYPE_OF_DEVICE, sizeof(dev_type), &dev_type); btif_storage_set_remote_device_property(&(p_btif_cb->bd_addr), &properties); + btif_storage_set_remote_addr_type( &p_btif_cb->bd_addr, p_btif_cb->addr_type); + HAL_CBACK(bt_gatt_callbacks, client->scan_result_cb, &p_btif_cb->bd_addr, p_btif_cb->rssi, p_btif_cb->value); break; diff --git a/btif/src/btif_rc.c b/btif/src/btif_rc.c index 2b17fccb2..5b0d3c930 100644 --- a/btif/src/btif_rc.c +++ b/btif/src/btif_rc.c @@ -189,7 +189,6 @@ static int uinput_driver_check(); static int uinput_create(char *name); static int init_uinput (void); static void close_uinput (void); -static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev); #if (AVRC_CTLR_INCLUDED == TRUE) static BOOLEAN conn_status = FALSE; #endif @@ -210,35 +209,6 @@ static const struct { { NULL, 0, 0, 0 } }; -/* the rc_black_addr_prefix and rc_white_addr_prefix are used to correct - * IOP issues of absolute volume feature - * We encoutered A2DP headsets/carkits advertising absolute volume but buggy. - * We would like to blacklist those devices. - * But we donot have a full list of the bad devices. So as a temp fix, we - * are blacklisting all the devices except the devices we have well tested, - * the ones in the whitelist. - * - * For now, only the rc_white_addr_prefix is used in the code while - * rc_black_addr_prefix is kept here for future long term solution. - */ -static const UINT8 rc_white_addr_prefix[][3] = { - {0x94, 0xCE, 0x2C}, // Sony SBH50 - {0x30, 0x17, 0xC8}, // Sony wm600 - {0x00, 0x15, 0x83}, // BlueSoleil dongle - {0x00, 0x80, 0x98}, // PTS dongle - {0x48, 0xC1, 0xAC}, // Plantronics Backbeat Go - {0x00, 0x1B, 0xDC}, // PTS dongle 2 - {0x00, 0x19, 0x8E}, // Demant - {0x04, 0x88, 0xE2}, // Apple - {0x00, 0x0C, 0x8A}, // Bose - {0x1C, 0x48, 0xF9} // Jabra Pulse -}; - -static const char* rc_white_name[] = { - "SBH50", - "MW600" -}; - static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status); static UINT8 opcode_from_pdu(UINT8 pdu); @@ -478,8 +448,7 @@ void handle_rc_features(int index) bdaddr_to_string(&avdtp_addr, &addr1, sizeof(bdstr_t)), bdaddr_to_string(&rc_addr, &addr2, sizeof(bdstr_t)) ); - if (dev_blacklisted_for_absolute_volume(btif_rc_cb[index].rc_addr) || - bdcmp(avdtp_addr.address, rc_addr.address)) + if (bdcmp(avdtp_addr.address, rc_addr.address)) { btif_rc_cb[index].rc_features &= ~BTA_AV_FEAT_ADV_CTRL; } @@ -4792,43 +4761,3 @@ void lbl_destroy() BTIF_TRACE_EVENT(" %s: lbllock destroy success ", __FUNCTION__); } } - -/******************************************************************************* -** Function dev_blacklisted_for_absolute_volume -** -** Description Blacklist Devices that donot handle absolute volume well -** We are blacklisting all the devices that are not in whitelist -** -** Returns True if the device is in the list -*******************************************************************************/ -static BOOLEAN dev_blacklisted_for_absolute_volume(BD_ADDR peer_dev) -{ - int i; - char *dev_name_str = NULL; - int whitelist_size = sizeof(rc_white_addr_prefix)/sizeof(rc_white_addr_prefix[0]); - - for (i = 0; i < whitelist_size; i++) { - if (rc_white_addr_prefix[i][0] == peer_dev[0] && - rc_white_addr_prefix[i][1] == peer_dev[1] && - rc_white_addr_prefix[i][2] == peer_dev[2]) { - BTIF_TRACE_DEBUG("whitelist absolute volume for %02x:%02x:%02x", - peer_dev[0], peer_dev[1], peer_dev[2]); - return FALSE; - } - } - - dev_name_str = BTM_SecReadDevName(peer_dev); - whitelist_size = sizeof(rc_white_name)/sizeof(char*); - if (dev_name_str != NULL) { - for (i = 0; i < whitelist_size; i++) { - if (strcmp(dev_name_str, rc_white_name[i]) == 0) { - BTIF_TRACE_DEBUG("whitelist absolute volume for %s", dev_name_str); - return FALSE; - } - } - } - - BTIF_TRACE_WARNING("blacklist absolute volume for %02x:%02x:%02x, name = %s", - peer_dev[0], peer_dev[1], peer_dev[2], dev_name_str); - return TRUE; -} diff --git a/device/include/interop_database.h b/device/include/interop_database.h index e7e0da32c..a0bdae756 100644 --- a/device/include/interop_database.h +++ b/device/include/interop_database.h @@ -46,9 +46,6 @@ static const interop_addr_t interop_addr_database[] = { {{0xac, 0x9e, 0x17, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, {{0xf0, 0x79, 0x59, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - // Polar Heart Rate Monitor - {{0x00, 0x22, 0xd0, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, - // Motorola Key Link {{0x1c, 0x96, 0x5a, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, @@ -56,6 +53,8 @@ static const interop_addr_t interop_addr_database[] = { {{0x80, 0xea, 0xCa, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, // Xiaomi Mi Band {{0x88, 0x0f, 0x10, 0,0,0}, 3, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, + // Flic smart button + {{0x80, 0xe4, 0xda, 0x70, 0,0}, 4, INTEROP_DISABLE_LE_SECURE_CONNECTIONS}, // BMW car kits (Harman/Becker) {{0x9c, 0xdf, 0x03, 0,0,0}, 3, INTEROP_AUTO_RETRY_PAIRING}, diff --git a/hci/src/hci_hal_h4.c b/hci/src/hci_hal_h4.c index 1a5734e4b..332c1a2ba 100644 --- a/hci/src/hci_hal_h4.c +++ b/hci/src/hci_hal_h4.c @@ -31,6 +31,7 @@ #include "vendor.h" #define HCI_HAL_SERIAL_BUFFER_SIZE 1026 +#define HCI_BLE_EVENT 0x3e // Increased HCI thread priority to keep up with the audio sub-system // when streaming time sensitive data (A2DP). @@ -47,6 +48,8 @@ static int uart_fd; static eager_reader_t *uart_stream; static serial_data_type_t current_data_type; static bool stream_has_interpretation; +static bool stream_corruption_detected; +static uint8_t stream_corruption_bytes_to_ignore; static void event_uart_has_bytes(eager_reader_t *reader, void *context); @@ -86,6 +89,8 @@ static bool hal_open() { } stream_has_interpretation = false; + stream_corruption_detected = false; + stream_corruption_bytes_to_ignore = 0; eager_reader_register(uart_stream, thread_get_reactor(thread), event_uart_has_bytes, NULL); // Raise thread priorities to keep up with audio @@ -185,6 +190,40 @@ static bool hal_dev_in_reset() // Internal functions +// WORKAROUND: +// As exhibited by b/23934838, during result-heavy LE scans, the UART byte +// stream can get corrupted, leading to assertions caused by mis-interpreting +// the bytes following the corruption. +// This workaround looks for tell-tale signs of a BLE event and attempts to +// skip the correct amount of bytes in the stream to re-synchronize onto +// a packet boundary. +// Function returns true if |byte_read| has been processed by the workaround. +static bool stream_corrupted_during_le_scan_workaround(const uint8_t byte_read) +{ + if (!stream_corruption_detected && byte_read == HCI_BLE_EVENT) { + LOG_ERROR("%s HCI stream corrupted (message type 0x3E)!", __func__); + stream_corruption_detected = true; + return true; + } + + if (stream_corruption_detected) { + if (stream_corruption_bytes_to_ignore == 0) { + stream_corruption_bytes_to_ignore = byte_read; + LOG_ERROR("%s About to skip %d bytes...", __func__, stream_corruption_bytes_to_ignore); + } else { + --stream_corruption_bytes_to_ignore; + } + + if (stream_corruption_bytes_to_ignore == 0) { + LOG_ERROR("%s Back to our regularly scheduled program...", __func__); + stream_corruption_detected = false; + } + return true; + } + + return false; +} + // See what data is waiting, and notify the upper layer static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *context) { if (stream_has_interpretation) { @@ -195,6 +234,10 @@ static void event_uart_has_bytes(eager_reader_t *reader, UNUSED_ATTR void *conte LOG_ERROR("%s could not read HCI message type", __func__); return; } + + if (stream_corrupted_during_le_scan_workaround(type_byte)) + return; + if (type_byte < DATA_TYPE_ACL || type_byte > DATA_TYPE_EVENT) { LOG_ERROR("%s Unknown HCI message type. Dropping this byte 0x%x, min %x, max %x", __func__, type_byte, DATA_TYPE_ACL, DATA_TYPE_EVENT); return; diff --git a/hci/test/hci_hal_h4_test.cpp b/hci/test/hci_hal_h4_test.cpp index 2c4030d4f..d64e8c4d2 100644 --- a/hci/test/hci_hal_h4_test.cpp +++ b/hci/test/hci_hal_h4_test.cpp @@ -43,6 +43,9 @@ DECLARE_TEST_MODES( type_byte_only ); +// Use as packet type to test stream_corrupted_during_le_scan_workaround() +static const uint8_t HCI_BLE_EVENT = 0x3e; + static char sample_data1[100] = "A point is that which has no part."; static char sample_data2[100] = "A line is breadthless length."; static char sample_data3[100] = "The ends of a line are points."; @@ -50,6 +53,9 @@ static char acl_data[100] = "A straight line is a line which lies evenly wit static char sco_data[100] = "A surface is that which has length and breadth only."; static char event_data[100] = "The edges of a surface are lines."; +// Test data for stream_corrupted_during_le_scan_workaround() +static char corrupted_data[] = { 0x5 /* length of remaining data */, 'H', 'e', 'l', 'l', 'o' }; + static const hci_hal_t *hal; static int dummy_serial_fd; static int reentry_i = 0; @@ -221,6 +227,7 @@ TEST_F(HciHalH4Test, test_read_synchronous) { reset_for(read_synchronous); write_packet(sockfd[1], DATA_TYPE_ACL, acl_data); + write_packet(sockfd[1], HCI_BLE_EVENT, corrupted_data); write_packet(sockfd[1], DATA_TYPE_SCO, sco_data); write_packet(sockfd[1], DATA_TYPE_EVENT, event_data); diff --git a/osi/src/alarm.c b/osi/src/alarm.c index c16affc97..59f5fa78b 100644 --- a/osi/src/alarm.c +++ b/osi/src/alarm.c @@ -35,6 +35,13 @@ #include "osi/include/semaphore.h" #include "osi/include/thread.h" +// Make callbacks run at high thread priority. Some callbacks are used for audio +// related timer tasks as well as re-transmissions etc. Since we at this point +// cannot differentiate what callback we are dealing with, assume high priority +// for now. +// TODO(eisenbach): Determine correct thread priority (from parent?/per alarm?) +static const int CALLBACK_THREAD_PRIORITY_HIGH = -19; + struct alarm_t { // The lock is held while the callback for this alarm is being executed. // It allows us to release the coarse-grained monitor lock while a potentially @@ -241,6 +248,7 @@ static bool lazy_initialize(void) { return false; } + thread_set_priority(callback_thread, CALLBACK_THREAD_PRIORITY_HIGH); thread_post(callback_thread, callback_dispatch, NULL); return true; } diff --git a/stack/btm/btm_acl.c b/stack/btm/btm_acl.c index 049fbe85d..a567cbdab 100644 --- a/stack/btm/btm_acl.c +++ b/stack/btm/btm_acl.c @@ -976,15 +976,16 @@ void btm_read_remote_version_complete (UINT8 *p) UINT16 handle; int xx; BTM_TRACE_DEBUG ("btm_read_remote_version_complete"); + STREAM_TO_UINT8 (status, p); - if (status == HCI_SUCCESS) - { - STREAM_TO_UINT16 (handle, p); + STREAM_TO_UINT16 (handle, p); - /* Look up the connection by handle and copy features */ - for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++) + /* Look up the connection by handle and copy features */ + for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_acl_cb++) + { + if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) { - if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) + if (status == HCI_SUCCESS) { STREAM_TO_UINT8 (p_acl_cb->lmp_version, p); STREAM_TO_UINT16 (p_acl_cb->manufacturer, p); @@ -995,8 +996,11 @@ void btm_read_remote_version_complete (UINT8 *p) BTM_TRACE_WARNING ("btm_read_remote_version_complete lmp_version %d manufacturer %d lmp_subversion %d", p_acl_cb->lmp_version,p_acl_cb->manufacturer, p_acl_cb->lmp_subversion); btm_read_remote_features (p_acl_cb->hci_handle); - break; } + + if (p_acl_cb->transport == BT_TRANSPORT_LE) + l2cble_notify_le_connection (p_acl_cb->remote_addr); + break; } } } diff --git a/stack/btm/btm_ble_gap.c b/stack/btm/btm_ble_gap.c index 19ec9e75a..8c24e7da9 100644 --- a/stack/btm/btm_ble_gap.c +++ b/stack/btm/btm_ble_gap.c @@ -3215,8 +3215,7 @@ void btm_ble_read_remote_features_complete(UINT8 *p) if ((p_acl_cb->in_use) && (p_acl_cb->hci_handle == handle)) { STREAM_TO_ARRAY(p_acl_cb->peer_le_features, p, BD_FEATURES_LEN); - /*notify link up here */ - l2cble_notify_le_connection (p_acl_cb->remote_addr); + btsnd_hcic_rmt_ver_req (p_acl_cb->hci_handle); break; } } diff --git a/stack/gatt/gatt_auth.c b/stack/gatt/gatt_auth.c index ae5214592..89e2cc1cd 100644 --- a/stack/gatt/gatt_auth.c +++ b/stack/gatt/gatt_auth.c @@ -103,6 +103,11 @@ void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf) UINT8 *p, *p_orig = (UINT8 *)(p_buf + 1) + p_buf->offset; UINT32 counter; + if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) { + GATT_TRACE_ERROR("%s: Data length %u less than expected %u", + __func__, p_buf->len, GATT_AUTH_SIGN_LEN + 4); + return; + } cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4; p = p_orig + cmd_len - 4; STREAM_TO_UINT32(counter, p); diff --git a/stack/gatt/gatt_utils.c b/stack/gatt/gatt_utils.c index 5030c5328..907862ff1 100644 --- a/stack/gatt/gatt_utils.c +++ b/stack/gatt/gatt_utils.c @@ -1497,7 +1497,7 @@ UINT32 gatt_add_sdp_record (tBT_UUID *p_uuid, UINT16 start_hdl, UINT16 end_hdl) case LEN_UUID_128: UINT8_TO_BE_STREAM (p, (UUID_DESC_TYPE << 3) | SIZE_SIXTEEN_BYTES); - ARRAY_TO_BE_STREAM (p, p_uuid->uu.uuid128, LEN_UUID_128); + ARRAY_TO_BE_STREAM_REVERSE (p, p_uuid->uu.uuid128, LEN_UUID_128); SDP_AddAttribute (sdp_handle, ATTR_ID_SERVICE_CLASS_ID_LIST, DATA_ELE_SEQ_DESC_TYPE, (UINT32) (p - buff), buff); break; diff --git a/stack/include/bt_types.h b/stack/include/bt_types.h index 4ea447eca..453aa38a3 100644 --- a/stack/include/bt_types.h +++ b/stack/include/bt_types.h @@ -286,6 +286,7 @@ typedef struct #define UINT16_TO_BE_STREAM(p, u16) {*(p)++ = (UINT8)((u16) >> 8); *(p)++ = (UINT8)(u16);} #define UINT8_TO_BE_STREAM(p, u8) {*(p)++ = (UINT8)(u8);} #define ARRAY_TO_BE_STREAM(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[ijk];} +#define ARRAY_TO_BE_STREAM_REVERSE(p, a, len) {register int ijk; for (ijk = 0; ijk < len; ijk++) *(p)++ = (UINT8) a[len - ijk - 1];} #define BE_STREAM_TO_UINT8(u8, p) {u8 = (UINT8)(*(p)); (p) += 1;} #define BE_STREAM_TO_UINT16(u16, p) {u16 = (UINT16)(((UINT16)(*(p)) << 8) + (UINT16)(*((p) + 1))); (p) += 2;} diff --git a/stack/include/hcidefs.h b/stack/include/hcidefs.h index 41dc936c0..4cd34852a 100644 --- a/stack/include/hcidefs.h +++ b/stack/include/hcidefs.h @@ -24,6 +24,9 @@ #define HCI_PROTO_VERSION_2_0 0x03 /* Version for BT spec 2.0 */ #define HCI_PROTO_VERSION_2_1 0x04 /* Version for BT spec 2.1 [Lisbon] */ #define HCI_PROTO_VERSION_3_0 0x05 /* Version for BT spec 3.0 */ +#define HCI_PROTO_VERSION_4_0 0x06 /* Version for BT spec 4.0 */ +#define HCI_PROTO_VERSION_4_1 0x07 /* Version for BT spec 4.1 */ +#define HCI_PROTO_VERSION_4_2 0x08 /* Version for BT spec 4.2 */ #define HCI_PROTO_REVISION 0x000C /* Current implementation version */ /* ** Definitions for HCI groups diff --git a/stack/sdp/sdp_api.c b/stack/sdp/sdp_api.c index d96ace91d..720fad717 100644 --- a/stack/sdp/sdp_api.c +++ b/stack/sdp/sdp_api.c @@ -357,7 +357,8 @@ BOOLEAN SDP_FindServiceUUIDInRec(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid) else if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == LEN_UUID_128) { p_uuid->len = LEN_UUID_128; - memcpy(p_uuid->uu.uuid128, p_sattr->attr_value.v.array, LEN_UUID_128); + for (uint8_t i = 0; i != LEN_UUID_128; ++i) + p_uuid->uu.uuid128[i] = p_sattr->attr_value.v.array[LEN_UUID_128-i-1]; } else if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == LEN_UUID_32) { @@ -443,8 +444,9 @@ BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid) /* only support 128 bits UUID for now */ if (SDP_DISC_ATTR_LEN(p_sattr->attr_len_type) == 16) { - p_uuid->len = 16; - memcpy(p_uuid->uu.uuid128, p_sattr->attr_value.v.array, MAX_UUID_SIZE); + p_uuid->len = LEN_UUID_128; + for (uint8_t i = 0; i != LEN_UUID_128; ++i) + p_uuid->uu.uuid128[i] = p_sattr->attr_value.v.array[LEN_UUID_128-i-1]; } return(TRUE); } @@ -457,8 +459,9 @@ BOOLEAN SDP_FindServiceUUIDInRec_128bit(tSDP_DISC_REC *p_rec, tBT_UUID * p_uuid) /* only support 128 bits UUID for now */ && (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) == 16)) { - p_uuid->len = 16; - memcpy(p_uuid->uu.uuid128, p_attr->attr_value.v.array, MAX_UUID_SIZE); + p_uuid->len = LEN_UUID_128; + for (uint8_t i = 0; i != LEN_UUID_128; ++i) + p_uuid->uu.uuid128[i] = p_attr->attr_value.v.array[LEN_UUID_128-i-1]; return(TRUE); } } diff --git a/stack/smp/smp_act.c b/stack/smp/smp_act.c index 462b02dce..119fd4de6 100644 --- a/stack/smp/smp_act.c +++ b/stack/smp/smp_act.c @@ -51,6 +51,18 @@ const tSMP_ACT smp_distribute_act [] = smp_set_derive_link_key }; +static bool lmp_version_below(BD_ADDR bda, uint8_t version) +{ + tACL_CONN *acl = btm_bda_to_acl(bda, BT_TRANSPORT_LE); + if (acl == NULL || acl->lmp_version == 0) + { + SMP_TRACE_WARNING("%s cannot retrieve LMP version...", __func__); + return false; + } + SMP_TRACE_WARNING("%s LMP version %d < %d", __func__, acl->lmp_version, version); + return acl->lmp_version < version; +} + /******************************************************************************* ** Function smp_update_key_mask ** Description This function updates the key mask for sending or receiving. @@ -173,6 +185,7 @@ void smp_send_app_cback(tSMP_CB *p_cb, tSMP_INT_DATA *p_data) } if (!(p_cb->loc_auth_req & SMP_SC_SUPPORT_BIT) + || lmp_version_below(p_cb->pairing_bda, HCI_PROTO_VERSION_4_2) || interop_addr_match(INTEROP_DISABLE_LE_SECURE_CONNECTIONS, (const bt_bdaddr_t *)&p_cb->pairing_bda)) { |