bluetooth_low_energy_win_fake.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648
  1. // Copyright 2016 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. #include "device/bluetooth/bluetooth_low_energy_win_fake.h"
  5. #include <memory>
  6. #include "base/memory/ptr_util.h"
  7. #include "base/strings/stringprintf.h"
  8. #include "device/bluetooth/bluetooth_low_energy_defs_win.h"
  9. namespace {
  10. const char kPlatformNotSupported[] =
  11. "Bluetooth Low energy is only supported on Windows 8 and later.";
  12. } // namespace
  13. namespace device {
  14. namespace win {
  15. BLEDevice::BLEDevice() {}
  16. BLEDevice::~BLEDevice() {}
  17. GattService::GattService() {}
  18. GattService::~GattService() {}
  19. GattCharacteristic::GattCharacteristic() {}
  20. GattCharacteristic::~GattCharacteristic() {}
  21. GattDescriptor::GattDescriptor() {}
  22. GattDescriptor::~GattDescriptor() {}
  23. GattCharacteristicObserver::GattCharacteristicObserver() {}
  24. GattCharacteristicObserver::~GattCharacteristicObserver() {}
  25. BluetoothLowEnergyWrapperFake::BluetoothLowEnergyWrapperFake()
  26. : observer_(nullptr) {}
  27. BluetoothLowEnergyWrapperFake::~BluetoothLowEnergyWrapperFake() {}
  28. bool BluetoothLowEnergyWrapperFake::IsBluetoothLowEnergySupported() {
  29. return true;
  30. }
  31. bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyDevices(
  32. std::vector<std::unique_ptr<BluetoothLowEnergyDeviceInfo>>* devices,
  33. std::string* error) {
  34. if (!IsBluetoothLowEnergySupported()) {
  35. *error = kPlatformNotSupported;
  36. return false;
  37. }
  38. for (auto& device : simulated_devices_) {
  39. if (device.second->marked_as_deleted)
  40. continue;
  41. auto device_info = std::make_unique<BluetoothLowEnergyDeviceInfo>();
  42. *device_info = *(device.second->device_info);
  43. devices->push_back(std::move(device_info));
  44. }
  45. return true;
  46. }
  47. bool BluetoothLowEnergyWrapperFake::
  48. EnumerateKnownBluetoothLowEnergyGattServiceDevices(
  49. std::vector<std::unique_ptr<BluetoothLowEnergyDeviceInfo>>* devices,
  50. std::string* error) {
  51. if (!IsBluetoothLowEnergySupported()) {
  52. *error = kPlatformNotSupported;
  53. return false;
  54. }
  55. for (auto& device : simulated_devices_) {
  56. for (auto& service : device.second->primary_services) {
  57. auto device_info = std::make_unique<BluetoothLowEnergyDeviceInfo>();
  58. *device_info = *(device.second->device_info);
  59. std::wstring path = GenerateGattServiceDevicePath(
  60. device.second->device_info->path.value(),
  61. service.second->service_info->AttributeHandle);
  62. device_info->path = base::FilePath(path);
  63. devices->push_back(std::move(device_info));
  64. }
  65. }
  66. return true;
  67. }
  68. bool BluetoothLowEnergyWrapperFake::EnumerateKnownBluetoothLowEnergyServices(
  69. const base::FilePath& device_path,
  70. std::vector<std::unique_ptr<BluetoothLowEnergyServiceInfo>>* services,
  71. std::string* error) {
  72. if (!IsBluetoothLowEnergySupported()) {
  73. *error = kPlatformNotSupported;
  74. return false;
  75. }
  76. std::wstring device_address =
  77. ExtractDeviceAddressFromDevicePath(device_path.value());
  78. std::vector<std::string> service_attribute_handles =
  79. ExtractServiceAttributeHandlesFromDevicePath(device_path.value());
  80. BLEDevicesMap::iterator it_d = simulated_devices_.find(
  81. std::string(device_address.begin(), device_address.end()));
  82. CHECK(it_d != simulated_devices_.end());
  83. // |service_attribute_handles| is empty means |device_path| is a BLE device
  84. // path, otherwise it is a BLE GATT service device path.
  85. if (service_attribute_handles.empty()) {
  86. // Return all primary services for BLE device.
  87. for (auto& primary_service : it_d->second->primary_services) {
  88. auto service_info = std::make_unique<BluetoothLowEnergyServiceInfo>();
  89. service_info->uuid = primary_service.second->service_info->ServiceUuid;
  90. service_info->attribute_handle =
  91. primary_service.second->service_info->AttributeHandle;
  92. services->push_back(std::move(service_info));
  93. }
  94. } else {
  95. // Return corresponding GATT service for BLE GATT service device.
  96. GattService* target_service =
  97. GetSimulatedGattService(it_d->second.get(), service_attribute_handles);
  98. auto service_info = std::make_unique<BluetoothLowEnergyServiceInfo>();
  99. service_info->uuid = target_service->service_info->ServiceUuid;
  100. service_info->attribute_handle =
  101. target_service->service_info->AttributeHandle;
  102. services->push_back(std::move(service_info));
  103. }
  104. return true;
  105. }
  106. HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicsOfAService(
  107. base::FilePath& service_path,
  108. const PBTH_LE_GATT_SERVICE service,
  109. std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC>* out_included_characteristics,
  110. USHORT* out_counts) {
  111. std::wstring device_address =
  112. ExtractDeviceAddressFromDevicePath(service_path.value());
  113. BLEDevice* target_device = GetSimulatedBLEDevice(
  114. std::string(device_address.begin(), device_address.end()));
  115. if (target_device == nullptr)
  116. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  117. const std::vector<std::string> service_att_handles =
  118. ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
  119. GattService* target_service =
  120. GetSimulatedGattService(target_device, service_att_handles);
  121. if (target_service == nullptr)
  122. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  123. std::size_t number_of_included_characteristic =
  124. target_service->included_characteristics.size();
  125. if (number_of_included_characteristic) {
  126. *out_counts = (USHORT)number_of_included_characteristic;
  127. out_included_characteristics->reset(
  128. new BTH_LE_GATT_CHARACTERISTIC[number_of_included_characteristic]);
  129. std::size_t i = 0;
  130. for (const auto& cha : target_service->included_characteristics) {
  131. out_included_characteristics->get()[i] =
  132. *(cha.second->characteristic_info);
  133. i++;
  134. }
  135. return S_OK;
  136. }
  137. return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
  138. }
  139. HRESULT BluetoothLowEnergyWrapperFake::ReadDescriptorsOfACharacteristic(
  140. base::FilePath& service_path,
  141. const PBTH_LE_GATT_CHARACTERISTIC characteristic,
  142. std::unique_ptr<BTH_LE_GATT_DESCRIPTOR>* out_included_descriptors,
  143. USHORT* out_counts) {
  144. GattCharacteristic* target_characteristic =
  145. GetSimulatedGattCharacteristic(service_path, characteristic);
  146. if (target_characteristic == nullptr)
  147. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  148. std::size_t number_of_included_descriptors =
  149. target_characteristic->included_descriptors.size();
  150. PBTH_LE_GATT_DESCRIPTOR win_descriptors_info =
  151. new BTH_LE_GATT_DESCRIPTOR[number_of_included_descriptors];
  152. *out_counts = USHORT(number_of_included_descriptors);
  153. std::size_t i = 0;
  154. for (const auto& d : target_characteristic->included_descriptors) {
  155. win_descriptors_info[i] = *(d.second->descriptor_info);
  156. i++;
  157. }
  158. out_included_descriptors->reset(win_descriptors_info);
  159. return S_OK;
  160. }
  161. HRESULT BluetoothLowEnergyWrapperFake::ReadCharacteristicValue(
  162. base::FilePath& service_path,
  163. const PBTH_LE_GATT_CHARACTERISTIC characteristic,
  164. std::unique_ptr<BTH_LE_GATT_CHARACTERISTIC_VALUE>* out_value) {
  165. GattCharacteristic* target_characteristic =
  166. GetSimulatedGattCharacteristic(service_path, characteristic);
  167. if (target_characteristic == nullptr)
  168. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  169. // Return error simulated by SimulateGattCharacteristicReadError.
  170. if (target_characteristic->read_errors.size()) {
  171. HRESULT hr = target_characteristic->read_errors[0];
  172. target_characteristic->read_errors.erase(
  173. target_characteristic->read_errors.begin());
  174. return hr;
  175. }
  176. PBTH_LE_GATT_CHARACTERISTIC_VALUE ret_value =
  177. (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(
  178. new UCHAR[sizeof(ULONG) + target_characteristic->value->DataSize]);
  179. ret_value->DataSize = target_characteristic->value->DataSize;
  180. for (ULONG i = 0; i < ret_value->DataSize; i++)
  181. ret_value->Data[i] = target_characteristic->value->Data[i];
  182. out_value->reset(ret_value);
  183. if (observer_)
  184. observer_->OnReadGattCharacteristicValue();
  185. return S_OK;
  186. }
  187. HRESULT BluetoothLowEnergyWrapperFake::WriteCharacteristicValue(
  188. base::FilePath& service_path,
  189. const PBTH_LE_GATT_CHARACTERISTIC characteristic,
  190. PBTH_LE_GATT_CHARACTERISTIC_VALUE new_value,
  191. ULONG flags) {
  192. // Web Bluetooth implementation currently only supports no flags or write
  193. // without response flag even if Windows supports other flags
  194. if (flags != BLUETOOTH_GATT_FLAG_NONE &&
  195. flags != BLUETOOTH_GATT_FLAG_WRITE_WITHOUT_RESPONSE) {
  196. return HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
  197. }
  198. GattCharacteristic* target_characteristic =
  199. GetSimulatedGattCharacteristic(service_path, characteristic);
  200. if (target_characteristic == nullptr)
  201. return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
  202. // Return error simulated by SimulateGattCharacteristicWriteError.
  203. if (target_characteristic->write_errors.size()) {
  204. HRESULT hr = *(target_characteristic->write_errors.begin());
  205. target_characteristic->write_errors.erase(
  206. target_characteristic->write_errors.begin());
  207. return hr;
  208. }
  209. PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value =
  210. (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(
  211. new UCHAR[new_value->DataSize + sizeof(ULONG)]);
  212. for (ULONG i = 0; i < new_value->DataSize; i++)
  213. win_value->Data[i] = new_value->Data[i];
  214. win_value->DataSize = new_value->DataSize;
  215. target_characteristic->value.reset(win_value);
  216. if (observer_)
  217. observer_->OnWriteGattCharacteristicValue(win_value);
  218. return S_OK;
  219. }
  220. HRESULT BluetoothLowEnergyWrapperFake::RegisterGattEvents(
  221. base::FilePath& service_path,
  222. BTH_LE_GATT_EVENT_TYPE type,
  223. PVOID event_parameter,
  224. PFNBLUETOOTH_GATT_EVENT_CALLBACK_CORRECTED callback,
  225. PVOID context,
  226. BLUETOOTH_GATT_EVENT_HANDLE* out_handle) {
  227. // Right now, only CharacteristicValueChangedEvent is supported.
  228. CHECK(CharacteristicValueChangedEvent == type);
  229. std::unique_ptr<GattCharacteristicObserver> observer(
  230. new GattCharacteristicObserver());
  231. observer->callback = callback;
  232. observer->context = context;
  233. *out_handle = (BLUETOOTH_GATT_EVENT_HANDLE)observer.get();
  234. PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION parameter =
  235. (PBLUETOOTH_GATT_VALUE_CHANGED_EVENT_REGISTRATION)event_parameter;
  236. for (USHORT i = 0; i < parameter->NumCharacteristics; i++) {
  237. GattCharacteristic* target_characteristic = GetSimulatedGattCharacteristic(
  238. service_path, &parameter->Characteristics[i]);
  239. CHECK(target_characteristic);
  240. // Return error simulated by SimulateGattCharacteristicSetNotifyError.
  241. if (target_characteristic->notify_errors.size()) {
  242. HRESULT error = target_characteristic->notify_errors[0];
  243. target_characteristic->notify_errors.erase(
  244. target_characteristic->notify_errors.begin());
  245. return error;
  246. }
  247. target_characteristic->observers.push_back(*out_handle);
  248. }
  249. gatt_characteristic_observers_[*out_handle] = std::move(observer);
  250. if (observer_)
  251. observer_->OnStartCharacteristicNotification();
  252. return S_OK;
  253. }
  254. HRESULT BluetoothLowEnergyWrapperFake::UnregisterGattEvent(
  255. BLUETOOTH_GATT_EVENT_HANDLE event_handle) {
  256. gatt_characteristic_observers_.erase(event_handle);
  257. return S_OK;
  258. }
  259. HRESULT BluetoothLowEnergyWrapperFake::WriteDescriptorValue(
  260. base::FilePath& service_path,
  261. const PBTH_LE_GATT_DESCRIPTOR descriptor,
  262. PBTH_LE_GATT_DESCRIPTOR_VALUE new_value) {
  263. if (new_value->DescriptorType == ClientCharacteristicConfiguration) {
  264. // Simulate the value the OS will write.
  265. std::vector<UCHAR> write_value;
  266. if (new_value->ClientCharacteristicConfiguration
  267. .IsSubscribeToNotification) {
  268. write_value.push_back(1);
  269. } else if (new_value->ClientCharacteristicConfiguration
  270. .IsSubscribeToIndication) {
  271. write_value.push_back(2);
  272. }
  273. write_value.push_back(0);
  274. if (observer_)
  275. observer_->OnWriteGattDescriptorValue(write_value);
  276. }
  277. return S_OK;
  278. }
  279. BLEDevice* BluetoothLowEnergyWrapperFake::SimulateBLEDevice(
  280. std::string device_name,
  281. BLUETOOTH_ADDRESS device_address) {
  282. BLEDevice* device = new BLEDevice();
  283. BluetoothLowEnergyDeviceInfo* device_info =
  284. new BluetoothLowEnergyDeviceInfo();
  285. std::string string_device_address =
  286. BluetoothAddressToCanonicalString(device_address);
  287. device_info->path =
  288. base::FilePath(GenerateBLEDevicePath(string_device_address));
  289. device_info->friendly_name = device_name;
  290. device_info->address = device_address;
  291. device->device_info.reset(device_info);
  292. device->marked_as_deleted = false;
  293. simulated_devices_[string_device_address] = base::WrapUnique(device);
  294. return device;
  295. }
  296. BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice(
  297. std::string device_address) {
  298. BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address);
  299. if (it_d == simulated_devices_.end())
  300. return nullptr;
  301. return it_d->second.get();
  302. }
  303. void BluetoothLowEnergyWrapperFake::RemoveSimulatedBLEDevice(
  304. std::string device_address) {
  305. simulated_devices_[device_address]->marked_as_deleted = true;
  306. }
  307. GattService* BluetoothLowEnergyWrapperFake::SimulateGattService(
  308. BLEDevice* device,
  309. GattService* parent_service,
  310. const BTH_LE_UUID& uuid) {
  311. CHECK(device);
  312. GattService* service = new GattService();
  313. PBTH_LE_GATT_SERVICE service_info = new BTH_LE_GATT_SERVICE[1];
  314. std::string string_device_address =
  315. BluetoothAddressToCanonicalString(device->device_info->address);
  316. service_info->AttributeHandle =
  317. GenerateAUniqueAttributeHandle(string_device_address);
  318. service_info->ServiceUuid = uuid;
  319. service->service_info.reset(service_info);
  320. if (parent_service) {
  321. parent_service
  322. ->included_services[std::to_string(service_info->AttributeHandle)] =
  323. base::WrapUnique(service);
  324. } else {
  325. device->primary_services[std::to_string(service_info->AttributeHandle)] =
  326. base::WrapUnique(service);
  327. }
  328. return service;
  329. }
  330. void BluetoothLowEnergyWrapperFake::SimulateGattServiceRemoved(
  331. BLEDevice* device,
  332. GattService* parent_service,
  333. std::string attribute_handle) {
  334. if (parent_service) {
  335. parent_service->included_services.erase(attribute_handle);
  336. } else {
  337. device->primary_services.erase(attribute_handle);
  338. }
  339. }
  340. GattService* BluetoothLowEnergyWrapperFake::GetSimulatedGattService(
  341. BLEDevice* device,
  342. const std::vector<std::string>& chain_of_att_handle) {
  343. // First, find the root primary service.
  344. GattServicesMap::iterator it_s =
  345. device->primary_services.find(chain_of_att_handle[0]);
  346. if (it_s == device->primary_services.end())
  347. return nullptr;
  348. // Iteratively follow the chain of included service attribute handles to find
  349. // the target service.
  350. for (std::size_t i = 1; i < chain_of_att_handle.size(); i++) {
  351. std::string included_att_handle = std::string(
  352. chain_of_att_handle[i].begin(), chain_of_att_handle[i].end());
  353. GattServicesMap::iterator it_i =
  354. it_s->second->included_services.find(included_att_handle);
  355. if (it_i == it_s->second->included_services.end())
  356. return nullptr;
  357. it_s = it_i;
  358. }
  359. return it_s->second.get();
  360. }
  361. GattCharacteristic* BluetoothLowEnergyWrapperFake::SimulateGattCharacterisc(
  362. std::string device_address,
  363. GattService* parent_service,
  364. const BTH_LE_GATT_CHARACTERISTIC& characteristic) {
  365. CHECK(parent_service);
  366. GattCharacteristic* win_characteristic = new GattCharacteristic();
  367. PBTH_LE_GATT_CHARACTERISTIC win_characteristic_info =
  368. new BTH_LE_GATT_CHARACTERISTIC[1];
  369. *win_characteristic_info = characteristic;
  370. (win_characteristic->characteristic_info).reset(win_characteristic_info);
  371. win_characteristic->characteristic_info->AttributeHandle =
  372. GenerateAUniqueAttributeHandle(device_address);
  373. parent_service->included_characteristics[std::to_string(
  374. win_characteristic->characteristic_info->AttributeHandle)] =
  375. base::WrapUnique(win_characteristic);
  376. // Set default empty value.
  377. PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value =
  378. (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(
  379. new UCHAR[sizeof(BTH_LE_GATT_CHARACTERISTIC_VALUE)]);
  380. win_value->DataSize = 0;
  381. win_characteristic->value.reset(win_value);
  382. return win_characteristic;
  383. }
  384. void BluetoothLowEnergyWrapperFake::SimulateGattCharacteriscRemove(
  385. GattService* parent_service,
  386. std::string attribute_handle) {
  387. CHECK(parent_service);
  388. parent_service->included_characteristics.erase(attribute_handle);
  389. }
  390. GattCharacteristic*
  391. BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic(
  392. GattService* parent_service,
  393. std::string attribute_handle) {
  394. CHECK(parent_service);
  395. GattCharacteristicsMap::iterator it =
  396. parent_service->included_characteristics.find(attribute_handle);
  397. if (it != parent_service->included_characteristics.end())
  398. return it->second.get();
  399. return nullptr;
  400. }
  401. void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicValue(
  402. GattCharacteristic* characteristic,
  403. const std::vector<uint8_t>& value) {
  404. GattCharacteristic* target_characteristic = characteristic;
  405. if (target_characteristic == nullptr)
  406. target_characteristic = remembered_characteristic_;
  407. CHECK(target_characteristic);
  408. PBTH_LE_GATT_CHARACTERISTIC_VALUE win_value =
  409. (PBTH_LE_GATT_CHARACTERISTIC_VALUE)(
  410. new UCHAR[value.size() + sizeof(ULONG)]);
  411. win_value->DataSize = (ULONG)value.size();
  412. for (std::size_t i = 0; i < value.size(); i++)
  413. win_value->Data[i] = value[i];
  414. target_characteristic->value.reset(win_value);
  415. }
  416. void BluetoothLowEnergyWrapperFake::
  417. SimulateCharacteristicValueChangeNotification(
  418. GattCharacteristic* characteristic) {
  419. GattCharacteristic* target_characteristic = characteristic;
  420. if (target_characteristic == nullptr)
  421. target_characteristic = remembered_characteristic_;
  422. CHECK(target_characteristic);
  423. for (auto* observer : target_characteristic->observers) {
  424. GattCharacteristicObserverTable::const_iterator it =
  425. gatt_characteristic_observers_.find(observer);
  426. // Check if |observer| has been unregistered by UnregisterGattEvent.
  427. if (it != gatt_characteristic_observers_.end()) {
  428. BLUETOOTH_GATT_VALUE_CHANGED_EVENT event;
  429. event.ChangedAttributeHandle =
  430. target_characteristic->characteristic_info->AttributeHandle;
  431. event.CharacteristicValueDataSize =
  432. target_characteristic->value->DataSize + sizeof(ULONG);
  433. event.CharacteristicValue = target_characteristic->value.get();
  434. it->second->callback(CharacteristicValueChangedEvent, &event,
  435. it->second->context);
  436. }
  437. }
  438. }
  439. void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicSetNotifyError(
  440. GattCharacteristic* characteristic,
  441. HRESULT error) {
  442. characteristic->notify_errors.push_back(error);
  443. }
  444. void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicReadError(
  445. GattCharacteristic* characteristic,
  446. HRESULT error) {
  447. CHECK(characteristic);
  448. characteristic->read_errors.push_back(error);
  449. }
  450. void BluetoothLowEnergyWrapperFake::SimulateGattCharacteristicWriteError(
  451. GattCharacteristic* characteristic,
  452. HRESULT error) {
  453. CHECK(characteristic);
  454. characteristic->write_errors.push_back(error);
  455. }
  456. void BluetoothLowEnergyWrapperFake::RememberCharacteristicForSubsequentAction(
  457. GattService* parent_service,
  458. std::string attribute_handle) {
  459. CHECK(parent_service);
  460. remembered_characteristic_ =
  461. parent_service->included_characteristics[attribute_handle].get();
  462. CHECK(remembered_characteristic_);
  463. }
  464. void BluetoothLowEnergyWrapperFake::SimulateGattDescriptor(
  465. std::string device_address,
  466. GattCharacteristic* characteristic,
  467. const BTH_LE_UUID& uuid) {
  468. std::unique_ptr<GattDescriptor> descriptor(new GattDescriptor());
  469. descriptor->descriptor_info.reset(new BTH_LE_GATT_DESCRIPTOR[1]);
  470. descriptor->descriptor_info->DescriptorUuid = uuid;
  471. descriptor->descriptor_info->AttributeHandle =
  472. GenerateAUniqueAttributeHandle(device_address);
  473. characteristic->included_descriptors[std::to_string(
  474. descriptor->descriptor_info->AttributeHandle)] = std::move(descriptor);
  475. }
  476. void BluetoothLowEnergyWrapperFake::AddObserver(Observer* observer) {
  477. observer_ = observer;
  478. }
  479. GattCharacteristic*
  480. BluetoothLowEnergyWrapperFake::GetSimulatedGattCharacteristic(
  481. base::FilePath& service_path,
  482. const PBTH_LE_GATT_CHARACTERISTIC characteristic) {
  483. std::wstring device_address =
  484. ExtractDeviceAddressFromDevicePath(service_path.value());
  485. BLEDevice* target_device = GetSimulatedBLEDevice(
  486. std::string(device_address.begin(), device_address.end()));
  487. if (target_device == nullptr)
  488. return nullptr;
  489. const std::vector<std::string> service_att_handles =
  490. ExtractServiceAttributeHandlesFromDevicePath(service_path.value());
  491. GattService* target_service =
  492. GetSimulatedGattService(target_device, service_att_handles);
  493. if (target_service == nullptr)
  494. return nullptr;
  495. GattCharacteristic* target_characteristic = GetSimulatedGattCharacteristic(
  496. target_service, std::to_string(characteristic->AttributeHandle));
  497. return target_characteristic;
  498. }
  499. USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle(
  500. std::string device_address) {
  501. std::unique_ptr<std::set<USHORT>>& set_of_ushort =
  502. attribute_handle_table_[device_address];
  503. if (set_of_ushort) {
  504. USHORT max_attribute_handle = *set_of_ushort->rbegin();
  505. if (max_attribute_handle < 0xFFFF) {
  506. USHORT new_attribute_handle = max_attribute_handle + 1;
  507. set_of_ushort->insert(new_attribute_handle);
  508. return new_attribute_handle;
  509. } else {
  510. USHORT i = 1;
  511. for (; i < 0xFFFF; i++) {
  512. if (set_of_ushort->find(i) == set_of_ushort->end())
  513. break;
  514. }
  515. if (i >= 0xFFFF)
  516. return 0;
  517. set_of_ushort->insert(i);
  518. return i;
  519. }
  520. }
  521. USHORT smallest_att_handle = 1;
  522. std::set<USHORT>* new_set = new std::set<USHORT>();
  523. new_set->insert(smallest_att_handle);
  524. set_of_ushort.reset(new_set);
  525. return smallest_att_handle;
  526. }
  527. std::wstring BluetoothLowEnergyWrapperFake::GenerateBLEDevicePath(
  528. std::string device_address) {
  529. return std::wstring(device_address.begin(), device_address.end());
  530. }
  531. std::wstring BluetoothLowEnergyWrapperFake::GenerateGattServiceDevicePath(
  532. std::wstring resident_device_path,
  533. USHORT service_attribute_handle) {
  534. std::string sub_path = std::to_string(service_attribute_handle);
  535. return resident_device_path + L"/" +
  536. std::wstring(sub_path.begin(), sub_path.end());
  537. }
  538. std::wstring BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath(
  539. std::wstring path) {
  540. std::size_t found = path.find_first_of('/');
  541. if (found != std::wstring::npos) {
  542. return path.substr(0, found);
  543. }
  544. return path;
  545. }
  546. std::vector<std::string>
  547. BluetoothLowEnergyWrapperFake::ExtractServiceAttributeHandlesFromDevicePath(
  548. std::wstring path) {
  549. std::size_t found = path.find('/');
  550. if (found == std::wstring::npos)
  551. return std::vector<std::string>();
  552. std::vector<std::string> chain_of_att_handle;
  553. while (true) {
  554. std::size_t next_found = path.find(path, found + 1);
  555. if (next_found == std::wstring::npos)
  556. break;
  557. std::wstring att_handle = path.substr(found + 1, next_found);
  558. chain_of_att_handle.push_back(
  559. std::string(att_handle.begin(), att_handle.end()));
  560. found = next_found;
  561. }
  562. std::wstring att_handle = path.substr(found + 1);
  563. chain_of_att_handle.push_back(
  564. std::string(att_handle.begin(), att_handle.end()));
  565. return chain_of_att_handle;
  566. }
  567. std::string BluetoothLowEnergyWrapperFake::BluetoothAddressToCanonicalString(
  568. const BLUETOOTH_ADDRESS& btha) {
  569. std::string result = base::StringPrintf(
  570. "%02X:%02X:%02X:%02X:%02X:%02X", btha.rgBytes[5], btha.rgBytes[4],
  571. btha.rgBytes[3], btha.rgBytes[2], btha.rgBytes[1], btha.rgBytes[0]);
  572. return result;
  573. }
  574. } // namespace win
  575. } // namespace device