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