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