Loading system/device/include/interop_database.h +3 −2 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ static const interop_name_entry_t interop_name_database[] = { // Kenwood KMM-BT518HD - no audio when A2DP codec sample rate is changed {"KMM-BT51*HD", 11, INTEROP_DISABLE_AVDTP_RECONFIGURE}, // Nintendo Switch Pro Controller - does not set sniff interval dynamically. // Requires custom HID report command to change mode. // Nintendo Switch Pro Controller and Joy Con - do not set sniff interval // dynamically. They require custom HID report command to change mode. {"Pro Controller", 14, INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL}, {"Joy-Con", 7, INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL}, }; system/gd/l2cap/classic/internal/link_manager.cc +13 −0 Original line number Diff line number Diff line Loading @@ -90,8 +90,10 @@ void LinkManager::ConnectDynamicChannelServices(hci::Address device, acl_manager_->CreateConnection(device); if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) { pending_dynamic_channels_[device].push_back(psm); pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection)); } else { pending_dynamic_channels_[device] = {psm}; pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection)); } return; } Loading Loading @@ -130,6 +132,7 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::AclConnection> acl_conne link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); } // Remove device from pending links list, if any auto pending_link = pending_links_.find(device); Loading @@ -147,6 +150,16 @@ void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason) { if (pending_link == pending_links_.end()) { // There is no pending link, exit LOG_DEBUG("Connection to %s failed without a pending link", device.ToString().c_str()); if (pending_dynamic_channels_callbacks_.find(device) != pending_dynamic_channels_callbacks_.end()) { for (PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { callbacks.handler_->Post(common::BindOnce(std::move(callbacks.on_fail_callback_), DynamicChannelManager::ConnectionResult{ .hci_error = hci::ErrorCode::CONNECTION_TIMEOUT, })); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); } return; } for (auto& pending_fixed_channel_connection : pending_link->second.pending_fixed_channel_connections_) { Loading system/gd/l2cap/classic/internal/link_manager.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ class LinkManager : public hci::ConnectionCallbacks { std::unordered_map<hci::Address, PendingLink> pending_links_; std::unordered_map<hci::Address, Link> links_; std::unordered_map<hci::Address, std::list<Psm>> pending_dynamic_channels_; std::unordered_map<hci::Address, std::list<PendingDynamicChannelConnection>> pending_dynamic_channels_callbacks_; DISALLOW_COPY_AND_ASSIGN(LinkManager); }; Loading system/gd/neighbor/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ filegroup { filegroup { name: "BluetoothNeighborTestSources", srcs: [ "inquiry_test.cc", ], } system/gd/neighbor/inquiry.cc +79 −62 Original line number Diff line number Diff line Loading @@ -88,10 +88,18 @@ struct InquiryModule::impl { hci::InquiryScanType inquiry_scan_type_; int8_t inquiry_response_tx_power_; void EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command); void EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command); void OnCommandComplete(hci::CommandCompleteView view); void OnCommandStatus(hci::CommandStatusView status); void EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command); void OnCommandCompleteSync(hci::CommandCompleteView view); void OnEvent(hci::EventPacketView view); std::promise<void>* command_sync_{nullptr}; hci::HciLayer* hci_layer_; os::Handler* handler_; }; Loading @@ -103,33 +111,34 @@ neighbor::InquiryModule::impl::impl(neighbor::InquiryModule& module) : module_(m limited_lap_.lap_ = kLimitedInquiryAccessCode; } void neighbor::InquiryModule::impl::OnCommandCompleteSync(hci::CommandCompleteView view) { OnCommandComplete(view); ASSERT(command_sync_ != nullptr); command_sync_->set_value(); } void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView view) { switch (view.GetCommandOpCode()) { case hci::OpCode::INQUIRY_CANCEL: { auto packet = hci::InquiryCancelCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_one_shot_ == nullptr) { LOG_WARN("Received inquiry cancel without a one shot inquiry in progress"); } active_one_shot_ = nullptr; } break; case hci::OpCode::PERIODIC_INQUIRY_MODE: { auto packet = hci::PeriodicInquiryModeCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_periodic_ != nullptr) { LOG_DEBUG("Periodic inquiry started lap:%s", LapText(active_periodic_->lap_).c_str()); } } break; case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE: { auto packet = hci::ExitPeriodicInquiryModeCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_periodic_ == nullptr) { LOG_WARN("Received exit periodic inquiry without a periodic inquiry in progress"); } active_periodic_ = nullptr; } } break; case hci::OpCode::WRITE_INQUIRY_MODE: { auto packet = hci::WriteInquiryModeCompleteView::Create(view); Loading Loading @@ -186,14 +195,14 @@ void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView v void neighbor::InquiryModule::impl::OnCommandStatus(hci::CommandStatusView status) { ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS); ASSERT(status.GetNumHciCommandPackets() == 1); switch (status.GetCommandOpCode()) { case hci::OpCode::INQUIRY: { auto packet = hci::InquiryStatusView::Create(status); ASSERT(packet.IsValid()); ASSERT(active_one_shot_ != nullptr); if (active_one_shot_ != nullptr) { LOG_DEBUG("Inquiry started lap:%s", LapText(active_one_shot_->lap_).c_str()); } } break; default: Loading @@ -207,6 +216,7 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { case hci::EventCode::INQUIRY_COMPLETE: { auto packet = hci::InquiryCompleteView::Create(view); ASSERT(packet.IsValid()); LOG_DEBUG("inquiry complete"); active_one_shot_ = nullptr; inquiry_callbacks_.complete(packet.GetStatus()); } break; Loading @@ -214,8 +224,8 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { case hci::EventCode::INQUIRY_RESULT: { auto packet = hci::InquiryResultView::Create(view); ASSERT(packet.IsValid()); LOG_DEBUG("Inquiry result num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d", packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(), LOG_DEBUG("Inquiry result size:%zd num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d", packet.size(), packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(), hci::PageScanRepetitionModeText(packet.GetPageScanRepetitionMode()).c_str(), packet.GetClassOfDevice().ToString().c_str(), packet.GetClockOffset()); inquiry_callbacks_.result(packet); Loading Loading @@ -252,27 +262,59 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { */ void neighbor::InquiryModule::impl::RegisterCallbacks(InquiryCallbacks callbacks) { inquiry_callbacks_ = callbacks; hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::UnregisterCallbacks() { hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE); hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT); inquiry_callbacks_ = {nullptr, nullptr, nullptr, nullptr}; } void neighbor::InquiryModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command) { ASSERT(command_sync_ == nullptr); command_sync_ = new std::promise<void>(); auto command_received = command_sync_->get_future(); hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandCompleteSync, common::Unretained(this)), handler_); command_received.wait(); delete command_sync_; command_sync_ = nullptr; } void neighbor::InquiryModule::impl::StartOneShotInquiry(hci::Lap& lap, InquiryLength inquiry_length, NumResponses num_responses) { ASSERT(active_one_shot_ == nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); ASSERT(active_one_shot_ == nullptr); active_one_shot_ = ⪅ EnqueueCommandStatus(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses)); } void neighbor::InquiryModule::impl::StopOneShotInquiry() { ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::InquiryCancelBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); ASSERT(active_one_shot_ != nullptr); active_one_shot_ = nullptr; EnqueueCommandComplete(hci::InquiryCancelBuilder::Create()); } bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const { Loading @@ -282,20 +324,17 @@ bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const void neighbor::InquiryModule::impl::StartPeriodicInquiry(hci::Lap& lap, InquiryLength inquiry_length, NumResponses num_responses, PeriodLength max_delay, PeriodLength min_delay) { ASSERT(active_periodic_ == nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand( hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); ASSERT(active_periodic_ == nullptr); active_periodic_ = ⪅ EnqueueCommandComplete( hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay)); } void neighbor::InquiryModule::impl::StopPeriodicInquiry() { ASSERT(active_periodic_ != nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::ExitPeriodicInquiryModeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); active_periodic_ = nullptr; EnqueueCommandComplete(hci::ExitPeriodicInquiryModeBuilder::Create()); } bool neighbor::InquiryModule::impl::IsPeriodicInquiryActive(hci::Lap& lap) const { Loading @@ -310,31 +349,16 @@ void neighbor::InquiryModule::impl::Start() { hci_layer_ = module_.GetDependency<hci::HciLayer>(); handler_ = module_.GetHandler(); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create()); EnqueueCommandComplete(hci::ReadInquiryScanActivityBuilder::Create()); EnqueueCommandComplete(hci::ReadInquiryScanTypeBuilder::Create()); EnqueueCommandCompleteSync(hci::ReadInquiryModeBuilder::Create()); hci_layer_->EnqueueCommand(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); LOG_DEBUG("Started inquiry module"); } void neighbor::InquiryModule::impl::Stop() { hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE); hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT); LOG_INFO("Inquiry scan interval:%hd window:%hd", inquiry_scan_.interval, inquiry_scan_.window); LOG_INFO("Inquiry scan interval:%hu window:%hu", inquiry_scan_.interval, inquiry_scan_.window); LOG_INFO("Inquiry mode:%s scan_type:%s", hci::InquiryModeText(inquiry_mode_).c_str(), hci::InquiryScanTypeText(inquiry_scan_type_).c_str()); LOG_INFO("Inquiry response tx power:%hhd", inquiry_response_tx_power_); Loading @@ -342,18 +366,14 @@ void neighbor::InquiryModule::impl::Stop() { } void neighbor::InquiryModule::impl::SetInquiryMode(hci::InquiryMode mode) { hci_layer_->EnqueueCommand(hci::WriteInquiryModeBuilder::Create(mode), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryModeBuilder::Create(mode)); inquiry_mode_ = mode; LOG_DEBUG("Set inquiry mode"); LOG_DEBUG("Set inquiry mode:%s", hci::InquiryModeText(mode).c_str()); } void neighbor::InquiryModule::impl::SetScanActivity(ScanParameters params) { hci_layer_->EnqueueCommand(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window)); inquiry_scan_ = params; LOG_DEBUG("Set scan activity interval:0x%x/%.02fms window:0x%x/%.02fms", params.interval, ScanIntervalTimeMs(params.interval), params.window, ScanWindowTimeMs(params.window)); } Loading @@ -363,10 +383,7 @@ ScanParameters neighbor::InquiryModule::impl::GetScanActivity() const { } void neighbor::InquiryModule::impl::SetScanType(hci::InquiryScanType scan_type) { hci_layer_->EnqueueCommand(hci::WriteInquiryScanTypeBuilder::Create(scan_type), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryScanTypeBuilder::Create(scan_type)); LOG_DEBUG("Set scan type:%s", hci::InquiryScanTypeText(scan_type).c_str()); } Loading Loading @@ -411,7 +428,7 @@ void neighbor::InquiryModule::StartLimitedInquiry(InquiryLength inquiry_length, } void neighbor::InquiryModule::StopInquiry() { if (pimpl_->IsInquiryActive()) { if (!pimpl_->IsInquiryActive()) { LOG_WARN("Ignoring stop one shot inquiry as an inquiry is not active"); return; } Loading Loading @@ -448,7 +465,7 @@ void neighbor::InquiryModule::StartLimitedPeriodicInquiry(InquiryLength inquiry_ } void neighbor::InquiryModule::StopPeriodicInquiry() { if (pimpl_->IsInquiryActive()) { if (!pimpl_->IsInquiryActive()) { LOG_WARN("Ignoring stop periodic inquiry as an inquiry is not active"); return; } Loading Loading
system/device/include/interop_database.h +3 −2 Original line number Diff line number Diff line Loading @@ -177,7 +177,8 @@ static const interop_name_entry_t interop_name_database[] = { // Kenwood KMM-BT518HD - no audio when A2DP codec sample rate is changed {"KMM-BT51*HD", 11, INTEROP_DISABLE_AVDTP_RECONFIGURE}, // Nintendo Switch Pro Controller - does not set sniff interval dynamically. // Requires custom HID report command to change mode. // Nintendo Switch Pro Controller and Joy Con - do not set sniff interval // dynamically. They require custom HID report command to change mode. {"Pro Controller", 14, INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL}, {"Joy-Con", 7, INTEROP_HID_HOST_LIMIT_SNIFF_INTERVAL}, };
system/gd/l2cap/classic/internal/link_manager.cc +13 −0 Original line number Diff line number Diff line Loading @@ -90,8 +90,10 @@ void LinkManager::ConnectDynamicChannelServices(hci::Address device, acl_manager_->CreateConnection(device); if (pending_dynamic_channels_.find(device) != pending_dynamic_channels_.end()) { pending_dynamic_channels_[device].push_back(psm); pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection)); } else { pending_dynamic_channels_[device] = {psm}; pending_dynamic_channels_callbacks_[device].push_back(std::move(pending_dynamic_channel_connection)); } return; } Loading Loading @@ -130,6 +132,7 @@ void LinkManager::OnConnectSuccess(std::unique_ptr<hci::AclConnection> acl_conne link->SendConnectionRequest(psm, link->ReserveDynamicChannel()); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); } // Remove device from pending links list, if any auto pending_link = pending_links_.find(device); Loading @@ -147,6 +150,16 @@ void LinkManager::OnConnectFail(hci::Address device, hci::ErrorCode reason) { if (pending_link == pending_links_.end()) { // There is no pending link, exit LOG_DEBUG("Connection to %s failed without a pending link", device.ToString().c_str()); if (pending_dynamic_channels_callbacks_.find(device) != pending_dynamic_channels_callbacks_.end()) { for (PendingDynamicChannelConnection& callbacks : pending_dynamic_channels_callbacks_[device]) { callbacks.handler_->Post(common::BindOnce(std::move(callbacks.on_fail_callback_), DynamicChannelManager::ConnectionResult{ .hci_error = hci::ErrorCode::CONNECTION_TIMEOUT, })); } pending_dynamic_channels_.erase(device); pending_dynamic_channels_callbacks_.erase(device); } return; } for (auto& pending_fixed_channel_connection : pending_link->second.pending_fixed_channel_connections_) { Loading
system/gd/l2cap/classic/internal/link_manager.h +1 −0 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ class LinkManager : public hci::ConnectionCallbacks { std::unordered_map<hci::Address, PendingLink> pending_links_; std::unordered_map<hci::Address, Link> links_; std::unordered_map<hci::Address, std::list<Psm>> pending_dynamic_channels_; std::unordered_map<hci::Address, std::list<PendingDynamicChannelConnection>> pending_dynamic_channels_callbacks_; DISALLOW_COPY_AND_ASSIGN(LinkManager); }; Loading
system/gd/neighbor/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ filegroup { filegroup { name: "BluetoothNeighborTestSources", srcs: [ "inquiry_test.cc", ], }
system/gd/neighbor/inquiry.cc +79 −62 Original line number Diff line number Diff line Loading @@ -88,10 +88,18 @@ struct InquiryModule::impl { hci::InquiryScanType inquiry_scan_type_; int8_t inquiry_response_tx_power_; void EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command); void EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command); void OnCommandComplete(hci::CommandCompleteView view); void OnCommandStatus(hci::CommandStatusView status); void EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command); void OnCommandCompleteSync(hci::CommandCompleteView view); void OnEvent(hci::EventPacketView view); std::promise<void>* command_sync_{nullptr}; hci::HciLayer* hci_layer_; os::Handler* handler_; }; Loading @@ -103,33 +111,34 @@ neighbor::InquiryModule::impl::impl(neighbor::InquiryModule& module) : module_(m limited_lap_.lap_ = kLimitedInquiryAccessCode; } void neighbor::InquiryModule::impl::OnCommandCompleteSync(hci::CommandCompleteView view) { OnCommandComplete(view); ASSERT(command_sync_ != nullptr); command_sync_->set_value(); } void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView view) { switch (view.GetCommandOpCode()) { case hci::OpCode::INQUIRY_CANCEL: { auto packet = hci::InquiryCancelCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_one_shot_ == nullptr) { LOG_WARN("Received inquiry cancel without a one shot inquiry in progress"); } active_one_shot_ = nullptr; } break; case hci::OpCode::PERIODIC_INQUIRY_MODE: { auto packet = hci::PeriodicInquiryModeCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_periodic_ != nullptr) { LOG_DEBUG("Periodic inquiry started lap:%s", LapText(active_periodic_->lap_).c_str()); } } break; case hci::OpCode::EXIT_PERIODIC_INQUIRY_MODE: { auto packet = hci::ExitPeriodicInquiryModeCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); if (active_periodic_ == nullptr) { LOG_WARN("Received exit periodic inquiry without a periodic inquiry in progress"); } active_periodic_ = nullptr; } } break; case hci::OpCode::WRITE_INQUIRY_MODE: { auto packet = hci::WriteInquiryModeCompleteView::Create(view); Loading Loading @@ -186,14 +195,14 @@ void neighbor::InquiryModule::impl::OnCommandComplete(hci::CommandCompleteView v void neighbor::InquiryModule::impl::OnCommandStatus(hci::CommandStatusView status) { ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS); ASSERT(status.GetNumHciCommandPackets() == 1); switch (status.GetCommandOpCode()) { case hci::OpCode::INQUIRY: { auto packet = hci::InquiryStatusView::Create(status); ASSERT(packet.IsValid()); ASSERT(active_one_shot_ != nullptr); if (active_one_shot_ != nullptr) { LOG_DEBUG("Inquiry started lap:%s", LapText(active_one_shot_->lap_).c_str()); } } break; default: Loading @@ -207,6 +216,7 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { case hci::EventCode::INQUIRY_COMPLETE: { auto packet = hci::InquiryCompleteView::Create(view); ASSERT(packet.IsValid()); LOG_DEBUG("inquiry complete"); active_one_shot_ = nullptr; inquiry_callbacks_.complete(packet.GetStatus()); } break; Loading @@ -214,8 +224,8 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { case hci::EventCode::INQUIRY_RESULT: { auto packet = hci::InquiryResultView::Create(view); ASSERT(packet.IsValid()); LOG_DEBUG("Inquiry result num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d", packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(), LOG_DEBUG("Inquiry result size:%zd num_responses:%d addr:%s repetition_mode:%s cod:%s clock_offset:%d", packet.size(), packet.GetNumResponses(), packet.GetBdAddr().ToString().c_str(), hci::PageScanRepetitionModeText(packet.GetPageScanRepetitionMode()).c_str(), packet.GetClassOfDevice().ToString().c_str(), packet.GetClockOffset()); inquiry_callbacks_.result(packet); Loading Loading @@ -252,27 +262,59 @@ void neighbor::InquiryModule::impl::OnEvent(hci::EventPacketView view) { */ void neighbor::InquiryModule::impl::RegisterCallbacks(InquiryCallbacks callbacks) { inquiry_callbacks_ = callbacks; hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::UnregisterCallbacks() { hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE); hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT); inquiry_callbacks_ = {nullptr, nullptr, nullptr, nullptr}; } void neighbor::InquiryModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); } void neighbor::InquiryModule::impl::EnqueueCommandCompleteSync(std::unique_ptr<hci::CommandPacketBuilder> command) { ASSERT(command_sync_ == nullptr); command_sync_ = new std::promise<void>(); auto command_received = command_sync_->get_future(); hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandCompleteSync, common::Unretained(this)), handler_); command_received.wait(); delete command_sync_; command_sync_ = nullptr; } void neighbor::InquiryModule::impl::StartOneShotInquiry(hci::Lap& lap, InquiryLength inquiry_length, NumResponses num_responses) { ASSERT(active_one_shot_ == nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); ASSERT(active_one_shot_ == nullptr); active_one_shot_ = ⪅ EnqueueCommandStatus(hci::InquiryBuilder::Create(lap, inquiry_length, num_responses)); } void neighbor::InquiryModule::impl::StopOneShotInquiry() { ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::InquiryCancelBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); ASSERT(active_one_shot_ != nullptr); active_one_shot_ = nullptr; EnqueueCommandComplete(hci::InquiryCancelBuilder::Create()); } bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const { Loading @@ -282,20 +324,17 @@ bool neighbor::InquiryModule::impl::IsOneShotInquiryActive(hci::Lap& lap) const void neighbor::InquiryModule::impl::StartPeriodicInquiry(hci::Lap& lap, InquiryLength inquiry_length, NumResponses num_responses, PeriodLength max_delay, PeriodLength min_delay) { ASSERT(active_periodic_ == nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand( hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); ASSERT(active_periodic_ == nullptr); active_periodic_ = ⪅ EnqueueCommandComplete( hci::PeriodicInquiryModeBuilder::Create(inquiry_length, num_responses, lap, max_delay, min_delay)); } void neighbor::InquiryModule::impl::StopPeriodicInquiry() { ASSERT(active_periodic_ != nullptr); ASSERT(HasCallbacks()); hci_layer_->EnqueueCommand(hci::ExitPeriodicInquiryModeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); active_periodic_ = nullptr; EnqueueCommandComplete(hci::ExitPeriodicInquiryModeBuilder::Create()); } bool neighbor::InquiryModule::impl::IsPeriodicInquiryActive(hci::Lap& lap) const { Loading @@ -310,31 +349,16 @@ void neighbor::InquiryModule::impl::Start() { hci_layer_ = module_.GetDependency<hci::HciLayer>(); handler_ = module_.GetHandler(); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); hci_layer_->RegisterEventHandler(hci::EventCode::INQUIRY_COMPLETE, common::Bind(&InquiryModule::impl::OnEvent, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create()); EnqueueCommandComplete(hci::ReadInquiryScanActivityBuilder::Create()); EnqueueCommandComplete(hci::ReadInquiryScanTypeBuilder::Create()); EnqueueCommandCompleteSync(hci::ReadInquiryModeBuilder::Create()); hci_layer_->EnqueueCommand(hci::ReadInquiryResponseTransmitPowerLevelBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); LOG_DEBUG("Started inquiry module"); } void neighbor::InquiryModule::impl::Stop() { hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_COMPLETE); hci_layer_->UnregisterEventHandler(hci::EventCode::EXTENDED_INQUIRY_RESULT); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT_WITH_RSSI); hci_layer_->UnregisterEventHandler(hci::EventCode::INQUIRY_RESULT); LOG_INFO("Inquiry scan interval:%hd window:%hd", inquiry_scan_.interval, inquiry_scan_.window); LOG_INFO("Inquiry scan interval:%hu window:%hu", inquiry_scan_.interval, inquiry_scan_.window); LOG_INFO("Inquiry mode:%s scan_type:%s", hci::InquiryModeText(inquiry_mode_).c_str(), hci::InquiryScanTypeText(inquiry_scan_type_).c_str()); LOG_INFO("Inquiry response tx power:%hhd", inquiry_response_tx_power_); Loading @@ -342,18 +366,14 @@ void neighbor::InquiryModule::impl::Stop() { } void neighbor::InquiryModule::impl::SetInquiryMode(hci::InquiryMode mode) { hci_layer_->EnqueueCommand(hci::WriteInquiryModeBuilder::Create(mode), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryModeBuilder::Create(mode)); inquiry_mode_ = mode; LOG_DEBUG("Set inquiry mode"); LOG_DEBUG("Set inquiry mode:%s", hci::InquiryModeText(mode).c_str()); } void neighbor::InquiryModule::impl::SetScanActivity(ScanParameters params) { hci_layer_->EnqueueCommand(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanActivityBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryScanActivityBuilder::Create(params.interval, params.window)); inquiry_scan_ = params; LOG_DEBUG("Set scan activity interval:0x%x/%.02fms window:0x%x/%.02fms", params.interval, ScanIntervalTimeMs(params.interval), params.window, ScanWindowTimeMs(params.window)); } Loading @@ -363,10 +383,7 @@ ScanParameters neighbor::InquiryModule::impl::GetScanActivity() const { } void neighbor::InquiryModule::impl::SetScanType(hci::InquiryScanType scan_type) { hci_layer_->EnqueueCommand(hci::WriteInquiryScanTypeBuilder::Create(scan_type), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); hci_layer_->EnqueueCommand(hci::ReadInquiryScanTypeBuilder::Create(), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); EnqueueCommandComplete(hci::WriteInquiryScanTypeBuilder::Create(scan_type)); LOG_DEBUG("Set scan type:%s", hci::InquiryScanTypeText(scan_type).c_str()); } Loading Loading @@ -411,7 +428,7 @@ void neighbor::InquiryModule::StartLimitedInquiry(InquiryLength inquiry_length, } void neighbor::InquiryModule::StopInquiry() { if (pimpl_->IsInquiryActive()) { if (!pimpl_->IsInquiryActive()) { LOG_WARN("Ignoring stop one shot inquiry as an inquiry is not active"); return; } Loading Loading @@ -448,7 +465,7 @@ void neighbor::InquiryModule::StartLimitedPeriodicInquiry(InquiryLength inquiry_ } void neighbor::InquiryModule::StopPeriodicInquiry() { if (pimpl_->IsInquiryActive()) { if (!pimpl_->IsInquiryActive()) { LOG_WARN("Ignoring stop periodic inquiry as an inquiry is not active"); return; } Loading