Home | History | Annotate | Download | only in service
      1 //
      2 //  Copyright 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 
     61 void Adapter::Observer::OnAdapterStateChanged(Adapter* adapter,
     62                                               AdapterState prev_state,
     63                                               AdapterState new_state) {
     64   // Default implementation does nothing
     65 }
     66 
     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:
     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 (auto& observer : observers_) {
    334       observer.OnDeviceConnectionStateChanged(this, device_address, connected);
    335     }
    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 (auto& observer : observers_) {
    366       observer.OnAdapterStateChanged(this, prev_state, new_state);
    367     }
    368   }
    369 
    370  private:
    371   // The current adapter state.
    372   std::atomic<AdapterState> state_;
    373 
    374   // The Bluetooth device address of the local adapter in string from
    375   // (i.e.. XX:XX:XX:XX:XX:XX)
    376   util::AtomicString address_;
    377 
    378   // The current local adapter name.
    379   util::AtomicString name_;
    380 
    381   // The current set of supported LE features as obtained from the stack. The
    382   // values here are all initially set to 0 and updated when the corresponding
    383   // adapter property has been received from the stack.
    384   std::mutex local_le_features_lock_;
    385   bt_local_le_features_t local_le_features_;
    386 
    387   // List of observers that are interested in notifications from us.
    388   std::mutex observers_lock_;
    389   base::ObserverList<Adapter::Observer> observers_;
    390 
    391   // List of devices addresses that are currently connected.
    392   std::mutex connected_devices_lock_;
    393   std::unordered_set<std::string> connected_devices_;
    394 
    395   // Factory used to create per-app LowEnergyClient instances.
    396   std::unique_ptr<LowEnergyClientFactory> ble_client_factory_;
    397 
    398   // Factory used to create per-app LeAdvertiser instances.
    399   std::unique_ptr<LowEnergyAdvertiserFactory> ble_advertiser_factory_;
    400 
    401   // Factory used to create per-app LeScanner instances.
    402   std::unique_ptr<LowEnergyScannerFactory> ble_scanner_factory_;
    403 
    404   // Factory used to create per-app GattClient instances.
    405   std::unique_ptr<GattClientFactory> gatt_client_factory_;
    406 
    407   // Factory used to create per-app GattServer instances.
    408   std::unique_ptr<GattServerFactory> gatt_server_factory_;
    409 
    410   DISALLOW_COPY_AND_ASSIGN(AdapterImpl);
    411 };
    412 
    413 // static
    414 std::unique_ptr<Adapter> Adapter::Create() {
    415   return std::unique_ptr<Adapter>(new AdapterImpl());
    416 }
    417 
    418 }  // namespace bluetooth
    419