blob: 561b5a7c6532bb92298f355d70b32c07ca0dec53 [file] [log] [blame]
[email protected]0ae97592012-10-22 22:06:051// Copyright (c) 2012 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.
[email protected]0ae97592012-10-22 22:06:054
5#include "device/bluetooth/bluetooth_device_win.h"
6
7#include <string>
[email protected]d7ba43752013-02-21 22:27:058
[email protected]f1ef2272014-07-31 12:17:259#include "base/containers/scoped_ptr_hash_map.h"
[email protected]0ae97592012-10-22 22:06:0510#include "base/logging.h"
[email protected]d7ba43752013-02-21 22:27:0511#include "base/memory/scoped_vector.h"
[email protected]73131fc12014-04-08 01:02:2712#include "base/sequenced_task_runner.h"
[email protected]0d8db082013-06-11 07:27:0113#include "base/strings/stringprintf.h"
scheibeea0c48e2015-09-16 22:09:5414#include "device/bluetooth/bluetooth_adapter_win.h"
gogerald43eba582016-02-10 22:25:5615#include "device/bluetooth/bluetooth_remote_gatt_service_win.h"
[email protected]d7ba43752013-02-21 22:27:0516#include "device/bluetooth/bluetooth_service_record_win.h"
[email protected]2c24d942014-05-02 16:07:3117#include "device/bluetooth/bluetooth_socket_thread.h"
[email protected]edcaf14a2013-02-25 17:46:3618#include "device/bluetooth/bluetooth_socket_win.h"
19#include "device/bluetooth/bluetooth_task_manager_win.h"
[email protected]56b6aea52014-05-08 05:15:5220#include "device/bluetooth/bluetooth_uuid.h"
[email protected]d7ba43752013-02-21 22:27:0521
22namespace {
23
isherman764baa242014-10-16 04:45:3324const char kApiUnavailable[] = "This API is not implemented on this platform.";
25
[email protected]d7ba43752013-02-21 22:27:0526} // namespace
[email protected]0ae97592012-10-22 22:06:0527
28namespace device {
29
[email protected]d7ba43752013-02-21 22:27:0530BluetoothDeviceWin::BluetoothDeviceWin(
scheibeea0c48e2015-09-16 22:09:5431 BluetoothAdapterWin* adapter,
[email protected]f1ef2272014-07-31 12:17:2532 const BluetoothTaskManagerWin::DeviceState& device_state,
33 const scoped_refptr<base::SequencedTaskRunner>& ui_task_runner,
34 const scoped_refptr<BluetoothSocketThread>& socket_thread,
[email protected]73131fc12014-04-08 01:02:2735 net::NetLog* net_log,
36 const net::NetLog::Source& net_log_source)
scheibeea0c48e2015-09-16 22:09:5437 : BluetoothDevice(adapter),
[email protected]73131fc12014-04-08 01:02:2738 ui_task_runner_(ui_task_runner),
39 socket_thread_(socket_thread),
40 net_log_(net_log),
41 net_log_source_(net_log_source) {
[email protected]f1ef2272014-07-31 12:17:2542 Update(device_state);
43}
44
45BluetoothDeviceWin::~BluetoothDeviceWin() {
46}
47
avi176e2692015-12-22 19:26:5248uint32_t BluetoothDeviceWin::GetBluetoothClass() const {
[email protected]320447d72013-04-05 03:32:2649 return bluetooth_class_;
50}
51
[email protected]320447d72013-04-05 03:32:2652std::string BluetoothDeviceWin::GetAddress() const {
53 return address_;
54}
55
[email protected]c81543192014-03-11 22:44:4856BluetoothDevice::VendorIDSource
57BluetoothDeviceWin::GetVendorIDSource() const {
58 return VENDOR_ID_UNKNOWN;
59}
60
avi176e2692015-12-22 19:26:5261uint16_t BluetoothDeviceWin::GetVendorID() const {
[email protected]611ae29a2013-04-29 21:32:1962 return 0;
63}
64
avi176e2692015-12-22 19:26:5265uint16_t BluetoothDeviceWin::GetProductID() const {
[email protected]611ae29a2013-04-29 21:32:1966 return 0;
67}
68
avi176e2692015-12-22 19:26:5269uint16_t BluetoothDeviceWin::GetDeviceID() const {
[email protected]611ae29a2013-04-29 21:32:1970 return 0;
71}
72
josephsih098a1cd82016-02-24 10:17:2373uint16_t BluetoothDeviceWin::GetAppearance() const {
74 // TODO(crbug.com/588083): Implementing GetAppearance()
75 // on mac, win, and android platforms for chrome
76 NOTIMPLEMENTED();
77 return 0;
78}
79
[email protected]0ae97592012-10-22 22:06:0580bool BluetoothDeviceWin::IsPaired() const {
[email protected]320447d72013-04-05 03:32:2681 return paired_;
82}
83
84bool BluetoothDeviceWin::IsConnected() const {
85 return connected_;
86}
87
scheib95560872015-09-21 05:09:3388bool BluetoothDeviceWin::IsGattConnected() const {
89 NOTIMPLEMENTED();
90 return false;
91}
92
[email protected]320447d72013-04-05 03:32:2693bool BluetoothDeviceWin::IsConnectable() const {
[email protected]0ae97592012-10-22 22:06:0594 return false;
95}
96
[email protected]320447d72013-04-05 03:32:2697bool BluetoothDeviceWin::IsConnecting() const {
98 return false;
99}
100
[email protected]9bf562c2014-03-20 19:11:57101BluetoothDevice::UUIDList BluetoothDeviceWin::GetUUIDs() const {
102 return uuids_;
[email protected]0ae97592012-10-22 22:06:05103}
104
avi176e2692015-12-22 19:26:52105int16_t BluetoothDeviceWin::GetInquiryRSSI() const {
jpawlowskib06ff5fb2015-05-11 18:17:00106 return kUnknownPower;
107}
108
avi176e2692015-12-22 19:26:52109int16_t BluetoothDeviceWin::GetInquiryTxPower() const {
jpawlowski1b3a81a02015-05-13 19:13:36110 NOTIMPLEMENTED();
111 return kUnknownPower;
112}
113
[email protected]0ae97592012-10-22 22:06:05114bool BluetoothDeviceWin::ExpectingPinCode() const {
115 NOTIMPLEMENTED();
116 return false;
117}
118
119bool BluetoothDeviceWin::ExpectingPasskey() const {
120 NOTIMPLEMENTED();
121 return false;
122}
123
124bool BluetoothDeviceWin::ExpectingConfirmation() const {
125 NOTIMPLEMENTED();
126 return false;
127}
128
tengsd0606902015-01-07 21:31:30129void BluetoothDeviceWin::GetConnectionInfo(
130 const ConnectionInfoCallback& callback) {
131 NOTIMPLEMENTED();
132 callback.Run(ConnectionInfo());
133}
134
[email protected]0ae97592012-10-22 22:06:05135void BluetoothDeviceWin::Connect(
136 PairingDelegate* pairing_delegate,
137 const base::Closure& callback,
[email protected]eb72b662012-12-18 06:55:41138 const ConnectErrorCallback& error_callback) {
[email protected]0ae97592012-10-22 22:06:05139 NOTIMPLEMENTED();
140}
141
142void BluetoothDeviceWin::SetPinCode(const std::string& pincode) {
143 NOTIMPLEMENTED();
144}
145
avi176e2692015-12-22 19:26:52146void BluetoothDeviceWin::SetPasskey(uint32_t passkey) {
[email protected]0ae97592012-10-22 22:06:05147 NOTIMPLEMENTED();
148}
149
150void BluetoothDeviceWin::ConfirmPairing() {
151 NOTIMPLEMENTED();
152}
153
154void BluetoothDeviceWin::RejectPairing() {
155 NOTIMPLEMENTED();
156}
157
158void BluetoothDeviceWin::CancelPairing() {
159 NOTIMPLEMENTED();
160}
161
162void BluetoothDeviceWin::Disconnect(
163 const base::Closure& callback,
164 const ErrorCallback& error_callback) {
165 NOTIMPLEMENTED();
166}
167
stevenjb56612932015-11-12 23:14:57168void BluetoothDeviceWin::Forget(const base::Closure& callback,
169 const ErrorCallback& error_callback) {
[email protected]0ae97592012-10-22 22:06:05170 NOTIMPLEMENTED();
171}
172
[email protected]56b6aea52014-05-08 05:15:52173void BluetoothDeviceWin::ConnectToService(
174 const BluetoothUUID& uuid,
175 const ConnectToServiceCallback& callback,
176 const ConnectToServiceErrorCallback& error_callback) {
[email protected]85317222014-06-06 11:03:39177 scoped_refptr<BluetoothSocketWin> socket(
178 BluetoothSocketWin::CreateBluetoothSocket(
[email protected]daed8ec2014-07-23 06:18:54179 ui_task_runner_, socket_thread_));
[email protected]85317222014-06-06 11:03:39180 socket->Connect(this, uuid, base::Bind(callback, socket), error_callback);
[email protected]56b6aea52014-05-08 05:15:52181}
182
isherman764baa242014-10-16 04:45:33183void BluetoothDeviceWin::ConnectToServiceInsecurely(
184 const BluetoothUUID& uuid,
185 const ConnectToServiceCallback& callback,
186 const ConnectToServiceErrorCallback& error_callback) {
187 error_callback.Run(kApiUnavailable);
188}
189
[email protected]9ca6bd22014-06-18 23:48:59190void BluetoothDeviceWin::CreateGattConnection(
191 const GattConnectionCallback& callback,
192 const ConnectErrorCallback& error_callback) {
193 // TODO(armansito): Implement.
194 error_callback.Run(ERROR_UNSUPPORTED_DEVICE);
195}
196
[email protected]85317222014-06-06 11:03:39197const BluetoothServiceRecordWin* BluetoothDeviceWin::GetServiceRecord(
[email protected]8148ad42014-04-04 04:10:38198 const device::BluetoothUUID& uuid) const {
[email protected]e55a50f2013-05-05 03:37:09199 for (ServiceRecordList::const_iterator iter = service_record_list_.begin();
200 iter != service_record_list_.end();
201 ++iter) {
[email protected]8148ad42014-04-04 04:10:38202 if ((*iter)->uuid() == uuid)
[email protected]69b68382013-07-31 15:49:36203 return *iter;
[email protected]d7ba43752013-02-21 22:27:05204 }
[email protected]e55a50f2013-05-05 03:37:09205 return NULL;
[email protected]d7ba43752013-02-21 22:27:05206}
207
scheib2326a772015-09-21 17:54:13208bool BluetoothDeviceWin::IsEqual(
209 const BluetoothTaskManagerWin::DeviceState& device_state) {
210 if (address_ != device_state.address || name_ != device_state.name ||
211 bluetooth_class_ != device_state.bluetooth_class ||
212 visible_ != device_state.visible ||
213 connected_ != device_state.connected ||
214 paired_ != device_state.authenticated) {
215 return false;
216 }
217
218 // Checks service collection
219 typedef std::set<BluetoothUUID> UUIDSet;
220 typedef base::ScopedPtrHashMap<
221 std::string, scoped_ptr<BluetoothServiceRecordWin>> ServiceRecordMap;
222
223 UUIDSet known_services;
224 for (UUIDList::const_iterator iter = uuids_.begin(); iter != uuids_.end();
225 ++iter) {
226 known_services.insert((*iter));
227 }
228
229 UUIDSet new_services;
230 ServiceRecordMap new_service_records;
231 for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
232 iter = device_state.service_record_states.begin();
233 iter != device_state.service_record_states.end(); ++iter) {
234 BluetoothServiceRecordWin* service_record = new BluetoothServiceRecordWin(
235 address_, (*iter)->name, (*iter)->sdp_bytes, (*iter)->gatt_uuid);
236 new_services.insert(service_record->uuid());
237 new_service_records.set(
238 service_record->uuid().canonical_value(),
239 scoped_ptr<BluetoothServiceRecordWin>(service_record));
240 }
241
242 UUIDSet removed_services =
243 base::STLSetDifference<UUIDSet>(known_services, new_services);
244 if (!removed_services.empty()) {
245 return false;
246 }
247 UUIDSet added_devices =
248 base::STLSetDifference<UUIDSet>(new_services, known_services);
249 if (!added_devices.empty()) {
250 return false;
251 }
252
253 for (ServiceRecordList::const_iterator iter = service_record_list_.begin();
254 iter != service_record_list_.end(); ++iter) {
255 BluetoothServiceRecordWin* service_record = (*iter);
256 BluetoothServiceRecordWin* new_service_record =
257 new_service_records.get((*iter)->uuid().canonical_value());
258 if (!service_record->IsEqual(*new_service_record))
259 return false;
260 }
261 return true;
262}
263
264void BluetoothDeviceWin::Update(
265 const BluetoothTaskManagerWin::DeviceState& device_state) {
266 address_ = device_state.address;
267 // Note: Callers are responsible for providing a canonicalized address.
268 DCHECK_EQ(address_, BluetoothDevice::CanonicalizeAddress(address_));
269 name_ = device_state.name;
270 bluetooth_class_ = device_state.bluetooth_class;
271 visible_ = device_state.visible;
272 connected_ = device_state.connected;
273 paired_ = device_state.authenticated;
274 UpdateServices(device_state);
275}
276
277std::string BluetoothDeviceWin::GetDeviceName() const {
278 return name_;
279}
280
281void BluetoothDeviceWin::CreateGattConnectionImpl() {
282 // Windows implementation does not use the default CreateGattConnection
283 // implementation.
284 NOTIMPLEMENTED();
285}
286
287void BluetoothDeviceWin::DisconnectGatt() {
288 // Windows implementation does not use the default CreateGattConnection
289 // implementation.
290 NOTIMPLEMENTED();
291}
292
293void BluetoothDeviceWin::SetVisible(bool visible) {
294 visible_ = visible;
295}
296
297void BluetoothDeviceWin::UpdateServices(
298 const BluetoothTaskManagerWin::DeviceState& device_state) {
299 uuids_.clear();
300 service_record_list_.clear();
301
302 for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
303 iter = device_state.service_record_states.begin();
304 iter != device_state.service_record_states.end(); ++iter) {
305 BluetoothServiceRecordWin* service_record =
306 new BluetoothServiceRecordWin(device_state.address, (*iter)->name,
307 (*iter)->sdp_bytes, (*iter)->gatt_uuid);
308 service_record_list_.push_back(service_record);
309 uuids_.push_back(service_record->uuid());
310 }
gogerald43eba582016-02-10 22:25:56311
312 if (!device_state.is_bluetooth_classic())
313 UpdateGattServices(device_state.service_record_states);
314}
315
316bool BluetoothDeviceWin::IsGattServiceDiscovered(BluetoothUUID& uuid,
317 uint16_t attribute_handle) {
318 GattServiceMap::iterator it = gatt_services_.begin();
319 for (; it != gatt_services_.end(); it++) {
320 uint16_t it_att_handle =
321 static_cast<BluetoothRemoteGattServiceWin*>(it->second)
322 ->GetAttributeHandle();
323 BluetoothUUID it_uuid = it->second->GetUUID();
324 if (attribute_handle == it_att_handle && uuid == it_uuid) {
325 return true;
326 }
327 }
328 return false;
329}
330
331bool BluetoothDeviceWin::DoesGattServiceExist(
332 const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>&
333 service_state,
334 BluetoothGattService* service) {
335 uint16_t attribute_handle =
336 static_cast<BluetoothRemoteGattServiceWin*>(service)
337 ->GetAttributeHandle();
338 BluetoothUUID uuid = service->GetUUID();
339 ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator it =
340 service_state.begin();
341 for (; it != service_state.end(); ++it) {
342 if (attribute_handle == (*it)->attribute_handle && uuid == (*it)->gatt_uuid)
343 return true;
344 }
345 return false;
346}
347
348void BluetoothDeviceWin::UpdateGattServices(
349 const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>&
350 service_state) {
351 // First, remove no longer exist GATT service.
352 {
353 std::vector<std::string> to_be_removed_services;
354 for (const auto& gatt_service : gatt_services_) {
355 if (!DoesGattServiceExist(service_state, gatt_service.second)) {
356 to_be_removed_services.push_back(gatt_service.first);
357 }
358 }
359 for (const auto& service : to_be_removed_services) {
gogeralde069a452016-02-26 15:36:09360 gatt_services_.take_and_erase(service);
gogerald43eba582016-02-10 22:25:56361 }
362 // Update previously discovered services.
363 for (auto gatt_service : gatt_services_) {
364 static_cast<BluetoothRemoteGattServiceWin*>(gatt_service.second)
365 ->Update();
366 }
367 }
368
369 // Return if no new services have been added.
370 if (gatt_services_.size() == service_state.size())
371 return;
372
373 // Add new services.
374 for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator
375 it = service_state.begin();
376 it != service_state.end(); ++it) {
377 if (!IsGattServiceDiscovered((*it)->gatt_uuid, (*it)->attribute_handle)) {
378 BluetoothRemoteGattServiceWin* primary_service =
379 new BluetoothRemoteGattServiceWin(this, (*it)->path, (*it)->gatt_uuid,
380 (*it)->attribute_handle, true,
381 nullptr, ui_task_runner_);
382 gatt_services_.add(primary_service->GetIdentifier(),
383 scoped_ptr<BluetoothGattService>(primary_service));
384 adapter_->NotifyGattServiceAdded(primary_service);
385 }
386 }
387
388 adapter_->NotifyGattServicesDiscovered(this);
scheib2326a772015-09-21 17:54:13389}
390
[email protected]0ae97592012-10-22 22:06:05391} // namespace device