1 /*
2  * Copyright 2019 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 #pragma once
17 
18 #include <bluetooth/log.h>
19 
20 #include <memory>
21 #include <vector>
22 
23 #include "common/callback.h"
24 #include "hci/hci_packets.h"
25 #include "module.h"
26 
27 namespace bluetooth {
28 namespace hci {
29 
30 class PeriodicAdvertisingParameters {
31 public:
32   bool enable;
33   bool include_adi;
34   uint16_t min_interval;
35   uint16_t max_interval;
36   uint16_t properties;
37   enum AdvertisingProperty { INCLUDE_TX_POWER = 0x06 };
38 };
39 
40 enum class AdvertiserAddressType {
41   PUBLIC,
42   RESOLVABLE_RANDOM,
43   NONRESOLVABLE_RANDOM,
44 };
45 
46 class AdvertisingConfig {
47 public:
48   std::vector<GapData> advertisement;
49   std::vector<GapData> scan_response;
50   uint16_t interval_min;
51   uint16_t interval_max;
52   AdvertisingType advertising_type;
53   AdvertiserAddressType requested_advertiser_address_type;
54   PeerAddressType peer_address_type;
55   Address peer_address;
56   uint8_t channel_map;
57   AdvertisingFilterPolicy filter_policy;
58   uint8_t tx_power;  // -127 to +20 (0x7f is no preference)
59   bool connectable = false;
60   bool discoverable = false;
61   bool scannable = false;
62   bool directed = false;
63   bool high_duty_cycle = false;
64   bool legacy_pdus = false;
65   bool anonymous = false;
66   bool include_tx_power = false;
67   bool use_le_coded_phy;       // Primary advertisement PHY is LE Coded
68   uint8_t secondary_max_skip;  // maximum advertising events to be skipped, 0x0 send AUX_ADV_IND
69                                // prior ot the next event
70   SecondaryPhyType secondary_advertising_phy;
71   uint8_t sid = 0x00;
72   Enable enable_scan_request_notifications = Enable::DISABLED;
73   std::vector<GapData> periodic_data;
74   PeriodicAdvertisingParameters periodic_advertising_parameters;
75   AdvertisingConfig() = default;
76 };
77 
78 using AdvertiserId = uint8_t;
79 
80 class AdvertisingCallback {
81 public:
82   enum AdvertisingStatus {
83     SUCCESS,
84     DATA_TOO_LARGE,
85     TOO_MANY_ADVERTISERS,
86     ALREADY_STARTED,
87     INTERNAL_ERROR,
88     FEATURE_UNSUPPORTED,
89     TIMEOUT
90   };
91 
92   virtual ~AdvertisingCallback() = default;
93   virtual void OnAdvertisingSetStarted(int reg_id, uint8_t advertiser_id, int8_t tx_power,
94                                        AdvertisingStatus status) = 0;
95   virtual void OnAdvertisingEnabled(uint8_t advertiser_id, bool enable,
96                                     AdvertisingStatus status) = 0;
97   virtual void OnAdvertisingDataSet(uint8_t advertiser_id, AdvertisingStatus status) = 0;
98   virtual void OnScanResponseDataSet(uint8_t advertiser_id, AdvertisingStatus status) = 0;
99   virtual void OnAdvertisingParametersUpdated(uint8_t advertiser_id, int8_t tx_power,
100                                               AdvertisingStatus status) = 0;
101   virtual void OnPeriodicAdvertisingParametersUpdated(uint8_t advertiser_id,
102                                                       AdvertisingStatus status) = 0;
103   virtual void OnPeriodicAdvertisingDataSet(uint8_t advertiser_id, AdvertisingStatus status) = 0;
104   virtual void OnPeriodicAdvertisingEnabled(uint8_t advertiser_id, bool enable,
105                                             AdvertisingStatus status) = 0;
106   virtual void OnOwnAddressRead(uint8_t advertiser_id, uint8_t address_type, Address address) = 0;
107 };
108 
109 class LeAdvertisingManager : public bluetooth::Module {
110 public:
111   static constexpr AdvertiserId kInvalidId = 0xFF;
112   static constexpr uint8_t kInvalidHandle = 0xFF;
113   static constexpr uint8_t kAdvertisingSetIdMask = 0x0F;
114   static constexpr uint16_t kLeMaximumLegacyAdvertisingDataLength = 31;
115   static constexpr uint16_t kLeMaximumFragmentLength = 251;
116   static constexpr uint16_t kLeMaximumPeriodicDataFragmentLength = 252;
117   static constexpr uint16_t kLeMaximumGapDataLength = 255;
118   static constexpr FragmentPreference kFragment_preference =
119           FragmentPreference::CONTROLLER_SHOULD_NOT;
120   LeAdvertisingManager();
121   LeAdvertisingManager(const LeAdvertisingManager&) = delete;
122   LeAdvertisingManager& operator=(const LeAdvertisingManager&) = delete;
123 
124   size_t GetNumberOfAdvertisingInstances() const;
125 
126   size_t GetNumberOfAdvertisingInstancesInUse() const;
127 
128   int GetAdvertiserRegId(AdvertiserId advertiser_id);
129 
130   void ExtendedCreateAdvertiser(
131           uint8_t client_id, int reg_id, const AdvertisingConfig config,
132           common::Callback<void(Address, AddressType)> scan_callback,
133           common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
134           uint16_t duration, uint8_t max_extended_advertising_events, os::Handler* handler);
135 
136   void StartAdvertising(AdvertiserId advertiser_id, const AdvertisingConfig config,
137                         uint16_t duration,
138                         base::OnceCallback<void(uint8_t /* status */)> status_callback,
139                         base::OnceCallback<void(uint8_t /* status */)> timeout_callback,
140                         common::Callback<void(Address, AddressType)> scan_callback,
141                         common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback,
142                         os::Handler* handler);
143 
144   void GetOwnAddress(uint8_t advertiser_id);
145 
146   void RegisterAdvertiser(
147           common::ContextualOnceCallback<void(uint8_t /* inst_id */,
148                                               AdvertisingCallback::AdvertisingStatus /* status */)>
149                   callback);
150 
151   void SetParameters(AdvertiserId advertiser_id, AdvertisingConfig config);
152 
153   void SetData(AdvertiserId advertiser_id, bool set_scan_rsp, std::vector<GapData> data);
154 
155   void EnableAdvertiser(AdvertiserId advertiser_id, bool enable, uint16_t duration,
156                         uint8_t max_extended_advertising_events);
157 
158   void SetPeriodicParameters(AdvertiserId advertiser_id,
159                              PeriodicAdvertisingParameters periodic_advertising_parameters);
160 
161   void SetPeriodicData(AdvertiserId advertiser_id, std::vector<GapData> data);
162 
163   void EnablePeriodicAdvertising(AdvertiserId advertiser_id, bool enable, bool include_adi);
164 
165   void RemoveAdvertiser(AdvertiserId advertiser_id);
166 
167   void RegisterAdvertisingCallback(AdvertisingCallback* advertising_callback);
168 
169   static const ModuleFactory Factory;
170 
171 protected:
172   void ListDependencies(ModuleList* list) const override;
173 
174   void Start() override;
175 
176   void Stop() override;
177 
178   std::string ToString() const override;
179 
180 private:
181   struct impl;
182   std::unique_ptr<impl> pimpl_;
183 };
184 
185 }  // namespace hci
186 }  // namespace bluetooth
187 
188 namespace std {
189 template <>
190 struct formatter<bluetooth::hci::AdvertiserAddressType>
191     : enum_formatter<bluetooth::hci::AdvertiserAddressType> {};
192 }  // namespace std
193