summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bta/dm/bta_dm_act.c7
-rw-r--r--btif/src/btif_gatt_client.c4
-rw-r--r--btif/src/btif_rc.c73
-rw-r--r--device/include/interop_database.h5
-rw-r--r--hci/src/hci_hal_h4.c43
-rw-r--r--hci/test/hci_hal_h4_test.cpp7
-rw-r--r--osi/src/alarm.c8
-rw-r--r--stack/btm/btm_acl.c18
-rw-r--r--stack/btm/btm_ble_gap.c3
-rw-r--r--stack/gatt/gatt_auth.c5
-rw-r--r--stack/gatt/gatt_utils.c2
-rw-r--r--stack/include/bt_types.h1
-rw-r--r--stack/include/hcidefs.h3
-rw-r--r--stack/sdp/sdp_api.c13
-rw-r--r--stack/smp/smp_act.c13
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))
{