blob: 3aebcbbcc8dfa0a215758d22c893ebaf421efb3d [file] [log] [blame]
/*
* 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.
*/
#include "hci/facade.h"
#include <condition_variable>
#include <memory>
#include <mutex>
#include "common/bind.h"
#include "common/blocking_queue.h"
#include "grpc/grpc_event_stream.h"
#include "hci/acl_manager.h"
#include "hci/classic_security_manager.h"
#include "hci/controller.h"
#include "hci/facade.grpc.pb.h"
#include "hci/hci_layer.h"
#include "hci/hci_packets.h"
#include "packet/raw_builder.h"
using ::grpc::ServerAsyncResponseWriter;
using ::grpc::ServerAsyncWriter;
using ::grpc::ServerContext;
using ::bluetooth::facade::EventStreamRequest;
using ::bluetooth::packet::RawBuilder;
namespace bluetooth {
namespace hci {
class AclManagerFacadeService : public AclManagerFacade::Service,
public ::bluetooth::hci::ConnectionCallbacks,
public ::bluetooth::hci::ConnectionManagementCallbacks,
public ::bluetooth::hci::AclManagerCallbacks {
public:
AclManagerFacadeService(AclManager* acl_manager, Controller* controller, HciLayer* hci_layer,
::bluetooth::os::Handler* facade_handler)
: acl_manager_(acl_manager), controller_(controller), hci_layer_(hci_layer), facade_handler_(facade_handler) {
acl_manager_->RegisterCallbacks(this, facade_handler_);
acl_manager_->RegisterAclManagerCallbacks(this, facade_handler_);
}
using EventStream = ::bluetooth::grpc::GrpcEventStream<AclData, AclPacketView>;
::grpc::Status SetPageScanMode(::grpc::ServerContext* context, const ::bluetooth::hci::PageScanMode* request,
::google::protobuf::Empty* response) override {
ScanEnable scan_enable = request->enabled() ? ScanEnable::PAGE_SCAN_ONLY : ScanEnable::NO_SCANS;
std::promise<void> promise;
auto future = promise.get_future();
hci_layer_->EnqueueCommand(
WriteScanEnableBuilder::Create(scan_enable),
common::BindOnce([](std::promise<void> promise, CommandCompleteView) { promise.set_value(); },
std::move(promise)),
facade_handler_);
future.wait();
return ::grpc::Status::OK;
}
::grpc::Status Connect(::grpc::ServerContext* context, const facade::BluetoothAddress* remote,
::google::protobuf::Empty* response) override {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(remote->address(), peer));
acl_manager_->CreateConnection(peer);
return ::grpc::Status::OK;
}
::grpc::Status Disconnect(::grpc::ServerContext* context, const facade::BluetoothAddress* request,
::google::protobuf::Empty* response) override {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
Address::FromString(request->address(), peer);
auto connection = acl_connections_.find(request->address());
if (connection == acl_connections_.end()) {
LOG_ERROR("Invalid address");
return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address");
} else {
connection->second->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION);
return ::grpc::Status::OK;
}
}
::grpc::Status AuthenticationRequested(::grpc::ServerContext* context, const facade::BluetoothAddress* request,
::google::protobuf::Empty* response) override {
Address peer;
Address::FromString(request->address(), peer);
auto connection = acl_connections_.find(request->address());
if (connection == acl_connections_.end()) {
LOG_ERROR("Invalid address");
return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address");
} else {
connection->second->AuthenticationRequested();
return ::grpc::Status::OK;
}
};
::grpc::Status SendAclData(::grpc::ServerContext* context, const AclData* request,
::google::protobuf::Empty* response) override {
std::unique_lock<std::mutex> lock(mutex_);
std::promise<void> promise;
auto future = promise.get_future();
acl_connections_[request->remote().address()]->GetAclQueueEnd()->RegisterEnqueue(
facade_handler_, common::Bind(&AclManagerFacadeService::enqueue_packet, common::Unretained(this),
common::Unretained(request), common::Passed(std::move(promise))));
future.wait();
return ::grpc::Status::OK;
}
std::unique_ptr<BasePacketBuilder> enqueue_packet(const AclData* request, std::promise<void> promise) {
acl_connections_[request->remote().address()]->GetAclQueueEnd()->UnregisterEnqueue();
std::string req_string = request->payload();
std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>();
packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end()));
promise.set_value();
return packet;
}
::grpc::Status FetchAclData(::grpc::ServerContext* context, const facade::EventStreamRequest* request,
::grpc::ServerWriter<AclData>* writer) override {
std::unique_lock<std::mutex> lock(mutex_);
return acl_stream_.HandleRequest(context, request, writer);
}
::grpc::Status TestInternalHciCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::google::protobuf::Empty* response) {
LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation();
LOG_DEBUG("local name : %s", controller_->GetControllerLocalName().c_str());
controller_->WriteLocalName("Device Under Test");
LOG_DEBUG("new local name : %s", controller_->GetControllerLocalName().c_str());
LOG_DEBUG("manufacturer name : %d", local_version_information.manufacturer_name_);
LOG_DEBUG("hci version : %x", (uint16_t)local_version_information.hci_version_);
LOG_DEBUG("lmp version : %x", (uint16_t)local_version_information.lmp_version_);
LOG_DEBUG("supported commands : %x", controller_->GetControllerLocalSupportedCommands()[0]);
LOG_DEBUG("local extended features :");
controller_->SetEventMask(0x00001FFFFFFFFFFF);
controller_->SetEventFilterInquiryResultAllDevices();
ClassOfDevice class_of_device({0xab, 0xcd, 0xef});
ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56});
controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask);
Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc});
controller_->SetEventFilterInquiryResultAddress(bdaddr);
controller_->SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag::AUTO_ACCEPT_OFF);
controller_->SetEventFilterConnectionSetupClassOfDevice(class_of_device, class_of_device_mask,
AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_DISABLED);
controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED);
controller_->SetEventFilterClearAll();
controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03);
return ::grpc::Status::OK;
}
::grpc::Status TestInternalHciLeCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::google::protobuf::Empty* response) {
LOG_DEBUG("le data packet length : %d", controller_->GetControllerLeBufferSize().le_data_packet_length_);
LOG_DEBUG("total num le packets : %d", controller_->GetControllerLeBufferSize().total_num_le_packets_);
LOG_DEBUG("le supported max tx octets : %d",
controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_);
LOG_DEBUG("le supported max tx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_tx_time_);
LOG_DEBUG("le supported max rx octets : %d",
controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_);
LOG_DEBUG("le supported max rx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_rx_time_);
LOG_DEBUG("le maximum advertising data length %d", controller_->GetControllerLeMaximumAdvertisingDataLength());
LOG_DEBUG("le number of supported advertising sets %d",
controller_->GetControllerLeNumberOfSupportedAdverisingSets());
controller_->LeSetEventMask(0x000000000000001F);
return ::grpc::Status::OK;
}
::grpc::Status TestClassicConnectionManagementCommands(::grpc::ServerContext* context,
const facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
Address peer;
Address::FromString(request->address(), peer);
auto connection = acl_connections_.find(request->address());
if (connection == acl_connections_.end()) {
LOG_ERROR("Invalid address");
return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address");
} else {
// TODO add individual grpc command if necessary
connection->second->RoleDiscovery();
connection->second->WriteLinkPolicySettings(0x07);
connection->second->ReadLinkPolicySettings();
connection->second->SniffSubrating(0x1234, 0x1234, 0x1234);
connection->second->WriteAutomaticFlushTimeout(0x07FF);
connection->second->ReadAutomaticFlushTimeout();
connection->second->ReadTransmitPowerLevel(TransmitPowerLevelType::CURRENT);
connection->second->ReadTransmitPowerLevel(TransmitPowerLevelType::MAXIMUM);
connection->second->WriteLinkSupervisionTimeout(0x5678);
connection->second->ReadLinkSupervisionTimeout();
connection->second->ReadFailedContactCounter();
connection->second->ResetFailedContactCounter();
connection->second->ReadLinkQuality();
connection->second->ReadAfhChannelMap();
connection->second->ReadRssi();
connection->second->ReadClock(WhichClock::LOCAL);
connection->second->ReadClock(WhichClock::PICONET);
connection->second->ChangeConnectionPacketType(0xEE1C);
connection->second->SetConnectionEncryption(Enable::ENABLED);
connection->second->ChangeConnectionLinkKey();
connection->second->ReadClockOffset();
connection->second->HoldMode(0x0500, 0x0020);
connection->second->SniffMode(0x0500, 0x0020, 0x0040, 0x0014);
connection->second->ExitSniffMode();
connection->second->QosSetup(ServiceType::BEST_EFFORT, 0x1234, 0x1233, 0x1232, 0x1231);
connection->second->FlowSpecification(FlowDirection::OUTGOING_FLOW, ServiceType::BEST_EFFORT, 0x1234, 0x1233,
0x1232, 0x1231);
connection->second->Flush();
acl_manager_->MasterLinkKey(KeyFlag::TEMPORARY);
acl_manager_->SwitchRole(peer, Role::MASTER);
acl_manager_->WriteDefaultLinkPolicySettings(0x07);
acl_manager_->ReadDefaultLinkPolicySettings();
return ::grpc::Status::OK;
}
}
void on_incoming_acl(std::string address) {
auto connection = acl_connections_.find(address);
if (connection == acl_connections_.end()) {
LOG_ERROR("Invalid address");
return;
}
auto packet = connection->second->GetAclQueueEnd()->TryDequeue();
auto acl_packet = AclPacketView::Create(*packet);
AclData acl_data;
acl_data.mutable_remote()->set_address(address);
std::string data = std::string(acl_packet.begin(), acl_packet.end());
acl_data.set_payload(data);
acl_stream_.OnIncomingEvent(acl_data);
}
void OnConnectSuccess(std::unique_ptr<::bluetooth::hci::AclConnection> connection) override {
std::unique_lock<std::mutex> lock(mutex_);
auto addr = connection->GetAddress();
std::shared_ptr<::bluetooth::hci::AclConnection> shared_connection = std::move(connection);
acl_connections_.emplace(addr.ToString(), shared_connection);
shared_connection->RegisterDisconnectCallback(
common::BindOnce(&AclManagerFacadeService::on_disconnect, common::Unretained(this), addr.ToString()),
facade_handler_);
shared_connection->RegisterCallbacks(this, facade_handler_);
connection_complete_stream_.OnIncomingEvent(shared_connection);
}
void OnMasterLinkKeyComplete(uint16_t connection_handle, KeyFlag key_flag) override {
LOG_DEBUG("OnMasterLinkKeyComplete connection_handle:%d", connection_handle);
}
void OnRoleChange(Address bd_addr, Role new_role) override {
LOG_DEBUG("OnRoleChange bd_addr:%s, new_role:%d", bd_addr.ToString().c_str(), (uint8_t)new_role);
}
void OnReadDefaultLinkPolicySettingsComplete(uint16_t default_link_policy_settings) override {
LOG_DEBUG("OnReadDefaultLinkPolicySettingsComplete default_link_policy_settings:%d", default_link_policy_settings);
}
void on_disconnect(std::string address, ErrorCode code) {
acl_connections_.erase(address);
DisconnectionEvent event;
event.mutable_remote()->set_address(address);
event.set_reason(static_cast<uint32_t>(code));
disconnection_stream_.OnIncomingEvent(event);
}
::grpc::Status FetchConnectionComplete(::grpc::ServerContext* context, const EventStreamRequest* request,
::grpc::ServerWriter<ConnectionEvent>* writer) override {
return connection_complete_stream_.HandleRequest(context, request, writer);
};
void OnConnectFail(Address address, ::bluetooth::hci::ErrorCode reason) override {
std::unique_lock<std::mutex> lock(mutex_);
ConnectionFailedEvent event;
event.mutable_remote()->set_address(address.ToString());
event.set_reason(static_cast<uint32_t>(reason));
connection_failed_stream_.OnIncomingEvent(event);
}
void OnConnectionPacketTypeChanged(uint16_t packet_type) override {
LOG_DEBUG("OnConnectionPacketTypeChanged packet_type:%d", packet_type);
}
void OnAuthenticationComplete() override {
LOG_DEBUG("OnAuthenticationComplete");
}
void OnEncryptionChange(EncryptionEnabled enabled) override {
LOG_DEBUG("OnConnectionPacketTypeChanged enabled:%d", (uint8_t)enabled);
}
void OnChangeConnectionLinkKeyComplete() override {
LOG_DEBUG("OnChangeConnectionLinkKeyComplete");
};
void OnReadClockOffsetComplete(uint16_t clock_offset) override {
LOG_DEBUG("OnReadClockOffsetComplete clock_offset:%d", clock_offset);
};
void OnModeChange(Mode current_mode, uint16_t interval) override {
LOG_DEBUG("OnModeChange Mode:%d, interval:%d", (uint8_t)current_mode, interval);
};
void OnQosSetupComplete(ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth, uint32_t latency,
uint32_t delay_variation) override {
LOG_DEBUG("OnQosSetupComplete service_type:%d, token_rate:%d, peak_bandwidth:%d, latency:%d, delay_variation:%d",
(uint8_t)service_type, token_rate, peak_bandwidth, latency, delay_variation);
}
void OnFlowSpecificationComplete(FlowDirection flow_direction, ServiceType service_type, uint32_t token_rate,
uint32_t token_bucket_size, uint32_t peak_bandwidth,
uint32_t access_latency) override {
LOG_DEBUG(
"OnFlowSpecificationComplete flow_direction:%d. service_type:%d, token_rate:%d, token_bucket_size:%d, "
"peak_bandwidth:%d, access_latency:%d",
(uint8_t)flow_direction, (uint8_t)service_type, token_rate, token_bucket_size, peak_bandwidth, access_latency);
}
void OnFlushOccurred() override {
LOG_DEBUG("OnFlushOccurred");
}
void OnRoleDiscoveryComplete(Role current_role) override {
LOG_DEBUG("OnRoleDiscoveryComplete current_role:%d", (uint8_t)current_role);
}
void OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings) override {
LOG_DEBUG("OnReadLinkPolicySettingsComplete link_policy_settings:%d", link_policy_settings);
}
void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override {
LOG_DEBUG("OnReadAutomaticFlushTimeoutComplete flush_timeout:%d", flush_timeout);
}
void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override {
LOG_DEBUG("OnReadTransmitPowerLevelComplete transmit_power_level:%d", transmit_power_level);
}
void OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout) override {
LOG_DEBUG("OnReadLinkSupervisionTimeoutComplete link_supervision_timeout:%d", link_supervision_timeout);
}
void OnReadFailedContactCounterComplete(uint16_t failed_contact_counter) override {
LOG_DEBUG("OnReadFailedContactCounterComplete failed_contact_counter:%d", failed_contact_counter);
}
void OnReadLinkQualityComplete(uint8_t link_quality) override {
LOG_DEBUG("OnReadLinkQualityComplete link_quality:%d", link_quality);
}
void OnReadAfhChannelMapComplete(AfhMode afh_mode, std::array<uint8_t, 10> afh_channel_map) {
LOG_DEBUG("OnReadAfhChannelMapComplete afh_mode:%d", (uint8_t)afh_mode);
}
void OnReadRssiComplete(uint8_t rssi) override {
LOG_DEBUG("OnReadRssiComplete rssi:%d", rssi);
}
void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override {
LOG_DEBUG("OnReadClockComplete clock:%d, accuracy:%d", clock, accuracy);
}
::grpc::Status FetchConnectionFailed(::grpc::ServerContext* context, const EventStreamRequest* request,
::grpc::ServerWriter<ConnectionFailedEvent>* writer) override {
return connection_failed_stream_.HandleRequest(context, request, writer);
};
::grpc::Status FetchDisconnection(::grpc::ServerContext* context,
const ::bluetooth::facade::EventStreamRequest* request,
::grpc::ServerWriter<DisconnectionEvent>* writer) override {
return disconnection_stream_.HandleRequest(context, request, writer);
}
private:
AclManager* acl_manager_;
Controller* controller_;
HciLayer* hci_layer_;
mutable std::mutex mutex_;
::bluetooth::os::Handler* facade_handler_;
class ConnectionCompleteStreamCallback
: public ::bluetooth::grpc::GrpcEventStreamCallback<ConnectionEvent, std::shared_ptr<AclConnection>> {
public:
void OnWriteResponse(ConnectionEvent* response, const std::shared_ptr<AclConnection>& connection) override {
response->mutable_remote()->set_address(connection->GetAddress().ToString());
response->set_connection_handle(connection->GetHandle());
}
} connection_complete_stream_callback_;
::bluetooth::grpc::GrpcEventStream<ConnectionEvent, std::shared_ptr<AclConnection>> connection_complete_stream_{
&connection_complete_stream_callback_};
class ConnectionFailedStreamCallback
: public ::bluetooth::grpc::GrpcEventStreamCallback<ConnectionFailedEvent, ConnectionFailedEvent> {
public:
void OnWriteResponse(ConnectionFailedEvent* response, const ConnectionFailedEvent& event) override {
response->CopyFrom(event);
}
} connection_failed_stream_callback_;
::bluetooth::grpc::GrpcEventStream<ConnectionFailedEvent, ConnectionFailedEvent> connection_failed_stream_{
&connection_failed_stream_callback_};
class DisconnectionStreamCallback
: public ::bluetooth::grpc::GrpcEventStreamCallback<DisconnectionEvent, DisconnectionEvent> {
public:
void OnWriteResponse(DisconnectionEvent* response, const DisconnectionEvent& event) override {
response->CopyFrom(event);
}
} disconnection_stream_callback_;
::bluetooth::grpc::GrpcEventStream<DisconnectionEvent, DisconnectionEvent> disconnection_stream_{
&disconnection_stream_callback_};
class AclStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<AclData, AclData> {
public:
AclStreamCallback(AclManagerFacadeService* service) : service_(service) {}
~AclStreamCallback() {
if (subscribed_) {
for (const auto& connection : service_->acl_connections_) {
connection.second->GetAclQueueEnd()->UnregisterDequeue();
}
subscribed_ = false;
}
}
void OnSubscribe() override {
if (subscribed_) {
LOG_WARN("Already subscribed");
return;
}
for (const auto& connection : service_->acl_connections_) {
auto remote_address = connection.second->GetAddress().ToString();
connection.second->GetAclQueueEnd()->RegisterDequeue(
service_->facade_handler_,
common::Bind(&AclManagerFacadeService::on_incoming_acl, common::Unretained(service_), remote_address));
}
subscribed_ = true;
}
void OnUnsubscribe() override {
if (!subscribed_) {
LOG_WARN("Not subscribed");
return;
}
for (const auto& connection : service_->acl_connections_) {
connection.second->GetAclQueueEnd()->UnregisterDequeue();
}
subscribed_ = false;
}
void OnWriteResponse(AclData* response, const AclData& event) override {
response->CopyFrom(event);
}
private:
AclManagerFacadeService* service_;
bool subscribed_ = false;
} acl_stream_callback_{this};
::bluetooth::grpc::GrpcEventStream<AclData, AclData> acl_stream_{&acl_stream_callback_};
std::map<std::string, std::shared_ptr<AclConnection>> acl_connections_;
};
void AclManagerFacadeModule::ListDependencies(ModuleList* list) {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<AclManager>();
list->add<Controller>();
list->add<HciLayer>();
}
void AclManagerFacadeModule::Start() {
::bluetooth::grpc::GrpcFacadeModule::Start();
service_ = new AclManagerFacadeService(GetDependency<AclManager>(), GetDependency<Controller>(),
GetDependency<HciLayer>(), GetHandler());
}
void AclManagerFacadeModule::Stop() {
delete service_;
::bluetooth::grpc::GrpcFacadeModule::Stop();
}
::grpc::Service* AclManagerFacadeModule::GetService() const {
return service_;
}
const ModuleFactory AclManagerFacadeModule::Factory =
::bluetooth::ModuleFactory([]() { return new AclManagerFacadeModule(); });
class ClassicSecurityManagerFacadeService : public ClassicSecurityManagerFacade::Service,
public ::bluetooth::hci::ClassicSecurityCommandCallbacks {
public:
ClassicSecurityManagerFacadeService(ClassicSecurityManager* classic_security_manager, Controller* controller,
HciLayer* hci_layer, ::bluetooth::os::Handler* facade_handler)
: classic_security_manager_(classic_security_manager), facade_handler_(facade_handler) {
classic_security_manager_->RegisterCallbacks(this, facade_handler_);
}
::grpc::Status LinkKeyRequestReply(::grpc::ServerContext* context,
const ::bluetooth::hci::LinkKeyRequestReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
common::LinkKey link_key;
ASSERT(Address::FromString(request->remote().address(), peer));
ASSERT(common::LinkKey::FromString(request->link_key(), link_key));
classic_security_manager_->LinkKeyRequestReply(peer, link_key);
return ::grpc::Status::OK;
};
::grpc::Status LinkKeyRequestNegativeReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->LinkKeyRequestNegativeReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status PinCodeRequestReply(::grpc::ServerContext* context,
const ::bluetooth::hci::PinCodeRequestReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
uint8_t len = request->len();
std::string pin_code = request->pin_code();
classic_security_manager_->PinCodeRequestReply(peer, len, pin_code);
return ::grpc::Status::OK;
};
::grpc::Status PinCodeRequestNegativeReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->PinCodeRequestNegativeReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status IoCapabilityRequestReply(::grpc::ServerContext* context,
const ::bluetooth::hci::IoCapabilityRequestReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
IoCapability io_capability = (IoCapability)request->io_capability();
OobDataPresent oob_present = (OobDataPresent)request->oob_present();
AuthenticationRequirements authentication_requirements =
(AuthenticationRequirements)request->authentication_requirements();
classic_security_manager_->IoCapabilityRequestReply(peer, io_capability, oob_present, authentication_requirements);
return ::grpc::Status::OK;
};
::grpc::Status IoCapabilityRequestNegativeReply(
::grpc::ServerContext* context, const ::bluetooth::hci::IoCapabilityRequestNegativeReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
ErrorCode reason = (ErrorCode)request->reason();
classic_security_manager_->IoCapabilityRequestNegativeReply(peer, reason);
return ::grpc::Status::OK;
};
::grpc::Status UserConfirmationRequestReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->UserConfirmationRequestReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status UserConfirmationRequestNegativeReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->UserConfirmationRequestNegativeReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status UserPasskeyRequestReply(::grpc::ServerContext* context,
const ::bluetooth::hci::UserPasskeyRequestReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
uint32_t passkey = request->passkey();
classic_security_manager_->UserPasskeyRequestReply(peer, passkey);
return ::grpc::Status::OK;
};
::grpc::Status UserPasskeyRequestNegativeReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->UserPasskeyRequestNegativeReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status RemoteOobDataRequestReply(::grpc::ServerContext* context,
const ::bluetooth::hci::RemoteOobDataRequestReplyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
std::string c_string = request->c();
std::string r_string = request->r();
std::array<uint8_t, 16> c;
std::array<uint8_t, 16> r;
std::copy(std::begin(c_string), std::end(c_string), std::begin(c));
std::copy(std::begin(r_string), std::end(r_string), std::begin(r));
classic_security_manager_->RemoteOobDataRequestReply(peer, c, r);
return ::grpc::Status::OK;
};
::grpc::Status RemoteOobDataRequestNegativeReply(::grpc::ServerContext* context,
const ::bluetooth::facade::BluetoothAddress* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->address(), peer));
classic_security_manager_->RemoteOobDataRequestNegativeReply(peer);
return ::grpc::Status::OK;
}
::grpc::Status ReadStoredLinkKey(::grpc::ServerContext* context,
const ::bluetooth::hci::ReadStoredLinkKeyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
ReadStoredLinkKeyReadAllFlag read_all_flag = (ReadStoredLinkKeyReadAllFlag)request->read_all_flag();
classic_security_manager_->ReadStoredLinkKey(peer, read_all_flag);
return ::grpc::Status::OK;
};
::grpc::Status WriteStoredLinkKey(::grpc::ServerContext* context,
const ::bluetooth::hci::WriteStoredLinkKeyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
uint8_t num_keys_to_write = request->num_keys_to_write();
std::vector<KeyAndAddress> keys;
for (size_t i = 0; i < num_keys_to_write; i++) {
KeyAndAddress key;
common::LinkKey link_key;
ASSERT(Address::FromString(request->remote().address(), key.address_));
ASSERT(common::LinkKey::FromString(request->link_keys(), link_key));
std::copy(std::begin(link_key.link_key), std::end(link_key.link_key), std::begin(key.link_key_));
keys.push_back(key);
}
classic_security_manager_->WriteStoredLinkKey(keys);
return ::grpc::Status::OK;
};
::grpc::Status DeleteStoredLinkKey(::grpc::ServerContext* context,
const ::bluetooth::hci::DeleteStoredLinkKeyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
DeleteStoredLinkKeyDeleteAllFlag delete_all_flag = (DeleteStoredLinkKeyDeleteAllFlag)request->delete_all_flag();
classic_security_manager_->DeleteStoredLinkKey(peer, delete_all_flag);
return ::grpc::Status::OK;
};
::grpc::Status RefreshEncryptionKey(::grpc::ServerContext* context,
const ::bluetooth::hci::RefreshEncryptionKeyMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
classic_security_manager_->RefreshEncryptionKey(request->connection_handle());
return ::grpc::Status::OK;
};
::grpc::Status ReadSimplePairingMode(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
classic_security_manager_->ReadSimplePairingMode();
return ::grpc::Status::OK;
};
::grpc::Status WriteSimplePairingMode(::grpc::ServerContext* context,
const ::bluetooth::hci::WriteSimplePairingModeMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Enable simple_pairing_mode = (Enable)request->simple_pairing_mode();
classic_security_manager_->WriteSimplePairingMode(simple_pairing_mode);
return ::grpc::Status::OK;
};
::grpc::Status ReadLocalOobData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
classic_security_manager_->ReadLocalOobData();
return ::grpc::Status::OK;
};
::grpc::Status SendKeypressNotification(::grpc::ServerContext* context,
const ::bluetooth::hci::SendKeypressNotificationMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
Address peer;
ASSERT(Address::FromString(request->remote().address(), peer));
KeypressNotificationType notification_type = (KeypressNotificationType)request->notification_type();
classic_security_manager_->SendKeypressNotification(peer, notification_type);
return ::grpc::Status::OK;
};
::grpc::Status ReadLocalOobExtendedData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
classic_security_manager_->ReadLocalOobExtendedData();
return ::grpc::Status::OK;
};
::grpc::Status ReadEncryptionKeySize(::grpc::ServerContext* context,
const ::bluetooth::hci::ReadEncryptionKeySizeMessage* request,
::google::protobuf::Empty* response) {
std::unique_lock<std::mutex> lock(mutex_);
classic_security_manager_->ReadEncryptionKeySize(request->connection_handle());
return ::grpc::Status::OK;
};
::grpc::Status FetchCommandCompleteEvent(::grpc::ServerContext* context, const EventStreamRequest* request,
::grpc::ServerWriter<CommandCompleteEvent>* writer) override {
return command_complete_stream_.HandleRequest(context, request, writer);
};
void OnCommandComplete(CommandCompleteView status) override {
std::unique_lock<std::mutex> lock(mutex_);
command_complete_stream_.OnIncomingEvent(status);
}
private:
ClassicSecurityManager* classic_security_manager_;
mutable std::mutex mutex_;
::bluetooth::os::Handler* facade_handler_;
class CommandCompleteStreamCallback
: public ::bluetooth::grpc::GrpcEventStreamCallback<CommandCompleteEvent, CommandCompleteView> {
public:
void OnWriteResponse(CommandCompleteEvent* response, CommandCompleteView const& status) override {
response->set_command_opcode((uint32_t)status.GetCommandOpCode());
}
} command_complete_stream_callback_;
::bluetooth::grpc::GrpcEventStream<CommandCompleteEvent, CommandCompleteView> command_complete_stream_{
&command_complete_stream_callback_};
};
void ClassicSecurityManagerFacadeModule::ListDependencies(ModuleList* list) {
::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list);
list->add<ClassicSecurityManager>();
list->add<Controller>();
list->add<HciLayer>();
}
void ClassicSecurityManagerFacadeModule::Start() {
::bluetooth::grpc::GrpcFacadeModule::Start();
service_ = new ClassicSecurityManagerFacadeService(
GetDependency<ClassicSecurityManager>(), GetDependency<Controller>(), GetDependency<HciLayer>(), GetHandler());
}
void ClassicSecurityManagerFacadeModule::Stop() {
delete service_;
::bluetooth::grpc::GrpcFacadeModule::Stop();
}
::grpc::Service* ClassicSecurityManagerFacadeModule::GetService() const {
return service_;
}
const ModuleFactory ClassicSecurityManagerFacadeModule::Factory =
::bluetooth::ModuleFactory([]() { return new ClassicSecurityManagerFacadeModule(); });
} // namespace hci
} // namespace bluetooth