1 /*
2  * Copyright 2020 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 <chrono>
20 #include <cstdint>
21 #include <optional>
22 #include <ratio>
23 #include <vector>
24 
25 #include "hci/address.h"
26 #include "hci/address_with_type.h"
27 #include "packets/hci_packets.h"
28 
29 namespace rootcanal {
30 
31 // Duration type for slots (increments of 625us).
32 using slots =
33     std::chrono::duration<unsigned long long, std::ratio<625, 1000000>>;
34 
35 // User defined literal for slots, e.g. `0x800_slots`
36 slots operator"" _slots(unsigned long long count);
37 
38 using namespace bluetooth::hci;
39 
40 // Advertising interface common to legacy and extended advertisers.
41 class Advertiser {
42  public:
43   Advertiser() = default;
44   ~Advertiser() = default;
45 
IsEnabled()46   bool IsEnabled() const { return advertising_enable; }
Disable()47   void Disable() { advertising_enable = false; }
48 
GetAdvertisingAddress()49   AddressWithType GetAdvertisingAddress() const { return advertising_address; }
GetTargetAddress()50   AddressWithType GetTargetAddress() const { return target_address; }
51 
52   // HCI properties.
53   bool advertising_enable{false};
54   AddressWithType advertising_address{Address::kEmpty,
55                                       AddressType::PUBLIC_DEVICE_ADDRESS};
56   AddressWithType target_address{Address::kEmpty,
57                                  AddressType::PUBLIC_DEVICE_ADDRESS};
58 
59   // Time keeping.
60   std::chrono::steady_clock::time_point next_event{};
61   std::optional<std::chrono::steady_clock::time_point> timeout{};
62 };
63 
64 // Implement the unique legacy advertising instance.
65 // For extended advertising check the ExtendedAdvertiser class.
66 class LegacyAdvertiser : public Advertiser {
67  public:
68   LegacyAdvertiser() = default;
69   ~LegacyAdvertiser() = default;
70 
IsScannable()71   bool IsScannable() const {
72     return advertising_type != AdvertisingType::ADV_NONCONN_IND &&
73            advertising_type != AdvertisingType::ADV_DIRECT_IND_HIGH &&
74            advertising_type != AdvertisingType::ADV_DIRECT_IND_LOW;
75   }
76 
IsConnectable()77   bool IsConnectable() const {
78     return advertising_type != AdvertisingType::ADV_NONCONN_IND &&
79            advertising_type != AdvertisingType::ADV_SCAN_IND;
80   }
81 
IsDirected()82   bool IsDirected() const {
83     return advertising_type == AdvertisingType::ADV_DIRECT_IND_HIGH ||
84            advertising_type == AdvertisingType::ADV_DIRECT_IND_LOW;
85   }
86 
87   // Host configuration parameters. Gather the configuration from the
88   // legacy advertising HCI commands. The initial configuration
89   // matches the default values of the parameters of the HCI command
90   // LE Set Advertising Parameters.
91   slots advertising_interval{0x0800};
92   AdvertisingType advertising_type{AdvertisingType::ADV_IND};
93   OwnAddressType own_address_type{OwnAddressType::PUBLIC_DEVICE_ADDRESS};
94   PeerAddressType peer_address_type{
95       PeerAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS};
96   Address peer_address{};
97   uint8_t advertising_channel_map{0x07};
98   AdvertisingFilterPolicy advertising_filter_policy{
99       AdvertisingFilterPolicy::ALL_DEVICES};
100   std::vector<uint8_t> advertising_data{};
101   std::vector<uint8_t> scan_response_data{};
102 };
103 
104 // Implement a single extended advertising set.
105 // The configuration is set by the extended advertising commands;
106 // for the legacy advertiser check the LegacyAdvertiser class.
107 class ExtendedAdvertiser : public Advertiser {
108  public:
109   ExtendedAdvertiser(uint8_t advertising_handle = 0)
advertising_handle(advertising_handle)110       : advertising_handle(advertising_handle) {}
111   ~ExtendedAdvertiser() = default;
112 
Enable()113   void Enable() {
114     advertising_enable = true;
115     periodic_advertising_enable_latch = periodic_advertising_enable;
116     next_event = std::chrono::steady_clock::now();
117   }
118 
EnablePeriodic()119   void EnablePeriodic() {
120     periodic_advertising_enable = true;
121     periodic_advertising_enable_latch = advertising_enable;
122     next_periodic_event = std::chrono::steady_clock::now();
123   }
124 
DisablePeriodic()125   void DisablePeriodic() {
126     periodic_advertising_enable = false;
127     periodic_advertising_enable_latch = false;
128   }
129 
IsPeriodicEnabled()130   bool IsPeriodicEnabled() const { return periodic_advertising_enable_latch; }
IsScannable()131   bool IsScannable() const { return advertising_event_properties.scannable_; }
132 
IsConnectable()133   bool IsConnectable() const {
134     return advertising_event_properties.connectable_;
135   }
136 
IsDirected()137   bool IsDirected() const { return advertising_event_properties.directed_; }
138 
139   // Host configuration parameters. Gather the configuration from the
140   // extended advertising HCI commands.
141   uint8_t advertising_handle;
142   AdvertisingEventProperties advertising_event_properties{};
143   slots primary_advertising_interval{};
144   uint8_t primary_advertising_channel_map{};
145   OwnAddressType own_address_type{};
146   PeerAddressType peer_address_type{};
147   Address peer_address{};
148   std::optional<Address> random_address{};
149   AdvertisingFilterPolicy advertising_filter_policy{};
150   uint8_t advertising_tx_power{};
151   PrimaryPhyType primary_advertising_phy{};
152   uint8_t secondary_max_skip{};
153   SecondaryPhyType secondary_advertising_phy{};
154   uint8_t advertising_sid{};
155   bool scan_request_notification_enable{};
156   std::vector<uint8_t> advertising_data{};
157   std::vector<uint8_t> scan_response_data{};
158   bool partial_advertising_data{false};
159   bool partial_scan_response_data{false};
160 
161   // Periodic advertising configuration.
162   // Note: the enable flag has a latch because of the semantic describe in the
163   // specification:
164   //
165   // If the advertising set is not currently enabled, the periodic advertising
166   // is not started until the advertising set is enabled. Once the advertising
167   // set has been enabled, the Controller shall continue periodic advertising
168   // until the Host issues an HCI_LE_Set_Periodic_Advertising_Enable command
169   // with bit 0 of Enable set to 0 (periodic advertising is disabled).
170   // Disabling the advertising set has no effect on the periodic advertising
171   // once the advertising set has been enabled.
172   //
173   // Thus the enable latch is set when the advertising set is enabled and
174   // periodic advertising is enabled, and cleared when periodic advertising
175   // gets disabled.
176   bool periodic_advertising_enable{false};
177   bool periodic_advertising_enable_latch{false};
178   slots periodic_advertising_interval{};
179   std::vector<uint8_t> periodic_advertising_data{};
180   bool partial_periodic_advertising_data{false};
181 
182   // Time keeping for periodic advertising.
183   std::chrono::steady_clock::time_point next_periodic_event{};
184 
185   // Enabled state.
186   uint8_t max_extended_advertising_events{0};
187   uint8_t num_completed_extended_advertising_events{0};
188 
189   // Not implemented at the moment.
190   bool constant_tone_extensions{false};
191 
192   // Compute the maximum advertising data payload size for the selected
193   // advertising event properties. The advertising data is not present if
194   // 0 is returned.
195   static uint16_t GetMaxAdvertisingDataLength(
196       const AdvertisingEventProperties& properties);
197 
198   // Compute the maximum scan response data payload size for the selected
199   // advertising event properties. The scan response data is not present if
200   // 0 is returned.
201   static uint16_t GetMaxScanResponseDataLength(
202       const AdvertisingEventProperties& properties);
203 
204   // Reconstitute the raw Advertising_Event_Properties bitmask.
205   static uint16_t GetRawAdvertisingEventProperties(
206       const AdvertisingEventProperties& properties);
207 
208   // Compute the maximum periodic advertising data payload size for the
209   // selected periodic advertising interval.
210   static uint16_t GetMaxPeriodicAdvertisingDataLength(
211       slots periodic_advertising_interval);
212 };
213 
214 }  // namespace rootcanal
215