You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.5 KiB
206 lines
5.5 KiB
/*
|
|
* 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/scan.h"
|
|
|
|
#include <memory>
|
|
|
|
#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 ScanModule::impl {
|
|
impl(ScanModule& module);
|
|
|
|
void SetInquiryScan(bool enabled);
|
|
bool IsInquiryEnabled() const;
|
|
|
|
void SetPageScan(bool enabled);
|
|
bool IsPageEnabled() const;
|
|
|
|
void Start();
|
|
void Stop();
|
|
|
|
private:
|
|
ScanModule& module_;
|
|
|
|
bool inquiry_scan_enabled_;
|
|
bool page_scan_enabled_;
|
|
|
|
void WriteScanEnable();
|
|
void ReadScanEnable(hci::ScanEnable);
|
|
|
|
void OnCommandComplete(hci::CommandCompleteView status);
|
|
|
|
hci::HciLayer* hci_layer_;
|
|
os::Handler* handler_;
|
|
};
|
|
|
|
const ModuleFactory neighbor::ScanModule::Factory = ModuleFactory([]() { return new neighbor::ScanModule(); });
|
|
|
|
neighbor::ScanModule::impl::impl(neighbor::ScanModule& module)
|
|
: module_(module), inquiry_scan_enabled_(false), page_scan_enabled_(false) {}
|
|
|
|
void neighbor::ScanModule::impl::OnCommandComplete(hci::CommandCompleteView view) {
|
|
switch (view.GetCommandOpCode()) {
|
|
case hci::OpCode::READ_SCAN_ENABLE: {
|
|
auto packet = hci::ReadScanEnableCompleteView::Create(view);
|
|
ASSERT(packet.IsValid());
|
|
ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
|
|
ReadScanEnable(packet.GetScanEnable());
|
|
} break;
|
|
|
|
case hci::OpCode::WRITE_SCAN_ENABLE: {
|
|
auto packet = hci::WriteScanEnableCompleteView::Create(view);
|
|
ASSERT(packet.IsValid());
|
|
ASSERT(packet.GetStatus() == hci::ErrorCode::SUCCESS);
|
|
} break;
|
|
|
|
default:
|
|
LOG_ERROR("Unhandled command %s", hci::OpCodeText(view.GetCommandOpCode()).c_str());
|
|
break;
|
|
}
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::WriteScanEnable() {
|
|
hci::ScanEnable scan_enable;
|
|
|
|
if (inquiry_scan_enabled_ && !page_scan_enabled_) {
|
|
scan_enable = hci::ScanEnable::INQUIRY_SCAN_ONLY;
|
|
} else if (!inquiry_scan_enabled_ && page_scan_enabled_) {
|
|
scan_enable = hci::ScanEnable::PAGE_SCAN_ONLY;
|
|
} else if (inquiry_scan_enabled_ && page_scan_enabled_) {
|
|
scan_enable = hci::ScanEnable::INQUIRY_AND_PAGE_SCAN;
|
|
} else {
|
|
scan_enable = hci::ScanEnable::NO_SCANS;
|
|
}
|
|
|
|
{
|
|
std::unique_ptr<hci::WriteScanEnableBuilder> packet = hci::WriteScanEnableBuilder::Create(scan_enable);
|
|
hci_layer_->EnqueueCommand(std::move(packet), handler_->BindOnceOn(this, &impl::OnCommandComplete));
|
|
}
|
|
|
|
{
|
|
std::unique_ptr<hci::ReadScanEnableBuilder> packet = hci::ReadScanEnableBuilder::Create();
|
|
hci_layer_->EnqueueCommand(std::move(packet), handler_->BindOnceOn(this, &impl::OnCommandComplete));
|
|
}
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::ReadScanEnable(hci::ScanEnable scan_enable) {
|
|
switch (scan_enable) {
|
|
case hci::ScanEnable::INQUIRY_SCAN_ONLY:
|
|
inquiry_scan_enabled_ = true;
|
|
page_scan_enabled_ = false;
|
|
break;
|
|
|
|
case hci::ScanEnable::PAGE_SCAN_ONLY:
|
|
inquiry_scan_enabled_ = false;
|
|
page_scan_enabled_ = true;
|
|
break;
|
|
|
|
case hci::ScanEnable::INQUIRY_AND_PAGE_SCAN:
|
|
inquiry_scan_enabled_ = true;
|
|
page_scan_enabled_ = true;
|
|
break;
|
|
|
|
default:
|
|
inquiry_scan_enabled_ = false;
|
|
page_scan_enabled_ = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::SetInquiryScan(bool enabled) {
|
|
inquiry_scan_enabled_ = enabled;
|
|
WriteScanEnable();
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::SetPageScan(bool enabled) {
|
|
page_scan_enabled_ = enabled;
|
|
WriteScanEnable();
|
|
}
|
|
|
|
bool neighbor::ScanModule::impl::IsInquiryEnabled() const {
|
|
return inquiry_scan_enabled_;
|
|
}
|
|
|
|
bool neighbor::ScanModule::impl::IsPageEnabled() const {
|
|
return page_scan_enabled_;
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::Start() {
|
|
hci_layer_ = module_.GetDependency<hci::HciLayer>();
|
|
handler_ = module_.GetHandler();
|
|
|
|
std::unique_ptr<hci::ReadScanEnableBuilder> packet = hci::ReadScanEnableBuilder::Create();
|
|
hci_layer_->EnqueueCommand(std::move(packet), handler_->BindOnceOn(this, &impl::OnCommandComplete));
|
|
}
|
|
|
|
void neighbor::ScanModule::impl::Stop() {
|
|
LOG_INFO("inquiry scan enabled:%d page scan enabled:%d", inquiry_scan_enabled_, page_scan_enabled_);
|
|
}
|
|
|
|
neighbor::ScanModule::ScanModule() : pimpl_(std::make_unique<impl>(*this)) {}
|
|
|
|
neighbor::ScanModule::~ScanModule() {
|
|
pimpl_.reset();
|
|
}
|
|
|
|
void neighbor::ScanModule::SetInquiryScan() {
|
|
pimpl_->SetInquiryScan(true);
|
|
}
|
|
|
|
void neighbor::ScanModule::ClearInquiryScan() {
|
|
pimpl_->SetInquiryScan(false);
|
|
}
|
|
|
|
void neighbor::ScanModule::SetPageScan() {
|
|
pimpl_->SetPageScan(true);
|
|
}
|
|
|
|
void neighbor::ScanModule::ClearPageScan() {
|
|
pimpl_->SetPageScan(false);
|
|
}
|
|
|
|
bool neighbor::ScanModule::IsInquiryEnabled() const {
|
|
return pimpl_->IsInquiryEnabled();
|
|
}
|
|
|
|
bool neighbor::ScanModule::IsPageEnabled() const {
|
|
return pimpl_->IsPageEnabled();
|
|
}
|
|
|
|
void neighbor::ScanModule::ListDependencies(ModuleList* list) {
|
|
list->add<hci::HciLayer>();
|
|
}
|
|
|
|
void neighbor::ScanModule::Start() {
|
|
pimpl_->Start();
|
|
}
|
|
|
|
void neighbor::ScanModule::Stop() {
|
|
pimpl_->Stop();
|
|
}
|
|
|
|
} // namespace neighbor
|
|
} // namespace bluetooth
|