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