simplejsble 0.0.4 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. package/VERSION +1 -0
  2. package/android/CMakeLists.txt +62 -20
  3. package/cmake/epilogue.cmake +81 -0
  4. package/cmake/find/FindDBus1.cmake +20 -0
  5. package/cmake/find/Findfmt.cmake +41 -0
  6. package/cmake/find/Findgoogletest.cmake +18 -0
  7. package/cmake/parse_version.cmake +45 -0
  8. package/cmake/prelude.cmake +8 -0
  9. package/dependencies/README +4 -0
  10. package/dependencies/external/kvn/kvn_bytearray.h +297 -0
  11. package/dependencies/external/kvn/kvn_safe_callback.hpp +66 -0
  12. package/dependencies/external/kvn/logfwd.hpp +35 -0
  13. package/dependencies/internal/include/fmt/LICENSE +27 -0
  14. package/dependencies/internal/include/fmt/args.h +220 -0
  15. package/dependencies/internal/include/fmt/base.h +2962 -0
  16. package/dependencies/internal/include/fmt/chrono.h +2338 -0
  17. package/dependencies/internal/include/fmt/color.h +610 -0
  18. package/dependencies/internal/include/fmt/compile.h +539 -0
  19. package/dependencies/internal/include/fmt/core.h +5 -0
  20. package/dependencies/internal/include/fmt/format-inl.h +1949 -0
  21. package/dependencies/internal/include/fmt/format.h +4244 -0
  22. package/dependencies/internal/include/fmt/os.h +427 -0
  23. package/dependencies/internal/include/fmt/ostream.h +166 -0
  24. package/dependencies/internal/include/fmt/printf.h +633 -0
  25. package/dependencies/internal/include/fmt/ranges.h +850 -0
  26. package/dependencies/internal/include/fmt/std.h +726 -0
  27. package/dependencies/internal/include/fmt/xchar.h +373 -0
  28. package/dependencies/internal/include/nanopb/pb.h +948 -0
  29. package/dependencies/internal/include/nanopb/pb_common.h +49 -0
  30. package/dependencies/internal/include/nanopb/pb_decode.h +204 -0
  31. package/dependencies/internal/include/nanopb/pb_encode.h +195 -0
  32. package/dependencies/internal/include/simplejni/Common.hpp +598 -0
  33. package/dependencies/internal/include/simplejni/References.hpp +151 -0
  34. package/dependencies/internal/include/simplejni/Registry.hpp +249 -0
  35. package/dependencies/internal/include/simplejni/VM.hpp +93 -0
  36. package/dependencies/internal/src/nanopb/pb_common.c +388 -0
  37. package/dependencies/internal/src/nanopb/pb_decode.c +1763 -0
  38. package/dependencies/internal/src/nanopb/pb_encode.c +1009 -0
  39. package/dependencies/internal/src/simplejni/Common.cpp +4 -0
  40. package/package.json +5 -1
  41. package/simpleble/CMakeLists.txt +519 -0
  42. package/simpleble/cmake/simpleble.pc.in +11 -0
  43. package/simpleble/include/simpleble/Adapter.h +102 -0
  44. package/simpleble/include/simpleble/AdapterSafe.h +58 -0
  45. package/simpleble/include/simpleble/Advanced.h +50 -0
  46. package/simpleble/include/simpleble/Characteristic.h +39 -0
  47. package/simpleble/include/simpleble/Config.h +64 -0
  48. package/simpleble/include/simpleble/Descriptor.h +30 -0
  49. package/simpleble/include/simpleble/Exceptions.h +72 -0
  50. package/simpleble/include/simpleble/Logging.h +73 -0
  51. package/simpleble/include/simpleble/Peripheral.h +82 -0
  52. package/simpleble/include/simpleble/PeripheralSafe.h +64 -0
  53. package/simpleble/include/simpleble/Service.h +34 -0
  54. package/simpleble/include/simpleble/SimpleBLE.h +8 -0
  55. package/simpleble/include/simpleble/Types.h +49 -0
  56. package/simpleble/include/simpleble/Utils.h +13 -0
  57. package/simpleble/include/simpleble_c/DEPRECATED +2 -0
  58. package/simpleble/include/simpleble_c/adapter.h +188 -0
  59. package/simpleble/include/simpleble_c/logging.h +37 -0
  60. package/simpleble/include/simpleble_c/peripheral.h +304 -0
  61. package/simpleble/include/simpleble_c/simpleble.h +21 -0
  62. package/simpleble/include/simpleble_c/types.h +73 -0
  63. package/simpleble/include/simpleble_c/utils.h +27 -0
  64. package/simpleble/src/CommonUtils.h +63 -0
  65. package/simpleble/src/Config.cpp +25 -0
  66. package/simpleble/src/Exceptions.cpp +31 -0
  67. package/simpleble/src/Logging.cpp +136 -0
  68. package/simpleble/src/LoggingInternal.h +85 -0
  69. package/simpleble/src/Utils.cpp +24 -0
  70. package/simpleble/src/backends/android/AdapterAndroid.cpp +101 -0
  71. package/simpleble/src/backends/android/AdapterAndroid.h +67 -0
  72. package/simpleble/src/backends/android/BackendAndroid.cpp +41 -0
  73. package/simpleble/src/backends/android/BackendAndroid.h +26 -0
  74. package/simpleble/src/backends/android/PeripheralAndroid.cpp +365 -0
  75. package/simpleble/src/backends/android/PeripheralAndroid.h +90 -0
  76. package/simpleble/src/backends/android/bridge/BluetoothGattCallback.cpp +432 -0
  77. package/simpleble/src/backends/android/bridge/BluetoothGattCallback.h +102 -0
  78. package/simpleble/src/backends/android/bridge/ScanCallback.cpp +142 -0
  79. package/simpleble/src/backends/android/bridge/ScanCallback.h +55 -0
  80. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothAdapter.cpp +107 -0
  81. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothAdapter.h +55 -0
  82. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothDevice.cpp +68 -0
  83. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothDevice.h +54 -0
  84. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGatt.cpp +115 -0
  85. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGatt.h +75 -0
  86. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattCharacteristic.cpp +142 -0
  87. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattCharacteristic.h +66 -0
  88. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattDescriptor.cpp +67 -0
  89. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattDescriptor.h +46 -0
  90. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattService.cpp +106 -0
  91. package/simpleble/src/backends/android/types/android/bluetooth/BluetoothGattService.h +47 -0
  92. package/simpleble/src/backends/android/types/android/bluetooth/le/BluetoothScanner.cpp +47 -0
  93. package/simpleble/src/backends/android/types/android/bluetooth/le/BluetoothScanner.h +37 -0
  94. package/simpleble/src/backends/android/types/android/bluetooth/le/ScanRecord.cpp +69 -0
  95. package/simpleble/src/backends/android/types/android/bluetooth/le/ScanRecord.h +41 -0
  96. package/simpleble/src/backends/android/types/android/bluetooth/le/ScanResult.cpp +63 -0
  97. package/simpleble/src/backends/android/types/android/bluetooth/le/ScanResult.h +42 -0
  98. package/simpleble/src/backends/android/types/android/os/ParcelUUID.cpp +32 -0
  99. package/simpleble/src/backends/android/types/android/os/ParcelUUID.h +30 -0
  100. package/simpleble/src/backends/android/types/android/util/SparseArray.cpp +54 -0
  101. package/simpleble/src/backends/android/types/android/util/SparseArray.h +37 -0
  102. package/simpleble/src/backends/android/types/java/util/Iterator.cpp +36 -0
  103. package/simpleble/src/backends/android/types/java/util/Iterator.h +28 -0
  104. package/simpleble/src/backends/android/types/java/util/List.cpp +29 -0
  105. package/simpleble/src/backends/android/types/java/util/List.h +27 -0
  106. package/simpleble/src/backends/android/types/java/util/Set.cpp +33 -0
  107. package/simpleble/src/backends/android/types/java/util/Set.h +28 -0
  108. package/simpleble/src/backends/android/types/java/util/UUID.cpp +26 -0
  109. package/simpleble/src/backends/android/types/java/util/UUID.h +29 -0
  110. package/simpleble/src/backends/common/AdapterBase.cpp +53 -0
  111. package/simpleble/src/backends/common/AdapterBase.h +81 -0
  112. package/simpleble/src/backends/common/AdapterBaseTypes.h +22 -0
  113. package/simpleble/src/backends/common/BackendBase.h +20 -0
  114. package/simpleble/src/backends/common/BackendUtils.h +33 -0
  115. package/simpleble/src/backends/common/CharacteristicBase.cpp +28 -0
  116. package/simpleble/src/backends/common/CharacteristicBase.h +38 -0
  117. package/simpleble/src/backends/common/DescriptorBase.cpp +7 -0
  118. package/simpleble/src/backends/common/DescriptorBase.h +19 -0
  119. package/simpleble/src/backends/common/PeripheralBase.h +82 -0
  120. package/simpleble/src/backends/common/ServiceBase.cpp +18 -0
  121. package/simpleble/src/backends/common/ServiceBase.h +28 -0
  122. package/simpleble/src/backends/dongl/AdapterBaseTypes.h +22 -0
  123. package/simpleble/src/backends/dongl/AdapterDongl.cpp +369 -0
  124. package/simpleble/src/backends/dongl/AdapterDongl.h +60 -0
  125. package/simpleble/src/backends/dongl/BackendDongl.cpp +35 -0
  126. package/simpleble/src/backends/dongl/PeripheralDongl.cpp +562 -0
  127. package/simpleble/src/backends/dongl/PeripheralDongl.h +136 -0
  128. package/simpleble/src/backends/dongl/protocol/basic.pb.c +33 -0
  129. package/simpleble/src/backends/dongl/protocol/basic.pb.h +172 -0
  130. package/simpleble/src/backends/dongl/protocol/d2h.pb.c +18 -0
  131. package/simpleble/src/backends/dongl/protocol/d2h.pb.h +118 -0
  132. package/simpleble/src/backends/dongl/protocol/h2d.pb.c +12 -0
  133. package/simpleble/src/backends/dongl/protocol/h2d.pb.h +69 -0
  134. package/simpleble/src/backends/dongl/protocol/simpleble.pb.c +123 -0
  135. package/simpleble/src/backends/dongl/protocol/simpleble.pb.h +908 -0
  136. package/simpleble/src/backends/dongl/protocol/softdevice.pb.c +18 -0
  137. package/simpleble/src/backends/dongl/protocol/softdevice.pb.h +815 -0
  138. package/simpleble/src/backends/dongl/protocol/softdevice_gap.pb.c +339 -0
  139. package/simpleble/src/backends/dongl/protocol/softdevice_gap.pb.h +2086 -0
  140. package/simpleble/src/backends/dongl/protocol/softdevice_gattc.pb.c +114 -0
  141. package/simpleble/src/backends/dongl/protocol/softdevice_gattc.pb.h +772 -0
  142. package/simpleble/src/backends/dongl/protocol/softdevice_gatts.pb.c +117 -0
  143. package/simpleble/src/backends/dongl/protocol/softdevice_gatts.pb.h +766 -0
  144. package/simpleble/src/backends/dongl/protocol/softdevice_types.pb.c +207 -0
  145. package/simpleble/src/backends/dongl/protocol/softdevice_types.pb.h +1686 -0
  146. package/simpleble/src/backends/dongl/serial/Protocol.cpp +887 -0
  147. package/simpleble/src/backends/dongl/serial/Protocol.h +117 -0
  148. package/simpleble/src/backends/dongl/serial/ProtocolBase.cpp +95 -0
  149. package/simpleble/src/backends/dongl/serial/ProtocolBase.h +54 -0
  150. package/simpleble/src/backends/dongl/serial/Wire.cpp +133 -0
  151. package/simpleble/src/backends/dongl/serial/Wire.h +116 -0
  152. package/simpleble/src/backends/dongl/usb/UsbHelper.cpp +53 -0
  153. package/simpleble/src/backends/dongl/usb/UsbHelper.h +32 -0
  154. package/simpleble/src/backends/dongl/usb/UsbHelperApple.cpp +266 -0
  155. package/simpleble/src/backends/dongl/usb/UsbHelperApple.h +34 -0
  156. package/simpleble/src/backends/dongl/usb/UsbHelperImpl.h +29 -0
  157. package/simpleble/src/backends/dongl/usb/UsbHelperLinux.cpp +21 -0
  158. package/simpleble/src/backends/dongl/usb/UsbHelperLinux.h +22 -0
  159. package/simpleble/src/backends/dongl/usb/UsbHelperNull.cpp +21 -0
  160. package/simpleble/src/backends/dongl/usb/UsbHelperNull.h +22 -0
  161. package/simpleble/src/backends/dongl/usb/UsbHelperWindows.cpp +21 -0
  162. package/simpleble/src/backends/dongl/usb/UsbHelperWindows.h +22 -0
  163. package/simpleble/src/backends/linux/AdapterLinux.cpp +102 -0
  164. package/simpleble/src/backends/linux/AdapterLinux.h +55 -0
  165. package/simpleble/src/backends/linux/BackendBluez.cpp +90 -0
  166. package/simpleble/src/backends/linux/PeripheralLinux.cpp +394 -0
  167. package/simpleble/src/backends/linux/PeripheralLinux.h +90 -0
  168. package/simpleble/src/backends/linux_legacy/AdapterLinuxLegacy.cpp +102 -0
  169. package/simpleble/src/backends/linux_legacy/AdapterLinuxLegacy.h +55 -0
  170. package/simpleble/src/backends/linux_legacy/BackendBluezLegacy.cpp +87 -0
  171. package/simpleble/src/backends/linux_legacy/PeripheralLinuxLegacy.cpp +376 -0
  172. package/simpleble/src/backends/linux_legacy/PeripheralLinuxLegacy.h +90 -0
  173. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Adapter.h +46 -0
  174. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Agent.h +52 -0
  175. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Bluez.h +37 -0
  176. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/BluezOrg.h +22 -0
  177. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/BluezOrgBluez.h +26 -0
  178. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/BluezRoot.h +32 -0
  179. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Characteristic.h +47 -0
  180. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Descriptor.h +33 -0
  181. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Device.h +64 -0
  182. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Exceptions.h +43 -0
  183. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Service.h +27 -0
  184. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/Types.h +9 -0
  185. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/Adapter1.h +49 -0
  186. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/Agent1.h +100 -0
  187. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/AgentManager1.h +24 -0
  188. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/Battery1.h +32 -0
  189. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/Device1.h +62 -0
  190. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/GattCharacteristic1.h +48 -0
  191. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/GattDescriptor1.h +41 -0
  192. package/simpleble/src/backends/linux_legacy/include/simplebluezlegacy/interfaces/GattService1.h +28 -0
  193. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/advanced/Interface.h +67 -0
  194. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/advanced/InterfaceRegistry.h +62 -0
  195. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/advanced/Proxy.h +117 -0
  196. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Connection.h +50 -0
  197. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Exceptions.h +56 -0
  198. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Holder.h +147 -0
  199. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Logging.h +57 -0
  200. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Message.h +89 -0
  201. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/base/Path.h +24 -0
  202. package/simpleble/src/backends/linux_legacy/include/simpledbuslegacy/interfaces/ObjectManager.h +26 -0
  203. package/simpleble/src/backends/linux_legacy/src/Adapter.cpp +78 -0
  204. package/simpleble/src/backends/linux_legacy/src/Agent.cpp +72 -0
  205. package/simpleble/src/backends/linux_legacy/src/Bluez.cpp +45 -0
  206. package/simpleble/src/backends/linux_legacy/src/BluezOrg.cpp +20 -0
  207. package/simpleble/src/backends/linux_legacy/src/BluezOrgBluez.cpp +23 -0
  208. package/simpleble/src/backends/linux_legacy/src/BluezRoot.cpp +44 -0
  209. package/simpleble/src/backends/linux_legacy/src/Characteristic.cpp +64 -0
  210. package/simpleble/src/backends/linux_legacy/src/Descriptor.cpp +27 -0
  211. package/simpleble/src/backends/linux_legacy/src/Device.cpp +104 -0
  212. package/simpleble/src/backends/linux_legacy/src/Exceptions.cpp +29 -0
  213. package/simpleble/src/backends/linux_legacy/src/Service.cpp +33 -0
  214. package/simpleble/src/backends/linux_legacy/src/advanced/Interface.cpp +155 -0
  215. package/simpleble/src/backends/linux_legacy/src/advanced/Proxy.cpp +374 -0
  216. package/simpleble/src/backends/linux_legacy/src/base/Connection.cpp +219 -0
  217. package/simpleble/src/backends/linux_legacy/src/base/Exceptions.cpp +39 -0
  218. package/simpleble/src/backends/linux_legacy/src/base/Holder.cpp +739 -0
  219. package/simpleble/src/backends/linux_legacy/src/base/Message.cpp +622 -0
  220. package/simpleble/src/backends/linux_legacy/src/base/Path.cpp +129 -0
  221. package/simpleble/src/backends/linux_legacy/src/interfaces/Adapter1.cpp +123 -0
  222. package/simpleble/src/backends/linux_legacy/src/interfaces/Agent1.cpp +143 -0
  223. package/simpleble/src/backends/linux_legacy/src/interfaces/AgentManager1.cpp +34 -0
  224. package/simpleble/src/backends/linux_legacy/src/interfaces/Battery1.cpp +30 -0
  225. package/simpleble/src/backends/linux_legacy/src/interfaces/Device1.cpp +170 -0
  226. package/simpleble/src/backends/linux_legacy/src/interfaces/GattCharacteristic1.cpp +118 -0
  227. package/simpleble/src/backends/linux_legacy/src/interfaces/GattDescriptor1.cpp +78 -0
  228. package/simpleble/src/backends/linux_legacy/src/interfaces/GattService1.cpp +28 -0
  229. package/simpleble/src/backends/linux_legacy/src/interfaces/ObjectManager.cpp +58 -0
  230. package/simpleble/src/backends/macos/AdapterBaseMacOS.h +29 -0
  231. package/simpleble/src/backends/macos/AdapterBaseMacOS.mm +235 -0
  232. package/simpleble/src/backends/macos/AdapterMac.h +78 -0
  233. package/simpleble/src/backends/macos/AdapterMac.mm +156 -0
  234. package/simpleble/src/backends/macos/BackendCoreBluetooth.mm +45 -0
  235. package/simpleble/src/backends/macos/PeripheralBaseMacOS.h +49 -0
  236. package/simpleble/src/backends/macos/PeripheralBaseMacOS.mm +714 -0
  237. package/simpleble/src/backends/macos/PeripheralMac.h +81 -0
  238. package/simpleble/src/backends/macos/PeripheralMac.mm +229 -0
  239. package/simpleble/src/backends/macos/Utils.h +9 -0
  240. package/simpleble/src/backends/macos/Utils.mm +23 -0
  241. package/simpleble/src/backends/plain/AdapterPlain.cpp +65 -0
  242. package/simpleble/src/backends/plain/AdapterPlain.h +49 -0
  243. package/simpleble/src/backends/plain/BackendPlain.cpp +30 -0
  244. package/simpleble/src/backends/plain/PeripheralPlain.cpp +159 -0
  245. package/simpleble/src/backends/plain/PeripheralPlain.h +72 -0
  246. package/simpleble/src/backends/windows/AdapterWindows.cpp +338 -0
  247. package/simpleble/src/backends/windows/AdapterWindows.h +89 -0
  248. package/simpleble/src/backends/windows/BackendWinRT.cpp +67 -0
  249. package/simpleble/src/backends/windows/BackendWinRT.h +18 -0
  250. package/simpleble/src/backends/windows/MtaManager.cpp +49 -0
  251. package/simpleble/src/backends/windows/MtaManager.h +90 -0
  252. package/simpleble/src/backends/windows/PeripheralWindows.cpp +487 -0
  253. package/simpleble/src/backends/windows/PeripheralWindows.h +129 -0
  254. package/simpleble/src/backends/windows/Utils.cpp +146 -0
  255. package/simpleble/src/backends/windows/Utils.h +47 -0
  256. package/simpleble/src/builders/BuildVec.h +32 -0
  257. package/simpleble/src/builders/BuilderBase.h +87 -0
  258. package/simpleble/src/external/TaskRunner.hpp +99 -0
  259. package/simpleble/src/external/ThreadRunner.h +52 -0
  260. package/simpleble/src/external/kvn_safe_callback.hpp +66 -0
  261. package/simpleble/src/external/kvn_safe_map.hpp +94 -0
  262. package/simpleble/src/external/kvn_threadrunner.hpp +70 -0
  263. package/simpleble/src/external/logfwd.hpp +35 -0
  264. package/simpleble/src/frontends/base/Adapter.cpp +111 -0
  265. package/simpleble/src/frontends/base/Advanced.cpp +34 -0
  266. package/simpleble/src/frontends/base/Backend.cpp +95 -0
  267. package/simpleble/src/frontends/base/Backend.h +76 -0
  268. package/simpleble/src/frontends/base/Characteristic.cpp +56 -0
  269. package/simpleble/src/frontends/base/Descriptor.cpp +21 -0
  270. package/simpleble/src/frontends/base/Peripheral.cpp +113 -0
  271. package/simpleble/src/frontends/base/Service.cpp +26 -0
  272. package/simpleble/src/frontends/safe/AdapterSafe.cpp +158 -0
  273. package/simpleble/src/frontends/safe/PeripheralSafe.cpp +219 -0
@@ -0,0 +1,90 @@
1
+ #pragma once
2
+
3
+ #include <winrt/base.h>
4
+ #include <atomic>
5
+ #include <condition_variable>
6
+ #include <functional>
7
+ #include <future>
8
+ #include <mutex>
9
+ #include <queue>
10
+ #include <thread>
11
+ #include <simpleble/Config.h>
12
+
13
+ namespace SimpleBLE {
14
+ namespace WinRT {
15
+ class MtaManager {
16
+ public:
17
+ static MtaManager& get() {
18
+ static MtaManager instance;
19
+ return instance;
20
+ }
21
+
22
+ void submit_task(std::function<void()> task);
23
+ void stop();
24
+
25
+ template<typename T>
26
+ T execute_sync(std::function<T()> task) {
27
+ // When flag is disabled, run in calling thread
28
+ if (!Config::WinRT::experimental_use_own_mta_apartment) {
29
+ try {
30
+ return task();
31
+ } catch (...) {
32
+ throw;
33
+ }
34
+ }
35
+
36
+ // Move the promise into the lambda to extend its lifetime
37
+ auto result_promise = std::make_shared<std::promise<T>>(); // Use shared_ptr to manage lifetime
38
+ auto result_future = result_promise->get_future();
39
+ submit_task([promise = std::move(result_promise), task]() {
40
+ try {
41
+ T result = task();
42
+ promise->set_value(result);
43
+ } catch (...) {
44
+ promise->set_exception(std::current_exception());
45
+ }
46
+ });
47
+ return result_future.get();
48
+ }
49
+
50
+ void execute_sync(std::function<void()> task) {
51
+ // When flag is disabled, run in calling thread
52
+ if (!Config::WinRT::experimental_use_own_mta_apartment) {
53
+ try {
54
+ task();
55
+ return;
56
+ } catch (...) {
57
+ throw;
58
+ }
59
+ }
60
+
61
+ // Move the promise into the lambda to extend its lifetime
62
+ auto result_promise = std::make_shared<std::promise<void>>(); // Use shared_ptr to manage lifetime
63
+ auto result_future = result_promise->get_future();
64
+ submit_task([promise = std::move(result_promise), task]() {
65
+ try {
66
+ task();
67
+ promise->set_value();
68
+ } catch (...) {
69
+ promise->set_exception(std::current_exception());
70
+ }
71
+ });
72
+ result_future.get();
73
+ }
74
+
75
+ private:
76
+ MtaManager();
77
+ ~MtaManager();
78
+ MtaManager(const MtaManager&) = delete;
79
+ MtaManager& operator=(const MtaManager&) = delete;
80
+
81
+ std::thread mta_thread_;
82
+ std::mutex task_mutex_;
83
+ std::condition_variable task_cv_;
84
+ std::queue<std::function<void()>> task_queue_;
85
+ std::atomic<bool> running_{true};
86
+
87
+ void mta_thread_func();
88
+ };
89
+ } // namespace WinRT
90
+ } // namespace SimpleBLE
@@ -0,0 +1,487 @@
1
+ // This weird pragma is required for the compiler to properly include the necessary namespaces.
2
+ #pragma comment(lib, "windowsapp")
3
+
4
+ #include "PeripheralWindows.h"
5
+ #include "CommonUtils.h"
6
+ #include "Utils.h"
7
+ #include "MtaManager.h"
8
+
9
+ #include "../common/CharacteristicBase.h"
10
+ #include "../common/DescriptorBase.h"
11
+ #include "../common/ServiceBase.h"
12
+ #include "simpleble/Characteristic.h"
13
+ #include "simpleble/Descriptor.h"
14
+ #include "simpleble/Service.h"
15
+
16
+ #include <simpleble/Exceptions.h>
17
+
18
+ #include "winrt/Windows.Foundation.Collections.h"
19
+ #include "winrt/Windows.Foundation.h"
20
+ #include "winrt/Windows.Storage.Streams.h"
21
+ #include "winrt/base.h"
22
+
23
+ #include <iostream>
24
+
25
+ using namespace SimpleBLE;
26
+ using namespace SimpleBLE::WinRT;
27
+ using namespace std::chrono_literals;
28
+
29
+ PeripheralWindows::PeripheralWindows(BluetoothLEDevice device) {
30
+ device_ = device;
31
+ identifier_ = winrt::to_string(device.Name());
32
+ address_ = _mac_address_to_str(device.BluetoothAddress());
33
+ address_type_ = BluetoothAddressType::PUBLIC;
34
+
35
+ // NOTE: We're assuming that the device is connectable, as this constructor is only called
36
+ // when the device has paired in the past.
37
+ connectable_ = true;
38
+ }
39
+
40
+ PeripheralWindows::PeripheralWindows(advertising_data_t advertising_data) {
41
+ address_type_ = advertising_data.address_type;
42
+ identifier_ = advertising_data.identifier;
43
+ address_ = advertising_data.mac_address;
44
+ rssi_ = advertising_data.rssi;
45
+ tx_power_ = advertising_data.tx_power;
46
+ manufacturer_data_ = advertising_data.manufacturer_data;
47
+ service_data_ = advertising_data.service_data;
48
+ connectable_ = advertising_data.connectable;
49
+ }
50
+
51
+ PeripheralWindows::~PeripheralWindows() {
52
+ if (connection_status_changed_token_ && device_ != nullptr) {
53
+ MtaManager::get().execute_sync([this]() {
54
+ device_.ConnectionStatusChanged(connection_status_changed_token_);
55
+ });
56
+ }
57
+ }
58
+
59
+ void* PeripheralWindows::underlying() const {
60
+ return reinterpret_cast<void*>(const_cast<BluetoothLEDevice*>(&device_));
61
+ }
62
+
63
+ SimpleBLE::BluetoothAddressType PeripheralWindows::address_type() { return address_type_; }
64
+
65
+ std::string PeripheralWindows::identifier() { return identifier_; }
66
+
67
+ BluetoothAddress PeripheralWindows::address() { return address_; }
68
+
69
+ int16_t PeripheralWindows::rssi() { return rssi_; }
70
+
71
+ int16_t PeripheralWindows::tx_power() { return tx_power_; }
72
+
73
+ uint16_t PeripheralWindows::mtu() {
74
+ if (!is_connected()) return 0;
75
+
76
+ // The value provided by the MaxPduSize includes an extra 3 bytes from the GATT header
77
+ // which needs to be removed.
78
+ return mtu_ - 3;
79
+ }
80
+
81
+ void PeripheralWindows::update_advertising_data(advertising_data_t advertising_data) {
82
+ if (advertising_data.identifier != "") {
83
+ identifier_ = advertising_data.identifier;
84
+ }
85
+ rssi_ = advertising_data.rssi;
86
+ tx_power_ = advertising_data.tx_power;
87
+ address_type_ = advertising_data.address_type;
88
+ manufacturer_data_ = advertising_data.manufacturer_data;
89
+
90
+ advertising_data.service_data.merge(service_data_);
91
+ service_data_ = advertising_data.service_data;
92
+ }
93
+
94
+ void PeripheralWindows::connect() {
95
+ MtaManager::get().execute_sync([this]() {
96
+ device_ = async_get(BluetoothLEDevice::FromBluetoothAddressAsync(_str_to_mac_address(address_)));
97
+ });
98
+
99
+ // Attempt to connect to the device.
100
+ for (size_t i = 0; i < 3; i++) {
101
+ if (_attempt_connect()) {
102
+ break;
103
+ }
104
+ }
105
+
106
+ if (is_connected()) {
107
+ MtaManager::get().execute_sync([this]() {
108
+ connection_status_changed_token_ = device_.ConnectionStatusChanged(
109
+ [this](const BluetoothLEDevice device, const auto args) {
110
+ if (device.ConnectionStatus() == BluetoothConnectionStatus::Disconnected) {
111
+ this->disconnection_cv_.notify_all();
112
+
113
+ SAFE_CALLBACK_CALL(this->callback_on_disconnected_);
114
+ }
115
+ });
116
+ });
117
+
118
+ SAFE_CALLBACK_CALL(this->callback_on_connected_);
119
+ } else {
120
+ throw SimpleBLE::Exception::OperationFailed("Failed to connect to device.");
121
+ }
122
+ }
123
+
124
+ void PeripheralWindows::disconnect() {
125
+ gatt_map_.clear();
126
+ if (device_ != nullptr) {
127
+ MtaManager::get().execute_sync([this]() {
128
+ device_.Close();
129
+ });
130
+
131
+ std::unique_lock<std::mutex> lock(disconnection_mutex_);
132
+ if (disconnection_cv_.wait_for(lock, 10s, [this] { return !this->is_connected(); })) {
133
+ // Disconnection successful
134
+ } else {
135
+ SIMPLEBLE_LOG_ERROR("Disconnection failed");
136
+ throw SimpleBLE::Exception::OperationFailed("Disconnection attempt was not acknowledged.");
137
+ }
138
+
139
+ device_ = nullptr;
140
+ }
141
+ }
142
+
143
+ bool PeripheralWindows::is_connected() {
144
+ if (device_ == nullptr) return false;
145
+
146
+ return MtaManager::get().execute_sync<bool>([this]() {
147
+ return device_.ConnectionStatus() == BluetoothConnectionStatus::Connected;
148
+ });
149
+ }
150
+
151
+ bool PeripheralWindows::is_connectable() { return connectable_; }
152
+
153
+ bool PeripheralWindows::is_paired() { throw Exception::OperationNotSupported(); }
154
+
155
+ void PeripheralWindows::unpair() { throw Exception::OperationNotSupported(); }
156
+
157
+ SharedPtrVector<ServiceBase> PeripheralWindows::available_services() {
158
+ SharedPtrVector<ServiceBase> service_list;
159
+ for (auto& [service_uuid, service] : gatt_map_) {
160
+ // Build the list of characteristics for the service.
161
+ SharedPtrVector<CharacteristicBase> characteristic_list;
162
+ for (auto& [characteristic_uuid, characteristic] : service.characteristics) {
163
+ // Build the list of descriptors for the characteristic.
164
+ SharedPtrVector<DescriptorBase> descriptor_list;
165
+ for (auto& [descriptor_uuid, descriptor] : characteristic.descriptors) {
166
+ descriptor_list.push_back(std::make_shared<DescriptorBase>(descriptor_uuid));
167
+ }
168
+
169
+ uint32_t properties = MtaManager::get().execute_sync<uint32_t>([&characteristic]() {
170
+ return (uint32_t)characteristic.obj.CharacteristicProperties();
171
+ });
172
+
173
+ bool can_read = (properties & (uint32_t)GattCharacteristicProperties::Read) != 0;
174
+ bool can_write_request = (properties & (uint32_t)GattCharacteristicProperties::Write) != 0;
175
+ bool can_write_command = (properties & (uint32_t)GattCharacteristicProperties::WriteWithoutResponse) != 0;
176
+ bool can_notify = (properties & (uint32_t)GattCharacteristicProperties::Notify) != 0;
177
+ bool can_indicate = (properties & (uint32_t)GattCharacteristicProperties::Indicate) != 0;
178
+
179
+ characteristic_list.push_back(
180
+ std::make_shared<CharacteristicBase>(characteristic_uuid, descriptor_list, can_read, can_write_request,
181
+ can_write_command, can_notify, can_indicate));
182
+ }
183
+ service_list.push_back(std::make_shared<ServiceBase>(service_uuid, characteristic_list));
184
+ }
185
+
186
+ return service_list;
187
+ }
188
+
189
+ SharedPtrVector<ServiceBase> PeripheralWindows::advertised_services() {
190
+ SharedPtrVector<ServiceBase> service_list;
191
+ for (auto& [service_uuid, data] : service_data_) {
192
+ service_list.push_back(std::make_shared<ServiceBase>(service_uuid, data));
193
+ }
194
+
195
+ return service_list;
196
+ }
197
+
198
+ std::map<uint16_t, ByteArray> PeripheralWindows::manufacturer_data() { return manufacturer_data_; }
199
+
200
+ ByteArray PeripheralWindows::read(BluetoothUUID const& service, BluetoothUUID const& characteristic) {
201
+ GattCharacteristic gatt_characteristic = _fetch_characteristic(service, characteristic).obj;
202
+
203
+ return MtaManager::get().execute_sync<ByteArray>([this, &gatt_characteristic]() {
204
+ // Validate that the operation can be performed.
205
+ uint32_t gatt_characteristic_prop = (uint32_t)gatt_characteristic.CharacteristicProperties();
206
+ if ((gatt_characteristic_prop & (uint32_t)GattCharacteristicProperties::Read) == 0) {
207
+ throw SimpleBLE::Exception::OperationNotSupported();
208
+ }
209
+
210
+ // Read the value.
211
+ auto result = async_get(gatt_characteristic.ReadValueAsync(Devices::Bluetooth::BluetoothCacheMode::Uncached));
212
+ if (result.Status() != GenericAttributeProfile::GattCommunicationStatus::Success) {
213
+ throw SimpleBLE::Exception::OperationFailed();
214
+ }
215
+ return ibuffer_to_bytearray(result.Value());
216
+ });
217
+ }
218
+
219
+ void PeripheralWindows::write_request(BluetoothUUID const& service, BluetoothUUID const& characteristic,
220
+ ByteArray const& data) {
221
+ GattCharacteristic gatt_characteristic = _fetch_characteristic(service, characteristic).obj;
222
+
223
+ MtaManager::get().execute_sync([this, &gatt_characteristic, &data]() {
224
+ // Validate that the operation can be performed.
225
+ uint32_t gatt_characteristic_prop = (uint32_t)gatt_characteristic.CharacteristicProperties();
226
+ if ((gatt_characteristic_prop & (uint32_t)GattCharacteristicProperties::Write) == 0) {
227
+ throw SimpleBLE::Exception::OperationNotSupported();
228
+ }
229
+
230
+ // Convert the request data to a buffer.
231
+ winrt::Windows::Storage::Streams::IBuffer buffer = bytearray_to_ibuffer(data);
232
+
233
+ // Write the value.
234
+ auto result = async_get(gatt_characteristic.WriteValueAsync(buffer, GattWriteOption::WriteWithResponse));
235
+ if (result != GenericAttributeProfile::GattCommunicationStatus::Success) {
236
+ throw SimpleBLE::Exception::OperationFailed();
237
+ }
238
+ });
239
+ }
240
+
241
+ void PeripheralWindows::write_command(BluetoothUUID const& service, BluetoothUUID const& characteristic,
242
+ ByteArray const& data) {
243
+ GattCharacteristic gatt_characteristic = _fetch_characteristic(service, characteristic).obj;
244
+
245
+ MtaManager::get().execute_sync([this, &gatt_characteristic, &data]() {
246
+ // Validate that the operation can be performed.
247
+ uint32_t gatt_characteristic_prop = (uint32_t)gatt_characteristic.CharacteristicProperties();
248
+ if ((gatt_characteristic_prop & (uint32_t)GattCharacteristicProperties::WriteWithoutResponse) == 0) {
249
+ throw SimpleBLE::Exception::OperationNotSupported();
250
+ }
251
+
252
+ // Convert the request data to a buffer.
253
+ winrt::Windows::Storage::Streams::IBuffer buffer = bytearray_to_ibuffer(data);
254
+
255
+ // Write the value.
256
+ auto result = async_get(gatt_characteristic.WriteValueAsync(buffer, GattWriteOption::WriteWithoutResponse));
257
+ if (result != GenericAttributeProfile::GattCommunicationStatus::Success) {
258
+ throw SimpleBLE::Exception::OperationFailed();
259
+ }
260
+ });
261
+ }
262
+
263
+ void PeripheralWindows::notify(BluetoothUUID const& service, BluetoothUUID const& characteristic,
264
+ std::function<void(ByteArray payload)> callback) {
265
+ _subscribe(service, characteristic, std::move(callback), GattCharacteristicProperties::Notify,
266
+ GattClientCharacteristicConfigurationDescriptorValue::Notify);
267
+ }
268
+
269
+ void PeripheralWindows::indicate(BluetoothUUID const& service, BluetoothUUID const& characteristic,
270
+ std::function<void(ByteArray payload)> callback) {
271
+ _subscribe(service, characteristic, std::move(callback), GattCharacteristicProperties::Indicate,
272
+ GattClientCharacteristicConfigurationDescriptorValue::Indicate);
273
+ }
274
+
275
+ void PeripheralWindows::unsubscribe(BluetoothUUID const& service, BluetoothUUID const& characteristic) {
276
+ gatt_characteristic_t& gatt_characteristic_holder = _fetch_characteristic(service, characteristic);
277
+ GattCharacteristic gatt_characteristic = gatt_characteristic_holder.obj;
278
+
279
+ MtaManager::get().execute_sync([this, &gatt_characteristic, &gatt_characteristic_holder]() {
280
+ if (gatt_characteristic_holder.value_changed_token) {
281
+ // Unregister the callback.
282
+ gatt_characteristic.ValueChanged(gatt_characteristic_holder.value_changed_token);
283
+ gatt_characteristic_holder.value_changed_token = {0};
284
+ }
285
+
286
+ // Start the indication.
287
+ auto result = async_get(gatt_characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(
288
+ GattClientCharacteristicConfigurationDescriptorValue::None));
289
+
290
+ if (result.Status() != GenericAttributeProfile::GattCommunicationStatus::Success) {
291
+ throw SimpleBLE::Exception::OperationFailed();
292
+ }
293
+ });
294
+ }
295
+
296
+ ByteArray PeripheralWindows::read(BluetoothUUID const& service, BluetoothUUID const& characteristic,
297
+ BluetoothUUID const& descriptor) {
298
+ GattDescriptor gatt_descriptor = _fetch_descriptor(service, characteristic, descriptor);
299
+
300
+ return MtaManager::get().execute_sync<ByteArray>([this, &gatt_descriptor]() {
301
+ // Read the value.
302
+ auto result = async_get(gatt_descriptor.ReadValueAsync(Devices::Bluetooth::BluetoothCacheMode::Uncached));
303
+ if (result.Status() != GenericAttributeProfile::GattCommunicationStatus::Success) {
304
+ throw SimpleBLE::Exception::OperationFailed();
305
+ }
306
+ return ibuffer_to_bytearray(result.Value());
307
+ });
308
+ }
309
+
310
+ void PeripheralWindows::write(BluetoothUUID const& service, BluetoothUUID const& characteristic,
311
+ BluetoothUUID const& descriptor, ByteArray const& data) {
312
+ GattDescriptor gatt_descriptor = _fetch_descriptor(service, characteristic, descriptor);
313
+
314
+ MtaManager::get().execute_sync([this, &gatt_descriptor, &data]() {
315
+ // Convert the request data to a buffer.
316
+ winrt::Windows::Storage::Streams::IBuffer buffer = bytearray_to_ibuffer(data);
317
+
318
+ // Write the value.
319
+ auto result = async_get(gatt_descriptor.WriteValueWithResultAsync(buffer));
320
+ if (result.Status() != GenericAttributeProfile::GattCommunicationStatus::Success) {
321
+ throw SimpleBLE::Exception::OperationFailed();
322
+ }
323
+ });
324
+ }
325
+
326
+ void PeripheralWindows::set_callback_on_connected(std::function<void()> on_connected) {
327
+ if (on_connected) {
328
+ callback_on_connected_.load(std::move(on_connected));
329
+ } else {
330
+ callback_on_connected_.unload();
331
+ }
332
+ }
333
+
334
+ void PeripheralWindows::set_callback_on_disconnected(std::function<void()> on_disconnected) {
335
+ if (on_disconnected) {
336
+ callback_on_disconnected_.load(std::move(on_disconnected));
337
+ } else {
338
+ callback_on_disconnected_.unload();
339
+ }
340
+ }
341
+
342
+ // Private methods
343
+
344
+ void PeripheralWindows::_subscribe(BluetoothUUID const& service, BluetoothUUID const& characteristic,
345
+ std::function<void(ByteArray payload)> callback,
346
+ GattCharacteristicProperties property,
347
+ GattClientCharacteristicConfigurationDescriptorValue descriptor_value) {
348
+ gatt_characteristic_t& gatt_characteristic_holder = _fetch_characteristic(service, characteristic);
349
+ GattCharacteristic gatt_characteristic = gatt_characteristic_holder.obj;
350
+
351
+ MtaManager::get().execute_sync([this, &gatt_characteristic, &gatt_characteristic_holder, callback, property, descriptor_value]() {
352
+ // Validate that the operation can be performed.
353
+ uint32_t gatt_characteristic_prop = (uint32_t)gatt_characteristic.CharacteristicProperties();
354
+ if ((gatt_characteristic_prop & (uint32_t)property) == 0) {
355
+ throw SimpleBLE::Exception::OperationNotSupported();
356
+ }
357
+
358
+ // If a notification for the given characteristic is already in progress, swap the callbacks.
359
+ if (gatt_characteristic_holder.value_changed_token) {
360
+ SIMPLEBLE_LOG_WARN("A notification for the given characteristic is already in progress. Swapping callbacks.");
361
+ // Unregister the callback.
362
+ gatt_characteristic.ValueChanged(gatt_characteristic_holder.value_changed_token);
363
+ gatt_characteristic_holder.value_changed_token = {0};
364
+ }
365
+
366
+ gatt_characteristic_holder.value_changed_callback = [=](const GattCharacteristic& sender,
367
+ const GattValueChangedEventArgs& args) {
368
+ // Convert the payload to a ByteArray.
369
+ ByteArray payload = ibuffer_to_bytearray(args.CharacteristicValue());
370
+ callback(payload);
371
+ };
372
+
373
+ // Register the callback.
374
+ gatt_characteristic_holder.value_changed_token = gatt_characteristic.ValueChanged(
375
+ gatt_characteristic_holder.value_changed_callback);
376
+
377
+ // Start the notification.
378
+ auto result = async_get(
379
+ gatt_characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(descriptor_value));
380
+
381
+ if (result.Status() != GenericAttributeProfile::GattCommunicationStatus::Success) {
382
+ throw SimpleBLE::Exception::OperationFailed();
383
+ }
384
+ });
385
+ }
386
+
387
+ bool PeripheralWindows::_attempt_connect() {
388
+ gatt_map_.clear();
389
+
390
+ return MtaManager::get().execute_sync<bool>([this]() {
391
+ // We need to cache all services, characteristics and descriptors in the class, else
392
+ // the underlying objects will be garbage collected.
393
+ auto services_result = async_get(device_.GetGattServicesAsync(BluetoothCacheMode::Uncached));
394
+ if (services_result.Status() != GattCommunicationStatus::Success) {
395
+ return false;
396
+ }
397
+
398
+ auto gatt_services = services_result.Services();
399
+ for (GattDeviceService&& service : gatt_services) {
400
+ // For each service...
401
+ gatt_service_t gatt_service;
402
+ gatt_service.obj = service;
403
+
404
+ // Save the MTU size
405
+ mtu_ = service.Session().MaxPduSize();
406
+
407
+ // Fetch the service UUID
408
+ std::string service_uuid = guid_to_uuid(service.Uuid());
409
+
410
+ // Fetch the service characteristics
411
+ auto characteristics_result = async_get(service.GetCharacteristicsAsync(BluetoothCacheMode::Uncached));
412
+ if (characteristics_result.Status() != GattCommunicationStatus::Success) {
413
+ return false;
414
+ }
415
+
416
+ // Load the characteristics into the service
417
+ auto gatt_characteristics = characteristics_result.Characteristics();
418
+ for (GattCharacteristic&& characteristic : gatt_characteristics) {
419
+ // For each characteristic...
420
+ gatt_characteristic_t gatt_characteristic;
421
+ gatt_characteristic.obj = characteristic;
422
+
423
+ // Fetch the characteristic UUID
424
+ std::string characteristic_uuid = guid_to_uuid(characteristic.Uuid());
425
+
426
+ // Fetch the characteristic descriptors
427
+ auto descriptors_result = async_get(characteristic.GetDescriptorsAsync(BluetoothCacheMode::Uncached));
428
+ if (descriptors_result.Status() != GattCommunicationStatus::Success) {
429
+ return false;
430
+ }
431
+
432
+ // Load the descriptors into the characteristic
433
+ auto gatt_descriptors = descriptors_result.Descriptors();
434
+ for (GattDescriptor&& descriptor : gatt_descriptors) {
435
+ // For each descriptor...
436
+ gatt_descriptor_t gatt_descriptor;
437
+ gatt_descriptor.obj = descriptor;
438
+
439
+ // Fetch the descriptor UUID.
440
+ std::string descriptor_uuid = guid_to_uuid(descriptor.Uuid());
441
+
442
+ // Append the descriptor to the characteristic.
443
+ gatt_characteristic.descriptors.emplace(descriptor_uuid, std::move(gatt_descriptor));
444
+ }
445
+
446
+ // Append the characteristic to the service.
447
+ gatt_service.characteristics.emplace(characteristic_uuid, std::move(gatt_characteristic));
448
+ }
449
+
450
+ // Append the service to the map.
451
+ gatt_map_.emplace(service_uuid, std::move(gatt_service));
452
+ }
453
+
454
+ return true;
455
+ });
456
+ }
457
+
458
+ gatt_characteristic_t& PeripheralWindows::_fetch_characteristic(const BluetoothUUID& service_uuid,
459
+ const BluetoothUUID& characteristic_uuid) {
460
+ if (gatt_map_.count(service_uuid) == 0) {
461
+ throw SimpleBLE::Exception::ServiceNotFound(service_uuid);
462
+ }
463
+
464
+ if (gatt_map_[service_uuid].characteristics.count(characteristic_uuid) == 0) {
465
+ throw SimpleBLE::Exception::CharacteristicNotFound(characteristic_uuid);
466
+ }
467
+
468
+ return gatt_map_[service_uuid].characteristics.at(characteristic_uuid);
469
+ }
470
+
471
+ GattDescriptor PeripheralWindows::_fetch_descriptor(const BluetoothUUID& service_uuid,
472
+ const BluetoothUUID& characteristic_uuid,
473
+ const BluetoothUUID& descriptor_uuid) {
474
+ if (gatt_map_.count(service_uuid) == 0) {
475
+ throw SimpleBLE::Exception::ServiceNotFound(service_uuid);
476
+ }
477
+
478
+ if (gatt_map_[service_uuid].characteristics.count(characteristic_uuid) == 0) {
479
+ throw SimpleBLE::Exception::CharacteristicNotFound(characteristic_uuid);
480
+ }
481
+
482
+ if (gatt_map_[service_uuid].characteristics[characteristic_uuid].descriptors.count(descriptor_uuid) == 0) {
483
+ throw SimpleBLE::Exception::DescriptorNotFound(descriptor_uuid);
484
+ }
485
+
486
+ return gatt_map_[service_uuid].characteristics[characteristic_uuid].descriptors.at(descriptor_uuid).obj;
487
+ }