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