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 <array>
20 #include <cstdint>
21 #include <vector>
22 
23 #include "packets/hci_packets.h"
24 #include "rootcanal/configuration.pb.h"
25 
26 namespace rootcanal {
27 using bluetooth::hci::HciVersion;
28 using bluetooth::hci::LmpVersion;
29 
30 // Local controller quirks.
31 struct ControllerQuirks {
32   // The specification states that the Random Address is invalid until
33   // explicitly set by the command LE Set Random Address. Certain HCI commands
34   // check for this condition.
35   //
36   // This quirk configures a default value for the LE random address in order
37   // to bypass this validation. The default random address will
38   // be ba:db:ad:ba:db:ad.
39   bool has_default_random_address{false};
40 
41   // This quirks configures the controller to send an Hardware Error event
42   // in case a command is received before the HCI Reset command.
43   //
44   // Receiving a different command is indicative of the emulator being
45   // started from a snapshot. In this case the controller state is lost
46   // but the Host stack is loaded post-initialization. This quirk
47   // ensures that the stack will reset itself after reloading.
48   bool hardware_error_before_reset{false};
49 };
50 
51 // Local controller information.
52 //
53 // Provide the Informational Parameters returned by HCI commands
54 // in the range of the same name (cf. [4] E.7.4).
55 // The informational parameters are fixed by the manufacturer of the Bluetooth
56 // hardware. These parameters provide information about the BR/EDR Controller
57 // and the capabilities of the Link Manager and Baseband in the BR/EDR
58 // Controller. The Host device cannot modify any of these parameters.
59 struct ControllerProperties {
60 public:
61   ControllerProperties();
62   ControllerProperties(rootcanal::configuration::Controller const&);
63   ControllerProperties(ControllerProperties const&) = default;
64   ControllerProperties(ControllerProperties&&) = default;
65   ~ControllerProperties() = default;
66 
67   ControllerProperties& operator=(ControllerProperties const&) = default;
68 
69   // Perform a bitwise and operation on the supported commands mask;
70   // the default bit setting is either loaded from the configuration
71   // file or all 1s.
72   void SetSupportedCommands(std::array<uint8_t, 64> supported_commands);
73 
74   // Check if the feature masks are valid according to the specification.
75   bool CheckSupportedFeatures() const;
76 
77   // Check if the supported command mask is valid according to the
78   // specification. If fixup is true, then the mask is updated instead of
79   // returning an error.
80   bool CheckSupportedCommands() const;
81 
82   // Enabled quirks.
83   ControllerQuirks quirks{};
84 
85   // Strict mode.
86   bool strict{true};
87 
88   // Local Version Information (Vol 4, Part E § 7.4.1).
89   HciVersion hci_version{HciVersion::V_5_3};
90   LmpVersion lmp_version{LmpVersion::V_5_3};
91   uint16_t hci_subversion{0};
92   uint16_t lmp_subversion{0};
93   uint16_t company_identifier{0x00E0};  // Google
94 
95   // Transports.
96   bool br_supported{true};
97   bool le_supported{true};
98 
99   // Local Supported Commands (Vol 4, Part E § 7.4.2).
100   std::array<uint8_t, 64> supported_commands{};
101 
102   // Vendor Supported Commands.
103   bool supports_le_get_vendor_capabilities_command{true};
104   bool supports_csr_vendor_command{true};
105   bool supports_le_apcf_vendor_command{true};
106 
107   // Local Supported Features (Vol 4, Part E § 7.4.3) and
108   // Local Extended Features (Vol 4, Part E § 7.4.3).
109   std::array<uint64_t, 3> lmp_features{};
110 
111   // LE Local Supported Features (Vol 4, Part E § 7.8.3).
112   uint64_t le_features{0};
113 
114   // Buffer Size (Vol 4, Part E § 7.4.5).
115   // Note: The blueZ HCI user socket limits the ACL Data Packet length to 1023
116   // bytes (see HCI_MAX_FRAME_SIZE).
117   uint16_t acl_data_packet_length{1023};
118   uint8_t sco_data_packet_length{255};
119   uint16_t total_num_acl_data_packets{10};
120   uint16_t total_num_sco_data_packets{10};
121 
122   // LE Buffer Size (Vol 4, Part E § 7.8.2).
123   uint16_t le_acl_data_packet_length{27};
124   uint16_t iso_data_packet_length{1021};
125   uint8_t total_num_le_acl_data_packets{20};
126   uint8_t total_num_iso_data_packets{12};
127 
128   // Number of Supported IAC (Vol 4, Part E § 7.3.43).
129   uint8_t num_supported_iac{4};
130 
131   // LE Advertising Physical Channel TX Power (Vol 4, Part E § 7.8.6).
132   uint8_t le_advertising_physical_channel_tx_power{static_cast<uint8_t>(-10)};
133 
134   // Supported Codecs (Vol 4, Part E § 7.4.8).
135   // Implements the [v1] version only.
136   std::vector<uint8_t> supported_standard_codecs{0};
137   std::vector<uint32_t> supported_vendor_specific_codecs{};
138 
139   // LE Filter Accept List Size (Vol 4, Part E § 7.8.14).
140   uint8_t le_filter_accept_list_size{16};
141 
142   // LE Resolving List Size (Vol 4, Part E § 7.8.41).
143   uint8_t le_resolving_list_size{16};
144 
145   // LE Supported States (Vol 4, Part E § 7.8.27).
146   uint64_t le_supported_states{0x3ffffffffff};
147 
148   // LE Maximum Advertising Data Length (Vol 4, Part E § 7.8.57).
149   // Note: valid range 0x001F to 0x0672.
150   uint16_t le_max_advertising_data_length{512};
151 
152   // LE Number of Supported Advertising Sets (Vol 4, Part E § 7.8.58)
153   // Note: the controller can change the number of advertising sets
154   // at any time. This behaviour is not emulated here.
155   uint8_t le_num_supported_advertising_sets{16};
156 
157   // LE Periodic Advertiser List Size (Vol 4, Part E § 7.8.73).
158   uint8_t le_periodic_advertiser_list_size{8};
159 
160   // Android Vendor Capabilities.
161   // https://source.android.com/docs/core/connect/bluetooth/hci_requirements#vendor-specific-capabilities
162   uint8_t le_apcf_filter_list_size{16};
163   uint8_t le_apcf_num_of_tracked_advertisers{16};
164   uint8_t le_apcf_broadcaster_address_filter_list_size{16};
165   uint8_t le_apcf_service_uuid_filter_list_size{16};
166   uint8_t le_apcf_service_solicitation_uuid_filter_list_size{16};
167   uint8_t le_apcf_local_name_filter_list_size{16};
168   uint8_t le_apcf_manufacturer_data_filter_list_size{16};
169   uint8_t le_apcf_service_data_filter_list_size{16};
170   uint8_t le_apcf_ad_type_filter_list_size{16};
171 
SupportsLMPFeatureControllerProperties172   bool SupportsLMPFeature(bluetooth::hci::LMPFeaturesPage0Bits bit) const {
173     return (lmp_features[0] & static_cast<uint64_t>(bit)) != 0;
174   }
175 
SupportsLMPFeatureControllerProperties176   bool SupportsLMPFeature(bluetooth::hci::LMPFeaturesPage2Bits bit) const {
177     return (lmp_features[2] & static_cast<uint64_t>(bit)) != 0;
178   }
179 
SupportsLLFeatureControllerProperties180   bool SupportsLLFeature(bluetooth::hci::LLFeaturesBits bit) const {
181     return (le_features & static_cast<uint64_t>(bit)) != 0;
182   }
183 
SupportsCommandControllerProperties184   bool SupportsCommand(bluetooth::hci::OpCodeIndex op_code) const {
185     int index = static_cast<int>(op_code);
186     return (supported_commands[index / 10] & (UINT64_C(1) << (index % 10))) != 0;
187   }
188 
189   /// Return a bit mask with all supported PHYs
190   /// (0b001 = LE_1M, 0b010 = LE_2M, 0b100 = LE_CODED).
LeSupportedPhysControllerProperties191   uint8_t LeSupportedPhys() const {
192     uint8_t supported_phys = 0x1;  // LE_1M is always supported.
193     if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_2M_PHY)) {
194       supported_phys |= 0x2;
195     }
196     if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_CODED_PHY)) {
197       supported_phys |= 0x4;
198     }
199     return supported_phys;
200   }
201 };
202 
203 }  // namespace rootcanal
204