1 /* 2 * Copyright 2015 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 #pragma once 18 19 #include <unistd.h> 20 21 #include <cstdint> 22 #include <functional> 23 #include <memory> 24 #include <random> 25 #include <string> 26 #include <unordered_map> 27 #include <vector> 28 29 #include "hci/address.h" 30 #include "model/controller/controller_properties.h" 31 #include "model/controller/link_layer_controller.h" 32 #include "model/controller/vendor_commands/csr.h" 33 #include "model/devices/device.h" 34 #include "packets/hci_packets.h" 35 #include "packets/link_layer_packets.h" 36 #include "phy.h" 37 38 namespace rootcanal { 39 40 using ::bluetooth::hci::Address; 41 using ::bluetooth::hci::CommandView; 42 43 // List of reject reasons for invalid packets. 44 enum InvalidPacketReason { 45 kUnknown = 0, 46 kParseError = 1, 47 kUnsupported = 2, 48 }; 49 50 // Emulates a dual mode BR/EDR + LE controller by maintaining the link layer 51 // state machine detailed in the Bluetooth Core Specification Version 4.2, 52 // Volume 6, Part B, Section 1.1 (page 30). Provides methods corresponding to 53 // commands sent by the HCI. These methods will be registered as callbacks from 54 // a controller instance with the HciHandler. To implement a new Bluetooth 55 // command, simply add the method declaration below, with return type void and a 56 // single const std::vector<uint8_t>& argument. After implementing the 57 // method, simply register it with the HciHandler using the SET_HANDLER macro in 58 // the controller's default constructor. Be sure to name your method after the 59 // corresponding Bluetooth command in the Core Specification with the prefix 60 // "Hci" to distinguish it as a controller command. 61 class DualModeController : public Device { 62 public: 63 DualModeController(ControllerProperties properties = ControllerProperties()); 64 DualModeController(DualModeController&&) = delete; 65 DualModeController(const DualModeController&) = delete; 66 ~DualModeController() = default; 67 68 DualModeController& operator=(const DualModeController&) = delete; 69 70 // Overwrite the configuration. 71 void SetProperties(ControllerProperties properties); 72 73 // Device methods. 74 std::string GetTypeString() const override; 75 76 void ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView incoming, Phy::Type type, 77 int8_t rssi) override; 78 79 void Tick() override; 80 void Close() override; 81 82 // Route commands and data from the stack. 83 void HandleAcl(std::shared_ptr<std::vector<uint8_t>> acl_packet); 84 void HandleCommand(std::shared_ptr<std::vector<uint8_t>> command_packet); 85 void HandleSco(std::shared_ptr<std::vector<uint8_t>> sco_packet); 86 void HandleIso(std::shared_ptr<std::vector<uint8_t>> iso_packet); 87 88 /// Report invalid packets received for this controller instance 89 /// to an external tracker. Packets are rejected if they failed to 90 /// be parsed, or run into an unimplemented part of the controller. 91 void RegisterInvalidPacketHandler( 92 const std::function<void(uint32_t, InvalidPacketReason, std::string, 93 std::vector<uint8_t> const&)>& handler); 94 95 // Set the callbacks for sending packets to the HCI. 96 void RegisterEventChannel( 97 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_event); 98 99 void RegisterAclChannel( 100 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_acl); 101 102 void RegisterScoChannel( 103 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_sco); 104 105 void RegisterIsoChannel( 106 const std::function<void(std::shared_ptr<std::vector<uint8_t>>)>& send_iso); 107 108 // Controller commands. For error codes, see the Bluetooth Core Specification, 109 // Version 4.2, Volume 2, Part D (page 370). 110 111 // Link Control Commands 112 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.1 113 114 // 7.1.1 115 void Inquiry(CommandView command); 116 117 // 7.1.2 118 void InquiryCancel(CommandView command); 119 120 // 7.1.5 121 void CreateConnection(CommandView command); 122 123 // 7.1.6 124 void Disconnect(CommandView command); 125 126 // Deprecated 127 void AddScoConnection(CommandView command); 128 129 // 7.1.7 130 void CreateConnectionCancel(CommandView command); 131 132 // 7.1.8 133 void AcceptConnectionRequest(CommandView command); 134 135 // 7.1.9 136 void RejectConnectionRequest(CommandView command); 137 138 // 7.1.14 139 void ChangeConnectionPacketType(CommandView command); 140 141 // 7.1.17 142 void ChangeConnectionLinkKey(CommandView command); 143 144 // 7.1.18 145 void CentralLinkKey(CommandView command); 146 147 // 7.1.19 148 void RemoteNameRequest(CommandView command); 149 150 // 7.1.21 151 void ReadRemoteSupportedFeatures(CommandView command); 152 153 // 7.1.22 154 void ReadRemoteExtendedFeatures(CommandView command); 155 156 // 7.1.23 157 void ReadRemoteVersionInformation(CommandView command); 158 159 // 7.1.24 160 void ReadClockOffset(CommandView command); 161 162 // 7.1.26 163 void SetupSynchronousConnection(CommandView command); 164 165 // 7.1.27 166 void AcceptSynchronousConnection(CommandView command); 167 168 // 7.1.28 169 void RejectSynchronousConnection(CommandView command); 170 171 // 7.1.45 172 void EnhancedSetupSynchronousConnection(CommandView command); 173 174 // 7.1.46 175 void EnhancedAcceptSynchronousConnection(CommandView command); 176 177 // Link Policy Commands 178 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.2 179 180 // 7.2.1 181 void HoldMode(CommandView command); 182 183 // 7.2.2 184 void SniffMode(CommandView command); 185 186 // 7.2.3 187 void ExitSniffMode(CommandView command); 188 189 // 7.2.6 190 void QosSetup(CommandView command); 191 192 // 7.2.7 193 void RoleDiscovery(CommandView command); 194 195 // 7.2.8 196 void SwitchRole(CommandView command); 197 198 // 7.2.9 199 void ReadLinkPolicySettings(CommandView command); 200 201 // 7.2.10 202 void WriteLinkPolicySettings(CommandView command); 203 204 // 7.2.11 205 void ReadDefaultLinkPolicySettings(CommandView command); 206 207 // 7.2.12 208 void WriteDefaultLinkPolicySettings(CommandView command); 209 210 // 7.2.13 211 void FlowSpecification(CommandView command); 212 213 // 7.2.14 214 void SniffSubrating(CommandView command); 215 216 // Link Controller Commands 217 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.3 218 219 // 7.3.1 220 void SetEventMask(CommandView command); 221 222 // 7.3.2 223 void Reset(CommandView command); 224 225 // 7.3.3 226 void SetEventFilter(CommandView command); 227 228 // 7.3.10 229 void DeleteStoredLinkKey(CommandView command); 230 231 // 7.3.11 232 void WriteLocalName(CommandView command); 233 234 // 7.3.12 235 void ReadLocalName(CommandView command); 236 237 // 7.3.13 - 7.3.14 238 void ReadConnectionAcceptTimeout(CommandView command); 239 void WriteConnectionAcceptTimeout(CommandView command); 240 241 // 7.3.15 - 7.3.16 242 void ReadPageTimeout(CommandView command); 243 void WritePageTimeout(CommandView command); 244 245 // 7.3.17 - 7.3.18 246 void ReadScanEnable(CommandView command); 247 void WriteScanEnable(CommandView command); 248 249 // 7.3.19 - 7.3.20 250 void ReadPageScanActivity(CommandView command); 251 void WritePageScanActivity(CommandView command); 252 253 // 7.3.21 - 7.3.22 254 void ReadInquiryScanActivity(CommandView command); 255 void WriteInquiryScanActivity(CommandView command); 256 257 // 7.3.23 - 7.3.24 258 void ReadAuthenticationEnable(CommandView command); 259 void WriteAuthenticationEnable(CommandView command); 260 261 // 7.3.25 - 7.3.26 262 void ReadClassOfDevice(CommandView command); 263 void WriteClassOfDevice(CommandView command); 264 265 // 7.3.27 - 7.3.28 266 void ReadVoiceSetting(CommandView command); 267 void WriteVoiceSetting(CommandView command); 268 269 // 7.3.35 270 void ReadTransmitPowerLevel(CommandView command); 271 272 // 7.3.36 - 7.3.37 273 void ReadSynchronousFlowControlEnable(CommandView command); 274 void WriteSynchronousFlowControlEnable(CommandView command); 275 276 // 7.3.39 277 void HostBufferSize(CommandView command); 278 279 // 7.3.42 280 void WriteLinkSupervisionTimeout(CommandView command); 281 282 // 7.3.43 283 void ReadNumberOfSupportedIac(CommandView command); 284 285 // 7.3.44 - 7.3.45 286 void ReadCurrentIacLap(CommandView command); 287 void WriteCurrentIacLap(CommandView command); 288 289 // 7.3.47 290 void ReadInquiryScanType(CommandView command); 291 292 // 7.3.48 293 void WriteInquiryScanType(CommandView command); 294 295 // 7.3.49 296 void ReadInquiryMode(CommandView command); 297 298 // 7.3.50 299 void WriteInquiryMode(CommandView command); 300 301 // 7.3.52 302 void ReadPageScanType(CommandView command); 303 304 // 7.3.52 305 void WritePageScanType(CommandView command); 306 307 // 7.3.56 308 void WriteExtendedInquiryResponse(CommandView command); 309 310 // 7.3.57 311 void RefreshEncryptionKey(CommandView command); 312 313 // 7.3.59 314 void WriteSimplePairingMode(CommandView command); 315 316 // 7.3.60 317 void ReadLocalOobData(CommandView command); 318 319 // 7.3.61 320 void ReadInquiryResponseTransmitPowerLevel(CommandView command); 321 322 // 7.3.66 323 void EnhancedFlush(CommandView command); 324 325 // 7.3.69 326 void SetEventMaskPage2(CommandView command); 327 328 // 7.3.74 329 void ReadEnhancedTransmitPowerLevel(CommandView command); 330 331 // 7.3.79 332 void WriteLeHostSupport(CommandView command); 333 334 // 7.3.92 335 void WriteSecureConnectionsHostSupport(CommandView command); 336 337 // 7.3.95 338 void ReadLocalOobExtendedData(CommandView command); 339 340 // Informational Parameters Commands 341 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.4 342 343 // 7.4.5 344 void ReadBufferSize(CommandView command); 345 346 // 7.4.1 347 void ReadLocalVersionInformation(CommandView command); 348 349 // 7.4.6 350 void ReadBdAddr(CommandView command); 351 352 // 7.4.2 353 void ReadLocalSupportedCommands(CommandView command); 354 355 // 7.4.3 356 void ReadLocalSupportedFeatures(CommandView command); 357 358 // 7.4.4 359 void ReadLocalExtendedFeatures(CommandView command); 360 361 // 7.4.8 362 void ReadLocalSupportedCodecsV1(CommandView command); 363 364 // Status Parameters Commands 365 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.5 366 367 // 7.5.1 - 7.5.2 368 void ReadFailedContactCounter(CommandView command); 369 void ResetFailedContactCounter(CommandView command); 370 371 // 7.5.4 372 void ReadRssi(CommandView command); 373 374 // 7.5.7 375 void ReadEncryptionKeySize(CommandView command); 376 377 // Test Commands 378 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.7 379 380 // 7.7.1 381 void ReadLoopbackMode(CommandView command); 382 383 // 7.7.2 384 void WriteLoopbackMode(CommandView command); 385 386 // LE Controller Commands 387 // Bluetooth Core Specification Version 4.2 Volume 2 Part E 7.8 388 389 // 7.8.1 390 void LeSetEventMask(CommandView command); 391 392 // 7.8.2 - 7.8.93 393 void LeReadBufferSizeV1(CommandView command); 394 void LeReadBufferSizeV2(CommandView command); 395 396 // 7.8.3 397 void LeReadLocalSupportedFeaturesPage0(CommandView command); 398 399 // 7.8.4 400 void LeSetRandomAddress(CommandView command); 401 402 // 7.8.5 - 7.8.9 403 void LeSetAdvertisingParameters(CommandView command); 404 void LeReadAdvertisingPhysicalChannelTxPower(CommandView command); 405 void LeSetAdvertisingData(CommandView command); 406 void LeSetScanResponseData(CommandView command); 407 void LeSetAdvertisingEnable(CommandView command); 408 409 // 7.8.10 - 7.8.11 410 void LeSetScanParameters(CommandView command); 411 void LeSetScanEnable(CommandView command); 412 413 // 7.8.12 - 7.8.13 414 void LeCreateConnection(CommandView command); 415 void LeCreateConnectionCancel(CommandView command); 416 417 // 7.8.14 - 7.8.17 418 void LeReadFilterAcceptListSize(CommandView command); 419 void LeClearFilterAcceptList(CommandView command); 420 void LeAddDeviceToFilterAcceptList(CommandView command); 421 void LeRemoveDeviceFromFilterAcceptList(CommandView command); 422 423 // 7.8.18 424 void LeConnectionUpdate(CommandView command); 425 426 // 7.8.21 427 void LeReadRemoteFeaturesPage0(CommandView command); 428 429 // 7.8.22 430 void LeEncrypt(CommandView command); 431 432 // 7.8.23 433 void LeRand(CommandView command); 434 435 // 7.8.24 436 void LeStartEncryption(CommandView command); 437 438 // 7.8.25 - 7.8.26 439 void LeLongTermKeyRequestReply(CommandView command); 440 void LeLongTermKeyRequestNegativeReply(CommandView command); 441 442 // 7.8.27 443 void LeReadSupportedStates(CommandView command); 444 445 // 7.8.31 - 7.8.32 446 void LeRemoteConnectionParameterRequestReply(CommandView command); 447 void LeRemoteConnectionParameterRequestNegativeReply(CommandView command); 448 449 // 7.8.34 - 7.8.35 450 void LeReadSuggestedDefaultDataLength(CommandView command); 451 void LeWriteSuggestedDefaultDataLength(CommandView command); 452 453 // 7.8.36 454 void LeReadLocalP256PublicKey(CommandView command); 455 456 // 7.8.38 - 7.8.41 457 void LeAddDeviceToResolvingList(CommandView command); 458 void LeRemoveDeviceFromResolvingList(CommandView command); 459 void LeClearResolvingList(CommandView command); 460 void LeReadResolvingListSize(CommandView command); 461 462 // 7.8.42 - 7.8.43 463 void LeReadPeerResolvableAddress(CommandView command); 464 void LeReadLocalResolvableAddress(CommandView command); 465 466 // 7.8.44 - 7.8.45 467 void LeSetAddressResolutionEnable(CommandView command); 468 void LeSetResolvablePrivateAddressTimeout(CommandView command); 469 470 // 7.8.46 471 void LeReadMaximumDataLength(CommandView command); 472 473 // 7.8.47 - 7.8.49 474 void LeReadPhy(CommandView command); 475 void LeSetDefaultPhy(CommandView command); 476 void LeSetPhy(CommandView command); 477 478 // 7.8.52 - 7.8.60 479 void LeSetAdvertisingSetRandomAddress(CommandView command); 480 void LeSetExtendedAdvertisingParametersV1(CommandView command); 481 void LeSetExtendedAdvertisingData(CommandView command); 482 void LeSetExtendedScanResponseData(CommandView command); 483 void LeSetExtendedAdvertisingEnable(CommandView command); 484 void LeReadMaximumAdvertisingDataLength(CommandView command); 485 void LeReadNumberOfSupportedAdvertisingSets(CommandView command); 486 void LeRemoveAdvertisingSet(CommandView command); 487 void LeClearAdvertisingSets(CommandView command); 488 489 // 7.8.61 - 7.8.63 490 void LeSetPeriodicAdvertisingParametersV1(CommandView command); 491 void LeSetPeriodicAdvertisingData(CommandView command); 492 void LeSetPeriodicAdvertisingEnable(CommandView command); 493 494 // 7.8.67 - 7.8.69 495 void LePeriodicAdvertisingCreateSync(CommandView command); 496 void LePeriodicAdvertisingCreateSyncCancel(CommandView command); 497 void LePeriodicAdvertisingTerminateSync(CommandView command); 498 499 // 7.8.70 - 7.8.73 500 void LeAddDeviceToPeriodicAdvertiserList(CommandView command); 501 void LeRemoveDeviceFromPeriodicAdvertiserList(CommandView command); 502 void LeClearPeriodicAdvertiserList(CommandView command); 503 void LeReadPeriodicAdvertiserListSize(CommandView command); 504 505 // 7.8.64 - 7.8.65 506 void LeSetExtendedScanParameters(CommandView command); 507 void LeSetExtendedScanEnable(CommandView command); 508 509 // 7.8.66 510 void LeExtendedCreateConnectionV1(CommandView command); 511 512 // 7.8.77 513 void LeSetPrivacyMode(CommandView command); 514 515 // 7.8.108 516 void LeRequestPeerSca(CommandView command); 517 518 // 7.8.115 519 void LeSetHostFeatureV1(CommandView command); 520 521 // Vendor-specific Commands 522 void LeGetVendorCapabilities(CommandView command); 523 void LeBatchScan(CommandView command); 524 void LeApcf(CommandView command); 525 void LeGetControllerActivityEnergyInfo(CommandView command); 526 void LeExSetScanParameters(CommandView command); 527 void GetControllerDebugInfo(CommandView command); 528 529 // CSR vendor command. 530 // Implement the command specific to the CSR controller 531 // used specifically by the PTS tool to pass certification tests. 532 void CsrVendorCommand(CommandView command); 533 void CsrReadVarid(CsrVarid varid, std::vector<uint8_t>& value) const; 534 void CsrWriteVarid(CsrVarid varid, std::vector<uint8_t> const& value) const; 535 void CsrReadPskey(CsrPskey pskey, std::vector<uint8_t>& value) const; 536 void CsrWritePskey(CsrPskey pskey, std::vector<uint8_t> const& value); 537 538 // Command pass-through. 539 void ForwardToLm(CommandView command); 540 void ForwardToLl(CommandView command); 541 542 protected: 543 // Controller configuration. 544 ControllerProperties properties_; 545 546 // Link Layer state. 547 LinkLayerController link_layer_controller_{address_, properties_, id_}; 548 549 private: 550 // Send a HCI_Command_Complete event for the specified op_code with 551 // the error code UNKNOWN_OPCODE. 552 void SendCommandCompleteUnknownOpCodeEvent(bluetooth::hci::OpCode op_code) const; 553 554 // Validate that a received packet is correctly formatted. 555 // If the packet failed to be parsed, the function sends a 556 // HCI Hardware Error event to the host and logs the packet to 557 // the configured handler. 558 template <typename T> CheckPacketView(T const & view,std::string reason)559 bool CheckPacketView(T const& view, std::string reason) { 560 if (view.IsValid()) { 561 return true; 562 } 563 564 // Send a hardware error to reset the host, and report the packet 565 // for tracing. 566 send_event_(bluetooth::hci::HardwareErrorBuilder::Create(0x43)); 567 invalid_packet_handler_(id_, InvalidPacketReason::kParseError, reason, view.bytes().bytes()); 568 return false; 569 } 570 571 // Callbacks to send packets back to the HCI. 572 std::function<void(std::shared_ptr<bluetooth::hci::AclBuilder>)> send_acl_; 573 std::function<void(std::shared_ptr<bluetooth::hci::EventBuilder>)> send_event_; 574 std::function<void(std::shared_ptr<bluetooth::hci::ScoBuilder>)> send_sco_; 575 std::function<void(std::shared_ptr<bluetooth::hci::IsoBuilder>)> send_iso_; 576 577 // Report invalid packets received on this controller instance. 578 std::function<void(uint32_t, InvalidPacketReason, std::string, std::vector<uint8_t> const&)> 579 invalid_packet_handler_; 580 581 // Loopback mode (Vol 4, Part E § 7.6.1). 582 // The local loopback mode is used to pass the android Vendor Test Suite 583 // with RootCanal. 584 bluetooth::hci::LoopbackMode loopback_mode_{LoopbackMode::NO_LOOPBACK}; 585 586 // Random value generator, always seeded with 0 to be deterministic. 587 std::mt19937_64 random_generator_{}; 588 589 // Flag set to true after the HCI Reset command has been received 590 // the first time. 591 bool controller_reset_{false}; 592 593 // Map command opcodes to the corresponding bit index in the 594 // supported command mask. 595 static const std::unordered_map<OpCode, OpCodeIndex> hci_command_op_code_to_index_; 596 597 // Map all implemented opcodes to the function implementing the handler 598 // for the associated command. The map should be a subset of the 599 // supported_command field in the properties_ object. Commands 600 // that are supported but not implemented will raise a fatal assert. 601 using CommandHandler = std::function<void(DualModeController*, bluetooth::hci::CommandView)>; 602 static const std::unordered_map<OpCode, CommandHandler> hci_command_handlers_; 603 }; 604 605 } // namespace rootcanal 606