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