Loading system/gd/neighbor/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ filegroup { "connectability.cc", "discoverability.cc", "inquiry.cc", "name.cc", "page.cc", "scan.cc", ], Loading system/gd/neighbor/name.cc 0 → 100644 +225 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "bt_gd_neigh" #include "neighbor/name.h" #include <memory> #include <unordered_map> #include <utility> #include "common/bind.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "module.h" #include "os/handler.h" #include "os/log.h" namespace bluetooth { namespace neighbor { struct ReadCallbackHandler { ReadRemoteNameCallback callback; os::Handler* handler; }; struct CancelCallbackHandler { CancelRemoteNameCallback callback; os::Handler* handler; }; constexpr std::array<uint8_t, 248> kEmptyName{}; struct NameModule::impl { void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler); void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback, os::Handler* handler); void Start(); void Stop(); impl(const NameModule& name_module); private: const NameModule& module_; 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 OnEvent(hci::EventPacketView view); std::unordered_map<hci::Address, std::unique_ptr<ReadCallbackHandler>> read_callback_handler_map_; std::unordered_map<hci::Address, std::unique_ptr<CancelCallbackHandler>> cancel_callback_handler_map_; hci::HciLayer* hci_layer_; os::Handler* handler_; }; const ModuleFactory neighbor::NameModule::Factory = ModuleFactory([]() { return new neighbor::NameModule(); }); neighbor::NameModule::impl::impl(const neighbor::NameModule& module) : module_(module) {} void neighbor::NameModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::OnCommandComplete(hci::CommandCompleteView view) { switch (view.GetCommandOpCode()) { case hci::OpCode::REMOTE_NAME_REQUEST_CANCEL: { auto packet = hci::RemoteNameRequestCancelCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); hci::Address address = packet.GetBdAddr(); ASSERT(cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()); cancel_callback_handler_map_.erase(address); } break; default: LOG_WARN("Unhandled command:%s", hci::OpCodeText(view.GetCommandOpCode()).c_str()); break; } } void neighbor::NameModule::impl::OnCommandStatus(hci::CommandStatusView status) { ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS); switch (status.GetCommandOpCode()) { case hci::OpCode::REMOTE_NAME_REQUEST: { auto packet = hci::RemoteNameRequestStatusView::Create(status); ASSERT(packet.IsValid()); } break; default: LOG_WARN("Unhandled command:%s", hci::OpCodeText(status.GetCommandOpCode()).c_str()); break; } } void neighbor::NameModule::impl::OnEvent(hci::EventPacketView view) { switch (view.GetEventCode()) { case hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: { auto packet = hci::RemoteNameRequestCompleteView::Create(view); ASSERT(packet.IsValid()); hci::Address address = packet.GetBdAddr(); ASSERT(read_callback_handler_map_.find(address) != read_callback_handler_map_.end()); auto read_callback_handler = std::move(read_callback_handler_map_[address]); read_callback_handler->handler->Post(common::BindOnce(std::move(read_callback_handler->callback), packet.GetStatus(), address, packet.GetRemoteName())); read_callback_handler_map_.erase(address); } break; default: LOG_ERROR("Unhandled event:%s", hci::EventCodeText(view.GetEventCode()).c_str()); break; } } void neighbor::NameModule::impl::Start() { hci_layer_ = module_.GetDependency<hci::HciLayer>(); handler_ = module_.GetHandler(); hci_layer_->RegisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE, common::Bind(&NameModule::impl::OnEvent, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::Stop() { hci_layer_->UnregisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE); } void neighbor::NameModule::impl::ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler) { LOG_DEBUG("%s Start read remote name request for %s", __func__, address.ToString().c_str()); if (read_callback_handler_map_.find(address) != read_callback_handler_map_.end()) { LOG_WARN("Ignoring duplicate read remote name request to:%s", address.ToString().c_str()); handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address, kEmptyName)); return; } read_callback_handler_map_[address] = std::unique_ptr<ReadCallbackHandler>(new ReadCallbackHandler{ .callback = std::move(callback), .handler = handler, }); EnqueueCommandStatus( hci::RemoteNameRequestBuilder::Create(address, page_scan_repetition_mode, clock_offset, clock_offset_valid)); } void neighbor::NameModule::impl::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) { LOG_DEBUG("%s Cancel remote name request for %s", __func__, address.ToString().c_str()); if (cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()) { LOG_WARN("Ignoring duplicate cancel remote name request to:%s", address.ToString().c_str()); handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address)); return; } cancel_callback_handler_map_[address] = std::unique_ptr<CancelCallbackHandler>(new CancelCallbackHandler{ .callback = std::move(callback), .handler = handler, }); EnqueueCommandComplete(hci::RemoteNameRequestCancelBuilder::Create(address)); } /** * General API here */ neighbor::NameModule::NameModule() : pimpl_(std::make_unique<impl>(*this)) {} neighbor::NameModule::~NameModule() { pimpl_.reset(); } void neighbor::NameModule::ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler) { GetHandler()->Post(common::BindOnce(&NameModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()), address, page_scan_repetition_mode, clock_offset, clock_offset_valid, std::move(callback), handler)); } void neighbor::NameModule::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) { GetHandler()->Post(common::BindOnce(&NameModule::impl::CancelRemoteNameRequest, common::Unretained(pimpl_.get()), address, std::move(callback), handler)); } /** * Module methods here */ void neighbor::NameModule::ListDependencies(ModuleList* list) { list->add<hci::HciLayer>(); } void neighbor::NameModule::Start() { pimpl_->Start(); } void neighbor::NameModule::Stop() { pimpl_->Stop(); } } // namespace neighbor } // namespace bluetooth system/gd/neighbor/name.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <array> #include <cstdint> #include <memory> #include "common/bind.h" #include "hci/address.h" #include "hci/hci_packets.h" #include "module.h" namespace bluetooth { namespace neighbor { using ReadRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name)>; using CancelRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address)>; class NameModule : public bluetooth::Module { public: void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback on_read_name, os::Handler* handler); void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback on_cancel, os::Handler* handler); static const ModuleFactory Factory; NameModule(); ~NameModule(); protected: void ListDependencies(ModuleList* list) override; void Start() override; void Stop() override; private: struct impl; std::unique_ptr<impl> pimpl_; DISALLOW_COPY_AND_ASSIGN(NameModule); }; } // namespace neighbor } // namespace bluetooth Loading
system/gd/neighbor/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,7 @@ filegroup { "connectability.cc", "discoverability.cc", "inquiry.cc", "name.cc", "page.cc", "scan.cc", ], Loading
system/gd/neighbor/name.cc 0 → 100644 +225 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "bt_gd_neigh" #include "neighbor/name.h" #include <memory> #include <unordered_map> #include <utility> #include "common/bind.h" #include "hci/hci_layer.h" #include "hci/hci_packets.h" #include "module.h" #include "os/handler.h" #include "os/log.h" namespace bluetooth { namespace neighbor { struct ReadCallbackHandler { ReadRemoteNameCallback callback; os::Handler* handler; }; struct CancelCallbackHandler { CancelRemoteNameCallback callback; os::Handler* handler; }; constexpr std::array<uint8_t, 248> kEmptyName{}; struct NameModule::impl { void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler); void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback, os::Handler* handler); void Start(); void Stop(); impl(const NameModule& name_module); private: const NameModule& module_; 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 OnEvent(hci::EventPacketView view); std::unordered_map<hci::Address, std::unique_ptr<ReadCallbackHandler>> read_callback_handler_map_; std::unordered_map<hci::Address, std::unique_ptr<CancelCallbackHandler>> cancel_callback_handler_map_; hci::HciLayer* hci_layer_; os::Handler* handler_; }; const ModuleFactory neighbor::NameModule::Factory = ModuleFactory([]() { return new neighbor::NameModule(); }); neighbor::NameModule::impl::impl(const neighbor::NameModule& module) : module_(module) {} void neighbor::NameModule::impl::EnqueueCommandComplete(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandComplete, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::EnqueueCommandStatus(std::unique_ptr<hci::CommandPacketBuilder> command) { hci_layer_->EnqueueCommand(std::move(command), common::BindOnce(&impl::OnCommandStatus, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::OnCommandComplete(hci::CommandCompleteView view) { switch (view.GetCommandOpCode()) { case hci::OpCode::REMOTE_NAME_REQUEST_CANCEL: { auto packet = hci::RemoteNameRequestCancelCompleteView::Create(view); ASSERT(packet.IsValid()); ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS); hci::Address address = packet.GetBdAddr(); ASSERT(cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()); cancel_callback_handler_map_.erase(address); } break; default: LOG_WARN("Unhandled command:%s", hci::OpCodeText(view.GetCommandOpCode()).c_str()); break; } } void neighbor::NameModule::impl::OnCommandStatus(hci::CommandStatusView status) { ASSERT(status.GetStatus() == hci::ErrorCode::SUCCESS); switch (status.GetCommandOpCode()) { case hci::OpCode::REMOTE_NAME_REQUEST: { auto packet = hci::RemoteNameRequestStatusView::Create(status); ASSERT(packet.IsValid()); } break; default: LOG_WARN("Unhandled command:%s", hci::OpCodeText(status.GetCommandOpCode()).c_str()); break; } } void neighbor::NameModule::impl::OnEvent(hci::EventPacketView view) { switch (view.GetEventCode()) { case hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE: { auto packet = hci::RemoteNameRequestCompleteView::Create(view); ASSERT(packet.IsValid()); hci::Address address = packet.GetBdAddr(); ASSERT(read_callback_handler_map_.find(address) != read_callback_handler_map_.end()); auto read_callback_handler = std::move(read_callback_handler_map_[address]); read_callback_handler->handler->Post(common::BindOnce(std::move(read_callback_handler->callback), packet.GetStatus(), address, packet.GetRemoteName())); read_callback_handler_map_.erase(address); } break; default: LOG_ERROR("Unhandled event:%s", hci::EventCodeText(view.GetEventCode()).c_str()); break; } } void neighbor::NameModule::impl::Start() { hci_layer_ = module_.GetDependency<hci::HciLayer>(); handler_ = module_.GetHandler(); hci_layer_->RegisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE, common::Bind(&NameModule::impl::OnEvent, common::Unretained(this)), handler_); } void neighbor::NameModule::impl::Stop() { hci_layer_->UnregisterEventHandler(hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE); } void neighbor::NameModule::impl::ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler) { LOG_DEBUG("%s Start read remote name request for %s", __func__, address.ToString().c_str()); if (read_callback_handler_map_.find(address) != read_callback_handler_map_.end()) { LOG_WARN("Ignoring duplicate read remote name request to:%s", address.ToString().c_str()); handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address, kEmptyName)); return; } read_callback_handler_map_[address] = std::unique_ptr<ReadCallbackHandler>(new ReadCallbackHandler{ .callback = std::move(callback), .handler = handler, }); EnqueueCommandStatus( hci::RemoteNameRequestBuilder::Create(address, page_scan_repetition_mode, clock_offset, clock_offset_valid)); } void neighbor::NameModule::impl::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) { LOG_DEBUG("%s Cancel remote name request for %s", __func__, address.ToString().c_str()); if (cancel_callback_handler_map_.find(address) != cancel_callback_handler_map_.end()) { LOG_WARN("Ignoring duplicate cancel remote name request to:%s", address.ToString().c_str()); handler->Post(common::BindOnce(std::move(callback), hci::ErrorCode::UNSPECIFIED_ERROR, address)); return; } cancel_callback_handler_map_[address] = std::unique_ptr<CancelCallbackHandler>(new CancelCallbackHandler{ .callback = std::move(callback), .handler = handler, }); EnqueueCommandComplete(hci::RemoteNameRequestCancelBuilder::Create(address)); } /** * General API here */ neighbor::NameModule::NameModule() : pimpl_(std::make_unique<impl>(*this)) {} neighbor::NameModule::~NameModule() { pimpl_.reset(); } void neighbor::NameModule::ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback callback, os::Handler* handler) { GetHandler()->Post(common::BindOnce(&NameModule::impl::ReadRemoteNameRequest, common::Unretained(pimpl_.get()), address, page_scan_repetition_mode, clock_offset, clock_offset_valid, std::move(callback), handler)); } void neighbor::NameModule::CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback callback, os::Handler* handler) { GetHandler()->Post(common::BindOnce(&NameModule::impl::CancelRemoteNameRequest, common::Unretained(pimpl_.get()), address, std::move(callback), handler)); } /** * Module methods here */ void neighbor::NameModule::ListDependencies(ModuleList* list) { list->add<hci::HciLayer>(); } void neighbor::NameModule::Start() { pimpl_->Start(); } void neighbor::NameModule::Stop() { pimpl_->Stop(); } } // namespace neighbor } // namespace bluetooth
system/gd/neighbor/name.h 0 → 100644 +59 −0 Original line number Diff line number Diff line /* * Copyright 2019 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include <array> #include <cstdint> #include <memory> #include "common/bind.h" #include "hci/address.h" #include "hci/hci_packets.h" #include "module.h" namespace bluetooth { namespace neighbor { using ReadRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address, std::array<uint8_t, 248> name)>; using CancelRemoteNameCallback = common::OnceCallback<void(hci::ErrorCode status, hci::Address address)>; class NameModule : public bluetooth::Module { public: void ReadRemoteNameRequest(hci::Address address, hci::PageScanRepetitionMode page_scan_repetition_mode, uint16_t clock_offset, hci::ClockOffsetValid clock_offset_valid, ReadRemoteNameCallback on_read_name, os::Handler* handler); void CancelRemoteNameRequest(hci::Address address, CancelRemoteNameCallback on_cancel, os::Handler* handler); static const ModuleFactory Factory; NameModule(); ~NameModule(); protected: void ListDependencies(ModuleList* list) override; void Start() override; void Stop() override; private: struct impl; std::unique_ptr<impl> pimpl_; DISALLOW_COPY_AND_ASSIGN(NameModule); }; } // namespace neighbor } // namespace bluetooth