Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright 2019 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
| 17 | #include "hci/facade.h" |
| 18 | |
| 19 | #include <condition_variable> |
| 20 | #include <memory> |
| 21 | #include <mutex> |
| 22 | |
| 23 | #include "common/bind.h" |
| 24 | #include "common/blocking_queue.h" |
| 25 | #include "grpc/grpc_event_stream.h" |
| 26 | #include "hci/acl_manager.h" |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 27 | #include "hci/classic_security_manager.h" |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 28 | #include "hci/controller.h" |
| 29 | #include "hci/facade.grpc.pb.h" |
| 30 | #include "hci/hci_layer.h" |
| 31 | #include "hci/hci_packets.h" |
| 32 | #include "packet/raw_builder.h" |
| 33 | |
| 34 | using ::grpc::ServerAsyncResponseWriter; |
| 35 | using ::grpc::ServerAsyncWriter; |
| 36 | using ::grpc::ServerContext; |
| 37 | |
| 38 | using ::bluetooth::facade::EventStreamRequest; |
| 39 | using ::bluetooth::packet::RawBuilder; |
| 40 | |
| 41 | namespace bluetooth { |
| 42 | namespace hci { |
| 43 | |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 44 | class AclManagerFacadeService : public AclManagerFacade::Service, |
| 45 | public ::bluetooth::hci::ConnectionCallbacks, |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 46 | public ::bluetooth::hci::ConnectionManagementCallbacks, |
| 47 | public ::bluetooth::hci::AclManagerCallbacks { |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 48 | public: |
| 49 | AclManagerFacadeService(AclManager* acl_manager, Controller* controller, HciLayer* hci_layer, |
| 50 | ::bluetooth::os::Handler* facade_handler) |
| 51 | : acl_manager_(acl_manager), controller_(controller), hci_layer_(hci_layer), facade_handler_(facade_handler) { |
| 52 | acl_manager_->RegisterCallbacks(this, facade_handler_); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 53 | acl_manager_->RegisterAclManagerCallbacks(this, facade_handler_); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 54 | } |
| 55 | |
| 56 | using EventStream = ::bluetooth::grpc::GrpcEventStream<AclData, AclPacketView>; |
| 57 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 58 | ::grpc::Status SetPageScanMode(::grpc::ServerContext* context, const ::bluetooth::hci::PageScanMode* request, |
| 59 | ::google::protobuf::Empty* response) override { |
| 60 | ScanEnable scan_enable = request->enabled() ? ScanEnable::PAGE_SCAN_ONLY : ScanEnable::NO_SCANS; |
| 61 | std::promise<void> promise; |
| 62 | auto future = promise.get_future(); |
| 63 | hci_layer_->EnqueueCommand( |
| 64 | WriteScanEnableBuilder::Create(scan_enable), |
| 65 | common::BindOnce([](std::promise<void> promise, CommandCompleteView) { promise.set_value(); }, |
| 66 | std::move(promise)), |
| 67 | facade_handler_); |
| 68 | future.wait(); |
| 69 | return ::grpc::Status::OK; |
| 70 | } |
| 71 | |
| 72 | ::grpc::Status Connect(::grpc::ServerContext* context, const facade::BluetoothAddress* remote, |
| 73 | ::google::protobuf::Empty* response) override { |
| 74 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 75 | Address peer; |
| 76 | ASSERT(Address::FromString(remote->address(), peer)); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 77 | acl_manager_->CreateConnection(peer); |
| 78 | return ::grpc::Status::OK; |
| 79 | } |
| 80 | |
| 81 | ::grpc::Status Disconnect(::grpc::ServerContext* context, const facade::BluetoothAddress* request, |
| 82 | ::google::protobuf::Empty* response) override { |
| 83 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 84 | Address peer; |
| 85 | Address::FromString(request->address(), peer); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 86 | auto connection = acl_connections_.find(request->address()); |
| 87 | if (connection == acl_connections_.end()) { |
| 88 | LOG_ERROR("Invalid address"); |
| 89 | return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address"); |
| 90 | } else { |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 91 | connection->second->Disconnect(DisconnectReason::REMOTE_USER_TERMINATED_CONNECTION); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 92 | return ::grpc::Status::OK; |
| 93 | } |
| 94 | } |
| 95 | |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 96 | ::grpc::Status AuthenticationRequested(::grpc::ServerContext* context, const facade::BluetoothAddress* request, |
| 97 | ::google::protobuf::Empty* response) override { |
| 98 | Address peer; |
| 99 | Address::FromString(request->address(), peer); |
| 100 | auto connection = acl_connections_.find(request->address()); |
| 101 | if (connection == acl_connections_.end()) { |
| 102 | LOG_ERROR("Invalid address"); |
| 103 | return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address"); |
| 104 | } else { |
| 105 | connection->second->AuthenticationRequested(); |
| 106 | return ::grpc::Status::OK; |
| 107 | } |
| 108 | }; |
| 109 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 110 | ::grpc::Status SendAclData(::grpc::ServerContext* context, const AclData* request, |
| 111 | ::google::protobuf::Empty* response) override { |
| 112 | std::unique_lock<std::mutex> lock(mutex_); |
| 113 | std::promise<void> promise; |
| 114 | auto future = promise.get_future(); |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 115 | acl_connections_[request->remote().address()]->GetAclQueueEnd()->RegisterEnqueue( |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 116 | facade_handler_, common::Bind(&AclManagerFacadeService::enqueue_packet, common::Unretained(this), |
| 117 | common::Unretained(request), common::Passed(std::move(promise)))); |
| 118 | future.wait(); |
| 119 | return ::grpc::Status::OK; |
| 120 | } |
| 121 | |
| 122 | std::unique_ptr<BasePacketBuilder> enqueue_packet(const AclData* request, std::promise<void> promise) { |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 123 | acl_connections_[request->remote().address()]->GetAclQueueEnd()->UnregisterEnqueue(); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 124 | std::string req_string = request->payload(); |
| 125 | std::unique_ptr<RawBuilder> packet = std::make_unique<RawBuilder>(); |
| 126 | packet->AddOctets(std::vector<uint8_t>(req_string.begin(), req_string.end())); |
| 127 | promise.set_value(); |
| 128 | return packet; |
| 129 | } |
| 130 | |
| 131 | ::grpc::Status FetchAclData(::grpc::ServerContext* context, const facade::EventStreamRequest* request, |
| 132 | ::grpc::ServerWriter<AclData>* writer) override { |
| 133 | std::unique_lock<std::mutex> lock(mutex_); |
| 134 | return acl_stream_.HandleRequest(context, request, writer); |
| 135 | } |
| 136 | |
Chienyuan | a7ad3fb | 2019-08-15 18:04:32 +0800 | [diff] [blame] | 137 | ::grpc::Status TestInternalHciCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, |
| 138 | ::google::protobuf::Empty* response) { |
| 139 | LocalVersionInformation local_version_information = controller_->GetControllerLocalVersionInformation(); |
| 140 | LOG_DEBUG("local name : %s", controller_->GetControllerLocalName().c_str()); |
| 141 | controller_->WriteLocalName("Device Under Test"); |
| 142 | LOG_DEBUG("new local name : %s", controller_->GetControllerLocalName().c_str()); |
| 143 | LOG_DEBUG("manufacturer name : %d", local_version_information.manufacturer_name_); |
| 144 | LOG_DEBUG("hci version : %x", (uint16_t)local_version_information.hci_version_); |
| 145 | LOG_DEBUG("lmp version : %x", (uint16_t)local_version_information.lmp_version_); |
| 146 | LOG_DEBUG("supported commands : %x", controller_->GetControllerLocalSupportedCommands()[0]); |
Chienyuan | a7ad3fb | 2019-08-15 18:04:32 +0800 | [diff] [blame] | 147 | LOG_DEBUG("local extended features :"); |
Chienyuan | a7ad3fb | 2019-08-15 18:04:32 +0800 | [diff] [blame] | 148 | |
| 149 | controller_->SetEventMask(0x00001FFFFFFFFFFF); |
| 150 | controller_->SetEventFilterInquiryResultAllDevices(); |
| 151 | ClassOfDevice class_of_device({0xab, 0xcd, 0xef}); |
| 152 | ClassOfDevice class_of_device_mask({0x12, 0x34, 0x56}); |
| 153 | controller_->SetEventFilterInquiryResultClassOfDevice(class_of_device, class_of_device_mask); |
| 154 | Address bdaddr({0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc}); |
| 155 | controller_->SetEventFilterInquiryResultAddress(bdaddr); |
| 156 | controller_->SetEventFilterConnectionSetupAllDevices(AutoAcceptFlag::AUTO_ACCEPT_OFF); |
| 157 | controller_->SetEventFilterConnectionSetupClassOfDevice(class_of_device, class_of_device_mask, |
| 158 | AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_DISABLED); |
| 159 | controller_->SetEventFilterConnectionSetupAddress(bdaddr, AutoAcceptFlag::AUTO_ACCEPT_ON_ROLE_SWITCH_ENABLED); |
| 160 | controller_->SetEventFilterClearAll(); |
| 161 | controller_->HostBufferSize(0xFF00, 0xF1, 0xFF02, 0xFF03); |
| 162 | return ::grpc::Status::OK; |
| 163 | } |
| 164 | |
| 165 | ::grpc::Status TestInternalHciLeCommands(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, |
| 166 | ::google::protobuf::Empty* response) { |
| 167 | LOG_DEBUG("le data packet length : %d", controller_->GetControllerLeBufferSize().le_data_packet_length_); |
| 168 | LOG_DEBUG("total num le packets : %d", controller_->GetControllerLeBufferSize().total_num_le_packets_); |
Chienyuan | a7ad3fb | 2019-08-15 18:04:32 +0800 | [diff] [blame] | 169 | LOG_DEBUG("le supported max tx octets : %d", |
| 170 | controller_->GetControllerLeMaximumDataLength().supported_max_tx_octets_); |
| 171 | LOG_DEBUG("le supported max tx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_tx_time_); |
| 172 | LOG_DEBUG("le supported max rx octets : %d", |
| 173 | controller_->GetControllerLeMaximumDataLength().supported_max_rx_octets_); |
| 174 | LOG_DEBUG("le supported max rx times : %d", controller_->GetControllerLeMaximumDataLength().supported_max_rx_time_); |
| 175 | LOG_DEBUG("le maximum advertising data length %d", controller_->GetControllerLeMaximumAdvertisingDataLength()); |
| 176 | LOG_DEBUG("le number of supported advertising sets %d", |
| 177 | controller_->GetControllerLeNumberOfSupportedAdverisingSets()); |
| 178 | |
| 179 | controller_->LeSetEventMask(0x000000000000001F); |
| 180 | return ::grpc::Status::OK; |
| 181 | } |
| 182 | |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 183 | ::grpc::Status TestClassicConnectionManagementCommands(::grpc::ServerContext* context, |
| 184 | const facade::BluetoothAddress* request, |
| 185 | ::google::protobuf::Empty* response) { |
| 186 | Address peer; |
| 187 | Address::FromString(request->address(), peer); |
| 188 | auto connection = acl_connections_.find(request->address()); |
| 189 | if (connection == acl_connections_.end()) { |
| 190 | LOG_ERROR("Invalid address"); |
| 191 | return ::grpc::Status(::grpc::StatusCode::INVALID_ARGUMENT, "Invalid address"); |
| 192 | } else { |
| 193 | // TODO add individual grpc command if necessary |
| 194 | connection->second->RoleDiscovery(); |
| 195 | connection->second->WriteLinkPolicySettings(0x07); |
| 196 | connection->second->ReadLinkPolicySettings(); |
| 197 | connection->second->SniffSubrating(0x1234, 0x1234, 0x1234); |
| 198 | connection->second->WriteAutomaticFlushTimeout(0x07FF); |
| 199 | connection->second->ReadAutomaticFlushTimeout(); |
| 200 | connection->second->ReadTransmitPowerLevel(TransmitPowerLevelType::CURRENT); |
| 201 | connection->second->ReadTransmitPowerLevel(TransmitPowerLevelType::MAXIMUM); |
| 202 | connection->second->WriteLinkSupervisionTimeout(0x5678); |
| 203 | connection->second->ReadLinkSupervisionTimeout(); |
| 204 | connection->second->ReadFailedContactCounter(); |
| 205 | connection->second->ResetFailedContactCounter(); |
| 206 | connection->second->ReadLinkQuality(); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 207 | connection->second->ReadAfhChannelMap(); |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 208 | connection->second->ReadRssi(); |
| 209 | connection->second->ReadClock(WhichClock::LOCAL); |
| 210 | connection->second->ReadClock(WhichClock::PICONET); |
| 211 | |
| 212 | connection->second->ChangeConnectionPacketType(0xEE1C); |
| 213 | connection->second->SetConnectionEncryption(Enable::ENABLED); |
| 214 | connection->second->ChangeConnectionLinkKey(); |
| 215 | connection->second->ReadClockOffset(); |
| 216 | connection->second->HoldMode(0x0500, 0x0020); |
| 217 | connection->second->SniffMode(0x0500, 0x0020, 0x0040, 0x0014); |
| 218 | connection->second->ExitSniffMode(); |
| 219 | connection->second->QosSetup(ServiceType::BEST_EFFORT, 0x1234, 0x1233, 0x1232, 0x1231); |
| 220 | connection->second->FlowSpecification(FlowDirection::OUTGOING_FLOW, ServiceType::BEST_EFFORT, 0x1234, 0x1233, |
| 221 | 0x1232, 0x1231); |
| 222 | connection->second->Flush(); |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 223 | |
| 224 | acl_manager_->MasterLinkKey(KeyFlag::TEMPORARY); |
| 225 | acl_manager_->SwitchRole(peer, Role::MASTER); |
| 226 | acl_manager_->WriteDefaultLinkPolicySettings(0x07); |
| 227 | acl_manager_->ReadDefaultLinkPolicySettings(); |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 228 | return ::grpc::Status::OK; |
| 229 | } |
| 230 | } |
| 231 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 232 | void on_incoming_acl(std::string address) { |
| 233 | auto connection = acl_connections_.find(address); |
| 234 | if (connection == acl_connections_.end()) { |
| 235 | LOG_ERROR("Invalid address"); |
| 236 | return; |
| 237 | } |
| 238 | |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 239 | auto packet = connection->second->GetAclQueueEnd()->TryDequeue(); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 240 | auto acl_packet = AclPacketView::Create(*packet); |
| 241 | AclData acl_data; |
| 242 | acl_data.mutable_remote()->set_address(address); |
| 243 | std::string data = std::string(acl_packet.begin(), acl_packet.end()); |
| 244 | acl_data.set_payload(data); |
| 245 | acl_stream_.OnIncomingEvent(acl_data); |
| 246 | } |
| 247 | |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 248 | void OnConnectSuccess(std::unique_ptr<::bluetooth::hci::AclConnection> connection) override { |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 249 | std::unique_lock<std::mutex> lock(mutex_); |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 250 | auto addr = connection->GetAddress(); |
| 251 | std::shared_ptr<::bluetooth::hci::AclConnection> shared_connection = std::move(connection); |
| 252 | acl_connections_.emplace(addr.ToString(), shared_connection); |
| 253 | shared_connection->RegisterDisconnectCallback( |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 254 | common::BindOnce(&AclManagerFacadeService::on_disconnect, common::Unretained(this), addr.ToString()), |
| 255 | facade_handler_); |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 256 | shared_connection->RegisterCallbacks(this, facade_handler_); |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 257 | connection_complete_stream_.OnIncomingEvent(shared_connection); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 258 | } |
| 259 | |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 260 | void OnMasterLinkKeyComplete(uint16_t connection_handle, KeyFlag key_flag) override { |
| 261 | LOG_DEBUG("OnMasterLinkKeyComplete connection_handle:%d", connection_handle); |
| 262 | } |
| 263 | |
| 264 | void OnRoleChange(Address bd_addr, Role new_role) override { |
| 265 | LOG_DEBUG("OnRoleChange bd_addr:%s, new_role:%d", bd_addr.ToString().c_str(), (uint8_t)new_role); |
| 266 | } |
| 267 | |
| 268 | void OnReadDefaultLinkPolicySettingsComplete(uint16_t default_link_policy_settings) override { |
| 269 | LOG_DEBUG("OnReadDefaultLinkPolicySettingsComplete default_link_policy_settings:%d", default_link_policy_settings); |
| 270 | } |
| 271 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 272 | void on_disconnect(std::string address, ErrorCode code) { |
| 273 | acl_connections_.erase(address); |
| 274 | DisconnectionEvent event; |
| 275 | event.mutable_remote()->set_address(address); |
| 276 | event.set_reason(static_cast<uint32_t>(code)); |
| 277 | disconnection_stream_.OnIncomingEvent(event); |
| 278 | } |
| 279 | |
| 280 | ::grpc::Status FetchConnectionComplete(::grpc::ServerContext* context, const EventStreamRequest* request, |
| 281 | ::grpc::ServerWriter<ConnectionEvent>* writer) override { |
| 282 | return connection_complete_stream_.HandleRequest(context, request, writer); |
| 283 | }; |
| 284 | |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 285 | void OnConnectFail(Address address, ::bluetooth::hci::ErrorCode reason) override { |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 286 | std::unique_lock<std::mutex> lock(mutex_); |
| 287 | ConnectionFailedEvent event; |
| 288 | event.mutable_remote()->set_address(address.ToString()); |
| 289 | event.set_reason(static_cast<uint32_t>(reason)); |
| 290 | connection_failed_stream_.OnIncomingEvent(event); |
| 291 | } |
| 292 | |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 293 | void OnConnectionPacketTypeChanged(uint16_t packet_type) override { |
| 294 | LOG_DEBUG("OnConnectionPacketTypeChanged packet_type:%d", packet_type); |
| 295 | } |
| 296 | |
| 297 | void OnAuthenticationComplete() override { |
| 298 | LOG_DEBUG("OnAuthenticationComplete"); |
| 299 | } |
| 300 | |
| 301 | void OnEncryptionChange(EncryptionEnabled enabled) override { |
| 302 | LOG_DEBUG("OnConnectionPacketTypeChanged enabled:%d", (uint8_t)enabled); |
| 303 | } |
| 304 | |
| 305 | void OnChangeConnectionLinkKeyComplete() override { |
| 306 | LOG_DEBUG("OnChangeConnectionLinkKeyComplete"); |
| 307 | }; |
| 308 | |
Chienyuan | d1f068f | 2019-09-27 17:27:27 +0800 | [diff] [blame] | 309 | void OnReadClockOffsetComplete(uint16_t clock_offset) override { |
| 310 | LOG_DEBUG("OnReadClockOffsetComplete clock_offset:%d", clock_offset); |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 311 | }; |
| 312 | |
| 313 | void OnModeChange(Mode current_mode, uint16_t interval) override { |
| 314 | LOG_DEBUG("OnModeChange Mode:%d, interval:%d", (uint8_t)current_mode, interval); |
| 315 | }; |
| 316 | |
| 317 | void OnQosSetupComplete(ServiceType service_type, uint32_t token_rate, uint32_t peak_bandwidth, uint32_t latency, |
| 318 | uint32_t delay_variation) override { |
| 319 | LOG_DEBUG("OnQosSetupComplete service_type:%d, token_rate:%d, peak_bandwidth:%d, latency:%d, delay_variation:%d", |
| 320 | (uint8_t)service_type, token_rate, peak_bandwidth, latency, delay_variation); |
| 321 | } |
| 322 | |
| 323 | void OnFlowSpecificationComplete(FlowDirection flow_direction, ServiceType service_type, uint32_t token_rate, |
| 324 | uint32_t token_bucket_size, uint32_t peak_bandwidth, |
| 325 | uint32_t access_latency) override { |
| 326 | LOG_DEBUG( |
| 327 | "OnFlowSpecificationComplete flow_direction:%d. service_type:%d, token_rate:%d, token_bucket_size:%d, " |
| 328 | "peak_bandwidth:%d, access_latency:%d", |
| 329 | (uint8_t)flow_direction, (uint8_t)service_type, token_rate, token_bucket_size, peak_bandwidth, access_latency); |
| 330 | } |
| 331 | |
| 332 | void OnFlushOccurred() override { |
| 333 | LOG_DEBUG("OnFlushOccurred"); |
| 334 | } |
| 335 | |
| 336 | void OnRoleDiscoveryComplete(Role current_role) override { |
| 337 | LOG_DEBUG("OnRoleDiscoveryComplete current_role:%d", (uint8_t)current_role); |
| 338 | } |
| 339 | |
| 340 | void OnReadLinkPolicySettingsComplete(uint16_t link_policy_settings) override { |
| 341 | LOG_DEBUG("OnReadLinkPolicySettingsComplete link_policy_settings:%d", link_policy_settings); |
| 342 | } |
| 343 | |
| 344 | void OnReadAutomaticFlushTimeoutComplete(uint16_t flush_timeout) override { |
| 345 | LOG_DEBUG("OnReadAutomaticFlushTimeoutComplete flush_timeout:%d", flush_timeout); |
| 346 | } |
| 347 | |
| 348 | void OnReadTransmitPowerLevelComplete(uint8_t transmit_power_level) override { |
| 349 | LOG_DEBUG("OnReadTransmitPowerLevelComplete transmit_power_level:%d", transmit_power_level); |
| 350 | } |
| 351 | |
| 352 | void OnReadLinkSupervisionTimeoutComplete(uint16_t link_supervision_timeout) override { |
| 353 | LOG_DEBUG("OnReadLinkSupervisionTimeoutComplete link_supervision_timeout:%d", link_supervision_timeout); |
| 354 | } |
| 355 | |
| 356 | void OnReadFailedContactCounterComplete(uint16_t failed_contact_counter) override { |
| 357 | LOG_DEBUG("OnReadFailedContactCounterComplete failed_contact_counter:%d", failed_contact_counter); |
| 358 | } |
| 359 | |
| 360 | void OnReadLinkQualityComplete(uint8_t link_quality) override { |
| 361 | LOG_DEBUG("OnReadLinkQualityComplete link_quality:%d", link_quality); |
| 362 | } |
| 363 | |
Chienyuan | 9145e7a | 2019-10-02 15:18:55 +0800 | [diff] [blame] | 364 | void OnReadAfhChannelMapComplete(AfhMode afh_mode, std::array<uint8_t, 10> afh_channel_map) { |
| 365 | LOG_DEBUG("OnReadAfhChannelMapComplete afh_mode:%d", (uint8_t)afh_mode); |
| 366 | } |
| 367 | |
Chienyuan | 7eb2365 | 2019-09-11 16:37:30 +0800 | [diff] [blame] | 368 | void OnReadRssiComplete(uint8_t rssi) override { |
| 369 | LOG_DEBUG("OnReadRssiComplete rssi:%d", rssi); |
| 370 | } |
| 371 | |
| 372 | void OnReadClockComplete(uint32_t clock, uint16_t accuracy) override { |
| 373 | LOG_DEBUG("OnReadClockComplete clock:%d, accuracy:%d", clock, accuracy); |
| 374 | } |
| 375 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 376 | ::grpc::Status FetchConnectionFailed(::grpc::ServerContext* context, const EventStreamRequest* request, |
| 377 | ::grpc::ServerWriter<ConnectionFailedEvent>* writer) override { |
| 378 | return connection_failed_stream_.HandleRequest(context, request, writer); |
| 379 | }; |
| 380 | |
| 381 | ::grpc::Status FetchDisconnection(::grpc::ServerContext* context, |
| 382 | const ::bluetooth::facade::EventStreamRequest* request, |
| 383 | ::grpc::ServerWriter<DisconnectionEvent>* writer) override { |
| 384 | return disconnection_stream_.HandleRequest(context, request, writer); |
| 385 | } |
| 386 | |
| 387 | private: |
| 388 | AclManager* acl_manager_; |
| 389 | Controller* controller_; |
| 390 | HciLayer* hci_layer_; |
| 391 | mutable std::mutex mutex_; |
| 392 | ::bluetooth::os::Handler* facade_handler_; |
| 393 | |
| 394 | class ConnectionCompleteStreamCallback |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 395 | : public ::bluetooth::grpc::GrpcEventStreamCallback<ConnectionEvent, std::shared_ptr<AclConnection>> { |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 396 | public: |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 397 | void OnWriteResponse(ConnectionEvent* response, const std::shared_ptr<AclConnection>& connection) override { |
| 398 | response->mutable_remote()->set_address(connection->GetAddress().ToString()); |
| 399 | response->set_connection_handle(connection->GetHandle()); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 400 | } |
| 401 | } connection_complete_stream_callback_; |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 402 | ::bluetooth::grpc::GrpcEventStream<ConnectionEvent, std::shared_ptr<AclConnection>> connection_complete_stream_{ |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 403 | &connection_complete_stream_callback_}; |
| 404 | |
| 405 | class ConnectionFailedStreamCallback |
| 406 | : public ::bluetooth::grpc::GrpcEventStreamCallback<ConnectionFailedEvent, ConnectionFailedEvent> { |
| 407 | public: |
| 408 | void OnWriteResponse(ConnectionFailedEvent* response, const ConnectionFailedEvent& event) override { |
| 409 | response->CopyFrom(event); |
| 410 | } |
| 411 | } connection_failed_stream_callback_; |
| 412 | ::bluetooth::grpc::GrpcEventStream<ConnectionFailedEvent, ConnectionFailedEvent> connection_failed_stream_{ |
| 413 | &connection_failed_stream_callback_}; |
| 414 | |
| 415 | class DisconnectionStreamCallback |
| 416 | : public ::bluetooth::grpc::GrpcEventStreamCallback<DisconnectionEvent, DisconnectionEvent> { |
| 417 | public: |
| 418 | void OnWriteResponse(DisconnectionEvent* response, const DisconnectionEvent& event) override { |
| 419 | response->CopyFrom(event); |
| 420 | } |
| 421 | } disconnection_stream_callback_; |
| 422 | ::bluetooth::grpc::GrpcEventStream<DisconnectionEvent, DisconnectionEvent> disconnection_stream_{ |
| 423 | &disconnection_stream_callback_}; |
| 424 | |
| 425 | class AclStreamCallback : public ::bluetooth::grpc::GrpcEventStreamCallback<AclData, AclData> { |
| 426 | public: |
| 427 | AclStreamCallback(AclManagerFacadeService* service) : service_(service) {} |
| 428 | |
| 429 | ~AclStreamCallback() { |
| 430 | if (subscribed_) { |
| 431 | for (const auto& connection : service_->acl_connections_) { |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 432 | connection.second->GetAclQueueEnd()->UnregisterDequeue(); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 433 | } |
| 434 | subscribed_ = false; |
| 435 | } |
| 436 | } |
| 437 | |
| 438 | void OnSubscribe() override { |
| 439 | if (subscribed_) { |
| 440 | LOG_WARN("Already subscribed"); |
| 441 | return; |
| 442 | } |
| 443 | for (const auto& connection : service_->acl_connections_) { |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 444 | auto remote_address = connection.second->GetAddress().ToString(); |
| 445 | connection.second->GetAclQueueEnd()->RegisterDequeue( |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 446 | service_->facade_handler_, |
| 447 | common::Bind(&AclManagerFacadeService::on_incoming_acl, common::Unretained(service_), remote_address)); |
| 448 | } |
| 449 | subscribed_ = true; |
| 450 | } |
| 451 | |
| 452 | void OnUnsubscribe() override { |
| 453 | if (!subscribed_) { |
| 454 | LOG_WARN("Not subscribed"); |
| 455 | return; |
| 456 | } |
| 457 | for (const auto& connection : service_->acl_connections_) { |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 458 | connection.second->GetAclQueueEnd()->UnregisterDequeue(); |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 459 | } |
| 460 | subscribed_ = false; |
| 461 | } |
| 462 | |
| 463 | void OnWriteResponse(AclData* response, const AclData& event) override { |
| 464 | response->CopyFrom(event); |
| 465 | } |
| 466 | |
| 467 | private: |
| 468 | AclManagerFacadeService* service_; |
| 469 | bool subscribed_ = false; |
| 470 | } acl_stream_callback_{this}; |
| 471 | ::bluetooth::grpc::GrpcEventStream<AclData, AclData> acl_stream_{&acl_stream_callback_}; |
| 472 | |
Jack He | a96f590 | 2019-08-19 16:41:20 -0700 | [diff] [blame] | 473 | std::map<std::string, std::shared_ptr<AclConnection>> acl_connections_; |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 474 | }; |
| 475 | |
| 476 | void AclManagerFacadeModule::ListDependencies(ModuleList* list) { |
| 477 | ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list); |
| 478 | list->add<AclManager>(); |
| 479 | list->add<Controller>(); |
| 480 | list->add<HciLayer>(); |
| 481 | } |
| 482 | |
| 483 | void AclManagerFacadeModule::Start() { |
| 484 | ::bluetooth::grpc::GrpcFacadeModule::Start(); |
| 485 | service_ = new AclManagerFacadeService(GetDependency<AclManager>(), GetDependency<Controller>(), |
| 486 | GetDependency<HciLayer>(), GetHandler()); |
| 487 | } |
| 488 | |
| 489 | void AclManagerFacadeModule::Stop() { |
| 490 | delete service_; |
| 491 | ::bluetooth::grpc::GrpcFacadeModule::Stop(); |
| 492 | } |
| 493 | |
| 494 | ::grpc::Service* AclManagerFacadeModule::GetService() const { |
| 495 | return service_; |
| 496 | } |
| 497 | |
| 498 | const ModuleFactory AclManagerFacadeModule::Factory = |
| 499 | ::bluetooth::ModuleFactory([]() { return new AclManagerFacadeModule(); }); |
| 500 | |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 501 | class ClassicSecurityManagerFacadeService : public ClassicSecurityManagerFacade::Service, |
| 502 | public ::bluetooth::hci::ClassicSecurityCommandCallbacks { |
| 503 | public: |
| 504 | ClassicSecurityManagerFacadeService(ClassicSecurityManager* classic_security_manager, Controller* controller, |
| 505 | HciLayer* hci_layer, ::bluetooth::os::Handler* facade_handler) |
| 506 | : classic_security_manager_(classic_security_manager), facade_handler_(facade_handler) { |
| 507 | classic_security_manager_->RegisterCallbacks(this, facade_handler_); |
| 508 | } |
| 509 | |
| 510 | ::grpc::Status LinkKeyRequestReply(::grpc::ServerContext* context, |
| 511 | const ::bluetooth::hci::LinkKeyRequestReplyMessage* request, |
| 512 | ::google::protobuf::Empty* response) { |
| 513 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 514 | Address peer; |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 515 | common::LinkKey link_key; |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 516 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 517 | ASSERT(common::LinkKey::FromString(request->link_key(), link_key)); |
| 518 | classic_security_manager_->LinkKeyRequestReply(peer, link_key); |
| 519 | return ::grpc::Status::OK; |
| 520 | }; |
| 521 | |
| 522 | ::grpc::Status LinkKeyRequestNegativeReply(::grpc::ServerContext* context, |
| 523 | const ::bluetooth::facade::BluetoothAddress* request, |
| 524 | ::google::protobuf::Empty* response) { |
| 525 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 526 | Address peer; |
| 527 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 528 | classic_security_manager_->LinkKeyRequestNegativeReply(peer); |
| 529 | return ::grpc::Status::OK; |
| 530 | } |
| 531 | |
| 532 | ::grpc::Status PinCodeRequestReply(::grpc::ServerContext* context, |
| 533 | const ::bluetooth::hci::PinCodeRequestReplyMessage* request, |
| 534 | ::google::protobuf::Empty* response) { |
| 535 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 536 | Address peer; |
| 537 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 538 | uint8_t len = request->len(); |
| 539 | std::string pin_code = request->pin_code(); |
| 540 | classic_security_manager_->PinCodeRequestReply(peer, len, pin_code); |
| 541 | return ::grpc::Status::OK; |
| 542 | }; |
| 543 | |
| 544 | ::grpc::Status PinCodeRequestNegativeReply(::grpc::ServerContext* context, |
| 545 | const ::bluetooth::facade::BluetoothAddress* request, |
| 546 | ::google::protobuf::Empty* response) { |
| 547 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 548 | Address peer; |
| 549 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 550 | classic_security_manager_->PinCodeRequestNegativeReply(peer); |
| 551 | return ::grpc::Status::OK; |
| 552 | } |
| 553 | |
| 554 | ::grpc::Status IoCapabilityRequestReply(::grpc::ServerContext* context, |
| 555 | const ::bluetooth::hci::IoCapabilityRequestReplyMessage* request, |
| 556 | ::google::protobuf::Empty* response) { |
| 557 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 558 | Address peer; |
| 559 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 560 | IoCapability io_capability = (IoCapability)request->io_capability(); |
| 561 | OobDataPresent oob_present = (OobDataPresent)request->oob_present(); |
| 562 | AuthenticationRequirements authentication_requirements = |
| 563 | (AuthenticationRequirements)request->authentication_requirements(); |
| 564 | classic_security_manager_->IoCapabilityRequestReply(peer, io_capability, oob_present, authentication_requirements); |
| 565 | return ::grpc::Status::OK; |
| 566 | }; |
| 567 | |
| 568 | ::grpc::Status IoCapabilityRequestNegativeReply( |
| 569 | ::grpc::ServerContext* context, const ::bluetooth::hci::IoCapabilityRequestNegativeReplyMessage* request, |
| 570 | ::google::protobuf::Empty* response) { |
| 571 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 572 | Address peer; |
| 573 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 574 | ErrorCode reason = (ErrorCode)request->reason(); |
| 575 | classic_security_manager_->IoCapabilityRequestNegativeReply(peer, reason); |
| 576 | return ::grpc::Status::OK; |
| 577 | }; |
| 578 | |
| 579 | ::grpc::Status UserConfirmationRequestReply(::grpc::ServerContext* context, |
| 580 | const ::bluetooth::facade::BluetoothAddress* request, |
| 581 | ::google::protobuf::Empty* response) { |
| 582 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 583 | Address peer; |
| 584 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 585 | classic_security_manager_->UserConfirmationRequestReply(peer); |
| 586 | return ::grpc::Status::OK; |
| 587 | } |
| 588 | |
| 589 | ::grpc::Status UserConfirmationRequestNegativeReply(::grpc::ServerContext* context, |
| 590 | const ::bluetooth::facade::BluetoothAddress* request, |
| 591 | ::google::protobuf::Empty* response) { |
| 592 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 593 | Address peer; |
| 594 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 595 | classic_security_manager_->UserConfirmationRequestNegativeReply(peer); |
| 596 | return ::grpc::Status::OK; |
| 597 | } |
| 598 | |
| 599 | ::grpc::Status UserPasskeyRequestReply(::grpc::ServerContext* context, |
| 600 | const ::bluetooth::hci::UserPasskeyRequestReplyMessage* request, |
| 601 | ::google::protobuf::Empty* response) { |
| 602 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 603 | Address peer; |
| 604 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 605 | uint32_t passkey = request->passkey(); |
| 606 | classic_security_manager_->UserPasskeyRequestReply(peer, passkey); |
| 607 | return ::grpc::Status::OK; |
| 608 | }; |
| 609 | |
| 610 | ::grpc::Status UserPasskeyRequestNegativeReply(::grpc::ServerContext* context, |
| 611 | const ::bluetooth::facade::BluetoothAddress* request, |
| 612 | ::google::protobuf::Empty* response) { |
| 613 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 614 | Address peer; |
| 615 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 616 | classic_security_manager_->UserPasskeyRequestNegativeReply(peer); |
| 617 | return ::grpc::Status::OK; |
| 618 | } |
| 619 | |
| 620 | ::grpc::Status RemoteOobDataRequestReply(::grpc::ServerContext* context, |
| 621 | const ::bluetooth::hci::RemoteOobDataRequestReplyMessage* request, |
| 622 | ::google::protobuf::Empty* response) { |
| 623 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 624 | Address peer; |
| 625 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 626 | std::string c_string = request->c(); |
| 627 | std::string r_string = request->r(); |
| 628 | std::array<uint8_t, 16> c; |
| 629 | std::array<uint8_t, 16> r; |
| 630 | std::copy(std::begin(c_string), std::end(c_string), std::begin(c)); |
| 631 | std::copy(std::begin(r_string), std::end(r_string), std::begin(r)); |
| 632 | classic_security_manager_->RemoteOobDataRequestReply(peer, c, r); |
| 633 | return ::grpc::Status::OK; |
| 634 | }; |
| 635 | |
| 636 | ::grpc::Status RemoteOobDataRequestNegativeReply(::grpc::ServerContext* context, |
| 637 | const ::bluetooth::facade::BluetoothAddress* request, |
| 638 | ::google::protobuf::Empty* response) { |
| 639 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 640 | Address peer; |
| 641 | ASSERT(Address::FromString(request->address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 642 | classic_security_manager_->RemoteOobDataRequestNegativeReply(peer); |
| 643 | return ::grpc::Status::OK; |
| 644 | } |
| 645 | |
| 646 | ::grpc::Status ReadStoredLinkKey(::grpc::ServerContext* context, |
| 647 | const ::bluetooth::hci::ReadStoredLinkKeyMessage* request, |
| 648 | ::google::protobuf::Empty* response) { |
| 649 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 650 | Address peer; |
| 651 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 652 | ReadStoredLinkKeyReadAllFlag read_all_flag = (ReadStoredLinkKeyReadAllFlag)request->read_all_flag(); |
| 653 | classic_security_manager_->ReadStoredLinkKey(peer, read_all_flag); |
| 654 | return ::grpc::Status::OK; |
| 655 | }; |
| 656 | |
| 657 | ::grpc::Status WriteStoredLinkKey(::grpc::ServerContext* context, |
| 658 | const ::bluetooth::hci::WriteStoredLinkKeyMessage* request, |
| 659 | ::google::protobuf::Empty* response) { |
| 660 | std::unique_lock<std::mutex> lock(mutex_); |
| 661 | uint8_t num_keys_to_write = request->num_keys_to_write(); |
Myles Watson | 2d23443 | 2019-08-19 13:33:27 -0700 | [diff] [blame] | 662 | std::vector<KeyAndAddress> keys; |
| 663 | for (size_t i = 0; i < num_keys_to_write; i++) { |
| 664 | KeyAndAddress key; |
| 665 | common::LinkKey link_key; |
| 666 | ASSERT(Address::FromString(request->remote().address(), key.address_)); |
| 667 | ASSERT(common::LinkKey::FromString(request->link_keys(), link_key)); |
| 668 | std::copy(std::begin(link_key.link_key), std::end(link_key.link_key), std::begin(key.link_key_)); |
| 669 | keys.push_back(key); |
| 670 | } |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 671 | |
Myles Watson | 2d23443 | 2019-08-19 13:33:27 -0700 | [diff] [blame] | 672 | classic_security_manager_->WriteStoredLinkKey(keys); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 673 | return ::grpc::Status::OK; |
| 674 | }; |
| 675 | |
| 676 | ::grpc::Status DeleteStoredLinkKey(::grpc::ServerContext* context, |
| 677 | const ::bluetooth::hci::DeleteStoredLinkKeyMessage* request, |
| 678 | ::google::protobuf::Empty* response) { |
| 679 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 680 | Address peer; |
| 681 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 682 | DeleteStoredLinkKeyDeleteAllFlag delete_all_flag = (DeleteStoredLinkKeyDeleteAllFlag)request->delete_all_flag(); |
| 683 | classic_security_manager_->DeleteStoredLinkKey(peer, delete_all_flag); |
| 684 | return ::grpc::Status::OK; |
| 685 | }; |
| 686 | |
| 687 | ::grpc::Status RefreshEncryptionKey(::grpc::ServerContext* context, |
| 688 | const ::bluetooth::hci::RefreshEncryptionKeyMessage* request, |
| 689 | ::google::protobuf::Empty* response) { |
| 690 | std::unique_lock<std::mutex> lock(mutex_); |
| 691 | classic_security_manager_->RefreshEncryptionKey(request->connection_handle()); |
| 692 | return ::grpc::Status::OK; |
| 693 | }; |
| 694 | |
| 695 | ::grpc::Status ReadSimplePairingMode(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, |
| 696 | ::google::protobuf::Empty* response) { |
| 697 | std::unique_lock<std::mutex> lock(mutex_); |
| 698 | classic_security_manager_->ReadSimplePairingMode(); |
| 699 | return ::grpc::Status::OK; |
| 700 | }; |
| 701 | |
| 702 | ::grpc::Status WriteSimplePairingMode(::grpc::ServerContext* context, |
| 703 | const ::bluetooth::hci::WriteSimplePairingModeMessage* request, |
| 704 | ::google::protobuf::Empty* response) { |
| 705 | std::unique_lock<std::mutex> lock(mutex_); |
| 706 | Enable simple_pairing_mode = (Enable)request->simple_pairing_mode(); |
| 707 | classic_security_manager_->WriteSimplePairingMode(simple_pairing_mode); |
| 708 | return ::grpc::Status::OK; |
| 709 | }; |
| 710 | |
| 711 | ::grpc::Status ReadLocalOobData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, |
| 712 | ::google::protobuf::Empty* response) { |
| 713 | std::unique_lock<std::mutex> lock(mutex_); |
| 714 | classic_security_manager_->ReadLocalOobData(); |
| 715 | return ::grpc::Status::OK; |
| 716 | }; |
| 717 | |
| 718 | ::grpc::Status SendKeypressNotification(::grpc::ServerContext* context, |
| 719 | const ::bluetooth::hci::SendKeypressNotificationMessage* request, |
| 720 | ::google::protobuf::Empty* response) { |
| 721 | std::unique_lock<std::mutex> lock(mutex_); |
Martin Brabham | 94db40c | 2019-03-29 10:24:52 -0700 | [diff] [blame] | 722 | Address peer; |
| 723 | ASSERT(Address::FromString(request->remote().address(), peer)); |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 724 | KeypressNotificationType notification_type = (KeypressNotificationType)request->notification_type(); |
| 725 | classic_security_manager_->SendKeypressNotification(peer, notification_type); |
| 726 | return ::grpc::Status::OK; |
| 727 | }; |
| 728 | |
| 729 | ::grpc::Status ReadLocalOobExtendedData(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, |
| 730 | ::google::protobuf::Empty* response) { |
| 731 | std::unique_lock<std::mutex> lock(mutex_); |
| 732 | classic_security_manager_->ReadLocalOobExtendedData(); |
| 733 | return ::grpc::Status::OK; |
| 734 | }; |
| 735 | |
| 736 | ::grpc::Status ReadEncryptionKeySize(::grpc::ServerContext* context, |
| 737 | const ::bluetooth::hci::ReadEncryptionKeySizeMessage* request, |
| 738 | ::google::protobuf::Empty* response) { |
| 739 | std::unique_lock<std::mutex> lock(mutex_); |
| 740 | classic_security_manager_->ReadEncryptionKeySize(request->connection_handle()); |
| 741 | return ::grpc::Status::OK; |
| 742 | }; |
| 743 | |
Chienyuan | 4d7cc81 | 2019-07-12 18:00:12 +0800 | [diff] [blame] | 744 | ::grpc::Status FetchCommandCompleteEvent(::grpc::ServerContext* context, const EventStreamRequest* request, |
| 745 | ::grpc::ServerWriter<CommandCompleteEvent>* writer) override { |
| 746 | return command_complete_stream_.HandleRequest(context, request, writer); |
| 747 | }; |
| 748 | |
| 749 | void OnCommandComplete(CommandCompleteView status) override { |
| 750 | std::unique_lock<std::mutex> lock(mutex_); |
| 751 | command_complete_stream_.OnIncomingEvent(status); |
| 752 | } |
| 753 | |
| 754 | private: |
| 755 | ClassicSecurityManager* classic_security_manager_; |
| 756 | mutable std::mutex mutex_; |
| 757 | ::bluetooth::os::Handler* facade_handler_; |
| 758 | |
| 759 | class CommandCompleteStreamCallback |
| 760 | : public ::bluetooth::grpc::GrpcEventStreamCallback<CommandCompleteEvent, CommandCompleteView> { |
| 761 | public: |
| 762 | void OnWriteResponse(CommandCompleteEvent* response, CommandCompleteView const& status) override { |
| 763 | response->set_command_opcode((uint32_t)status.GetCommandOpCode()); |
| 764 | } |
| 765 | } command_complete_stream_callback_; |
| 766 | ::bluetooth::grpc::GrpcEventStream<CommandCompleteEvent, CommandCompleteView> command_complete_stream_{ |
| 767 | &command_complete_stream_callback_}; |
| 768 | }; |
| 769 | |
| 770 | void ClassicSecurityManagerFacadeModule::ListDependencies(ModuleList* list) { |
| 771 | ::bluetooth::grpc::GrpcFacadeModule::ListDependencies(list); |
| 772 | list->add<ClassicSecurityManager>(); |
| 773 | list->add<Controller>(); |
| 774 | list->add<HciLayer>(); |
| 775 | } |
| 776 | |
| 777 | void ClassicSecurityManagerFacadeModule::Start() { |
| 778 | ::bluetooth::grpc::GrpcFacadeModule::Start(); |
| 779 | service_ = new ClassicSecurityManagerFacadeService( |
| 780 | GetDependency<ClassicSecurityManager>(), GetDependency<Controller>(), GetDependency<HciLayer>(), GetHandler()); |
| 781 | } |
| 782 | |
| 783 | void ClassicSecurityManagerFacadeModule::Stop() { |
| 784 | delete service_; |
| 785 | ::bluetooth::grpc::GrpcFacadeModule::Stop(); |
| 786 | } |
| 787 | |
| 788 | ::grpc::Service* ClassicSecurityManagerFacadeModule::GetService() const { |
| 789 | return service_; |
| 790 | } |
| 791 | |
| 792 | const ModuleFactory ClassicSecurityManagerFacadeModule::Factory = |
| 793 | ::bluetooth::ModuleFactory([]() { return new ClassicSecurityManagerFacadeModule(); }); |
| 794 | |
Hansong Zhang | c5ec8f9 | 2019-06-19 17:22:21 -0700 | [diff] [blame] | 795 | } // namespace hci |
| 796 | } // namespace bluetooth |