• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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