Loading system/gd/shim/iinquiry.h +10 −3 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ #pragma once #include <cstddef> #include <cstdint> #include <functional> #include <string> #include <vector> /** Loading @@ -25,9 +27,14 @@ namespace bluetooth { namespace shim { using InquiryResultCallback = std::function<void(std::vector<const uint8_t> data)>; using InquiryResultWithRssiCallback = std::function<void(std::vector<const uint8_t> data)>; using ExtendedInquiryResultCallback = std::function<void(std::vector<const uint8_t> data)>; using InquiryResultCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset)>; using InquiryResultWithRssiCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi)>; using ExtendedInquiryResultCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len)>; using InquiryCompleteCallback = std::function<void(uint16_t status)>; struct LegacyInquiryCallbacks { Loading system/gd/shim/inquiry.cc +39 −9 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace bluetooth { namespace shim { constexpr size_t kMaxExtendedInquiryResponse = 240; struct Inquiry::impl { void Result(hci::InquiryResultView view); void ResultWithRssi(hci::InquiryResultWithRssiView view); Loading Loading @@ -61,33 +63,61 @@ struct Inquiry::impl { const ModuleFactory Inquiry::Factory = ModuleFactory([]() { return new Inquiry(); }); void Inquiry::impl::Result(hci::InquiryResultView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.result_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.result_callback(v); for (auto& response : view.GetInquiryResults()) { callbacks_.result_callback(response.bd_addr_.ToString(), static_cast<uint8_t>(response.page_scan_repetition_mode_), response.class_of_device_.ToString(), response.clock_offset_); } } void Inquiry::impl::ResultWithRssi(hci::InquiryResultWithRssiView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.result_with_rssi_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.result_with_rssi_callback(v); for (auto& response : view.GetInquiryResults()) { callbacks_.result_with_rssi_callback(response.address_.ToString(), static_cast<uint8_t>(response.page_scan_repetition_mode_), response.class_of_device_.ToString(), response.clock_offset_, response.rssi_); } } void Inquiry::impl::ExtendedResult(hci::ExtendedInquiryResultView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.extended_result_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.extended_result_callback(v); uint8_t gap_data_buffer[kMaxExtendedInquiryResponse]; uint8_t* data = nullptr; size_t data_len = 0; if (!view.GetExtendedInquiryResponse().empty()) { bzero(gap_data_buffer, sizeof(gap_data_buffer)); uint8_t* p = gap_data_buffer; for (auto gap_data : view.GetExtendedInquiryResponse()) { *p++ = gap_data.data_.size() + sizeof(gap_data.data_type_); *p++ = static_cast<uint8_t>(gap_data.data_type_); p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) + gap_data.data_.size(); } data = gap_data_buffer; data_len = p - data; } callbacks_.extended_result_callback(view.GetAddress().ToString(), static_cast<uint8_t>(view.GetPageScanRepetitionMode()), view.GetClassOfDevice().ToString(), static_cast<uint16_t>(view.GetClockOffset()), static_cast<int8_t>(view.GetRssi()), data, data_len); } void Inquiry::impl::Complete(hci::ErrorCode status) { ASSERT(callbacks_.complete_callback != nullptr); limited_inquiry_active_ = false; general_inquiry_active_ = false; callbacks_.complete_callback(static_cast<uint16_t>(status)); } void Inquiry::impl::RegisterInquiryCallbacks(LegacyInquiryCallbacks callbacks) { callbacks_ = callbacks; ASSERT(callbacks_.result_callback); ASSERT(callbacks_.result_with_rssi_callback); ASSERT(callbacks_.extended_result_callback); ASSERT(callbacks_.complete_callback); } void Inquiry::impl::UnregisterInquiryCallbacks() { Loading system/main/shim/btm.cc +75 −28 Original line number Diff line number Diff line Loading @@ -17,21 +17,21 @@ #define LOG_TAG "bt_shim_btm" #include <algorithm> #include <cstddef> #include <cstdint> #include <cstring> #include "stack/btm/btm_int_types.h" #include "main/shim/btm.h" #include "main/shim/controller.h" #include "main/shim/entry.h" #include "main/shim/shim.h" #include "osi/include/log.h" #include "stack/btm/btm_int_types.h" #include "types/class_of_device.h" #include "types/raw_address.h" extern tBTM_CB btm_cb; static constexpr size_t kMaxInquiryResultSize = 4096; static uint8_t inquiry_result_buf[kMaxInquiryResultSize]; static constexpr size_t kRemoteDeviceNameLength = 248; static constexpr uint8_t kAdvDataInfoNotPresent = 0xff; Loading @@ -41,6 +41,8 @@ static constexpr uint8_t kNotPeriodicAdvertisement = 0x00; static constexpr bool kActiveScanning = true; static constexpr bool kPassiveScanning = false; using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME; extern void btm_process_cancel_complete(uint8_t status, uint8_t mode); extern void btm_process_inq_complete(uint8_t status, uint8_t result_type); extern void btm_ble_process_adv_addr(RawAddress& raw_address, Loading @@ -51,29 +53,59 @@ extern void btm_ble_process_adv_pkt_cont( int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len, uint8_t* data); using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME; /** * */ void bluetooth::shim::Btm::OnInquiryResult(std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); extern void btm_api_process_inquiry_result(const RawAddress& raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset); extern void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi); extern void btm_api_process_extended_inquiry_result( RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi, const uint8_t* eir_data, size_t eir_len); void bluetooth::shim::Btm::OnInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_inquiry_result(raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset); } void bluetooth::shim::Btm::OnInquiryResultWithRssi( std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_inquiry_result_with_rssi( raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset, rssi); } void bluetooth::shim::Btm::OnExtendedInquiryResult( std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_extended_inquiry_result(raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset, rssi, gap_data, gap_data_len); } void bluetooth::shim::Btm::OnInquiryComplete(uint16_t status) { Loading Loading @@ -151,11 +183,18 @@ bool bluetooth::shim::Btm::StartInquiry(uint8_t mode, uint8_t duration, case kGeneralInquiryMode: { LegacyInquiryCallbacks legacy_inquiry_callbacks{ .result_callback = std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1), .result_with_rssi_callback = std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1), .extended_result_callback = std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1), std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), .result_with_rssi_callback = std::bind( &Btm::OnInquiryResultWithRssi, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), .extended_result_callback = std::bind( &Btm::OnExtendedInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7), .complete_callback = std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1), }; Loading Loading @@ -186,6 +225,7 @@ bool bluetooth::shim::Btm::StartInquiry(uint8_t mode, uint8_t duration, } void bluetooth::shim::Btm::CancelInquiry() { LOG_DEBUG(LOG_TAG, "%s", __func__); bluetooth::shim::GetInquiry()->StopInquiry(); } Loading Loading @@ -216,11 +256,18 @@ bool bluetooth::shim::Btm::StartPeriodicInquiry( case kGeneralInquiryMode: { LegacyInquiryCallbacks legacy_inquiry_callbacks{ .result_callback = std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1), .result_with_rssi_callback = std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1), .extended_result_callback = std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1), std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), .result_with_rssi_callback = std::bind( &Btm::OnInquiryResultWithRssi, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), .extended_result_callback = std::bind( &Btm::OnExtendedInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7), .complete_callback = std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1), }; Loading system/main/shim/btm.h +13 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <cstddef> #include <cstdint> #include <mutex> #include <unordered_map> Loading Loading @@ -132,9 +133,18 @@ class Btm { ~Btm() = default; // Inquiry result callbacks void OnInquiryResult(std::vector<const uint8_t> result); void OnInquiryResultWithRssi(std::vector<const uint8_t> result); void OnExtendedInquiryResult(std::vector<const uint8_t> result); void OnInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset); void OnInquiryResultWithRssi(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi); void OnExtendedInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len); void OnInquiryComplete(uint16_t status); // Inquiry API Loading system/main/shim/btm_api.cc +230 −4 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ #include <base/callback.h> #include "common/time_util.h" #include "device/include/controller.h" #include "main/shim/btm.h" #include "main/shim/btm_api.h" #include "osi/include/log.h" #include "stack/btm/btm_int_types.h" #include "types/class_of_device.h" #include "types/raw_address.h" static bluetooth::shim::Btm shim_btm; Loading @@ -31,11 +34,236 @@ static bluetooth::shim::Btm shim_btm; */ extern tBTM_CB btm_cb; extern bool btm_inq_find_bdaddr(const RawAddress& p_bda); extern tINQ_DB_ENT* btm_inq_db_find(const RawAddress& raw_address); extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda); extern void btm_acl_update_busy_level(tBTM_BLI_EVENT event); extern void btm_clear_all_pending_le_entry(void); extern void btm_clr_inq_result_flt(void); extern void btm_set_eir_uuid(uint8_t* p_eir, tBTM_INQ_RESULTS* p_results); extern void btm_sort_inq_result(void); static bool max_responses_reached() { return (btm_cb.btm_inq_vars.inqparms.max_resps && btm_cb.btm_inq_vars.inq_cmpl_info.num_resp >= btm_cb.btm_inq_vars.inqparms.max_resps); } static bool is_periodic_inquiry_active() { return btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE; } static bool has_le_device(tBT_DEVICE_TYPE device_type) { return device_type & BT_DEVICE_TYPE_BLE; } static bool is_classic_device(tBT_DEVICE_TYPE device_type) { return device_type == BT_DEVICE_TYPE_BREDR; } static bool has_classic_device(tBT_DEVICE_TYPE device_type) { return device_type & BT_DEVICE_TYPE_BREDR; } static bool is_dual_mode_device(tBT_DEVICE_TYPE device_type) { return device_type == BT_DEVICE_TYPE_DUMO; } static bool is_observing_or_active_scanning() { return btm_cb.btm_inq_vars.inqparms.mode & BTM_BLE_INQUIRY_MASK; } static void check_exceeded_responses(tBT_DEVICE_TYPE device_type, bool scan_rsp) { if (!is_periodic_inquiry_active() && max_responses_reached() && ((is_observing_or_active_scanning() && is_dual_mode_device(device_type) && scan_rsp) || (is_observing_or_active_scanning()))) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s Device max responses found...cancelling inquiry", __func__); } } void btm_api_process_inquiry_result(const RawAddress& raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); CHECK(p_i != nullptr); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && is_classic_device(p_i->inq_info.results.device_type)) { return; } p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, nullptr, 0); } void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } bool update = false; if (btm_inq_find_bdaddr(raw_address)) { if (btm_cb.btm_inq_vars.inqparms.report_dup && p_i != nullptr && (rssi > p_i->inq_info.results.rssi || p_i->inq_info.results.rssi == 0 || has_classic_device(p_i->inq_info.results.device_type))) { update = true; } } bool is_new = true; if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); CHECK(p_i != nullptr); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && is_classic_device(p_i->inq_info.results.device_type)) { is_new = false; } p_i->inq_info.results.rssi = rssi; if (is_new) { p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } if (is_new || update) { (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, nullptr, 0); } } void btm_api_process_extended_inquiry_result(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi, const uint8_t* eir_data, size_t eir_len) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } bool update = false; if (btm_inq_find_bdaddr(raw_address) && p_i != nullptr) { update = true; } bool is_new = true; if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR)) { is_new = false; } p_i->inq_info.results.rssi = rssi; if (is_new) { p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } if (is_new || update) { memset(p_i->inq_info.results.eir_uuid, 0, BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8)); btm_set_eir_uuid(const_cast<uint8_t*>(eir_data), &p_i->inq_info.results); uint8_t* p_eir_data = const_cast<uint8_t*>(eir_data); (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, p_eir_data, eir_len); } } tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms, tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb) { Loading @@ -43,13 +271,11 @@ tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms, CHECK(p_results_cb != nullptr); CHECK(p_cmpl_cb != nullptr); btm_cb.btm_inq_vars.inq_cmpl_info.num_resp = 0; /* Clear the results counter */ uint8_t classic_mode = p_inqparms->mode & 0x0f; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp = 0; shim_btm.StartActiveScanning(); uint8_t classic_mode = p_inqparms->mode & 0x0f; if (!shim_btm.SetInquiryFilter(classic_mode, p_inqparms->filter_cond_type, p_inqparms->filter_cond)) { LOG_WARN(LOG_TAG, "%s Unable to set inquiry filter", __func__); Loading Loading
system/gd/shim/iinquiry.h +10 −3 Original line number Diff line number Diff line Loading @@ -15,8 +15,10 @@ */ #pragma once #include <cstddef> #include <cstdint> #include <functional> #include <string> #include <vector> /** Loading @@ -25,9 +27,14 @@ namespace bluetooth { namespace shim { using InquiryResultCallback = std::function<void(std::vector<const uint8_t> data)>; using InquiryResultWithRssiCallback = std::function<void(std::vector<const uint8_t> data)>; using ExtendedInquiryResultCallback = std::function<void(std::vector<const uint8_t> data)>; using InquiryResultCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset)>; using InquiryResultWithRssiCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi)>; using ExtendedInquiryResultCallback = std::function<void(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len)>; using InquiryCompleteCallback = std::function<void(uint16_t status)>; struct LegacyInquiryCallbacks { Loading
system/gd/shim/inquiry.cc +39 −9 Original line number Diff line number Diff line Loading @@ -32,6 +32,8 @@ namespace bluetooth { namespace shim { constexpr size_t kMaxExtendedInquiryResponse = 240; struct Inquiry::impl { void Result(hci::InquiryResultView view); void ResultWithRssi(hci::InquiryResultWithRssiView view); Loading Loading @@ -61,33 +63,61 @@ struct Inquiry::impl { const ModuleFactory Inquiry::Factory = ModuleFactory([]() { return new Inquiry(); }); void Inquiry::impl::Result(hci::InquiryResultView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.result_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.result_callback(v); for (auto& response : view.GetInquiryResults()) { callbacks_.result_callback(response.bd_addr_.ToString(), static_cast<uint8_t>(response.page_scan_repetition_mode_), response.class_of_device_.ToString(), response.clock_offset_); } } void Inquiry::impl::ResultWithRssi(hci::InquiryResultWithRssiView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.result_with_rssi_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.result_with_rssi_callback(v); for (auto& response : view.GetInquiryResults()) { callbacks_.result_with_rssi_callback(response.address_.ToString(), static_cast<uint8_t>(response.page_scan_repetition_mode_), response.class_of_device_.ToString(), response.clock_offset_, response.rssi_); } } void Inquiry::impl::ExtendedResult(hci::ExtendedInquiryResultView view) { ASSERT(view.size() >= sizeof(uint16_t)); ASSERT(callbacks_.extended_result_callback != nullptr); std::vector<const uint8_t> v(view.begin() + sizeof(uint16_t), view.end()); callbacks_.extended_result_callback(v); uint8_t gap_data_buffer[kMaxExtendedInquiryResponse]; uint8_t* data = nullptr; size_t data_len = 0; if (!view.GetExtendedInquiryResponse().empty()) { bzero(gap_data_buffer, sizeof(gap_data_buffer)); uint8_t* p = gap_data_buffer; for (auto gap_data : view.GetExtendedInquiryResponse()) { *p++ = gap_data.data_.size() + sizeof(gap_data.data_type_); *p++ = static_cast<uint8_t>(gap_data.data_type_); p = (uint8_t*)memcpy(p, &gap_data.data_[0], gap_data.data_.size()) + gap_data.data_.size(); } data = gap_data_buffer; data_len = p - data; } callbacks_.extended_result_callback(view.GetAddress().ToString(), static_cast<uint8_t>(view.GetPageScanRepetitionMode()), view.GetClassOfDevice().ToString(), static_cast<uint16_t>(view.GetClockOffset()), static_cast<int8_t>(view.GetRssi()), data, data_len); } void Inquiry::impl::Complete(hci::ErrorCode status) { ASSERT(callbacks_.complete_callback != nullptr); limited_inquiry_active_ = false; general_inquiry_active_ = false; callbacks_.complete_callback(static_cast<uint16_t>(status)); } void Inquiry::impl::RegisterInquiryCallbacks(LegacyInquiryCallbacks callbacks) { callbacks_ = callbacks; ASSERT(callbacks_.result_callback); ASSERT(callbacks_.result_with_rssi_callback); ASSERT(callbacks_.extended_result_callback); ASSERT(callbacks_.complete_callback); } void Inquiry::impl::UnregisterInquiryCallbacks() { Loading
system/main/shim/btm.cc +75 −28 Original line number Diff line number Diff line Loading @@ -17,21 +17,21 @@ #define LOG_TAG "bt_shim_btm" #include <algorithm> #include <cstddef> #include <cstdint> #include <cstring> #include "stack/btm/btm_int_types.h" #include "main/shim/btm.h" #include "main/shim/controller.h" #include "main/shim/entry.h" #include "main/shim/shim.h" #include "osi/include/log.h" #include "stack/btm/btm_int_types.h" #include "types/class_of_device.h" #include "types/raw_address.h" extern tBTM_CB btm_cb; static constexpr size_t kMaxInquiryResultSize = 4096; static uint8_t inquiry_result_buf[kMaxInquiryResultSize]; static constexpr size_t kRemoteDeviceNameLength = 248; static constexpr uint8_t kAdvDataInfoNotPresent = 0xff; Loading @@ -41,6 +41,8 @@ static constexpr uint8_t kNotPeriodicAdvertisement = 0x00; static constexpr bool kActiveScanning = true; static constexpr bool kPassiveScanning = false; using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME; extern void btm_process_cancel_complete(uint8_t status, uint8_t mode); extern void btm_process_inq_complete(uint8_t status, uint8_t result_type); extern void btm_ble_process_adv_addr(RawAddress& raw_address, Loading @@ -51,29 +53,59 @@ extern void btm_ble_process_adv_pkt_cont( int8_t tx_power, int8_t rssi, uint16_t periodic_adv_int, uint8_t data_len, uint8_t* data); using BtmRemoteDeviceName = tBTM_REMOTE_DEV_NAME; /** * */ void bluetooth::shim::Btm::OnInquiryResult(std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); extern void btm_api_process_inquiry_result(const RawAddress& raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset); extern void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi); extern void btm_api_process_extended_inquiry_result( RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi, const uint8_t* eir_data, size_t eir_len); void bluetooth::shim::Btm::OnInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_inquiry_result(raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset); } void bluetooth::shim::Btm::OnInquiryResultWithRssi( std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_inquiry_result_with_rssi( raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset, rssi); } void bluetooth::shim::Btm::OnExtendedInquiryResult( std::vector<const uint8_t> result) { CHECK(result.size() < kMaxInquiryResultSize); std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len) { RawAddress raw_address; RawAddress::FromString(string_address, raw_address); ClassOfDevice class_of_device; ClassOfDevice::FromString(string_class_of_device, class_of_device); std::copy(result.begin(), result.end(), inquiry_result_buf); btm_api_process_extended_inquiry_result(raw_address, page_scan_rep_mode, class_of_device.cod, clock_offset, rssi, gap_data, gap_data_len); } void bluetooth::shim::Btm::OnInquiryComplete(uint16_t status) { Loading Loading @@ -151,11 +183,18 @@ bool bluetooth::shim::Btm::StartInquiry(uint8_t mode, uint8_t duration, case kGeneralInquiryMode: { LegacyInquiryCallbacks legacy_inquiry_callbacks{ .result_callback = std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1), .result_with_rssi_callback = std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1), .extended_result_callback = std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1), std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), .result_with_rssi_callback = std::bind( &Btm::OnInquiryResultWithRssi, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), .extended_result_callback = std::bind( &Btm::OnExtendedInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7), .complete_callback = std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1), }; Loading Loading @@ -186,6 +225,7 @@ bool bluetooth::shim::Btm::StartInquiry(uint8_t mode, uint8_t duration, } void bluetooth::shim::Btm::CancelInquiry() { LOG_DEBUG(LOG_TAG, "%s", __func__); bluetooth::shim::GetInquiry()->StopInquiry(); } Loading Loading @@ -216,11 +256,18 @@ bool bluetooth::shim::Btm::StartPeriodicInquiry( case kGeneralInquiryMode: { LegacyInquiryCallbacks legacy_inquiry_callbacks{ .result_callback = std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1), .result_with_rssi_callback = std::bind(&Btm::OnInquiryResultWithRssi, this, std::placeholders::_1), .extended_result_callback = std::bind(&Btm::OnExtendedInquiryResult, this, std::placeholders::_1), std::bind(&Btm::OnInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4), .result_with_rssi_callback = std::bind( &Btm::OnInquiryResultWithRssi, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5), .extended_result_callback = std::bind( &Btm::OnExtendedInquiryResult, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6, std::placeholders::_7), .complete_callback = std::bind(&Btm::OnInquiryComplete, this, std::placeholders::_1), }; Loading
system/main/shim/btm.h +13 −3 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #pragma once #include <cstddef> #include <cstdint> #include <mutex> #include <unordered_map> Loading Loading @@ -132,9 +133,18 @@ class Btm { ~Btm() = default; // Inquiry result callbacks void OnInquiryResult(std::vector<const uint8_t> result); void OnInquiryResultWithRssi(std::vector<const uint8_t> result); void OnExtendedInquiryResult(std::vector<const uint8_t> result); void OnInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset); void OnInquiryResultWithRssi(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi); void OnExtendedInquiryResult(std::string string_address, uint8_t page_scan_rep_mode, std::string string_class_of_device, uint16_t clock_offset, int8_t rssi, const uint8_t* gap_data, size_t gap_data_len); void OnInquiryComplete(uint16_t status); // Inquiry API Loading
system/main/shim/btm_api.cc +230 −4 Original line number Diff line number Diff line Loading @@ -18,11 +18,14 @@ #include <base/callback.h> #include "common/time_util.h" #include "device/include/controller.h" #include "main/shim/btm.h" #include "main/shim/btm_api.h" #include "osi/include/log.h" #include "stack/btm/btm_int_types.h" #include "types/class_of_device.h" #include "types/raw_address.h" static bluetooth::shim::Btm shim_btm; Loading @@ -31,11 +34,236 @@ static bluetooth::shim::Btm shim_btm; */ extern tBTM_CB btm_cb; extern bool btm_inq_find_bdaddr(const RawAddress& p_bda); extern tINQ_DB_ENT* btm_inq_db_find(const RawAddress& raw_address); extern tINQ_DB_ENT* btm_inq_db_new(const RawAddress& p_bda); extern void btm_acl_update_busy_level(tBTM_BLI_EVENT event); extern void btm_clear_all_pending_le_entry(void); extern void btm_clr_inq_result_flt(void); extern void btm_set_eir_uuid(uint8_t* p_eir, tBTM_INQ_RESULTS* p_results); extern void btm_sort_inq_result(void); static bool max_responses_reached() { return (btm_cb.btm_inq_vars.inqparms.max_resps && btm_cb.btm_inq_vars.inq_cmpl_info.num_resp >= btm_cb.btm_inq_vars.inqparms.max_resps); } static bool is_periodic_inquiry_active() { return btm_cb.btm_inq_vars.inq_active & BTM_PERIODIC_INQUIRY_ACTIVE; } static bool has_le_device(tBT_DEVICE_TYPE device_type) { return device_type & BT_DEVICE_TYPE_BLE; } static bool is_classic_device(tBT_DEVICE_TYPE device_type) { return device_type == BT_DEVICE_TYPE_BREDR; } static bool has_classic_device(tBT_DEVICE_TYPE device_type) { return device_type & BT_DEVICE_TYPE_BREDR; } static bool is_dual_mode_device(tBT_DEVICE_TYPE device_type) { return device_type == BT_DEVICE_TYPE_DUMO; } static bool is_observing_or_active_scanning() { return btm_cb.btm_inq_vars.inqparms.mode & BTM_BLE_INQUIRY_MASK; } static void check_exceeded_responses(tBT_DEVICE_TYPE device_type, bool scan_rsp) { if (!is_periodic_inquiry_active() && max_responses_reached() && ((is_observing_or_active_scanning() && is_dual_mode_device(device_type) && scan_rsp) || (is_observing_or_active_scanning()))) { LOG_INFO(LOG_TAG, "UNIMPLEMENTED %s Device max responses found...cancelling inquiry", __func__); } } void btm_api_process_inquiry_result(const RawAddress& raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); CHECK(p_i != nullptr); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && is_classic_device(p_i->inq_info.results.device_type)) { return; } p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->inq_info.results.rssi = BTM_INQ_RES_IGNORE_RSSI; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, nullptr, 0); } void btm_api_process_inquiry_result_with_rssi(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } bool update = false; if (btm_inq_find_bdaddr(raw_address)) { if (btm_cb.btm_inq_vars.inqparms.report_dup && p_i != nullptr && (rssi > p_i->inq_info.results.rssi || p_i->inq_info.results.rssi == 0 || has_classic_device(p_i->inq_info.results.device_type))) { update = true; } } bool is_new = true; if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); CHECK(p_i != nullptr); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && is_classic_device(p_i->inq_info.results.device_type)) { is_new = false; } p_i->inq_info.results.rssi = rssi; if (is_new) { p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } if (is_new || update) { (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, nullptr, 0); } } void btm_api_process_extended_inquiry_result(RawAddress raw_address, uint8_t page_scan_rep_mode, DEV_CLASS device_class, uint16_t clock_offset, int8_t rssi, const uint8_t* eir_data, size_t eir_len) { tINQ_DB_ENT* p_i = btm_inq_db_find(raw_address); if (max_responses_reached()) { if (p_i == nullptr || !has_le_device(p_i->inq_info.results.device_type)) { return; } } bool update = false; if (btm_inq_find_bdaddr(raw_address) && p_i != nullptr) { update = true; } bool is_new = true; if (p_i == nullptr) { p_i = btm_inq_db_new(raw_address); } else if (p_i->inq_count == btm_cb.btm_inq_vars.inq_counter && (p_i->inq_info.results.device_type == BT_DEVICE_TYPE_BREDR)) { is_new = false; } p_i->inq_info.results.rssi = rssi; if (is_new) { p_i->inq_info.results.page_scan_rep_mode = page_scan_rep_mode; p_i->inq_info.results.page_scan_per_mode = 0; // RESERVED p_i->inq_info.results.page_scan_mode = 0; // RESERVED p_i->inq_info.results.dev_class[0] = device_class[0]; p_i->inq_info.results.dev_class[1] = device_class[1]; p_i->inq_info.results.dev_class[2] = device_class[2]; p_i->inq_info.results.clock_offset = clock_offset | BTM_CLOCK_OFFSET_VALID; p_i->inq_info.results.inq_result_type = BTM_INQ_RESULT_BR; p_i->time_of_resp = bluetooth::common::time_get_os_boottime_ms(); p_i->inq_count = btm_cb.btm_inq_vars.inq_counter; p_i->inq_info.appl_knows_rem_name = false; if (p_i->inq_count != btm_cb.btm_inq_vars.inq_counter) { p_i->inq_info.results.device_type = BT_DEVICE_TYPE_BREDR; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp++; p_i->scan_rsp = false; } else { p_i->inq_info.results.device_type |= BT_DEVICE_TYPE_BREDR; } } check_exceeded_responses(p_i->inq_info.results.device_type, p_i->scan_rsp); if (btm_cb.btm_inq_vars.p_inq_results_cb == nullptr) { return; } if (is_new || update) { memset(p_i->inq_info.results.eir_uuid, 0, BTM_EIR_SERVICE_ARRAY_SIZE * (BTM_EIR_ARRAY_BITS / 8)); btm_set_eir_uuid(const_cast<uint8_t*>(eir_data), &p_i->inq_info.results); uint8_t* p_eir_data = const_cast<uint8_t*>(eir_data); (btm_cb.btm_inq_vars.p_inq_results_cb)(&p_i->inq_info.results, p_eir_data, eir_len); } } tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms, tBTM_INQ_RESULTS_CB* p_results_cb, tBTM_CMPL_CB* p_cmpl_cb) { Loading @@ -43,13 +271,11 @@ tBTM_STATUS bluetooth::shim::BTM_StartInquiry(tBTM_INQ_PARMS* p_inqparms, CHECK(p_results_cb != nullptr); CHECK(p_cmpl_cb != nullptr); btm_cb.btm_inq_vars.inq_cmpl_info.num_resp = 0; /* Clear the results counter */ uint8_t classic_mode = p_inqparms->mode & 0x0f; btm_cb.btm_inq_vars.inq_cmpl_info.num_resp = 0; shim_btm.StartActiveScanning(); uint8_t classic_mode = p_inqparms->mode & 0x0f; if (!shim_btm.SetInquiryFilter(classic_mode, p_inqparms->filter_cond_type, p_inqparms->filter_cond)) { LOG_WARN(LOG_TAG, "%s Unable to set inquiry filter", __func__); Loading