Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(54)

Side by Side Diff: device/bluetooth/bluetooth_remote_gatt_service_win.cc

Issue 1606013002: BLE GATT service implementation in Chrome for Windows 8 and later (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update Build.gn Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
6
7 #include "base/bind.h"
8
9 namespace device {
10
11 void BluetoothRemoteGattServiceWin::NotifyServiceDiscComplIfNecessary() {
12 if (discovery_completed_included_charateristics_.size() ==
13 included_characteristic_objects_.size() &&
14 discovery_completed_included_services_.size() ==
15 included_service_objects_.size() &&
16 included_services_discovered_ && included_characteristics_discovered_ &&
17 !complete_notified_) {
18 if (is_primary_)
19 adapter_->NotifyGattDiscoveryCompleteForService(this);
20 else
21 parent_service_->NotifyGattServiceAdded(this);
22 complete_notified_ = true;
23 }
24 }
25
26 void BluetoothRemoteGattServiceWin::UpdateIncludedCharacteristics(
27 PBTH_LE_GATT_CHARACTERISTIC characteristics,
28 uint16_t num) {
29 if (num == 0) {
30 discovery_completed_included_charateristics_.clear();
31 included_characteristic_objects_.clear();
32 return;
33 }
34
35 // Map of retreived characteristic uuid value to its index in
36 // |characteristics|.
37 std::map<std::string, uint16_t> current_characteristics;
38 for (uint16_t i = 0; i < num; i++) {
39 current_characteristics[task_manager_
40 ->BluetoothLowEnergyUuidToBluetoothUuid(
41 characteristics[i].CharacteristicUuid)
42 .value()] = i;
43 }
44
45 // Map of known characteristics uuid value to its identifier.
46 std::map<std::string, std::string> known_characteristics;
47 // Remove no longer existed characteristics first.
48 if (included_characteristic_objects_.size() != 0) {
49 for (auto e : included_characteristic_objects_) {
50 known_characteristics[e.second->GetUUID().value()] = e.first;
51 }
52 std::vector<std::string> removed_characteristics;
53 for (auto e : known_characteristics) {
54 if (current_characteristics.find(e.first) ==
55 current_characteristics.end()) {
56 removed_characteristics.push_back(e.second);
57 }
58 }
59 for (auto identifier : removed_characteristics) {
60 discovery_completed_included_charateristics_.erase(identifier);
61 included_characteristic_objects_.erase(identifier);
62 }
63 // Update previously known characteristics.
64 for (auto e : included_characteristic_objects_)
65 e.second->Update();
66 }
67
68 // Return if no new characteristics have been added.
69 if (included_characteristic_objects_.size() == num)
70 return;
71
72 // Add new characteristics.
73 for (auto e : current_characteristics) {
74 if (known_characteristics.find(e.first) == known_characteristics.end()) {
75 PBTH_LE_GATT_CHARACTERISTIC info = new BTH_LE_GATT_CHARACTERISTIC();
76 *info = characteristics[e.second];
77 BluetoothRemoteGattCharacteristicWin* characteristic_object =
78 new BluetoothRemoteGattCharacteristicWin(this, info, ui_task_runner_);
79 included_characteristic_objects_.add(
80 characteristic_object->GetIdentifier(),
81 scoped_ptr<BluetoothRemoteGattCharacteristicWin>(
82 characteristic_object));
83 }
84 }
85 }
86
87 void BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback(
88 PBTH_LE_GATT_CHARACTERISTIC characteristics,
89 uint16_t num,
90 HRESULT hr) {
91 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
92 if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
93 return;
94 UpdateIncludedCharacteristics(characteristics, num);
95 included_characteristics_discovered_ = true;
96 NotifyServiceDiscComplIfNecessary();
97 }
98
99 void BluetoothRemoteGattServiceWin::UpdateIncludedServices(
100 PBTH_LE_GATT_SERVICE services,
101 uint16_t num) {
102 if (num == 0) {
103 discovery_completed_included_services_.clear();
104 included_service_objects_.clear();
105 return;
106 }
107
108 // Map of retreived service uuid value to its index in
109 // |services|.
110 std::map<std::string, uint16_t> current_services;
111 for (uint16_t i = 0; i < num; i++) {
112 current_services[task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
113 services[i].ServiceUuid)
114 .value()] = i;
115 }
116
117 // Map of known services uuid value to its identifier.
118 std::map<std::string, std::string> known_services;
119 // Remove no longer existed services first.
120 if (included_service_objects_.size() != 0) {
121 for (auto e : included_service_objects_) {
122 known_services[e.second->GetUUID().value()] = e.first;
123 }
124 std::vector<std::string> removed_services;
125 for (auto e : known_services) {
126 if (current_services.find(e.first) == current_services.end()) {
127 removed_services.push_back(e.second);
128 }
129 }
130 for (auto identifier : removed_services) {
131 discovery_completed_included_services_.erase(identifier);
132 included_service_objects_.erase(identifier);
133 }
134 // Update previously known included services.
135 for (auto e : included_service_objects_)
136 e.second->Update();
137 }
138
139 // Return if no new services have been added.
140 if (included_service_objects_.size() == num)
141 return;
142
143 // Add new services.
144 for (auto e : current_services) {
145 if (known_services.find(e.first) == known_services.end()) {
146 BluetoothUUID uuid = task_manager_->BluetoothLowEnergyUuidToBluetoothUuid(
147 services[e.second].ServiceUuid);
148 BluetoothRemoteGattServiceWin* service_object =
149 new BluetoothRemoteGattServiceWin(device_, service_path_, uuid,
150 services[e.second].AttributeHandle,
151 false, this, ui_task_runner_);
152 included_service_objects_.add(
153 service_object->GetIdentifier(),
154 scoped_ptr<BluetoothRemoteGattServiceWin>(service_object));
155 }
156 }
157 }
158
159 void BluetoothRemoteGattServiceWin::GetIncludedServicesCallback(
160 PBTH_LE_GATT_SERVICE services,
161 uint16_t num,
162 HRESULT hr) {
163 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
164 if (FAILED(hr) && hr != HRESULT_FROM_WIN32(ERROR_NOT_FOUND))
165 return;
166 UpdateIncludedServices(services, num);
167 included_services_discovered_ = true;
168 NotifyServiceDiscComplIfNecessary();
169 }
170
171 // Called by included service.
172 void BluetoothRemoteGattServiceWin::NotifyGattServiceAdded(
173 BluetoothRemoteGattServiceWin* service) {
174 discovery_completed_included_services_.insert(service->GetIdentifier());
175 NotifyServiceDiscComplIfNecessary();
176 }
177
178 // Called by included characteristics.
179 void BluetoothRemoteGattServiceWin::NotifyGattCharacteristicAdded(
180 BluetoothRemoteGattCharacteristicWin* characteristic) {
181 discovery_completed_included_charateristics_.insert(
182 characteristic->GetIdentifier());
183 adapter_->NotifyGattCharacteristicAdded(characteristic);
184 NotifyServiceDiscComplIfNecessary();
185 }
186
187 BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin(
188 BluetoothDeviceWin* device,
189 base::FilePath service_path,
190 BluetoothUUID service_uuid,
191 uint16_t service_attribute_handle,
192 bool is_primary,
193 BluetoothRemoteGattServiceWin* parent_service,
194 scoped_refptr<base::SequencedTaskRunner>& ui_task_runner)
195 : service_path_(service_path),
196 device_(device),
197 service_uuid_(service_uuid),
198 service_attribute_handle_(service_attribute_handle),
199 is_primary_(is_primary),
200 parent_service_(parent_service),
201 adapter_(nullptr),
202 task_manager_(nullptr),
203 complete_notified_(false),
204 included_services_discovered_(false),
205 included_characteristics_discovered_(false),
206 ui_task_runner_(ui_task_runner),
207 weak_ptr_factory_(this) {
208 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
209 discovery_completed_included_charateristics_.clear();
210 discovery_completed_included_services_.clear();
211 included_characteristic_objects_.clear();
212 included_service_objects_.clear();
213 adapter_ = const_cast<BluetoothAdapterWin*>(device_->GetAdapter());
214 task_manager_ = adapter_->GetWinBluetoothTaskManager();
215 DCHECK(device_);
216 if (!is_primary_)
217 DCHECK(parent_service_);
218 DCHECK(adapter_);
219 DCHECK(task_manager_);
220 Update();
221 }
222
223 BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {
224 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
225 included_service_objects_.clear();
226 included_characteristic_objects_.clear();
227 discovery_completed_included_charateristics_.clear();
228 discovery_completed_included_services_.clear();
229 included_services_discovered_ = false;
230 included_characteristics_discovered_ = false;
231
232 // Only primary service notify adapter the service removed. The life cycle of
233 // included service is controlled by its parent service.
234 if (is_primary_)
235 adapter_->NotifyGattServiceRemoved(device_, this);
236 }
237
238 std::string BluetoothRemoteGattServiceWin::GetIdentifier() const {
239 std::string identifier =
240 service_uuid_.value() + "_" + std::to_string(service_attribute_handle_);
241 if (is_primary_)
242 return device_->GetIdentifier() + "_" + identifier;
243 else
244 return parent_service_->GetIdentifier() + "_" + identifier;
245 }
246
247 BluetoothUUID BluetoothRemoteGattServiceWin::GetUUID() const {
248 return const_cast<BluetoothUUID&>(service_uuid_);
249 }
250
251 bool BluetoothRemoteGattServiceWin::IsLocal() const {
252 return false;
253 }
254
255 bool BluetoothRemoteGattServiceWin::IsPrimary() const {
256 return is_primary_;
257 }
258
259 BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const {
260 return device_;
261 }
262
263 std::vector<BluetoothGattCharacteristic*>
264 BluetoothRemoteGattServiceWin::GetCharacteristics() const {
265 std::vector<BluetoothGattCharacteristic*> has_characteristics;
266 for (auto c : included_characteristic_objects_)
267 has_characteristics.push_back(c.second);
268 return has_characteristics;
269 }
270
271 std::vector<BluetoothGattService*>
272 BluetoothRemoteGattServiceWin::GetIncludedServices() const {
273 std::vector<BluetoothGattService*> has_services;
274 for (auto s : included_service_objects_)
275 has_services.push_back(s.second);
276 return has_services;
277 }
278
279 BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic(
280 const std::string& identifier) const {
281 GattCharacteristicsMap::const_iterator it =
282 included_characteristic_objects_.find(identifier);
283 if (it != included_characteristic_objects_.end())
284 return it->second;
285 return nullptr;
286 }
287
288 bool BluetoothRemoteGattServiceWin::AddCharacteristic(
289 device::BluetoothGattCharacteristic* characteristic) {
290 NOTIMPLEMENTED();
291 return false;
292 }
293
294 bool BluetoothRemoteGattServiceWin::AddIncludedService(
295 device::BluetoothGattService* service) {
296 NOTIMPLEMENTED();
297 return false;
298 }
299
300 void BluetoothRemoteGattServiceWin::Register(
301 const base::Closure& callback,
302 const ErrorCallback& error_callback) {
303 NOTIMPLEMENTED();
304 error_callback.Run();
305 }
306
307 void BluetoothRemoteGattServiceWin::Unregister(
308 const base::Closure& callback,
309 const ErrorCallback& error_callback) {
310 NOTIMPLEMENTED();
311 error_callback.Run();
312 }
313
314 void BluetoothRemoteGattServiceWin::Update() {
315 DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
316
317 task_manager_->PostGetGattIncludedServices(
318 service_path_, service_uuid_, service_attribute_handle_,
319 base::Bind(&BluetoothRemoteGattServiceWin::GetIncludedServicesCallback,
320 weak_ptr_factory_.GetWeakPtr()));
321 task_manager_->PostGetGattIncludedCharacteristics(
322 service_path_, service_uuid_, service_attribute_handle_,
323 base::Bind(
324 &BluetoothRemoteGattServiceWin::GetIncludedCharacteristicsCallback,
325 weak_ptr_factory_.GetWeakPtr()));
326 }
327
328 } // namespace device.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698