• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

タグ
未設定

よく使われているワード(クリックで追加)

javaandroidc++linuxc#objective-ccocoa誰得qtrubypythonwindowsphpgamebathyscaphegui翻訳comegattwitterframeworkbtronvb.net計画中(planning stage)testdomarduinodirectxpreviewerゲームエンジン

system/bt


コミットメタ情報

リビジョンf32527f508fa9d7966cd72265b299f5d4183f3cc (tree)
日時2019-06-05 18:35:26
作者Chih-Wei Huang <cwhuang@linu...>
コミッターChih-Wei Huang

ログメッセージ

Android 8.1.0 release 65
-----BEGIN PGP SIGNATURE-----

iF0EABECAB0WIQRDQNE1cO+UXoOBCWTorT+BmrEOeAUCXPGt7AAKCRDorT+BmrEO
eFv+AJ0SJfS84jRefbEsWwbmCP2Y1dsz3ACeKB2fryFj0j3Nds5WsChBb3YHqxk=
=kTQ5
-----END PGP SIGNATURE-----

Merge tag 'android-8.1.0_r65' into oreo-x86

Android 8.1.0 release 65

変更サマリ

差分

--- a/btif/src/btif_dm.cc
+++ b/btif/src/btif_dm.cc
@@ -183,7 +183,6 @@ typedef struct {
183183 #define BTA_SERVICE_ID_TO_SERVICE_MASK(id) (1 << (id))
184184
185185 #define UUID_HUMAN_INTERFACE_DEVICE "00001124-0000-1000-8000-00805f9b34fb"
186-#define UUID_EMPTY "00000000-0000-0000-0000-000000000000"
187186
188187 #define MAX_BTIF_BOND_EVENT_ENTRIES 15
189188
@@ -262,11 +261,6 @@ static bool is_empty_128bit(uint8_t* data) {
262261 return !memcmp(zero, data, sizeof(zero));
263262 }
264263
265-static bool is_bonding_or_sdp() {
266- return pairing_cb.state == BT_BOND_STATE_BONDING ||
267- (pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts);
268-}
269-
270264 static void btif_dm_data_copy(uint16_t event, char* dst, char* src) {
271265 tBTA_DM_SEC* dst_dm_sec = (tBTA_DM_SEC*)dst;
272266 tBTA_DM_SEC* src_dm_sec = (tBTA_DM_SEC*)src;
@@ -493,6 +487,8 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
493487 bt_bond_state_t state) {
494488 btif_stats_add_bond_event(bd_addr, BTIF_DM_FUNC_BOND_STATE_CHANGED, state);
495489
490+ // Send bonding state only once - based on outgoing/incoming we may receive
491+ // duplicates
496492 if ((pairing_cb.state == state) && (state == BT_BOND_STATE_BONDING)) {
497493 // Cross key pairing so send callback for static address
498494 if (!pairing_cb.static_bdaddr.IsEmpty()) {
@@ -510,18 +506,14 @@ static void bond_state_changed(bt_status_t status, const RawAddress& bd_addr,
510506 auto tmp = bd_addr;
511507 HAL_CBACK(bt_hal_cbacks, bond_state_changed_cb, status, &tmp, state);
512508
513- int dev_type;
514- if (!btif_get_device_type(bd_addr, &dev_type)) {
515- dev_type = BT_DEVICE_TYPE_BREDR;
516- }
517-
518- if (state == BT_BOND_STATE_BONDING ||
519- (state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts > 0)) {
520- // Save state for the device is bonding or SDP.
509+ if (state == BT_BOND_STATE_BONDING) {
521510 pairing_cb.state = state;
522511 pairing_cb.bd_addr = bd_addr;
523512 } else {
524- pairing_cb = {};
513+ if (!pairing_cb.sdp_attempts)
514+ memset(&pairing_cb, 0, sizeof(pairing_cb));
515+ else
516+ BTIF_TRACE_DEBUG("%s: BR-EDR service discovery active", __func__);
525517 }
526518 }
527519
@@ -1129,10 +1121,6 @@ static void btif_dm_auth_cmpl_evt(tBTA_DM_AUTH_CMPL* p_auth_cmpl) {
11291121
11301122 /* Trigger SDP on the device */
11311123 pairing_cb.sdp_attempts = 1;
1132-
1133- // Report bonded to Java before start SDP
1134- bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
1135-
11361124 btif_dm_get_remote_services(bd_addr);
11371125 }
11381126 }
@@ -1390,9 +1378,9 @@ static void btif_dm_search_services_evt(uint16_t event, char* p_param) {
13901378
13911379 BTIF_TRACE_DEBUG("%s:(result=0x%x, services 0x%x)", __func__,
13921380 p_data->disc_res.result, p_data->disc_res.services);
1393- if (p_data->disc_res.result != BTA_SUCCESS &&
1394- pairing_cb.state == BT_BOND_STATE_BONDED &&
1395- pairing_cb.sdp_attempts < BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING) {
1381+ if ((p_data->disc_res.result != BTA_SUCCESS) &&
1382+ (pairing_cb.state == BT_BOND_STATE_BONDING) &&
1383+ (pairing_cb.sdp_attempts < BTIF_DM_MAX_SDP_ATTEMPTS_AFTER_PAIRING)) {
13961384 BTIF_TRACE_WARNING("%s:SDP failed after bonding re-attempting",
13971385 __func__);
13981386 pairing_cb.sdp_attempts++;
@@ -1417,42 +1405,21 @@ static void btif_dm_search_services_evt(uint16_t event, char* p_param) {
14171405 /* onUuidChanged requires getBondedDevices to be populated.
14181406 ** bond_state_changed needs to be sent prior to remote_device_property
14191407 */
1420- if ((pairing_cb.state == BT_BOND_STATE_BONDED && pairing_cb.sdp_attempts) &&
1408+ if ((pairing_cb.state == BT_BOND_STATE_BONDING) &&
14211409 (p_data->disc_res.bd_addr == pairing_cb.bd_addr ||
1422- p_data->disc_res.bd_addr == pairing_cb.static_bdaddr)) {
1423- LOG_INFO(LOG_TAG, "%s Remote Service SDP done.", __func__);
1410+ p_data->disc_res.bd_addr == pairing_cb.static_bdaddr) &&
1411+ pairing_cb.sdp_attempts > 0) {
1412+ BTIF_TRACE_DEBUG(
1413+ "%s Remote Service SDP done. Call bond_state_changed_cb BONDED",
1414+ __func__);
14241415 pairing_cb.sdp_attempts = 0;
14251416
1426- // If bond occured due to cross-key pairing, send bond state callback
1417+ // If bonding occured due to cross-key pairing, send bonding callback
14271418 // for static address now
1428- if (p_data->disc_res.bd_addr == pairing_cb.static_bdaddr) {
1419+ if (p_data->disc_res.bd_addr == pairing_cb.static_bdaddr)
14291420 bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDING);
1430- bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
1431- }
1432- if (pairing_cb.state == BT_BOND_STATE_BONDED) {
1433- if (p_data->disc_res.result == BTA_SUCCESS) {
1434- // Device is bonded and SDP completed. Clear the pairing control
1435- // block.
1436- pairing_cb = {};
1437- } else {
1438- // Report empty UUID to Java if SDP report negative result while
1439- // pairing.
1440- bt_property_t prop;
1441- bt_uuid_t uuid;
1442- char uuid_str[128] = UUID_EMPTY;
1443-
1444- string_to_uuid(uuid_str, &uuid);
1445-
1446- prop.type = BT_PROPERTY_UUIDS;
1447- prop.val = uuid.uu;
1448- prop.len = MAX_UUID_SIZE;
1449-
1450- /* Send the event to the BTIF */
1451- HAL_CBACK(bt_hal_cbacks, remote_device_properties_cb,
1452- BT_STATUS_SUCCESS, &bd_addr, 1, &prop);
1453- break;
1454- }
1455- }
1421+
1422+ bond_state_changed(BT_STATUS_SUCCESS, bd_addr, BT_BOND_STATE_BONDED);
14561423 }
14571424
14581425 if (p_data->disc_res.num_uuids != 0) {
@@ -1662,7 +1629,7 @@ static void btif_dm_upstreams_evt(uint16_t event, char* p_param) {
16621629 break;
16631630
16641631 case BTA_DM_BOND_CANCEL_CMPL_EVT:
1665- if (is_bonding_or_sdp()) {
1632+ if (pairing_cb.state == BT_BOND_STATE_BONDING) {
16661633 bd_addr = pairing_cb.bd_addr;
16671634 btm_set_bond_type_dev(pairing_cb.bd_addr, BOND_TYPE_UNKNOWN);
16681635 bond_state_changed((bt_status_t)p_data->bond_cancel_cmpl.result,
@@ -2310,7 +2277,7 @@ bt_status_t btif_dm_cancel_bond(const RawAddress* bd_addr) {
23102277 ** 1. Restore scan modes
23112278 ** 2. special handling for HID devices
23122279 */
2313- if (is_bonding_or_sdp()) {
2280+ if (pairing_cb.state == BT_BOND_STATE_BONDING) {
23142281 if (pairing_cb.is_ssp) {
23152282 if (pairing_cb.is_le_only) {
23162283 BTA_DmBleSecurityGrant(*bd_addr, BTA_DM_SEC_PAIR_NOT_SPT);
@@ -2502,7 +2469,7 @@ bt_status_t btif_dm_get_remote_services(const RawAddress& remote_addr) {
25022469
25032470 /*******************************************************************************
25042471 *
2505- * Function btif_dm_get_remote_services_by_transport
2472+ * Function btif_dm_get_remote_services_transport
25062473 *
25072474 * Description Start SDP to get remote services by transport
25082475 *
@@ -3204,7 +3171,7 @@ bt_status_t btif_le_test_mode(uint16_t opcode, uint8_t* buf, uint8_t len) {
32043171
32053172 void btif_dm_on_disable() {
32063173 /* cancel any pending pairing requests */
3207- if (is_bonding_or_sdp()) {
3174+ if (pairing_cb.state == BT_BOND_STATE_BONDING) {
32083175 BTIF_TRACE_DEBUG("%s: Cancel pending pairing request", __func__);
32093176 btif_dm_cancel_bond(&pairing_cb.bd_addr);
32103177 }
--- a/btif/src/btif_storage.cc
+++ b/btif/src/btif_storage.cc
@@ -35,6 +35,7 @@
3535 #include <alloca.h>
3636 #include <base/logging.h>
3737 #include <ctype.h>
38+#include <log/log.h>
3839 #include <stdlib.h>
3940 #include <string.h>
4041 #include <time.h>
@@ -783,6 +784,47 @@ bt_status_t btif_storage_remove_bonded_device(
783784 return ret ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
784785 }
785786
787+/* Some devices hardcode sample LTK value from spec, instead of generating one.
788+ * Treat such devices as insecure, and remove such bonds when bluetooth
789+ * restarts. Removing them after disconnection is handled separately.
790+ *
791+ * We still allow such devices to bond in order to give the user a chance to
792+ * update firmware.
793+ */
794+static void remove_devices_with_sample_ltk() {
795+ std::vector<RawAddress> bad_ltk;
796+ for (const btif_config_section_iter_t* iter = btif_config_section_begin();
797+ iter != btif_config_section_end();
798+ iter = btif_config_section_next(iter)) {
799+ const std::string name(btif_config_section_name(iter));
800+ if (!RawAddress::IsValidAddress(name)) {
801+ continue;
802+ }
803+
804+ RawAddress bd_addr;
805+ RawAddress::FromString(name, bd_addr);
806+
807+ tBTA_LE_KEY_VALUE key;
808+ memset(&key, 0, sizeof(key));
809+
810+ if (btif_storage_get_ble_bonding_key(
811+ &bd_addr, BTIF_DM_LE_KEY_PENC, (char*)&key,
812+ sizeof(tBTM_LE_PENC_KEYS)) == BT_STATUS_SUCCESS) {
813+ if (is_sample_ltk(key.penc_key.ltk)) {
814+ bad_ltk.push_back(bd_addr);
815+ }
816+ }
817+ }
818+
819+ for (RawAddress address : bad_ltk) {
820+ android_errorWriteLog(0x534e4554, "128437297");
821+ LOG(ERROR) << __func__
822+ << ": removing bond to device using test TLK: " << address;
823+
824+ btif_storage_remove_bonded_device(&address);
825+ }
826+}
827+
786828 /*******************************************************************************
787829 *
788830 * Function btif_storage_load_bonded_devices
@@ -810,6 +852,8 @@ bt_status_t btif_storage_load_bonded_devices(void) {
810852 bt_uuid_t remote_uuids[BT_MAX_NUM_UUIDS];
811853 bt_status_t status;
812854
855+ remove_devices_with_sample_ltk();
856+
813857 btif_in_fetch_bonded_devices(&bonded_devices, 1);
814858
815859 /* Now send the adapter_properties_cb with all adapter_properties */
--- a/device/src/controller.cc
+++ b/device/src/controller.cc
@@ -253,6 +253,10 @@ static future_t* start_up(void) {
253253 response, &number_of_local_supported_codecs, local_supported_codecs);
254254 }
255255
256+ if (!HCI_READ_ENCR_KEY_SIZE_SUPPORTED(supported_commands)) {
257+ LOG(FATAL) << " Controller must support Read Encryption Key Size command";
258+ }
259+
256260 readable = true;
257261 return future_new_immediate(FUTURE_SUCCESS);
258262 }
--- a/stack/btm/btm_sec.cc
+++ b/stack/btm/btm_sec.cc
@@ -24,6 +24,7 @@
2424
2525 #define LOG_TAG "bt_btm_sec"
2626
27+#include <log/log.h>
2728 #include <stdarg.h>
2829 #include <stdio.h>
2930 #include <string.h>
@@ -42,6 +43,8 @@
4243
4344 #include "gatt_int.h"
4445
46+#include "bta/dm/bta_dm_int.h"
47+
4548 #define BTM_SEC_MAX_COLLISION_DELAY (5000)
4649
4750 #ifdef APPL_AUTH_WRITE_EXCEPTION
@@ -4660,6 +4663,19 @@ void btm_sec_disconnected(uint16_t handle, uint8_t reason) {
46604663 BTM_TRACE_EVENT("%s after update sec_flags=0x%x", __func__,
46614664 p_dev_rec->sec_flags);
46624665
4666+ /* Some devices hardcode sample LTK value from spec, instead of generating
4667+ * one. Treat such devices as insecure, and remove such bonds on
4668+ * disconnection.
4669+ */
4670+ if (is_sample_ltk(p_dev_rec->ble.keys.pltk)) {
4671+ android_errorWriteLog(0x534e4554, "128437297");
4672+ LOG(INFO) << __func__ << " removing bond to device that used sample LTK";
4673+
4674+ tBTA_DM_MSG p_data;
4675+ p_data.remove_dev.bd_addr = p_dev_rec->bd_addr;
4676+ bta_dm_remove_device(&p_data);
4677+ }
4678+
46634679 if (p_dev_rec->sec_state == BTM_SEC_STATE_DISCONNECTING_BOTH) {
46644680 p_dev_rec->sec_state = (transport == BT_TRANSPORT_LE)
46654681 ? BTM_SEC_STATE_DISCONNECTING
--- a/stack/btu/btu_hcif.cc
+++ b/stack/btu/btu_hcif.cc
@@ -32,6 +32,7 @@
3232 #include <base/location.h>
3333 #include <base/logging.h>
3434 #include <base/threading/thread.h>
35+#include <log/log.h>
3536 #include <stdio.h>
3637 #include <stdlib.h>
3738 #include <string.h>
@@ -705,6 +706,31 @@ static void btu_hcif_rmt_name_request_comp_evt(uint8_t* p, uint16_t evt_len) {
705706 btm_sec_rmt_name_request_complete(&bd_addr, p, status);
706707 }
707708
709+constexpr uint8_t MIN_KEY_SIZE = 7;
710+
711+static void read_encryption_key_size_complete_after_encryption_change(
712+ uint8_t status, uint16_t handle, uint8_t key_size) {
713+ if (status != HCI_SUCCESS) {
714+ HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
715+ btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
716+ return;
717+ }
718+
719+ if (key_size < MIN_KEY_SIZE) {
720+ android_errorWriteLog(0x534e4554, "124301137");
721+ HCI_TRACE_ERROR(
722+ "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
723+ "%d",
724+ __func__, handle, key_size);
725+
726+ btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
727+ return;
728+ }
729+
730+ // good key size - succeed
731+ btm_acl_encrypt_change(handle, status, 1 /* enable */);
732+ btm_sec_encrypt_change(handle, status, 1 /* enable */);
733+}
708734 /*******************************************************************************
709735 *
710736 * Function btu_hcif_encryption_change_evt
@@ -723,8 +749,15 @@ static void btu_hcif_encryption_change_evt(uint8_t* p) {
723749 STREAM_TO_UINT16(handle, p);
724750 STREAM_TO_UINT8(encr_enable, p);
725751
726- btm_acl_encrypt_change(handle, status, encr_enable);
727- btm_sec_encrypt_change(handle, status, encr_enable);
752+ if (status != HCI_SUCCESS || encr_enable == 0 ||
753+ BTM_IsBleConnection(handle)) {
754+ btm_acl_encrypt_change(handle, status, encr_enable);
755+ btm_sec_encrypt_change(handle, status, encr_enable);
756+ } else {
757+ btsnd_hcic_read_encryption_key_size(
758+ handle,
759+ base::Bind(&read_encryption_key_size_complete_after_encryption_change));
760+ }
728761 }
729762
730763 /*******************************************************************************
@@ -1622,22 +1655,48 @@ static void btu_hcif_enhanced_flush_complete_evt(void) {
16221655 * End of Simple Pairing Events
16231656 **********************************************/
16241657
1625-/**********************************************
1626- * BLE Events
1627- **********************************************/
1658+static void read_encryption_key_size_complete_after_key_refresh(
1659+ uint8_t status, uint16_t handle, uint8_t key_size) {
1660+ if (status != HCI_SUCCESS) {
1661+ HCI_TRACE_WARNING("%s: disconnecting, status: 0x%02x", __func__, status);
1662+ btsnd_hcic_disconnect(handle, HCI_ERR_PEER_USER);
1663+ return;
1664+ }
1665+
1666+ if (key_size < MIN_KEY_SIZE) {
1667+ android_errorWriteLog(0x534e4554, "124301137");
1668+ HCI_TRACE_WARNING(
1669+ "%s encryption key too short, disconnecting. handle: 0x%02x, key_size: "
1670+ "%d",
1671+ __func__, handle, key_size);
1672+
1673+ btsnd_hcic_disconnect(handle, HCI_ERR_HOST_REJECT_SECURITY);
1674+ return;
1675+ }
1676+
1677+ btm_sec_encrypt_change(handle, status, 1 /* enc_enable */);
1678+}
1679+
16281680 static void btu_hcif_encryption_key_refresh_cmpl_evt(uint8_t* p) {
16291681 uint8_t status;
1630- uint8_t enc_enable = 0;
16311682 uint16_t handle;
16321683
16331684 STREAM_TO_UINT8(status, p);
16341685 STREAM_TO_UINT16(handle, p);
16351686
1636- if (status == HCI_SUCCESS) enc_enable = 1;
1637-
1638- btm_sec_encrypt_change(handle, status, enc_enable);
1687+ if (status != HCI_SUCCESS || BTM_IsBleConnection(handle)) {
1688+ btm_sec_encrypt_change(handle, status, (status == HCI_SUCCESS) ? 1 : 0);
1689+ } else {
1690+ btsnd_hcic_read_encryption_key_size(
1691+ handle,
1692+ base::Bind(&read_encryption_key_size_complete_after_key_refresh));
1693+ }
16391694 }
16401695
1696+/**********************************************
1697+ * BLE Events
1698+ **********************************************/
1699+
16411700 static void btu_ble_ll_conn_complete_evt(uint8_t* p, uint16_t evt_len) {
16421701 btm_ble_conn_complete(p, evt_len, false);
16431702 }
--- a/stack/hcic/hcicmds.cc
+++ b/stack/hcic/hcicmds.cc
@@ -29,6 +29,7 @@
2929 #include "hcidefs.h"
3030 #include "hcimsgs.h"
3131
32+#include <base/bind.h>
3233 #include <stddef.h>
3334 #include <string.h>
3435
@@ -1311,6 +1312,32 @@ void btsnd_hcic_read_rssi(uint16_t handle) {
13111312 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
13121313 }
13131314
1315+static void read_encryption_key_size_complete(
1316+ ReadEncKeySizeCb cb, uint8_t* return_parameters,
1317+ uint16_t return_parameters_length) {
1318+ uint8_t status;
1319+ uint16_t handle;
1320+ uint8_t key_size;
1321+ STREAM_TO_UINT8(status, return_parameters);
1322+ STREAM_TO_UINT16(handle, return_parameters);
1323+ STREAM_TO_UINT8(key_size, return_parameters);
1324+
1325+ std::move(cb).Run(status, handle, key_size);
1326+}
1327+
1328+void btsnd_hcic_read_encryption_key_size(uint16_t handle, ReadEncKeySizeCb cb) {
1329+ constexpr uint8_t len = 2;
1330+ uint8_t param[len];
1331+ memset(param, 0, len);
1332+
1333+ uint8_t* p = param;
1334+ UINT16_TO_STREAM(p, handle);
1335+
1336+ btu_hcif_send_cmd_with_cb(
1337+ FROM_HERE, HCI_READ_ENCR_KEY_SIZE, param, len,
1338+ base::Bind(&read_encryption_key_size_complete, base::Passed(&cb)));
1339+}
1340+
13141341 void btsnd_hcic_read_failed_contact_counter(uint16_t handle) {
13151342 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
13161343 uint8_t* pp = (uint8_t*)(p + 1);
--- a/stack/include/bt_types.h
+++ b/stack/include/bt_types.h
@@ -21,6 +21,7 @@
2121
2222 #include <stdbool.h>
2323 #include <stdint.h>
24+#include <string.h>
2425
2526 #ifndef FALSE
2627 #define FALSE false
@@ -929,4 +930,12 @@ typedef uint8_t tBT_DEVICE_TYPE;
929930 /* Define a function for logging */
930931 typedef void(BT_LOG_FUNC)(int trace_type, const char* fmt_str, ...);
931932
933+static inline bool is_sample_ltk(const BT_OCTET16 ltk) {
934+ /* Sample LTK from BT Spec 5.1 | Vol 6, Part C 1
935+ * 0x4C68384139F574D836BCF34E9DFB01BF */
936+ const uint8_t SAMPLE_LTK[] = {0xbf, 0x01, 0xfb, 0x9d, 0x4e, 0xf3, 0xbc, 0x36,
937+ 0xd8, 0x74, 0xf5, 0x39, 0x41, 0x38, 0x68, 0x4c};
938+ return memcmp(ltk, SAMPLE_LTK, BT_OCTET16_LEN) == 0;
939+}
940+
932941 #endif
--- a/stack/include/btm_ble_api.h
+++ b/stack/include/btm_ble_api.h
@@ -366,6 +366,18 @@ extern void BTM_ReadConnectionAddr(const RawAddress& remote_bda,
366366
367367 /*******************************************************************************
368368 *
369+ * Function BTM_IsBleConnection
370+ *
371+ * Description This function is called to check if the connection handle
372+ * for an LE link
373+ *
374+ * Returns true if connection is LE link, otherwise false.
375+ *
376+ ******************************************************************************/
377+extern bool BTM_IsBleConnection(uint16_t conn_handle);
378+
379+/*******************************************************************************
380+ *
369381 * Function BTM_ReadRemoteConnectionAddr
370382 *
371383 * Description Read the remote device address currently used.
--- a/stack/include/hcimsgs.h
+++ b/stack/include/hcimsgs.h
@@ -612,6 +612,9 @@ extern void btsnd_hcic_write_cur_iac_lap(
612612
613613 extern void btsnd_hcic_get_link_quality(uint16_t handle); /* Get Link Quality */
614614 extern void btsnd_hcic_read_rssi(uint16_t handle); /* Read RSSI */
615+using ReadEncKeySizeCb = base::Callback<void(uint8_t, uint16_t, uint8_t)>;
616+extern void btsnd_hcic_read_encryption_key_size(uint16_t handle,
617+ ReadEncKeySizeCb cb);
615618 extern void btsnd_hcic_read_failed_contact_counter(uint16_t handle);
616619 extern void btsnd_hcic_read_automatic_flush_timeout(uint16_t handle);
617620 extern void btsnd_hcic_enable_test_mode(