• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_bluetooth_sapphire/internal/host/gatt/remote_service_manager.h"
16 
17 #include <gmock/gmock.h>
18 
19 #include <vector>
20 
21 #include "pw_async/fake_dispatcher_fixture.h"
22 #include "pw_bluetooth_sapphire/internal/host/att/att.h"
23 #include "pw_bluetooth_sapphire/internal/host/att/error.h"
24 #include "pw_bluetooth_sapphire/internal/host/common/macros.h"
25 #include "pw_bluetooth_sapphire/internal/host/gatt/fake_client.h"
26 #include "pw_bluetooth_sapphire/internal/host/gatt/gatt_defs.h"
27 #include "pw_bluetooth_sapphire/internal/host/testing/test_helpers.h"
28 
29 #pragma clang diagnostic ignored "-Wshadow"
30 
31 namespace bt::gatt::internal {
32 namespace {
33 
34 using namespace ::testing;
35 
36 constexpr UUID kTestServiceUuid1(uint16_t{0xbeef});
37 constexpr UUID kTestServiceUuid2(uint16_t{0xcafe});
38 constexpr UUID kTestServiceUuid3(uint16_t{0xface});
39 constexpr UUID kTestUuid3(uint16_t{0xfefe});
40 constexpr UUID kTestUuid4(uint16_t{0xefef});
41 
42 // Buffers for descriptor responses.
43 // ExtendedProperty::kReliableWrite enabled.
44 const StaticByteBuffer kExtendedPropValue(0x01, 0x00);
45 const StaticByteBuffer kCCCNotifyValue(0x01, 0x00);
46 const StaticByteBuffer kCCCIndicateValue(0x02, 0x00);
47 
48 // Constants used for initializing fake characteristic data.
49 constexpr att::Handle kStart = 1;
50 constexpr att::Handle kCharDecl = 2;
51 constexpr att::Handle kCharValue = 3;
52 constexpr att::Handle kDesc1 = 4;
53 constexpr att::Handle kDesc2 = 5;
54 constexpr att::Handle kEnd = 5;
55 
NopStatusCallback(att::Result<>)56 void NopStatusCallback(att::Result<>) {}
NopMtuCallback(uint16_t)57 void NopMtuCallback(uint16_t) {}
NopValueCallback(const ByteBuffer &,bool)58 void NopValueCallback(const ByteBuffer& /*value*/, bool /*maybe_truncated*/) {}
59 
60 class RemoteServiceManagerTest : public pw::async::test::FakeDispatcherFixture {
61  public:
62   RemoteServiceManagerTest() = default;
63   ~RemoteServiceManagerTest() override = default;
64 
65  protected:
SetUp()66   void SetUp() override {
67     auto client = std::make_unique<testing::FakeClient>(dispatcher());
68     fake_client_ = client.get();
69 
70     mgr_ = std::make_unique<RemoteServiceManager>(std::move(client));
71   }
72 
TearDown()73   void TearDown() override {
74     // Clear any previous expectations that are based on the ATT Write Request,
75     // so that write requests sent during RemoteService::ShutDown() are ignored.
76     if (fake_client_) {
77       fake_client()->set_write_request_callback({});
78     }
79     mgr_ = nullptr;
80   }
81 
82   // Initializes a RemoteService based on |data|.
SetUpFakeService(const ServiceData & data)83   RemoteService::WeakPtr SetUpFakeService(const ServiceData& data) {
84     std::vector<ServiceData> fake_services{{data}};
85     fake_client()->set_services(std::move(fake_services));
86 
87     mgr()->Initialize(NopStatusCallback, NopMtuCallback);
88 
89     ServiceList services;
90     mgr()->ListServices(std::vector<UUID>(),
91                         [&services](auto status, ServiceList cb_services) {
92                           services = std::move(cb_services);
93                         });
94 
95     RunUntilIdle();
96 
97     BT_DEBUG_ASSERT(services.size() == 1u);
98     return services[0];
99   }
100 
SetCharacteristicsAndDescriptors(std::vector<CharacteristicData> fake_chrs,std::vector<DescriptorData> fake_descrs=std::vector<DescriptorData> ())101   void SetCharacteristicsAndDescriptors(
102       std::vector<CharacteristicData> fake_chrs,
103       std::vector<DescriptorData> fake_descrs = std::vector<DescriptorData>()) {
104     fake_client()->set_characteristics(std::move(fake_chrs));
105     fake_client()->set_descriptors(std::move(fake_descrs));
106     fake_client()->set_characteristic_discovery_status(fit::ok());
107   }
108 
109   // Discover the characteristics of |service| based on the given |fake_data|.
SetupCharacteristics(RemoteService::WeakPtr service,std::vector<CharacteristicData> fake_chrs,std::vector<DescriptorData> fake_descrs=std::vector<DescriptorData> ())110   void SetupCharacteristics(
111       RemoteService::WeakPtr service,
112       std::vector<CharacteristicData> fake_chrs,
113       std::vector<DescriptorData> fake_descrs = std::vector<DescriptorData>()) {
114     BT_DEBUG_ASSERT(service.is_alive());
115 
116     SetCharacteristicsAndDescriptors(std::move(fake_chrs),
117                                      std::move(fake_descrs));
118 
119     service->DiscoverCharacteristics([](auto, const auto&) {});
120     RunUntilIdle();
121   }
122 
SetupServiceWithChrcs(const ServiceData & data,std::vector<CharacteristicData> fake_chrs,std::vector<DescriptorData> fake_descrs=std::vector<DescriptorData> ())123   RemoteService::WeakPtr SetupServiceWithChrcs(
124       const ServiceData& data,
125       std::vector<CharacteristicData> fake_chrs,
126       std::vector<DescriptorData> fake_descrs = std::vector<DescriptorData>()) {
127     auto service = SetUpFakeService(data);
128     SetupCharacteristics(service, fake_chrs, fake_descrs);
129     return service;
130   }
131 
132   // Create a fake service with one notifiable characteristic.
SetupNotifiableService()133   RemoteService::WeakPtr SetupNotifiableService() {
134     ServiceData data(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1);
135     auto service = SetUpFakeService(data);
136 
137     CharacteristicData chr(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
138     DescriptorData desc(4, types::kClientCharacteristicConfig);
139     SetupCharacteristics(service, {{chr}}, {{desc}});
140 
141     fake_client()->set_write_request_callback(
142         [&](att::Handle, const auto&, auto status_callback) {
143           status_callback(fit::ok());
144         });
145 
146     RunUntilIdle();
147 
148     return service;
149   }
150 
EnableNotifications(RemoteService::WeakPtr service,CharacteristicHandle chr_id,att::Result<> * out_status,IdType * out_id,RemoteService::ValueCallback callback=NopValueCallback)151   void EnableNotifications(
152       RemoteService::WeakPtr service,
153       CharacteristicHandle chr_id,
154       att::Result<>* out_status,
155       IdType* out_id,
156       RemoteService::ValueCallback callback = NopValueCallback) {
157     BT_DEBUG_ASSERT(out_status);
158     BT_DEBUG_ASSERT(out_id);
159     service->EnableNotifications(chr_id,
160                                  std::move(callback),
161                                  [&](att::Result<> cb_status, IdType cb_id) {
162                                    *out_status = cb_status;
163                                    *out_id = cb_id;
164                                  });
165     RunUntilIdle();
166   }
167 
DestroyServiceManager()168   void DestroyServiceManager() {
169     mgr_.reset();
170     fake_client_ = nullptr;
171   }
172 
mgr() const173   RemoteServiceManager* mgr() const { return mgr_.get(); }
fake_client() const174   testing::FakeClient* fake_client() const { return fake_client_; }
175 
176  private:
177   std::unique_ptr<RemoteServiceManager> mgr_;
178 
179   // The memory is owned by |mgr_|.
180   testing::FakeClient* fake_client_;
181 
182   BT_DISALLOW_COPY_AND_ASSIGN_ALLOW_MOVE(RemoteServiceManagerTest);
183 };
184 
TEST_F(RemoteServiceManagerTest,InitializeNoServices)185 TEST_F(RemoteServiceManagerTest, InitializeNoServices) {
186   ServiceList services;
187   mgr()->set_service_watcher(
188       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
189         services.insert(services.end(), added.begin(), added.end());
190       });
191 
192   att::Result<> status = ToResult(HostError::kFailed);
193   mgr()->Initialize([&status](att::Result<> val) { status = val; },
194                     NopMtuCallback);
195 
196   RunUntilIdle();
197 
198   EXPECT_EQ(fit::ok(), status);
199   EXPECT_TRUE(services.empty());
200 
201   mgr()->ListServices(std::vector<UUID>(),
202                       [&services](auto status, ServiceList cb_services) {
203                         services = std::move(cb_services);
204                       });
205   EXPECT_TRUE(services.empty());
206 }
207 
TEST_F(RemoteServiceManagerTest,Initialize)208 TEST_F(RemoteServiceManagerTest, Initialize) {
209   ServiceData svc1(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
210   ServiceData svc2(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid2);
211   std::vector<ServiceData> fake_services{{svc1, svc2}};
212   fake_client()->set_services(std::move(fake_services));
213 
214   ServiceList services;
215   mgr()->set_service_watcher(
216       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
217         services.insert(services.end(), added.begin(), added.end());
218       });
219 
220   const uint16_t kArbitraryMtu = att::kLEMinMTU + 10;
221   fake_client()->set_server_mtu(kArbitraryMtu);
222 
223   uint16_t new_mtu = 0;
224   auto mtu_cb = [&](uint16_t cb_mtu) { new_mtu = cb_mtu; };
225 
226   att::Result<> status = ToResult(HostError::kFailed);
227   mgr()->Initialize([&status](att::Result<> val) { status = val; },
228                     std::move(mtu_cb));
229 
230   RunUntilIdle();
231 
232   EXPECT_EQ(kArbitraryMtu, new_mtu);
233 
234   EXPECT_EQ(fit::ok(), status);
235   EXPECT_EQ(2u, services.size());
236   EXPECT_EQ(svc1.range_start, services[0]->handle());
237   EXPECT_EQ(svc2.range_start, services[1]->handle());
238   EXPECT_EQ(svc1.type, services[0]->uuid());
239   EXPECT_EQ(svc2.type, services[1]->uuid());
240 }
241 
TEST_F(RemoteServiceManagerTest,InitializeFailure)242 TEST_F(RemoteServiceManagerTest, InitializeFailure) {
243   fake_client()->set_discover_services_callback([](ServiceKind kind) {
244     if (kind == ServiceKind::PRIMARY) {
245       return ToResult(att::ErrorCode::kRequestNotSupported);
246     }
247     return att::Result<>(fit::ok());
248   });
249 
250   ServiceList watcher_services;
251   mgr()->set_service_watcher([&watcher_services](auto /*removed*/,
252                                                  ServiceList added,
253                                                  auto /*modified*/) {
254     watcher_services.insert(watcher_services.end(), added.begin(), added.end());
255   });
256 
257   ServiceList services;
258   mgr()->ListServices(std::vector<UUID>(),
259                       [&services](auto status, ServiceList cb_services) {
260                         services = std::move(cb_services);
261                       });
262   ASSERT_TRUE(services.empty());
263 
264   att::Result<> status = ToResult(HostError::kFailed);
265   mgr()->Initialize([&status](att::Result<> val) { status = val; },
266                     NopMtuCallback);
267 
268   RunUntilIdle();
269 
270   EXPECT_EQ(ToResult(att::ErrorCode::kRequestNotSupported), status);
271   EXPECT_TRUE(services.empty());
272   EXPECT_TRUE(watcher_services.empty());
273 }
274 
TEST_F(RemoteServiceManagerTest,InitializeMtuExchangeNotSupportedSucceeds)275 TEST_F(RemoteServiceManagerTest, InitializeMtuExchangeNotSupportedSucceeds) {
276   ServiceData svc(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
277   fake_client()->set_services({svc});
278   // The MTU exchange is an optional procedure, so if the peer tells us that
279   // they do not support it, we should continue with initialization.
280   fake_client()->set_exchange_mtu_status(
281       ToResult(att::ErrorCode::kRequestNotSupported));
282 
283   ServiceList services;
284   mgr()->set_service_watcher(
285       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
286         services.insert(services.end(), added.begin(), added.end());
287       });
288 
289   std::optional<uint16_t> mtu;
290   auto mtu_cb = [&mtu](uint16_t cb_mtu) { mtu = cb_mtu; };
291 
292   att::Result<> status = ToResult(HostError::kFailed);
293   mgr()->Initialize([&status](att::Result<> val) { status = val; },
294                     std::move(mtu_cb));
295 
296   RunUntilIdle();
297 
298   EXPECT_EQ(fit::ok(), status);
299   ASSERT_EQ(1u, services.size());
300   EXPECT_EQ(svc.range_start, services[0]->handle());
301   EXPECT_EQ(svc.type, services[0]->uuid());
302 
303   // If the MTU exchange isn't supported, "the default MTU shall be used" (v5.3
304   // Vol. 3 Part G 4.3.1)
305   ASSERT_TRUE(mtu.has_value());
306   EXPECT_EQ(att::kLEMinMTU, *mtu);
307 }
308 
TEST_F(RemoteServiceManagerTest,InitializeMtuExchangeFailure)309 TEST_F(RemoteServiceManagerTest, InitializeMtuExchangeFailure) {
310   fake_client()->set_exchange_mtu_status(
311       ToResult(att::ErrorCode::kUnlikelyError));
312 
313   bool mtu_updated = false;
314   auto mtu_cb = [&](uint16_t /*ignore*/) { mtu_updated = true; };
315 
316   att::Result<> status = fit::ok();
317   mgr()->Initialize([&status](att::Result<> val) { status = val; },
318                     std::move(mtu_cb));
319 
320   RunUntilIdle();
321 
322   EXPECT_EQ(ToResult(att::ErrorCode::kUnlikelyError), status);
323   EXPECT_FALSE(mtu_updated);
324 }
325 
TEST_F(RemoteServiceManagerTest,InitializeByUUIDNoServices)326 TEST_F(RemoteServiceManagerTest, InitializeByUUIDNoServices) {
327   ServiceList services;
328   mgr()->set_service_watcher(
329       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
330         services.insert(services.end(), added.begin(), added.end());
331       });
332 
333   att::Result<> status = ToResult(HostError::kFailed);
334   mgr()->Initialize([&status](att::Result<> val) { status = val; },
335                     NopMtuCallback,
336                     {kTestServiceUuid1});
337 
338   RunUntilIdle();
339 
340   EXPECT_EQ(fit::ok(), status);
341   EXPECT_TRUE(services.empty());
342 
343   mgr()->ListServices(std::vector<UUID>(),
344                       [&services](auto status, ServiceList cb_services) {
345                         services = std::move(cb_services);
346                       });
347   EXPECT_TRUE(services.empty());
348 }
349 
TEST_F(RemoteServiceManagerTest,InitializeWithUuids)350 TEST_F(RemoteServiceManagerTest, InitializeWithUuids) {
351   ServiceData svc1(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
352   ServiceData svc2(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid2);
353   ServiceData svc3(ServiceKind::PRIMARY, 3, 3, kTestServiceUuid3);
354   std::vector<ServiceData> fake_services{{svc1, svc2, svc3}};
355   fake_client()->set_services(std::move(fake_services));
356 
357   ServiceList services;
358   mgr()->set_service_watcher(
359       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
360         services.insert(services.end(), added.begin(), added.end());
361       });
362 
363   att::Result<> status = ToResult(HostError::kFailed);
364   mgr()->Initialize([&status](att::Result<> val) { status = val; },
365                     NopMtuCallback,
366                     {kTestServiceUuid1, kTestServiceUuid3});
367 
368   RunUntilIdle();
369 
370   EXPECT_EQ(fit::ok(), status);
371   std::vector<ServiceData> found_services;
372   for (const auto& ptr : services) {
373     found_services.push_back(ptr->info());
374   }
375   EXPECT_THAT(found_services, UnorderedElementsAre(Eq(svc1), Eq(svc3)));
376 }
377 
TEST_F(RemoteServiceManagerTest,InitializeByUUIDFailure)378 TEST_F(RemoteServiceManagerTest, InitializeByUUIDFailure) {
379   fake_client()->set_discover_services_callback([](ServiceKind kind) {
380     if (kind == ServiceKind::PRIMARY) {
381       return ToResult(att::ErrorCode::kRequestNotSupported);
382     }
383     return att::Result<>(fit::ok());
384   });
385 
386   ServiceList watcher_services;
387   mgr()->set_service_watcher([&watcher_services](auto /*removed*/,
388                                                  ServiceList added,
389                                                  auto /*modified*/) {
390     watcher_services.insert(watcher_services.end(), added.begin(), added.end());
391   });
392 
393   ServiceList services;
394   mgr()->ListServices(std::vector<UUID>(),
395                       [&services](auto status, ServiceList cb_services) {
396                         services = std::move(cb_services);
397                       });
398   ASSERT_TRUE(services.empty());
399 
400   att::Result<> status = ToResult(HostError::kFailed);
401   mgr()->Initialize([&status](att::Result<> val) { status = val; },
402                     NopMtuCallback,
403                     {kTestServiceUuid1});
404 
405   RunUntilIdle();
406 
407   EXPECT_EQ(ToResult(att::ErrorCode::kRequestNotSupported), status);
408   EXPECT_TRUE(services.empty());
409   EXPECT_TRUE(watcher_services.empty());
410 }
411 
TEST_F(RemoteServiceManagerTest,InitializeSecondaryServices)412 TEST_F(RemoteServiceManagerTest, InitializeSecondaryServices) {
413   ServiceData svc(ServiceKind::SECONDARY, 1, 1, kTestServiceUuid1);
414   std::vector<ServiceData> fake_services{{svc}};
415   fake_client()->set_services(std::move(fake_services));
416 
417   ServiceList services;
418   mgr()->set_service_watcher(
419       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
420         services.insert(services.end(), added.begin(), added.end());
421       });
422 
423   att::Result<> status = ToResult(HostError::kFailed);
424   mgr()->Initialize([&status](att::Result<> val) { status = val; },
425                     NopMtuCallback);
426 
427   RunUntilIdle();
428 
429   EXPECT_EQ(fit::ok(), status);
430   ASSERT_EQ(1u, services.size());
431   EXPECT_EQ(svc.range_start, services[0]->handle());
432   EXPECT_EQ(svc.type, services[0]->uuid());
433   EXPECT_EQ(ServiceKind::SECONDARY, services[0]->info().kind);
434 }
435 
TEST_F(RemoteServiceManagerTest,InitializePrimaryAndSecondaryServices)436 TEST_F(RemoteServiceManagerTest, InitializePrimaryAndSecondaryServices) {
437   ServiceData svc1(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
438   ServiceData svc2(ServiceKind::SECONDARY, 2, 2, kTestServiceUuid2);
439   std::vector<ServiceData> fake_services{{svc1, svc2}};
440   fake_client()->set_services(std::move(fake_services));
441 
442   ServiceList services;
443   mgr()->set_service_watcher(
444       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
445         services.insert(services.end(), added.begin(), added.end());
446       });
447 
448   att::Result<> status = ToResult(HostError::kFailed);
449   mgr()->Initialize([&status](att::Result<> val) { status = val; },
450                     NopMtuCallback);
451 
452   RunUntilIdle();
453 
454   EXPECT_EQ(fit::ok(), status);
455   EXPECT_EQ(2u, services.size());
456   EXPECT_EQ(ServiceKind::PRIMARY, services[0]->info().kind);
457   EXPECT_EQ(ServiceKind::SECONDARY, services[1]->info().kind);
458 }
459 
TEST_F(RemoteServiceManagerTest,InitializePrimaryAndSecondaryServicesOutOfOrder)460 TEST_F(RemoteServiceManagerTest,
461        InitializePrimaryAndSecondaryServicesOutOfOrder) {
462   // RemoteServiceManager discovers primary services first, followed by
463   // secondary services. Test that the results are stored and represented in the
464   // correct order when a secondary service precedes a primary service.
465   ServiceData svc1(ServiceKind::SECONDARY, 1, 1, kTestServiceUuid1);
466   ServiceData svc2(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid2);
467   fake_client()->set_services({{svc1, svc2}});
468 
469   ServiceList services;
470   mgr()->set_service_watcher(
471       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
472         services.insert(services.end(), added.begin(), added.end());
473       });
474 
475   att::Result<> status = ToResult(HostError::kFailed);
476   mgr()->Initialize([&status](att::Result<> val) { status = val; },
477                     NopMtuCallback);
478   RunUntilIdle();
479 
480   EXPECT_EQ(fit::ok(), status);
481   EXPECT_EQ(2u, services.size());
482   EXPECT_EQ(ServiceKind::SECONDARY, services[0]->info().kind);
483   EXPECT_EQ(ServiceKind::PRIMARY, services[1]->info().kind);
484 }
485 
486 // Tests that an ATT error that occurs during secondary service aborts
487 // initialization.
TEST_F(RemoteServiceManagerTest,InitializeSecondaryServicesFailure)488 TEST_F(RemoteServiceManagerTest, InitializeSecondaryServicesFailure) {
489   fake_client()->set_discover_services_callback([](ServiceKind kind) {
490     if (kind == ServiceKind::SECONDARY) {
491       return ToResult(att::ErrorCode::kRequestNotSupported);
492     }
493     return att::Result<>(fit::ok());
494   });
495 
496   ServiceList services;
497   mgr()->set_service_watcher(
498       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
499         services.insert(services.end(), added.begin(), added.end());
500       });
501 
502   att::Result<> status = fit::ok();
503   mgr()->Initialize([&status](att::Result<> val) { status = val; },
504                     NopMtuCallback);
505   RunUntilIdle();
506 
507   EXPECT_EQ(ToResult(att::ErrorCode::kRequestNotSupported), status);
508   EXPECT_TRUE(services.empty());
509 }
510 
511 // Tests that the "unsupported group type" error is treated as a failure for
512 // primary services.
TEST_F(RemoteServiceManagerTest,InitializePrimaryServicesErrorUnsupportedGroupType)513 TEST_F(RemoteServiceManagerTest,
514        InitializePrimaryServicesErrorUnsupportedGroupType) {
515   fake_client()->set_discover_services_callback([](ServiceKind kind) {
516     if (kind == ServiceKind::PRIMARY) {
517       return ToResult(att::ErrorCode::kUnsupportedGroupType);
518     }
519     return att::Result<>(fit::ok());
520   });
521 
522   ServiceList services;
523   mgr()->set_service_watcher(
524       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
525         services.insert(services.end(), added.begin(), added.end());
526       });
527 
528   att::Result<> status = fit::ok();
529   mgr()->Initialize([&status](att::Result<> val) { status = val; },
530                     NopMtuCallback);
531   RunUntilIdle();
532 
533   EXPECT_EQ(ToResult(att::ErrorCode::kUnsupportedGroupType), status);
534   EXPECT_TRUE(services.empty());
535 }
536 
537 // Tests that the "unsupported group type" error is NOT treated as a failure for
538 // secondary services.
TEST_F(RemoteServiceManagerTest,InitializeSecondaryServicesErrorUnsupportedGroupTypeIsIgnored)539 TEST_F(RemoteServiceManagerTest,
540        InitializeSecondaryServicesErrorUnsupportedGroupTypeIsIgnored) {
541   ServiceData svc1(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
542   fake_client()->set_services({{svc1}});
543   fake_client()->set_discover_services_callback([](ServiceKind kind) {
544     if (kind == ServiceKind::SECONDARY) {
545       return ToResult(att::ErrorCode::kUnsupportedGroupType);
546     }
547     return att::Result<>(fit::ok());
548   });
549 
550   ServiceList services;
551   mgr()->set_service_watcher(
552       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
553         services.insert(services.end(), added.begin(), added.end());
554       });
555 
556   att::Result<> status = fit::ok();
557   mgr()->Initialize([&status](att::Result<> val) { status = val; },
558                     NopMtuCallback);
559   RunUntilIdle();
560 
561   EXPECT_EQ(fit::ok(), status);
562   ASSERT_EQ(1u, services.size());
563   EXPECT_EQ(svc1, services[0]->info());
564 }
565 
TEST_F(RemoteServiceManagerTest,ListServicesBeforeInit)566 TEST_F(RemoteServiceManagerTest, ListServicesBeforeInit) {
567   ServiceData svc(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
568   std::vector<ServiceData> fake_services{{svc}};
569   fake_client()->set_services(std::move(fake_services));
570 
571   ServiceList services;
572   mgr()->ListServices(std::vector<UUID>(),
573                       [&services](auto status, ServiceList cb_services) {
574                         services = std::move(cb_services);
575                       });
576   EXPECT_TRUE(services.empty());
577 
578   att::Result<> status = ToResult(HostError::kFailed);
579   mgr()->Initialize([&status](att::Result<> val) { status = val; },
580                     NopMtuCallback);
581 
582   RunUntilIdle();
583 
584   EXPECT_EQ(fit::ok(), status);
585   ASSERT_EQ(1u, services.size());
586   EXPECT_EQ(svc.range_start, services[0]->handle());
587   EXPECT_EQ(svc.type, services[0]->uuid());
588 }
589 
TEST_F(RemoteServiceManagerTest,ListServicesAfterInit)590 TEST_F(RemoteServiceManagerTest, ListServicesAfterInit) {
591   ServiceData svc(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
592   std::vector<ServiceData> fake_services{{svc}};
593   fake_client()->set_services(std::move(fake_services));
594 
595   att::Result<> status = ToResult(HostError::kFailed);
596   mgr()->Initialize([&status](att::Result<> val) { status = val; },
597                     NopMtuCallback);
598 
599   RunUntilIdle();
600 
601   ASSERT_EQ(fit::ok(), status);
602 
603   ServiceList services;
604   mgr()->ListServices(std::vector<UUID>(),
605                       [&services](auto status, ServiceList cb_services) {
606                         services = std::move(cb_services);
607                       });
608   ASSERT_EQ(1u, services.size());
609   EXPECT_EQ(svc.range_start, services[0]->handle());
610   EXPECT_EQ(svc.type, services[0]->uuid());
611 }
612 
TEST_F(RemoteServiceManagerTest,ListServicesByUuid)613 TEST_F(RemoteServiceManagerTest, ListServicesByUuid) {
614   std::vector<UUID> uuids{kTestServiceUuid1};
615 
616   ServiceData svc1(ServiceKind::PRIMARY, 1, 1, kTestServiceUuid1);
617   ServiceData svc2(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid2);
618   std::vector<ServiceData> fake_services{{svc1, svc2}};
619   fake_client()->set_services(std::move(fake_services));
620 
621   ServiceList service_watcher_services;
622   mgr()->set_service_watcher([&service_watcher_services](auto /*removed*/,
623                                                          ServiceList added,
624                                                          auto /*modified*/) {
625     service_watcher_services.insert(
626         service_watcher_services.end(), added.begin(), added.end());
627   });
628 
629   att::Result<> list_services_status = fit::ok();
630   ServiceList list_services;
631   mgr()->ListServices(std::move(uuids),
632                       [&](att::Result<> cb_status, ServiceList cb_services) {
633                         list_services_status = cb_status;
634                         list_services = std::move(cb_services);
635                       });
636   ASSERT_TRUE(service_watcher_services.empty());
637 
638   att::Result<> status = ToResult(HostError::kFailed);
639   mgr()->Initialize([&status](att::Result<> val) { status = val; },
640                     NopMtuCallback);
641 
642   RunUntilIdle();
643   EXPECT_EQ(fit::ok(), status);
644   EXPECT_EQ(fit::ok(), list_services_status);
645   // Only svc1 has a type in |uuids|.
646   EXPECT_EQ(1u, list_services.size());
647   EXPECT_EQ(svc1.range_start, list_services[0]->handle());
648   EXPECT_EQ(svc1.type, list_services[0]->uuid());
649   // All services should be discovered and returned to service watcher because
650   // Initialize() was not called with a list of uuids to discover.
651   EXPECT_EQ(2u, service_watcher_services.size());
652 }
653 
TEST_F(RemoteServiceManagerTest,DiscoverCharacteristicsSuccess)654 TEST_F(RemoteServiceManagerTest, DiscoverCharacteristicsSuccess) {
655   auto data = ServiceData(ServiceKind::PRIMARY, 1, 5, kTestServiceUuid1);
656   auto service = SetUpFakeService(data);
657 
658   CharacteristicData fake_chrc1(0, std::nullopt, 2, 3, kTestUuid3);
659   CharacteristicData fake_chrc2(0, std::nullopt, 4, 5, kTestUuid4);
660   std::vector<CharacteristicData> fake_chrcs{{fake_chrc1, fake_chrc2}};
661   fake_client()->set_characteristics(std::move(fake_chrcs));
662 
663   std::map<
664       CharacteristicHandle,
665       std::pair<CharacteristicData, std::map<DescriptorHandle, DescriptorData>>>
666       expected = {{CharacteristicHandle(3), {fake_chrc1, {}}},
667                   {CharacteristicHandle(5), {fake_chrc2, {}}}};
668 
669   att::Result<> status1 = ToResult(HostError::kFailed);
670 
671   auto cb = [expected](att::Result<>* status) {
672     return [status, expected](att::Result<> cb_status, const auto& chrcs) {
673       *status = cb_status;
674       EXPECT_EQ(expected, chrcs);
675     };
676   };
677 
678   service->DiscoverCharacteristics(
679       [&](att::Result<> cb_status, const auto& chrcs) {
680         status1 = cb_status;
681         EXPECT_EQ(expected, chrcs);
682       });
683 
684   // Queue a second request.
685   att::Result<> status2 = ToResult(HostError::kFailed);
686   service->DiscoverCharacteristics(
687       [&](att::Result<> cb_status, const auto& chrcs) {
688         status2 = cb_status;
689         EXPECT_EQ(expected, chrcs);
690       });
691 
692   RunUntilIdle();
693   // Only one ATT request should have been made.
694   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
695   EXPECT_TRUE(service->IsDiscovered());
696   EXPECT_EQ(fit::ok(), status1);
697   EXPECT_EQ(fit::ok(), status2);
698   EXPECT_EQ(data.range_start,
699             fake_client()->last_chrc_discovery_start_handle());
700   EXPECT_EQ(data.range_end, fake_client()->last_chrc_discovery_end_handle());
701 
702   // Request discovery again. This should succeed without an ATT request.
703   status1 = ToResult(HostError::kFailed);
704   service->DiscoverCharacteristics(
705       [&status1](att::Result<> cb_status, const auto&) {
706         status1 = cb_status;
707       });
708 
709   RunUntilIdle();
710 
711   EXPECT_EQ(fit::ok(), status1);
712   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
713   EXPECT_TRUE(service->IsDiscovered());
714 }
715 
TEST_F(RemoteServiceManagerTest,DiscoverCharacteristicsError)716 TEST_F(RemoteServiceManagerTest, DiscoverCharacteristicsError) {
717   auto service = SetUpFakeService(
718       ServiceData(ServiceKind::PRIMARY, 1, 5, kTestServiceUuid1));
719 
720   CharacteristicData chrc1(0, std::nullopt, 2, 3, kTestUuid3);
721   CharacteristicData chrc2(0, std::nullopt, 4, 5, kTestUuid4);
722   std::vector<CharacteristicData> fake_chrcs{{chrc1, chrc2}};
723   fake_client()->set_characteristics(std::move(fake_chrcs));
724 
725   fake_client()->set_characteristic_discovery_status(
726       ToResult(HostError::kNotSupported));
727 
728   att::Result<> status1 = fit::ok();
729   service->DiscoverCharacteristics(
730       [&](att::Result<> cb_status, const auto& chrcs) {
731         status1 = cb_status;
732         EXPECT_TRUE(chrcs.empty());
733       });
734 
735   // Queue a second request.
736   att::Result<> status2 = fit::ok();
737   service->DiscoverCharacteristics(
738       [&](att::Result<> cb_status, const auto& chrcs) {
739         status2 = cb_status;
740         EXPECT_TRUE(chrcs.empty());
741       });
742 
743   RunUntilIdle();
744   // Only one request should have been made.
745   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
746   EXPECT_FALSE(service->IsDiscovered());
747   EXPECT_EQ(ToResult(HostError::kNotSupported), status1);
748   EXPECT_EQ(ToResult(HostError::kNotSupported), status2);
749 }
750 
751 // Discover descriptors of a service with one characteristic.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsOfOneSuccess)752 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsOfOneSuccess) {
753   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
754   auto service = SetUpFakeService(data);
755 
756   CharacteristicData fake_chrc(
757       0, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
758   fake_client()->set_characteristics({{fake_chrc}});
759 
760   DescriptorData fake_desc1(kDesc1, kTestUuid3);
761   DescriptorData fake_desc2(kDesc2, kTestUuid4);
762   fake_client()->set_descriptors({{fake_desc1, fake_desc2}});
763 
764   att::Result<> status = ToResult(HostError::kFailed);
765   service->DiscoverCharacteristics(
766       [&](att::Result<> cb_status, const auto chrcs) {
767         status = cb_status;
768         EXPECT_EQ(1u, chrcs.size());
769 
770         std::map<CharacteristicHandle,
771                  std::pair<CharacteristicData,
772                            std::map<DescriptorHandle, DescriptorData>>>
773             expected = {
774                 {CharacteristicHandle(kCharValue),
775                  {fake_chrc, {{kDesc1, fake_desc1}, {kDesc2, fake_desc2}}}}};
776 
777         EXPECT_EQ(expected, chrcs);
778       });
779 
780   RunUntilIdle();
781   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
782   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
783   EXPECT_TRUE(service->IsDiscovered());
784   EXPECT_EQ(fit::ok(), status);
785   EXPECT_EQ(kDesc1, fake_client()->last_desc_discovery_start_handle());
786   EXPECT_EQ(kEnd, fake_client()->last_desc_discovery_end_handle());
787 }
788 
789 // Discover descriptors of a service with one characteristic.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsOfOneError)790 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsOfOneError) {
791   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
792   auto service = SetUpFakeService(data);
793 
794   CharacteristicData fake_chrc(
795       0, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
796   fake_client()->set_characteristics({{fake_chrc}});
797 
798   DescriptorData fake_desc1(kDesc1, kTestUuid3);
799   DescriptorData fake_desc2(kDesc2, kTestUuid4);
800   fake_client()->set_descriptors({{fake_desc1, fake_desc2}});
801   fake_client()->set_descriptor_discovery_status(
802       ToResult(HostError::kNotSupported));
803 
804   att::Result<> status = fit::ok();
805   service->DiscoverCharacteristics(
806       [&](att::Result<> cb_status, const auto& chrcs) {
807         status = cb_status;
808         EXPECT_TRUE(chrcs.empty());
809       });
810 
811   RunUntilIdle();
812   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
813   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
814   EXPECT_FALSE(service->IsDiscovered());
815   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
816 }
817 
818 // Discover descriptors of a service with multiple characteristics
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsOfMultipleSuccess)819 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleSuccess) {
820   // Has one descriptor
821   CharacteristicData fake_char1(0, std::nullopt, 2, 3, kTestUuid3);
822   DescriptorData fake_desc1(4, kTestUuid4);
823 
824   // Has no descriptors
825   CharacteristicData fake_char2(0, std::nullopt, 5, 6, kTestUuid3);
826 
827   // Has two descriptors
828   CharacteristicData fake_char3(0, std::nullopt, 7, 8, kTestUuid3);
829   DescriptorData fake_desc2(9, kTestUuid4);
830   DescriptorData fake_desc3(10, kTestUuid4);
831 
832   ServiceData data(
833       ServiceKind::PRIMARY, 1, fake_desc3.handle, kTestServiceUuid1);
834   auto service = SetUpFakeService(data);
835   fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
836   fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});
837 
838   att::Result<> status = ToResult(HostError::kFailed);
839   service->DiscoverCharacteristics([&](att::Result<> cb_status,
840                                        const auto& chrcs) {
841     status = cb_status;
842 
843     std::map<CharacteristicHandle,
844              std::pair<CharacteristicData,
845                        std::map<DescriptorHandle, DescriptorData>>>
846         expected = {{CharacteristicHandle(3), {fake_char1, {{4, fake_desc1}}}},
847                     {CharacteristicHandle(6), {fake_char2, {}}},
848                     {CharacteristicHandle(8),
849                      {fake_char3, {{9, fake_desc2}, {10, fake_desc3}}}}};
850 
851     EXPECT_EQ(expected, chrcs);
852   });
853 
854   RunUntilIdle();
855   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
856   // There should have been two descriptor discovery requests as discovery
857   // should have been skipped for characteristic #2 due to its handles.
858   EXPECT_EQ(2u, fake_client()->desc_discovery_count());
859   EXPECT_TRUE(service->IsDiscovered());
860   EXPECT_EQ(fit::ok(), status);
861 }
862 
863 // Discover descriptors of a service with multiple characteristics. The first
864 // request results in an error though others succeed.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsOfMultipleEarlyFail)865 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleEarlyFail) {
866   // Has one descriptor
867   CharacteristicData fake_char1(0, std::nullopt, 2, 3, kTestUuid3);
868   DescriptorData fake_desc1(4, kTestUuid4);
869 
870   // Has no descriptors
871   CharacteristicData fake_char2(0, std::nullopt, 5, 6, kTestUuid3);
872 
873   // Has two descriptors
874   CharacteristicData fake_char3(0, std::nullopt, 7, 8, kTestUuid3);
875   DescriptorData fake_desc2(9, kTestUuid4);
876   DescriptorData fake_desc3(10, kTestUuid4);
877 
878   ServiceData data(
879       ServiceKind::PRIMARY, 1, fake_desc3.handle, kTestServiceUuid1);
880   auto service = SetUpFakeService(data);
881   fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
882   fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});
883 
884   // The first request will fail
885   fake_client()->set_descriptor_discovery_status(
886       ToResult(HostError::kNotSupported), 1);
887 
888   att::Result<> status = ToResult(HostError::kFailed);
889   service->DiscoverCharacteristics(
890       [&](att::Result<> cb_status, const auto& chrcs) {
891         status = cb_status;
892         EXPECT_TRUE(chrcs.empty());
893       });
894 
895   RunUntilIdle();
896   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
897   // There should have been two descriptor discovery requests as discovery
898   // should have been skipped for characteristic #2 due to its handles.
899   EXPECT_EQ(2u, fake_client()->desc_discovery_count());
900   EXPECT_FALSE(service->IsDiscovered());
901   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
902 }
903 
904 // Discover descriptors of a service with multiple characteristics. The last
905 // request results in an error while the preceding ones succeed.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsOfMultipleLateFail)906 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsOfMultipleLateFail) {
907   // Has one descriptor
908   CharacteristicData fake_char1(0, std::nullopt, 2, 3, kTestUuid3);
909   DescriptorData fake_desc1(4, kTestUuid4);
910 
911   // Has no descriptors
912   CharacteristicData fake_char2(0, std::nullopt, 5, 6, kTestUuid3);
913 
914   // Has two descriptors
915   CharacteristicData fake_char3(0, std::nullopt, 7, 8, kTestUuid3);
916   DescriptorData fake_desc2(9, kTestUuid4);
917   DescriptorData fake_desc3(10, kTestUuid4);
918 
919   ServiceData data(
920       ServiceKind::PRIMARY, 1, fake_desc3.handle, kTestServiceUuid1);
921   auto service = SetUpFakeService(data);
922   fake_client()->set_characteristics({{fake_char1, fake_char2, fake_char3}});
923   fake_client()->set_descriptors({{fake_desc1, fake_desc2, fake_desc3}});
924 
925   // The last request will fail
926   fake_client()->set_descriptor_discovery_status(
927       ToResult(HostError::kNotSupported), 2);
928 
929   att::Result<> status = ToResult(HostError::kFailed);
930   service->DiscoverCharacteristics(
931       [&](att::Result<> cb_status, const auto& chrcs) {
932         status = cb_status;
933         EXPECT_TRUE(chrcs.empty());
934       });
935 
936   RunUntilIdle();
937   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
938   // There should have been two descriptor discovery requests as discovery
939   // should have been skipped for characteristic #2 due to its handles.
940   EXPECT_EQ(2u, fake_client()->desc_discovery_count());
941   EXPECT_FALSE(service->IsDiscovered());
942   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
943 }
944 
945 // Discover descriptors of a service with extended properties set.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsWithExtendedPropertiesSuccess)946 TEST_F(RemoteServiceManagerTest,
947        DiscoverDescriptorsWithExtendedPropertiesSuccess) {
948   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
949   auto service = SetUpFakeService(data);
950 
951   // The ExtendedProperties of the characteristic is set.
952   const Properties props = Property::kExtendedProperties;
953   CharacteristicData fake_chrc(
954       props, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
955 
956   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
957   DescriptorData fake_desc2(kDesc2, kTestUuid4);
958 
959   SetCharacteristicsAndDescriptors({fake_chrc}, {fake_desc1, fake_desc2});
960 
961   // The callback should be triggered once to read the value of the descriptor
962   // containing the ExtendedProperties bitfield.
963   size_t read_cb_count = 0;
964   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
965     EXPECT_EQ(kDesc1, handle);
966     callback(fit::ok(), kExtendedPropValue, /*maybe_truncated=*/false);
967     read_cb_count++;
968   };
969   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
970 
971   att::Result<> status = ToResult(HostError::kFailed);
972   service->DiscoverCharacteristics([&](att::Result<> cb_status,
973                                        const auto chrcs) {
974     status = cb_status;
975     EXPECT_EQ(1u, chrcs.size());
976 
977     CharacteristicData expected_chrc(
978         props, kReliableWrite, kCharDecl, kCharValue, kTestUuid3);
979     std::map<CharacteristicHandle,
980              std::pair<CharacteristicData,
981                        std::map<DescriptorHandle, DescriptorData>>>
982         expected = {
983             {CharacteristicHandle(kCharValue),
984              {expected_chrc, {{kDesc1, fake_desc1}, {kDesc2, fake_desc2}}}}};
985     EXPECT_EQ(expected, chrcs);
986 
987     // Validate that the ExtendedProperties have been written to the |chrcs|
988     // returned in the callback.
989     CharacteristicData chrc_data =
990         chrcs.at(CharacteristicHandle(kCharValue)).first;
991     EXPECT_TRUE(chrc_data.extended_properties.has_value());
992     EXPECT_EQ(ExtendedProperty::kReliableWrite,
993               chrc_data.extended_properties.value());
994   });
995 
996   RunUntilIdle();
997   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
998   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
999   EXPECT_EQ(1u, read_cb_count);
1000   EXPECT_TRUE(service->IsDiscovered());
1001   EXPECT_EQ(fit::ok(), status);
1002   EXPECT_EQ(kDesc1, fake_client()->last_desc_discovery_start_handle());
1003   EXPECT_EQ(kEnd, fake_client()->last_desc_discovery_end_handle());
1004 }
1005 
1006 // Discover descriptors of a service that doesn't contain the ExtendedProperties
1007 // bit set, but with a descriptor containing an ExtendedProperty value. This is
1008 // not invalid, as per the spec, and so discovery shouldn't fail.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsExtendedPropertiesNotSet)1009 TEST_F(RemoteServiceManagerTest, DiscoverDescriptorsExtendedPropertiesNotSet) {
1010   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
1011   auto service = SetUpFakeService(data);
1012 
1013   // The ExtendedProperties of the characteristic is not set.
1014   CharacteristicData fake_chrc(
1015       0, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
1016   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
1017   SetCharacteristicsAndDescriptors({fake_chrc}, {fake_desc1});
1018 
1019   // Callback should not be executed.
1020   size_t read_cb_count = 0;
1021   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
1022     callback(fit::ok(), kExtendedPropValue, /*maybe_truncated=*/false);
1023     read_cb_count++;
1024   };
1025   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
1026 
1027   att::Result<> status = ToResult(HostError::kFailed);
1028   service->DiscoverCharacteristics(
1029       [&](att::Result<> cb_status, const auto chrcs) {
1030         status = cb_status;
1031         EXPECT_EQ(1u, chrcs.size());
1032 
1033         std::map<CharacteristicHandle,
1034                  std::pair<CharacteristicData,
1035                            std::map<DescriptorHandle, DescriptorData>>>
1036             expected = {{CharacteristicHandle(kCharValue),
1037                          {fake_chrc, {{kDesc1, fake_desc1}}}}};
1038 
1039         EXPECT_EQ(expected, chrcs);
1040 
1041         // Validate that the ExtendedProperties has not been updated.
1042         CharacteristicData chrc_data =
1043             chrcs.at(CharacteristicHandle(kCharValue)).first;
1044         EXPECT_FALSE(chrc_data.extended_properties.has_value());
1045       });
1046 
1047   RunUntilIdle();
1048   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
1049   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
1050   EXPECT_EQ(0u, read_cb_count);
1051   EXPECT_TRUE(service->IsDiscovered());
1052   EXPECT_EQ(fit::ok(), status);
1053 }
1054 
1055 // Discover descriptors of a service with two descriptors containing
1056 // ExtendedProperties. This is invalid, and discovery should fail.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsMultipleExtendedPropertiesError)1057 TEST_F(RemoteServiceManagerTest,
1058        DiscoverDescriptorsMultipleExtendedPropertiesError) {
1059   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
1060   auto service = SetUpFakeService(data);
1061 
1062   // The ExtendedProperties of the characteristic is set.
1063   const Properties props = Property::kExtendedProperties;
1064   CharacteristicData fake_chrc(
1065       props, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
1066   // Two descriptors with ExtProperties.
1067   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
1068   DescriptorData fake_desc2(kDesc2, types::kCharacteristicExtProperties);
1069   SetCharacteristicsAndDescriptors({fake_chrc}, {fake_desc1, fake_desc2});
1070 
1071   size_t read_cb_count = 0;
1072   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
1073     callback(fit::ok(), kExtendedPropValue, /*maybe_truncated=*/false);
1074     read_cb_count++;
1075   };
1076   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
1077 
1078   att::Result<> status = ToResult(HostError::kFailed);
1079   service->DiscoverCharacteristics(
1080       [&](att::Result<> cb_status, const auto chrcs) {
1081         status = cb_status;
1082         EXPECT_TRUE(chrcs.empty());
1083       });
1084 
1085   RunUntilIdle();
1086   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
1087   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
1088   EXPECT_EQ(0u, read_cb_count);
1089   EXPECT_FALSE(service->IsDiscovered());
1090   EXPECT_EQ(ToResult(HostError::kFailed), status);
1091 }
1092 
1093 // Discover descriptors of a service with ExtendedProperties set, but with
1094 // an error when reading the descriptor value. Discovery should fail.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsExtendedPropertiesReadDescValueError)1095 TEST_F(RemoteServiceManagerTest,
1096        DiscoverDescriptorsExtendedPropertiesReadDescValueError) {
1097   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
1098   auto service = SetUpFakeService(data);
1099 
1100   // The ExtendedProperties of the characteristic is set.
1101   const Properties props = Property::kExtendedProperties;
1102   CharacteristicData fake_chrc(
1103       props, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
1104   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
1105   DescriptorData fake_desc2(kDesc2, kTestUuid4);
1106   SetCharacteristicsAndDescriptors({fake_chrc}, {fake_desc1, fake_desc2});
1107 
1108   // The callback should be triggered once to read the value of the descriptor
1109   // containing the ExtendedProperties bitfield.
1110   size_t read_cb_count = 0;
1111   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
1112     EXPECT_EQ(kDesc1, handle);
1113     callback(ToResult(att::ErrorCode::kReadNotPermitted),
1114              BufferView(),
1115              /*maybe_truncated=*/false);
1116     read_cb_count++;
1117   };
1118   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
1119 
1120   att::Result<> status = ToResult(HostError::kFailed);
1121   service->DiscoverCharacteristics(
1122       [&](att::Result<> cb_status, const auto chrcs) {
1123         status = cb_status;
1124         EXPECT_TRUE(chrcs.empty());
1125       });
1126 
1127   RunUntilIdle();
1128 
1129   EXPECT_EQ(1u, read_cb_count);
1130   EXPECT_FALSE(service->IsDiscovered());
1131   ASSERT_TRUE(status.is_error());
1132   EXPECT_TRUE(status.error_value().is_protocol_error());
1133 }
1134 
1135 // Discover descriptors of a service with ExtendedProperties set, but with
1136 // a malformed response when reading the descriptor value. Discovery should
1137 // fail.
TEST_F(RemoteServiceManagerTest,DiscoverDescriptorsExtendedPropertiesReadDescInvalidValue)1138 TEST_F(RemoteServiceManagerTest,
1139        DiscoverDescriptorsExtendedPropertiesReadDescInvalidValue) {
1140   ServiceData data(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1);
1141   auto service = SetUpFakeService(data);
1142 
1143   // The ExtendedProperties of the characteristic is set.
1144   const Properties props = Property::kExtendedProperties;
1145   CharacteristicData fake_chrc(
1146       props, std::nullopt, kCharDecl, kCharValue, kTestUuid3);
1147   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
1148   DescriptorData fake_desc2(kDesc2, kTestUuid4);
1149   SetCharacteristicsAndDescriptors({fake_chrc}, {fake_desc1, fake_desc2});
1150 
1151   // The callback should be triggered once to read the value of the descriptor
1152   // containing the ExtendedProperties bitfield.
1153   size_t read_cb_count = 0;
1154   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
1155     EXPECT_EQ(kDesc1, handle);
1156     callback(fit::ok(),
1157              BufferView(),
1158              /*maybe_truncated=*/false);  // Invalid return buf
1159     read_cb_count++;
1160   };
1161   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
1162 
1163   att::Result<> status = ToResult(HostError::kFailed);
1164   service->DiscoverCharacteristics(
1165       [&](att::Result<> cb_status, const auto chrcs) {
1166         status = cb_status;
1167         EXPECT_TRUE(chrcs.empty());
1168       });
1169 
1170   RunUntilIdle();
1171   EXPECT_EQ(1u, fake_client()->chrc_discovery_count());
1172   EXPECT_EQ(1u, fake_client()->desc_discovery_count());
1173   EXPECT_EQ(1u, read_cb_count);
1174   EXPECT_FALSE(service->IsDiscovered());
1175   EXPECT_EQ(ToResult(HostError::kPacketMalformed), status);
1176 }
1177 
1178 constexpr CharacteristicHandle kDefaultCharacteristic(3);
1179 constexpr CharacteristicHandle kSecondCharacteristic(6);
1180 constexpr CharacteristicHandle kInvalidCharacteristic(1);
1181 
1182 constexpr att::Handle kDefaultChrcValueHandle = 3;
1183 
UnreadableChrc()1184 CharacteristicData UnreadableChrc() {
1185   return CharacteristicData(
1186       0, std::nullopt, 2, kDefaultChrcValueHandle, kTestUuid3);
1187 }
ReadableChrc()1188 CharacteristicData ReadableChrc() {
1189   return CharacteristicData(
1190       Property::kRead, std::nullopt, 2, kDefaultChrcValueHandle, kTestUuid3);
1191 }
WritableChrc()1192 CharacteristicData WritableChrc() {
1193   return CharacteristicData(
1194       Property::kWrite, std::nullopt, 2, kDefaultChrcValueHandle, kTestUuid3);
1195 }
WriteableExtendedPropChrc()1196 CharacteristicData WriteableExtendedPropChrc() {
1197   auto props = Property::kWrite | Property::kExtendedProperties;
1198   return CharacteristicData(
1199       props, std::nullopt, 2, kDefaultChrcValueHandle, kTestUuid3);
1200 }
1201 
TEST_F(RemoteServiceManagerTest,ReadCharWhileNotReady)1202 TEST_F(RemoteServiceManagerTest, ReadCharWhileNotReady) {
1203   auto service = SetUpFakeService(
1204       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
1205 
1206   att::Result<> status = fit::ok();
1207   service->ReadCharacteristic(
1208       kDefaultCharacteristic,
1209       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1210 
1211   RunUntilIdle();
1212   EXPECT_EQ(ToResult(HostError::kNotReady), status);
1213 }
1214 
TEST_F(RemoteServiceManagerTest,ReadCharNotFound)1215 TEST_F(RemoteServiceManagerTest, ReadCharNotFound) {
1216   auto service = SetupServiceWithChrcs(
1217       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
1218   att::Result<> status = fit::ok();
1219   service->ReadCharacteristic(
1220       kDefaultCharacteristic,
1221       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1222 
1223   RunUntilIdle();
1224   EXPECT_EQ(ToResult(HostError::kNotFound), status);
1225 }
1226 
TEST_F(RemoteServiceManagerTest,ReadCharNotSupported)1227 TEST_F(RemoteServiceManagerTest, ReadCharNotSupported) {
1228   auto service = SetupServiceWithChrcs(
1229       ServiceData(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1),
1230       {UnreadableChrc()});
1231   att::Result<> status = fit::ok();
1232   service->ReadCharacteristic(
1233       kDefaultCharacteristic,
1234       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1235 
1236   RunUntilIdle();
1237   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
1238 }
1239 
TEST_F(RemoteServiceManagerTest,ReadCharSendsReadRequest)1240 TEST_F(RemoteServiceManagerTest, ReadCharSendsReadRequest) {
1241   auto service = SetupServiceWithChrcs(
1242       ServiceData(
1243           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1244       {ReadableChrc()});
1245 
1246   const StaticByteBuffer kValue('t', 'e', 's', 't');
1247 
1248   fake_client()->set_read_request_callback(
1249       [&](att::Handle handle, auto callback) {
1250         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1251         callback(fit::ok(), kValue, /*maybe_truncated=*/false);
1252       });
1253 
1254   att::Result<> status = ToResult(HostError::kFailed);
1255   service->ReadCharacteristic(
1256       kDefaultCharacteristic,
1257       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1258         status = cb_status;
1259         EXPECT_TRUE(ContainersEqual(kValue, value));
1260         EXPECT_FALSE(maybe_truncated);
1261       });
1262 
1263   RunUntilIdle();
1264 
1265   EXPECT_EQ(fit::ok(), status);
1266 }
1267 
TEST_F(RemoteServiceManagerTest,ReadLongWhileNotReady)1268 TEST_F(RemoteServiceManagerTest, ReadLongWhileNotReady) {
1269   auto service = SetUpFakeService(
1270       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
1271 
1272   att::Result<> status = fit::ok();
1273   service->ReadLongCharacteristic(
1274       CharacteristicHandle(0),
1275       0,
1276       512,
1277       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1278 
1279   RunUntilIdle();
1280 
1281   EXPECT_EQ(ToResult(HostError::kNotReady), status);
1282 }
1283 
TEST_F(RemoteServiceManagerTest,ReadLongNotFound)1284 TEST_F(RemoteServiceManagerTest, ReadLongNotFound) {
1285   auto service = SetupServiceWithChrcs(
1286       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
1287 
1288   att::Result<> status = fit::ok();
1289   service->ReadLongCharacteristic(
1290       CharacteristicHandle(0),
1291       0,
1292       512,
1293       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1294 
1295   RunUntilIdle();
1296 
1297   EXPECT_EQ(ToResult(HostError::kNotFound), status);
1298 }
1299 
TEST_F(RemoteServiceManagerTest,ReadLongNotSupported)1300 TEST_F(RemoteServiceManagerTest, ReadLongNotSupported) {
1301   auto service = SetupServiceWithChrcs(
1302       ServiceData(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1),
1303       {UnreadableChrc()});
1304 
1305   att::Result<> status = fit::ok();
1306   service->ReadLongCharacteristic(
1307       kDefaultCharacteristic,
1308       0,
1309       512,
1310       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1311 
1312   RunUntilIdle();
1313 
1314   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
1315 }
1316 
1317 // 0 is not a valid parameter for the |max_size| field of ReadLongCharacteristic
TEST_F(RemoteServiceManagerTest,ReadLongMaxSizeZero)1318 TEST_F(RemoteServiceManagerTest, ReadLongMaxSizeZero) {
1319   auto service = SetupServiceWithChrcs(
1320       ServiceData(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1),
1321       {ReadableChrc()});
1322 
1323   att::Result<> status = fit::ok();
1324   service->ReadLongCharacteristic(
1325       kDefaultCharacteristic,
1326       0,
1327       0,
1328       [&](att::Result<> cb_status, const auto&, auto) { status = cb_status; });
1329 
1330   RunUntilIdle();
1331 
1332   EXPECT_EQ(ToResult(HostError::kInvalidParameters), status);
1333 }
1334 
1335 // The complete attribute value is read in a single request.
TEST_F(RemoteServiceManagerTest,ReadLongSingleBlob)1336 TEST_F(RemoteServiceManagerTest, ReadLongSingleBlob) {
1337   constexpr uint16_t kOffset = 0;
1338   constexpr size_t kMaxBytes = 1000;
1339 
1340   auto service = SetupServiceWithChrcs(
1341       ServiceData(
1342           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1343       {ReadableChrc()});
1344 
1345   const StaticByteBuffer kValue('t', 'e', 's', 't');
1346 
1347   int request_count = 0;
1348   fake_client()->set_read_request_callback(
1349       [&](att::Handle handle, auto callback) {
1350         request_count++;
1351         EXPECT_EQ(request_count, 1);
1352         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1353         callback(fit::ok(), kValue, /*maybe_truncated=*/false);
1354       });
1355 
1356   att::Result<> status = ToResult(HostError::kFailed);
1357   service->ReadLongCharacteristic(
1358       kDefaultCharacteristic,
1359       kOffset,
1360       kMaxBytes,
1361       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1362         status = cb_status;
1363         EXPECT_TRUE(ContainersEqual(kValue, value));
1364         EXPECT_FALSE(maybe_truncated);
1365       });
1366 
1367   RunUntilIdle();
1368   EXPECT_EQ(fit::ok(), status);
1369 }
1370 
TEST_F(RemoteServiceManagerTest,ReadLongMultipleBlobs)1371 TEST_F(RemoteServiceManagerTest, ReadLongMultipleBlobs) {
1372   constexpr uint16_t kOffset = 0;
1373   constexpr size_t kMaxBytes = 1000;
1374   constexpr int kExpectedBlobCount = 4;
1375 
1376   auto service = SetupServiceWithChrcs(
1377       ServiceData(
1378           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1379       {ReadableChrc()});
1380 
1381   // Create a buffer that will take 4 requests to read. Since the default MTU is
1382   // 23:
1383   //   a. The size of |expected_value| is 69.
1384   //   b. We should read 22 + 22 + 22 + 3 bytes across 4 requests.
1385   StaticByteBuffer<att::kLEMinMTU * 3> expected_value;
1386 
1387   // Initialize the contents.
1388   for (size_t i = 0; i < expected_value.size(); ++i) {
1389     expected_value[i] = i;
1390   }
1391 
1392   int read_count = 0;
1393   fake_client()->set_read_request_callback(
1394       [&](att::Handle handle, auto callback) {
1395         read_count++;
1396         EXPECT_EQ(read_count, 1);
1397         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1398         auto blob = expected_value.view(0, att::kLEMinMTU - 1);
1399         callback(fit::ok(), blob, /*maybe_truncated=*/true);
1400       });
1401 
1402   fake_client()->set_read_blob_request_callback(
1403       [&](att::Handle handle, uint16_t offset, auto callback) {
1404         read_count++;
1405         EXPECT_GT(read_count, 1);
1406         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1407         bool maybe_truncated = true;
1408 
1409         // Return a blob at the given offset with at most MTU - 1 bytes.
1410         auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
1411         if (read_count == kExpectedBlobCount) {
1412           // The final blob should contain 3 bytes.
1413           EXPECT_EQ(3u, blob.size());
1414           maybe_truncated = false;
1415         }
1416 
1417         callback(fit::ok(), blob, maybe_truncated);
1418       });
1419 
1420   att::Result<> status = ToResult(HostError::kFailed);
1421   service->ReadLongCharacteristic(
1422       kDefaultCharacteristic,
1423       kOffset,
1424       kMaxBytes,
1425       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1426         status = cb_status;
1427         EXPECT_TRUE(ContainersEqual(expected_value, value));
1428         EXPECT_FALSE(maybe_truncated);
1429       });
1430 
1431   RunUntilIdle();
1432   EXPECT_EQ(fit::ok(), status);
1433   EXPECT_EQ(kExpectedBlobCount, read_count);
1434 }
1435 
1436 // Simulates a peer that rejects a read blob request with a kAttributeNotLong
1437 // error. The initial read request completes successfully and contains the
1438 // entire value. The specification implies that the peer can either respond with
1439 // an empty buffer or a kAttributeNotLong error for the second request.
TEST_F(RemoteServiceManagerTest,ReadLongCharacteristicAttributeNotLongErrorIgnored)1440 TEST_F(RemoteServiceManagerTest,
1441        ReadLongCharacteristicAttributeNotLongErrorIgnored) {
1442   constexpr uint16_t kOffset = 0;
1443   constexpr size_t kMaxBytes = 1000;
1444   constexpr int kExpectedBlobCount = 2;
1445 
1446   auto service = SetupServiceWithChrcs(
1447       ServiceData(
1448           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1449       {ReadableChrc()});
1450 
1451   StaticByteBuffer<att::kLEMinMTU - 1> expected_value;
1452   for (size_t i = 0; i < expected_value.size(); ++i) {
1453     expected_value[i] = i;
1454   }
1455 
1456   int read_count = 0;
1457   fake_client()->set_read_request_callback(
1458       [&](att::Handle handle, auto callback) {
1459         read_count++;
1460         EXPECT_EQ(read_count, 1);
1461         callback(fit::ok(), expected_value.view(), /*maybe_truncated=*/true);
1462       });
1463 
1464   fake_client()->set_read_blob_request_callback(
1465       [&](att::Handle handle, uint16_t offset, auto callback) {
1466         read_count++;
1467         EXPECT_EQ(read_count, 2);
1468         callback(ToResult(att::ErrorCode::kAttributeNotLong),
1469                  BufferView(),
1470                  /*maybe_truncated=*/false);
1471       });
1472 
1473   att::Result<> status = ToResult(HostError::kFailed);
1474   service->ReadLongCharacteristic(
1475       kDefaultCharacteristic,
1476       kOffset,
1477       kMaxBytes,
1478       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1479         status = cb_status;
1480         EXPECT_TRUE(ContainersEqual(expected_value, value));
1481         EXPECT_FALSE(maybe_truncated);
1482       });
1483 
1484   RunUntilIdle();
1485   EXPECT_EQ(fit::ok(), status);
1486   EXPECT_EQ(kExpectedBlobCount, read_count);
1487 }
1488 
TEST_F(RemoteServiceManagerTest,ReadLongCharacteristicAttributeNotLongErrorOnFirstReadRequest)1489 TEST_F(RemoteServiceManagerTest,
1490        ReadLongCharacteristicAttributeNotLongErrorOnFirstReadRequest) {
1491   constexpr uint16_t kOffset = 0;
1492   constexpr size_t kMaxBytes = 1000;
1493   constexpr int kExpectedBlobCount = 1;
1494 
1495   auto service = SetupServiceWithChrcs(
1496       ServiceData(
1497           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1498       {ReadableChrc()});
1499 
1500   int read_count = 0;
1501   fake_client()->set_read_request_callback(
1502       [&](att::Handle handle, auto callback) {
1503         read_count++;
1504         EXPECT_EQ(read_count, 1);
1505         callback(ToResult(att::ErrorCode::kAttributeNotLong),
1506                  BufferView(),
1507                  /*maybe_truncated=*/false);
1508       });
1509   fake_client()->set_read_blob_request_callback(
1510       [&](auto, auto, auto) { FAIL(); });
1511 
1512   att::Result<> status = fit::ok();
1513   service->ReadLongCharacteristic(
1514       kDefaultCharacteristic,
1515       kOffset,
1516       kMaxBytes,
1517       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1518         status = cb_status;
1519         EXPECT_FALSE(maybe_truncated);
1520       });
1521 
1522   RunUntilIdle();
1523   EXPECT_EQ(ToResult(att::ErrorCode::kAttributeNotLong), status);
1524   EXPECT_EQ(kExpectedBlobCount, read_count);
1525 }
1526 
1527 // Same as ReadLongMultipleBlobs except the characteristic value has a size that
1528 // is a multiple of (ATT_MTU - 1), so that the last read blob request returns 0
1529 // bytes.
TEST_F(RemoteServiceManagerTest,ReadLongValueExactMultipleOfMTU)1530 TEST_F(RemoteServiceManagerTest, ReadLongValueExactMultipleOfMTU) {
1531   constexpr uint16_t kOffset = 0;
1532   constexpr size_t kMaxBytes = 1000;
1533   constexpr int kExpectedBlobCount = 4;
1534 
1535   auto service = SetupServiceWithChrcs(
1536       ServiceData(
1537           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1538       {ReadableChrc()});
1539 
1540   // Create a buffer that will take 4 requests to read. Since the default MTU is
1541   // 23:
1542   //   a. The size of |expected_value| is 66.
1543   //   b. We should read 22 + 22 + 22 + 0 bytes across 4 requests.
1544   StaticByteBuffer<(att::kLEMinMTU - 1) * 3> expected_value;
1545 
1546   // Initialize the contents.
1547   for (size_t i = 0; i < expected_value.size(); ++i) {
1548     expected_value[i] = i;
1549   }
1550 
1551   int read_count = 0;
1552   fake_client()->set_read_request_callback(
1553       [&](att::Handle handle, auto callback) {
1554         read_count++;
1555         EXPECT_EQ(read_count, 1);
1556         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1557         auto blob = expected_value.view(0, att::kLEMinMTU - 1);
1558         callback(fit::ok(), blob, /*maybe_truncated=*/true);
1559       });
1560 
1561   fake_client()->set_read_blob_request_callback(
1562       [&](att::Handle handle, uint16_t offset, auto callback) {
1563         read_count++;
1564         EXPECT_GT(read_count, 1);
1565         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1566         bool maybe_truncated = true;
1567 
1568         // Return a blob at the given offset with at most MTU - 1 bytes.
1569         auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
1570         if (read_count == kExpectedBlobCount) {
1571           // The final blob should be empty.
1572           EXPECT_EQ(0u, blob.size());
1573           maybe_truncated = false;
1574         }
1575 
1576         callback(fit::ok(), blob, maybe_truncated);
1577       });
1578 
1579   att::Result<> status = ToResult(HostError::kFailed);
1580   service->ReadLongCharacteristic(
1581       kDefaultCharacteristic,
1582       kOffset,
1583       kMaxBytes,
1584       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1585         status = cb_status;
1586         EXPECT_TRUE(ContainersEqual(expected_value, value));
1587         EXPECT_FALSE(maybe_truncated);
1588       });
1589 
1590   RunUntilIdle();
1591   EXPECT_EQ(fit::ok(), status);
1592   EXPECT_EQ(kExpectedBlobCount, read_count);
1593 }
1594 
1595 // Same as ReadLongMultipleBlobs but a maximum size is given that is smaller
1596 // than the size of the attribute value.
TEST_F(RemoteServiceManagerTest,ReadLongMultipleBlobsWithMaxSize)1597 TEST_F(RemoteServiceManagerTest, ReadLongMultipleBlobsWithMaxSize) {
1598   constexpr uint16_t kOffset = 0;
1599   constexpr size_t kMaxBytes = 40;
1600   constexpr int kExpectedBlobCount = 2;
1601 
1602   auto service = SetupServiceWithChrcs(
1603       ServiceData(
1604           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1605       {ReadableChrc()});
1606 
1607   // Reads will return 22 + 22 bytes across 2 requests, but only 18 bytes of the
1608   // second read will be reported to ReadLongCharacteristic (the value will be
1609   // truncated).
1610   StaticByteBuffer<att::kLEMinMTU * 3> expected_value;
1611 
1612   // Initialize the contents.
1613   for (size_t i = 0; i < expected_value.size(); ++i) {
1614     expected_value[i] = i;
1615   }
1616 
1617   int read_count = 0;
1618   fake_client()->set_read_request_callback(
1619       [&](att::Handle handle, auto callback) {
1620         read_count++;
1621         EXPECT_EQ(read_count, 1);
1622         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1623         BufferView blob = expected_value.view(0, att::kLEMinMTU - 1);
1624         callback(fit::ok(), blob, /*maybe_truncated=*/true);
1625       });
1626 
1627   fake_client()->set_read_blob_request_callback(
1628       [&](att::Handle handle, uint16_t offset, auto callback) {
1629         read_count++;
1630         EXPECT_GT(read_count, 1);
1631         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1632         BufferView blob = expected_value.view(offset, att::kLEMinMTU - 1);
1633         callback(fit::ok(), blob, /*maybe_truncated=*/true);
1634       });
1635 
1636   att::Result<> status = ToResult(HostError::kFailed);
1637   service->ReadLongCharacteristic(
1638       kDefaultCharacteristic,
1639       kOffset,
1640       kMaxBytes,
1641       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1642         status = cb_status;
1643         EXPECT_TRUE(ContainersEqual(expected_value.view(0, kMaxBytes), value));
1644         EXPECT_TRUE(maybe_truncated);
1645       });
1646 
1647   RunUntilIdle();
1648   EXPECT_EQ(fit::ok(), status);
1649   EXPECT_EQ(kExpectedBlobCount, read_count);
1650 }
1651 
1652 // Same as ReadLongMultipleBlobs but a non-zero offset is given.
TEST_F(RemoteServiceManagerTest,ReadLongAtOffset)1653 TEST_F(RemoteServiceManagerTest, ReadLongAtOffset) {
1654   constexpr uint16_t kOffset = 30;
1655   constexpr size_t kMaxBytes = 1000;
1656   constexpr int kExpectedBlobCount = 2;
1657 
1658   auto service = SetupServiceWithChrcs(
1659       ServiceData(
1660           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1661       {ReadableChrc()});
1662 
1663   // Size: 69.
1664   // Reads starting at offset 30 will return 22 + 17 bytes across 2 requests.
1665   StaticByteBuffer<att::kLEMinMTU * 3> expected_value;
1666 
1667   // Initialize the contents.
1668   for (size_t i = 0; i < expected_value.size(); ++i) {
1669     expected_value[i] = i;
1670   }
1671 
1672   int read_blob_count = 0;
1673   fake_client()->set_read_blob_request_callback(
1674       [&](att::Handle handle, uint16_t offset, auto callback) {
1675         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1676         read_blob_count++;
1677         BufferView blob = expected_value.view(offset, att::kLEMinMTU - 1);
1678         bool maybe_truncated = (read_blob_count != kExpectedBlobCount);
1679         callback(fit::ok(), blob, maybe_truncated);
1680       });
1681 
1682   att::Result<> status = ToResult(HostError::kFailed);
1683   service->ReadLongCharacteristic(
1684       kDefaultCharacteristic,
1685       kOffset,
1686       kMaxBytes,
1687       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1688         status = cb_status;
1689         EXPECT_TRUE(
1690             ContainersEqual(expected_value.view(kOffset, kMaxBytes), value));
1691         EXPECT_FALSE(maybe_truncated);
1692       });
1693 
1694   RunUntilIdle();
1695   EXPECT_EQ(fit::ok(), status);
1696   EXPECT_EQ(kExpectedBlobCount, read_blob_count);
1697 }
1698 
1699 // Same as ReadLongAtOffset but a very small max size is given.
TEST_F(RemoteServiceManagerTest,ReadLongAtOffsetWithMaxBytes)1700 TEST_F(RemoteServiceManagerTest, ReadLongAtOffsetWithMaxBytes) {
1701   constexpr uint16_t kOffset = 10;
1702   constexpr size_t kMaxBytes = 34;
1703   constexpr int kExpectedBlobCount = 2;
1704 
1705   auto service = SetupServiceWithChrcs(
1706       ServiceData(
1707           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1708       {ReadableChrc()});
1709 
1710   // Size: 69.
1711   // Reads starting at offset 10 will return 22 + 22 bytes across 2 requests,
1712   // but the second read value will be truncated to 12 bytes by RemoteService
1713   // due to |kMaxBytes|. A third read blob should not be sent since this should
1714   // satisfy |kMaxBytes|.
1715   StaticByteBuffer<att::kLEMinMTU * 3> expected_value;
1716 
1717   // Initialize the contents.
1718   for (size_t i = 0; i < expected_value.size(); ++i) {
1719     expected_value[i] = static_cast<uint8_t>(i);
1720   }
1721 
1722   int read_blob_count = 0;
1723   fake_client()->set_read_blob_request_callback(
1724       [&](att::Handle handle, uint16_t offset, auto callback) {
1725         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1726         read_blob_count++;
1727         BufferView blob = expected_value.view(offset, att::kLEMinMTU - 1);
1728         callback(fit::ok(), blob, /*maybe_truncated=*/true);
1729       });
1730 
1731   att::Result<> status = ToResult(HostError::kFailed);
1732   service->ReadLongCharacteristic(
1733       kDefaultCharacteristic,
1734       kOffset,
1735       kMaxBytes,
1736       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1737         status = cb_status;
1738         EXPECT_TRUE(
1739             ContainersEqual(expected_value.view(kOffset, kMaxBytes), value));
1740         EXPECT_TRUE(maybe_truncated);
1741       });
1742 
1743   RunUntilIdle();
1744   EXPECT_EQ(fit::ok(), status);
1745   EXPECT_EQ(kExpectedBlobCount, read_blob_count);
1746 }
1747 
TEST_F(RemoteServiceManagerTest,ReadLongError)1748 TEST_F(RemoteServiceManagerTest, ReadLongError) {
1749   constexpr uint16_t kOffset = 0;
1750   constexpr size_t kMaxBytes = 1000;
1751   constexpr int kExpectedBlobCount = 2;  // The second request will fail.
1752 
1753   auto service = SetupServiceWithChrcs(
1754       ServiceData(
1755           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
1756       {ReadableChrc()});
1757 
1758   // Make the first blob large enough that it will cause a second read blob
1759   // request.
1760   StaticByteBuffer<att::kLEMinMTU - 1> first_blob;
1761 
1762   int read_count = 0;
1763   fake_client()->set_read_request_callback(
1764       [&](att::Handle handle, auto callback) {
1765         read_count++;
1766         EXPECT_EQ(read_count, 1);
1767         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1768         callback(fit::ok(), first_blob, /*maybe_truncated=*/true);
1769       });
1770 
1771   fake_client()->set_read_blob_request_callback(
1772       [&](att::Handle handle, uint16_t offset, auto callback) {
1773         read_count++;
1774         EXPECT_EQ(read_count, 2);
1775         EXPECT_EQ(kDefaultChrcValueHandle, handle);
1776         callback(ToResult(att::ErrorCode::kInvalidOffset),
1777                  BufferView(),
1778                  /*maybe_truncated=*/false);
1779       });
1780 
1781   att::Result<> status = fit::ok();
1782   service->ReadLongCharacteristic(
1783       kDefaultCharacteristic,
1784       kOffset,
1785       kMaxBytes,
1786       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
1787         status = cb_status;
1788         EXPECT_EQ(0u, value.size());  // No value should be returned on error.
1789         EXPECT_FALSE(maybe_truncated);
1790       });
1791 
1792   RunUntilIdle();
1793   EXPECT_EQ(ToResult(att::ErrorCode::kInvalidOffset), status);
1794   EXPECT_EQ(kExpectedBlobCount, read_count);
1795 }
1796 
TEST_F(RemoteServiceManagerTest,ReadByTypeSendsReadRequestsUntilAttributeNotFound)1797 TEST_F(RemoteServiceManagerTest,
1798        ReadByTypeSendsReadRequestsUntilAttributeNotFound) {
1799   constexpr att::Handle kStartHandle = 1;
1800   constexpr att::Handle kEndHandle = 5;
1801   auto service = SetUpFakeService(ServiceData(
1802       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
1803 
1804   constexpr UUID kCharUuid(uint16_t{0xfefe});
1805 
1806   constexpr att::Handle kHandle0 = 2;
1807   const StaticByteBuffer kValue0(0x00, 0x01, 0x02);
1808   const std::vector<Client::ReadByTypeValue> kValues0 = {
1809       {kHandle0, kValue0.view(), /*maybe_truncated=*/false}};
1810 
1811   constexpr att::Handle kHandle1 = 3;
1812   const StaticByteBuffer kValue1(0x03, 0x04, 0x05);
1813   const std::vector<Client::ReadByTypeValue> kValues1 = {
1814       {kHandle1, kValue1.view(), /*maybe_truncated=*/true}};
1815 
1816   size_t read_count = 0;
1817   fake_client()->set_read_by_type_request_callback(
1818       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
1819         switch (read_count++) {
1820           case 0:
1821             EXPECT_EQ(kStartHandle, start);
1822             callback(fit::ok(kValues0));
1823             break;
1824           case 1:
1825             EXPECT_EQ(kHandle0 + 1, start);
1826             callback(fit::ok(kValues1));
1827             break;
1828           case 2:
1829             EXPECT_EQ(kHandle1 + 1, start);
1830             callback(fit::error(Client::ReadByTypeError{
1831                 att::Error(att::ErrorCode::kAttributeNotFound), start}));
1832             break;
1833           default:
1834             FAIL();
1835         }
1836       });
1837 
1838   std::optional<att::Result<>> status;
1839   service->ReadByType(
1840       kCharUuid,
1841       [&](att::Result<> cb_status,
1842           std::vector<RemoteService::ReadByTypeResult> values) {
1843         status = cb_status;
1844         EXPECT_EQ(fit::ok(), *status);
1845         ASSERT_EQ(2u, values.size());
1846         EXPECT_EQ(CharacteristicHandle(kHandle0), values[0].handle);
1847         ASSERT_EQ(fit::ok(), values[0].result);
1848         EXPECT_TRUE(ContainersEqual(kValue0, *values[0].result.value()));
1849         EXPECT_FALSE(values[0].maybe_truncated);
1850         EXPECT_EQ(CharacteristicHandle(kHandle1), values[1].handle);
1851         ASSERT_EQ(fit::ok(), values[1].result);
1852         EXPECT_TRUE(ContainersEqual(kValue1, *values[1].result.value()));
1853         EXPECT_TRUE(values[1].maybe_truncated);
1854       });
1855 
1856   RunUntilIdle();
1857   ASSERT_TRUE(status.has_value());
1858   // kAttributeNotFound error should be treated as success.
1859   EXPECT_EQ(fit::ok(), *status);
1860 }
1861 
TEST_F(RemoteServiceManagerTest,ReadByTypeSendsReadRequestsUntilServiceEndHandle)1862 TEST_F(RemoteServiceManagerTest,
1863        ReadByTypeSendsReadRequestsUntilServiceEndHandle) {
1864   constexpr att::Handle kStartHandle = 1;
1865   constexpr att::Handle kEndHandle = 2;
1866   auto service = SetUpFakeService(ServiceData(
1867       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
1868 
1869   constexpr UUID kCharUuid(uint16_t{0xfefe});
1870 
1871   constexpr att::Handle kHandle = kEndHandle;
1872   const StaticByteBuffer kValue(0x00, 0x01, 0x02);
1873   const std::vector<Client::ReadByTypeValue> kValues = {
1874       {kHandle, kValue.view(), /*maybe_truncated=*/false}};
1875 
1876   size_t read_count = 0;
1877   fake_client()->set_read_by_type_request_callback(
1878       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
1879         EXPECT_EQ(kStartHandle, start);
1880         EXPECT_EQ(0u, read_count++);
1881         callback(fit::ok(kValues));
1882       });
1883 
1884   std::optional<att::Result<>> status;
1885   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
1886     status = cb_status;
1887     ASSERT_EQ(1u, values.size());
1888     EXPECT_EQ(CharacteristicHandle(kHandle), values[0].handle);
1889     ASSERT_EQ(fit::ok(), values[0].result);
1890     EXPECT_TRUE(ContainersEqual(kValue, *values[0].result.value()));
1891   });
1892 
1893   RunUntilIdle();
1894   ASSERT_TRUE(status.has_value());
1895   EXPECT_EQ(fit::ok(), *status);
1896 }
1897 
TEST_F(RemoteServiceManagerTest,ReadByTypeReturnsReadErrorsWithResults)1898 TEST_F(RemoteServiceManagerTest, ReadByTypeReturnsReadErrorsWithResults) {
1899   constexpr att::Handle kStartHandle = 1;
1900   constexpr att::Handle kEndHandle = 5;
1901   auto service = SetUpFakeService(ServiceData(
1902       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
1903 
1904   constexpr UUID kCharUuid(uint16_t{0xfefe});
1905 
1906   const std::array<att::ErrorCode, 5> errors = {
1907       att::ErrorCode::kInsufficientAuthorization,
1908       att::ErrorCode::kInsufficientAuthentication,
1909       att::ErrorCode::kInsufficientEncryptionKeySize,
1910       att::ErrorCode::kInsufficientEncryption,
1911       att::ErrorCode::kReadNotPermitted};
1912 
1913   size_t read_count = 0;
1914   fake_client()->set_read_by_type_request_callback(
1915       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
1916         if (read_count < errors.size()) {
1917           EXPECT_EQ(kStartHandle + read_count, start);
1918           callback(fit::error(Client::ReadByTypeError{
1919               att::Error(errors[read_count++]), start}));
1920         } else {
1921           FAIL();
1922         }
1923       });
1924 
1925   std::optional<att::Result<>> status;
1926   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
1927     status = cb_status;
1928     ASSERT_EQ(errors.size(), values.size());
1929     for (size_t i = 0; i < values.size(); i++) {
1930       SCOPED_TRACE(bt_lib_cpp_string::StringPrintf("i: %zu", i));
1931       EXPECT_EQ(CharacteristicHandle(kStartHandle + i), values[i].handle);
1932       ASSERT_TRUE(values[i].result.is_error());
1933       EXPECT_EQ(errors[i], values[i].result.error_value());
1934       EXPECT_FALSE(values[i].maybe_truncated);
1935     }
1936   });
1937 
1938   RunUntilIdle();
1939   ASSERT_TRUE(status.has_value());
1940   ASSERT_EQ(fit::ok(), *status);
1941 }
1942 
TEST_F(RemoteServiceManagerTest,ReadByTypeReturnsProtocolErrorAfterRead)1943 TEST_F(RemoteServiceManagerTest, ReadByTypeReturnsProtocolErrorAfterRead) {
1944   constexpr att::Handle kStartHandle = 1;
1945   constexpr att::Handle kEndHandle = 5;
1946   auto service = SetUpFakeService(ServiceData(
1947       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
1948 
1949   constexpr UUID kCharUuid(uint16_t{0xfefe});
1950 
1951   constexpr att::Handle kHandle = kEndHandle;
1952   const auto kValue = StaticByteBuffer(0x00, 0x01, 0x02);
1953   const std::vector<Client::ReadByTypeValue> kValues = {
1954       {kHandle, kValue.view(), /*maybe_truncated=*/false}};
1955 
1956   const std::vector<std::pair<const char*, att::ErrorCode>>
1957       general_protocol_errors = {
1958           {"kRequestNotSupported", att::ErrorCode::kRequestNotSupported},
1959           {"kInsufficientResources", att::ErrorCode::kInsufficientResources},
1960           {"kInvalidPDU", att::ErrorCode::kInvalidPDU}};
1961 
1962   for (const auto& [name, code] : general_protocol_errors) {
1963     SCOPED_TRACE(bt_lib_cpp_string::StringPrintf("Error Code: %s", name));
1964     size_t read_count = 0;
1965     fake_client()->set_read_by_type_request_callback(
1966         [&, code = code](const UUID& type,
1967                          att::Handle start,
1968                          att::Handle end,
1969                          auto callback) {
1970           ASSERT_EQ(0u, read_count++);
1971           switch (read_count++) {
1972             case 0:
1973               callback(fit::ok(kValues));
1974               break;
1975             case 1:
1976               callback(fit::error(
1977                   Client::ReadByTypeError{att::Error(code), std::nullopt}));
1978               break;
1979             default:
1980               FAIL();
1981           }
1982         });
1983 
1984     std::optional<att::Result<>> status;
1985     service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
1986       status = cb_status;
1987       EXPECT_EQ(0u, values.size());
1988     });
1989 
1990     RunUntilIdle();
1991     ASSERT_TRUE(status.has_value());
1992     EXPECT_EQ(ToResult(code), status);
1993   }
1994 }
1995 
TEST_F(RemoteServiceManagerTest,ReadByTypeHandlesReadErrorWithMissingHandle)1996 TEST_F(RemoteServiceManagerTest, ReadByTypeHandlesReadErrorWithMissingHandle) {
1997   constexpr att::Handle kStartHandle = 1;
1998   constexpr att::Handle kEndHandle = 5;
1999   auto service = SetUpFakeService(ServiceData(
2000       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
2001 
2002   constexpr UUID kCharUuid(uint16_t{0xfefe});
2003 
2004   size_t read_count = 0;
2005   fake_client()->set_read_by_type_request_callback(
2006       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
2007         ASSERT_EQ(0u, read_count++);
2008         callback(fit::error(Client::ReadByTypeError{
2009             att::Error(att::ErrorCode::kReadNotPermitted), std::nullopt}));
2010       });
2011 
2012   std::optional<att::Result<>> status;
2013   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
2014     status = cb_status;
2015   });
2016   RunUntilIdle();
2017   ASSERT_TRUE(status.has_value());
2018   EXPECT_EQ(ToResult(att::ErrorCode::kReadNotPermitted), *status);
2019 }
2020 
TEST_F(RemoteServiceManagerTest,ReadByTypeHandlesReadErrorWithOutOfRangeHandle)2021 TEST_F(RemoteServiceManagerTest,
2022        ReadByTypeHandlesReadErrorWithOutOfRangeHandle) {
2023   constexpr att::Handle kStartHandle = 1;
2024   constexpr att::Handle kEndHandle = 5;
2025   auto service = SetUpFakeService(ServiceData(
2026       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
2027 
2028   constexpr UUID kCharUuid(uint16_t{0xfefe});
2029 
2030   size_t read_count = 0;
2031   fake_client()->set_read_by_type_request_callback(
2032       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
2033         ASSERT_EQ(0u, read_count++);
2034         callback(fit::error(Client::ReadByTypeError{
2035             att::Error(att::ErrorCode::kReadNotPermitted), kEndHandle + 1}));
2036       });
2037 
2038   std::optional<att::Result<>> status;
2039   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
2040     status = cb_status;
2041   });
2042   RunUntilIdle();
2043   ASSERT_TRUE(status.has_value());
2044   EXPECT_EQ(ToResult(HostError::kPacketMalformed), *status);
2045 }
2046 
TEST_F(RemoteServiceManagerTest,ReadByTypeReturnsErrorIfUuidIsInternal)2047 TEST_F(RemoteServiceManagerTest, ReadByTypeReturnsErrorIfUuidIsInternal) {
2048   const std::array<UUID, 10> kInternalUuids = {
2049       types::kPrimaryService,
2050       types::kSecondaryService,
2051       types::kIncludeDeclaration,
2052       types::kCharacteristicDeclaration,
2053       types::kCharacteristicExtProperties,
2054       types::kCharacteristicUserDescription,
2055       types::kClientCharacteristicConfig,
2056       types::kServerCharacteristicConfig,
2057       types::kCharacteristicFormat,
2058       types::kCharacteristicAggregateFormat};
2059 
2060   auto service = SetUpFakeService(ServiceData(
2061       ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1));
2062 
2063   fake_client()->set_read_by_type_request_callback(
2064       [&](auto, auto, auto, auto) { ADD_FAILURE(); });
2065 
2066   for (const UUID& uuid : kInternalUuids) {
2067     std::optional<att::Result<>> status;
2068     service->ReadByType(uuid, [&](att::Result<> cb_status, auto values) {
2069       status = cb_status;
2070       EXPECT_EQ(0u, values.size());
2071     });
2072 
2073     RunUntilIdle();
2074     ASSERT_TRUE(status.has_value()) << "UUID: " << uuid;
2075     EXPECT_EQ(ToResult(HostError::kInvalidParameters), *status);
2076   }
2077 }
2078 
TEST_F(RemoteServiceManagerTest,WriteCharWhileNotReady)2079 TEST_F(RemoteServiceManagerTest, WriteCharWhileNotReady) {
2080   auto service = SetUpFakeService(
2081       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2082 
2083   att::Result<> status = fit::ok();
2084   service->WriteCharacteristic(
2085       kDefaultCharacteristic,
2086       std::vector<uint8_t>(),
2087       [&](att::Result<> cb_status) { status = cb_status; });
2088 
2089   RunUntilIdle();
2090 
2091   EXPECT_EQ(ToResult(HostError::kNotReady), status);
2092 }
2093 
TEST_F(RemoteServiceManagerTest,WriteCharNotFound)2094 TEST_F(RemoteServiceManagerTest, WriteCharNotFound) {
2095   auto service = SetupServiceWithChrcs(
2096       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
2097 
2098   att::Result<> status = fit::ok();
2099   service->WriteCharacteristic(
2100       kDefaultCharacteristic,
2101       std::vector<uint8_t>(),
2102       [&](att::Result<> cb_status) { status = cb_status; });
2103 
2104   RunUntilIdle();
2105 
2106   EXPECT_EQ(ToResult(HostError::kNotFound), status);
2107 }
2108 
TEST_F(RemoteServiceManagerTest,WriteCharNotSupported)2109 TEST_F(RemoteServiceManagerTest, WriteCharNotSupported) {
2110   // No "write" property set.
2111   auto service = SetupServiceWithChrcs(
2112       ServiceData(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1),
2113       {ReadableChrc()});
2114 
2115   att::Result<> status = fit::ok();
2116   service->WriteCharacteristic(
2117       kDefaultCharacteristic,
2118       std::vector<uint8_t>(),
2119       [&](att::Result<> cb_status) { status = cb_status; });
2120 
2121   RunUntilIdle();
2122 
2123   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
2124 }
2125 
TEST_F(RemoteServiceManagerTest,WriteCharSendsWriteRequest)2126 TEST_F(RemoteServiceManagerTest, WriteCharSendsWriteRequest) {
2127   const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
2128   constexpr att::Result<> kStatus =
2129       ToResult(att::ErrorCode::kWriteNotPermitted);
2130 
2131   auto service = SetupServiceWithChrcs(
2132       ServiceData(
2133           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
2134       {WritableChrc()});
2135 
2136   fake_client()->set_write_request_callback(
2137       [&](att::Handle handle, const auto& value, auto status_callback) {
2138         EXPECT_EQ(kDefaultChrcValueHandle, handle);
2139         EXPECT_TRUE(std::equal(
2140             kValue.begin(), kValue.end(), value.begin(), value.end()));
2141         status_callback(kStatus);
2142       });
2143 
2144   att::Result<> status = fit::ok();
2145   service->WriteCharacteristic(
2146       kDefaultCharacteristic, kValue, [&](att::Result<> cb_status) {
2147         status = cb_status;
2148       });
2149 
2150   RunUntilIdle();
2151 
2152   EXPECT_EQ(kStatus, status);
2153 }
2154 
2155 // Tests that a long write is chunked up properly into a series of QueuedWrites
2156 // that will be processed by the client. This tests a non-zero offset.
TEST_F(RemoteServiceManagerTest,WriteCharLongOffsetSuccess)2157 TEST_F(RemoteServiceManagerTest, WriteCharLongOffsetSuccess) {
2158   constexpr uint16_t kOffset = 5;
2159   constexpr uint16_t kExpectedQueueSize = 4;
2160   constexpr uint16_t kExpectedFullWriteSize = 18;
2161   constexpr uint16_t kExpectedFinalWriteSize = 15;
2162 
2163   auto service = SetupServiceWithChrcs(
2164       ServiceData(
2165           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
2166       {WritableChrc()});
2167 
2168   // Create a vector that will take 4 requests to write. Since the default MTU
2169   // is 23:
2170   //   a. The size of |full_write_value| is 69.
2171   //   b. att:Handle, |kOffset|, and att::OpCode size is 5 bytes total.
2172   //   c. We should write 18 + 18 + 18 + 15 bytes across 4 requests.
2173   //   d. These bytes will be written with offset 5, from (5) to (5+69)
2174   std::vector<uint8_t> full_write_value(att::kLEMinMTU * 3);
2175 
2176   // Initialize the contents.
2177   for (size_t i = 0; i < full_write_value.size(); ++i) {
2178     full_write_value[i] = i;
2179   }
2180 
2181   uint8_t process_long_write_count = 0;
2182   fake_client()->set_execute_prepare_writes_callback(
2183       [&](att::PrepareWriteQueue write_queue,
2184           auto /*reliable_mode*/,
2185           auto callback) {
2186         EXPECT_EQ(write_queue.size(), kExpectedQueueSize);
2187 
2188         for (int i = 0; i < kExpectedQueueSize; i++) {
2189           auto write = std::move(write_queue.front());
2190           write_queue.pop();
2191 
2192           EXPECT_EQ(write.handle(), kDefaultChrcValueHandle);
2193           EXPECT_EQ(write.offset(), kOffset + (i * kExpectedFullWriteSize));
2194 
2195           // All writes expect the final should be full, the final should be
2196           // the remainder.
2197           if (i < kExpectedQueueSize - 1) {
2198             EXPECT_EQ(write.value().size(), kExpectedFullWriteSize);
2199           } else {
2200             EXPECT_EQ(write.value().size(), kExpectedFinalWriteSize);
2201           }
2202         }
2203 
2204         process_long_write_count++;
2205 
2206         callback(fit::ok());
2207       });
2208 
2209   ReliableMode mode = ReliableMode::kDisabled;
2210   att::Result<> status = ToResult(HostError::kFailed);
2211   service->WriteLongCharacteristic(
2212       kDefaultCharacteristic,
2213       kOffset,
2214       full_write_value,
2215       mode,
2216       [&](att::Result<> cb_status) { status = cb_status; });
2217 
2218   RunUntilIdle();
2219   EXPECT_EQ(fit::ok(), status);
2220   EXPECT_EQ(1u, process_long_write_count);
2221 }
2222 
TEST_F(RemoteServiceManagerTest,WriteCharLongAtExactMultipleOfMtu)2223 TEST_F(RemoteServiceManagerTest, WriteCharLongAtExactMultipleOfMtu) {
2224   constexpr uint16_t kOffset = 0;
2225   constexpr uint16_t kExpectedQueueSize = 4;
2226   constexpr uint16_t kExpectedFullWriteSize = 18;
2227 
2228   auto service = SetupServiceWithChrcs(
2229       ServiceData(
2230           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
2231       {WritableChrc()});
2232 
2233   // Create a vector that will take 4 requests to write. Since the default MTU
2234   // is 23:
2235   //   a. The size of |full_write_value| is 72.
2236   //   b. att:Handle, |kOffset|, and att::OpCode size is 5 bytes total.
2237   //   c. We should write 18 + 18 + 18 + 18 bytes across 4 requests.
2238   //   d. These bytes will be written with offset 0, from (0) to (72)
2239   std::vector<uint8_t> full_write_value((att::kLEMinMTU - 5) * 4);
2240 
2241   // Initialize the contents.
2242   for (size_t i = 0; i < full_write_value.size(); ++i) {
2243     full_write_value[i] = i;
2244   }
2245 
2246   uint8_t process_long_write_count = 0;
2247   fake_client()->set_execute_prepare_writes_callback(
2248       [&](att::PrepareWriteQueue write_queue,
2249           auto /*reliable_mode*/,
2250           auto callback) {
2251         EXPECT_EQ(write_queue.size(), kExpectedQueueSize);
2252 
2253         for (int i = 0; i < kExpectedQueueSize; i++) {
2254           auto write = std::move(write_queue.front());
2255           write_queue.pop();
2256 
2257           EXPECT_EQ(write.handle(), kDefaultChrcValueHandle);
2258           EXPECT_EQ(write.offset(), kOffset + (i * kExpectedFullWriteSize));
2259 
2260           // All writes should be full
2261           EXPECT_EQ(write.value().size(), kExpectedFullWriteSize);
2262         }
2263 
2264         process_long_write_count++;
2265 
2266         callback(fit::ok());
2267       });
2268 
2269   ReliableMode mode = ReliableMode::kDisabled;
2270   att::Result<> status = ToResult(HostError::kFailed);
2271   service->WriteLongCharacteristic(
2272       kDefaultCharacteristic,
2273       kOffset,
2274       full_write_value,
2275       mode,
2276       [&](att::Result<> cb_status) { status = cb_status; });
2277 
2278   RunUntilIdle();
2279   EXPECT_EQ(fit::ok(), status);
2280   EXPECT_EQ(1u, process_long_write_count);
2281 }
2282 
2283 // Writing a long characteristic with ReliableMode::Enabled should succeed.
TEST_F(RemoteServiceManagerTest,WriteCharLongReliableWrite)2284 TEST_F(RemoteServiceManagerTest, WriteCharLongReliableWrite) {
2285   constexpr uint16_t kOffset = 0;
2286   constexpr uint16_t kExpectedQueueSize = 1;
2287 
2288   DescriptorData fake_desc1(kDesc1, types::kCharacteristicExtProperties);
2289   DescriptorData fake_desc2(kDesc2, kTestUuid4);
2290 
2291   // The callback should be triggered once to read the value of the descriptor
2292   // containing the ExtendedProperties bitfield.
2293   auto extended_prop_read_cb = [&](att::Handle handle, auto callback) {
2294     callback(fit::ok(), kExtendedPropValue, /*maybe_truncated=*/false);
2295   };
2296   fake_client()->set_read_request_callback(std::move(extended_prop_read_cb));
2297 
2298   auto service = SetupServiceWithChrcs(
2299       ServiceData(ServiceKind::PRIMARY, kStart, kEnd, kTestServiceUuid1),
2300       {WriteableExtendedPropChrc()},
2301       {fake_desc1, fake_desc2});
2302 
2303   // Create a vector that will take 1 request to write. Since the default MTU
2304   // is 23:
2305   //   a. The size of |full_write_value| is 18.
2306   //   b. att:Handle, |kOffset|, and att::OpCode size is 5 bytes total.
2307   //   c. We should write 18 bytes.
2308   std::vector<uint8_t> full_write_value((att::kLEMinMTU - 5));
2309 
2310   // Initialize the contents.
2311   for (size_t i = 0; i < full_write_value.size(); ++i) {
2312     full_write_value[i] = i;
2313   }
2314 
2315   uint8_t process_long_write_count = 0;
2316   fake_client()->set_execute_prepare_writes_callback(
2317       [&](att::PrepareWriteQueue write_queue,
2318           auto /*reliable_mode*/,
2319           auto callback) {
2320         EXPECT_EQ(write_queue.size(), kExpectedQueueSize);
2321         process_long_write_count++;
2322         callback(fit::ok());
2323       });
2324 
2325   ReliableMode mode = ReliableMode::kEnabled;
2326   att::Result<> status = ToResult(HostError::kFailed);
2327   service->WriteLongCharacteristic(
2328       kDefaultCharacteristic,
2329       kOffset,
2330       full_write_value,
2331       mode,
2332       [&](att::Result<> cb_status) { status = cb_status; });
2333 
2334   RunUntilIdle();
2335   EXPECT_EQ(fit::ok(), status);
2336   EXPECT_EQ(1u, process_long_write_count);
2337 }
2338 
TEST_F(RemoteServiceManagerTest,WriteWithoutResponseNotSupported)2339 TEST_F(RemoteServiceManagerTest, WriteWithoutResponseNotSupported) {
2340   ServiceData data(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1);
2341   auto service = SetUpFakeService(data);
2342 
2343   // No "write" or "write without response" property.
2344   CharacteristicData chr(0, std::nullopt, 2, 3, kTestUuid3);
2345   SetupCharacteristics(service, {{chr}});
2346 
2347   bool called = false;
2348   fake_client()->set_write_without_rsp_callback(
2349       [&](auto, const auto&, auto) { called = true; });
2350 
2351   std::optional<att::Result<>> status;
2352   service->WriteCharacteristicWithoutResponse(
2353       kDefaultCharacteristic,
2354       std::vector<uint8_t>(),
2355       [&](att::Result<> cb_status) { status = cb_status; });
2356   RunUntilIdle();
2357   EXPECT_FALSE(called);
2358   ASSERT_TRUE(status.has_value());
2359   EXPECT_EQ(ToResult(HostError::kNotSupported), *status);
2360 }
2361 
TEST_F(RemoteServiceManagerTest,WriteWithoutResponseBeforeCharacteristicDiscovery)2362 TEST_F(RemoteServiceManagerTest,
2363        WriteWithoutResponseBeforeCharacteristicDiscovery) {
2364   ServiceData data(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1);
2365   auto service = SetUpFakeService(data);
2366 
2367   bool called = false;
2368   fake_client()->set_write_without_rsp_callback(
2369       [&](auto, const auto&, auto) { called = true; });
2370 
2371   std::optional<att::Result<>> status;
2372   service->WriteCharacteristicWithoutResponse(
2373       kDefaultCharacteristic,
2374       std::vector<uint8_t>(),
2375       [&](att::Result<> cb_status) { status = cb_status; });
2376   RunUntilIdle();
2377   EXPECT_FALSE(called);
2378   ASSERT_TRUE(status.has_value());
2379   EXPECT_EQ(ToResult(HostError::kNotReady), *status);
2380 }
2381 
TEST_F(RemoteServiceManagerTest,WriteWithoutResponseSuccessWithWriteWithoutResponseProperty)2382 TEST_F(RemoteServiceManagerTest,
2383        WriteWithoutResponseSuccessWithWriteWithoutResponseProperty) {
2384   const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
2385 
2386   CharacteristicData chr(Property::kWriteWithoutResponse,
2387                          std::nullopt,
2388                          2,
2389                          kDefaultChrcValueHandle,
2390                          kTestUuid3);
2391   auto service = SetupServiceWithChrcs(
2392       ServiceData(
2393           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
2394       {chr});
2395 
2396   bool called = false;
2397   fake_client()->set_write_without_rsp_callback(
2398       [&](att::Handle handle, const auto& value, att::ResultFunction<> cb) {
2399         EXPECT_EQ(kDefaultChrcValueHandle, handle);
2400         EXPECT_TRUE(std::equal(
2401             kValue.begin(), kValue.end(), value.begin(), value.end()));
2402         called = true;
2403         cb(fit::ok());
2404       });
2405 
2406   std::optional<att::Result<>> status;
2407   service->WriteCharacteristicWithoutResponse(
2408       kDefaultCharacteristic, kValue, [&](att::Result<> cb_status) {
2409         status = cb_status;
2410       });
2411   RunUntilIdle();
2412   EXPECT_TRUE(called);
2413   ASSERT_TRUE(status.has_value());
2414   EXPECT_EQ(fit::ok(), *status);
2415 }
2416 
TEST_F(RemoteServiceManagerTest,WriteWithoutResponseSuccessWithWriteProperty)2417 TEST_F(RemoteServiceManagerTest, WriteWithoutResponseSuccessWithWriteProperty) {
2418   const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
2419 
2420   CharacteristicData chr(
2421       Property::kWrite, std::nullopt, 2, kDefaultChrcValueHandle, kTestUuid3);
2422   auto service = SetupServiceWithChrcs(
2423       ServiceData(
2424           ServiceKind::PRIMARY, 1, kDefaultChrcValueHandle, kTestServiceUuid1),
2425       {chr});
2426 
2427   bool called = false;
2428   fake_client()->set_write_without_rsp_callback(
2429       [&](att::Handle handle, const auto& value, att::ResultFunction<> cb) {
2430         EXPECT_EQ(kDefaultChrcValueHandle, handle);
2431         EXPECT_TRUE(std::equal(
2432             kValue.begin(), kValue.end(), value.begin(), value.end()));
2433         called = true;
2434         cb(fit::ok());
2435       });
2436 
2437   std::optional<att::Result<>> status;
2438   service->WriteCharacteristicWithoutResponse(
2439       kDefaultCharacteristic, kValue, [&](att::Result<> cb_status) {
2440         status = cb_status;
2441       });
2442   RunUntilIdle();
2443 
2444   EXPECT_TRUE(called);
2445   ASSERT_TRUE(status.has_value());
2446   EXPECT_EQ(fit::ok(), *status);
2447 }
2448 
TEST_F(RemoteServiceManagerTest,ReadDescWhileNotReady)2449 TEST_F(RemoteServiceManagerTest, ReadDescWhileNotReady) {
2450   auto service = SetUpFakeService(
2451       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2452 
2453   att::Result<> status = fit::ok();
2454   service->ReadDescriptor(0, [&](att::Result<> cb_status, const auto&, auto) {
2455     status = cb_status;
2456   });
2457 
2458   RunUntilIdle();
2459 
2460   EXPECT_EQ(ToResult(HostError::kNotReady), status);
2461 }
2462 
TEST_F(RemoteServiceManagerTest,ReadDescriptorNotFound)2463 TEST_F(RemoteServiceManagerTest, ReadDescriptorNotFound) {
2464   auto service = SetupServiceWithChrcs(
2465       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
2466 
2467   att::Result<> status = fit::ok();
2468   service->ReadDescriptor(0, [&](att::Result<> cb_status, const auto&, auto) {
2469     status = cb_status;
2470   });
2471 
2472   RunUntilIdle();
2473 
2474   EXPECT_EQ(ToResult(HostError::kNotFound), status);
2475 }
2476 
TEST_F(RemoteServiceManagerTest,ReadDescSendsReadRequest)2477 TEST_F(RemoteServiceManagerTest, ReadDescSendsReadRequest) {
2478   // TODO(armansito): Some of the service set up and |status| verification
2479   // boilerplate could be reduced by factoring them out into helpers on the test
2480   // harness (also see code review comment in
2481   // https://fuchsia-review.googlesource.com/c/garnet/+/213794/6/drivers/bluetooth/lib/gatt/remote_service_manager_test.cc).
2482   constexpr att::Handle kValueHandle1 = 3;
2483   constexpr att::Handle kValueHandle2 = 5;
2484   constexpr att::Handle kDescrHandle = 6;
2485 
2486   ServiceData data(ServiceKind::PRIMARY, 1, kDescrHandle, kTestServiceUuid1);
2487   auto service = SetUpFakeService(data);
2488 
2489   CharacteristicData chr1(
2490       Property::kRead, std::nullopt, 2, kValueHandle1, kTestUuid3);
2491   CharacteristicData chr2(
2492       Property::kRead, std::nullopt, 4, kValueHandle2, kTestUuid3);
2493   DescriptorData desc(kDescrHandle, kTestUuid4);
2494   SetupCharacteristics(service, {{chr1, chr2}}, {{desc}});
2495 
2496   const StaticByteBuffer kValue('t', 'e', 's', 't');
2497 
2498   fake_client()->set_read_request_callback(
2499       [&](att::Handle handle, auto callback) {
2500         EXPECT_EQ(kDescrHandle, handle);
2501         callback(fit::ok(), kValue, /*maybe_truncated=*/false);
2502       });
2503 
2504   att::Result<> status = ToResult(HostError::kFailed);
2505   service->ReadDescriptor(
2506       DescriptorHandle(kDescrHandle),
2507       [&](att::Result<> cb_status, const auto& value, auto) {
2508         status = cb_status;
2509         EXPECT_TRUE(ContainersEqual(kValue, value));
2510       });
2511 
2512   RunUntilIdle();
2513 
2514   EXPECT_EQ(fit::ok(), status);
2515 }
2516 
TEST_F(RemoteServiceManagerTest,ReadLongDescWhileNotReady)2517 TEST_F(RemoteServiceManagerTest, ReadLongDescWhileNotReady) {
2518   auto service = SetUpFakeService(
2519       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2520 
2521   att::Result<> status = fit::ok();
2522   service->ReadLongDescriptor(
2523       0, 0, 512, [&](att::Result<> cb_status, const auto&, auto) {
2524         status = cb_status;
2525       });
2526 
2527   RunUntilIdle();
2528 
2529   EXPECT_EQ(ToResult(HostError::kNotReady), status);
2530 }
2531 
TEST_F(RemoteServiceManagerTest,ReadLongDescNotFound)2532 TEST_F(RemoteServiceManagerTest, ReadLongDescNotFound) {
2533   auto service = SetupServiceWithChrcs(
2534       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
2535 
2536   att::Result<> status = fit::ok();
2537   service->ReadLongDescriptor(
2538       0, 0, 512, [&](att::Result<> cb_status, const auto&, auto) {
2539         status = cb_status;
2540       });
2541 
2542   RunUntilIdle();
2543 
2544   EXPECT_EQ(ToResult(HostError::kNotFound), status);
2545 }
2546 
2547 // Tests that ReadLongDescriptor sends Read Blob requests. Other conditions
2548 // around the long read procedure are already covered by the tests for
2549 // ReadLongCharacteristic as the implementations are shared.
TEST_F(RemoteServiceManagerTest,ReadLongDescriptor)2550 TEST_F(RemoteServiceManagerTest, ReadLongDescriptor) {
2551   constexpr att::Handle kValueHandle = 3;
2552   constexpr att::Handle kDescrHandle = 4;
2553   constexpr uint16_t kOffset = 0;
2554   constexpr size_t kMaxBytes = 1000;
2555   constexpr int kExpectedBlobCount = 4;
2556 
2557   ServiceData data(ServiceKind::PRIMARY, 1, kDescrHandle, kTestServiceUuid1);
2558   auto service = SetUpFakeService(data);
2559 
2560   CharacteristicData chr(
2561       Property::kRead, std::nullopt, 2, kValueHandle, kTestUuid3);
2562   DescriptorData desc(kDescrHandle, kTestUuid4);
2563   SetupCharacteristics(service, {{chr}}, {{desc}});
2564 
2565   // Create a buffer that will take 4 requests to read. Since the default MTU is
2566   // 23:
2567   //   a. The size of |expected_value| is 69.
2568   //   b. We should read 22 + 22 + 22 + 3 bytes across 4 requests.
2569   StaticByteBuffer<att::kLEMinMTU * 3> expected_value;
2570 
2571   // Initialize the contents.
2572   for (size_t i = 0; i < expected_value.size(); ++i) {
2573     expected_value[i] = i;
2574   }
2575 
2576   int read_count = 0;
2577   fake_client()->set_read_request_callback(
2578       [&](att::Handle handle, auto callback) {
2579         read_count++;
2580         EXPECT_EQ(read_count, 1);
2581         EXPECT_EQ(kDescrHandle, handle);
2582         auto blob = expected_value.view(0, att::kLEMinMTU - 1);
2583         callback(fit::ok(), blob, /*maybe_truncated=*/true);
2584       });
2585 
2586   fake_client()->set_read_blob_request_callback(
2587       [&](att::Handle handle, uint16_t offset, auto callback) {
2588         read_count++;
2589         EXPECT_GT(read_count, 1);
2590         EXPECT_EQ(kDescrHandle, handle);
2591         bool maybe_truncated = true;
2592 
2593         // Return a blob at the given offset with at most MTU - 1 bytes.
2594         auto blob = expected_value.view(offset, att::kLEMinMTU - 1);
2595         if (read_count == kExpectedBlobCount) {
2596           // The final blob should contain 3 bytes.
2597           EXPECT_EQ(3u, blob.size());
2598           maybe_truncated = false;
2599         }
2600 
2601         callback(fit::ok(), blob, maybe_truncated);
2602       });
2603 
2604   att::Result<> status = ToResult(HostError::kFailed);
2605   service->ReadLongDescriptor(
2606       DescriptorHandle(kDescrHandle),
2607       kOffset,
2608       kMaxBytes,
2609       [&](att::Result<> cb_status, const auto& value, bool maybe_truncated) {
2610         status = cb_status;
2611         EXPECT_TRUE(ContainersEqual(expected_value, value));
2612         EXPECT_FALSE(maybe_truncated);
2613       });
2614 
2615   RunUntilIdle();
2616   EXPECT_EQ(fit::ok(), status);
2617   EXPECT_EQ(kExpectedBlobCount, read_count);
2618 }
2619 
TEST_F(RemoteServiceManagerTest,WriteDescWhileNotReady)2620 TEST_F(RemoteServiceManagerTest, WriteDescWhileNotReady) {
2621   auto service = SetUpFakeService(
2622       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2623 
2624   att::Result<> status = fit::ok();
2625   service->WriteDescriptor(
2626       0, std::vector<uint8_t>(), [&](att::Result<> cb_status) {
2627         status = cb_status;
2628       });
2629 
2630   RunUntilIdle();
2631 
2632   EXPECT_EQ(ToResult(HostError::kNotReady), status);
2633 }
2634 
TEST_F(RemoteServiceManagerTest,WriteDescNotFound)2635 TEST_F(RemoteServiceManagerTest, WriteDescNotFound) {
2636   auto service = SetUpFakeService(
2637       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2638   SetupCharacteristics(service, std::vector<CharacteristicData>());
2639 
2640   att::Result<> status = fit::ok();
2641   service->WriteDescriptor(
2642       0, std::vector<uint8_t>(), [&](att::Result<> cb_status) {
2643         status = cb_status;
2644       });
2645 
2646   RunUntilIdle();
2647 
2648   EXPECT_EQ(ToResult(HostError::kNotFound), status);
2649 }
2650 
TEST_F(RemoteServiceManagerTest,WriteDescNotAllowed)2651 TEST_F(RemoteServiceManagerTest, WriteDescNotAllowed) {
2652   auto service = SetUpFakeService(
2653       ServiceData(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1));
2654 
2655   // "CCC" characteristic cannot be written to.
2656   CharacteristicData chr(0, std::nullopt, 2, 3, kTestUuid3);
2657   DescriptorData desc(4, types::kClientCharacteristicConfig);
2658   SetupCharacteristics(service, {{chr}}, {{desc}});
2659 
2660   att::Result<> status = fit::ok();
2661   service->WriteDescriptor(
2662       4, std::vector<uint8_t>(), [&](att::Result<> cb_status) {
2663         status = cb_status;
2664       });
2665 
2666   RunUntilIdle();
2667 
2668   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
2669 }
2670 
TEST_F(RemoteServiceManagerTest,WriteDescSendsWriteRequest)2671 TEST_F(RemoteServiceManagerTest, WriteDescSendsWriteRequest) {
2672   constexpr att::Handle kValueHandle = 3;
2673   constexpr att::Handle kDescrHandle = 4;
2674   const std::vector<uint8_t> kValue{{'t', 'e', 's', 't'}};
2675   const att::Result<> kStatus = ToResult(HostError::kNotSupported);
2676 
2677   ServiceData data(ServiceKind::PRIMARY, 1, kDescrHandle, kTestServiceUuid1);
2678   auto service = SetUpFakeService(data);
2679 
2680   CharacteristicData chr(
2681       Property::kWrite, std::nullopt, 2, kValueHandle, kTestUuid3);
2682   DescriptorData desc(kDescrHandle, kTestUuid4);
2683   SetupCharacteristics(service, {{chr}}, {{desc}});
2684 
2685   fake_client()->set_write_request_callback(
2686       [&](att::Handle handle, const auto& value, auto status_callback) {
2687         EXPECT_EQ(kDescrHandle, handle);
2688         EXPECT_TRUE(std::equal(
2689             kValue.begin(), kValue.end(), value.begin(), value.end()));
2690         status_callback(kStatus);
2691       });
2692 
2693   att::Result<> status = fit::ok();
2694   service->WriteDescriptor(kDescrHandle, kValue, [&](att::Result<> cb_status) {
2695     status = cb_status;
2696   });
2697 
2698   RunUntilIdle();
2699   EXPECT_EQ(kStatus, status);
2700 }
2701 
2702 // Tests that WriteDescriptor with a long vector is prepared correctly.
2703 // Other conditions around the long write procedure are already covered by the
2704 // tests for WriteCharacteristic as the implementations are shared.
TEST_F(RemoteServiceManagerTest,WriteDescLongSuccess)2705 TEST_F(RemoteServiceManagerTest, WriteDescLongSuccess) {
2706   constexpr att::Handle kValueHandle = 3;
2707   constexpr att::Handle kDescrHandle = 4;
2708   constexpr uint16_t kOffset = 0;
2709   constexpr uint16_t kExpectedQueueSize = 4;
2710   constexpr uint16_t kExpectedFullWriteSize = 18;
2711   constexpr uint16_t kExpectedFinalWriteSize = 15;
2712 
2713   ServiceData data(ServiceKind::PRIMARY, 1, kDescrHandle, kTestServiceUuid1);
2714   auto service = SetUpFakeService(data);
2715 
2716   CharacteristicData chr(
2717       Property::kWrite, std::nullopt, 2, kValueHandle, kTestUuid3);
2718   DescriptorData desc(kDescrHandle, kTestUuid4);
2719   SetupCharacteristics(service, {{chr}}, {{desc}});
2720 
2721   // Create a vector that will take 4 requests to write. Since the default MTU
2722   // is 23:
2723   //   a. The size of |full_write_value| is 69.
2724   //   b. att:Handle, |kOffset|, and att::OpCode size is 5 bytes total.
2725   //   c. We should write 18 + 18 + 18 + 15 bytes across 4 requests.
2726   //   d. These bytes will be written with offset 5, from (5) to (5+69)
2727   std::vector<uint8_t> full_write_value(att::kLEMinMTU * 3);
2728 
2729   // Initialize the contents.
2730   for (size_t i = 0; i < full_write_value.size(); ++i) {
2731     full_write_value[i] = i;
2732   }
2733 
2734   uint8_t process_long_write_count = 0;
2735   fake_client()->set_execute_prepare_writes_callback(
2736       [&](att::PrepareWriteQueue write_queue,
2737           auto /*reliable_mode*/,
2738           auto callback) {
2739         EXPECT_EQ(write_queue.size(), kExpectedQueueSize);
2740 
2741         att::QueuedWrite prepare_write;
2742         for (int i = 0; i < kExpectedQueueSize; i++) {
2743           auto write = std::move(write_queue.front());
2744           write_queue.pop();
2745 
2746           EXPECT_EQ(write.handle(), kDescrHandle);
2747           EXPECT_EQ(write.offset(), kOffset + (i * kExpectedFullWriteSize));
2748 
2749           // All writes expect the final should be full, the final should be
2750           // the remainder.
2751           if (i < kExpectedQueueSize - 1) {
2752             EXPECT_EQ(write.value().size(), kExpectedFullWriteSize);
2753           } else {
2754             EXPECT_EQ(write.value().size(), kExpectedFinalWriteSize);
2755           }
2756         }
2757 
2758         process_long_write_count++;
2759 
2760         callback(fit::ok());
2761       });
2762 
2763   att::Result<> status = ToResult(HostError::kFailed);
2764   service->WriteLongDescriptor(
2765       DescriptorHandle(kDescrHandle),
2766       kOffset,
2767       full_write_value,
2768       [&](att::Result<> cb_status) { status = cb_status; });
2769 
2770   RunUntilIdle();
2771   EXPECT_EQ(fit::ok(), status);
2772   EXPECT_EQ(1u, process_long_write_count);
2773 }
2774 
TEST_F(RemoteServiceManagerTest,EnableNotificationsWhileNotReady)2775 TEST_F(RemoteServiceManagerTest, EnableNotificationsWhileNotReady) {
2776   auto service = SetUpFakeService(
2777       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1));
2778 
2779   att::Result<> status = fit::ok();
2780   service->EnableNotifications(
2781       kDefaultCharacteristic,
2782       NopValueCallback,
2783       [&](att::Result<> cb_status, IdType) { status = cb_status; });
2784 
2785   RunUntilIdle();
2786 
2787   EXPECT_EQ(ToResult(HostError::kNotReady), status);
2788 }
2789 
TEST_F(RemoteServiceManagerTest,EnableNotificationsCharNotFound)2790 TEST_F(RemoteServiceManagerTest, EnableNotificationsCharNotFound) {
2791   auto service = SetupServiceWithChrcs(
2792       ServiceData(ServiceKind::PRIMARY, 1, 2, kTestServiceUuid1), {});
2793 
2794   att::Result<> status = fit::ok();
2795   service->EnableNotifications(
2796       kDefaultCharacteristic,
2797       NopValueCallback,
2798       [&](att::Result<> cb_status, IdType) { status = cb_status; });
2799 
2800   RunUntilIdle();
2801 
2802   EXPECT_EQ(ToResult(HostError::kNotFound), status);
2803 }
2804 
TEST_F(RemoteServiceManagerTest,EnableNotificationsNoProperties)2805 TEST_F(RemoteServiceManagerTest, EnableNotificationsNoProperties) {
2806   auto service = SetUpFakeService(
2807       ServiceData(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1));
2808 
2809   // Has neither the "notify" nor "indicate" property but has a CCC descriptor.
2810   CharacteristicData chr(Property::kRead, std::nullopt, 2, 3, kTestUuid3);
2811   DescriptorData desc(4, types::kClientCharacteristicConfig);
2812   SetupCharacteristics(service, {{chr}}, {{desc}});
2813 
2814   att::Result<> status = fit::ok();
2815   service->EnableNotifications(
2816       kDefaultCharacteristic,
2817       NopValueCallback,
2818       [&](att::Result<> cb_status, IdType) { status = cb_status; });
2819   RunUntilIdle();
2820 
2821   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
2822 }
2823 
TEST_F(RemoteServiceManagerTest,EnableNotificationsSuccess)2824 TEST_F(RemoteServiceManagerTest, EnableNotificationsSuccess) {
2825   constexpr att::Handle kCCCHandle = 4;
2826   auto service = SetUpFakeService(
2827       ServiceData(ServiceKind::PRIMARY, 1, kCCCHandle, kTestServiceUuid1));
2828 
2829   CharacteristicData chr(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
2830   DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
2831   SetupCharacteristics(service, {{chr}}, {{desc}});
2832 
2833   fake_client()->set_write_request_callback(
2834       [&](att::Handle handle, const auto& value, auto status_callback) {
2835         EXPECT_EQ(kCCCHandle, handle);
2836         EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));
2837         status_callback(fit::ok());
2838       });
2839 
2840   IdType id = kInvalidId;
2841   att::Result<> status = ToResult(HostError::kFailed);
2842   service->EnableNotifications(kDefaultCharacteristic,
2843                                NopValueCallback,
2844                                [&](att::Result<> cb_status, IdType cb_id) {
2845                                  status = cb_status;
2846                                  id = cb_id;
2847                                });
2848 
2849   RunUntilIdle();
2850 
2851   EXPECT_EQ(fit::ok(), status);
2852   EXPECT_NE(kInvalidId, id);
2853 }
2854 
TEST_F(RemoteServiceManagerTest,EnableIndications)2855 TEST_F(RemoteServiceManagerTest, EnableIndications) {
2856   constexpr att::Handle kCCCHandle = 4;
2857   auto service = SetUpFakeService(
2858       ServiceData(ServiceKind::PRIMARY, 1, kCCCHandle, kTestServiceUuid1));
2859 
2860   CharacteristicData chr(Property::kIndicate, std::nullopt, 2, 3, kTestUuid3);
2861   DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
2862   SetupCharacteristics(service, {{chr}}, {{desc}});
2863 
2864   fake_client()->set_write_request_callback(
2865       [&](att::Handle handle, const auto& value, auto status_callback) {
2866         EXPECT_EQ(kCCCHandle, handle);
2867         EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
2868         status_callback(fit::ok());
2869       });
2870 
2871   IdType id = kInvalidId;
2872   att::Result<> status = ToResult(HostError::kFailed);
2873   service->EnableNotifications(kDefaultCharacteristic,
2874                                NopValueCallback,
2875                                [&](att::Result<> cb_status, IdType cb_id) {
2876                                  status = cb_status;
2877                                  id = cb_id;
2878                                });
2879 
2880   RunUntilIdle();
2881 
2882   EXPECT_EQ(fit::ok(), status);
2883   EXPECT_NE(kInvalidId, id);
2884 }
2885 
TEST_F(RemoteServiceManagerTest,EnableNotificationsError)2886 TEST_F(RemoteServiceManagerTest, EnableNotificationsError) {
2887   constexpr att::Handle kCCCHandle = 4;
2888 
2889   auto service = SetUpFakeService(
2890       ServiceData(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1));
2891 
2892   CharacteristicData chr(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
2893   DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
2894   SetupCharacteristics(service, {{chr}}, {{desc}});
2895 
2896   // Should enable notifications
2897   const StaticByteBuffer kExpectedValue(0x01, 0x00);
2898 
2899   fake_client()->set_write_request_callback(
2900       [&](att::Handle handle, const auto& value, auto status_callback) {
2901         EXPECT_EQ(kCCCHandle, handle);
2902         EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
2903         status_callback(ToResult(att::ErrorCode::kUnlikelyError));
2904       });
2905 
2906   IdType id = kInvalidId;
2907   att::Result<> status = fit::ok();
2908   service->EnableNotifications(kDefaultCharacteristic,
2909                                NopValueCallback,
2910                                [&](att::Result<> cb_status, IdType cb_id) {
2911                                  status = cb_status;
2912                                  id = cb_id;
2913                                });
2914 
2915   RunUntilIdle();
2916 
2917   EXPECT_EQ(ToResult(att::ErrorCode::kUnlikelyError), status);
2918   EXPECT_EQ(kInvalidId, id);
2919 }
2920 
TEST_F(RemoteServiceManagerTest,EnableNotificationsRequestMany)2921 TEST_F(RemoteServiceManagerTest, EnableNotificationsRequestMany) {
2922   constexpr att::Handle kCCCHandle1 = 4;
2923   constexpr att::Handle kCCCHandle2 = 7;
2924 
2925   auto service = SetUpFakeService(
2926       ServiceData(ServiceKind::PRIMARY, 1, 7, kTestServiceUuid1));
2927 
2928   // Set up two characteristics
2929   CharacteristicData chr1(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
2930   DescriptorData desc1(kCCCHandle1, types::kClientCharacteristicConfig);
2931 
2932   CharacteristicData chr2(Property::kIndicate, std::nullopt, 5, 6, kTestUuid3);
2933   DescriptorData desc2(kCCCHandle2, types::kClientCharacteristicConfig);
2934 
2935   SetupCharacteristics(service, {{chr1, chr2}}, {{desc1, desc2}});
2936 
2937   int ccc_write_count = 0;
2938   att::ResultFunction<> status_callback1, status_callback2;
2939   fake_client()->set_write_request_callback(
2940       [&](att::Handle handle, const auto& value, auto status_cb) {
2941         if (handle == kCCCHandle1) {
2942           EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));
2943           status_callback1 = std::move(status_cb);
2944         } else if (handle == kCCCHandle2) {
2945           EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
2946           status_callback2 = std::move(status_cb);
2947         } else {
2948           ADD_FAILURE() << "Unexpected handle: " << handle;
2949         }
2950         ccc_write_count++;
2951       });
2952 
2953   size_t cb_count = 0u;
2954 
2955   service->EnableNotifications(kDefaultCharacteristic,
2956                                NopValueCallback,
2957                                [&](att::Result<> status, IdType id) {
2958                                  cb_count++;
2959                                  EXPECT_EQ(1u, id);
2960                                  EXPECT_EQ(fit::ok(), status);
2961                                });
2962   service->EnableNotifications(kDefaultCharacteristic,
2963                                NopValueCallback,
2964                                [&](att::Result<> status, IdType id) {
2965                                  cb_count++;
2966                                  EXPECT_EQ(2u, id);
2967                                  EXPECT_EQ(fit::ok(), status);
2968                                });
2969   service->EnableNotifications(kSecondCharacteristic,
2970                                NopValueCallback,
2971                                [&](att::Result<> status, IdType id) {
2972                                  cb_count++;
2973                                  EXPECT_EQ(1u, id);
2974                                  EXPECT_EQ(fit::ok(), status);
2975                                });
2976   service->EnableNotifications(kSecondCharacteristic,
2977                                NopValueCallback,
2978                                [&](att::Result<> status, IdType id) {
2979                                  cb_count++;
2980                                  EXPECT_EQ(2u, id);
2981                                  EXPECT_EQ(fit::ok(), status);
2982                                });
2983   service->EnableNotifications(kSecondCharacteristic,
2984                                NopValueCallback,
2985                                [&](att::Result<> status, IdType id) {
2986                                  cb_count++;
2987                                  EXPECT_EQ(3u, id);
2988                                  EXPECT_EQ(fit::ok(), status);
2989                                });
2990 
2991   RunUntilIdle();
2992 
2993   // ATT write requests should be sent but none of the notification requests
2994   // should be resolved.
2995   EXPECT_EQ(2, ccc_write_count);
2996   EXPECT_EQ(0u, cb_count);
2997 
2998   // An ATT response should resolve all pending requests for the right
2999   // characteristic.
3000   status_callback1(fit::ok());
3001   EXPECT_EQ(2u, cb_count);
3002   status_callback2(fit::ok());
3003   EXPECT_EQ(5u, cb_count);
3004 
3005   // An extra request should succeed without sending any PDUs.
3006   service->EnableNotifications(kDefaultCharacteristic,
3007                                NopValueCallback,
3008                                [&](att::Result<> status, IdType) {
3009                                  cb_count++;
3010                                  EXPECT_EQ(fit::ok(), status);
3011                                });
3012 
3013   RunUntilIdle();
3014 
3015   EXPECT_EQ(2, ccc_write_count);
3016   EXPECT_EQ(6u, cb_count);
3017 }
3018 
TEST_F(RemoteServiceManagerTest,EnableNotificationsRequestManyError)3019 TEST_F(RemoteServiceManagerTest, EnableNotificationsRequestManyError) {
3020   constexpr att::Handle kCCCHandle = 4;
3021 
3022   auto service = SetUpFakeService(
3023       ServiceData(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1));
3024 
3025   // Set up two characteristics
3026   CharacteristicData chr(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
3027   DescriptorData desc(kCCCHandle, types::kClientCharacteristicConfig);
3028 
3029   SetupCharacteristics(service, {{chr}}, {{desc}});
3030 
3031   int ccc_write_count = 0;
3032   att::ResultFunction<> status_callback;
3033   fake_client()->set_write_request_callback(
3034       [&](att::Handle handle, const auto& value, auto status_cb) {
3035         EXPECT_EQ(kCCCHandle, handle);
3036         EXPECT_TRUE(ContainersEqual(kCCCNotifyValue, value));
3037 
3038         ccc_write_count++;
3039         status_callback = std::move(status_cb);
3040       });
3041 
3042   int cb_count = 0;
3043   att::Result<> status = fit::ok();
3044   auto cb = [&](att::Result<> cb_status, IdType id) {
3045     status = cb_status;
3046     cb_count++;
3047   };
3048 
3049   service->EnableNotifications(
3050       kDefaultCharacteristic, NopValueCallback, std::move(cb));
3051   service->EnableNotifications(
3052       kDefaultCharacteristic, NopValueCallback, std::move(cb));
3053   service->EnableNotifications(
3054       kDefaultCharacteristic, NopValueCallback, std::move(cb));
3055 
3056   RunUntilIdle();
3057 
3058   // Requests should be buffered and only one ATT request should have been sent
3059   // out.
3060   EXPECT_EQ(1, ccc_write_count);
3061   EXPECT_EQ(0, cb_count);
3062 
3063   status_callback(ToResult(HostError::kNotSupported));
3064   EXPECT_EQ(3, cb_count);
3065   EXPECT_EQ(ToResult(HostError::kNotSupported), status);
3066 
3067   // A new request should write to the descriptor again.
3068   service->EnableNotifications(
3069       kDefaultCharacteristic, NopValueCallback, std::move(cb));
3070 
3071   RunUntilIdle();
3072 
3073   EXPECT_EQ(2, ccc_write_count);
3074   EXPECT_EQ(3, cb_count);
3075 
3076   status_callback(fit::ok());
3077   EXPECT_EQ(2, ccc_write_count);
3078   EXPECT_EQ(4, cb_count);
3079   EXPECT_EQ(fit::ok(), status);
3080 }
3081 
3082 // Enabling notifications should succeed without a descriptor write.
TEST_F(RemoteServiceManagerTest,EnableNotificationsWithoutCCC)3083 TEST_F(RemoteServiceManagerTest, EnableNotificationsWithoutCCC) {
3084   // Has the "notify" property but no CCC descriptor.
3085   CharacteristicData chr(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
3086   auto service = SetupServiceWithChrcs(
3087       ServiceData(ServiceKind::PRIMARY, 1, 3, kTestServiceUuid1), {chr});
3088 
3089   bool write_requested = false;
3090   fake_client()->set_write_request_callback(
3091       [&](auto, auto&, auto) { write_requested = true; });
3092 
3093   int notify_count = 0;
3094   auto notify_cb = [&](const auto& value, bool /*maybe_truncated*/) {
3095     notify_count++;
3096   };
3097 
3098   att::Result<> status = fit::ok();
3099   IdType id;
3100   service->EnableNotifications(kDefaultCharacteristic,
3101                                std::move(notify_cb),
3102                                [&](att::Result<> _status, IdType _id) {
3103                                  status = _status;
3104                                  id = _id;
3105                                });
3106   RunUntilIdle();
3107 
3108   EXPECT_EQ(fit::ok(), status);
3109   EXPECT_FALSE(write_requested);
3110 
3111   fake_client()->SendNotification(/*indicate=*/false,
3112                                   3,
3113                                   StaticByteBuffer('y', 'e'),
3114                                   /*maybe_truncated=*/false);
3115   EXPECT_EQ(1, notify_count);
3116 
3117   // Disabling notifications should not result in a write request.
3118   service->DisableNotifications(
3119       kDefaultCharacteristic, id, [&](auto _status) { status = _status; });
3120   RunUntilIdle();
3121   EXPECT_EQ(fit::ok(), status);
3122   EXPECT_FALSE(write_requested);
3123 
3124   // The handler should no longer receive notifications.
3125   fake_client()->SendNotification(/*indicate=*/false,
3126                                   3,
3127                                   StaticByteBuffer('o', 'y', 'e'),
3128                                   /*maybe_truncated=*/false);
3129   EXPECT_EQ(1, notify_count);
3130 }
3131 
3132 // Notifications received when the remote service database is empty should be
3133 // dropped and not cause a crash.
TEST_F(RemoteServiceManagerTest,NotificationWithoutServices)3134 TEST_F(RemoteServiceManagerTest, NotificationWithoutServices) {
3135   for (att::Handle i = 0; i < 10; ++i) {
3136     fake_client()->SendNotification(
3137         /*indicate=*/false,
3138         i,
3139         StaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'),
3140         /*maybe_truncated=*/false);
3141   }
3142   RunUntilIdle();
3143 }
3144 
TEST_F(RemoteServiceManagerTest,NotificationCallback)3145 TEST_F(RemoteServiceManagerTest, NotificationCallback) {
3146   auto service = SetUpFakeService(
3147       ServiceData(ServiceKind::PRIMARY, 1, 7, kTestServiceUuid1));
3148 
3149   // Set up two characteristics
3150   CharacteristicData chr1(Property::kNotify, std::nullopt, 2, 3, kTestUuid3);
3151   DescriptorData desc1(4, types::kClientCharacteristicConfig);
3152 
3153   CharacteristicData chr2(Property::kIndicate, std::nullopt, 5, 6, kTestUuid3);
3154   DescriptorData desc2(7, types::kClientCharacteristicConfig);
3155 
3156   SetupCharacteristics(service, {{chr1, chr2}}, {{desc1, desc2}});
3157 
3158   fake_client()->set_write_request_callback(
3159       [&](att::Handle, const auto&, auto status_callback) {
3160         status_callback(fit::ok());
3161       });
3162 
3163   IdType handler_id = kInvalidId;
3164   att::Result<> status = ToResult(HostError::kFailed);
3165 
3166   int chr1_count = 0;
3167   auto chr1_cb = [&](const ByteBuffer& value, bool maybe_truncated) {
3168     chr1_count++;
3169     EXPECT_EQ("notify", value.AsString());
3170     EXPECT_FALSE(maybe_truncated);
3171   };
3172 
3173   int chr2_count = 0;
3174   auto chr2_cb = [&](const ByteBuffer& value, bool maybe_truncated) {
3175     chr2_count++;
3176     EXPECT_EQ("indicate", value.AsString());
3177     EXPECT_TRUE(maybe_truncated);
3178   };
3179 
3180   // Notify both characteristics which should get dropped.
3181   fake_client()->SendNotification(
3182       /*indicate=*/false,
3183       3,
3184       StaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'),
3185       /*maybe_truncated=*/false);
3186   fake_client()->SendNotification(
3187       /*indicate=*/true,
3188       6,
3189       StaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'),
3190       /*maybe_truncated=*/true);
3191 
3192   EnableNotifications(service,
3193                       kDefaultCharacteristic,
3194                       &status,
3195                       &handler_id,
3196                       std::move(chr1_cb));
3197   ASSERT_EQ(fit::ok(), status);
3198   EnableNotifications(
3199       service, kSecondCharacteristic, &status, &handler_id, std::move(chr2_cb));
3200   ASSERT_EQ(fit::ok(), status);
3201 
3202   // Notify characteristic 1.
3203   fake_client()->SendNotification(
3204       /*indicate=*/false,
3205       3,
3206       StaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'),
3207       /*maybe_truncated=*/false);
3208   EXPECT_EQ(1, chr1_count);
3209   EXPECT_EQ(0, chr2_count);
3210 
3211   // Notify characteristic 2.
3212   fake_client()->SendNotification(
3213       /*indicate=*/true,
3214       6,
3215       StaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'),
3216       /*maybe_truncated=*/true);
3217   EXPECT_EQ(1, chr1_count);
3218   EXPECT_EQ(1, chr2_count);
3219 
3220   // Disable notifications from characteristic 1.
3221   status = ToResult(HostError::kFailed);
3222   service->DisableNotifications(
3223       kDefaultCharacteristic, handler_id, [&](att::Result<> cb_status) {
3224         status = cb_status;
3225       });
3226 
3227   RunUntilIdle();
3228   EXPECT_EQ(fit::ok(), status);
3229 
3230   // Notifications for characteristic 1 should get dropped.
3231   fake_client()->SendNotification(
3232       /*indicate=*/false,
3233       3,
3234       StaticByteBuffer('n', 'o', 't', 'i', 'f', 'y'),
3235       /*maybe_truncated=*/false);
3236   fake_client()->SendNotification(
3237       /*indicate=*/true,
3238       6,
3239       StaticByteBuffer('i', 'n', 'd', 'i', 'c', 'a', 't', 'e'),
3240       /*maybe_truncated=*/true);
3241   EXPECT_EQ(1, chr1_count);
3242   EXPECT_EQ(2, chr2_count);
3243 }
3244 
TEST_F(RemoteServiceManagerTest,DisableNotificationsWhileNotReady)3245 TEST_F(RemoteServiceManagerTest, DisableNotificationsWhileNotReady) {
3246   ServiceData data(ServiceKind::PRIMARY, 1, 4, kTestServiceUuid1);
3247   auto service = SetUpFakeService(data);
3248 
3249   att::Result<> status = fit::ok();
3250   service->DisableNotifications(
3251       kDefaultCharacteristic, 1, [&](att::Result<> cb_status) {
3252         status = cb_status;
3253       });
3254 
3255   RunUntilIdle();
3256 
3257   EXPECT_EQ(ToResult(HostError::kNotReady), status);
3258 }
3259 
TEST_F(RemoteServiceManagerTest,DisableNotificationsCharNotFound)3260 TEST_F(RemoteServiceManagerTest, DisableNotificationsCharNotFound) {
3261   auto service = SetupNotifiableService();
3262 
3263   IdType id = kInvalidId;
3264   att::Result<> status = ToResult(HostError::kFailed);
3265   EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3266 
3267   // "1" is an invalid characteristic ID.
3268   service->DisableNotifications(
3269       kInvalidCharacteristic, id, [&](att::Result<> cb_status) {
3270         status = cb_status;
3271       });
3272 
3273   RunUntilIdle();
3274 
3275   EXPECT_EQ(ToResult(HostError::kNotFound), status);
3276 }
3277 
TEST_F(RemoteServiceManagerTest,DisableNotificationsIdNotFound)3278 TEST_F(RemoteServiceManagerTest, DisableNotificationsIdNotFound) {
3279   auto service = SetupNotifiableService();
3280 
3281   IdType id = kInvalidId;
3282   att::Result<> status = ToResult(HostError::kFailed);
3283   EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3284 
3285   // Valid characteristic ID but invalid notification handler ID.
3286   service->DisableNotifications(
3287       kDefaultCharacteristic, id + 1, [&](att::Result<> cb_status) {
3288         status = cb_status;
3289       });
3290 
3291   RunUntilIdle();
3292 
3293   EXPECT_EQ(ToResult(HostError::kNotFound), status);
3294 }
3295 
TEST_F(RemoteServiceManagerTest,DisableNotificationsSingleHandler)3296 TEST_F(RemoteServiceManagerTest, DisableNotificationsSingleHandler) {
3297   constexpr att::Handle kCCCHandle = 4;
3298   auto service = SetupNotifiableService();
3299 
3300   IdType id = kInvalidId;
3301   att::Result<> status = ToResult(HostError::kFailed);
3302   EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3303 
3304   // Should disable notifications
3305   const StaticByteBuffer kExpectedValue(0x00, 0x00);
3306 
3307   int ccc_write_count = 0;
3308   fake_client()->set_write_request_callback(
3309       [&](att::Handle handle, const auto& value, auto status_callback) {
3310         EXPECT_EQ(kCCCHandle, handle);
3311         EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
3312         ccc_write_count++;
3313         status_callback(fit::ok());
3314       });
3315 
3316   status = ToResult(HostError::kFailed);
3317   service->DisableNotifications(
3318       kDefaultCharacteristic, id, [&](att::Result<> cb_status) {
3319         status = cb_status;
3320       });
3321 
3322   RunUntilIdle();
3323 
3324   EXPECT_EQ(fit::ok(), status);
3325   EXPECT_EQ(1, ccc_write_count);
3326 }
3327 
TEST_F(RemoteServiceManagerTest,DisableNotificationsOnDestruction)3328 TEST_F(RemoteServiceManagerTest, DisableNotificationsOnDestruction) {
3329   constexpr att::Handle kCCCHandle = 4;
3330   auto service = SetupNotifiableService();
3331 
3332   IdType id = kInvalidId;
3333   att::Result<> status = ToResult(HostError::kFailed);
3334   EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3335   ASSERT_EQ(fit::ok(), status);
3336 
3337   // Should disable notifications
3338   const StaticByteBuffer kExpectedValue(0x00, 0x00);
3339 
3340   int ccc_write_count = 0;
3341   fake_client()->set_write_request_callback(
3342       [&](att::Handle handle, const auto& value, auto status_callback) {
3343         EXPECT_EQ(kCCCHandle, handle);
3344         EXPECT_TRUE(ContainersEqual(kExpectedValue, value));
3345         ccc_write_count++;
3346         status_callback(fit::ok());
3347       });
3348 
3349   // Destroying the service manager (which destroys the service characteristics)
3350   // should clear the CCC.
3351   DestroyServiceManager();
3352   RunUntilIdle();
3353   EXPECT_EQ(1, ccc_write_count);
3354 }
3355 
TEST_F(RemoteServiceManagerTest,DisableNotificationsManyHandlers)3356 TEST_F(RemoteServiceManagerTest, DisableNotificationsManyHandlers) {
3357   auto service = SetupNotifiableService();
3358 
3359   IdType id = kInvalidId;
3360   std::vector<IdType> handler_ids;
3361 
3362   for (int i = 0; i < 2; i++) {
3363     att::Result<> status = ToResult(HostError::kFailed);
3364     EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3365     ASSERT_EQ(fit::ok(), status);
3366     handler_ids.push_back(id);
3367   }
3368 
3369   int ccc_write_count = 0;
3370   fake_client()->set_write_request_callback(
3371       [&](att::Handle handle, const auto& value, auto status_callback) {
3372         ccc_write_count++;
3373         status_callback(fit::ok());
3374       });
3375 
3376   // Disabling should succeed without an ATT transaction.
3377   att::Result<> status = ToResult(HostError::kFailed);
3378   service->DisableNotifications(
3379       kDefaultCharacteristic, handler_ids.back(), [&](att::Result<> cb_status) {
3380         status = cb_status;
3381       });
3382   handler_ids.pop_back();
3383   RunUntilIdle();
3384   EXPECT_EQ(fit::ok(), status);
3385   EXPECT_EQ(0, ccc_write_count);
3386 
3387   // Enabling should succeed without an ATT transaction.
3388   status = ToResult(HostError::kFailed);
3389   EnableNotifications(service, kDefaultCharacteristic, &status, &id);
3390   EXPECT_EQ(fit::ok(), status);
3391   EXPECT_EQ(0, ccc_write_count);
3392   handler_ids.push_back(id);
3393 
3394   // Disabling all should send out an ATT transaction.
3395   while (!handler_ids.empty()) {
3396     att::Result<> status = ToResult(HostError::kFailed);
3397     service->DisableNotifications(
3398         kDefaultCharacteristic,
3399         handler_ids.back(),
3400         [&](att::Result<> cb_status) { status = cb_status; });
3401     handler_ids.pop_back();
3402     RunUntilIdle();
3403     EXPECT_EQ(fit::ok(), status);
3404   }
3405 
3406   EXPECT_EQ(1, ccc_write_count);
3407 }
3408 
TEST_F(RemoteServiceManagerTest,ReadByTypeErrorOnLastHandleDoesNotOverflowHandle)3409 TEST_F(RemoteServiceManagerTest,
3410        ReadByTypeErrorOnLastHandleDoesNotOverflowHandle) {
3411   constexpr att::Handle kStartHandle = 0xFFFE;
3412   constexpr att::Handle kEndHandle = 0xFFFF;
3413   auto service = SetUpFakeService(ServiceData(
3414       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
3415   constexpr UUID kCharUuid(uint16_t{0xfefe});
3416 
3417   size_t read_count = 0;
3418   fake_client()->set_read_by_type_request_callback(
3419       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
3420         ASSERT_EQ(0u, read_count++);
3421         EXPECT_EQ(kStartHandle, start);
3422         callback(fit::error(Client::ReadByTypeError{
3423             att::Error(att::ErrorCode::kReadNotPermitted), kEndHandle}));
3424       });
3425 
3426   std::optional<att::Result<>> status;
3427   std::vector<RemoteService::ReadByTypeResult> results;
3428   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto cb_results) {
3429     status = cb_status;
3430     results = std::move(cb_results);
3431   });
3432   RunUntilIdle();
3433   ASSERT_TRUE(status.has_value());
3434   EXPECT_EQ(fit::ok(), *status);
3435   ASSERT_EQ(1u, results.size());
3436   EXPECT_EQ(CharacteristicHandle(kEndHandle), results[0].handle);
3437   EXPECT_EQ(att::ErrorCode::kReadNotPermitted, results[0].result.error_value());
3438 }
3439 
TEST_F(RemoteServiceManagerTest,ReadByTypeResultOnLastHandleDoesNotOverflowHandle)3440 TEST_F(RemoteServiceManagerTest,
3441        ReadByTypeResultOnLastHandleDoesNotOverflowHandle) {
3442   constexpr att::Handle kStartHandle = 0xFFFE;
3443   constexpr att::Handle kEndHandle = 0xFFFF;
3444   auto service = SetUpFakeService(ServiceData(
3445       ServiceKind::PRIMARY, kStartHandle, kEndHandle, kTestServiceUuid1));
3446 
3447   constexpr UUID kCharUuid(uint16_t{0xfefe});
3448 
3449   constexpr att::Handle kHandle = kEndHandle;
3450   const auto kValue = StaticByteBuffer(0x00, 0x01, 0x02);
3451   const std::vector<Client::ReadByTypeValue> kValues = {
3452       {kHandle, kValue.view(), /*maybe_truncated=*/false}};
3453 
3454   size_t read_count = 0;
3455   fake_client()->set_read_by_type_request_callback(
3456       [&](const UUID& type, att::Handle start, att::Handle end, auto callback) {
3457         ASSERT_EQ(0u, read_count++);
3458         EXPECT_EQ(kStartHandle, start);
3459         callback(fit::ok(kValues));
3460       });
3461 
3462   std::optional<att::Result<>> status;
3463   service->ReadByType(kCharUuid, [&](att::Result<> cb_status, auto values) {
3464     status = cb_status;
3465     ASSERT_EQ(1u, values.size());
3466     EXPECT_EQ(CharacteristicHandle(kHandle), values[0].handle);
3467     ASSERT_EQ(fit::ok(), values[0].result);
3468     EXPECT_TRUE(ContainersEqual(kValue, *values[0].result.value()));
3469   });
3470 
3471   RunUntilIdle();
3472   ASSERT_TRUE(status.has_value());
3473   EXPECT_EQ(fit::ok(), *status);
3474 }
3475 
3476 class RemoteServiceManagerServiceChangedTest : public RemoteServiceManagerTest {
3477  public:
3478   RemoteServiceManagerServiceChangedTest() = default;
3479   ~RemoteServiceManagerServiceChangedTest() override = default;
3480 
3481  protected:
3482   struct ServiceWatcherData {
3483     std::vector<att::Handle> removed;
3484     ServiceList added;
3485     ServiceList modified;
3486   };
3487 
SetUp()3488   void SetUp() override {
3489     RemoteServiceManagerTest::SetUp();
3490     fake_client()->set_services({gatt_service()});
3491     fake_client()->set_characteristics({service_changed_characteristic()});
3492     fake_client()->set_descriptors({ccc_descriptor()});
3493 
3494     mgr()->set_service_watcher(
3495         [this](auto removed, ServiceList added, ServiceList modified) {
3496           svc_watcher_data_.push_back({removed, added, modified});
3497         });
3498 
3499     // Expect a Service Changed Client Characteristic Config descriptor write
3500     // that enables indications.
3501     fake_client()->set_write_request_callback(
3502         [this](att::Handle handle, const auto& value, auto status_callback) {
3503           write_request_count_++;
3504           EXPECT_EQ(ccc_descriptor_handle_, handle);
3505           EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
3506           status_callback(fit::ok());
3507         });
3508 
3509     att::Result<> status = ToResult(HostError::kFailed);
3510     mgr()->Initialize([&status](att::Result<> val) { status = val; },
3511                       NopMtuCallback);
3512     RunUntilIdle();
3513     EXPECT_EQ(fit::ok(), status);
3514     EXPECT_EQ(write_request_count_, 1);
3515     ASSERT_EQ(1u, svc_watcher_data_.size());
3516     ASSERT_EQ(1u, svc_watcher_data_[0].added.size());
3517     EXPECT_EQ(gatt_svc_start_handle_, svc_watcher_data_[0].added[0]->handle());
3518     EXPECT_EQ(types::kGenericAttributeService,
3519               svc_watcher_data_[0].added[0]->uuid());
3520     // Clear data so that tests start with index 0
3521     svc_watcher_data_.clear();
3522   }
3523 
TearDown()3524   void TearDown() override { RemoteServiceManagerTest::TearDown(); }
3525 
gatt_service() const3526   ServiceData gatt_service() const {
3527     return ServiceData(ServiceKind::PRIMARY,
3528                        gatt_svc_start_handle_,
3529                        gatt_svc_end_handle_,
3530                        types::kGenericAttributeService);
3531   }
3532 
service_changed_characteristic() const3533   CharacteristicData service_changed_characteristic() const {
3534     return CharacteristicData(Property::kIndicate,
3535                               std::nullopt,
3536                               svc_changed_char_handle_,
3537                               svc_changed_char_value_handle_,
3538                               types::kServiceChangedCharacteristic);
3539   }
3540 
ccc_descriptor() const3541   DescriptorData ccc_descriptor() const {
3542     return DescriptorData(ccc_descriptor_handle_,
3543                           types::kClientCharacteristicConfig);
3544   }
3545 
svc_watcher_data()3546   const std::vector<ServiceWatcherData>& svc_watcher_data() {
3547     return svc_watcher_data_;
3548   }
3549 
service_changed_ccc_write_count() const3550   int service_changed_ccc_write_count() const { return write_request_count_; }
3551 
3552  private:
3553   std::vector<ServiceWatcherData> svc_watcher_data_;
3554   int write_request_count_ = 0;
3555   const att::Handle gatt_svc_start_handle_ = 1;
3556   const att::Handle svc_changed_char_handle_ = 2;
3557   const att::Handle svc_changed_char_value_handle_ = 3;
3558   const att::Handle ccc_descriptor_handle_ = 4;
3559   const att::Handle gatt_svc_end_handle_ = 4;
3560 };
3561 
TEST_F(RemoteServiceManagerServiceChangedTest,ServiceChangedNotificationWrongSizeBuffer)3562 TEST_F(RemoteServiceManagerServiceChangedTest,
3563        ServiceChangedNotificationWrongSizeBuffer) {
3564   const att::Handle kSvc1StartHandle(5);
3565   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
3566   ServiceData svc1(ServiceKind::PRIMARY,
3567                    kSvc1StartHandle,
3568                    kSvc1EndHandle,
3569                    kTestServiceUuid1);
3570   fake_client()->set_services({gatt_service(), svc1});
3571 
3572   // Send a too small notification.
3573   auto svc_changed_range_buffer_too_small = StaticByteBuffer(0x01);
3574   fake_client()->SendNotification(/*indicate=*/true,
3575                                   service_changed_characteristic().value_handle,
3576                                   svc_changed_range_buffer_too_small,
3577                                   /*maybe_truncated=*/false);
3578   RunUntilIdle();
3579   // The notification should have been safely ignored.
3580   ASSERT_EQ(0u, svc_watcher_data().size());
3581 
3582   // Send a too large notification.
3583   StaticByteBuffer<sizeof(ServiceChangedCharacteristicValue) + 1>
3584       svc_changed_range_buffer_too_large =
3585           StaticByteBuffer(0x01, 0x02, 0x03, 0x04, 0x05);
3586   fake_client()->SendNotification(/*indicate=*/true,
3587                                   service_changed_characteristic().value_handle,
3588                                   svc_changed_range_buffer_too_large,
3589                                   /*maybe_truncated=*/false);
3590   RunUntilIdle();
3591   // The notification should have been safely ignored.
3592   ASSERT_EQ(0u, svc_watcher_data().size());
3593 }
3594 
TEST_F(RemoteServiceManagerServiceChangedTest,ServiceChangedNotificationRangeStartGreaterThanRangeEnd)3595 TEST_F(RemoteServiceManagerServiceChangedTest,
3596        ServiceChangedNotificationRangeStartGreaterThanRangeEnd) {
3597   const att::Handle kSvc1StartHandle(6);
3598   const att::Handle kSvc1EndHandle(7);
3599   ServiceData svc1(ServiceKind::PRIMARY,
3600                    kSvc1StartHandle,
3601                    kSvc1EndHandle,
3602                    kTestServiceUuid1);
3603   fake_client()->set_services({gatt_service(), svc1});
3604 
3605   // Send notification with start/end handles swapped.
3606   auto svc_changed_range_buffer = StaticByteBuffer(
3607       LowerBits(kSvc1EndHandle),
3608       UpperBits(kSvc1EndHandle),  // start handle of affected range
3609       LowerBits(kSvc1StartHandle),
3610       UpperBits(kSvc1StartHandle)  // end handle of affected range
3611   );
3612   fake_client()->SendNotification(/*indicate=*/true,
3613                                   service_changed_characteristic().value_handle,
3614                                   svc_changed_range_buffer,
3615                                   /*maybe_truncated=*/false);
3616   RunUntilIdle();
3617   // The notification should have been safely ignored.
3618   ASSERT_EQ(0u, svc_watcher_data().size());
3619 }
3620 
TEST_F(RemoteServiceManagerServiceChangedTest,AddModifyAndRemoveService)3621 TEST_F(RemoteServiceManagerServiceChangedTest, AddModifyAndRemoveService) {
3622   // Add a test service to ensure that service discovery occurs after the
3623   // Service Changed characteristic is configured. The test service has a
3624   // characteristic that supports indications in order to test that
3625   // notifications aren't disabled when the service is modified or removed.
3626   const att::Handle kSvc1StartHandle(5);
3627   const att::Handle kSvc1ChrcHandle(6);
3628   const att::Handle kSvc1ChrcValueHandle(7);
3629   const att::Handle kSvc1CCCHandle(8);
3630   const UUID kSvc1ChrcUuid(kTestUuid3);
3631   const att::Handle kSvc1EndHandle(kSvc1CCCHandle);
3632 
3633   ServiceData svc1(ServiceKind::PRIMARY,
3634                    kSvc1StartHandle,
3635                    kSvc1EndHandle,
3636                    kTestServiceUuid1);
3637   CharacteristicData svc1_characteristic(Property::kIndicate,
3638                                          std::nullopt,
3639                                          kSvc1ChrcHandle,
3640                                          kSvc1ChrcValueHandle,
3641                                          kSvc1ChrcUuid);
3642   DescriptorData svc1_descriptor(kSvc1CCCHandle,
3643                                  types::kClientCharacteristicConfig);
3644   fake_client()->set_services({gatt_service(), svc1});
3645   fake_client()->set_characteristics(
3646       {service_changed_characteristic(), svc1_characteristic});
3647   fake_client()->set_descriptors({ccc_descriptor(), svc1_descriptor});
3648 
3649   // Send a notification that svc1 has been added.
3650   auto svc_changed_range_buffer = StaticByteBuffer(
3651       LowerBits(kSvc1StartHandle),
3652       UpperBits(kSvc1StartHandle),  // start handle of affected range
3653       LowerBits(kSvc1EndHandle),
3654       UpperBits(kSvc1EndHandle)  // end handle of affected range
3655   );
3656   fake_client()->SendNotification(/*indicate=*/true,
3657                                   service_changed_characteristic().value_handle,
3658                                   svc_changed_range_buffer,
3659                                   /*maybe_truncated=*/false);
3660   RunUntilIdle();
3661   ASSERT_EQ(1u, svc_watcher_data().size());
3662   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
3663   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
3664   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
3665   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[0].added[0]->handle());
3666   bool original_service_removed = false;
3667   svc_watcher_data()[0].added[0]->AddRemovedHandler(
3668       [&]() { original_service_removed = true; });
3669 
3670   // Discover the characteristic with the CCC descriptor before enabling
3671   // characteristic value notifications.
3672   svc_watcher_data()[0].added[0]->DiscoverCharacteristics(
3673       [&](att::Result<> status, const CharacteristicMap& characteristics) {
3674         EXPECT_EQ(fit::ok(), status);
3675         EXPECT_EQ(characteristics.size(), 1u);
3676       });
3677   RunUntilIdle();
3678 
3679   // Expect writes to the service's CCC descriptor when notifications are
3680   // enabled.
3681   int svc1_ccc_write_request_count = 0;
3682   fake_client()->set_write_request_callback(
3683       [&](att::Handle handle, const auto& value, auto status_callback) {
3684         svc1_ccc_write_request_count++;
3685         EXPECT_EQ(kSvc1CCCHandle, handle);
3686         EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
3687         status_callback(fit::ok());
3688       });
3689 
3690   std::optional<att::Result<>> original_notification_status;
3691   svc_watcher_data()[0].added[0]->EnableNotifications(
3692       bt::gatt::CharacteristicHandle(kSvc1ChrcValueHandle),
3693       NopValueCallback,
3694       [&](att::Result<> cb_status, IdType cb_id) {
3695         original_notification_status = cb_status;
3696       });
3697   RunUntilIdle();
3698   ASSERT_TRUE(original_notification_status);
3699   EXPECT_EQ(fit::ok(), *original_notification_status);
3700   EXPECT_EQ(svc1_ccc_write_request_count, 1);
3701 
3702   // Send a notification that svc1 has been modified. Service Changed
3703   // notifications guarantee that all services within their range have been
3704   // modified if they are still present after a fresh service discovery, so we
3705   // can just send the same range again. (Core Spec v5.3, Vol 3, Part G,
3706   // Sec 7.1)
3707   fake_client()->SendNotification(/*indicate=*/true,
3708                                   service_changed_characteristic().value_handle,
3709                                   svc_changed_range_buffer,
3710                                   /*maybe_truncated=*/false);
3711   RunUntilIdle();
3712   EXPECT_TRUE(original_service_removed);
3713   // CCC should not be written to when the service is modified.
3714   EXPECT_EQ(svc1_ccc_write_request_count, 1);
3715   ASSERT_EQ(2u, svc_watcher_data().size());
3716   EXPECT_EQ(0u, svc_watcher_data()[1].added.size());
3717   EXPECT_EQ(0u, svc_watcher_data()[1].removed.size());
3718   ASSERT_EQ(1u, svc_watcher_data()[1].modified.size());
3719   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[1].modified[0]->handle());
3720   bool modified_service_removed = false;
3721   svc_watcher_data()[1].modified[0]->AddRemovedHandler(
3722       [&]() { modified_service_removed = true; });
3723 
3724   svc_watcher_data()[1].modified[0]->DiscoverCharacteristics(
3725       [&](att::Result<> status, const CharacteristicMap& characteristics) {
3726         EXPECT_EQ(fit::ok(), status);
3727         EXPECT_EQ(characteristics.size(), 1u);
3728       });
3729   RunUntilIdle();
3730 
3731   std::optional<att::Result<>> modified_notification_status;
3732   svc_watcher_data()[1].modified[0]->EnableNotifications(
3733       bt::gatt::CharacteristicHandle(kSvc1ChrcValueHandle),
3734       NopValueCallback,
3735       [&](att::Result<> cb_status, IdType cb_id) {
3736         modified_notification_status = cb_status;
3737       });
3738   RunUntilIdle();
3739   ASSERT_TRUE(modified_notification_status);
3740   EXPECT_EQ(fit::ok(), *modified_notification_status);
3741   EXPECT_EQ(svc1_ccc_write_request_count, 2);
3742 
3743   // Remove svc1.
3744   fake_client()->set_services({gatt_service()});
3745 
3746   // Send a notification that svc1 has been removed.
3747   fake_client()->SendNotification(/*indicate=*/true,
3748                                   service_changed_characteristic().value_handle,
3749                                   svc_changed_range_buffer,
3750                                   /*maybe_truncated=*/false);
3751   RunUntilIdle();
3752   EXPECT_TRUE(modified_service_removed);
3753   // CCC should not be written to when the service is removed.
3754   EXPECT_EQ(svc1_ccc_write_request_count, 2);
3755   ASSERT_EQ(3u, svc_watcher_data().size());
3756   EXPECT_EQ(0u, svc_watcher_data()[2].added.size());
3757   ASSERT_EQ(1u, svc_watcher_data()[2].removed.size());
3758   EXPECT_EQ(0u, svc_watcher_data()[2].modified.size());
3759   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[2].removed[0]);
3760   EXPECT_EQ(svc1_ccc_write_request_count, 2);
3761 }
3762 
3763 // A Service Changed notification received during initialization (service
3764 // discovery) should be queued and processed after service discovery completes
3765 // (as the last step of initialization). The service watcher should only be
3766 // called once.
TEST_F(RemoteServiceManagerTest,ServiceChangedDuringInitialization)3767 TEST_F(RemoteServiceManagerTest, ServiceChangedDuringInitialization) {
3768   const att::Handle kGattSvcStartHandle(1);
3769   const att::Handle kSvcChangedChrcHandle(2);
3770   const att::Handle kSvcChangedChrcValueHandle(3);
3771   const att::Handle kCCCDescriptorHandle(4);
3772   const att::Handle kGattSvcEndHandle(kCCCDescriptorHandle);
3773   const att::Handle kSvc1StartHandle(5);
3774   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
3775 
3776   ServiceData gatt_svc(ServiceKind::PRIMARY,
3777                        kGattSvcStartHandle,
3778                        kGattSvcEndHandle,
3779                        types::kGenericAttributeService);
3780   CharacteristicData service_changed_chrc(Property::kIndicate,
3781                                           std::nullopt,
3782                                           kSvcChangedChrcHandle,
3783                                           kSvcChangedChrcValueHandle,
3784                                           types::kServiceChangedCharacteristic);
3785   DescriptorData ccc_descriptor(kCCCDescriptorHandle,
3786                                 types::kClientCharacteristicConfig);
3787   ServiceData svc1(ServiceKind::PRIMARY,
3788                    kSvc1StartHandle,
3789                    kSvc1EndHandle,
3790                    kTestServiceUuid1);
3791   fake_client()->set_services({gatt_svc, svc1});
3792   fake_client()->set_characteristics({service_changed_chrc});
3793   fake_client()->set_descriptors({ccc_descriptor});
3794 
3795   int svc_watcher_count = 0;
3796   mgr()->set_service_watcher([&](std::vector<att::Handle> removed,
3797                                  ServiceList added,
3798                                  ServiceList modified) {
3799     EXPECT_EQ(0u, removed.size());
3800     EXPECT_EQ(2u, added.size());
3801     EXPECT_EQ(0u, modified.size());
3802     svc_watcher_count++;
3803   });
3804 
3805   // Send a notification during primary service discovery (i.e. the second
3806   // discovery, as the first is for discovering the GATT Service).
3807   int discover_services_count = 0;
3808   fake_client()->set_discover_services_callback([&](ServiceKind /*kind*/) {
3809     if (discover_services_count == 1) {
3810       auto svc_changed_range_buffer = StaticByteBuffer(
3811           LowerBits(kSvc1StartHandle),
3812           UpperBits(kSvc1StartHandle),  // start handle of affected range
3813           LowerBits(kSvc1EndHandle),
3814           UpperBits(kSvc1EndHandle)  // end handle of affected range
3815       );
3816       fake_client()->SendNotification(/*indicate=*/true,
3817                                       kSvcChangedChrcValueHandle,
3818                                       svc_changed_range_buffer,
3819                                       /*maybe_truncated=*/false);
3820     }
3821     discover_services_count++;
3822     return fit::ok();
3823   });
3824 
3825   // Expect a Service Changed Client Characteristic Config descriptor write that
3826   // enables indications.
3827   int write_request_count = 0;
3828   fake_client()->set_write_request_callback(
3829       [&](att::Handle handle, const auto& value, auto status_callback) {
3830         write_request_count++;
3831         EXPECT_EQ(kCCCDescriptorHandle, handle);
3832         EXPECT_TRUE(ContainersEqual(kCCCIndicateValue, value));
3833         status_callback(fit::ok());
3834       });
3835 
3836   att::Result<> status = ToResult(HostError::kFailed);
3837   mgr()->Initialize(
3838       [&](att::Result<> val) {
3839         status = val;
3840         EXPECT_EQ(1, svc_watcher_count);
3841       },
3842       NopMtuCallback);
3843   RunUntilIdle();
3844   EXPECT_EQ(fit::ok(), status);
3845   EXPECT_EQ(1, write_request_count);
3846   EXPECT_EQ(1, svc_watcher_count);
3847 }
3848 
TEST_F(RemoteServiceManagerServiceChangedTest,SecondServiceChangedNotificationIsQueued)3849 TEST_F(RemoteServiceManagerServiceChangedTest,
3850        SecondServiceChangedNotificationIsQueued) {
3851   const att::Handle kSvc1StartHandle(5);
3852   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
3853 
3854   // Add a test service to ensure that service discovery occurs after the
3855   // Service Changed characteristic is configured.
3856   ServiceData svc1(ServiceKind::PRIMARY,
3857                    kSvc1StartHandle,
3858                    kSvc1EndHandle,
3859                    kTestServiceUuid1);
3860   fake_client()->set_services({gatt_service(), svc1});
3861 
3862   // Send a notification that svc1 has been added.
3863   auto svc_changed_range_buffer = StaticByteBuffer(
3864       LowerBits(kSvc1StartHandle),
3865       UpperBits(kSvc1StartHandle),  // start handle of affected range
3866       LowerBits(kSvc1EndHandle),
3867       UpperBits(kSvc1EndHandle)  // end handle of affected range
3868   );
3869   fake_client()->SendNotification(/*indicate=*/true,
3870                                   service_changed_characteristic().value_handle,
3871                                   svc_changed_range_buffer,
3872                                   /*maybe_truncated=*/false);
3873   // Send a notification that svc1 has been modified.
3874   fake_client()->SendNotification(/*indicate=*/true,
3875                                   service_changed_characteristic().value_handle,
3876                                   svc_changed_range_buffer,
3877                                   /*maybe_truncated=*/false);
3878 
3879   RunUntilIdle();
3880   ASSERT_EQ(2u, svc_watcher_data().size());
3881 
3882   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
3883   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
3884   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
3885   EXPECT_FALSE(svc_watcher_data()[0]
3886                    .added[0]
3887                    .is_alive());  // WeakPtr should already be invalidated
3888 
3889   EXPECT_EQ(0u, svc_watcher_data()[1].added.size());
3890   EXPECT_EQ(0u, svc_watcher_data()[1].removed.size());
3891   ASSERT_EQ(1u, svc_watcher_data()[1].modified.size());
3892   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[1].modified[0]->handle());
3893 }
3894 
TEST_F(RemoteServiceManagerServiceChangedTest,ServiceUuidChanged)3895 TEST_F(RemoteServiceManagerServiceChangedTest, ServiceUuidChanged) {
3896   const att::Handle kSvcStartHandle(5);
3897   const att::Handle kSvcEndHandle(kSvcStartHandle);
3898 
3899   ServiceData svc1(
3900       ServiceKind::PRIMARY, kSvcStartHandle, kSvcEndHandle, kTestServiceUuid1);
3901   fake_client()->set_services({gatt_service(), svc1});
3902 
3903   // Send a notification that svc1 has been added.
3904   auto svc_changed_range_buffer = StaticByteBuffer(
3905       LowerBits(kSvcStartHandle),
3906       UpperBits(kSvcStartHandle),  // start handle of affected range
3907       LowerBits(kSvcEndHandle),
3908       UpperBits(kSvcEndHandle)  // end handle of affected range
3909   );
3910   fake_client()->SendNotification(/*indicate=*/true,
3911                                   service_changed_characteristic().value_handle,
3912                                   svc_changed_range_buffer,
3913                                   /*maybe_truncated=*/false);
3914 
3915   RunUntilIdle();
3916   ASSERT_EQ(1u, svc_watcher_data().size());
3917 
3918   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
3919   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
3920   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
3921   EXPECT_EQ(kSvcStartHandle, svc_watcher_data()[0].added[0]->handle());
3922   EXPECT_EQ(kTestServiceUuid1, svc_watcher_data()[0].added[0]->uuid());
3923 
3924   ServiceData svc2(
3925       ServiceKind::PRIMARY, kSvcStartHandle, kSvcEndHandle, kTestServiceUuid2);
3926   fake_client()->set_services({gatt_service(), svc2});
3927 
3928   // Send a notification that svc2 has replaced svc1.
3929   fake_client()->SendNotification(/*indicate=*/true,
3930                                   service_changed_characteristic().value_handle,
3931                                   svc_changed_range_buffer,
3932                                   /*maybe_truncated=*/false);
3933   RunUntilIdle();
3934   ASSERT_EQ(2u, svc_watcher_data().size());
3935 
3936   ASSERT_EQ(1u, svc_watcher_data()[1].added.size());
3937   ASSERT_EQ(1u, svc_watcher_data()[1].removed.size());
3938   EXPECT_EQ(0u, svc_watcher_data()[1].modified.size());
3939   EXPECT_EQ(kSvcStartHandle, svc_watcher_data()[1].removed[0]);
3940   EXPECT_EQ(kSvcStartHandle, svc_watcher_data()[1].added[0]->handle());
3941   EXPECT_EQ(kTestServiceUuid2, svc_watcher_data()[1].added[0]->uuid());
3942 }
3943 
TEST_F(RemoteServiceManagerServiceChangedTest,AddServiceThenRemoveServiceAndAddTwoMoreServicesBeforeAndAfterRemovedServiceWithSameNotification)3944 TEST_F(
3945     RemoteServiceManagerServiceChangedTest,
3946     AddServiceThenRemoveServiceAndAddTwoMoreServicesBeforeAndAfterRemovedServiceWithSameNotification) {
3947   const att::Handle kSvc1StartHandle(7);
3948   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
3949   const att::Handle kSvc2StartHandle(6);
3950   const att::Handle kSvc2EndHandle(kSvc2StartHandle);
3951   const att::Handle kSvc3StartHandle(8);
3952   const att::Handle kSvc3EndHandle(kSvc3StartHandle);
3953 
3954   ServiceData svc1(ServiceKind::PRIMARY,
3955                    kSvc1StartHandle,
3956                    kSvc1EndHandle,
3957                    kTestServiceUuid1);
3958   fake_client()->set_services({gatt_service(), svc1});
3959 
3960   // Send a notification that svc1 has been added.
3961   auto svc_changed_range_buffer_0 = StaticByteBuffer(
3962       LowerBits(kSvc1StartHandle),
3963       UpperBits(kSvc1StartHandle),  // start handle of affected range
3964       LowerBits(kSvc1EndHandle),
3965       UpperBits(kSvc1EndHandle)  // end handle of affected range
3966   );
3967   fake_client()->SendNotification(/*indicate=*/true,
3968                                   service_changed_characteristic().value_handle,
3969                                   svc_changed_range_buffer_0,
3970                                   /*maybe_truncated=*/false);
3971 
3972   RunUntilIdle();
3973   ASSERT_EQ(1u, svc_watcher_data().size());
3974   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
3975   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
3976   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
3977   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[0].added[0]->handle());
3978 
3979   ServiceData svc2(ServiceKind::PRIMARY,
3980                    kSvc2StartHandle,
3981                    kSvc2EndHandle,
3982                    kTestServiceUuid2);
3983   ServiceData svc3(ServiceKind::PRIMARY,
3984                    kSvc3StartHandle,
3985                    kSvc3EndHandle,
3986                    kTestServiceUuid3);
3987   fake_client()->set_services({gatt_service(), svc2, svc3});
3988 
3989   // Range includes all 3 services.
3990   auto svc_changed_range_buffer_1 = StaticByteBuffer(
3991       LowerBits(kSvc2StartHandle),
3992       UpperBits(kSvc2StartHandle),  // start handle of affected range
3993       LowerBits(kSvc3EndHandle),
3994       UpperBits(kSvc3EndHandle)  // end handle of affected range
3995   );
3996   fake_client()->SendNotification(/*indicate=*/true,
3997                                   service_changed_characteristic().value_handle,
3998                                   svc_changed_range_buffer_1,
3999                                   /*maybe_truncated=*/false);
4000 
4001   RunUntilIdle();
4002   ASSERT_EQ(2u, svc_watcher_data().size());
4003   ASSERT_EQ(2u, svc_watcher_data()[1].added.size());
4004   ASSERT_EQ(1u, svc_watcher_data()[1].removed.size());
4005   EXPECT_EQ(0u, svc_watcher_data()[1].modified.size());
4006   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[1].removed[0]);
4007   EXPECT_EQ(kSvc2StartHandle, svc_watcher_data()[1].added[0]->handle());
4008   EXPECT_EQ(kSvc3StartHandle, svc_watcher_data()[1].added[1]->handle());
4009 }
4010 
4011 class RemoteServiceManagerServiceChangedTestWithServiceKindParam
4012     : public RemoteServiceManagerServiceChangedTest,
4013       public ::testing::WithParamInterface<ServiceKind> {};
4014 
TEST_P(RemoteServiceManagerServiceChangedTestWithServiceKindParam,ServiceChangedServiceDiscoveryFailureThenSuccess)4015 TEST_P(RemoteServiceManagerServiceChangedTestWithServiceKindParam,
4016        ServiceChangedServiceDiscoveryFailureThenSuccess) {
4017   const ServiceKind kKind = GetParam();
4018 
4019   const att::Handle kSvc1StartHandle(5);
4020   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
4021   ServiceData svc1(kKind, kSvc1StartHandle, kSvc1EndHandle, kTestServiceUuid1);
4022   const att::Handle kSvc2StartHandle(7);
4023   const att::Handle kSvc2EndHandle(kSvc2StartHandle);
4024   ServiceData svc2(kKind, kSvc2StartHandle, kSvc2EndHandle, kTestServiceUuid2);
4025   fake_client()->set_services({gatt_service(), svc1, svc2});
4026 
4027   // Cause only the first service discovery to fail.
4028   int discover_services_count = 0;
4029   fake_client()->set_discover_services_callback(
4030       [&](ServiceKind kind) -> att::Result<> {
4031         if (kind == kKind) {
4032           discover_services_count++;
4033           if (discover_services_count == 1) {
4034             return ToResult(HostError::kFailed);
4035           }
4036         }
4037         return fit::ok();
4038       });
4039 
4040   auto svc1_changed_range_buffer = StaticByteBuffer(
4041       LowerBits(kSvc1StartHandle),
4042       UpperBits(kSvc1StartHandle),  // start handle of affected range
4043       LowerBits(kSvc1EndHandle),
4044       UpperBits(kSvc1EndHandle)  // end handle of affected range
4045   );
4046   fake_client()->SendNotification(/*indicate=*/true,
4047                                   service_changed_characteristic().value_handle,
4048                                   svc1_changed_range_buffer,
4049                                   /*maybe_truncated=*/false);
4050 
4051   // This second notification should be queued and processed after the first
4052   // service discovery fails.
4053   auto svc2_changed_range_buffer = StaticByteBuffer(
4054       LowerBits(kSvc2StartHandle),
4055       UpperBits(kSvc2StartHandle),  // start handle of affected range
4056       LowerBits(kSvc2EndHandle),
4057       UpperBits(kSvc2EndHandle)  // end handle of affected range
4058   );
4059   fake_client()->SendNotification(/*indicate=*/true,
4060                                   service_changed_characteristic().value_handle,
4061                                   svc2_changed_range_buffer,
4062                                   /*maybe_truncated=*/false);
4063 
4064   RunUntilIdle();
4065   ASSERT_EQ(1u, svc_watcher_data().size());
4066   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
4067   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
4068   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
4069   EXPECT_EQ(kSvc2StartHandle, svc_watcher_data()[0].added[0]->handle());
4070 }
4071 
4072 INSTANTIATE_TEST_SUITE_P(
4073     ServiceKind,
4074     RemoteServiceManagerServiceChangedTestWithServiceKindParam,
4075     ::testing::Values(ServiceKind::PRIMARY, ServiceKind::SECONDARY));
4076 
TEST_F(RemoteServiceManagerServiceChangedTest,SecondaryServiceDiscoveryIgnoresUnsupportedGroupTypeError)4077 TEST_F(RemoteServiceManagerServiceChangedTest,
4078        SecondaryServiceDiscoveryIgnoresUnsupportedGroupTypeError) {
4079   const att::Handle kSvc1StartHandle(5);
4080   const att::Handle kSvc1EndHandle(kSvc1StartHandle);
4081 
4082   ServiceData svc1(ServiceKind::PRIMARY,
4083                    kSvc1StartHandle,
4084                    kSvc1EndHandle,
4085                    kTestServiceUuid1);
4086   fake_client()->set_services({gatt_service(), svc1});
4087 
4088   fake_client()->set_discover_services_callback([](ServiceKind kind) {
4089     if (kind == ServiceKind::SECONDARY) {
4090       return ToResult(att::ErrorCode::kUnsupportedGroupType);
4091     }
4092     return att::Result<>(fit::ok());
4093   });
4094 
4095   // Send a notification that svc1 has been added.
4096   auto svc_changed_range_buffer = StaticByteBuffer(
4097       LowerBits(kSvc1StartHandle),
4098       UpperBits(kSvc1StartHandle),  // start handle of affected range
4099       LowerBits(kSvc1EndHandle),
4100       UpperBits(kSvc1EndHandle)  // end handle of affected range
4101   );
4102   fake_client()->SendNotification(/*indicate=*/true,
4103                                   service_changed_characteristic().value_handle,
4104                                   svc_changed_range_buffer,
4105                                   /*maybe_truncated=*/false);
4106   RunUntilIdle();
4107   ASSERT_EQ(1u, svc_watcher_data().size());
4108   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
4109   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
4110   EXPECT_EQ(0u, svc_watcher_data()[0].modified.size());
4111   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[0].added[0]->handle());
4112 }
4113 
TEST_F(RemoteServiceManagerServiceChangedTest,GattProfileServiceChanged)4114 TEST_F(RemoteServiceManagerServiceChangedTest, GattProfileServiceChanged) {
4115   EXPECT_EQ(1, service_changed_ccc_write_count());
4116 
4117   StaticByteBuffer svc_changed_range_buffer(
4118       LowerBits(gatt_service().range_start),
4119       UpperBits(gatt_service().range_start),  // start handle of affected range
4120       LowerBits(gatt_service().range_end),
4121       UpperBits(gatt_service().range_end)  // end handle of affected range
4122   );
4123   fake_client()->SendNotification(/*indicate=*/true,
4124                                   service_changed_characteristic().value_handle,
4125                                   svc_changed_range_buffer,
4126                                   /*maybe_truncated=*/false);
4127   RunUntilIdle();
4128   ASSERT_EQ(1u, svc_watcher_data().size());
4129   EXPECT_EQ(0u, svc_watcher_data()[0].added.size());
4130   EXPECT_EQ(0u, svc_watcher_data()[0].removed.size());
4131   ASSERT_EQ(1u, svc_watcher_data()[0].modified.size());
4132   EXPECT_EQ(gatt_service().range_start,
4133             svc_watcher_data()[0].modified[0]->handle());
4134   EXPECT_EQ(1, service_changed_ccc_write_count());
4135 
4136   // The handler for notifications should remain configured.
4137   fake_client()->SendNotification(/*indicate=*/true,
4138                                   service_changed_characteristic().value_handle,
4139                                   svc_changed_range_buffer,
4140                                   /*maybe_truncated=*/false);
4141   RunUntilIdle();
4142   ASSERT_EQ(2u, svc_watcher_data().size());
4143   EXPECT_EQ(0u, svc_watcher_data()[1].added.size());
4144   EXPECT_EQ(0u, svc_watcher_data()[1].removed.size());
4145   ASSERT_EQ(1u, svc_watcher_data()[1].modified.size());
4146   EXPECT_EQ(gatt_service().range_start,
4147             svc_watcher_data()[1].modified[0]->handle());
4148   EXPECT_EQ(1, service_changed_ccc_write_count());
4149   // A new service should not have been created for the modified GATT Profile
4150   // service.
4151   EXPECT_EQ(&svc_watcher_data()[0].modified[0].get(),
4152             &svc_watcher_data()[1].modified[0].get());
4153 }
4154 
TEST_F(RemoteServiceManagerTest,ErrorDiscoveringGattProfileService)4155 TEST_F(RemoteServiceManagerTest, ErrorDiscoveringGattProfileService) {
4156   ServiceData gatt_svc(
4157       ServiceKind::PRIMARY, 1, 1, types::kGenericAttributeService);
4158   ServiceData svc1(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid1);
4159   std::vector<ServiceData> fake_services{{gatt_svc, svc1}};
4160   fake_client()->set_services(std::move(fake_services));
4161 
4162   fake_client()->set_discover_services_callback([](ServiceKind kind) {
4163     if (kind == ServiceKind::PRIMARY) {
4164       return ToResult(att::ErrorCode::kRequestNotSupported);
4165     }
4166     return att::Result<>(fit::ok());
4167   });
4168 
4169   std::optional<att::Result<>> status;
4170   mgr()->Initialize([&status](att::Result<> val) { status = val; },
4171                     NopMtuCallback);
4172   RunUntilIdle();
4173   EXPECT_EQ(ToResult(att::ErrorCode::kRequestNotSupported), *status);
4174 }
4175 
TEST_F(RemoteServiceManagerTest,MultipleGattProfileServicesFailsInitialization)4176 TEST_F(RemoteServiceManagerTest,
4177        MultipleGattProfileServicesFailsInitialization) {
4178   ServiceData gatt_svc0(
4179       ServiceKind::PRIMARY, 1, 1, types::kGenericAttributeService);
4180   ServiceData gatt_svc1(
4181       ServiceKind::PRIMARY, 2, 2, types::kGenericAttributeService);
4182   std::vector<ServiceData> fake_services{{gatt_svc0, gatt_svc1}};
4183   fake_client()->set_services(std::move(fake_services));
4184 
4185   std::optional<att::Result<>> status;
4186   mgr()->Initialize([&status](att::Result<> val) { status = val; },
4187                     NopMtuCallback);
4188   RunUntilIdle();
4189   EXPECT_EQ(ToResult(HostError::kFailed), *status);
4190 }
4191 
TEST_F(RemoteServiceManagerTest,InitializeEmptyGattProfileService)4192 TEST_F(RemoteServiceManagerTest, InitializeEmptyGattProfileService) {
4193   ServiceData gatt_svc(
4194       ServiceKind::PRIMARY, 1, 1, types::kGenericAttributeService);
4195   ServiceData svc1(ServiceKind::PRIMARY, 2, 2, kTestServiceUuid1);
4196   std::vector<ServiceData> fake_services{{gatt_svc, svc1}};
4197   fake_client()->set_services(std::move(fake_services));
4198 
4199   ServiceList services;
4200   mgr()->set_service_watcher(
4201       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
4202         services.insert(services.end(), added.begin(), added.end());
4203       });
4204 
4205   att::Result<> status = ToResult(HostError::kFailed);
4206   mgr()->Initialize([&status](att::Result<> val) { status = val; },
4207                     NopMtuCallback);
4208   RunUntilIdle();
4209   EXPECT_EQ(fit::ok(), status);
4210   ASSERT_EQ(2u, services.size());
4211   EXPECT_EQ(gatt_svc.range_start, services[0]->handle());
4212   EXPECT_EQ(gatt_svc.type, services[0]->uuid());
4213   EXPECT_EQ(svc1.range_start, services[1]->handle());
4214   EXPECT_EQ(svc1.type, services[1]->uuid());
4215 }
4216 
TEST_F(RemoteServiceManagerTest,EnableServiceChangedNotificationsReturnsError)4217 TEST_F(RemoteServiceManagerTest,
4218        EnableServiceChangedNotificationsReturnsError) {
4219   const att::Handle kGattSvcStartHandle(1);
4220   const att::Handle kSvcChangedChrcHandle(2);
4221   const att::Handle kSvcChangedChrcValueHandle(3);
4222   const att::Handle kCCCDescriptorHandle(4);
4223   const att::Handle kGattSvcEndHandle(kCCCDescriptorHandle);
4224 
4225   ServiceData gatt_svc(ServiceKind::PRIMARY,
4226                        kGattSvcStartHandle,
4227                        kGattSvcEndHandle,
4228                        types::kGenericAttributeService);
4229   CharacteristicData service_changed_chrc(Property::kIndicate,
4230                                           std::nullopt,
4231                                           kSvcChangedChrcHandle,
4232                                           kSvcChangedChrcValueHandle,
4233                                           types::kServiceChangedCharacteristic);
4234   DescriptorData ccc_descriptor(kCCCDescriptorHandle,
4235                                 types::kClientCharacteristicConfig);
4236   fake_client()->set_services({gatt_svc});
4237   fake_client()->set_characteristics({service_changed_chrc});
4238   fake_client()->set_descriptors({ccc_descriptor});
4239 
4240   ServiceList services;
4241   mgr()->set_service_watcher(
4242       [&services](auto /*removed*/, ServiceList added, auto /*modified*/) {
4243         services.insert(services.end(), added.begin(), added.end());
4244       });
4245 
4246   // Return an error when a Service Changed Client Characteristic Config
4247   // descriptor write is performed.
4248   int write_request_count = 0;
4249   fake_client()->set_write_request_callback(
4250       [&](att::Handle handle, const auto& value, auto status_callback) {
4251         write_request_count++;
4252         EXPECT_EQ(kCCCDescriptorHandle, handle);
4253         status_callback(ToResult(att::ErrorCode::kWriteNotPermitted));
4254       });
4255 
4256   std::optional<att::Result<>> status;
4257   mgr()->Initialize([&status](att::Result<> val) { status = val; },
4258                     NopMtuCallback);
4259   RunUntilIdle();
4260   EXPECT_EQ(ToResult(att::ErrorCode::kWriteNotPermitted), *status);
4261   EXPECT_EQ(write_request_count, 1);
4262 }
4263 
TEST_F(RemoteServiceManagerTest,ErrorDiscoveringGattProfileServiceCharacteristics)4264 TEST_F(RemoteServiceManagerTest,
4265        ErrorDiscoveringGattProfileServiceCharacteristics) {
4266   ServiceData gatt_svc(
4267       ServiceKind::PRIMARY, 1, 3, types::kGenericAttributeService);
4268   ServiceData svc1(ServiceKind::PRIMARY, 4, 4, kTestServiceUuid1);
4269   std::vector<ServiceData> fake_services{{gatt_svc, svc1}};
4270   fake_client()->set_services(std::move(fake_services));
4271 
4272   fake_client()->set_characteristic_discovery_status(
4273       ToResult(att::ErrorCode::kRequestNotSupported));
4274 
4275   std::optional<att::Result<>> status;
4276   mgr()->Initialize([&status](att::Result<> val) { status = val; },
4277                     NopMtuCallback);
4278   RunUntilIdle();
4279   EXPECT_EQ(ToResult(att::ErrorCode::kRequestNotSupported), *status);
4280 }
4281 
TEST_F(RemoteServiceManagerTest,DisableNotificationInHandlerCallback)4282 TEST_F(RemoteServiceManagerTest, DisableNotificationInHandlerCallback) {
4283   const CharacteristicHandle kChrcValueHandle(3);
4284   RemoteService::WeakPtr svc = SetupNotifiableService();
4285   std::optional<IdType> handler_id;
4286   RemoteCharacteristic::NotifyStatusCallback status_cb =
4287       [&](att::Result<> status, IdType cb_handler_id) {
4288         EXPECT_EQ(fit::ok(), status);
4289         handler_id = cb_handler_id;
4290       };
4291 
4292   int value_cb_count = 0;
4293   RemoteCharacteristic::ValueCallback value_cb = [&](auto&, auto) {
4294     value_cb_count++;
4295     ASSERT_TRUE(handler_id);
4296     // Disabling notifications in handler should not crash.
4297     svc->DisableNotifications(
4298         kChrcValueHandle, handler_id.value(), [](auto) {});
4299   };
4300   svc->EnableNotifications(
4301       kChrcValueHandle, std::move(value_cb), std::move(status_cb));
4302 
4303   fake_client()->SendNotification(/*indicate=*/false,
4304                                   kChrcValueHandle.value,
4305                                   StaticByteBuffer('y', 'e'),
4306                                   /*maybe_truncated=*/false);
4307   RunUntilIdle();
4308   EXPECT_EQ(value_cb_count, 1);
4309 
4310   // Second notification should not notify disabled handler.
4311   fake_client()->SendNotification(/*indicate=*/false,
4312                                   kChrcValueHandle.value,
4313                                   StaticByteBuffer('y', 'e'),
4314                                   /*maybe_truncated=*/false);
4315   RunUntilIdle();
4316   EXPECT_EQ(value_cb_count, 1);
4317 }
4318 
TEST_F(RemoteServiceManagerServiceChangedTest,ServiceRemovedDuringReadLongCharacteristic)4319 TEST_F(RemoteServiceManagerServiceChangedTest,
4320        ServiceRemovedDuringReadLongCharacteristic) {
4321   const att::Handle kSvc1StartHandle(5);
4322   const att::Handle kSvc1ChrcHandle(6);
4323   const att::Handle kSvc1ChrcValueHandle(7);
4324   const att::Handle kSvc1EndHandle(kSvc1ChrcValueHandle);
4325   ServiceData svc1(ServiceKind::PRIMARY,
4326                    kSvc1StartHandle,
4327                    kSvc1EndHandle,
4328                    kTestServiceUuid1);
4329   const UUID kSvc1ChrcUuid(kTestUuid3);
4330   CharacteristicData svc1_characteristic(Property::kRead,
4331                                          std::nullopt,
4332                                          kSvc1ChrcHandle,
4333                                          kSvc1ChrcValueHandle,
4334                                          kSvc1ChrcUuid);
4335   fake_client()->set_services({gatt_service(), svc1});
4336   fake_client()->set_characteristics(
4337       {service_changed_characteristic(), svc1_characteristic});
4338   fake_client()->set_descriptors({ccc_descriptor()});
4339 
4340   // Send a notification that svc1 has been added.
4341   auto svc_changed_range_buffer = StaticByteBuffer(
4342       LowerBits(kSvc1StartHandle),
4343       UpperBits(kSvc1StartHandle),  // start handle of affected range
4344       LowerBits(kSvc1EndHandle),
4345       UpperBits(kSvc1EndHandle)  // end handle of affected range
4346   );
4347   fake_client()->SendNotification(/*indicate=*/true,
4348                                   service_changed_characteristic().value_handle,
4349                                   svc_changed_range_buffer,
4350                                   /*maybe_truncated=*/false);
4351   RunUntilIdle();
4352   ASSERT_EQ(1u, svc_watcher_data().size());
4353   ASSERT_EQ(1u, svc_watcher_data()[0].added.size());
4354   EXPECT_EQ(kSvc1StartHandle, svc_watcher_data()[0].added[0]->handle());
4355 
4356   RemoteService::WeakPtr service = svc_watcher_data()[0].added[0];
4357   service->DiscoverCharacteristics([](auto, const auto&) {});
4358   RunUntilIdle();
4359 
4360   int read_req_count = 0;
4361   RemoteService::ReadValueCallback read_callback = nullptr;
4362   fake_client()->set_read_request_callback(
4363       [&](auto, RemoteService::ReadValueCallback callback) {
4364         EXPECT_EQ(read_req_count, 0);
4365         read_req_count++;
4366         read_callback = std::move(callback);
4367       });
4368   fake_client()->set_read_blob_request_callback(
4369       [](auto, auto, auto) { FAIL(); });
4370 
4371   int read_long_cb_count = 0;
4372   service->ReadLongCharacteristic(
4373       CharacteristicHandle(kSvc1ChrcValueHandle),
4374       /*offset=*/0,
4375       att::kMaxAttributeValueLength,
4376       [&](auto, auto&, auto) { read_long_cb_count++; });
4377 
4378   // Remove svc1.
4379   fake_client()->set_services({gatt_service()});
4380   fake_client()->SendNotification(/*indicate=*/true,
4381                                   service_changed_characteristic().value_handle,
4382                                   svc_changed_range_buffer,
4383                                   /*maybe_truncated=*/false);
4384   RunUntilIdle();
4385   EXPECT_FALSE(service.is_alive());
4386   ASSERT_EQ(2u, svc_watcher_data().size());
4387   ASSERT_EQ(1u, svc_watcher_data()[1].removed.size());
4388   EXPECT_EQ(read_req_count, 1);
4389   ASSERT_TRUE(read_callback);
4390 
4391   // Now that the service has been destroyed, the read long procedure should be
4392   // aborted when the first read request callback is called.
4393   StaticByteBuffer<att::kLEMinMTU - 1> expected_value;
4394   expected_value.Fill(0x02);
4395   read_callback(fit::ok(), expected_value.view(), /*maybe_truncated=*/true);
4396   RunUntilIdle();
4397   EXPECT_EQ(read_long_cb_count, 0);
4398 }
4399 
4400 }  // namespace
4401 }  // namespace bt::gatt::internal
4402