fast_pair_gatt_service_client_impl.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573
  1. // Copyright 2021 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 "ash/quick_pair/fast_pair_handshake/fast_pair_gatt_service_client_impl.h"
  5. #include "ash/quick_pair/common/constants.h"
  6. #include "ash/quick_pair/common/fast_pair/fast_pair_metrics.h"
  7. #include "ash/quick_pair/common/logging.h"
  8. #include "ash/quick_pair/fast_pair_handshake/fast_pair_data_encryptor.h"
  9. #include "base/memory/ptr_util.h"
  10. #include "base/strings/string_piece.h"
  11. #include "base/time/time.h"
  12. #include "device/bluetooth/bluetooth_device.h"
  13. #include "device/bluetooth/bluetooth_gatt_connection.h"
  14. #include "device/bluetooth/bluetooth_gatt_notify_session.h"
  15. #include "device/bluetooth/bluetooth_remote_gatt_characteristic.h"
  16. #include "device/bluetooth/bluetooth_remote_gatt_service.h"
  17. #include "device/bluetooth/public/cpp/bluetooth_address.h"
  18. #include "third_party/boringssl/src/include/openssl/rand.h"
  19. namespace {
  20. // We have two UUID possibilities for each characteristic because they changed
  21. // across different Fast Pair versions.
  22. const device::BluetoothUUID kKeyBasedCharacteristicUuidV1("1234");
  23. const device::BluetoothUUID kKeyBasedCharacteristicUuidV2(
  24. "FE2C1234-8366-4814-8EB0-01DE32100BEA");
  25. const device::BluetoothUUID kPasskeyCharacteristicUuidV1("1235");
  26. const device::BluetoothUUID kPasskeyCharacteristicUuidV2(
  27. "FE2C1235-8366-4814-8EB0-01DE32100BEA");
  28. const device::BluetoothUUID kAccountKeyCharacteristicUuidV1("1236");
  29. const device::BluetoothUUID kAccountKeyCharacteristicUuidV2(
  30. "FE2C1236-8366-4814-8EB0-01DE32100BEA");
  31. constexpr uint8_t kProviderAddressStartIndex = 2;
  32. constexpr uint8_t kSeekerAddressStartIndex = 8;
  33. constexpr uint8_t kSeekerPasskey = 0x02;
  34. constexpr uint8_t kAccountKeyStartByte = 0x04;
  35. constexpr base::TimeDelta kGattOperationTimeout = base::Seconds(5);
  36. constexpr const char* ToString(
  37. device::BluetoothGattService::GattErrorCode error_code) {
  38. switch (error_code) {
  39. case device::BluetoothGattService::GATT_ERROR_UNKNOWN:
  40. return "GATT_ERROR_UNKNOWN";
  41. case device::BluetoothGattService::GATT_ERROR_FAILED:
  42. return "GATT_ERROR_FAILED";
  43. case device::BluetoothGattService::GATT_ERROR_IN_PROGRESS:
  44. return "GATT_ERROR_IN_PROGRESS";
  45. case device::BluetoothGattService::GATT_ERROR_INVALID_LENGTH:
  46. return "GATT_ERROR_INVALID_LENGTH";
  47. case device::BluetoothGattService::GATT_ERROR_NOT_PERMITTED:
  48. return "GATT_ERROR_NOT_PERMITTED";
  49. case device::BluetoothGattService::GATT_ERROR_NOT_AUTHORIZED:
  50. return "GATT_ERROR_NOT_AUTHORIZED";
  51. case device::BluetoothGattService::GATT_ERROR_NOT_PAIRED:
  52. return "GATT_ERROR_NOT_PAIRED";
  53. case device::BluetoothGattService::GATT_ERROR_NOT_SUPPORTED:
  54. return "GATT_ERROR_NOT_SUPPORTED";
  55. default:
  56. NOTREACHED();
  57. return "";
  58. }
  59. }
  60. constexpr const char* ToString(
  61. device::BluetoothDevice::ConnectErrorCode error_code) {
  62. switch (error_code) {
  63. case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_CANCELED:
  64. return "ERROR_AUTH_CANCELED";
  65. case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_FAILED:
  66. return "ERROR_AUTH_FAILED";
  67. case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_REJECTED:
  68. return "ERROR_AUTH_REJECTED";
  69. case device::BluetoothDevice::ConnectErrorCode::ERROR_AUTH_TIMEOUT:
  70. return "ERROR_AUTH_TIMEOUT";
  71. case device::BluetoothDevice::ConnectErrorCode::ERROR_FAILED:
  72. return "ERROR_FAILED";
  73. case device::BluetoothDevice::ConnectErrorCode::ERROR_INPROGRESS:
  74. return "ERROR_INPROGRESS";
  75. case device::BluetoothDevice::ConnectErrorCode::ERROR_UNKNOWN:
  76. return "ERROR_UNKNOWN";
  77. case device::BluetoothDevice::ConnectErrorCode::ERROR_UNSUPPORTED_DEVICE:
  78. return "ERROR_UNSUPPORTED_DEVICE";
  79. default:
  80. NOTREACHED();
  81. return "";
  82. }
  83. }
  84. } // namespace
  85. namespace ash {
  86. namespace quick_pair {
  87. // static
  88. FastPairGattServiceClientImpl::Factory*
  89. FastPairGattServiceClientImpl::Factory::g_test_factory_ = nullptr;
  90. // static
  91. std::unique_ptr<FastPairGattServiceClient>
  92. FastPairGattServiceClientImpl::Factory::Create(
  93. device::BluetoothDevice* device,
  94. scoped_refptr<device::BluetoothAdapter> adapter,
  95. base::OnceCallback<void(absl::optional<PairFailure>)>
  96. on_initialized_callback) {
  97. if (g_test_factory_) {
  98. return g_test_factory_->CreateInstance(device, adapter,
  99. std::move(on_initialized_callback));
  100. }
  101. return base::WrapUnique(new FastPairGattServiceClientImpl(
  102. device, adapter, std::move(on_initialized_callback)));
  103. }
  104. // static
  105. void FastPairGattServiceClientImpl::Factory::SetFactoryForTesting(
  106. Factory* g_test_factory) {
  107. g_test_factory_ = g_test_factory;
  108. }
  109. FastPairGattServiceClientImpl::Factory::~Factory() = default;
  110. FastPairGattServiceClientImpl::FastPairGattServiceClientImpl(
  111. device::BluetoothDevice* device,
  112. scoped_refptr<device::BluetoothAdapter> adapter,
  113. base::OnceCallback<void(absl::optional<PairFailure>)>
  114. on_initialized_callback)
  115. : on_initialized_callback_(std::move(on_initialized_callback)),
  116. device_address_(device->GetAddress()),
  117. adapter_(std::move(adapter)) {
  118. adapter_observation_.Observe(adapter_.get());
  119. QP_LOG(INFO) << __func__ << ": Starting the GATT connection to device";
  120. device->CreateGattConnection(
  121. base::BindOnce(&FastPairGattServiceClientImpl::OnGattConnection,
  122. weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()),
  123. kFastPairBluetoothUuid);
  124. gatt_service_discovery_timer_.Start(
  125. FROM_HERE, kGattOperationTimeout,
  126. base::BindOnce(&FastPairGattServiceClientImpl::NotifyInitializedError,
  127. weak_ptr_factory_.GetWeakPtr(),
  128. PairFailure::kGattServiceDiscoveryTimeout));
  129. }
  130. FastPairGattServiceClientImpl::~FastPairGattServiceClientImpl() = default;
  131. void FastPairGattServiceClientImpl::OnGattConnection(
  132. base::TimeTicks gatt_connection_start_time,
  133. std::unique_ptr<device::BluetoothGattConnection> gatt_connection,
  134. absl::optional<device::BluetoothDevice::ConnectErrorCode> error_code) {
  135. RecordGattConnectionResult(/*success=*/!error_code.has_value());
  136. if (error_code) {
  137. QP_LOG(WARNING) << "Error creating GATT connection to device: "
  138. << ToString(error_code.value());
  139. RecordGattConnectionErrorCode(error_code.value());
  140. NotifyInitializedError(PairFailure::kCreateGattConnection);
  141. } else {
  142. QP_LOG(INFO) << __func__
  143. << ": Successful creation of GATT connection to device";
  144. RecordTotalGattConnectionTime(base::TimeTicks::Now() -
  145. gatt_connection_start_time);
  146. gatt_connection_ = std::move(gatt_connection);
  147. }
  148. }
  149. void FastPairGattServiceClientImpl::ClearCurrentState() {
  150. adapter_.reset();
  151. adapter_observation_.Reset();
  152. gatt_connection_.reset();
  153. gatt_service_ = nullptr;
  154. account_key_characteristic_ = nullptr;
  155. key_based_characteristic_ = nullptr;
  156. passkey_characteristic_ = nullptr;
  157. gatt_service_discovery_timer_.Stop();
  158. passkey_notify_session_timer_.Stop();
  159. keybased_notify_session_timer_.Stop();
  160. passkey_write_request_timer_.Stop();
  161. key_based_write_request_timer_.Stop();
  162. bluetooth_gatt_notify_sessions_.clear();
  163. }
  164. void FastPairGattServiceClientImpl::NotifyInitializedError(
  165. PairFailure failure) {
  166. ClearCurrentState();
  167. // This function is invoked in several flows and it is possible for it to run
  168. // twice. In that case, we are ok with the first instance being the one that
  169. // reports the failure. An example is if we timeout waiting for all notify
  170. // sessions to start.
  171. if (on_initialized_callback_)
  172. std::move(on_initialized_callback_).Run(failure);
  173. }
  174. void FastPairGattServiceClientImpl::NotifyWriteRequestError(
  175. PairFailure failure) {
  176. key_based_write_request_timer_.Stop();
  177. DCHECK(key_based_write_response_callback_);
  178. std::move(key_based_write_response_callback_)
  179. .Run(/*response_data=*/{}, failure);
  180. }
  181. void FastPairGattServiceClientImpl::NotifyWritePasskeyError(
  182. PairFailure failure) {
  183. passkey_write_request_timer_.Stop();
  184. DCHECK(passkey_write_response_callback_);
  185. std::move(passkey_write_response_callback_)
  186. .Run(/*response_data=*/{}, failure);
  187. }
  188. void FastPairGattServiceClientImpl::NotifyWriteAccountKeyError(
  189. device::BluetoothGattService::GattErrorCode error) {
  190. DCHECK(write_account_key_callback_);
  191. std::move(write_account_key_callback_).Run(error);
  192. }
  193. void FastPairGattServiceClientImpl::GattDiscoveryCompleteForService(
  194. device::BluetoothAdapter* adapter,
  195. device::BluetoothRemoteGattService* service) {
  196. gatt_service_discovery_timer_.Stop();
  197. // Verify that the discovered service and device are the ones we care about.
  198. if (service->GetUUID() == kFastPairBluetoothUuid &&
  199. service->GetDevice()->GetAddress() == device_address_) {
  200. QP_LOG(INFO) << __func__
  201. << ": Completed discovery for Fast Pair GATT service";
  202. gatt_service_ = service;
  203. FindGattCharacteristicsAndStartNotifySessions();
  204. }
  205. }
  206. std::vector<device::BluetoothRemoteGattCharacteristic*>
  207. FastPairGattServiceClientImpl::GetCharacteristicsByUUIDs(
  208. const device::BluetoothUUID& uuidV1,
  209. const device::BluetoothUUID& uuidV2) {
  210. if (!gatt_service_)
  211. return {};
  212. std::vector<device::BluetoothRemoteGattCharacteristic*> characteristics =
  213. gatt_service_->GetCharacteristicsByUUID(uuidV1);
  214. characteristics = characteristics.size()
  215. ? characteristics
  216. : gatt_service_->GetCharacteristicsByUUID(uuidV2);
  217. return characteristics;
  218. }
  219. void FastPairGattServiceClientImpl::
  220. FindGattCharacteristicsAndStartNotifySessions() {
  221. std::vector<device::BluetoothRemoteGattCharacteristic*>
  222. key_based_characteristics = GetCharacteristicsByUUIDs(
  223. kKeyBasedCharacteristicUuidV1, kKeyBasedCharacteristicUuidV2);
  224. if (key_based_characteristics.empty()) {
  225. NotifyInitializedError(
  226. PairFailure::kKeyBasedPairingCharacteristicDiscovery);
  227. return;
  228. }
  229. std::vector<device::BluetoothRemoteGattCharacteristic*>
  230. passkey_characteristics = GetCharacteristicsByUUIDs(
  231. kPasskeyCharacteristicUuidV1, kPasskeyCharacteristicUuidV2);
  232. if (passkey_characteristics.empty()) {
  233. NotifyInitializedError(PairFailure::kPasskeyCharacteristicDiscovery);
  234. return;
  235. }
  236. std::vector<device::BluetoothRemoteGattCharacteristic*>
  237. account_key_characteristics = GetCharacteristicsByUUIDs(
  238. kAccountKeyCharacteristicUuidV1, kAccountKeyCharacteristicUuidV2);
  239. if (account_key_characteristics.empty()) {
  240. NotifyInitializedError(PairFailure::kAccountKeyCharacteristicDiscovery);
  241. return;
  242. }
  243. account_key_characteristic_ = account_key_characteristics[0];
  244. keybased_notify_session_timer_.Start(
  245. FROM_HERE, kGattOperationTimeout,
  246. base::BindOnce(
  247. &FastPairGattServiceClientImpl::NotifyInitializedError,
  248. weak_ptr_factory_.GetWeakPtr(),
  249. PairFailure::kKeyBasedPairingCharacteristicNotifySessionTimeout));
  250. passkey_notify_session_timer_.Start(
  251. FROM_HERE, kGattOperationTimeout,
  252. base::BindOnce(&FastPairGattServiceClientImpl::NotifyInitializedError,
  253. weak_ptr_factory_.GetWeakPtr(),
  254. PairFailure::kPasskeyCharacteristicNotifySessionTimeout));
  255. key_based_characteristic_ = key_based_characteristics[0];
  256. key_based_characteristic_->StartNotifySession(
  257. base::BindOnce(&FastPairGattServiceClientImpl::OnNotifySession,
  258. weak_ptr_factory_.GetWeakPtr()),
  259. base::BindOnce(&FastPairGattServiceClientImpl::OnGattError,
  260. weak_ptr_factory_.GetWeakPtr(),
  261. PairFailure::kKeyBasedPairingCharacteristicNotifySession));
  262. passkey_characteristic_ = passkey_characteristics[0];
  263. passkey_characteristic_->StartNotifySession(
  264. base::BindOnce(&FastPairGattServiceClientImpl::OnNotifySession,
  265. weak_ptr_factory_.GetWeakPtr()),
  266. base::BindOnce(&FastPairGattServiceClientImpl::OnGattError,
  267. weak_ptr_factory_.GetWeakPtr(),
  268. PairFailure::kPasskeyCharacteristicNotifySession));
  269. }
  270. void FastPairGattServiceClientImpl::OnNotifySession(
  271. std::unique_ptr<device::BluetoothGattNotifySession> session) {
  272. // Check which characteristic the session corresponds to and stop the relevant
  273. // timer.
  274. if (key_based_characteristic_ &&
  275. session->GetCharacteristic() == key_based_characteristic_) {
  276. keybased_notify_session_timer_.Stop();
  277. } else if (passkey_characteristic_ &&
  278. session->GetCharacteristic() == passkey_characteristic_) {
  279. passkey_notify_session_timer_.Stop();
  280. }
  281. bluetooth_gatt_notify_sessions_.push_back(std::move(session));
  282. // Once expected characteristics are notifying, Run the callback with no
  283. // error. Here, we are waiting for both the key based characteristics and the
  284. // pass key characteristics to notify, thus size "2";
  285. if (bluetooth_gatt_notify_sessions_.size() == 2) {
  286. QP_LOG(INFO) << __func__ << ": Finished initializing GATT service";
  287. is_initialized_ = true;
  288. // This check handles the case where a timer for the characteristic's notify
  289. // session fires and the |on_initialized_callback_| callback has been used
  290. // to send a PairFailure, but the notify session is received here
  291. // afterwards.
  292. if (on_initialized_callback_)
  293. std::move(on_initialized_callback_).Run(absl::nullopt);
  294. }
  295. }
  296. void FastPairGattServiceClientImpl::OnGattError(
  297. PairFailure failure,
  298. device::BluetoothGattService::GattErrorCode error) {
  299. QP_LOG(INFO) << __func__ << ": Error: " << ToString(error);
  300. NotifyInitializedError(failure);
  301. }
  302. device::BluetoothRemoteGattService*
  303. FastPairGattServiceClientImpl::gatt_service() {
  304. return gatt_service_;
  305. }
  306. const std::array<uint8_t, kBlockByteSize>
  307. FastPairGattServiceClientImpl::CreateRequest(
  308. uint8_t message_type,
  309. uint8_t flags,
  310. const std::string& provider_address,
  311. const std::string& seekers_address) {
  312. std::array<uint8_t, kBlockByteSize> data_to_write;
  313. RAND_bytes(data_to_write.data(), kBlockByteSize);
  314. data_to_write[0] = message_type;
  315. data_to_write[1] = flags;
  316. std::array<uint8_t, 6> provider_address_bytes;
  317. device::ParseBluetoothAddress(provider_address, provider_address_bytes);
  318. std::copy(provider_address_bytes.begin(), provider_address_bytes.end(),
  319. std::begin(data_to_write) + kProviderAddressStartIndex);
  320. // Seekers address can be empty, in which we would just have the bytes be
  321. // the salt.
  322. if (!seekers_address.empty()) {
  323. std::array<uint8_t, 6> seeker_address_bytes;
  324. device::ParseBluetoothAddress(seekers_address, seeker_address_bytes);
  325. std::copy(seeker_address_bytes.begin(), seeker_address_bytes.end(),
  326. std::begin(data_to_write) + kSeekerAddressStartIndex);
  327. }
  328. return data_to_write;
  329. }
  330. const std::array<uint8_t, kBlockByteSize>
  331. FastPairGattServiceClientImpl::CreatePasskeyBlock(uint8_t message_type,
  332. uint32_t passkey) {
  333. std::array<uint8_t, kBlockByteSize> data_to_write;
  334. RAND_bytes(data_to_write.data(), kBlockByteSize);
  335. data_to_write[0] = message_type;
  336. // Need to convert the uint_32 to uint_8 to use in our data vector.
  337. data_to_write[1] = (passkey & 0x00ff0000) >> 16;
  338. data_to_write[2] = (passkey & 0x0000ff00) >> 8;
  339. data_to_write[3] = passkey & 0x000000ff;
  340. return data_to_write;
  341. }
  342. bool FastPairGattServiceClientImpl::IsConnected() {
  343. return gatt_connection_ && gatt_connection_->IsConnected();
  344. }
  345. void FastPairGattServiceClientImpl::WriteRequestAsync(
  346. uint8_t message_type,
  347. uint8_t flags,
  348. const std::string& provider_address,
  349. const std::string& seekers_address,
  350. FastPairDataEncryptor* fast_pair_data_encryptor,
  351. base::OnceCallback<void(std::vector<uint8_t>, absl::optional<PairFailure>)>
  352. write_response_callback) {
  353. DCHECK(is_initialized_);
  354. DCHECK(!key_based_write_response_callback_);
  355. DCHECK(fast_pair_data_encryptor);
  356. key_based_write_response_callback_ = std::move(write_response_callback);
  357. // We don't need to check that the write response callback exists still before
  358. // we run the callback with the timeout PairFailure if the timer fires a call
  359. // to |NotifyWriteRequestError|. If the callback is used to notify error
  360. // before the timer expires, |NotifyWriteRequestError| will stop the
  361. // corresponding timer before it fires here.
  362. key_based_write_request_timer_.Start(
  363. FROM_HERE, kGattOperationTimeout,
  364. base::BindOnce(&FastPairGattServiceClientImpl::NotifyWriteRequestError,
  365. weak_ptr_factory_.GetWeakPtr(),
  366. PairFailure::kKeyBasedPairingResponseTimeout));
  367. const std::array<uint8_t, kBlockSizeBytes> data_to_write =
  368. fast_pair_data_encryptor->EncryptBytes(CreateRequest(
  369. message_type, flags, provider_address, seekers_address));
  370. std::vector<uint8_t> data_to_write_vec(data_to_write.begin(),
  371. data_to_write.end());
  372. // Append the public version of the private key to the message so the device
  373. // can generate the shared secret to decrypt the message.
  374. const absl::optional<std::array<uint8_t, 64>> public_key =
  375. fast_pair_data_encryptor->GetPublicKey();
  376. if (public_key) {
  377. const std::vector<uint8_t> public_key_vec = std::vector<uint8_t>(
  378. public_key.value().begin(), public_key.value().end());
  379. data_to_write_vec.insert(data_to_write_vec.end(), public_key_vec.begin(),
  380. public_key_vec.end());
  381. }
  382. notify_keybased_start_time_ = base::TimeTicks::Now();
  383. key_based_characteristic_->WriteRemoteCharacteristic(
  384. data_to_write_vec,
  385. device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse,
  386. base::BindOnce(&FastPairGattServiceClientImpl::OnWriteRequest,
  387. weak_ptr_factory_.GetWeakPtr()),
  388. base::BindOnce(&FastPairGattServiceClientImpl::OnWriteRequestError,
  389. weak_ptr_factory_.GetWeakPtr()));
  390. }
  391. void FastPairGattServiceClientImpl::WritePasskeyAsync(
  392. uint8_t message_type,
  393. uint32_t passkey,
  394. FastPairDataEncryptor* fast_pair_data_encryptor,
  395. base::OnceCallback<void(std::vector<uint8_t>, absl::optional<PairFailure>)>
  396. write_response_callback) {
  397. DCHECK(message_type == kSeekerPasskey);
  398. DCHECK(is_initialized_);
  399. passkey_write_response_callback_ = std::move(write_response_callback);
  400. // We don't need to check that the write response callback exists still before
  401. // we run the callback with the timeout PairFailure if the timer fires a call
  402. // to |NotifyWritePasskeyError|. If the callback is used to notify error
  403. // before the timer expires, |NotifyWritePasskeyError| will stop the
  404. // corresponding timer before it fires here.
  405. passkey_write_request_timer_.Start(
  406. FROM_HERE, kGattOperationTimeout,
  407. base::BindOnce(&FastPairGattServiceClientImpl::NotifyWritePasskeyError,
  408. weak_ptr_factory_.GetWeakPtr(),
  409. PairFailure::kPasskeyResponseTimeout));
  410. const std::array<uint8_t, kBlockSizeBytes> data_to_write =
  411. fast_pair_data_encryptor->EncryptBytes(
  412. CreatePasskeyBlock(message_type, passkey));
  413. notify_passkey_start_time_ = base::TimeTicks::Now();
  414. passkey_characteristic_->WriteRemoteCharacteristic(
  415. std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()),
  416. device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse,
  417. base::BindOnce(&FastPairGattServiceClientImpl::OnWritePasskey,
  418. weak_ptr_factory_.GetWeakPtr()),
  419. base::BindOnce(&FastPairGattServiceClientImpl::OnWritePasskeyError,
  420. weak_ptr_factory_.GetWeakPtr()));
  421. }
  422. void FastPairGattServiceClientImpl::WriteAccountKey(
  423. std::array<uint8_t, 16> account_key,
  424. FastPairDataEncryptor* fast_pair_data_encryptor,
  425. base::OnceCallback<
  426. void(absl::optional<device::BluetoothGattService::GattErrorCode>)>
  427. write_account_key_callback) {
  428. DCHECK(account_key[0] == kAccountKeyStartByte);
  429. DCHECK(is_initialized_);
  430. write_account_key_callback_ = std::move(write_account_key_callback);
  431. const std::array<uint8_t, kBlockSizeBytes> data_to_write =
  432. fast_pair_data_encryptor->EncryptBytes(account_key);
  433. account_key_characteristic_->WriteRemoteCharacteristic(
  434. std::vector<uint8_t>(data_to_write.begin(), data_to_write.end()),
  435. device::BluetoothRemoteGattCharacteristic::WriteType::kWithResponse,
  436. base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKey,
  437. weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now()),
  438. base::BindOnce(&FastPairGattServiceClientImpl::OnWriteAccountKeyError,
  439. weak_ptr_factory_.GetWeakPtr()));
  440. }
  441. void FastPairGattServiceClientImpl::GattCharacteristicValueChanged(
  442. device::BluetoothAdapter* adapter,
  443. device::BluetoothRemoteGattCharacteristic* characteristic,
  444. const std::vector<uint8_t>& value) {
  445. DCHECK_EQ(adapter, adapter_.get());
  446. // We check that the callbacks still exists still before we run the
  447. // it with the response bytes to handle the case where the callback
  448. // has already been used to notify error. This can happen if the timer for
  449. // fires with an error, and then the write completes successfully after and
  450. // we get response bytes here.
  451. if (characteristic == key_based_characteristic_ &&
  452. key_based_write_response_callback_) {
  453. key_based_write_request_timer_.Stop();
  454. std::move(key_based_write_response_callback_)
  455. .Run(value, /*failure=*/absl::nullopt);
  456. RecordNotifyKeyBasedCharacteristicTime(base::TimeTicks::Now() -
  457. notify_keybased_start_time_);
  458. } else if (characteristic == passkey_characteristic_ &&
  459. passkey_write_response_callback_) {
  460. passkey_write_request_timer_.Stop();
  461. RecordNotifyPasskeyCharacteristicTime(base::TimeTicks::Now() -
  462. notify_passkey_start_time_);
  463. std::move(passkey_write_response_callback_)
  464. .Run(value, /*failure=*/absl::nullopt);
  465. }
  466. }
  467. void FastPairGattServiceClientImpl::OnWriteRequest() {
  468. QP_LOG(INFO) << __func__;
  469. }
  470. void FastPairGattServiceClientImpl::OnWritePasskey() {
  471. QP_LOG(INFO) << __func__;
  472. }
  473. void FastPairGattServiceClientImpl::OnWriteRequestError(
  474. device::BluetoothGattService::GattErrorCode error) {
  475. QP_LOG(WARNING) << ": Error: " << ToString(error);
  476. RecordWriteRequestGattError(error);
  477. NotifyWriteRequestError(PairFailure::kKeyBasedPairingCharacteristicWrite);
  478. }
  479. void FastPairGattServiceClientImpl::OnWritePasskeyError(
  480. device::BluetoothGattService::GattErrorCode error) {
  481. QP_LOG(WARNING) << ": Error: " << ToString(error);
  482. RecordWritePasskeyGattError(error);
  483. NotifyWritePasskeyError(PairFailure::kPasskeyPairingCharacteristicWrite);
  484. }
  485. void FastPairGattServiceClientImpl::OnWriteAccountKey(
  486. base::TimeTicks write_account_key_start_time) {
  487. QP_LOG(INFO) << __func__;
  488. DCHECK(write_account_key_callback_);
  489. RecordWriteAccountKeyTime(base::TimeTicks::Now() -
  490. write_account_key_start_time);
  491. std::move(write_account_key_callback_).Run(/*failure=*/absl::nullopt);
  492. }
  493. void FastPairGattServiceClientImpl::OnWriteAccountKeyError(
  494. device::BluetoothGattService::GattErrorCode error) {
  495. QP_LOG(WARNING) << __func__ << ": Error: " << ToString(error);
  496. RecordWriteAccountKeyGattError(error);
  497. NotifyWriteAccountKeyError(error);
  498. }
  499. } // namespace quick_pair
  500. } // namespace ash