blob: 9d6171dedd84019609b26dd409b844888df439e8 [file] [log] [blame]
/*
* Copyright 2021 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.
*/
#include "hci/vendor_specific_event_manager.h"
#include "hci/controller.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
namespace bluetooth {
namespace hci {
const ModuleFactory VendorSpecificEventManager::Factory =
ModuleFactory([]() { return new VendorSpecificEventManager(); });
struct VendorSpecificEventManager::impl {
impl(Module* module) : module_(module){};
~impl() {}
void start(os::Handler* handler, hci::HciLayer* hci_layer, hci::Controller* controller) {
module_handler_ = handler;
hci_layer_ = hci_layer;
controller_ = controller;
hci_layer_->RegisterEventHandler(
EventCode::VENDOR_SPECIFIC, handler->BindOn(this, &VendorSpecificEventManager::impl::on_vendor_specific_event));
vendor_capabilities_ = controller->GetVendorCapabilities();
}
void stop() {}
void register_event(VseSubeventCode event, common::ContextualCallback<void(VendorSpecificEventView)> handler) {
ASSERT_LOG(
subevent_handlers_.count(event) == 0,
"Can not register a second handler for %02hhx (%s)",
event,
VseSubeventCodeText(event).c_str());
subevent_handlers_[event] = handler;
}
void unregister_event(VseSubeventCode event) {
subevent_handlers_.erase(subevent_handlers_.find(event));
}
bool check_event_supported(VseSubeventCode event) {
switch (event) {
case (VseSubeventCode::BLE_THRESHOLD): {
if (vendor_capabilities_.total_scan_results_storage_ > 0) {
return true;
}
} break;
case (VseSubeventCode::BLE_TRACKING): {
if (vendor_capabilities_.total_num_of_advt_tracked_ > 0) {
return true;
}
} break;
case (VseSubeventCode::DEBUG_INFO): {
return vendor_capabilities_.debug_logging_supported_;
} break;
case (VseSubeventCode::BQR_EVENT): {
return vendor_capabilities_.bluetooth_quality_report_support_;
} break;
default:
LOG_WARN("Unhandled event %s", VseSubeventCodeText(event).c_str());
}
return false;
}
void on_vendor_specific_event(EventView event_view) {
auto vendor_specific_event_view = VendorSpecificEventView::Create(event_view);
ASSERT(vendor_specific_event_view.IsValid());
VseSubeventCode vse_subevent_code = vendor_specific_event_view.GetSubeventCode();
if (subevent_handlers_.find(vse_subevent_code) == subevent_handlers_.end()) {
LOG_WARN("Unhandled vendor specific event of type 0x%02hhx", vse_subevent_code);
return;
}
subevent_handlers_[vse_subevent_code].Invoke(vendor_specific_event_view);
}
Module* module_;
os::Handler* module_handler_;
hci::HciLayer* hci_layer_;
hci::Controller* controller_;
VendorCapabilities vendor_capabilities_;
std::map<VseSubeventCode, common::ContextualCallback<void(VendorSpecificEventView)>> subevent_handlers_;
};
VendorSpecificEventManager::VendorSpecificEventManager() {
pimpl_ = std::make_unique<impl>(this);
}
void VendorSpecificEventManager::ListDependencies(ModuleList* list) const {
list->add<hci::HciLayer>();
list->add<hci::Controller>();
}
void VendorSpecificEventManager::Start() {
pimpl_->start(GetHandler(), GetDependency<hci::HciLayer>(), GetDependency<hci::Controller>());
}
void VendorSpecificEventManager::Stop() {
pimpl_->stop();
pimpl_.reset();
}
std::string VendorSpecificEventManager::ToString() const {
return "Vendor Specific Event Manager";
}
void VendorSpecificEventManager::RegisterEventHandler(
VseSubeventCode event, common::ContextualCallback<void(VendorSpecificEventView)> handler) {
CallOn(pimpl_.get(), &impl::register_event, event, handler);
}
void VendorSpecificEventManager::UnregisterEventHandler(VseSubeventCode event) {
CallOn(pimpl_.get(), &impl::unregister_event, event);
}
} // namespace hci
} // namespace bluetooth