blob: ea048bb68facbb6ed4d3f0a26c280cfa88936805 [file] [log] [blame]
Arman Ugurayc2fc0f22015-09-03 15:09:41 -07001//
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
Arman Uguray2fea18e2015-09-23 23:43:18 -070019#include <atomic>
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070020#include <functional>
21#include <map>
22#include <mutex>
23
24#include <base/macros.h>
25
Arman Uguraybb18c412015-11-12 13:44:31 -080026#include "service/bluetooth_instance.h"
Arman Uguray234138e2015-10-06 15:56:36 -070027#include "service/common/bluetooth/low_energy_constants.h"
Arman Uguray480174f2015-11-30 15:36:17 -080028#include "service/common/bluetooth/scan_filter.h"
Arman Uguray82ea72f2015-12-02 17:29:27 -080029#include "service/common/bluetooth/scan_result.h"
Arman Uguray480174f2015-11-30 15:36:17 -080030#include "service/common/bluetooth/scan_settings.h"
Arman Uguray234138e2015-10-06 15:56:36 -070031#include "service/common/bluetooth/uuid.h"
Arman Uguray08f80eb2015-09-21 11:17:07 -070032#include "service/hal/bluetooth_gatt_interface.h"
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070033
34namespace bluetooth {
35
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080036struct ConnComparator {
Jakub Pawlowskia484a882017-06-24 17:30:18 -070037 bool operator()(const RawAddress& a, const RawAddress& b) const {
38 return memcmp(&a, &b, sizeof(RawAddress)) < 0;
Myles Watson911d1ae2016-11-28 16:44:40 -080039 }
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080040};
41
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -080042class Adapter;
43
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070044// A LowEnergyClient represents an application's handle to perform various
45// Bluetooth Low Energy GAP operations. Instances cannot be created directly and
46// should be obtained through the factory.
Arman Uguray08f80eb2015-09-21 11:17:07 -070047class LowEnergyClient : private hal::BluetoothGattInterface::ClientObserver,
Arman Uguraybb18c412015-11-12 13:44:31 -080048 public BluetoothInstance {
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070049 public:
Arman Uguray82ea72f2015-12-02 17:29:27 -080050 // The Delegate interface is used to notify asynchronous events related to BLE
51 // GAP operations.
52 class Delegate {
53 public:
54 Delegate() = default;
55 virtual ~Delegate() = default;
56
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080057 // Called asynchronously to notify the delegate of connection state change
58 virtual void OnConnectionState(LowEnergyClient* client, int status,
59 const char* address, bool connected) = 0;
60
Jakub Pawlowskia6551072016-01-26 12:58:47 -080061 // Called asynchronously to notify the delegate of mtu change
Myles Watson911d1ae2016-11-28 16:44:40 -080062 virtual void OnMtuChanged(LowEnergyClient* client, int status,
63 const char* address, int mtu) = 0;
Jakub Pawlowskia6551072016-01-26 12:58:47 -080064
Arman Uguray82ea72f2015-12-02 17:29:27 -080065 private:
66 DISALLOW_COPY_AND_ASSIGN(Delegate);
67 };
68
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070069 // The destructor automatically unregisters this client instance from the
70 // stack.
Arman Uguray08f80eb2015-09-21 11:17:07 -070071 ~LowEnergyClient() override;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070072
Arman Uguray82ea72f2015-12-02 17:29:27 -080073 // Assigns a delegate to this instance. |delegate| must out-live this
74 // LowEnergyClient instance.
75 void SetDelegate(Delegate* delegate);
76
Arman Uguray12338402015-09-16 18:00:05 -070077 // Callback type used to return the result of asynchronous operations below.
78 using StatusCallback = std::function<void(BLEStatus)>;
79
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080080 // Initiates a BLE connection do device with address |address|. If
81 // |is_direct| is set, use direct connect procedure. Return true on success
82 //, false otherwise.
Chih-Hung Hsieh5dc0d152016-08-17 14:12:51 -070083 bool Connect(const std::string& address, bool is_direct);
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080084
85 // Disconnect from previously connected BLE device with address |address|.
86 // Return true on success, false otherwise.
Chih-Hung Hsieh5dc0d152016-08-17 14:12:51 -070087 bool Disconnect(const std::string& address);
Jakub Pawlowskia6372e92016-01-19 16:42:37 -080088
Jakub Pawlowskia6551072016-01-26 12:58:47 -080089 // Sends request to set MTU to |mtu| for device with address |address|.
90 // Return true on success, false otherwise.
Chih-Hung Hsieh5dc0d152016-08-17 14:12:51 -070091 bool SetMtu(const std::string& address, int mtu);
Jakub Pawlowskia6551072016-01-26 12:58:47 -080092
Arman Uguray08f80eb2015-09-21 11:17:07 -070093 // BluetoothClientInstace overrides:
94 const UUID& GetAppIdentifier() const override;
Arman Uguraybb18c412015-11-12 13:44:31 -080095 int GetInstanceId() const override;
Arman Uguray08f80eb2015-09-21 11:17:07 -070096
Arman Ugurayc2fc0f22015-09-03 15:09:41 -070097 private:
98 friend class LowEnergyClientFactory;
99
Arman Uguray08f80eb2015-09-21 11:17:07 -0700100 // Constructor shouldn't be called directly as instances are meant to be
101 // obtained from the factory.
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -0800102 LowEnergyClient(Adapter& adapter, const UUID& uuid, int client_id);
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700103
Arman Uguray12338402015-09-16 18:00:05 -0700104 // BluetoothGattInterface::ClientObserver overrides:
Myles Watson911d1ae2016-11-28 16:44:40 -0800105 void ConnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
106 int status, int client_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700107 const RawAddress& bda) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800108 void DisconnectCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
109 int status, int client_id,
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700110 const RawAddress& bda) override;
Myles Watson911d1ae2016-11-28 16:44:40 -0800111 void MtuChangedCallback(hal::BluetoothGattInterface* gatt_iface, int conn_id,
112 int status, int mtu) override;
Arman Uguray12338402015-09-16 18:00:05 -0700113
114 // Calls and clears the pending callbacks.
115 void InvokeAndClearStartCallback(BLEStatus status);
116 void InvokeAndClearStopCallback(BLEStatus status);
117
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -0800118 // Raw pointer to the Bluetooth Adapter.
119 Adapter& adapter_;
120
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700121 // See getters above for documentation.
122 UUID app_identifier_;
Arman Uguraybb18c412015-11-12 13:44:31 -0800123 int client_id_;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700124
Arman Uguray82ea72f2015-12-02 17:29:27 -0800125 // Raw handle to the Delegate, which must outlive this LowEnergyClient
126 // instance.
127 std::mutex delegate_mutex_;
128 Delegate* delegate_;
129
Jakub Pawlowskia6372e92016-01-19 16:42:37 -0800130 // Protects device connection related members below.
131 std::mutex connection_fields_lock_;
132
133 // Maps bluetooth address to connection id
Myles Watson911d1ae2016-11-28 16:44:40 -0800134 // TODO(jpawlowski): change type to bimap
Jakub Pawlowskia484a882017-06-24 17:30:18 -0700135 std::map<const RawAddress, int, ConnComparator> connection_ids_;
Jakub Pawlowskia6372e92016-01-19 16:42:37 -0800136
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700137 DISALLOW_COPY_AND_ASSIGN(LowEnergyClient);
138};
139
140// LowEnergyClientFactory is used to register and obtain a per-application
Arman Uguraybb18c412015-11-12 13:44:31 -0800141// LowEnergyClient instance. Users should call RegisterInstance to obtain their
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700142// own unique LowEnergyClient instance that has been registered with the
143// Bluetooth stack.
144class LowEnergyClientFactory
Arman Uguray08f80eb2015-09-21 11:17:07 -0700145 : private hal::BluetoothGattInterface::ClientObserver,
Arman Uguraybb18c412015-11-12 13:44:31 -0800146 public BluetoothInstanceFactory {
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700147 public:
148 // Don't construct/destruct directly except in tests. Instead, obtain a handle
Arman Uguray08f80eb2015-09-21 11:17:07 -0700149 // from an Adapter instance.
Chih-Hung Hsieh33987302016-06-30 15:45:24 -0700150 explicit LowEnergyClientFactory(Adapter& adapter);
Arman Uguray08f80eb2015-09-21 11:17:07 -0700151 ~LowEnergyClientFactory() override;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700152
Arman Uguraybb18c412015-11-12 13:44:31 -0800153 // BluetoothInstanceFactory override:
154 bool RegisterInstance(const UUID& uuid,
155 const RegisterCallback& callback) override;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700156
157 private:
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -0800158 friend class LowEnergyClient;
159
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700160 // BluetoothGattInterface::ClientObserver overrides:
Myles Watson911d1ae2016-11-28 16:44:40 -0800161 void RegisterClientCallback(hal::BluetoothGattInterface* gatt_iface,
162 int status, int client_id,
163 const bt_uuid_t& app_uuid) override;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700164
165 // Map of pending calls to register.
166 std::mutex pending_calls_lock_;
Arman Uguray08f80eb2015-09-21 11:17:07 -0700167 std::map<UUID, RegisterCallback> pending_calls_;
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700168
Jakub Pawlowski60b0e8f2016-01-12 13:51:35 -0800169 // Raw pointer to the Adapter that owns this factory.
170 Adapter& adapter_;
171
Arman Ugurayc2fc0f22015-09-03 15:09:41 -0700172 DISALLOW_COPY_AND_ASSIGN(LowEnergyClientFactory);
173};
174
175} // namespace bluetooth