1 #pragma once
2 #include "types/bluetooth/uuid.h"
3 #include "src/gatt/ffi/gatt_shim.h"
4 #include "stack/arbiter/acl_arbiter.h"
5 #include <algorithm>
6 #include <array>
7 #include <cassert>
8 #include <cstddef>
9 #include <cstdint>
10 #include <initializer_list>
11 #include <iterator>
12 #include <memory>
13 #include <new>
14 #include <stdexcept>
15 #include <type_traits>
16 #include <utility>
17 
18 namespace rust {
19 inline namespace cxxbridge1 {
20 // #include "rust/cxx.h"
21 
22 #ifndef CXXBRIDGE1_PANIC
23 #define CXXBRIDGE1_PANIC
24 template <typename Exception>
25 void panic [[noreturn]] (const char *msg);
26 #endif // CXXBRIDGE1_PANIC
27 
28 namespace {
29 template <typename T>
30 class impl;
31 } // namespace
32 
33 class Opaque;
34 
35 template <typename T>
36 ::std::size_t size_of();
37 template <typename T>
38 ::std::size_t align_of();
39 
40 #ifndef CXXBRIDGE1_RUST_SLICE
41 #define CXXBRIDGE1_RUST_SLICE
42 namespace detail {
43 template <bool>
44 struct copy_assignable_if {};
45 
46 template <>
47 struct copy_assignable_if<false> {
48   copy_assignable_if() noexcept = default;
49   copy_assignable_if(const copy_assignable_if &) noexcept = default;
50   copy_assignable_if &operator=(const copy_assignable_if &) &noexcept = delete;
51   copy_assignable_if &operator=(copy_assignable_if &&) &noexcept = default;
52 };
53 } // namespace detail
54 
55 template <typename T>
56 class Slice final
57     : private detail::copy_assignable_if<std::is_const<T>::value> {
58 public:
59   using value_type = T;
60 
61   Slice() noexcept;
62   Slice(T *, std::size_t count) noexcept;
63 
64   Slice &operator=(const Slice<T> &) &noexcept = default;
65   Slice &operator=(Slice<T> &&) &noexcept = default;
66 
67   T *data() const noexcept;
68   std::size_t size() const noexcept;
69   std::size_t length() const noexcept;
70   bool empty() const noexcept;
71 
72   T &operator[](std::size_t n) const noexcept;
73   T &at(std::size_t n) const;
74   T &front() const noexcept;
75   T &back() const noexcept;
76 
77   Slice(const Slice<T> &) noexcept = default;
78   ~Slice() noexcept = default;
79 
80   class iterator;
81   iterator begin() const noexcept;
82   iterator end() const noexcept;
83 
84   void swap(Slice &) noexcept;
85 
86 private:
87   class uninit;
88   Slice(uninit) noexcept;
89   friend impl<Slice>;
90   friend void sliceInit(void *, const void *, std::size_t) noexcept;
91   friend void *slicePtr(const void *) noexcept;
92   friend std::size_t sliceLen(const void *) noexcept;
93 
94   std::array<std::uintptr_t, 2> repr;
95 };
96 
97 template <typename T>
98 class Slice<T>::iterator final {
99 public:
100   using iterator_category = std::random_access_iterator_tag;
101   using value_type = T;
102   using difference_type = std::ptrdiff_t;
103   using pointer = typename std::add_pointer<T>::type;
104   using reference = typename std::add_lvalue_reference<T>::type;
105 
106   reference operator*() const noexcept;
107   pointer operator->() const noexcept;
108   reference operator[](difference_type) const noexcept;
109 
110   iterator &operator++() noexcept;
111   iterator operator++(int) noexcept;
112   iterator &operator--() noexcept;
113   iterator operator--(int) noexcept;
114 
115   iterator &operator+=(difference_type) noexcept;
116   iterator &operator-=(difference_type) noexcept;
117   iterator operator+(difference_type) const noexcept;
118   iterator operator-(difference_type) const noexcept;
119   difference_type operator-(const iterator &) const noexcept;
120 
121   bool operator==(const iterator &) const noexcept;
122   bool operator!=(const iterator &) const noexcept;
123   bool operator<(const iterator &) const noexcept;
124   bool operator<=(const iterator &) const noexcept;
125   bool operator>(const iterator &) const noexcept;
126   bool operator>=(const iterator &) const noexcept;
127 
128 private:
129   friend class Slice;
130   void *pos;
131   std::size_t stride;
132 };
133 
134 template <typename T>
135 Slice<T>::Slice() noexcept {
136   sliceInit(this, reinterpret_cast<void *>(align_of<T>()), 0);
137 }
138 
139 template <typename T>
140 Slice<T>::Slice(T *s, std::size_t count) noexcept {
141   assert(s != nullptr || count == 0);
142   sliceInit(this,
143             s == nullptr && count == 0
144                 ? reinterpret_cast<void *>(align_of<T>())
145                 : const_cast<typename std::remove_const<T>::type *>(s),
146             count);
147 }
148 
149 template <typename T>
150 T *Slice<T>::data() const noexcept {
151   return reinterpret_cast<T *>(slicePtr(this));
152 }
153 
154 template <typename T>
155 std::size_t Slice<T>::size() const noexcept {
156   return sliceLen(this);
157 }
158 
159 template <typename T>
160 std::size_t Slice<T>::length() const noexcept {
161   return this->size();
162 }
163 
164 template <typename T>
165 bool Slice<T>::empty() const noexcept {
166   return this->size() == 0;
167 }
168 
169 template <typename T>
170 T &Slice<T>::operator[](std::size_t n) const noexcept {
171   assert(n < this->size());
172   auto ptr = static_cast<char *>(slicePtr(this)) + size_of<T>() * n;
173   return *reinterpret_cast<T *>(ptr);
174 }
175 
176 template <typename T>
177 T &Slice<T>::at(std::size_t n) const {
178   if (n >= this->size()) {
179     panic<std::out_of_range>("rust::Slice index out of range");
180   }
181   return (*this)[n];
182 }
183 
184 template <typename T>
185 T &Slice<T>::front() const noexcept {
186   assert(!this->empty());
187   return (*this)[0];
188 }
189 
190 template <typename T>
191 T &Slice<T>::back() const noexcept {
192   assert(!this->empty());
193   return (*this)[this->size() - 1];
194 }
195 
196 template <typename T>
197 typename Slice<T>::iterator::reference
198 Slice<T>::iterator::operator*() const noexcept {
199   return *static_cast<T *>(this->pos);
200 }
201 
202 template <typename T>
203 typename Slice<T>::iterator::pointer
204 Slice<T>::iterator::operator->() const noexcept {
205   return static_cast<T *>(this->pos);
206 }
207 
208 template <typename T>
209 typename Slice<T>::iterator::reference Slice<T>::iterator::operator[](
210     typename Slice<T>::iterator::difference_type n) const noexcept {
211   auto ptr = static_cast<char *>(this->pos) + this->stride * n;
212   return *reinterpret_cast<T *>(ptr);
213 }
214 
215 template <typename T>
216 typename Slice<T>::iterator &Slice<T>::iterator::operator++() noexcept {
217   this->pos = static_cast<char *>(this->pos) + this->stride;
218   return *this;
219 }
220 
221 template <typename T>
222 typename Slice<T>::iterator Slice<T>::iterator::operator++(int) noexcept {
223   auto ret = iterator(*this);
224   this->pos = static_cast<char *>(this->pos) + this->stride;
225   return ret;
226 }
227 
228 template <typename T>
229 typename Slice<T>::iterator &Slice<T>::iterator::operator--() noexcept {
230   this->pos = static_cast<char *>(this->pos) - this->stride;
231   return *this;
232 }
233 
234 template <typename T>
235 typename Slice<T>::iterator Slice<T>::iterator::operator--(int) noexcept {
236   auto ret = iterator(*this);
237   this->pos = static_cast<char *>(this->pos) - this->stride;
238   return ret;
239 }
240 
241 template <typename T>
242 typename Slice<T>::iterator &Slice<T>::iterator::operator+=(
243     typename Slice<T>::iterator::difference_type n) noexcept {
244   this->pos = static_cast<char *>(this->pos) + this->stride * n;
245   return *this;
246 }
247 
248 template <typename T>
249 typename Slice<T>::iterator &Slice<T>::iterator::operator-=(
250     typename Slice<T>::iterator::difference_type n) noexcept {
251   this->pos = static_cast<char *>(this->pos) - this->stride * n;
252   return *this;
253 }
254 
255 template <typename T>
256 typename Slice<T>::iterator Slice<T>::iterator::operator+(
257     typename Slice<T>::iterator::difference_type n) const noexcept {
258   auto ret = iterator(*this);
259   ret.pos = static_cast<char *>(this->pos) + this->stride * n;
260   return ret;
261 }
262 
263 template <typename T>
264 typename Slice<T>::iterator Slice<T>::iterator::operator-(
265     typename Slice<T>::iterator::difference_type n) const noexcept {
266   auto ret = iterator(*this);
267   ret.pos = static_cast<char *>(this->pos) - this->stride * n;
268   return ret;
269 }
270 
271 template <typename T>
272 typename Slice<T>::iterator::difference_type
273 Slice<T>::iterator::operator-(const iterator &other) const noexcept {
274   auto diff = std::distance(static_cast<char *>(other.pos),
275                             static_cast<char *>(this->pos));
276   return diff / static_cast<typename Slice<T>::iterator::difference_type>(
277                     this->stride);
278 }
279 
280 template <typename T>
281 bool Slice<T>::iterator::operator==(const iterator &other) const noexcept {
282   return this->pos == other.pos;
283 }
284 
285 template <typename T>
286 bool Slice<T>::iterator::operator!=(const iterator &other) const noexcept {
287   return this->pos != other.pos;
288 }
289 
290 template <typename T>
291 bool Slice<T>::iterator::operator<(const iterator &other) const noexcept {
292   return this->pos < other.pos;
293 }
294 
295 template <typename T>
296 bool Slice<T>::iterator::operator<=(const iterator &other) const noexcept {
297   return this->pos <= other.pos;
298 }
299 
300 template <typename T>
301 bool Slice<T>::iterator::operator>(const iterator &other) const noexcept {
302   return this->pos > other.pos;
303 }
304 
305 template <typename T>
306 bool Slice<T>::iterator::operator>=(const iterator &other) const noexcept {
307   return this->pos >= other.pos;
308 }
309 
310 template <typename T>
311 typename Slice<T>::iterator Slice<T>::begin() const noexcept {
312   iterator it;
313   it.pos = slicePtr(this);
314   it.stride = size_of<T>();
315   return it;
316 }
317 
318 template <typename T>
319 typename Slice<T>::iterator Slice<T>::end() const noexcept {
320   iterator it = this->begin();
321   it.pos = static_cast<char *>(it.pos) + it.stride * this->size();
322   return it;
323 }
324 
325 template <typename T>
326 void Slice<T>::swap(Slice &rhs) noexcept {
327   std::swap(*this, rhs);
328 }
329 #endif // CXXBRIDGE1_RUST_SLICE
330 
331 #ifndef CXXBRIDGE1_RUST_BITCOPY_T
332 #define CXXBRIDGE1_RUST_BITCOPY_T
333 struct unsafe_bitcopy_t final {
334   explicit unsafe_bitcopy_t() = default;
335 };
336 #endif // CXXBRIDGE1_RUST_BITCOPY_T
337 
338 #ifndef CXXBRIDGE1_RUST_VEC
339 #define CXXBRIDGE1_RUST_VEC
340 template <typename T>
341 class Vec final {
342 public:
343   using value_type = T;
344 
345   Vec() noexcept;
346   Vec(std::initializer_list<T>);
347   Vec(const Vec &);
348   Vec(Vec &&) noexcept;
349   ~Vec() noexcept;
350 
351   Vec &operator=(Vec &&) &noexcept;
352   Vec &operator=(const Vec &) &;
353 
354   std::size_t size() const noexcept;
355   bool empty() const noexcept;
356   const T *data() const noexcept;
357   T *data() noexcept;
358   std::size_t capacity() const noexcept;
359 
360   const T &operator[](std::size_t n) const noexcept;
361   const T &at(std::size_t n) const;
362   const T &front() const noexcept;
363   const T &back() const noexcept;
364 
365   T &operator[](std::size_t n) noexcept;
366   T &at(std::size_t n);
367   T &front() noexcept;
368   T &back() noexcept;
369 
370   void reserve(std::size_t new_cap);
371   void push_back(const T &value);
372   void push_back(T &&value);
373   template <typename... Args>
374   void emplace_back(Args &&...args);
375   void truncate(std::size_t len);
376   void clear();
377 
378   using iterator = typename Slice<T>::iterator;
379   iterator begin() noexcept;
380   iterator end() noexcept;
381 
382   using const_iterator = typename Slice<const T>::iterator;
383   const_iterator begin() const noexcept;
384   const_iterator end() const noexcept;
385   const_iterator cbegin() const noexcept;
386   const_iterator cend() const noexcept;
387 
388   void swap(Vec &) noexcept;
389 
390   Vec(unsafe_bitcopy_t, const Vec &) noexcept;
391 
392 private:
393   void reserve_total(std::size_t new_cap) noexcept;
394   void set_len(std::size_t len) noexcept;
395   void drop() noexcept;
396 
397   friend void swap(Vec &lhs, Vec &rhs) noexcept { lhs.swap(rhs); }
398 
399   std::array<std::uintptr_t, 3> repr;
400 };
401 
402 template <typename T>
403 Vec<T>::Vec(std::initializer_list<T> init) : Vec{} {
404   this->reserve_total(init.size());
405   std::move(init.begin(), init.end(), std::back_inserter(*this));
406 }
407 
408 template <typename T>
409 Vec<T>::Vec(const Vec &other) : Vec() {
410   this->reserve_total(other.size());
411   std::copy(other.begin(), other.end(), std::back_inserter(*this));
412 }
413 
414 template <typename T>
415 Vec<T>::Vec(Vec &&other) noexcept : repr(other.repr) {
416   new (&other) Vec();
417 }
418 
419 template <typename T>
420 Vec<T>::~Vec() noexcept {
421   this->drop();
422 }
423 
424 template <typename T>
425 Vec<T> &Vec<T>::operator=(Vec &&other) &noexcept {
426   this->drop();
427   this->repr = other.repr;
428   new (&other) Vec();
429   return *this;
430 }
431 
432 template <typename T>
433 Vec<T> &Vec<T>::operator=(const Vec &other) & {
434   if (this != &other) {
435     this->drop();
436     new (this) Vec(other);
437   }
438   return *this;
439 }
440 
441 template <typename T>
442 bool Vec<T>::empty() const noexcept {
443   return this->size() == 0;
444 }
445 
446 template <typename T>
447 T *Vec<T>::data() noexcept {
448   return const_cast<T *>(const_cast<const Vec<T> *>(this)->data());
449 }
450 
451 template <typename T>
452 const T &Vec<T>::operator[](std::size_t n) const noexcept {
453   assert(n < this->size());
454   auto data = reinterpret_cast<const char *>(this->data());
455   return *reinterpret_cast<const T *>(data + n * size_of<T>());
456 }
457 
458 template <typename T>
459 const T &Vec<T>::at(std::size_t n) const {
460   if (n >= this->size()) {
461     panic<std::out_of_range>("rust::Vec index out of range");
462   }
463   return (*this)[n];
464 }
465 
466 template <typename T>
467 const T &Vec<T>::front() const noexcept {
468   assert(!this->empty());
469   return (*this)[0];
470 }
471 
472 template <typename T>
473 const T &Vec<T>::back() const noexcept {
474   assert(!this->empty());
475   return (*this)[this->size() - 1];
476 }
477 
478 template <typename T>
479 T &Vec<T>::operator[](std::size_t n) noexcept {
480   assert(n < this->size());
481   auto data = reinterpret_cast<char *>(this->data());
482   return *reinterpret_cast<T *>(data + n * size_of<T>());
483 }
484 
485 template <typename T>
486 T &Vec<T>::at(std::size_t n) {
487   if (n >= this->size()) {
488     panic<std::out_of_range>("rust::Vec index out of range");
489   }
490   return (*this)[n];
491 }
492 
493 template <typename T>
494 T &Vec<T>::front() noexcept {
495   assert(!this->empty());
496   return (*this)[0];
497 }
498 
499 template <typename T>
500 T &Vec<T>::back() noexcept {
501   assert(!this->empty());
502   return (*this)[this->size() - 1];
503 }
504 
505 template <typename T>
506 void Vec<T>::reserve(std::size_t new_cap) {
507   this->reserve_total(new_cap);
508 }
509 
510 template <typename T>
511 void Vec<T>::push_back(const T &value) {
512   this->emplace_back(value);
513 }
514 
515 template <typename T>
516 void Vec<T>::push_back(T &&value) {
517   this->emplace_back(std::move(value));
518 }
519 
520 template <typename T>
521 template <typename... Args>
522 void Vec<T>::emplace_back(Args &&...args) {
523   auto size = this->size();
524   this->reserve_total(size + 1);
525   ::new (reinterpret_cast<T *>(reinterpret_cast<char *>(this->data()) +
526                                size * size_of<T>()))
527       T(std::forward<Args>(args)...);
528   this->set_len(size + 1);
529 }
530 
531 template <typename T>
532 void Vec<T>::clear() {
533   this->truncate(0);
534 }
535 
536 template <typename T>
537 typename Vec<T>::iterator Vec<T>::begin() noexcept {
538   return Slice<T>(this->data(), this->size()).begin();
539 }
540 
541 template <typename T>
542 typename Vec<T>::iterator Vec<T>::end() noexcept {
543   return Slice<T>(this->data(), this->size()).end();
544 }
545 
546 template <typename T>
547 typename Vec<T>::const_iterator Vec<T>::begin() const noexcept {
548   return this->cbegin();
549 }
550 
551 template <typename T>
552 typename Vec<T>::const_iterator Vec<T>::end() const noexcept {
553   return this->cend();
554 }
555 
556 template <typename T>
557 typename Vec<T>::const_iterator Vec<T>::cbegin() const noexcept {
558   return Slice<const T>(this->data(), this->size()).begin();
559 }
560 
561 template <typename T>
562 typename Vec<T>::const_iterator Vec<T>::cend() const noexcept {
563   return Slice<const T>(this->data(), this->size()).end();
564 }
565 
566 template <typename T>
567 void Vec<T>::swap(Vec &rhs) noexcept {
568   using std::swap;
569   swap(this->repr, rhs.repr);
570 }
571 
572 template <typename T>
573 Vec<T>::Vec(unsafe_bitcopy_t, const Vec &bits) noexcept : repr(bits.repr) {}
574 #endif // CXXBRIDGE1_RUST_VEC
575 
576 #ifndef CXXBRIDGE1_RUST_FN
577 #define CXXBRIDGE1_RUST_FN
578 template <typename Signature>
579 class Fn;
580 
581 template <typename Ret, typename... Args>
582 class Fn<Ret(Args...)> final {
583 public:
584   Ret operator()(Args... args) const noexcept;
585   Fn operator*() const noexcept;
586 
587 private:
588   Ret (*trampoline)(Args..., void *fn) noexcept;
589   void *fn;
590 };
591 
592 template <typename Ret, typename... Args>
593 Ret Fn<Ret(Args...)>::operator()(Args... args) const noexcept {
594   return (*this->trampoline)(std::forward<Args>(args)..., this->fn);
595 }
596 
597 template <typename Ret, typename... Args>
598 Fn<Ret(Args...)> Fn<Ret(Args...)>::operator*() const noexcept {
599   return *this;
600 }
601 #endif // CXXBRIDGE1_RUST_FN
602 
603 #ifndef CXXBRIDGE1_IS_COMPLETE
604 #define CXXBRIDGE1_IS_COMPLETE
605 namespace detail {
606 namespace {
607 template <typename T, typename = std::size_t>
608 struct is_complete : std::false_type {};
609 template <typename T>
610 struct is_complete<T, decltype(sizeof(T))> : std::true_type {};
611 } // namespace
612 } // namespace detail
613 #endif // CXXBRIDGE1_IS_COMPLETE
614 
615 #ifndef CXXBRIDGE1_LAYOUT
616 #define CXXBRIDGE1_LAYOUT
617 class layout {
618   template <typename T>
619   friend std::size_t size_of();
620   template <typename T>
621   friend std::size_t align_of();
622   template <typename T>
623   static typename std::enable_if<std::is_base_of<Opaque, T>::value,
624                                  std::size_t>::type
625   do_size_of() {
626     return T::layout::size();
627   }
628   template <typename T>
629   static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
630                                  std::size_t>::type
631   do_size_of() {
632     return sizeof(T);
633   }
634   template <typename T>
635   static
636       typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
637       size_of() {
638     return do_size_of<T>();
639   }
640   template <typename T>
641   static typename std::enable_if<std::is_base_of<Opaque, T>::value,
642                                  std::size_t>::type
643   do_align_of() {
644     return T::layout::align();
645   }
646   template <typename T>
647   static typename std::enable_if<!std::is_base_of<Opaque, T>::value,
648                                  std::size_t>::type
649   do_align_of() {
650     return alignof(T);
651   }
652   template <typename T>
653   static
654       typename std::enable_if<detail::is_complete<T>::value, std::size_t>::type
655       align_of() {
656     return do_align_of<T>();
657   }
658 };
659 
660 template <typename T>
661 std::size_t size_of() {
662   return layout::size_of<T>();
663 }
664 
665 template <typename T>
666 std::size_t align_of() {
667   return layout::align_of<T>();
668 }
669 #endif // CXXBRIDGE1_LAYOUT
670 } // namespace cxxbridge1
671 } // namespace rust
672 
673 namespace bluetooth {
674   namespace gatt {
675     using AttributeBackingType = ::bluetooth::gatt::AttributeBackingType;
676     using GattServerCallbacks = ::bluetooth::gatt::GattServerCallbacks;
677     enum class GattRecordType : ::std::uint8_t;
678     struct GattRecord;
679   }
680   namespace shim {
681     namespace arbiter {
682       using InterceptAction = ::bluetooth::shim::arbiter::InterceptAction;
683     }
684   }
685 }
686 
687 namespace bluetooth {
688 namespace gatt {
689 static_assert(::std::is_enum<AttributeBackingType>::value, "expected enum");
690 static_assert(sizeof(AttributeBackingType) == sizeof(::std::uint32_t), "incorrect size");
691 static_assert(static_cast<::std::uint32_t>(AttributeBackingType::CHARACTERISTIC) == 0, "disagrees with the value in #[cxx::bridge]");
692 static_assert(static_cast<::std::uint32_t>(AttributeBackingType::DESCRIPTOR) == 1, "disagrees with the value in #[cxx::bridge]");
693 } // namespace gatt
694 
695 namespace shim {
696 namespace arbiter {
697 static_assert(::std::is_enum<InterceptAction>::value, "expected enum");
698 static_assert(sizeof(InterceptAction) == sizeof(::std::uint32_t), "incorrect size");
699 static_assert(static_cast<::std::uint32_t>(InterceptAction::FORWARD) == 0, "disagrees with the value in #[cxx::bridge]");
700 static_assert(static_cast<::std::uint32_t>(InterceptAction::DROP) == 1, "disagrees with the value in #[cxx::bridge]");
701 } // namespace arbiter
702 } // namespace shim
703 
704 namespace gatt {
705 #ifndef CXXBRIDGE1_ENUM_bluetooth$gatt$GattRecordType
706 #define CXXBRIDGE1_ENUM_bluetooth$gatt$GattRecordType
707 // The type of GATT record supplied over FFI
708 enum class GattRecordType : ::std::uint8_t {
709   PrimaryService = 0,
710   SecondaryService = 1,
711   IncludedService = 2,
712   Characteristic = 3,
713   Descriptor = 4,
714 };
715 #endif // CXXBRIDGE1_ENUM_bluetooth$gatt$GattRecordType
716 
717 #ifndef CXXBRIDGE1_STRUCT_bluetooth$gatt$GattRecord
718 #define CXXBRIDGE1_STRUCT_bluetooth$gatt$GattRecord
719 // An entry in a service definition received from JNI. See GattRecordType
720 // for possible types.
721 struct GattRecord final {
722   ::bluetooth::Uuid uuid;
723   ::bluetooth::gatt::GattRecordType record_type;
724   ::std::uint16_t attribute_handle;
725   ::std::uint8_t properties;
726   ::std::uint16_t extended_properties;
727   ::std::uint16_t permissions;
728 
729   using IsRelocatable = ::std::true_type;
730 };
731 #endif // CXXBRIDGE1_STRUCT_bluetooth$gatt$GattRecord
732 
733 void open_server(::std::uint8_t server_id) noexcept;
734 
735 void close_server(::std::uint8_t server_id) noexcept;
736 
737 void add_service(::std::uint8_t server_id, ::rust::Vec<::bluetooth::gatt::GattRecord> service_records) noexcept;
738 
739 void remove_service(::std::uint8_t server_id, ::std::uint16_t service_handle) noexcept;
740 
741 void send_response(::std::uint8_t server_id, ::std::uint16_t conn_id, ::std::uint32_t trans_id, ::std::uint8_t status, ::rust::Slice<::std::uint8_t const> value) noexcept;
742 
743 void send_indication(::std::uint8_t _server_id, ::std::uint16_t handle, ::std::uint16_t conn_id, ::rust::Slice<::std::uint8_t const> value) noexcept;
744 
745 bool is_connection_isolated(::std::uint16_t conn_id) noexcept;
746 
747 void associate_server_with_advertiser(::std::uint8_t server_id, ::std::uint8_t advertiser_id) noexcept;
748 
749 void clear_advertiser(::std::uint8_t advertiser_id) noexcept;
750 } // namespace gatt
751 } // namespace bluetooth
752