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
36using std::lock_guard;
37using std::mutex;
38
39namespace bluetooth {
40
41// static
42const char Adapter::kDefaultAddress[] = "00:00:00:00:00:00";
43// static
44const 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.
53const int kMinAdvInstancesForMultiAdv = 5;
54
55// Used when determining if offloaded scan filtering is supported.
56const int kMinOffloadedFilters = 10;
57
58// Used when determining if offloaded scan batching is supported.
59const int kMinOffloadedScanStorageBytes = 1024;
60
61void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
62                                              AdapterState prev_state,
63                                              AdapterState new_state) {
64  // Default implementation does nothing
65}
66
67void 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.
73class AdapterImpl : public Adapter, public hal::BluetoothInterface::Observer {
74 public:
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
89  ~AdapterImpl() override {
90    hal::BluetoothInterface::Get()->RemoveObserver(this);
91  }
92
93  void AddObserver(Adapter::Observer* observer) override {
94    lock_guard<mutex> lock(observers_lock_);
95    observers_.AddObserver(observer);
96  }
97
98  void RemoveObserver(Adapter::Observer* observer) override {
99    lock_guard<mutex> lock(observers_lock_);
100    observers_.RemoveObserver(observer);
101  }
102
103  AdapterState GetState() const override { return state_.load(); }
104
105  bool IsEnabled() const override { return state_.load() == ADAPTER_STATE_ON; }
106
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
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
158  std::string GetName() const override { return name_.Get(); }
159
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
184  std::string GetAddress() const override { return address_.Get(); }
185
186  bool IsMultiAdvertisementSupported() override {
187    lock_guard<mutex> lock(local_le_features_lock_);
188    return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
189  }
190
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
196  int GetTotalNumberOfTrackableAdvertisements() override {
197    lock_guard<mutex> lock(local_le_features_lock_);
198    return local_le_features_.total_trackable_advertisers;
199  }
200
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
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
212  LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
213    return ble_client_factory_.get();
214  }
215
216  LowEnergyAdvertiserFactory* GetLeAdvertiserFactory() const override {
217    return ble_advertiser_factory_.get();
218  }
219
220  LowEnergyScannerFactory* GetLeScannerFactory() const override {
221    return ble_scanner_factory_.get();
222  }
223
224  GattClientFactory* GetGattClientFactory() const override {
225    return gatt_client_factory_.get();
226  }
227
228  GattServerFactory* GetGattServerFactory() const override {
229    return gatt_server_factory_.get();
230  }
231
232  // hal::BluetoothInterface::Observer overrides.
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
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<RawAddress*>(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
303  void SSPRequestCallback(RawAddress*, bt_bdname_t*, uint32_t, bt_ssp_variant_t,
304                          uint32_t pass_key) override {
305    LOG(INFO) << "Passkey is: " << pass_key;
306  }
307
308  void AclStateChangedCallback(bt_status_t status,
309                               const RawAddress& 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.
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.
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
413std::unique_ptr<Adapter> Adapter::Create() {
414  return std::unique_ptr<Adapter>(new AdapterImpl());
415}
416
417}  // namespace bluetooth
418