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 <memory> 22 #include <optional> 23 #include <ratio> 24 25 #include "hci/address_with_type.h" 26 #include "hci/hci_packets.h" 27 #include "packets/link_layer_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 IsScannable()113 bool IsScannable() const { return advertising_event_properties.scannable_; } 114 IsConnectable()115 bool IsConnectable() const { 116 return advertising_event_properties.connectable_; 117 } 118 IsDirected()119 bool IsDirected() const { return advertising_event_properties.directed_; } 120 121 // Host configuration parameters. Gather the configuration from the 122 // extended advertising HCI commands. 123 uint8_t advertising_handle; 124 bool periodic_advertising_enable{false}; 125 AdvertisingEventProperties advertising_event_properties{}; 126 slots primary_advertising_interval{}; 127 uint8_t primary_advertising_channel_map{}; 128 OwnAddressType own_address_type{}; 129 PeerAddressType peer_address_type{}; 130 Address peer_address{}; 131 std::optional<Address> random_address{}; 132 AdvertisingFilterPolicy advertising_filter_policy{}; 133 uint8_t advertising_tx_power{}; 134 PrimaryPhyType primary_advertising_phy{}; 135 uint8_t secondary_max_skip{}; 136 SecondaryPhyType secondary_advertising_phy{}; 137 uint8_t advertising_sid{}; 138 bool scan_request_notification_enable{}; 139 std::vector<uint8_t> advertising_data{}; 140 std::vector<uint8_t> scan_response_data{}; 141 bool partial_advertising_data{false}; 142 bool partial_scan_response_data{false}; 143 144 // Enabled state. 145 uint8_t max_extended_advertising_events{0}; 146 uint8_t num_completed_extended_advertising_events{0}; 147 148 // Not implemented at the moment. 149 bool constant_tone_extensions{false}; 150 151 // Compute the maximum advertising data payload size for the selected 152 // advertising event properties. The advertising data is not present if 153 // 0 is returned. 154 static uint16_t GetMaxAdvertisingDataLength( 155 const AdvertisingEventProperties& properties); 156 157 // Compute the maximum scan response data payload size for the selected 158 // advertising event properties. The scan response data is not present if 159 // 0 is returned. 160 static uint16_t GetMaxScanResponseDataLength( 161 const AdvertisingEventProperties& properties); 162 163 // Reconstitute the raw Advertising_Event_Properties bitmask. 164 static uint16_t GetRawAdvertisingEventProperties( 165 const AdvertisingEventProperties& properties); 166 }; 167 168 } // namespace rootcanal 169