#include "service/common/bluetooth/advertise_data.h"
#include "service/common/bluetooth/advertise_settings.h"
#include "service/common/bluetooth/low_energy_constants.h"
+#include "service/common/bluetooth/scan_filter.h"
+#include "service/common/bluetooth/scan_result.h"
+#include "service/common/bluetooth/scan_settings.h"
#include "service/common/bluetooth/uuid.h"
#include "service/hal/bluetooth_gatt_interface.h"
namespace bluetooth {
+struct ConnComparator {
+ bool operator()(const bt_bdaddr_t& a, const bt_bdaddr_t& b) const {
+ return memcmp(&a, &b, sizeof(bt_bdaddr_t)) < 0;
+ }
+};
+
+class Adapter;
+
// A LowEnergyClient represents an application's handle to perform various
// Bluetooth Low Energy GAP operations. Instances cannot be created directly and
// should be obtained through the factory.
class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
public BluetoothInstance {
public:
+ // The Delegate interface is used to notify asynchronous events related to BLE
+ // GAP operations.
+ class Delegate {
+ public:
+ Delegate() = default;
+ virtual ~Delegate() = default;
+
+ // Called asynchronously to notify the delegate of nearby BLE advertisers
+ // found during a device scan.
+ virtual void OnScanResult(LowEnergyClient* client,
+ const ScanResult& scan_result) = 0;
+
+ // Called asynchronously to notify the delegate of connection state change
+ virtual void OnConnectionState(LowEnergyClient* client, int status,
+ const char* address, bool connected) = 0;
+
+ // Called asynchronously to notify the delegate of mtu change
+ virtual void OnMtuChanged(LowEnergyClient* client, int status, const char* address,
+ int mtu) = 0;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Delegate);
+ };
+
// The destructor automatically unregisters this client instance from the
// stack.
~LowEnergyClient() override;
+ // Assigns a delegate to this instance. |delegate| must out-live this
+ // LowEnergyClient instance.
+ void SetDelegate(Delegate* delegate);
+
// Callback type used to return the result of asynchronous operations below.
using StatusCallback = std::function<void(BLEStatus)>;
+ // Initiates a BLE connection do device with address |address|. If
+ // |is_direct| is set, use direct connect procedure. Return true on success
+ //, false otherwise.
+ bool Connect(std::string address, bool is_direct);
+
+ // Disconnect from previously connected BLE device with address |address|.
+ // Return true on success, false otherwise.
+ bool Disconnect(std::string address);
+
+ // Sends request to set MTU to |mtu| for device with address |address|.
+ // Return true on success, false otherwise.
+ bool SetMtu(std::string address, int mtu);
+
+ // Initiates a BLE device scan for this client using the given |settings| and
+ // |filters|. See the documentation for ScanSettings and ScanFilter for how
+ // these parameters can be configured. Return true on success, false
+ // otherwise. Please see logs for details in case of error.
+ bool StartScan(const ScanSettings& settings,
+ const std::vector<ScanFilter>& filters);
+
+ // Stops an ongoing BLE device scan for this client.
+ bool StopScan();
+
// Starts advertising based on the given advertising and scan response
// data and the provided |settings|. Reports the result of the operation in
- // |callback|.
+ // |callback|. Return true on success, false otherwise. Please see logs for
+ // details in case of error.
bool StartAdvertising(const AdvertiseSettings& settings,
const AdvertiseData& advertise_data,
const AdvertiseData& scan_response,
bool IsStoppingAdvertising() const;
// Returns the current advertising settings.
- const AdvertiseSettings& settings() const { return settings_; }
+ const AdvertiseSettings& advertise_settings() const {
+ return advertise_settings_;
+ }
+
+ // Returns the current scan settings.
+ const ScanSettings& scan_settings() const { return scan_settings_; }
// BluetoothClientInstace overrides:
const UUID& GetAppIdentifier() const override;
// Constructor shouldn't be called directly as instances are meant to be
// obtained from the factory.
- LowEnergyClient(const UUID& uuid, int client_id);
+ LowEnergyClient(Adapter& adapter, const UUID& uuid, int client_id);
// BluetoothGattInterface::ClientObserver overrides:
+ void ScanResultCallback(
+ hal::BluetoothGattInterface* gatt_iface,
+ const bt_bdaddr_t& bda, int rssi, uint8_t* adv_data) override;
+
+ void ConnectCallback(
+ hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
+ int client_id, const bt_bdaddr_t& bda) override;
+ void DisconnectCallback(
+ hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
+ int client_id, const bt_bdaddr_t& bda) override;
+ void MtuChangedCallback(
+ hal::BluetoothGattInterface* gatt_iface, int conn_id, int status,
+ int mtu) override;
void MultiAdvEnableCallback(
hal::BluetoothGattInterface* gatt_iface,
int client_id, int status) override;
void InvokeAndClearStartCallback(BLEStatus status);
void InvokeAndClearStopCallback(BLEStatus status);
+ // Raw pointer to the Bluetooth Adapter.
+ Adapter& adapter_;
+
// See getters above for documentation.
UUID app_identifier_;
int client_id_;
std::atomic_bool scan_rsp_needs_update_;
// Latest advertising settings.
- AdvertiseSettings settings_;
+ AdvertiseSettings advertise_settings_;
// Whether or not there is a pending call to update advertising or scan
// response data.
std::unique_ptr<StatusCallback> adv_start_callback_;
std::unique_ptr<StatusCallback> adv_stop_callback_;
+ // Protects device scan related members below.
+ std::mutex scan_fields_lock_;
+
+ // Current scan settings.
+ ScanSettings scan_settings_;
+
+ // If true, then this client have a BLE device scan in progress.
+ std::atomic_bool scan_started_;
+
+ // Raw handle to the Delegate, which must outlive this LowEnergyClient
+ // instance.
+ std::mutex delegate_mutex_;
+ Delegate* delegate_;
+
+ // Protects device connection related members below.
+ std::mutex connection_fields_lock_;
+
+ // Maps bluetooth address to connection id
+ //TODO(jpawlowski): change type to bimap
+ std::map<const bt_bdaddr_t, int, ConnComparator> connection_ids_;
+
DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
};
public:
// Don't construct/destruct directly except in tests. Instead, obtain a handle
// from an Adapter instance.
- LowEnergyClientFactory();
+ LowEnergyClientFactory(Adapter& adapter);
~LowEnergyClientFactory() override;
// BluetoothInstanceFactory override:
const RegisterCallback& callback) override;
private:
+ friend class LowEnergyClient;
+
// BluetoothGattInterface::ClientObserver overrides:
void RegisterClientCallback(
hal::BluetoothGattInterface* gatt_iface,
std::mutex pending_calls_lock_;
std::map<UUID, RegisterCallback> pending_calls_;
+ // Raw pointer to the Adapter that owns this factory.
+ Adapter& adapter_;
+
DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory);
};