1 //
2 // Copyright (C) 2015 Google, Inc.
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 #include "service/adapter.h"
18
19 #include <atomic>
20 #include <mutex>
21 #include <string>
22 #include <unordered_set>
23
24 #include <base/logging.h>
25 #include <base/observer_list.h>
26
27 #include "service/common/bluetooth/util/atomic_string.h"
28 #include "service/gatt_client.h"
29 #include "service/gatt_server.h"
30 #include "service/hal/bluetooth_interface.h"
31 #include "service/logging_helpers.h"
32 #include "service/low_energy_advertiser.h"
33 #include "service/low_energy_client.h"
34 #include "service/low_energy_scanner.h"
35
36 using std::lock_guard;
37 using std::mutex;
38
39 namespace bluetooth {
40
41 // static
42 const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
43 // static
44 const char Adapter::kDefaultName[] = "not-initialized";
45
46 // TODO(armansito): The following constants come straight from
47 // packages/apps/Bluetooth/src/c/a/b/btservice/AdapterService.java. It would be
48 // nice to know if there were a way to obtain these values from the stack
49 // instead of hardcoding them here.
50
51 // The minimum number of advertising instances required for multi-advertisement
52 // support.
53 const int kMinAdvInstancesForMultiAdv = 5;
54
55 // Used when determining if offloaded scan filtering is supported.
56 const int kMinOffloadedFilters = 10;
57
58 // Used when determining if offloaded scan batching is supported.
59 const int kMinOffloadedScanStorageBytes = 1024;
60
OnAdapterStateChanged(Adapter * adapter,AdapterState prev_state,AdapterState new_state)61 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
62 AdapterState prev_state,
63 AdapterState new_state) {
64 // Default implementation does nothing
65 }
66
OnDeviceConnectionStateChanged(Adapter * adapter,const std::string & device_address,bool connected)67 void Adapter::Observer::OnDeviceConnectionStateChanged(
68 Adapter* adapter, const std::string& device_address, bool connected) {
69 // Default implementation does nothing
70 }
71
72 // The real Adapter implementation used in production.
73 class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
74 public:
AdapterImpl()75 AdapterImpl()
76 : state_(ADAPTER_STATE_OFF),
77 address_(kDefaultAddress),
78 name_(kDefaultName) {
79 memset(&local_le_features_, 0, sizeof(local_le_features_));
80 hal::BluetoothInterface::Get()->AddObserver(this);
81 ble_client_factory_.reset(new LowEnergyClientFactory(*this));
82 ble_advertiser_factory_.reset(new LowEnergyAdvertiserFactory());
83 ble_scanner_factory_.reset(new LowEnergyScannerFactory(*this));
84 gatt_client_factory_.reset(new GattClientFactory());
85 gatt_server_factory_.reset(new GattServerFactory());
86 hal::BluetoothInterface::Get()->GetHALInterface()->get_adapter_properties();
87 }
88
~AdapterImpl()89 ~AdapterImpl() override {
90 hal::BluetoothInterface::Get()->RemoveObserver(this);
91 }
92
AddObserver(Adapter::Observer * observer)93 void AddObserver(Adapter::Observer* observer) override {
94 lock_guard<mutex> lock(observers_lock_);
95 observers_.AddObserver(observer);
96 }
97
RemoveObserver(Adapter::Observer * observer)98 void RemoveObserver(Adapter::Observer* observer) override {
99 lock_guard<mutex> lock(observers_lock_);
100 observers_.RemoveObserver(observer);
101 }
102
GetState() const103 AdapterState GetState() const override { return state_.load(); }
104
IsEnabled() const105 bool IsEnabled() const override { return state_.load() == ADAPTER_STATE_ON; }
106
Enable(bool start_restricted)107 bool Enable(bool start_restricted) override {
108 AdapterState current_state = GetState();
109 if (current_state != ADAPTER_STATE_OFF) {
110 LOG(INFO) << "Adapter not disabled - state: "
111 << AdapterStateToString(current_state);
112 return false;
113 }
114
115 // Set the state before calling enable() as there might be a race between
116 // here and the AdapterStateChangedCallback.
117 state_ = ADAPTER_STATE_TURNING_ON;
118 NotifyAdapterStateChanged(current_state, state_);
119
120 int status = hal::BluetoothInterface::Get()->GetHALInterface()->enable(
121 start_restricted);
122 if (status != BT_STATUS_SUCCESS) {
123 LOG(ERROR) << "Failed to enable Bluetooth - status: "
124 << BtStatusText((const bt_status_t)status);
125 state_ = ADAPTER_STATE_OFF;
126 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_ON, state_);
127 return false;
128 }
129
130 return true;
131 }
132
Disable()133 bool Disable() override {
134 if (!IsEnabled()) {
135 LOG(INFO) << "Adapter is not enabled";
136 return false;
137 }
138
139 AdapterState current_state = GetState();
140
141 // Set the state before calling enable() as there might be a race between
142 // here and the AdapterStateChangedCallback.
143 state_ = ADAPTER_STATE_TURNING_OFF;
144 NotifyAdapterStateChanged(current_state, state_);
145
146 int status = hal::BluetoothInterface::Get()->GetHALInterface()->disable();
147 if (status != BT_STATUS_SUCCESS) {
148 LOG(ERROR) << "Failed to disable Bluetooth - status: "
149 << BtStatusText((const bt_status_t)status);
150 state_ = current_state;
151 NotifyAdapterStateChanged(ADAPTER_STATE_TURNING_OFF, state_);
152 return false;
153 }
154
155 return true;
156 }
157
GetName() const158 std::string GetName() const override { return name_.Get(); }
159
SetName(const std::string & name)160 bool SetName(const std::string& name) override {
161 bt_bdname_t hal_name;
162 size_t max_name_len = sizeof(hal_name.name);
163
164 // Include the \0 byte in size measurement.
165 if (name.length() >= max_name_len) {
166 LOG(ERROR) << "Given name \"" << name << "\" is larger than maximum"
167 << " allowed size: " << max_name_len;
168 return false;
169 }
170
171 strncpy(reinterpret_cast<char*>(hal_name.name), name.c_str(),
172 name.length() + 1);
173
174 VLOG(1) << "Setting adapter name: " << name;
175
176 if (!SetAdapterProperty(BT_PROPERTY_BDNAME, &hal_name, sizeof(hal_name))) {
177 LOG(ERROR) << "Failed to set adapter name: " << name;
178 return false;
179 }
180
181 return true;
182 }
183
GetAddress() const184 std::string GetAddress() const override { return address_.Get(); }
185
IsMultiAdvertisementSupported()186 bool IsMultiAdvertisementSupported() override {
187 lock_guard<mutex> lock(local_le_features_lock_);
188 return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
189 }
190
IsDeviceConnected(const std::string & device_address)191 bool IsDeviceConnected(const std::string& device_address) override {
192 lock_guard<mutex> lock(connected_devices_lock_);
193 return connected_devices_.find(device_address) != connected_devices_.end();
194 }
195
GetTotalNumberOfTrackableAdvertisements()196 int GetTotalNumberOfTrackableAdvertisements() override {
197 lock_guard<mutex> lock(local_le_features_lock_);
198 return local_le_features_.total_trackable_advertisers;
199 }
200
IsOffloadedFilteringSupported()201 bool IsOffloadedFilteringSupported() override {
202 lock_guard<mutex> lock(local_le_features_lock_);
203 return local_le_features_.max_adv_filter_supported >= kMinOffloadedFilters;
204 }
205
IsOffloadedScanBatchingSupported()206 bool IsOffloadedScanBatchingSupported() override {
207 lock_guard<mutex> lock(local_le_features_lock_);
208 return local_le_features_.scan_result_storage_size >=
209 kMinOffloadedScanStorageBytes;
210 }
211
GetLowEnergyClientFactory() const212 LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
213 return ble_client_factory_.get();
214 }
215
GetLeAdvertiserFactory() const216 LowEnergyAdvertiserFactory* GetLeAdvertiserFactory() const override {
217 return ble_advertiser_factory_.get();
218 }
219
GetLeScannerFactory() const220 LowEnergyScannerFactory* GetLeScannerFactory() const override {
221 return ble_scanner_factory_.get();
222 }
223
GetGattClientFactory() const224 GattClientFactory* GetGattClientFactory() const override {
225 return gatt_client_factory_.get();
226 }
227
GetGattServerFactory() const228 GattServerFactory* GetGattServerFactory() const override {
229 return gatt_server_factory_.get();
230 }
231
232 // hal::BluetoothInterface::Observer overrides.
AdapterStateChangedCallback(bt_state_t state)233 void AdapterStateChangedCallback(bt_state_t state) override {
234 LOG(INFO) << "Adapter state changed: " << BtStateText(state);
235
236 AdapterState prev_state = GetState();
237
238 switch (state) {
239 case BT_STATE_OFF:
240 state_ = ADAPTER_STATE_OFF;
241 break;
242
243 case BT_STATE_ON:
244 state_ = ADAPTER_STATE_ON;
245 break;
246
247 default:
248 NOTREACHED();
249 }
250
251 NotifyAdapterStateChanged(prev_state, GetState());
252 }
253
AdapterPropertiesCallback(bt_status_t status,int num_properties,bt_property_t * properties)254 void AdapterPropertiesCallback(bt_status_t status, int num_properties,
255 bt_property_t* properties) override {
256 LOG(INFO) << "Adapter properties changed";
257
258 if (status != BT_STATUS_SUCCESS) {
259 LOG(ERROR) << "status: " << BtStatusText(status);
260 return;
261 }
262
263 for (int i = 0; i < num_properties; i++) {
264 bt_property_t* property = properties + i;
265 switch (property->type) {
266 case BT_PROPERTY_BDADDR: {
267 std::string address =
268 BtAddrString(reinterpret_cast<bt_bdaddr_t*>(property->val));
269 LOG(INFO) << "Adapter address changed: " << address;
270 address_.Set(address);
271 break;
272 }
273 case BT_PROPERTY_BDNAME: {
274 bt_bdname_t* hal_name = reinterpret_cast<bt_bdname_t*>(property->val);
275 std::string name = reinterpret_cast<char*>(hal_name->name);
276 LOG(INFO) << "Adapter name changed: " << name;
277 name_.Set(name);
278 break;
279 }
280 case BT_PROPERTY_LOCAL_LE_FEATURES: {
281 lock_guard<mutex> lock(local_le_features_lock_);
282 if (property->len != sizeof(bt_local_le_features_t)) {
283 LOG(WARNING) << "Malformed value received for property: "
284 << "BT_PROPERTY_LOCAL_LE_FEATURES";
285 break;
286 }
287 bt_local_le_features_t* features =
288 reinterpret_cast<bt_local_le_features_t*>(property->val);
289 memcpy(&local_le_features_, features, sizeof(*features));
290 LOG(INFO) << "Supported LE features updated";
291 break;
292 }
293 default:
294 VLOG(1) << "Unhandled adapter property: "
295 << BtPropertyText(property->type);
296 break;
297 }
298
299 // TODO(armansito): notify others of the updated properties
300 }
301 }
302
SSPRequestCallback(bt_bdaddr_t *,bt_bdname_t *,uint32_t,bt_ssp_variant_t,uint32_t pass_key)303 void SSPRequestCallback(bt_bdaddr_t*, bt_bdname_t*, uint32_t,
304 bt_ssp_variant_t, uint32_t pass_key) override {
305 LOG(INFO) << "Passkey is: " << pass_key;
306 }
307
AclStateChangedCallback(bt_status_t status,const bt_bdaddr_t & remote_bdaddr,bt_acl_state_t state)308 void AclStateChangedCallback(bt_status_t status,
309 const bt_bdaddr_t& remote_bdaddr,
310 bt_acl_state_t state) override {
311 std::string device_address = BtAddrString(&remote_bdaddr);
312 bool connected = (state == BT_ACL_STATE_CONNECTED);
313 LOG(INFO) << "ACL state changed: " << device_address
314 << " - connected: " << (connected ? "true" : "false");
315
316 // If this is reported with an error status, I suppose the best thing we can
317 // do is to log it and ignore the event.
318 if (status != BT_STATUS_SUCCESS) {
319 LOG(ERROR) << "status: " << BtStatusText(status);
320 return;
321 }
322
323 // Introduce a scope to manage |connected_devices_lock_| with RAII.
324 {
325 lock_guard<mutex> lock(connected_devices_lock_);
326 if (connected)
327 connected_devices_.insert(device_address);
328 else
329 connected_devices_.erase(device_address);
330 }
331
332 lock_guard<mutex> lock(observers_lock_);
333 FOR_EACH_OBSERVER(
334 Adapter::Observer, observers_,
335 OnDeviceConnectionStateChanged(this, device_address, connected));
336 }
337
338 // Sends a request to set the given HAL adapter property type and value.
SetAdapterProperty(bt_property_type_t type,void * value,int length)339 bool SetAdapterProperty(bt_property_type_t type, void* value, int length) {
340 CHECK(length > 0);
341 CHECK(value);
342
343 bt_property_t property;
344 property.len = length;
345 property.val = value;
346 property.type = type;
347
348 int status =
349 hal::BluetoothInterface::Get()->GetHALInterface()->set_adapter_property(
350 &property);
351 if (status != BT_STATUS_SUCCESS) {
352 VLOG(1) << "Failed to set property";
353 return false;
354 }
355
356 return true;
357 }
358
359 // Helper for invoking the AdapterStateChanged observer method.
NotifyAdapterStateChanged(AdapterState prev_state,AdapterState new_state)360 void NotifyAdapterStateChanged(AdapterState prev_state,
361 AdapterState new_state) {
362 if (prev_state == new_state) return;
363
364 lock_guard<mutex> lock(observers_lock_);
365 FOR_EACH_OBSERVER(Adapter::Observer, observers_,
366 OnAdapterStateChanged(this, prev_state, new_state));
367 }
368
369 private:
370 // The current adapter state.
371 std::atomic<AdapterState> state_;
372
373 // The Bluetooth device address of the local adapter in string from
374 // (i.e.. XX:XX:XX:XX:XX:XX)
375 util::AtomicString address_;
376
377 // The current local adapter name.
378 util::AtomicString name_;
379
380 // The current set of supported LE features as obtained from the stack. The
381 // values here are all initially set to 0 and updated when the corresponding
382 // adapter property has been received from the stack.
383 std::mutex local_le_features_lock_;
384 bt_local_le_features_t local_le_features_;
385
386 // List of observers that are interested in notifications from us.
387 std::mutex observers_lock_;
388 base::ObserverList<Adapter::Observer> observers_;
389
390 // List of devices addresses that are currently connected.
391 std::mutex connected_devices_lock_;
392 std::unordered_set<std::string> connected_devices_;
393
394 // Factory used to create per-app LowEnergyClient instances.
395 std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;
396
397 // Factory used to create per-app LeAdvertiser instances.
398 std::unique_ptr<LowEnergyAdvertiserFactory> ble_advertiser_factory_;
399
400 // Factory used to create per-app LeScanner instances.
401 std::unique_ptr<LowEnergyScannerFactory> ble_scanner_factory_;
402
403 // Factory used to create per-app GattClient instances.
404 std::unique_ptr<GattClientFactory> gatt_client_factory_;
405
406 // Factory used to create per-app GattServer instances.
407 std::unique_ptr<GattServerFactory> gatt_server_factory_;
408
409 DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
410 };
411
412 // static
Create()413 std::unique_ptr<Adapter> Adapter::Create() {
414 return std::unique_ptr<Adapter>(new AdapterImpl());
415 }
416
417 } // namespace bluetooth
418