Home | History | Annotate | Download | only in service
      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 
     59 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
     60                                               AdapterState prev_state,
     61                                               AdapterState new_state) {
     62   // Default implementation does nothing
     63 }
     64 
     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:
     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 
     86   ~AdapterImpl() override {
     87     hal::BluetoothInterface::Get()->RemoveObserver(this);
     88   }
     89 
     90   void AddObserver(Adapter::Observer* observer) override {
     91     lock_guard<mutex> lock(observers_lock_);
     92     observers_.AddObserver(observer);
     93   }
     94 
     95   void RemoveObserver(Adapter::Observer* observer) override {
     96     lock_guard<mutex> lock(observers_lock_);
     97     observers_.RemoveObserver(observer);
     98   }
     99 
    100   AdapterState GetState() const override {
    101     return state_.load();
    102   }
    103 
    104   bool IsEnabled() const override {
    105     return state_.load() == ADAPTER_STATE_ON;
    106   }
    107 
    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 
    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 {
    159     return name_.Get();
    160   }
    161 
    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 
    186   std::string GetAddress() const override {
    187     return address_.Get();
    188   }
    189 
    190   bool IsMultiAdvertisementSupported() override {
    191     lock_guard<mutex> lock(local_le_features_lock_);
    192     return local_le_features_.max_adv_instance >= kMinAdvInstancesForMultiAdv;
    193   }
    194 
    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 
    200   int GetTotalNumberOfTrackableAdvertisements() override {
    201     lock_guard<mutex> lock(local_le_features_lock_);
    202     return local_le_features_.total_trackable_advertisers;
    203   }
    204 
    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 
    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 
    216   LowEnergyClientFactory* GetLowEnergyClientFactory() const override {
    217     return ble_client_factory_.get();
    218   }
    219 
    220   GattClientFactory* GetGattClientFactory() const override {
    221     return gatt_client_factory_.get();
    222   }
    223 
    224   GattServerFactory* GetGattServerFactory() const override {
    225     return gatt_server_factory_.get();
    226   }
    227 
    228   // hal::BluetoothInterface::Observer overrides.
    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 
    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 
    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.
    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.
    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
    399 std::unique_ptr<Adapter> Adapter::Create() {
    400   return std::unique_ptr<Adapter>(new AdapterImpl());
    401 }
    402 
    403 }  // namespace bluetooth
    404