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