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