@glassly/bluetooth-sdk 0.1.0-dev.26

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 (548) hide show
  1. package/README.md +563 -0
  2. package/android/build.gradle +450 -0
  3. package/android/gradle.properties.example +9 -0
  4. package/android/lc3Lib/CMakeLists.txt +6 -0
  5. package/android/lc3Lib/build.gradle +212 -0
  6. package/android/lc3Lib/proguard-rules.pro +33 -0
  7. package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
  8. package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
  9. package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
  10. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
  11. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
  12. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
  13. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
  14. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
  15. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
  16. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
  17. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
  18. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
  19. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
  20. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
  21. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
  22. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
  23. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
  24. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
  25. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
  26. package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
  27. package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
  28. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
  29. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
  30. package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
  31. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
  32. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
  33. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
  34. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
  35. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
  36. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
  37. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
  38. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
  39. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
  40. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
  41. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
  42. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
  43. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
  44. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
  45. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
  46. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
  47. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
  48. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
  49. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
  50. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
  51. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
  52. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
  53. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
  54. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
  55. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
  56. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
  57. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
  58. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
  59. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
  60. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
  61. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
  62. package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
  63. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
  64. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
  65. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
  66. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
  67. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
  68. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
  69. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
  70. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
  71. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
  72. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
  73. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
  74. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
  75. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
  76. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
  77. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
  78. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
  79. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
  80. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
  81. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
  82. package/android/lc3Lib/src/main/java/com/glassly/lc3Lib/Lc3Cpp.java +38 -0
  83. package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
  84. package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
  85. package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
  86. package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
  87. package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
  88. package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
  89. package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
  90. package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
  91. package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
  92. package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
  93. package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
  94. package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
  95. package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
  96. package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
  97. package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
  98. package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
  99. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
  100. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
  101. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
  102. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
  103. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
  104. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
  105. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
  106. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
  107. package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
  108. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
  109. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
  110. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
  111. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
  112. package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
  113. package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
  114. package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
  115. package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
  116. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
  117. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
  118. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
  119. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
  120. package/android/settings.gradle +4 -0
  121. package/android/silero/LICENSE.md +17 -0
  122. package/android/silero/build.gradle +50 -0
  123. package/android/silero/proguard-rules.pro +24 -0
  124. package/android/silero/src/androidTest/assets/hello.wav +0 -0
  125. package/android/silero/src/androidTest/java/com/konovalov/vad/silero/VadSileroTest.kt +79 -0
  126. package/android/silero/src/main/assets/LICENSE +21 -0
  127. package/android/silero/src/main/assets/silero_vad.onnx +0 -0
  128. package/android/silero/src/main/java/com/konovalov/vad/silero/Vad.kt +160 -0
  129. package/android/silero/src/main/java/com/konovalov/vad/silero/VadSilero.kt +449 -0
  130. package/android/silero/src/main/java/com/konovalov/vad/silero/config/FrameSize.kt +15 -0
  131. package/android/silero/src/main/java/com/konovalov/vad/silero/config/Mode.kt +14 -0
  132. package/android/silero/src/main/java/com/konovalov/vad/silero/config/SampleRate.kt +12 -0
  133. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/AudioUtils.kt +47 -0
  134. package/android/silero/src/main/java/com/konovalov/vad/silero/utils/TensorMap.kt +41 -0
  135. package/android/silero/src/test/java/com/konovalov/vad/silero/utils/AudioUtilsTest.kt +44 -0
  136. package/android/src/main/AndroidManifest.xml +42 -0
  137. package/android/src/main/assets/G2Firmware/README.md +11 -0
  138. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdk.kt +2325 -0
  139. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkAnalytics.kt +216 -0
  140. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkDebug.kt +14 -0
  141. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkDefaults.kt +7 -0
  142. package/android/src/main/java/com/glassly/bluetoothsdk/BluetoothSdkModule.kt +1088 -0
  143. package/android/src/main/java/com/glassly/bluetoothsdk/Bridge.kt +953 -0
  144. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceManager.kt +2528 -0
  145. package/android/src/main/java/com/glassly/bluetoothsdk/DeviceStore.kt +360 -0
  146. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedChangelogCatalog.kt +8 -0
  147. package/android/src/main/java/com/glassly/bluetoothsdk/GeneratedReleaseMetadata.kt +11 -0
  148. package/android/src/main/java/com/glassly/bluetoothsdk/LocalNetworkModule.kt +414 -0
  149. package/android/src/main/java/com/glassly/bluetoothsdk/ObservableStore.kt +88 -0
  150. package/android/src/main/java/com/glassly/bluetoothsdk/OtaManifest.kt +191 -0
  151. package/android/src/main/java/com/glassly/bluetoothsdk/ReleaseChangelog.kt +61 -0
  152. package/android/src/main/java/com/glassly/bluetoothsdk/ScopedNetworkReadiness.kt +17 -0
  153. package/android/src/main/java/com/glassly/bluetoothsdk/audio/AudioModels.kt +144 -0
  154. package/android/src/main/java/com/glassly/bluetoothsdk/camera/CameraModels.kt +486 -0
  155. package/android/src/main/java/com/glassly/bluetoothsdk/connection/ConnectionModels.kt +78 -0
  156. package/android/src/main/java/com/glassly/bluetoothsdk/controllers/ControllerManager.kt +158 -0
  157. package/android/src/main/java/com/glassly/bluetoothsdk/controllers/R1.kt +937 -0
  158. package/android/src/main/java/com/glassly/bluetoothsdk/debug/BleTraceLogger.kt +165 -0
  159. package/android/src/main/java/com/glassly/bluetoothsdk/events/BluetoothEvents.kt +178 -0
  160. package/android/src/main/java/com/glassly/bluetoothsdk/internal/MapParsing.kt +140 -0
  161. package/android/src/main/java/com/glassly/bluetoothsdk/net/LocalIpv4.kt +57 -0
  162. package/android/src/main/java/com/glassly/bluetoothsdk/otaserver/LocalOtaServer.kt +304 -0
  163. package/android/src/main/java/com/glassly/bluetoothsdk/otaserver/OtaServerModule.kt +120 -0
  164. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistry.java +108 -0
  165. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoUploadServer.kt +622 -0
  166. package/android/src/main/java/com/glassly/bluetoothsdk/photoreceiver/PhotoReceiverModule.kt +156 -0
  167. package/android/src/main/java/com/glassly/bluetoothsdk/requests/DisplayRequests.kt +56 -0
  168. package/android/src/main/java/com/glassly/bluetoothsdk/services/Foreground.kt +272 -0
  169. package/android/src/main/java/com/glassly/bluetoothsdk/services/PhoneMic.kt +1195 -0
  170. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Ar99.java +2653 -0
  171. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/BesOtaHeartbeatGuard.kt +49 -0
  172. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/BesOtaProgressMapper.kt +27 -0
  173. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G1.kt +3878 -0
  174. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G1TextSanitizer.kt +38 -0
  175. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2.kt +6428 -0
  176. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassification.kt +49 -0
  177. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwRenderer.kt +1241 -0
  178. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCache.kt +270 -0
  179. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2FlashProtocol.kt +291 -0
  180. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/G2Flasher.kt +411 -0
  181. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/GlasslyBle.java +43189 -0
  182. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Mach1.kt +1280 -0
  183. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLive.kt +10817 -0
  184. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLiveL2capChannel.kt +274 -0
  185. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraLivePairingAdvertisement.kt +54 -0
  186. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/MentraNex.kt +2011 -0
  187. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Nimo.kt +2532 -0
  188. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/SGCManager.kt +470 -0
  189. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/Simulated.kt +228 -0
  190. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/Ar99OtaManager.java +566 -0
  191. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaByteUtils.java +18 -0
  192. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaCommandConstants.java +35 -0
  193. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaCrc32Util.java +13 -0
  194. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaGattTransport.java +11 -0
  195. package/android/src/main/java/com/glassly/bluetoothsdk/sgcs/ar99/ota/OtaProtocol.java +92 -0
  196. package/android/src/main/java/com/glassly/bluetoothsdk/speakerid/SpeakerIdEngine.kt +525 -0
  197. package/android/src/main/java/com/glassly/bluetoothsdk/status/DeviceStatus.kt +669 -0
  198. package/android/src/main/java/com/glassly/bluetoothsdk/status/RuntimeState.kt +201 -0
  199. package/android/src/main/java/com/glassly/bluetoothsdk/status/WifiHotspotStatus.kt +189 -0
  200. package/android/src/main/java/com/glassly/bluetoothsdk/streaming/StreamModels.kt +518 -0
  201. package/android/src/main/java/com/glassly/bluetoothsdk/stt/STTTools.kt +391 -0
  202. package/android/src/main/java/com/glassly/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +518 -0
  203. package/android/src/main/java/com/glassly/bluetoothsdk/stt/VadGateSpeechPolicy.kt +229 -0
  204. package/android/src/main/java/com/glassly/bluetoothsdk/tts/TTSTools.kt +248 -0
  205. package/android/src/main/java/com/glassly/bluetoothsdk/types/DeviceModels.kt +96 -0
  206. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AES.java +106 -0
  207. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
  208. package/android/src/main/java/com/glassly/bluetoothsdk/utils/AvifExifStripper.java +573 -0
  209. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
  210. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BleJsonCompact.java +496 -0
  211. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BlePhotoUploadService.java +677 -0
  212. package/android/src/main/java/com/glassly/bluetoothsdk/utils/BleWireProtocol.java +108 -0
  213. package/android/src/main/java/com/glassly/bluetoothsdk/utils/Constants.kt +46 -0
  214. package/android/src/main/java/com/glassly/bluetoothsdk/utils/G1Text.kt +436 -0
  215. package/android/src/main/java/com/glassly/bluetoothsdk/utils/HeifExifTagReader.java +199 -0
  216. package/android/src/main/java/com/glassly/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
  217. package/android/src/main/java/com/glassly/bluetoothsdk/utils/IncidentLogBleUploadService.java +77 -0
  218. package/android/src/main/java/com/glassly/bluetoothsdk/utils/K900LengthCodec.java +115 -0
  219. package/android/src/main/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtils.java +827 -0
  220. package/android/src/main/java/com/glassly/bluetoothsdk/utils/MessageChunkReassembler.java +228 -0
  221. package/android/src/main/java/com/glassly/bluetoothsdk/utils/MessageChunker.java +325 -0
  222. package/android/src/main/java/com/glassly/bluetoothsdk/utils/NexSGCUtils.kt +698 -0
  223. package/android/src/main/java/com/glassly/bluetoothsdk/utils/PhoneAudioMonitor.kt +348 -0
  224. package/android/src/main/java/com/glassly/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
  225. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/Ar99OpusPcmDecoder.java +398 -0
  226. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
  227. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
  228. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
  229. package/android/src/main/java/com/glassly/bluetoothsdk/utils/audio/PcmStreamPlayer.kt +328 -0
  230. package/android/src/main/res/values/strings.xml +4 -0
  231. package/android/src/test/java/com/glassly/bluetoothsdk/BluetoothSdkExceptionTest.kt +18 -0
  232. package/android/src/test/java/com/glassly/bluetoothsdk/OtaManifestDowngradeTest.kt +86 -0
  233. package/android/src/test/java/com/glassly/bluetoothsdk/OtaStartResponsePolicyTest.kt +30 -0
  234. package/android/src/test/java/com/glassly/bluetoothsdk/ReleaseChangelogTest.kt +13 -0
  235. package/android/src/test/java/com/glassly/bluetoothsdk/ScopedNetworkReadinessTest.kt +39 -0
  236. package/android/src/test/java/com/glassly/bluetoothsdk/StreamStatusEventTest.kt +29 -0
  237. package/android/src/test/java/com/glassly/bluetoothsdk/camera/PhotoRequestTest.kt +141 -0
  238. package/android/src/test/java/com/glassly/bluetoothsdk/otaserver/LocalOtaServerTest.kt +82 -0
  239. package/android/src/test/java/com/glassly/bluetoothsdk/photoreceiver/LocalPhotoReceiverRegistryTest.java +75 -0
  240. package/android/src/test/java/com/glassly/bluetoothsdk/services/ForegroundServiceTypeTest.kt +69 -0
  241. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/Ar99AdvertisementMatcherTest.java +22 -0
  242. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/BesOtaHeartbeatGuardTest.kt +73 -0
  243. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/BesOtaProgressMapperTest.kt +67 -0
  244. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/EvenRleTest.kt +63 -0
  245. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G1TextSanitizerTest.kt +31 -0
  246. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwClassificationTest.kt +89 -0
  247. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwRendererTest.kt +344 -0
  248. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2CfwTextureCacheTest.kt +200 -0
  249. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/G2FlashProtocolTest.kt +131 -0
  250. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/MentraLiveGattCharacteristicsTest.kt +39 -0
  251. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/MentraLivePairingAdvertisementParserTest.kt +133 -0
  252. package/android/src/test/java/com/glassly/bluetoothsdk/sgcs/NimoProtocolTest.kt +333 -0
  253. package/android/src/test/java/com/glassly/bluetoothsdk/utils/AvifExifStripperTest.java +46 -0
  254. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BinaryMessageChunkerTest.java +84 -0
  255. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BleJsonCompactTest.java +319 -0
  256. package/android/src/test/java/com/glassly/bluetoothsdk/utils/BlePhotoUploadServiceTest.java +107 -0
  257. package/android/src/test/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtilsEndiannessTest.java +172 -0
  258. package/android/src/test/java/com/glassly/bluetoothsdk/utils/K900ProtocolUtilsTest.java +24 -0
  259. package/android/src/test/java/com/glassly/bluetoothsdk/utils/PhoneAudioMonitorTest.kt +45 -0
  260. package/android/src/test/resources/avif_with_exif.avif +0 -0
  261. package/app.plugin.js +3 -0
  262. package/build/BluetoothSdk.types.d.ts +1354 -0
  263. package/build/BluetoothSdk.types.d.ts.map +1 -0
  264. package/build/BluetoothSdk.types.js +41 -0
  265. package/build/BluetoothSdk.types.js.map +1 -0
  266. package/build/_internal.d.ts +17 -0
  267. package/build/_internal.d.ts.map +1 -0
  268. package/build/_internal.js +16 -0
  269. package/build/_internal.js.map +1 -0
  270. package/build/_private/BluetoothSdkModule.d.ts +172 -0
  271. package/build/_private/BluetoothSdkModule.d.ts.map +1 -0
  272. package/build/_private/BluetoothSdkModule.js +300 -0
  273. package/build/_private/BluetoothSdkModule.js.map +1 -0
  274. package/build/_private/LocalNetworkModule.d.ts +38 -0
  275. package/build/_private/LocalNetworkModule.d.ts.map +1 -0
  276. package/build/_private/LocalNetworkModule.js +3 -0
  277. package/build/_private/LocalNetworkModule.js.map +1 -0
  278. package/build/_private/cameraRequestPayload.d.ts +4 -0
  279. package/build/_private/cameraRequestPayload.d.ts.map +1 -0
  280. package/build/_private/cameraRequestPayload.js +32 -0
  281. package/build/_private/cameraRequestPayload.js.map +1 -0
  282. package/build/_private/photoRequestPayload.d.ts +6 -0
  283. package/build/_private/photoRequestPayload.d.ts.map +1 -0
  284. package/build/_private/photoRequestPayload.js +86 -0
  285. package/build/_private/photoRequestPayload.js.map +1 -0
  286. package/build/_private/sdkOtaManifest.d.ts +11 -0
  287. package/build/_private/sdkOtaManifest.d.ts.map +1 -0
  288. package/build/_private/sdkOtaManifest.js +15 -0
  289. package/build/_private/sdkOtaManifest.js.map +1 -0
  290. package/build/changelogs.d.ts +7 -0
  291. package/build/changelogs.d.ts.map +1 -0
  292. package/build/changelogs.js +46 -0
  293. package/build/changelogs.js.map +1 -0
  294. package/build/debug.d.ts +3 -0
  295. package/build/debug.d.ts.map +1 -0
  296. package/build/debug.js +8 -0
  297. package/build/debug.js.map +1 -0
  298. package/build/generated/changelogCatalog.d.ts +9 -0
  299. package/build/generated/changelogCatalog.d.ts.map +1 -0
  300. package/build/generated/changelogCatalog.js +12 -0
  301. package/build/generated/changelogCatalog.js.map +1 -0
  302. package/build/generated/releaseMetadata.d.ts +12 -0
  303. package/build/generated/releaseMetadata.d.ts.map +1 -0
  304. package/build/generated/releaseMetadata.js +10 -0
  305. package/build/generated/releaseMetadata.js.map +1 -0
  306. package/build/index.d.ts +6 -0
  307. package/build/index.d.ts.map +1 -0
  308. package/build/index.js +171 -0
  309. package/build/index.js.map +1 -0
  310. package/build/ota-server/OtaServer.types.d.ts +14 -0
  311. package/build/ota-server/OtaServer.types.d.ts.map +1 -0
  312. package/build/ota-server/OtaServer.types.js +2 -0
  313. package/build/ota-server/OtaServer.types.js.map +1 -0
  314. package/build/ota-server/OtaServerModule.d.ts +21 -0
  315. package/build/ota-server/OtaServerModule.d.ts.map +1 -0
  316. package/build/ota-server/OtaServerModule.js +3 -0
  317. package/build/ota-server/OtaServerModule.js.map +1 -0
  318. package/build/ota-server/OtaServerModule.web.d.ts +10 -0
  319. package/build/ota-server/OtaServerModule.web.d.ts.map +1 -0
  320. package/build/ota-server/OtaServerModule.web.js +12 -0
  321. package/build/ota-server/OtaServerModule.web.js.map +1 -0
  322. package/build/ota-server/index.d.ts +3 -0
  323. package/build/ota-server/index.d.ts.map +1 -0
  324. package/build/ota-server/index.js +3 -0
  325. package/build/ota-server/index.js.map +1 -0
  326. package/build/ota-transport/index.d.ts +67 -0
  327. package/build/ota-transport/index.d.ts.map +1 -0
  328. package/build/ota-transport/index.js +58 -0
  329. package/build/ota-transport/index.js.map +1 -0
  330. package/build/photo-receiver/PhotoReceiver.types.d.ts +18 -0
  331. package/build/photo-receiver/PhotoReceiver.types.d.ts.map +1 -0
  332. package/build/photo-receiver/PhotoReceiver.types.js +2 -0
  333. package/build/photo-receiver/PhotoReceiver.types.js.map +1 -0
  334. package/build/photo-receiver/PhotoReceiverModule.d.ts +10 -0
  335. package/build/photo-receiver/PhotoReceiverModule.d.ts.map +1 -0
  336. package/build/photo-receiver/PhotoReceiverModule.js +3 -0
  337. package/build/photo-receiver/PhotoReceiverModule.js.map +1 -0
  338. package/build/photo-receiver/PhotoReceiverModule.web.d.ts +10 -0
  339. package/build/photo-receiver/PhotoReceiverModule.web.d.ts.map +1 -0
  340. package/build/photo-receiver/PhotoReceiverModule.web.js +12 -0
  341. package/build/photo-receiver/PhotoReceiverModule.web.js.map +1 -0
  342. package/build/photo-receiver/index.d.ts +3 -0
  343. package/build/photo-receiver/index.d.ts.map +1 -0
  344. package/build/photo-receiver/index.js +3 -0
  345. package/build/photo-receiver/index.js.map +1 -0
  346. package/build/react/index.d.ts +5 -0
  347. package/build/react/index.d.ts.map +1 -0
  348. package/build/react/index.js +4 -0
  349. package/build/react/index.js.map +1 -0
  350. package/build/react/useBluetooth.d.ts +100 -0
  351. package/build/react/useBluetooth.d.ts.map +1 -0
  352. package/build/react/useBluetooth.js +167 -0
  353. package/build/react/useBluetooth.js.map +1 -0
  354. package/build/react/useBluetoothEvent.d.ts +6 -0
  355. package/build/react/useBluetoothEvent.d.ts.map +1 -0
  356. package/build/react/useBluetoothEvent.js +21 -0
  357. package/build/react/useBluetoothEvent.js.map +1 -0
  358. package/build/react/useBluetoothScan.d.ts +22 -0
  359. package/build/react/useBluetoothScan.d.ts.map +1 -0
  360. package/build/react/useBluetoothScan.js +135 -0
  361. package/build/react/useBluetoothScan.js.map +1 -0
  362. package/build/react/useBluetoothStatus.d.ts +16 -0
  363. package/build/react/useBluetoothStatus.d.ts.map +1 -0
  364. package/build/react/useBluetoothStatus.js +137 -0
  365. package/build/react/useBluetoothStatus.js.map +1 -0
  366. package/build/react/useGlassesConnection.d.ts +29 -0
  367. package/build/react/useGlassesConnection.d.ts.map +1 -0
  368. package/build/react/useGlassesConnection.js +153 -0
  369. package/build/react/useGlassesConnection.js.map +1 -0
  370. package/build/types/index.d.ts +3 -0
  371. package/build/types/index.d.ts.map +1 -0
  372. package/build/types/index.js +2 -0
  373. package/build/types/index.js.map +1 -0
  374. package/expo-module.config.json +14 -0
  375. package/ios/BackgroundOtaArtifactDownloader.swift +125 -0
  376. package/ios/BluetoothSdkModule.swift +1034 -0
  377. package/ios/GlasslyBluetoothSDK.podspec +106 -0
  378. package/ios/LocalIPv4.swift +150 -0
  379. package/ios/LocalOtaServer.swift +309 -0
  380. package/ios/LocalPhotoUploadServer.swift +754 -0
  381. package/ios/OtaServerModule.swift +147 -0
  382. package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
  383. package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
  384. package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
  385. package/ios/Packages/CoreObjC/attdet.c +92 -0
  386. package/ios/Packages/CoreObjC/attdet.h +44 -0
  387. package/ios/Packages/CoreObjC/bits.c +375 -0
  388. package/ios/Packages/CoreObjC/bits.h +315 -0
  389. package/ios/Packages/CoreObjC/bwdet.c +129 -0
  390. package/ios/Packages/CoreObjC/bwdet.h +69 -0
  391. package/ios/Packages/CoreObjC/common.h +151 -0
  392. package/ios/Packages/CoreObjC/energy.c +70 -0
  393. package/ios/Packages/CoreObjC/energy.h +43 -0
  394. package/ios/Packages/CoreObjC/fastmath.h +158 -0
  395. package/ios/Packages/CoreObjC/include/PcmConverter.h +22 -0
  396. package/ios/Packages/CoreObjC/lc3.c +704 -0
  397. package/ios/Packages/CoreObjC/lc3.h +313 -0
  398. package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
  399. package/ios/Packages/CoreObjC/lc3_private.h +163 -0
  400. package/ios/Packages/CoreObjC/ltpf.c +905 -0
  401. package/ios/Packages/CoreObjC/ltpf.h +111 -0
  402. package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
  403. package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
  404. package/ios/Packages/CoreObjC/makefile.mk +35 -0
  405. package/ios/Packages/CoreObjC/mdct.c +469 -0
  406. package/ios/Packages/CoreObjC/mdct.h +57 -0
  407. package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
  408. package/ios/Packages/CoreObjC/meson.build +61 -0
  409. package/ios/Packages/CoreObjC/plc.c +61 -0
  410. package/ios/Packages/CoreObjC/plc.h +57 -0
  411. package/ios/Packages/CoreObjC/rnnoise.h +114 -0
  412. package/ios/Packages/CoreObjC/sns.c +880 -0
  413. package/ios/Packages/CoreObjC/sns.h +103 -0
  414. package/ios/Packages/CoreObjC/spec.c +907 -0
  415. package/ios/Packages/CoreObjC/spec.h +119 -0
  416. package/ios/Packages/CoreObjC/tables.c +3457 -0
  417. package/ios/Packages/CoreObjC/tables.h +94 -0
  418. package/ios/Packages/CoreObjC/tns.c +457 -0
  419. package/ios/Packages/CoreObjC/tns.h +99 -0
  420. package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
  421. package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
  422. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +2383 -0
  423. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +48 -0
  424. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/c-api.h +4689 -0
  425. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/Headers/sherpa-onnx/c-api/cxx-api.h +2036 -0
  426. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
  427. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/c-api.h +4689 -0
  428. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/Headers/sherpa-onnx/c-api/cxx-api.h +2036 -0
  429. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
  430. package/ios/Packages/libbz2/module.modulemap +5 -0
  431. package/ios/Packages/libbz2/shim.h +1 -0
  432. package/ios/PhotoReceiverModule.swift +129 -0
  433. package/ios/Source/BluetoothSDK.swift +2303 -0
  434. package/ios/Source/BluetoothSDKDebug.swift +12 -0
  435. package/ios/Source/BluetoothSdkDefaults.swift +29 -0
  436. package/ios/Source/Bridge.swift +708 -0
  437. package/ios/Source/Bridging-Header.h +16 -0
  438. package/ios/Source/DeviceManager.swift +2109 -0
  439. package/ios/Source/DeviceStore.swift +336 -0
  440. package/ios/Source/GeneratedChangelogCatalog.swift +7 -0
  441. package/ios/Source/GeneratedReleaseMetadata.swift +11 -0
  442. package/ios/Source/ObservableStore.swift +118 -0
  443. package/ios/Source/OtaManifest.swift +211 -0
  444. package/ios/Source/PrivacyInfo.xcprivacy +23 -0
  445. package/ios/Source/ReleaseChangelog.swift +65 -0
  446. package/ios/Source/Resources/G2Firmware/README.md +10 -0
  447. package/ios/Source/audio/AudioModels.swift +178 -0
  448. package/ios/Source/audio/PcmStreamPlayer.swift +410 -0
  449. package/ios/Source/camera/CameraModels.swift +866 -0
  450. package/ios/Source/connection/ScanSession.swift +27 -0
  451. package/ios/Source/controllers/ControllerManager.swift +184 -0
  452. package/ios/Source/controllers/R1.swift +829 -0
  453. package/ios/Source/errors/BluetoothSdkError.swift +19 -0
  454. package/ios/Source/events/BluetoothEvents.swift +342 -0
  455. package/ios/Source/internal/BleTraceLogger.swift +192 -0
  456. package/ios/Source/internal/BluetoothAvailability.swift +78 -0
  457. package/ios/Source/internal/BluetoothSdkAnalytics.swift +199 -0
  458. package/ios/Source/internal/ValueParsing.swift +99 -0
  459. package/ios/Source/requests/DisplayRequests.swift +82 -0
  460. package/ios/Source/services/PhoneMic.swift +662 -0
  461. package/ios/Source/sgcs/Ar99.swift +2451 -0
  462. package/ios/Source/sgcs/Frame.swift +649 -0
  463. package/ios/Source/sgcs/G1.swift +2554 -0
  464. package/ios/Source/sgcs/G2.swift +6887 -0
  465. package/ios/Source/sgcs/G2CfwClassification.swift +43 -0
  466. package/ios/Source/sgcs/G2CfwRenderer.swift +1279 -0
  467. package/ios/Source/sgcs/G2CfwTextureCache.swift +233 -0
  468. package/ios/Source/sgcs/G2FlashProtocol.swift +312 -0
  469. package/ios/Source/sgcs/G2Flasher.swift +773 -0
  470. package/ios/Source/sgcs/Mach1.swift +541 -0
  471. package/ios/Source/sgcs/MentraLive.swift +7011 -0
  472. package/ios/Source/sgcs/MentraLiveL2capChannel.swift +183 -0
  473. package/ios/Source/sgcs/MentraLivePairingAdvertisement.swift +64 -0
  474. package/ios/Source/sgcs/MentraNex.swift +3221 -0
  475. package/ios/Source/sgcs/Nimo.swift +1886 -0
  476. package/ios/Source/sgcs/SGCManager.swift +608 -0
  477. package/ios/Source/sgcs/Simulated.swift +274 -0
  478. package/ios/Source/sgcs/ar99/ota/Ar99OtaManager.swift +637 -0
  479. package/ios/Source/sgcs/glassly_ble.pb.swift +4354 -0
  480. package/ios/Source/speakerid/SpeakerIdEngine.swift +573 -0
  481. package/ios/Source/status/DeviceStatus.swift +981 -0
  482. package/ios/Source/status/RuntimeState.swift +359 -0
  483. package/ios/Source/status/WifiHotspotStatus.swift +345 -0
  484. package/ios/Source/streaming/StreamModels.swift +693 -0
  485. package/ios/Source/stt/STTTools.swift +191 -0
  486. package/ios/Source/stt/SherpaOnnxTranscriber.swift +466 -0
  487. package/ios/Source/tts/TTSTools.swift +171 -0
  488. package/ios/Source/types/DeviceModels.swift +177 -0
  489. package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
  490. package/ios/Source/utils/BinaryCodec.swift +61 -0
  491. package/ios/Source/utils/BleJsonCompact.swift +405 -0
  492. package/ios/Source/utils/BleWireProtocol.swift +92 -0
  493. package/ios/Source/utils/Constants.swift +78 -0
  494. package/ios/Source/utils/Enums.swift +95 -0
  495. package/ios/Source/utils/G1Text.swift +2096 -0
  496. package/ios/Source/utils/JSCExperiment.swift +241 -0
  497. package/ios/Source/utils/MemoryMonitor.swift +44 -0
  498. package/ios/Source/utils/MessageChunkReassembler.swift +190 -0
  499. package/ios/Source/utils/MessageChunker.swift +294 -0
  500. package/ios/Source/utils/Models.swift +135 -0
  501. package/ios/Source/utils/PhoneAudioMonitor.swift +230 -0
  502. package/ios/Source/utils/TarBz2Extractor.swift +257 -0
  503. package/ios/Tests/BluetoothSDKTests/G2CfwClassificationTests.swift +78 -0
  504. package/ios/Tests/BluetoothSDKTests/G2CfwRendererTests.swift +372 -0
  505. package/ios/Tests/BluetoothSDKTests/G2CfwTextureCacheTests.swift +162 -0
  506. package/ios/Tests/BluetoothSDKTests/G2FlashProtocolTests.swift +182 -0
  507. package/ios/Tests/MentraLivePairingAdvertisementTests.swift +160 -0
  508. package/ios/Tests/ReleaseChangelogTests.swift +13 -0
  509. package/package.json +129 -0
  510. package/plugin/build/index.d.ts +10 -0
  511. package/plugin/build/index.js +12 -0
  512. package/plugin/build/withAndroid.d.ts +3 -0
  513. package/plugin/build/withAndroid.js +190 -0
  514. package/plugin/build/withIos.d.ts +5 -0
  515. package/plugin/build/withIos.js +108 -0
  516. package/scripts/inject-ios-sdk-version.mjs +65 -0
  517. package/scripts/public-ota-api.test.mjs +37 -0
  518. package/scripts/verify-release-package.mjs +45 -0
  519. package/scripts/write-release-metadata.mjs +152 -0
  520. package/scripts/write-release-metadata.test.mjs +37 -0
  521. package/src/BluetoothSdk.types.ts +1623 -0
  522. package/src/_internal.ts +16 -0
  523. package/src/_private/BluetoothSdkModule.ts +684 -0
  524. package/src/_private/LocalNetworkModule.ts +50 -0
  525. package/src/_private/cameraRequestPayload.ts +34 -0
  526. package/src/_private/photoRequestPayload.ts +90 -0
  527. package/src/_private/sdkOtaManifest.ts +18 -0
  528. package/src/changelogs.ts +46 -0
  529. package/src/debug.ts +9 -0
  530. package/src/generated/changelogCatalog.ts +13 -0
  531. package/src/generated/releaseMetadata.ts +20 -0
  532. package/src/index.ts +321 -0
  533. package/src/ota-server/OtaServer.types.ts +10 -0
  534. package/src/ota-server/OtaServerModule.ts +23 -0
  535. package/src/ota-server/OtaServerModule.web.ts +17 -0
  536. package/src/ota-server/index.ts +2 -0
  537. package/src/ota-transport/index.ts +116 -0
  538. package/src/photo-receiver/PhotoReceiver.types.ts +20 -0
  539. package/src/photo-receiver/PhotoReceiverModule.ts +11 -0
  540. package/src/photo-receiver/PhotoReceiverModule.web.ts +17 -0
  541. package/src/photo-receiver/index.ts +2 -0
  542. package/src/react/index.ts +21 -0
  543. package/src/react/useBluetooth.ts +309 -0
  544. package/src/react/useBluetoothEvent.ts +35 -0
  545. package/src/react/useBluetoothScan.ts +173 -0
  546. package/src/react/useBluetoothStatus.ts +180 -0
  547. package/src/react/useGlassesConnection.ts +202 -0
  548. package/src/types/index.ts +12 -0
@@ -0,0 +1,270 @@
1
+ package com.glassly.bluetoothsdk.sgcs
2
+
3
+ import java.io.ByteArrayOutputStream
4
+
5
+ /**
6
+ * Phone-side model of the Glassly CFW's lease-scoped 64 KiB texture cache
7
+ * (g2flash texture_cache.c), plus the mode-12/13/14 wire encoders.
8
+ *
9
+ * The firmware allocates and zeroes the cache on the first mode-12 write and
10
+ * frees it when the fbguard lease ends, so this model is only valid for one
11
+ * lease/generation: the owner bumps a generation counter whenever the lease
12
+ * cycles (or a send fails and residency becomes unknown) and the model
13
+ * re-learns from scratch — uploads are cheap (a full mono font is a few KiB).
14
+ *
15
+ * Cached image format: `[width:u8][height:u8][4bpp RLE]` where the RLE covers
16
+ * exactly width*height pixels with NO row-pad nibbles (unlike modes 3/6).
17
+ * Mode-14 fonts are a 96-entry little-endian u16 image-offset table for
18
+ * characters 32..127; a zero entry points at cache offset 0, so the first
19
+ * two bytes of the cache are left zero (width 0 ⇒ invalid image) and real
20
+ * allocations start past them.
21
+ */
22
+ internal class G2CfwTextureCache {
23
+ companion object {
24
+ const val CACHE_SIZE = 64 * 1024
25
+ const val FONT_TABLE_CHARS = 96 // ASCII 32..127
26
+
27
+ /** Keep mode-12 payloads comfortably inside one BLE image message. */
28
+ const val MAX_UPLOAD_PAYLOAD_BYTES = 3600
29
+
30
+ /**
31
+ * 0x0F: identity ramp (top color 15), opaque — a full-cell glyph or a
32
+ * full-box image drawn opaque self-erases whatever was under it.
33
+ */
34
+ const val OPAQUE_DRAW_OPTIONS = 0x0F
35
+
36
+ /**
37
+ * RLE over a flat 8-bit grayscale pixel sequence (quantized to 4bpp),
38
+ * covering exactly the pixel count — no row padding, per the cached-image
39
+ * contract. Token forms match modes 3/6.
40
+ */
41
+ fun rleEncodePixels(gray: ByteArray): ByteArray {
42
+ val output = ByteArrayOutputStream()
43
+ var index = 0
44
+ while (index < gray.size) {
45
+ // Same rounded quantization as pack4Bpp: a cached draw must reproduce
46
+ // the composited frame's exact levels or the phone-side shadow
47
+ // diverges from the panel.
48
+ val color = G2CfwRenderer.grayNibble(gray[index].toInt())
49
+ var end = index + 1
50
+ while (end < gray.size && G2CfwRenderer.grayNibble(gray[end].toInt()) == color) end += 1
51
+ var remaining = end - index
52
+ while (remaining > 0) {
53
+ val chunk = minOf(remaining, 0xFFFF)
54
+ when {
55
+ chunk <= 15 -> output.write((chunk shl 4) or color)
56
+ chunk <= 255 -> {
57
+ output.write(color)
58
+ output.write(chunk)
59
+ }
60
+ else -> {
61
+ output.write(color)
62
+ output.write(0)
63
+ output.write(chunk and 0xFF)
64
+ output.write((chunk ushr 8) and 0xFF)
65
+ }
66
+ }
67
+ remaining -= chunk
68
+ }
69
+ index = end
70
+ }
71
+ return output.toByteArray()
72
+ }
73
+
74
+ /** Mode-13 cached-image draw: `[13][offset:u16][x:u16][y:u16][options]`. */
75
+ fun imageDrawPayload(offset: Int, x: Int, y: Int, options: Int): ByteArray? {
76
+ if (offset !in 0..0xFFFF || x !in 0..0xFFFF || y !in 0..0xFFFF) return null
77
+ val payload = ByteArrayOutputStream()
78
+ payload.write(13)
79
+ for (value in intArrayOf(offset, x, y)) {
80
+ payload.write(value and 0xFF)
81
+ payload.write((value ushr 8) and 0xFF)
82
+ }
83
+ payload.write(options and 0xFF)
84
+ return payload.toByteArray()
85
+ }
86
+
87
+ /**
88
+ * Mode-14 cached-glyph run:
89
+ * `[14][font-offset:u16][x:u16][y:u16][options][strlen:u8][chars]`.
90
+ * Every char must be 32..126 and resident (the firmware validates each
91
+ * referenced glyph and rejects the whole draw otherwise).
92
+ */
93
+ fun stringRunPayload(
94
+ fontTableOffset: Int,
95
+ x: Int,
96
+ y: Int,
97
+ options: Int,
98
+ chars: ByteArray,
99
+ ): ByteArray? {
100
+ if (chars.isEmpty() || chars.size > 255) return null
101
+ if (fontTableOffset !in 0..(CACHE_SIZE - FONT_TABLE_CHARS * 2)) return null
102
+ if (x !in 0..0xFFFF || y !in 0..0xFFFF) return null
103
+ if (chars.any { (it.toInt() and 0xFF) < 32 || (it.toInt() and 0xFF) > 126 }) return null
104
+ val payload = ByteArrayOutputStream()
105
+ payload.write(14)
106
+ for (value in intArrayOf(fontTableOffset, x, y)) {
107
+ payload.write(value and 0xFF)
108
+ payload.write((value ushr 8) and 0xFF)
109
+ }
110
+ payload.write(options and 0xFF)
111
+ payload.write(chars.size)
112
+ payload.write(chars)
113
+ return payload.toByteArray()
114
+ }
115
+ }
116
+
117
+ class FontEntry(val tableOffset: Int, val cellWidth: Int, val lineHeight: Int) {
118
+ /** Cache offset per printable char (index = char - 32), null = not resident. */
119
+ val glyphOffsets = arrayOfNulls<Int>(FONT_TABLE_CHARS)
120
+ }
121
+
122
+ var generation = -1
123
+ private set
124
+
125
+ private val fonts = mutableMapOf<Int, FontEntry>()
126
+ private val images = mutableMapOf<String, Int>()
127
+
128
+ /**
129
+ * Content hashes seen in earlier frames. Streaming content (a minimap
130
+ * re-rendered every frame) never repeats a hash, so it never enters the
131
+ * cache; static icons promote on their second sighting.
132
+ */
133
+ private val seenImageHashes = ArrayDeque<String>()
134
+
135
+ /** Bump allocator. Bytes 0..1 stay zero as the invalid-image guard. */
136
+ private var nextOffset = 2
137
+
138
+ /** Mode-12 entries not yet flushed into payloads. */
139
+ private val pendingUploads = mutableListOf<Pair<Int, ByteArray>>()
140
+
141
+ /**
142
+ * The bump allocator filled up. The reference client recycles a full
143
+ * cache (`TextureCacheState.reset` "or we ran out of space"); without
144
+ * recovery every later ensure fails and the texture path silently dies
145
+ * for the rest of the lease. The renderer checks this before each frame
146
+ * and starts a fresh generation.
147
+ */
148
+ var exhausted = false
149
+ private set
150
+
151
+ /**
152
+ * Forget everything and adopt `generation` (the on-glass cache was freed
153
+ * or its state became unknown).
154
+ */
155
+ fun reset(generation: Int) {
156
+ this.generation = generation
157
+ fonts.clear()
158
+ images.clear()
159
+ seenImageHashes.clear()
160
+ nextOffset = 2
161
+ pendingUploads.clear()
162
+ exhausted = false
163
+ }
164
+
165
+ private fun allocate(length: Int): Int? {
166
+ if (length <= 0 || nextOffset + length > CACHE_SIZE) {
167
+ if (length > 0) exhausted = true
168
+ return null
169
+ }
170
+ val offset = nextOffset
171
+ nextOffset += length
172
+ return offset
173
+ }
174
+
175
+ /**
176
+ * The font table for `fontSize`, allocating (and zero-filling on-glass by
177
+ * virtue of the fresh cache) the 192-byte offset table on first use.
178
+ */
179
+ fun font(fontSize: Int, cellWidth: Int, lineHeight: Int): FontEntry? {
180
+ fonts[fontSize]?.let { return it }
181
+ val tableOffset = allocate(FONT_TABLE_CHARS * 2) ?: return null
182
+ val entry = FontEntry(tableOffset, cellWidth, lineHeight)
183
+ fonts[fontSize] = entry
184
+ return entry
185
+ }
186
+
187
+ /**
188
+ * Make `char` (ASCII 32..126) resident for `font`, uploading its RLE
189
+ * raster and patching the font table. `rasterize` supplies the full-cell
190
+ * 8-bit grayscale raster (cellWidth × lineHeight) on first upload.
191
+ * Returns false when the cache is full or the raster is unavailable.
192
+ */
193
+ fun ensureGlyph(font: FontEntry, char: Int, rasterize: () -> ByteArray?): Boolean {
194
+ if (char < 32 || char > 126) return false
195
+ val index = char - 32
196
+ if (font.glyphOffsets[index] != null) return true
197
+ val gray = rasterize() ?: return false
198
+ if (gray.size != font.cellWidth * font.lineHeight) return false
199
+ val image = ByteArrayOutputStream()
200
+ image.write(font.cellWidth)
201
+ image.write(font.lineHeight)
202
+ image.write(rleEncodePixels(gray))
203
+ val bytes = image.toByteArray()
204
+ val offset = allocate(bytes.size) ?: return false
205
+ font.glyphOffsets[index] = offset
206
+ pendingUploads.add(offset to bytes)
207
+ pendingUploads.add(
208
+ (font.tableOffset + index * 2) to
209
+ byteArrayOf((offset and 0xFF).toByte(), ((offset ushr 8) and 0xFF).toByte())
210
+ )
211
+ return true
212
+ }
213
+
214
+ /**
215
+ * Record a sighting of an image content hash; true when it was already
216
+ * seen in an earlier frame (worth caching).
217
+ */
218
+ fun noteImageSighting(hash: String): Boolean {
219
+ if (images.containsKey(hash)) return true
220
+ if (hash in seenImageHashes) return true
221
+ seenImageHashes.addLast(hash)
222
+ if (seenImageHashes.size > 32) seenImageHashes.removeFirst()
223
+ return false
224
+ }
225
+
226
+ /**
227
+ * The cache offset of an image, uploading it on first residency.
228
+ * `gray` is the width×height 8-bit grayscale raster.
229
+ */
230
+ fun ensureImage(hash: String, gray: ByteArray, width: Int, height: Int): Int? {
231
+ images[hash]?.let { return it }
232
+ if (width !in 1..255 || height !in 1..255 || gray.size != width * height) return null
233
+ val image = ByteArrayOutputStream()
234
+ image.write(width)
235
+ image.write(height)
236
+ image.write(rleEncodePixels(gray))
237
+ val bytes = image.toByteArray()
238
+ val offset = allocate(bytes.size) ?: return null
239
+ images[hash] = offset
240
+ pendingUploads.add(offset to bytes)
241
+ return offset
242
+ }
243
+
244
+ /**
245
+ * Drain the pending mode-12 entries into `[12][offset16][len16][data]...`
246
+ * payloads, each at most [MAX_UPLOAD_PAYLOAD_BYTES]. An entry larger than
247
+ * the budget gets a payload of its own (the BLE fragmenter splits it).
248
+ */
249
+ fun takeUploadPayloads(): List<ByteArray> {
250
+ if (pendingUploads.isEmpty()) return emptyList()
251
+ val payloads = mutableListOf<ByteArray>()
252
+ var current = ByteArrayOutputStream().apply { write(12) }
253
+ for ((offset, data) in pendingUploads) {
254
+ val record = ByteArrayOutputStream()
255
+ record.write(offset and 0xFF)
256
+ record.write((offset ushr 8) and 0xFF)
257
+ record.write(data.size and 0xFF)
258
+ record.write((data.size ushr 8) and 0xFF)
259
+ record.write(data)
260
+ if (current.size() > 1 && current.size() + record.size() > MAX_UPLOAD_PAYLOAD_BYTES) {
261
+ payloads.add(current.toByteArray())
262
+ current = ByteArrayOutputStream().apply { write(12) }
263
+ }
264
+ record.writeTo(current)
265
+ }
266
+ if (current.size() > 1) payloads.add(current.toByteArray())
267
+ pendingUploads.clear()
268
+ return payloads
269
+ }
270
+ }
@@ -0,0 +1,291 @@
1
+ package com.glassly.bluetoothsdk.sgcs
2
+
3
+ /** Byte-exact EVENOTA framing, validation, and MRAM brick guard. No BLE I/O lives here. */
4
+ internal object G2FlashProtocol {
5
+ private const val U32_MASK = 0xFFFF_FFFFL
6
+ const val CHUNK = 232
7
+ const val APP_LOAD_ADDR = 0x0043_8000L
8
+ const val APP_MAX_END = 0x007F_0000L
9
+ const val APP_PREAMBLE = 0x20
10
+ const val REQUIRED_SEGMENT = "ota/s200_firmware_ota.bin"
11
+
12
+ class BadImageException(message: String) : Exception("bad firmware image: $message")
13
+
14
+ data class Rx(val sequence: Int, val sid: Int, val pb: ByteArray)
15
+
16
+ data class Segment(
17
+ val eid: Long,
18
+ val off: Long,
19
+ val size: Long,
20
+ val crc: Long,
21
+ val sub: ByteArray,
22
+ val ps: Long,
23
+ val fn: String,
24
+ )
25
+
26
+ data class GuardResult(
27
+ val ps: Long,
28
+ val loadAddr: Long,
29
+ val preLen: Long,
30
+ val progEnd: Long,
31
+ val pass: Boolean,
32
+ val reason: String,
33
+ )
34
+
35
+ data class ValidatedImage(val segments: List<Segment>, val guardResult: GuardResult)
36
+
37
+ data class GoldenVector(
38
+ val sha256: String,
39
+ val ps: Long,
40
+ val progEnd: Long,
41
+ val pass: Boolean,
42
+ )
43
+
44
+ val goldenStock =
45
+ GoldenVector(
46
+ sha256 = "f4dfb0b49ad3de3c2daf17f8a27a157c3dc98411d6a0d3ab2cfd0918f41b9afa",
47
+ ps = 3_523_396,
48
+ progEnd = 0x0079_4324,
49
+ pass = true,
50
+ )
51
+
52
+ fun crc16(data: ByteArray): ByteArray {
53
+ var crc = 0xFFFF
54
+ for (byte in data) {
55
+ crc = crc xor ((byte.toInt() and 0xFF) shl 8)
56
+ repeat(8) {
57
+ crc =
58
+ if ((crc and 0x8000) != 0) {
59
+ ((crc shl 1) xor 0x1021) and 0xFFFF
60
+ } else {
61
+ (crc shl 1) and 0xFFFF
62
+ }
63
+ }
64
+ }
65
+ return byteArrayOf((crc and 0xFF).toByte(), ((crc ushr 8) and 0xFF).toByte())
66
+ }
67
+
68
+ private val crc32cTable =
69
+ LongArray(256).also { table ->
70
+ for (byte in 0 until 256) {
71
+ var crc = (byte.toLong() shl 24) and U32_MASK
72
+ repeat(8) {
73
+ crc =
74
+ if ((crc and 0x8000_0000L) != 0L) {
75
+ ((crc shl 1) xor 0x1EDC_6F41L) and U32_MASK
76
+ } else {
77
+ (crc shl 1) and U32_MASK
78
+ }
79
+ }
80
+ table[byte] = crc
81
+ }
82
+ }
83
+
84
+ fun crc32c(data: ByteArray): Long {
85
+ var crc = 0L
86
+ for (byte in data) {
87
+ val index = (((crc ushr 24) xor (byte.toLong() and 0xFF)) and 0xFF).toInt()
88
+ crc = (((crc shl 8) and U32_MASK) xor crc32cTable[index]) and U32_MASK
89
+ }
90
+ return crc
91
+ }
92
+
93
+ fun readU32LE(bytes: ByteArray, offset: Int): Long =
94
+ (bytes[offset].toLong() and 0xFF) or
95
+ ((bytes[offset + 1].toLong() and 0xFF) shl 8) or
96
+ ((bytes[offset + 2].toLong() and 0xFF) shl 16) or
97
+ ((bytes[offset + 3].toLong() and 0xFF) shl 24)
98
+
99
+ fun frames(sid: Int, pb: ByteArray, flag: Int = 0, seq: Int): List<ByteArray> {
100
+ val body = pb + crc16(pb)
101
+ val total = maxOf(1, (body.size + CHUNK - 1) / CHUNK)
102
+ return List(total) { index ->
103
+ val start = index * CHUNK
104
+ val chunk = body.copyOfRange(start, minOf(start + CHUNK, body.size))
105
+ byteArrayOf(
106
+ 0xAA.toByte(),
107
+ 0x21,
108
+ (seq and 0xFF).toByte(),
109
+ chunk.size.toByte(),
110
+ total.toByte(),
111
+ (index + 1).toByte(),
112
+ sid.toByte(),
113
+ flag.toByte(),
114
+ ) + chunk
115
+ }
116
+ }
117
+
118
+ fun ctrlFrames(op: Int, data: ByteArray = ByteArray(0), seq: Int): List<ByteArray> =
119
+ frames(sid = 0xC0, pb = byteArrayOf(op.toByte()) + data, seq = seq)
120
+
121
+ fun dataFrames(block: ByteArray, seq: Int): List<ByteArray> =
122
+ frames(sid = 0xC1, pb = block, seq = seq)
123
+
124
+ fun parseRx(frame: ByteArray): Rx? {
125
+ if (frame.size < 10 || (frame[0].toInt() and 0xFF) != 0xAA ||
126
+ (frame[1].toInt() and 0xFF) != 0x12
127
+ ) {
128
+ return null
129
+ }
130
+ val length = frame[3].toInt() and 0xFF
131
+ val payloadLength = maxOf(0, length - 2)
132
+ val end = minOf(8 + payloadLength, frame.size)
133
+ return Rx(
134
+ sequence = frame[2].toInt() and 0xFF,
135
+ sid = frame[6].toInt() and 0xFF,
136
+ pb = if (end >= 8) frame.copyOfRange(8, end) else ByteArray(0),
137
+ )
138
+ }
139
+
140
+ /** Real OTA replies correlate by notification characteristic and opcode, not echoed seq/SID. */
141
+ fun otaAckStatus(frames: Iterable<ByteArray>, opcode: Int): Int? {
142
+ for (frame in frames) {
143
+ val parsed = parseRx(frame) ?: continue
144
+ if (parsed.pb.size >= 2 && (parsed.pb[0].toInt() and 0xFF) == opcode) {
145
+ return parsed.pb[1].toInt() and 0xFF
146
+ }
147
+ }
148
+ return null
149
+ }
150
+
151
+ @Throws(BadImageException::class)
152
+ fun parseSegments(image: ByteArray): List<Segment> {
153
+ if (image.size < 0x40) throw BadImageException("file too small")
154
+ val count = readU32LE(image, 8)
155
+ if (count !in 1..64) throw BadImageException("implausible component count $count")
156
+ return List(count.toInt()) { index ->
157
+ val toc = 0x40 + index * 16
158
+ if (toc + 16 > image.size) throw BadImageException("TOC entry $index past EOF")
159
+ val offset = readU32LE(image, toc + 4)
160
+ if (offset > Int.MAX_VALUE || offset + 128 > image.size.toLong()) {
161
+ throw BadImageException("segment $index subheader past EOF")
162
+ }
163
+ val sub = image.copyOfRange(offset.toInt(), offset.toInt() + 128)
164
+ var nameEnd = 48
165
+ while (nameEnd < sub.size && sub[nameEnd].toInt() != 0) nameEnd += 1
166
+ Segment(
167
+ eid = readU32LE(image, toc),
168
+ off = offset,
169
+ size = readU32LE(image, toc + 8),
170
+ crc = readU32LE(image, toc + 12),
171
+ sub = sub,
172
+ ps = readU32LE(sub, 8),
173
+ fn = String(sub, 48, nameEnd - 48, Charsets.ISO_8859_1),
174
+ )
175
+ }
176
+ }
177
+
178
+ @Throws(BadImageException::class)
179
+ fun validateFirmware(image: ByteArray): ValidatedImage {
180
+ val segments = parseSegments(image)
181
+ val names = segments.map { it.fn }
182
+ if (segments.size !in 5..6) {
183
+ throw BadImageException("expected 5-6 segments, found ${segments.size}: $names")
184
+ }
185
+ if (REQUIRED_SEGMENT !in names) {
186
+ throw BadImageException("required segment $REQUIRED_SEGMENT not found; segments are: $names")
187
+ }
188
+ for ((index, segment) in segments.withIndex()) {
189
+ val payloadOffset = segment.off + 128
190
+ val payloadEnd = payloadOffset + segment.ps
191
+ if (segment.ps <= 0 || payloadOffset < 128 || payloadEnd > image.size.toLong()) {
192
+ throw BadImageException("segment $index (${segment.fn}) payload extends past EOF")
193
+ }
194
+ if (segment.ps > U32_MASK - 128 || segment.size != segment.ps + 128) {
195
+ throw BadImageException(
196
+ "segment $index (${segment.fn}) TOC size ${segment.size} != payload+header ${segment.ps + 128}"
197
+ )
198
+ }
199
+ val payload = image.copyOfRange(payloadOffset.toInt(), payloadEnd.toInt())
200
+ val calculated = crc32c(payload)
201
+ val subheaderCrc = readU32LE(segment.sub, 12)
202
+ if (calculated != segment.crc || calculated != subheaderCrc) {
203
+ throw BadImageException(
204
+ String.format(
205
+ "segment %d (%s) CRC32C mismatch: payload=%08x TOC=%08x sub=%08x",
206
+ index,
207
+ segment.fn,
208
+ calculated,
209
+ segment.crc,
210
+ subheaderCrc,
211
+ )
212
+ )
213
+ }
214
+ }
215
+ val guard = checkMainAppFitsMram(image, segments)
216
+ if (!guard.pass) throw BadImageException("brick guard blocked image: ${guard.reason}")
217
+ return ValidatedImage(segments, guard)
218
+ }
219
+
220
+ fun checkMainAppFitsMram(image: ByteArray, segments: List<Segment>): GuardResult {
221
+ val segment =
222
+ segments.firstOrNull { it.fn == REQUIRED_SEGMENT }
223
+ ?: return GuardResult(0, 0, 0, 0, false, "main-app segment $REQUIRED_SEGMENT not found")
224
+ val payloadOffset = segment.off + 128
225
+ if (payloadOffset + APP_PREAMBLE > image.size.toLong()) {
226
+ return GuardResult(
227
+ segment.ps,
228
+ 0,
229
+ 0,
230
+ 0,
231
+ false,
232
+ "main-app payload smaller than its 32-byte preamble",
233
+ )
234
+ }
235
+ val offset = payloadOffset.toInt()
236
+ val loadAddr = readU32LE(image, offset + 0x14)
237
+ val preLen = readU32LE(image, offset) and 0x00FF_FFFFL
238
+ if (loadAddr != APP_LOAD_ADDR) {
239
+ return GuardResult(
240
+ segment.ps,
241
+ loadAddr,
242
+ preLen,
243
+ 0,
244
+ false,
245
+ String.format("load addr 0x%08x != 0x00438000", loadAddr),
246
+ )
247
+ }
248
+ if (preLen != segment.ps) {
249
+ return GuardResult(
250
+ segment.ps,
251
+ loadAddr,
252
+ preLen,
253
+ 0,
254
+ false,
255
+ "preamble length $preLen != staged payload size ${segment.ps}",
256
+ )
257
+ }
258
+ val programEnd = (APP_LOAD_ADDR + segment.ps - APP_PREAMBLE) and U32_MASK
259
+ if (programEnd > APP_MAX_END) {
260
+ return GuardResult(
261
+ segment.ps,
262
+ loadAddr,
263
+ preLen,
264
+ programEnd,
265
+ false,
266
+ String.format("too large: prog_end 0x%08x past ceiling 0x%08x", programEnd, APP_MAX_END),
267
+ )
268
+ }
269
+ return GuardResult(segment.ps, loadAddr, preLen, programEnd, true, "ok")
270
+ }
271
+
272
+ fun selfTestGuard(image: ByteArray, expected: GoldenVector): String? {
273
+ val segments =
274
+ try {
275
+ parseSegments(image)
276
+ } catch (error: Exception) {
277
+ return "parse failed: $error"
278
+ }
279
+ val result = checkMainAppFitsMram(image, segments)
280
+ if (result.pass != expected.pass) return "guard pass=${result.pass} != golden ${expected.pass}"
281
+ if (result.ps != expected.ps) return "ps ${result.ps} != golden ${expected.ps}"
282
+ if (result.progEnd != expected.progEnd) {
283
+ return String.format(
284
+ "prog_end 0x%08x != golden 0x%08x",
285
+ result.progEnd,
286
+ expected.progEnd,
287
+ )
288
+ }
289
+ return null
290
+ }
291
+ }