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 #pragma once
     18 
     19 #include <atomic>
     20 #include <functional>
     21 #include <map>
     22 #include <mutex>
     23 
     24 #include <base/macros.h>
     25 
     26 #include "service/bluetooth_instance.h"
     27 #include "service/common/bluetooth/advertise_data.h"
     28 #include "service/common/bluetooth/advertise_settings.h"
     29 #include "service/common/bluetooth/low_energy_constants.h"
     30 #include "service/common/bluetooth/scan_filter.h"
     31 #include "service/common/bluetooth/scan_result.h"
     32 #include "service/common/bluetooth/scan_settings.h"
     33 #include "service/common/bluetooth/uuid.h"
     34 #include "service/hal/bluetooth_gatt_interface.h"
     35 
     36 namespace bluetooth {
     37 
     38 struct ConnComparator {
     39     bool operator()(const bt_bdaddr_t& a, const bt_bdaddr_t& b) const {
     40         return memcmp(&a, &b, sizeof(bt_bdaddr_t)) < 0;
     41     }
     42 };
     43 
     44 class Adapter;
     45 
     46 // A LowEnergyClient represents an application's handle to perform various
     47 // Bluetooth Low Energy GAP operations. Instances cannot be created directly and
     48 // should be obtained through the factory.
     49 class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
     50                         public BluetoothInstance {
     51  public:
     52   // The Delegate interface is used to notify asynchronous events related to BLE
     53   // GAP operations.
     54   class Delegate {
     55    public:
     56     Delegate() = default;
     57     virtual ~Delegate() = default;
     58 
     59     // Called asynchronously to notify the delegate of nearby BLE advertisers
     60     // found during a device scan.
     61     virtual void OnScanResult(LowEnergyClient* client,
     62                               const ScanResult& scan_result) = 0;
     63 
     64     // Called asynchronously to notify the delegate of connection state change
     65     virtual void OnConnectionState(LowEnergyClient* client, int status,
     66                                    const char* address, bool connected) = 0;
     67 
     68     // Called asynchronously to notify the delegate of mtu change
     69     virtual void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
     70                               int mtu) = 0;
     71 
     72    private:
     73     DISALLOW_COPY_AND_ASSIGN(Delegate);
     74   };
     75 
     76   // The destructor automatically unregisters this client instance from the
     77   // stack.
     78   ~LowEnergyClient() override;
     79 
     80   // Assigns a delegate to this instance. |delegate| must out-live this
     81   // LowEnergyClient instance.
     82   void SetDelegate(Delegate* delegate);
     83 
     84   // Callback type used to return the result of asynchronous operations below.
     85   using StatusCallback = std::function<void(BLEStatus)>;
     86 
     87   // Initiates a BLE connection do device with address |address|. If
     88   // |is_direct| is set, use direct connect procedure. Return true on success
     89   //, false otherwise.
     90   bool Connect(std::string address, bool is_direct);
     91 
     92   // Disconnect from previously connected BLE device with address |address|.
     93   // Return true on success, false otherwise.
     94   bool Disconnect(std::string address);
     95 
     96   // Sends request to set MTU to |mtu| for device with address |address|.
     97   // Return true on success, false otherwise.
     98   bool SetMtu(std::string address, int mtu);
     99 
    100   // Initiates a BLE device scan for this client using the given |settings| and
    101   // |filters|. See the documentation for ScanSettings and ScanFilter for how
    102   // these parameters can be configured. Return true on success, false
    103   // otherwise. Please see logs for details in case of error.
    104   bool StartScan(const ScanSettings& settings,
    105                  const std::vector<ScanFilter>& filters);
    106 
    107   // Stops an ongoing BLE device scan for this client.
    108   bool StopScan();
    109 
    110   // Starts advertising based on the given advertising and scan response
    111   // data and the provided |settings|. Reports the result of the operation in
    112   // |callback|. Return true on success, false otherwise. Please see logs for
    113   // details in case of error.
    114   bool StartAdvertising(const AdvertiseSettings& settings,
    115                         const AdvertiseData& advertise_data,
    116                         const AdvertiseData& scan_response,
    117                         const StatusCallback& callback);
    118 
    119   // Stops advertising if it was already started. Reports the result of the
    120   // operation in |callback|.
    121   bool StopAdvertising(const StatusCallback& callback);
    122 
    123   // Returns true if advertising has been started.
    124   bool IsAdvertisingStarted() const;
    125 
    126   // Returns the state of pending advertising operations.
    127   bool IsStartingAdvertising() const;
    128   bool IsStoppingAdvertising() const;
    129 
    130   // Returns the current advertising settings.
    131   const AdvertiseSettings& advertise_settings() const {
    132     return advertise_settings_;
    133   }
    134 
    135   // Returns the current scan settings.
    136   const ScanSettings& scan_settings() const { return scan_settings_; }
    137 
    138   // BluetoothClientInstace overrides:
    139   const UUID& GetAppIdentifier() const override;
    140   int GetInstanceId() const override;
    141 
    142  private:
    143   friend class LowEnergyClientFactory;
    144 
    145   // Constructor shouldn't be called directly as instances are meant to be
    146   // obtained from the factory.
    147   LowEnergyClient(Adapter& adapter, const UUID& uuid, int client_id);
    148 
    149   // BluetoothGattInterface::ClientObserver overrides:
    150   void ScanResultCallback(
    151       hal::BluetoothGattInterface* gatt_iface,
    152       const bt_bdaddr_t& bda, int rssi, uint8_t* adv_data) override;
    153 
    154   void ConnectCallback(
    155       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
    156       int client_id, const bt_bdaddr_t& bda) override;
    157   void DisconnectCallback(
    158       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
    159       int client_id, const bt_bdaddr_t& bda) override;
    160   void MtuChangedCallback(
    161       hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
    162       int mtu) override;
    163   void MultiAdvEnableCallback(
    164       hal::BluetoothGattInterface* gatt_iface,
    165       int client_id, int status) override;
    166   void MultiAdvDataCallback(
    167       hal::BluetoothGattInterface* gatt_iface,
    168       int client_id, int status) override;
    169   void MultiAdvDisableCallback(
    170       hal::BluetoothGattInterface* gatt_iface,
    171       int client_id, int status) override;
    172 
    173   // Helper method called from SetAdvertiseData/SetScanResponse.
    174   bt_status_t SetAdvertiseData(
    175       hal::BluetoothGattInterface* gatt_iface,
    176       const AdvertiseData& data,
    177       bool set_scan_rsp);
    178 
    179   // Handles deferred advertise/scan-response data updates. We set the data if
    180   // there's data to be set, otherwise we either defer it if advertisements
    181   // aren't enabled or do nothing.
    182   void HandleDeferredAdvertiseData(hal::BluetoothGattInterface* gatt_iface);
    183 
    184   // Calls and clears the pending callbacks.
    185   void InvokeAndClearStartCallback(BLEStatus status);
    186   void InvokeAndClearStopCallback(BLEStatus status);
    187 
    188   // Raw pointer to the Bluetooth Adapter.
    189   Adapter& adapter_;
    190 
    191   // See getters above for documentation.
    192   UUID app_identifier_;
    193   int client_id_;
    194 
    195   // Protects advertising-related members below.
    196   std::mutex adv_fields_lock_;
    197 
    198   // The advertising and scan response data fields that will be sent to the
    199   // controller.
    200   AdvertiseData adv_data_;
    201   AdvertiseData scan_response_;
    202   std::atomic_bool adv_data_needs_update_;
    203   std::atomic_bool scan_rsp_needs_update_;
    204 
    205   // Latest advertising settings.
    206   AdvertiseSettings advertise_settings_;
    207 
    208   // Whether or not there is a pending call to update advertising or scan
    209   // response data.
    210   std::atomic_bool is_setting_adv_data_;
    211 
    212   std::atomic_bool adv_started_;
    213   std::unique_ptr<StatusCallback> adv_start_callback_;
    214   std::unique_ptr<StatusCallback> adv_stop_callback_;
    215 
    216   // Protects device scan related members below.
    217   std::mutex scan_fields_lock_;
    218 
    219   // Current scan settings.
    220   ScanSettings scan_settings_;
    221 
    222   // If true, then this client have a BLE device scan in progress.
    223   std::atomic_bool scan_started_;
    224 
    225   // Raw handle to the Delegate, which must outlive this LowEnergyClient
    226   // instance.
    227   std::mutex delegate_mutex_;
    228   Delegate* delegate_;
    229 
    230   // Protects device connection related members below.
    231   std::mutex connection_fields_lock_;
    232 
    233   // Maps bluetooth address to connection id
    234   //TODO(jpawlowski): change type to bimap
    235   std::map<const bt_bdaddr_t, int, ConnComparator> connection_ids_;
    236 
    237   DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
    238 };
    239 
    240 // LowEnergyClientFactory is used to register and obtain a per-application
    241 // LowEnergyClient instance. Users should call RegisterInstance to obtain their
    242 // own unique LowEnergyClient instance that has been registered with the
    243 // Bluetooth stack.
    244 class LowEnergyClientFactory
    245     : private hal::BluetoothGattInterface::ClientObserver,
    246       public BluetoothInstanceFactory {
    247  public:
    248   // Don't construct/destruct directly except in tests. Instead, obtain a handle
    249   // from an Adapter instance.
    250   LowEnergyClientFactory(Adapter& adapter);
    251   ~LowEnergyClientFactory() override;
    252 
    253   // BluetoothInstanceFactory override:
    254   bool RegisterInstance(const UUID& uuid,
    255                         const RegisterCallback& callback) override;
    256 
    257  private:
    258   friend class LowEnergyClient;
    259 
    260   // BluetoothGattInterface::ClientObserver overrides:
    261   void RegisterClientCallback(
    262       hal::BluetoothGattInterface* gatt_iface,
    263       int status, int client_id,
    264       const bt_uuid_t& app_uuid) override;
    265 
    266   // Map of pending calls to register.
    267   std::mutex pending_calls_lock_;
    268   std::map<UUID, RegisterCallback> pending_calls_;
    269 
    270   // Raw pointer to the Adapter that owns this factory.
    271   Adapter& adapter_;
    272 
    273   DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory);
    274 };
    275 
    276 }  // namespace bluetooth
    277