@mentra/bluetooth-sdk 0.1.0

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 (278) hide show
  1. package/README.md +278 -0
  2. package/android/build.gradle +167 -0
  3. package/android/lc3Lib/CMakeLists.txt +6 -0
  4. package/android/lc3Lib/build.gradle +109 -0
  5. package/android/lc3Lib/proguard-rules.pro +33 -0
  6. package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
  7. package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
  8. package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
  9. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
  10. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
  11. package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
  12. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
  13. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
  14. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
  15. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
  16. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
  17. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
  18. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
  19. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
  20. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
  21. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
  22. package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
  23. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
  24. package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
  25. package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
  26. package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
  27. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
  28. package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
  29. package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
  30. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
  31. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
  32. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
  33. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
  34. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
  35. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
  36. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
  37. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
  38. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
  39. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
  40. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
  41. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
  42. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
  43. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
  44. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
  45. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
  46. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
  47. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
  48. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
  49. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
  50. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
  51. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
  52. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
  53. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
  54. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
  55. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
  56. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
  57. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
  58. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
  59. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
  60. package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
  61. package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
  62. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
  63. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
  64. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
  65. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
  66. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
  67. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
  68. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
  69. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
  70. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
  71. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
  72. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
  73. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
  74. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
  75. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
  76. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
  77. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
  78. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
  79. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
  80. package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
  81. package/android/lc3Lib/src/main/java/com/mentra/lc3Lib/Lc3Cpp.java +38 -0
  82. package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
  83. package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
  84. package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
  85. package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
  86. package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
  87. package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
  88. package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
  89. package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
  90. package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
  91. package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
  92. package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
  93. package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
  94. package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
  95. package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
  96. package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
  97. package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
  98. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
  99. package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
  100. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
  101. package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
  102. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
  103. package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
  104. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
  105. package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
  106. package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
  107. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
  108. package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
  109. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
  110. package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
  111. package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
  112. package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
  113. package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
  114. package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
  115. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
  116. package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
  117. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
  118. package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
  119. package/android/settings.gradle +1 -0
  120. package/android/src/main/AndroidManifest.xml +40 -0
  121. package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +528 -0
  122. package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +610 -0
  123. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +1616 -0
  124. package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +314 -0
  125. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +1710 -0
  126. package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +554 -0
  127. package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +68 -0
  128. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +158 -0
  129. package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +934 -0
  130. package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +175 -0
  131. package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +1109 -0
  132. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +3974 -0
  133. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3551 -0
  134. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1327 -0
  135. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +6959 -0
  136. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1655 -0
  137. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +53675 -0
  138. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +202 -0
  139. package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +224 -0
  140. package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +340 -0
  141. package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +465 -0
  142. package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +221 -0
  143. package/android/src/main/java/com/mentra/bluetoothsdk/utils/AES.java +106 -0
  144. package/android/src/main/java/com/mentra/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
  145. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
  146. package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +179 -0
  147. package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +44 -0
  148. package/android/src/main/java/com/mentra/bluetoothsdk/utils/G1Text.kt +436 -0
  149. package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
  150. package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleUploadService.java +76 -0
  151. package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +791 -0
  152. package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +186 -0
  153. package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +589 -0
  154. package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +303 -0
  155. package/android/src/main/java/com/mentra/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
  156. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
  157. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
  158. package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
  159. package/android/src/main/res/values/strings.xml +4 -0
  160. package/app.plugin.js +1 -0
  161. package/build/BluetoothSdk.types.d.ts +498 -0
  162. package/build/BluetoothSdk.types.d.ts.map +1 -0
  163. package/build/BluetoothSdk.types.js +23 -0
  164. package/build/BluetoothSdk.types.js.map +1 -0
  165. package/build/BluetoothSdkModule.d.ts +71 -0
  166. package/build/BluetoothSdkModule.d.ts.map +1 -0
  167. package/build/BluetoothSdkModule.js +106 -0
  168. package/build/BluetoothSdkModule.js.map +1 -0
  169. package/build/index.d.ts +3 -0
  170. package/build/index.d.ts.map +1 -0
  171. package/build/index.js +5 -0
  172. package/build/index.js.map +1 -0
  173. package/expo-module.config.json +9 -0
  174. package/ios/BluetoothSdkModule.swift +665 -0
  175. package/ios/MentraBluetoothSDK.podspec +77 -0
  176. package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
  177. package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
  178. package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
  179. package/ios/Packages/CoreObjC/attdet.c +92 -0
  180. package/ios/Packages/CoreObjC/attdet.h +44 -0
  181. package/ios/Packages/CoreObjC/bits.c +375 -0
  182. package/ios/Packages/CoreObjC/bits.h +315 -0
  183. package/ios/Packages/CoreObjC/bwdet.c +129 -0
  184. package/ios/Packages/CoreObjC/bwdet.h +69 -0
  185. package/ios/Packages/CoreObjC/common.h +151 -0
  186. package/ios/Packages/CoreObjC/energy.c +70 -0
  187. package/ios/Packages/CoreObjC/energy.h +43 -0
  188. package/ios/Packages/CoreObjC/fastmath.h +158 -0
  189. package/ios/Packages/CoreObjC/lc3.c +704 -0
  190. package/ios/Packages/CoreObjC/lc3.h +313 -0
  191. package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
  192. package/ios/Packages/CoreObjC/lc3_private.h +163 -0
  193. package/ios/Packages/CoreObjC/ltpf.c +905 -0
  194. package/ios/Packages/CoreObjC/ltpf.h +111 -0
  195. package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
  196. package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
  197. package/ios/Packages/CoreObjC/makefile.mk +35 -0
  198. package/ios/Packages/CoreObjC/mdct.c +469 -0
  199. package/ios/Packages/CoreObjC/mdct.h +57 -0
  200. package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
  201. package/ios/Packages/CoreObjC/meson.build +61 -0
  202. package/ios/Packages/CoreObjC/plc.c +61 -0
  203. package/ios/Packages/CoreObjC/plc.h +57 -0
  204. package/ios/Packages/CoreObjC/rnnoise.h +114 -0
  205. package/ios/Packages/CoreObjC/sns.c +880 -0
  206. package/ios/Packages/CoreObjC/sns.h +103 -0
  207. package/ios/Packages/CoreObjC/spec.c +907 -0
  208. package/ios/Packages/CoreObjC/spec.h +119 -0
  209. package/ios/Packages/CoreObjC/tables.c +3457 -0
  210. package/ios/Packages/CoreObjC/tables.h +94 -0
  211. package/ios/Packages/CoreObjC/tns.c +457 -0
  212. package/ios/Packages/CoreObjC/tns.h +99 -0
  213. package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
  214. package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
  215. package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +1659 -0
  216. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +162 -0
  217. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +1852 -0
  218. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +674 -0
  219. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +44 -0
  220. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
  221. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
  222. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
  223. package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
  224. package/ios/Packages/VAD/Common/VAD/VADQuality.swift +41 -0
  225. package/ios/Packages/VAD/Common/VAD/VADState.swift +26 -0
  226. package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +29 -0
  227. package/ios/Packages/VAD/Common/VAD/VADType.swift +14 -0
  228. package/ios/Packages/VAD/Data/Configuration.swift +68 -0
  229. package/ios/Packages/VAD/Data/FrameSize.swift +39 -0
  230. package/ios/Packages/VAD/Data/Record.swift +13 -0
  231. package/ios/Packages/VAD/Data/Result.swift +22 -0
  232. package/ios/Packages/VAD/Data/SampleRate.swift +48 -0
  233. package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
  234. package/ios/Packages/VAD/Silero/SileroVAD.swift +284 -0
  235. package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +64 -0
  236. package/ios/Packages/libbz2/module.modulemap +5 -0
  237. package/ios/Packages/libbz2/shim.h +1 -0
  238. package/ios/Source/Bridge.swift +353 -0
  239. package/ios/Source/Bridging-Header.h +16 -0
  240. package/ios/Source/DeviceManager.swift +1478 -0
  241. package/ios/Source/DeviceStore.swift +295 -0
  242. package/ios/Source/MentraBluetoothSDK.swift +2439 -0
  243. package/ios/Source/ObservableStore.swift +88 -0
  244. package/ios/Source/PrivacyInfo.xcprivacy +23 -0
  245. package/ios/Source/controllers/ControllerManager.swift +187 -0
  246. package/ios/Source/controllers/R1.swift +827 -0
  247. package/ios/Source/services/PhoneMic.swift +662 -0
  248. package/ios/Source/sgcs/Frame.swift +651 -0
  249. package/ios/Source/sgcs/G1.swift +2505 -0
  250. package/ios/Source/sgcs/G2.swift +3730 -0
  251. package/ios/Source/sgcs/Mach1.swift +543 -0
  252. package/ios/Source/sgcs/MentraLive.swift +4708 -0
  253. package/ios/Source/sgcs/MentraNex.swift +2479 -0
  254. package/ios/Source/sgcs/SGCManager.swift +243 -0
  255. package/ios/Source/sgcs/Simulated.swift +270 -0
  256. package/ios/Source/sgcs/mentraos_ble.pb.swift +3811 -0
  257. package/ios/Source/stt/STTTools.swift +154 -0
  258. package/ios/Source/stt/SherpaOnnxTranscriber.swift +401 -0
  259. package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
  260. package/ios/Source/utils/Constants.swift +74 -0
  261. package/ios/Source/utils/Enums.swift +95 -0
  262. package/ios/Source/utils/G1Text.swift +2067 -0
  263. package/ios/Source/utils/JSCExperiment.swift +241 -0
  264. package/ios/Source/utils/MemoryMonitor.swift +44 -0
  265. package/ios/Source/utils/MessageChunker.swift +164 -0
  266. package/ios/Source/utils/Models.swift +135 -0
  267. package/ios/Source/utils/PhoneAudioMonitor.swift +226 -0
  268. package/ios/Source/utils/TarBz2Extractor.swift +206 -0
  269. package/package.json +78 -0
  270. package/plugin/build/index.d.ts +6 -0
  271. package/plugin/build/index.js +12 -0
  272. package/plugin/build/withAndroid.d.ts +4 -0
  273. package/plugin/build/withAndroid.js +80 -0
  274. package/plugin/build/withIos.d.ts +4 -0
  275. package/plugin/build/withIos.js +64 -0
  276. package/src/BluetoothSdk.types.ts +581 -0
  277. package/src/BluetoothSdkModule.ts +259 -0
  278. package/src/index.ts +4 -0
@@ -0,0 +1,610 @@
1
+ //
2
+ // Bridge.kt
3
+ // AOS
4
+ //
5
+ // Created by Matthew Fosse on 3/4/25.
6
+ //
7
+
8
+ package com.mentra.bluetoothsdk
9
+
10
+ import android.util.Base64
11
+ import android.util.Log
12
+ import java.util.HashMap
13
+ import java.util.UUID
14
+ import kotlin.jvm.JvmStatic
15
+ import kotlin.jvm.Synchronized
16
+ import kotlin.jvm.Volatile
17
+
18
+ /**
19
+ * Bridge class for SDK communication between Expo modules and native Android code This is the
20
+ * Android equivalent of the iOS Bridge.swift
21
+ */
22
+ public class Bridge private constructor() {
23
+ private var deviceManager: DeviceManager? = null
24
+
25
+ companion object {
26
+ private const val TAG = "Bridge"
27
+
28
+ @Volatile private var instance: Bridge? = null
29
+
30
+ private const val DEFAULT_EVENT_SINK_ID = "default"
31
+
32
+ // Event sinks for JS and native consumers.
33
+ private val eventSinks = linkedMapOf<String, (String, Map<String, Any>) -> Unit>()
34
+
35
+ // Android Context for native operations
36
+ private var appContext: android.content.Context? = null
37
+
38
+ @JvmStatic
39
+ @Synchronized
40
+ fun getInstance(): Bridge {
41
+ if (instance == null) {
42
+ instance = Bridge()
43
+ }
44
+ return instance!!
45
+ }
46
+
47
+ /**
48
+ * Initialize the Bridge with event callback and context This should be called from
49
+ * BluetoothSdkModule
50
+ */
51
+ @JvmStatic
52
+ fun initialize(
53
+ context: android.content.Context,
54
+ callback: (String, Map<String, Any>) -> Unit
55
+ ) {
56
+ Log.d(TAG, "Initializing Bridge with context and event callback")
57
+ initialize(context)
58
+ setEventSink(DEFAULT_EVENT_SINK_ID, callback)
59
+ }
60
+
61
+ @JvmStatic
62
+ fun initialize(context: android.content.Context) {
63
+ appContext = context
64
+ }
65
+
66
+ @JvmStatic
67
+ @Synchronized
68
+ fun addEventSink(callback: (String, Map<String, Any>) -> Unit): String {
69
+ val id = UUID.randomUUID().toString()
70
+ setEventSink(id, callback)
71
+ return id
72
+ }
73
+
74
+ @JvmStatic
75
+ @Synchronized
76
+ fun removeEventSink(id: String) {
77
+ eventSinks.remove(id)
78
+ }
79
+
80
+ @Synchronized
81
+ private fun setEventSink(id: String, callback: (String, Map<String, Any>) -> Unit) {
82
+ eventSinks[id] = callback
83
+ }
84
+
85
+ @Synchronized
86
+ private fun getEventSinks(): List<(String, Map<String, Any>) -> Unit> {
87
+ return eventSinks.values.toList()
88
+ }
89
+
90
+ /** Get the Android context for native operations */
91
+ @JvmStatic
92
+ fun getContext(): android.content.Context {
93
+ return appContext ?: throw IllegalStateException("Bridge not initialized with context")
94
+ }
95
+
96
+ /** Log a message and send it to JavaScript */
97
+ @JvmStatic
98
+ fun log(message: String) {
99
+ val data = HashMap<String, Any>()
100
+ data["message"] = message
101
+ sendTypedMessage("log", data as Map<String, Any>)
102
+ }
103
+
104
+ /** Send head position event */
105
+ @JvmStatic
106
+ fun sendHeadUp(isUp: Boolean) {
107
+ val data = HashMap<String, Any>()
108
+ data["up"] = isUp
109
+ sendTypedMessage("head_up", data as Map<String, Any>)
110
+ }
111
+
112
+ /** Send pair failure event */
113
+ @JvmStatic
114
+ fun sendPairFailureEvent(error: String) {
115
+ val data = HashMap<String, Any>()
116
+ data["error"] = error
117
+ sendTypedMessage("pair_failure", data as Map<String, Any>)
118
+ }
119
+
120
+ /** Send audio connected event - matches iOS implementation for platform parity */
121
+ @JvmStatic
122
+ fun sendAudioConnected(deviceName: String) {
123
+ val data = HashMap<String, Any>()
124
+ data["device_name"] = deviceName
125
+ sendTypedMessage("audio_connected", data as Map<String, Any>)
126
+ }
127
+
128
+ /** Send audio disconnected event - matches iOS implementation for platform parity */
129
+ @JvmStatic
130
+ fun sendAudioDisconnected() {
131
+ val data = HashMap<String, Any>()
132
+ sendTypedMessage("audio_disconnected", data as Map<String, Any>)
133
+ }
134
+
135
+ @JvmStatic
136
+ fun sendMicPcm(data: ByteArray) {
137
+ // val base64String = Base64.encodeToString(data, Base64.NO_WRAP)
138
+ // val body = HashMap<String, Any>()
139
+ // body["base64"] = base64String
140
+ // sendTypedMessage("mic_pcm", body as Map<String, Any>)
141
+ val body = HashMap<String, Any>()
142
+ body["pcm"] = data
143
+ sendTypedMessage("mic_pcm", body as Map<String, Any>)
144
+ }
145
+
146
+ @JvmStatic
147
+ fun sendMicLc3(data: ByteArray) {
148
+ // val base64String = Base64.encodeToString(data, Base64.NO_WRAP)
149
+ // val body = HashMap<String, Any>()
150
+ // body["base64"] = base64String
151
+ // sendTypedMessage("mic_lc3", body as Map<String, Any>)
152
+ val body = HashMap<String, Any>()
153
+ body["lc3"] = data
154
+ sendTypedMessage("mic_lc3", body as Map<String, Any>)
155
+ }
156
+
157
+ /** Save a setting */
158
+ @JvmStatic
159
+ fun saveSetting(key: String, value: Any) {
160
+ val body = HashMap<String, Any>()
161
+ body["key"] = key
162
+ body["value"] = value
163
+ sendTypedMessage("save_setting", body as Map<String, Any>)
164
+ }
165
+
166
+ /** Send VAD (Voice Activity Detection) status */
167
+ @JvmStatic
168
+ fun sendVadEvent(isSpeaking: Boolean) {
169
+ val body = HashMap<String, Any>()
170
+ body["status"] = isSpeaking
171
+ sendTypedMessage("vad_status", body as Map<String, Any>)
172
+ }
173
+
174
+ /** Send battery status */
175
+ @JvmStatic
176
+ fun sendBatteryStatus(level: Int, charging: Boolean) {
177
+ val body = HashMap<String, Any>()
178
+ body["level"] = level
179
+ body["charging"] = charging
180
+ body["timestamp"] = System.currentTimeMillis()
181
+ sendTypedMessage("battery_status", body as Map<String, Any>)
182
+ }
183
+
184
+ /** Send discovered device */
185
+ @JvmStatic
186
+ @JvmOverloads
187
+ fun sendDiscoveredDevice(
188
+ deviceModel: String,
189
+ deviceName: String,
190
+ deviceAddress: String = "",
191
+ rssi: Int? = null
192
+ ) {
193
+ val searchResults =
194
+ (DeviceStore.store.getCategory("bluetooth")["searchResults"] as? List<*>)
195
+ ?.mapNotNull { result ->
196
+ (result as? Map<*, *>)?.entries
197
+ ?.mapNotNull { (key, value) ->
198
+ if (key is String && value != null) key to value else null
199
+ }
200
+ ?.toMap()
201
+ }
202
+ ?: emptyList()
203
+ val id = "$deviceModel:$deviceName"
204
+ val newResult =
205
+ buildMap<String, Any> {
206
+ put("id", id)
207
+ put("model", deviceModel)
208
+ put("name", deviceName)
209
+ if (deviceAddress.isNotBlank()) {
210
+ put("address", deviceAddress)
211
+ }
212
+ rssi?.let { put("rssi", it) }
213
+ }
214
+ val allResults = searchResults + newResult
215
+ val uniqueResults =
216
+ allResults
217
+ .asReversed()
218
+ .distinctBy {
219
+ val model = it["model"] ?: it["deviceModel"] ?: deviceModel
220
+ val name = it["name"] ?: it["deviceName"] ?: return@distinctBy null
221
+ "$model:$name"
222
+ }
223
+ .asReversed()
224
+ DeviceStore.set("bluetooth", "searchResults", uniqueResults)
225
+ }
226
+
227
+ // MARK: - Hardware Events
228
+
229
+ /** Send button press event to React Native - matches iOS implementation */
230
+ @JvmStatic
231
+ fun sendButtonPressEvent(buttonId: String, pressType: String) {
232
+ val buttonData = HashMap<String, Any>()
233
+ buttonData["buttonId"] = buttonId
234
+ buttonData["pressType"] = pressType
235
+ buttonData["timestamp"] = System.currentTimeMillis()
236
+
237
+ sendTypedMessage("button_press", buttonData as Map<String, Any>)
238
+ }
239
+
240
+ /** Send miniapp selection event from glasses dashboard menu */
241
+ @JvmStatic
242
+ fun sendMiniappSelected(packageName: String) {
243
+ val body = HashMap<String, Any>()
244
+ body["packageName"] = packageName
245
+ sendTypedMessage("miniapp_selected", body)
246
+ }
247
+
248
+ /** Send touch/gesture event from glasses - matches iOS implementation */
249
+ @JvmStatic
250
+ @JvmOverloads
251
+ fun sendTouchEvent(
252
+ deviceModel: String,
253
+ gestureName: String,
254
+ timestamp: Long,
255
+ source: Int? = null
256
+ ) {
257
+ val body = HashMap<String, Any>()
258
+ body["device_model"] = deviceModel
259
+ body["gesture_name"] = gestureName
260
+ body["timestamp"] = timestamp
261
+ if (source != null) {
262
+ body["source"] = source
263
+ }
264
+ sendTypedMessage("touch_event", body)
265
+ }
266
+
267
+ /** Send swipe volume control status - matches iOS implementation */
268
+ @JvmStatic
269
+ fun sendSwipeVolumeStatus(enabled: Boolean, timestamp: Long) {
270
+ val body = HashMap<String, Any>()
271
+ body["enabled"] = enabled
272
+ body["timestamp"] = timestamp
273
+ sendTypedMessage("swipe_volume_status", body)
274
+ }
275
+
276
+ /** Send switch status from glasses - matches iOS implementation */
277
+ @JvmStatic
278
+ fun sendSwitchStatus(switchType: Int, value: Int, timestamp: Long) {
279
+ val body = HashMap<String, Any>()
280
+ body["switch_type"] = switchType
281
+ body["switch_value"] = value
282
+ body["timestamp"] = timestamp
283
+ sendTypedMessage("switch_status", body)
284
+ }
285
+
286
+ @JvmStatic
287
+ fun sendPhotoError(requestId: String, errorCode: String, errorMessage: String) {
288
+ val event = HashMap<String, Any>()
289
+ event["type"] = "photo_response"
290
+ event["state"] = "error"
291
+ event["requestId"] = requestId
292
+ event["errorCode"] = errorCode
293
+ event["errorMessage"] = errorMessage
294
+ event["timestamp"] = System.currentTimeMillis()
295
+ sendTypedMessage("photo_response", event as Map<String, Any>)
296
+ }
297
+
298
+ /** Send RGB LED control response */
299
+ @JvmStatic
300
+ fun sendRgbLedControlResponse(requestId: String, success: Boolean, error: String?) {
301
+ if (requestId.isEmpty()) return
302
+ try {
303
+ val body = HashMap<String, Any>()
304
+ body["requestId"] = requestId
305
+ body["state"] = if (success) "success" else "error"
306
+ if (!success) {
307
+ body["errorCode"] = error ?: "unknown_error"
308
+ }
309
+ sendTypedMessage("rgb_led_control_response", body)
310
+ } catch (e: Exception) {
311
+ log("Bridge: Error sending rgb_led_control_response: $e")
312
+ }
313
+ }
314
+
315
+ /**
316
+ * Send transcription result to server Used by AOSManager to send pre-formatted
317
+ * transcription results Matches the Swift structure exactly
318
+ */
319
+ @JvmStatic
320
+ fun sendLocalTranscription(transcription: Map<String, Any>) {
321
+ val text = transcription["text"] as? String
322
+ if (text == null || text.isEmpty()) {
323
+ log("Skipping empty transcription result")
324
+ return
325
+ }
326
+
327
+ sendTypedMessage("local_transcription", transcription)
328
+ }
329
+
330
+ /** Convenience method for sending local transcription from transcriber */
331
+ @JvmStatic
332
+ fun sendLocalTranscription(text: String, isFinal: Boolean, language: String) {
333
+ if (text.isEmpty()) {
334
+ log("Skipping empty transcription result")
335
+ return
336
+ }
337
+
338
+ val transcription =
339
+ mapOf(
340
+ "text" to text,
341
+ "isFinal" to isFinal,
342
+ "language" to language,
343
+ "type" to "local_transcription"
344
+ )
345
+
346
+ sendTypedMessage("local_transcription", transcription)
347
+ }
348
+
349
+ // Bluetooth SDK bridge funcs:
350
+
351
+ /** Send status update */
352
+ @JvmStatic
353
+ fun sendStatus(statusObj: Map<String, Any>) {
354
+ val body = HashMap<String, Any>()
355
+ body["bluetooth_status"] = statusObj
356
+ sendTypedMessage("bluetooth_status_update", body as Map<String, Any>)
357
+ }
358
+
359
+ /** Send glasses serial number */
360
+ @JvmStatic
361
+ fun sendserialNumber(serialNumber: String, style: String, color: String) {
362
+ val serialData = HashMap<String, Any>()
363
+ serialData["serial_number"] = serialNumber
364
+ serialData["style"] = style
365
+ serialData["color"] = color
366
+
367
+ val body = HashMap<String, Any>()
368
+ body["glasses_serial_number"] = serialData
369
+ sendTypedMessage("glasses_serial_number", body as Map<String, Any>)
370
+ }
371
+
372
+ /** Send WiFi status change */
373
+ @JvmStatic
374
+ fun sendWifiStatusChange(connected: Boolean, ssid: String?, localIp: String?) {
375
+ val status = WifiStatus.fromStoreFields(connected, ssid, localIp) ?: return
376
+ sendTypedMessage("wifi_status_change", status.toMap())
377
+ }
378
+
379
+ /** Send WiFi scan results */
380
+ @JvmStatic
381
+ fun updateWifiScanResults(networks: List<Map<String, Any>>) {
382
+ var storedNetworks: List<Map<String, Any>> =
383
+ DeviceStore.get("bluetooth", "wifiScanResults") as? List<Map<String, Any>>
384
+ ?: emptyList()
385
+ // add the networks to the storedNetworks array, removing duplicates by ssid
386
+ val updatedNetworks = storedNetworks.toMutableList()
387
+ for (network in networks) {
388
+ if (!updatedNetworks.any { it["ssid"] as? String == network["ssid"] as? String }) {
389
+ updatedNetworks.add(network)
390
+ }
391
+ }
392
+ DeviceStore.apply("bluetooth", "wifiScanResults", updatedNetworks)
393
+ }
394
+
395
+ /** Send gallery status - matches iOS MentraLive.swift handleGalleryStatus pattern */
396
+ @JvmStatic
397
+ fun sendGalleryStatus(
398
+ photoCount: Int,
399
+ videoCount: Int,
400
+ totalCount: Int,
401
+ totalSize: Long,
402
+ hasContent: Boolean
403
+ ) {
404
+ val galleryData = HashMap<String, Any>()
405
+ galleryData["photos"] = photoCount
406
+ galleryData["videos"] = videoCount
407
+ galleryData["total"] = totalCount
408
+ galleryData["total_size"] = totalSize
409
+ galleryData["has_content"] = hasContent
410
+
411
+ sendTypedMessage("gallery_status", galleryData as Map<String, Any>)
412
+ }
413
+
414
+ /** Send hotspot status change - matches iOS MentraLive.swift emitHotspotStatusChange */
415
+ @JvmStatic
416
+ fun sendHotspotStatusChange(
417
+ enabled: Boolean,
418
+ ssid: String,
419
+ password: String,
420
+ gatewayIp: String
421
+ ) {
422
+ val status = HotspotStatus.fromStoreFields(enabled, ssid, password, gatewayIp) ?: return
423
+ sendTypedMessage("hotspot_status_change", status.toMap())
424
+ }
425
+
426
+ /** Send hotspot error - notifies React Native of hotspot failures */
427
+ @JvmStatic
428
+ fun sendHotspotError(errorMessage: String, timestamp: Long) {
429
+ val eventBody = HashMap<String, Any>()
430
+ eventBody["error_message"] = errorMessage
431
+ eventBody["timestamp"] = timestamp
432
+
433
+ sendTypedMessage("hotspot_error", eventBody as Map<String, Any>)
434
+ }
435
+
436
+ /** Send MTK firmware update complete notification - matches iOS implementation */
437
+ @JvmStatic
438
+ fun sendMtkUpdateComplete(message: String) {
439
+ val eventBody = HashMap<String, Any>()
440
+ eventBody["message"] = message
441
+ eventBody["timestamp"] = System.currentTimeMillis()
442
+ sendTypedMessage("mtk_update_complete", eventBody as Map<String, Any>)
443
+ }
444
+
445
+ /**
446
+ * Send OTA update available notification - glasses have detected an available update
447
+ * (background mode)
448
+ */
449
+ @JvmStatic
450
+ fun sendOtaUpdateAvailable(
451
+ versionCode: Long,
452
+ versionName: String,
453
+ updates: List<String>,
454
+ totalSize: Long
455
+ ) {
456
+ val eventBody = HashMap<String, Any>()
457
+ eventBody["version_code"] = versionCode
458
+ eventBody["version_name"] = versionName
459
+ eventBody["updates"] = updates
460
+ eventBody["total_size"] = totalSize
461
+
462
+ sendTypedMessage("ota_update_available", eventBody as Map<String, Any>)
463
+ }
464
+
465
+ /** Send ota_start_ack — glasses confirmed receipt of ota_start command */
466
+ @JvmStatic
467
+ fun sendOtaStartAck() {
468
+ val eventBody = HashMap<String, Any>()
469
+ eventBody["timestamp"] = System.currentTimeMillis()
470
+ sendTypedMessage("ota_start_ack", eventBody as Map<String, Any>)
471
+ }
472
+
473
+ @JvmStatic
474
+ fun sendOtaStatus(
475
+ sessionId: String,
476
+ totalSteps: Int,
477
+ currentStep: Int,
478
+ stepType: String,
479
+ phase: String,
480
+ stepPercent: Int,
481
+ overallPercent: Int,
482
+ status: String,
483
+ errorMessage: String?
484
+ ) {
485
+ val eventBody = HashMap<String, Any>()
486
+ eventBody["session_id"] = sessionId
487
+ eventBody["total_steps"] = totalSteps
488
+ eventBody["current_step"] = currentStep
489
+ eventBody["step_type"] = stepType
490
+ eventBody["phase"] = phase
491
+ eventBody["step_percent"] = stepPercent
492
+ eventBody["overall_percent"] = overallPercent
493
+ eventBody["status"] = status
494
+ errorMessage?.let { eventBody["error_message"] = it }
495
+
496
+ Log.d(TAG, "Bridge: sendOtaStatus: $eventBody")
497
+
498
+ sendTypedMessage("ota_status", eventBody as Map<String, Any>)
499
+ }
500
+
501
+ /** Send stream status - forwards to websocket system (matches iOS) */
502
+ @JvmStatic
503
+ fun sendStreamStatus(statusJson: Map<String, Any>) {
504
+ sendTypedMessage("stream_status", statusJson)
505
+ }
506
+
507
+ /** Send keep alive ACK - forwards to websocket system (matches iOS) */
508
+ @JvmStatic
509
+ fun sendKeepAliveAck(ackJson: Map<String, Any>) {
510
+ sendTypedMessage("keep_alive_ack", ackJson)
511
+ }
512
+
513
+ /** Send IMU data event - matches iOS MentraLive.swift emitImuDataEvent */
514
+ @JvmStatic
515
+ fun sendImuDataEvent(
516
+ accel: DoubleArray,
517
+ gyro: DoubleArray,
518
+ mag: DoubleArray,
519
+ quat: DoubleArray,
520
+ euler: DoubleArray,
521
+ timestamp: Long
522
+ ) {
523
+ val eventBody = HashMap<String, Any>()
524
+ eventBody["accel"] = accel.toList()
525
+ eventBody["gyro"] = gyro.toList()
526
+ eventBody["mag"] = mag.toList()
527
+ eventBody["quat"] = quat.toList()
528
+ eventBody["euler"] = euler.toList()
529
+ eventBody["timestamp"] = timestamp
530
+
531
+ sendTypedMessage("imu_data_event", eventBody as Map<String, Any>)
532
+ }
533
+
534
+ /** Send IMU gesture event - matches iOS MentraLive.swift emitImuGestureEvent */
535
+ @JvmStatic
536
+ fun sendImuGestureEvent(gesture: String, timestamp: Long) {
537
+ val eventBody = HashMap<String, Any>()
538
+ eventBody["gesture"] = gesture
539
+ eventBody["timestamp"] = timestamp
540
+
541
+ sendTypedMessage("imu_gesture_event", eventBody as Map<String, Any>)
542
+ }
543
+
544
+ // Arbitrary WS Comms (don't use these, make a dedicated function for your use case):
545
+
546
+ /** Send WebSocket text message */
547
+ @JvmStatic
548
+ fun sendWSText(msg: String) {
549
+ val data = HashMap<String, Any>()
550
+ data["text"] = msg
551
+ sendTypedMessage("ws_text", data as Map<String, Any>)
552
+ }
553
+
554
+ /** Send WebSocket binary message */
555
+ @JvmStatic
556
+ fun sendWSBinary(data: ByteArray) {
557
+ val base64String = Base64.encodeToString(data, Base64.NO_WRAP)
558
+ val body = HashMap<String, Any>()
559
+ body["base64"] = base64String
560
+ sendTypedMessage("ws_bin", body as Map<String, Any>)
561
+ }
562
+
563
+ /**
564
+ * Send a typed message to JavaScript Don't call this function directly, instead make a
565
+ * function above that calls this function
566
+ */
567
+ @JvmStatic
568
+ fun sendTypedMessage(type: String, body: Map<String, Any>) {
569
+ var mutableBody = body
570
+ if (body !is HashMap) {
571
+ mutableBody = HashMap(body)
572
+ }
573
+ (mutableBody as HashMap<String, Any>)["type"] = type
574
+
575
+ try {
576
+ val sinks = getEventSinks()
577
+ if (sinks.isEmpty()) {
578
+ Log.w(
579
+ TAG,
580
+ "Cannot send typed message '$type': no event sinks registered (app may be killed/backgrounded)"
581
+ )
582
+ return
583
+ }
584
+
585
+ // Send directly using type as event name - no JSON serialization
586
+ sinks.forEach { sink ->
587
+ try {
588
+ sink(type, mutableBody as Map<String, Any>)
589
+ } catch (e: Exception) {
590
+ Log.e(
591
+ TAG,
592
+ "Error invoking event sink for type '$type' (listener may be dead)",
593
+ e
594
+ )
595
+ // Don't rethrow - one dead listener should not break other consumers.
596
+ }
597
+ }
598
+ } catch (e: Exception) {
599
+ Log.e(TAG, "Error sending typed message of type '$type'", e)
600
+ }
601
+ }
602
+ }
603
+
604
+ init {
605
+ deviceManager = DeviceManager.Companion.getInstance()
606
+ if (deviceManager == null) {
607
+ Log.e(TAG, "Failed to initialize DeviceManager in Bridge constructor")
608
+ }
609
+ }
610
+ }