@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.
- package/README.md +278 -0
- package/android/build.gradle +167 -0
- package/android/lc3Lib/CMakeLists.txt +6 -0
- package/android/lc3Lib/build.gradle +109 -0
- package/android/lc3Lib/proguard-rules.pro +33 -0
- package/android/lc3Lib/src/main/AndroidManifest.xml +2 -0
- package/android/lc3Lib/src/main/cpp/CMakeLists.txt +8 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/CMakeLists.txt +30 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/CMakeLists.txt +7 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.cc +96 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/jni/ogg_opus_encoder.h +53 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/Makefile.am +6 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/config_types.h.in +26 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/ogg.h +209 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libogg/os_types.h +158 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus.h +981 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_custom.h +342 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_defines.h +799 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_multistream.h +660 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_projection.h +568 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/libopus/opus_types.h +166 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.cc +268 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/ogg_opus_encoder.h +115 -0
- package/android/lc3Lib/src/main/cpp/google_opus_stuff/opus_tools/opus_header.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/CMakeLists.txt +38 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3.h +309 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/lc3_private.h +162 -0
- package/android/lc3Lib/src/main/cpp/liblc3/include/rnnoise.h +114 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/CMakeLists.txt +19 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.c +92 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/attdet.h +44 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.c +375 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bits.h +315 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.c +129 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/bwdet.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/common.h +148 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.c +70 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/energy.h +43 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/fastmath.h +158 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/lc3.c +702 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.c +893 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf.h +111 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_arm.h +506 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/ltpf_neon.h +281 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/makefile.mk +35 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.c +452 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/mdct_neon.h +296 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/meson.build +46 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.c +61 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/plc.h +57 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.c +880 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/sns.h +103 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.c +904 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/spec.h +119 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.c +3457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tables.h +94 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.c +457 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3/tns.h +99 -0
- package/android/lc3Lib/src/main/cpp/liblc3/liblc3.cpp +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/_kiss_fft_guts.h +182 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/arch.h +261 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.c +279 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/celt_lpc.h +59 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/common.h +48 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/compile.sh +3 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/denoise.c +646 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.c +601 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/kiss_fft.h +203 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/opus_types.h +159 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.c +526 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/pitch.h +149 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.c +178 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn.h +69 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.c +11051 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_data.h +34 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_reader.c +168 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/rnn_train.py +66 -0
- package/android/lc3Lib/src/main/cpp/liblc3/rnnoise/tansig_table.h +45 -0
- package/android/lc3Lib/src/main/java/com/mentra/lc3Lib/Lc3Cpp.java +38 -0
- package/android/lc3Lib/third_party/CMakeLists.txt +23 -0
- package/android/lc3Lib/third_party/CMakeLists_libogg.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_libopus.txt +18 -0
- package/android/lc3Lib/third_party/CMakeLists_opus-tools.txt +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/AUTHORS +5 -0
- package/android/lc3Lib/third_party/opus_tools/src/CMakeLists.txt +4 -0
- package/android/lc3Lib/third_party/opus_tools/src/COPYING +371 -0
- package/android/lc3Lib/third_party/opus_tools/src/ChangeLog +3 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.am +42 -0
- package/android/lc3Lib/third_party/opus_tools/src/Makefile.unix +23 -0
- package/android/lc3Lib/third_party/opus_tools/src/NEWS +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/README +0 -0
- package/android/lc3Lib/third_party/opus_tools/src/autogen.sh +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/configure.ac +293 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/arch.h +239 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/audio-in.c +1046 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.c +245 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/diag_range.h +28 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.c +320 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/info_opus.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.c +157 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/lpc.h +27 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.c +286 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opus_header.h +59 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusdec.c +884 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.c +1021 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusenc.h +101 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.c +639 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/opusinfo.h +51 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/os_support.h +167 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/resample.c +1137 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/speex_resampler.h +344 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/stack_alloc.h +115 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.c +125 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wav_io.h +62 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.c +223 -0
- package/android/lc3Lib/third_party/opus_tools/src/src/wave_out.h +60 -0
- package/android/settings.gradle +1 -0
- package/android/src/main/AndroidManifest.xml +40 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/BluetoothSdkModule.kt +528 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/Bridge.kt +610 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceManager.kt +1616 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/DeviceStore.kt +314 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothModels.kt +1710 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/MentraBluetoothSdk.kt +554 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/ObservableStore.kt +68 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/ControllerManager.kt +158 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/controllers/R1.kt +934 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/Foreground.kt +175 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/services/PhoneMic.kt +1109 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G1.java +3974 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/G2.kt +3551 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Mach1.java +1327 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraLive.java +6959 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraNex.kt +1655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/MentraosBle.java +53675 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/SGCManager.kt +202 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/sgcs/Simulated.kt +224 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/STTTools.kt +340 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/SherpaOnnxTranscriber.kt +465 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/stt/VadGateSpeechPolicy.kt +221 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AES.java +106 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/AudioSessionMonitor.kt +189 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BitmapJavaUtils.java +169 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/BlePhotoUploadService.java +179 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/Constants.kt +44 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/G1Text.kt +436 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleRelayNaming.java +29 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/IncidentLogBleUploadService.java +76 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/K900ProtocolUtils.java +791 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/MessageChunker.java +186 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/NexSGCUtils.kt +589 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/PhoneAudioMonitor.kt +303 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/SmartGlassesConnectionState.java +9 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/ByteUtilAudioPlayer.java +655 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/Lc3Player.java +441 -0
- package/android/src/main/java/com/mentra/bluetoothsdk/utils/audio/PCMAudioPlayer.java +431 -0
- package/android/src/main/res/values/strings.xml +4 -0
- package/app.plugin.js +1 -0
- package/build/BluetoothSdk.types.d.ts +498 -0
- package/build/BluetoothSdk.types.d.ts.map +1 -0
- package/build/BluetoothSdk.types.js +23 -0
- package/build/BluetoothSdk.types.js.map +1 -0
- package/build/BluetoothSdkModule.d.ts +71 -0
- package/build/BluetoothSdkModule.d.ts.map +1 -0
- package/build/BluetoothSdkModule.js +106 -0
- package/build/BluetoothSdkModule.js.map +1 -0
- package/build/index.d.ts +3 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +5 -0
- package/build/index.js.map +1 -0
- package/expo-module.config.json +9 -0
- package/ios/BluetoothSdkModule.swift +665 -0
- package/ios/MentraBluetoothSDK.podspec +77 -0
- package/ios/Packages/CoreObjC/CoreObjC.xcodeproj/project.pbxproj +213 -0
- package/ios/Packages/CoreObjC/PcmConverter.h +22 -0
- package/ios/Packages/CoreObjC/PcmConverter.m +266 -0
- package/ios/Packages/CoreObjC/attdet.c +92 -0
- package/ios/Packages/CoreObjC/attdet.h +44 -0
- package/ios/Packages/CoreObjC/bits.c +375 -0
- package/ios/Packages/CoreObjC/bits.h +315 -0
- package/ios/Packages/CoreObjC/bwdet.c +129 -0
- package/ios/Packages/CoreObjC/bwdet.h +69 -0
- package/ios/Packages/CoreObjC/common.h +151 -0
- package/ios/Packages/CoreObjC/energy.c +70 -0
- package/ios/Packages/CoreObjC/energy.h +43 -0
- package/ios/Packages/CoreObjC/fastmath.h +158 -0
- package/ios/Packages/CoreObjC/lc3.c +704 -0
- package/ios/Packages/CoreObjC/lc3.h +313 -0
- package/ios/Packages/CoreObjC/lc3_cpp.h +283 -0
- package/ios/Packages/CoreObjC/lc3_private.h +163 -0
- package/ios/Packages/CoreObjC/ltpf.c +905 -0
- package/ios/Packages/CoreObjC/ltpf.h +111 -0
- package/ios/Packages/CoreObjC/ltpf_arm.h +506 -0
- package/ios/Packages/CoreObjC/ltpf_neon.h +281 -0
- package/ios/Packages/CoreObjC/makefile.mk +35 -0
- package/ios/Packages/CoreObjC/mdct.c +469 -0
- package/ios/Packages/CoreObjC/mdct.h +57 -0
- package/ios/Packages/CoreObjC/mdct_neon.h +296 -0
- package/ios/Packages/CoreObjC/meson.build +61 -0
- package/ios/Packages/CoreObjC/plc.c +61 -0
- package/ios/Packages/CoreObjC/plc.h +57 -0
- package/ios/Packages/CoreObjC/rnnoise.h +114 -0
- package/ios/Packages/CoreObjC/sns.c +880 -0
- package/ios/Packages/CoreObjC/sns.h +103 -0
- package/ios/Packages/CoreObjC/spec.c +907 -0
- package/ios/Packages/CoreObjC/spec.h +119 -0
- package/ios/Packages/CoreObjC/tables.c +3457 -0
- package/ios/Packages/CoreObjC/tables.h +94 -0
- package/ios/Packages/CoreObjC/tns.c +457 -0
- package/ios/Packages/CoreObjC/tns.h +99 -0
- package/ios/Packages/SherpaOnnx/Model/joiner.onnx +0 -0
- package/ios/Packages/SherpaOnnx/Model/tokens.txt +502 -0
- package/ios/Packages/SherpaOnnx/SherpaOnnx.swift +1659 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/cargs.h +162 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/c-api.h +1852 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Headers/sherpa-onnx/c-api/cxx-api.h +674 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/Info.plist +44 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64/sherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/libsherpa-onnx.a +0 -0
- package/ios/Packages/SherpaOnnx/sherpa-onnx.xcframework/ios-arm64_x86_64-simulator/sherpa-onnx.a +0 -0
- package/ios/Packages/VAD/Common/VAD/VADQuality.swift +41 -0
- package/ios/Packages/VAD/Common/VAD/VADState.swift +26 -0
- package/ios/Packages/VAD/Common/VAD/VADStrategy.swift +29 -0
- package/ios/Packages/VAD/Common/VAD/VADType.swift +14 -0
- package/ios/Packages/VAD/Data/Configuration.swift +68 -0
- package/ios/Packages/VAD/Data/FrameSize.swift +39 -0
- package/ios/Packages/VAD/Data/Record.swift +13 -0
- package/ios/Packages/VAD/Data/Result.swift +22 -0
- package/ios/Packages/VAD/Data/SampleRate.swift +48 -0
- package/ios/Packages/VAD/Silero/Model/silero_vad.onnx +0 -0
- package/ios/Packages/VAD/Silero/SileroVAD.swift +284 -0
- package/ios/Packages/VAD/Silero/SileroVADStrategy.swift +64 -0
- package/ios/Packages/libbz2/module.modulemap +5 -0
- package/ios/Packages/libbz2/shim.h +1 -0
- package/ios/Source/Bridge.swift +353 -0
- package/ios/Source/Bridging-Header.h +16 -0
- package/ios/Source/DeviceManager.swift +1478 -0
- package/ios/Source/DeviceStore.swift +295 -0
- package/ios/Source/MentraBluetoothSDK.swift +2439 -0
- package/ios/Source/ObservableStore.swift +88 -0
- package/ios/Source/PrivacyInfo.xcprivacy +23 -0
- package/ios/Source/controllers/ControllerManager.swift +187 -0
- package/ios/Source/controllers/R1.swift +827 -0
- package/ios/Source/services/PhoneMic.swift +662 -0
- package/ios/Source/sgcs/Frame.swift +651 -0
- package/ios/Source/sgcs/G1.swift +2505 -0
- package/ios/Source/sgcs/G2.swift +3730 -0
- package/ios/Source/sgcs/Mach1.swift +543 -0
- package/ios/Source/sgcs/MentraLive.swift +4708 -0
- package/ios/Source/sgcs/MentraNex.swift +2479 -0
- package/ios/Source/sgcs/SGCManager.swift +243 -0
- package/ios/Source/sgcs/Simulated.swift +270 -0
- package/ios/Source/sgcs/mentraos_ble.pb.swift +3811 -0
- package/ios/Source/stt/STTTools.swift +154 -0
- package/ios/Source/stt/SherpaOnnxTranscriber.swift +401 -0
- package/ios/Source/utils/AudioSessionMonitor.swift +283 -0
- package/ios/Source/utils/Constants.swift +74 -0
- package/ios/Source/utils/Enums.swift +95 -0
- package/ios/Source/utils/G1Text.swift +2067 -0
- package/ios/Source/utils/JSCExperiment.swift +241 -0
- package/ios/Source/utils/MemoryMonitor.swift +44 -0
- package/ios/Source/utils/MessageChunker.swift +164 -0
- package/ios/Source/utils/Models.swift +135 -0
- package/ios/Source/utils/PhoneAudioMonitor.swift +226 -0
- package/ios/Source/utils/TarBz2Extractor.swift +206 -0
- package/package.json +78 -0
- package/plugin/build/index.d.ts +6 -0
- package/plugin/build/index.js +12 -0
- package/plugin/build/withAndroid.d.ts +4 -0
- package/plugin/build/withAndroid.js +80 -0
- package/plugin/build/withIos.d.ts +4 -0
- package/plugin/build/withIos.js +64 -0
- package/src/BluetoothSdk.types.ts +581 -0
- package/src/BluetoothSdkModule.ts +259 -0
- package/src/index.ts +4 -0
|
@@ -0,0 +1,436 @@
|
|
|
1
|
+
package com.mentra.bluetoothsdk.utils
|
|
2
|
+
|
|
3
|
+
class G1Text {
|
|
4
|
+
companion object {
|
|
5
|
+
// Constants for text wall display
|
|
6
|
+
private const val TEXT_COMMAND: Byte = 0x4E // Text command
|
|
7
|
+
private const val DISPLAY_WIDTH = 488
|
|
8
|
+
private const val DISPLAY_USE_WIDTH = 488 // How much of the display to use
|
|
9
|
+
private const val FONT_MULTIPLIER: Float = 1 / 50.0f
|
|
10
|
+
private const val OLD_FONT_SIZE = 21 // Font size
|
|
11
|
+
private const val FONT_DIVIDER: Float = 2.0f
|
|
12
|
+
private const val LINES_PER_SCREEN = 5 // Lines per screen
|
|
13
|
+
private const val MAX_CHUNK_SIZE = 176 // Maximum chunk size for BLE packets
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
private var textSeqNum = 0 // Sequence number for text packets
|
|
17
|
+
private val fontLoader = G1FontLoaderKt()
|
|
18
|
+
|
|
19
|
+
// Calculate text width in pixels
|
|
20
|
+
fun calculateTextWidth(text: String): Int {
|
|
21
|
+
var width = 0
|
|
22
|
+
for (char in text) {
|
|
23
|
+
val glyph = fontLoader.getGlyph(char)
|
|
24
|
+
width += glyph.width + 1 // Add 1 pixel per character for spacing
|
|
25
|
+
}
|
|
26
|
+
return width * 2
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
private fun calculateSubstringWidth(text: String, start: Int, end: Int): Int {
|
|
30
|
+
val substring = text.substring(start, end)
|
|
31
|
+
return calculateTextWidth(substring)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
private fun calculateSpacesForAlignment(currentWidth: Int, targetPosition: Int, spaceWidth: Int): Int {
|
|
35
|
+
// Calculate space needed in pixels
|
|
36
|
+
val pixelsNeeded = targetPosition - currentWidth
|
|
37
|
+
|
|
38
|
+
// Calculate spaces needed (with minimum of 1 space for separation)
|
|
39
|
+
if (pixelsNeeded <= 0) {
|
|
40
|
+
return 1 // Ensure at least one space between columns
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Calculate the exact number of spaces needed
|
|
44
|
+
val spaces = Math.ceil(pixelsNeeded.toDouble() / spaceWidth.toDouble()).toInt()
|
|
45
|
+
|
|
46
|
+
// Cap at a reasonable maximum
|
|
47
|
+
return Math.min(spaces, 100)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fun splitIntoLines(text: String, maxDisplayWidth: Int): List<String> {
|
|
51
|
+
// Replace specific symbols
|
|
52
|
+
val processedText = text.replace("⬆", "^").replace("⟶", "-")
|
|
53
|
+
|
|
54
|
+
val lines = mutableListOf<String>()
|
|
55
|
+
|
|
56
|
+
// Handle empty or single space case
|
|
57
|
+
if (processedText.isEmpty() || processedText == " ") {
|
|
58
|
+
lines.add(processedText)
|
|
59
|
+
return lines
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Split by newlines first
|
|
63
|
+
val rawLines = processedText.split("\n")
|
|
64
|
+
|
|
65
|
+
for (rawLine in rawLines) {
|
|
66
|
+
// Add empty lines for newlines
|
|
67
|
+
if (rawLine.isEmpty()) {
|
|
68
|
+
lines.add("")
|
|
69
|
+
continue
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
val lineLength = rawLine.length
|
|
73
|
+
var startIndex = 0
|
|
74
|
+
|
|
75
|
+
while (startIndex < lineLength) {
|
|
76
|
+
// Get maximum possible end index
|
|
77
|
+
val endIndex = lineLength
|
|
78
|
+
|
|
79
|
+
// Calculate width of the entire remaining text
|
|
80
|
+
val lineWidth = calculateSubstringWidth(rawLine, startIndex, endIndex)
|
|
81
|
+
|
|
82
|
+
// If entire line fits, add it and move to next line
|
|
83
|
+
if (lineWidth <= maxDisplayWidth) {
|
|
84
|
+
lines.add(rawLine.substring(startIndex))
|
|
85
|
+
break
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Binary search to find the maximum number of characters that fit
|
|
89
|
+
var left = startIndex + 1
|
|
90
|
+
var right = lineLength
|
|
91
|
+
var bestSplitIndex = startIndex + 1
|
|
92
|
+
|
|
93
|
+
while (left <= right) {
|
|
94
|
+
val mid = left + (right - left) / 2
|
|
95
|
+
val width = calculateSubstringWidth(rawLine, startIndex, mid)
|
|
96
|
+
|
|
97
|
+
if (width <= maxDisplayWidth) {
|
|
98
|
+
bestSplitIndex = mid
|
|
99
|
+
left = mid + 1
|
|
100
|
+
} else {
|
|
101
|
+
right = mid - 1
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Now find a good place to break (preferably at a space)
|
|
106
|
+
var splitIndex = bestSplitIndex
|
|
107
|
+
|
|
108
|
+
// Look for a space to break at
|
|
109
|
+
var foundSpace = false
|
|
110
|
+
for (i in bestSplitIndex downTo startIndex + 1) {
|
|
111
|
+
if (i > 0 && rawLine[i - 1] == ' ') {
|
|
112
|
+
splitIndex = i
|
|
113
|
+
foundSpace = true
|
|
114
|
+
break
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// If we couldn't find a space in a reasonable range, use the calculated split point
|
|
119
|
+
if (!foundSpace && bestSplitIndex - startIndex > 2) {
|
|
120
|
+
splitIndex = bestSplitIndex
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Add the line
|
|
124
|
+
val line = rawLine.substring(startIndex, splitIndex).trim()
|
|
125
|
+
lines.add(line)
|
|
126
|
+
|
|
127
|
+
// Skip any spaces at the beginning of the next line
|
|
128
|
+
var newStartIndex = splitIndex
|
|
129
|
+
while (newStartIndex < lineLength && rawLine[newStartIndex] == ' ') {
|
|
130
|
+
newStartIndex++
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
startIndex = newStartIndex
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return lines
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
fun createTextWallChunks(text: String): List<ByteArray> {
|
|
141
|
+
val margin = 5
|
|
142
|
+
|
|
143
|
+
// Get width of single space character
|
|
144
|
+
val spaceWidth = calculateTextWidth(" ")
|
|
145
|
+
|
|
146
|
+
// Calculate effective display width after accounting for left and right margins in spaces
|
|
147
|
+
val marginWidth = margin * spaceWidth // Width of left margin in pixels
|
|
148
|
+
val effectiveWidth = DISPLAY_WIDTH - (2 * marginWidth) // Subtract left and right margins
|
|
149
|
+
|
|
150
|
+
// Split text into lines based on effective display width
|
|
151
|
+
val lines = splitIntoLines(text, effectiveWidth)
|
|
152
|
+
|
|
153
|
+
// Calculate total pages (hard set to 1 - 1PAGECHANGE)
|
|
154
|
+
val totalPages = 1
|
|
155
|
+
|
|
156
|
+
val allChunks = mutableListOf<ByteArray>()
|
|
157
|
+
|
|
158
|
+
// Process each page
|
|
159
|
+
for (page in 0 until totalPages) {
|
|
160
|
+
// Get lines for current page
|
|
161
|
+
val startLine = page * LINES_PER_SCREEN
|
|
162
|
+
val endLine = Math.min(startLine + LINES_PER_SCREEN, lines.size)
|
|
163
|
+
val pageLines = lines.subList(startLine, endLine)
|
|
164
|
+
|
|
165
|
+
// Combine lines for this page with proper indentation
|
|
166
|
+
val pageText = StringBuilder()
|
|
167
|
+
|
|
168
|
+
for (line in pageLines) {
|
|
169
|
+
// Add the exact number of spaces for indentation
|
|
170
|
+
val indentation = " ".repeat(margin)
|
|
171
|
+
pageText.append("$indentation$line\n")
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
val textBytes = pageText.toString().toByteArray(Charsets.UTF_8)
|
|
175
|
+
val totalChunks = Math.ceil(textBytes.size.toDouble() / MAX_CHUNK_SIZE.toDouble()).toInt()
|
|
176
|
+
|
|
177
|
+
// Create chunks for this page
|
|
178
|
+
for (i in 0 until totalChunks) {
|
|
179
|
+
val start = i * MAX_CHUNK_SIZE
|
|
180
|
+
val end = Math.min(start + MAX_CHUNK_SIZE, textBytes.size)
|
|
181
|
+
val payloadChunk = textBytes.copyOfRange(start, end)
|
|
182
|
+
|
|
183
|
+
// Create header with protocol specifications
|
|
184
|
+
val screenStatus: Byte = 0x71 // New content (0x01) + Text Show (0x70)
|
|
185
|
+
val header = byteArrayOf(
|
|
186
|
+
TEXT_COMMAND, // Command type
|
|
187
|
+
textSeqNum.toByte(), // Sequence number
|
|
188
|
+
totalChunks.toByte(), // Total packages
|
|
189
|
+
i.toByte(), // Current package number
|
|
190
|
+
screenStatus, // Screen status
|
|
191
|
+
0x00, // new_char_pos0 (high)
|
|
192
|
+
0x00, // new_char_pos1 (low)
|
|
193
|
+
page.toByte(), // Current page number
|
|
194
|
+
totalPages.toByte() // Max page number
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
// Combine header and payload
|
|
198
|
+
val chunk = header + payloadChunk
|
|
199
|
+
|
|
200
|
+
allChunks.add(chunk)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Increment sequence number for next page
|
|
204
|
+
textSeqNum = (textSeqNum + 1) % 256
|
|
205
|
+
break // Hard set to 1 - 1PAGECHANGE
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return allChunks
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Creates BLE chunks for pre-composed double text wall.
|
|
213
|
+
*
|
|
214
|
+
* NOTE: DisplayProcessor now composes double_text_wall into a single text_wall
|
|
215
|
+
* with pixel-precise column alignment using ColumnComposer. This method may
|
|
216
|
+
* not be called anymore for new flows, but is kept for backwards compatibility.
|
|
217
|
+
*
|
|
218
|
+
* Column composition is handled by DisplayProcessor in React Native.
|
|
219
|
+
* This method is a "dumb pipe" - it just combines and chunks the text.
|
|
220
|
+
*
|
|
221
|
+
* @param textTop Pre-composed left/top column text
|
|
222
|
+
* @param textBottom Pre-composed right/bottom column text
|
|
223
|
+
* @return List of BLE chunks ready for transmission
|
|
224
|
+
*/
|
|
225
|
+
fun createDoubleTextWallChunks(textTop: String, textBottom: String): List<ByteArray> {
|
|
226
|
+
// Text is already composed by DisplayProcessor's ColumnComposer
|
|
227
|
+
// Just combine and chunk for transmission - no custom wrapping logic needed
|
|
228
|
+
val combinedText = "$textTop\n$textBottom"
|
|
229
|
+
return chunkTextForTransmission(combinedText)
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private fun chunkTextForTransmission(text: String): List<ByteArray> {
|
|
233
|
+
val textBytes = text.toByteArray(Charsets.UTF_8)
|
|
234
|
+
val totalChunks = Math.ceil(textBytes.size.toDouble() / MAX_CHUNK_SIZE.toDouble()).toInt()
|
|
235
|
+
|
|
236
|
+
val allChunks = mutableListOf<ByteArray>()
|
|
237
|
+
for (i in 0 until totalChunks) {
|
|
238
|
+
val start = i * MAX_CHUNK_SIZE
|
|
239
|
+
val end = Math.min(start + MAX_CHUNK_SIZE, textBytes.size)
|
|
240
|
+
val payloadChunk = textBytes.copyOfRange(start, end)
|
|
241
|
+
|
|
242
|
+
// Create header with protocol specifications
|
|
243
|
+
val screenStatus: Byte = 0x71 // New content (0x01) + Text Show (0x70)
|
|
244
|
+
val header = byteArrayOf(
|
|
245
|
+
TEXT_COMMAND, // Command type
|
|
246
|
+
textSeqNum.toByte(), // Sequence number
|
|
247
|
+
totalChunks.toByte(), // Total packages
|
|
248
|
+
i.toByte(), // Current package number
|
|
249
|
+
screenStatus, // Screen status
|
|
250
|
+
0x00, // new_char_pos0 (high)
|
|
251
|
+
0x00, // new_char_pos1 (low)
|
|
252
|
+
0x00, // Current page number (always 0 for now)
|
|
253
|
+
0x01 // Max page number (always 1)
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
// Combine header and payload
|
|
257
|
+
val chunk = header + payloadChunk
|
|
258
|
+
|
|
259
|
+
allChunks.add(chunk)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Increment sequence number for next page
|
|
263
|
+
textSeqNum = (textSeqNum + 1) % 256
|
|
264
|
+
|
|
265
|
+
return allChunks
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Font loader with hardcoded font data
|
|
270
|
+
class G1FontLoaderKt {
|
|
271
|
+
private val fontMap: MutableMap<Char, FontGlyph> = mutableMapOf()
|
|
272
|
+
|
|
273
|
+
init {
|
|
274
|
+
loadHardcodedFontData()
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
private fun loadHardcodedFontData() {
|
|
278
|
+
// Hardcoded font data based on the Swift implementation
|
|
279
|
+
val hardcodedGlyphs = listOf(
|
|
280
|
+
GlyphData(32, ' ', 2, 26),
|
|
281
|
+
GlyphData(33, '!', 1, 26),
|
|
282
|
+
GlyphData(34, '"', 2, 26),
|
|
283
|
+
GlyphData(35, '#', 6, 26),
|
|
284
|
+
GlyphData(36, '$', 5, 26),
|
|
285
|
+
GlyphData(37, '%', 6, 26),
|
|
286
|
+
GlyphData(38, '&', 7, 26),
|
|
287
|
+
GlyphData(39, '\'', 1, 26),
|
|
288
|
+
GlyphData(40, '(', 2, 26),
|
|
289
|
+
GlyphData(41, ')', 2, 26),
|
|
290
|
+
GlyphData(42, '*', 3, 26),
|
|
291
|
+
GlyphData(43, '+', 4, 26),
|
|
292
|
+
GlyphData(44, ',', 1, 26),
|
|
293
|
+
GlyphData(45, '-', 4, 26),
|
|
294
|
+
GlyphData(46, '.', 1, 26),
|
|
295
|
+
GlyphData(47, '/', 3, 26),
|
|
296
|
+
GlyphData(48, '0', 5, 26),
|
|
297
|
+
GlyphData(49, '1', 3, 26),
|
|
298
|
+
GlyphData(50, '2', 5, 26),
|
|
299
|
+
GlyphData(51, '3', 5, 26),
|
|
300
|
+
GlyphData(52, '4', 5, 26),
|
|
301
|
+
GlyphData(53, '5', 5, 26),
|
|
302
|
+
GlyphData(54, '6', 5, 26),
|
|
303
|
+
GlyphData(55, '7', 5, 26),
|
|
304
|
+
GlyphData(56, '8', 5, 26),
|
|
305
|
+
GlyphData(57, '9', 5, 26),
|
|
306
|
+
GlyphData(58, ':', 1, 26),
|
|
307
|
+
GlyphData(59, ';', 1, 26),
|
|
308
|
+
GlyphData(60, '<', 4, 26),
|
|
309
|
+
GlyphData(61, '=', 4, 26),
|
|
310
|
+
GlyphData(62, '>', 4, 26),
|
|
311
|
+
GlyphData(63, '?', 5, 26),
|
|
312
|
+
GlyphData(64, '@', 7, 26),
|
|
313
|
+
GlyphData(65, 'A', 6, 26),
|
|
314
|
+
GlyphData(66, 'B', 5, 26),
|
|
315
|
+
GlyphData(67, 'C', 5, 26),
|
|
316
|
+
GlyphData(68, 'D', 5, 26),
|
|
317
|
+
GlyphData(69, 'E', 4, 26),
|
|
318
|
+
GlyphData(70, 'F', 4, 26),
|
|
319
|
+
GlyphData(71, 'G', 5, 26),
|
|
320
|
+
GlyphData(72, 'H', 5, 26),
|
|
321
|
+
GlyphData(73, 'I', 2, 26),
|
|
322
|
+
GlyphData(74, 'J', 3, 26),
|
|
323
|
+
GlyphData(75, 'K', 5, 26),
|
|
324
|
+
GlyphData(76, 'L', 4, 26),
|
|
325
|
+
GlyphData(77, 'M', 7, 26),
|
|
326
|
+
GlyphData(78, 'N', 5, 26),
|
|
327
|
+
GlyphData(79, 'O', 5, 26),
|
|
328
|
+
GlyphData(80, 'P', 5, 26),
|
|
329
|
+
GlyphData(81, 'Q', 5, 26),
|
|
330
|
+
GlyphData(82, 'R', 5, 26),
|
|
331
|
+
GlyphData(83, 'S', 5, 26),
|
|
332
|
+
GlyphData(84, 'T', 5, 26),
|
|
333
|
+
GlyphData(85, 'U', 5, 26),
|
|
334
|
+
GlyphData(86, 'V', 6, 26),
|
|
335
|
+
GlyphData(87, 'W', 7, 26),
|
|
336
|
+
GlyphData(88, 'X', 6, 26),
|
|
337
|
+
GlyphData(89, 'Y', 6, 26),
|
|
338
|
+
GlyphData(90, 'Z', 5, 26),
|
|
339
|
+
GlyphData(91, '[', 2, 26),
|
|
340
|
+
GlyphData(92, '\\', 3, 26),
|
|
341
|
+
GlyphData(93, ']', 2, 26),
|
|
342
|
+
GlyphData(94, '^', 4, 26),
|
|
343
|
+
GlyphData(95, '_', 3, 26),
|
|
344
|
+
GlyphData(96, '`', 2, 26),
|
|
345
|
+
GlyphData(97, 'a', 5, 26),
|
|
346
|
+
GlyphData(98, 'b', 4, 26),
|
|
347
|
+
GlyphData(99, 'c', 4, 26),
|
|
348
|
+
GlyphData(100, 'd', 4, 26),
|
|
349
|
+
GlyphData(101, 'e', 4, 26),
|
|
350
|
+
GlyphData(102, 'f', 4, 26),
|
|
351
|
+
GlyphData(103, 'g', 4, 26),
|
|
352
|
+
GlyphData(104, 'h', 4, 26),
|
|
353
|
+
GlyphData(105, 'i', 1, 26),
|
|
354
|
+
GlyphData(106, 'j', 2, 26),
|
|
355
|
+
GlyphData(107, 'k', 4, 26),
|
|
356
|
+
GlyphData(108, 'l', 1, 26),
|
|
357
|
+
GlyphData(109, 'm', 7, 26),
|
|
358
|
+
GlyphData(110, 'n', 4, 26),
|
|
359
|
+
GlyphData(111, 'o', 4, 26),
|
|
360
|
+
GlyphData(112, 'p', 4, 26),
|
|
361
|
+
GlyphData(113, 'q', 4, 26),
|
|
362
|
+
GlyphData(114, 'r', 3, 26),
|
|
363
|
+
GlyphData(115, 's', 4, 26),
|
|
364
|
+
GlyphData(116, 't', 3, 26),
|
|
365
|
+
GlyphData(117, 'u', 5, 26),
|
|
366
|
+
GlyphData(118, 'v', 5, 26),
|
|
367
|
+
GlyphData(119, 'w', 7, 26),
|
|
368
|
+
GlyphData(120, 'x', 5, 26),
|
|
369
|
+
GlyphData(121, 'y', 5, 26),
|
|
370
|
+
GlyphData(122, 'z', 4, 26),
|
|
371
|
+
GlyphData(123, '{', 3, 26),
|
|
372
|
+
GlyphData(124, '|', 1, 26),
|
|
373
|
+
GlyphData(125, '}', 3, 26),
|
|
374
|
+
GlyphData(126, '~', 7, 26),
|
|
375
|
+
GlyphData(192, 'À', 6, 26),
|
|
376
|
+
GlyphData(194, 'Â', 6, 26),
|
|
377
|
+
GlyphData(199, 'Ç', 5, 26),
|
|
378
|
+
GlyphData(200, 'È', 4, 26),
|
|
379
|
+
GlyphData(201, 'É', 4, 26),
|
|
380
|
+
GlyphData(202, 'Ê', 4, 26),
|
|
381
|
+
GlyphData(203, 'Ë', 4, 26),
|
|
382
|
+
GlyphData(206, 'Î', 3, 26),
|
|
383
|
+
GlyphData(207, 'Ï', 3, 26),
|
|
384
|
+
GlyphData(212, 'Ô', 5, 26),
|
|
385
|
+
GlyphData(217, 'Ù', 5, 26),
|
|
386
|
+
GlyphData(219, 'Û', 5, 26),
|
|
387
|
+
GlyphData(220, 'Ü', 5, 26),
|
|
388
|
+
GlyphData(224, 'à', 5, 26),
|
|
389
|
+
GlyphData(231, 'ç', 4, 26),
|
|
390
|
+
GlyphData(232, 'è', 4, 26),
|
|
391
|
+
GlyphData(233, 'é', 4, 26),
|
|
392
|
+
GlyphData(234, 'ê', 4, 26),
|
|
393
|
+
GlyphData(235, 'ë', 4, 26),
|
|
394
|
+
GlyphData(238, 'î', 3, 26),
|
|
395
|
+
GlyphData(239, 'ï', 3, 26),
|
|
396
|
+
GlyphData(244, 'ô', 4, 26),
|
|
397
|
+
GlyphData(249, 'ù', 5, 26),
|
|
398
|
+
GlyphData(251, 'û', 5, 26),
|
|
399
|
+
GlyphData(252, 'ü', 5, 26),
|
|
400
|
+
GlyphData(255, 'ÿ', 5, 26),
|
|
401
|
+
GlyphData(376, 'Ÿ', 6, 26),
|
|
402
|
+
GlyphData(196, 'Ä', 6, 26),
|
|
403
|
+
GlyphData(228, 'ä', 5, 26),
|
|
404
|
+
GlyphData(214, 'Ö', 5, 26),
|
|
405
|
+
GlyphData(246, 'ö', 4, 26),
|
|
406
|
+
GlyphData(223, 'ß', 4, 26),
|
|
407
|
+
GlyphData(7838, 'ẞ', 5, 26),
|
|
408
|
+
GlyphData(226, 'â', 5, 26),
|
|
409
|
+
GlyphData(193, 'Á', 6, 26),
|
|
410
|
+
GlyphData(225, 'á', 5, 26),
|
|
411
|
+
GlyphData(205, 'Í', 2, 26),
|
|
412
|
+
GlyphData(237, 'í', 2, 26),
|
|
413
|
+
GlyphData(209, 'Ñ', 5, 26),
|
|
414
|
+
GlyphData(241, 'ñ', 4, 26),
|
|
415
|
+
GlyphData(250, 'ú', 5, 26),
|
|
416
|
+
GlyphData(211, 'Ó', 5, 26),
|
|
417
|
+
GlyphData(243, 'ó', 4, 26),
|
|
418
|
+
GlyphData(218, 'Ú', 5, 26)
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
// Map characters directly to FontGlyph objects
|
|
422
|
+
for (glyph in hardcodedGlyphs) {
|
|
423
|
+
fontMap[glyph.char] = FontGlyph(glyph.width, glyph.height)
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
println("Hardcoded font data loaded successfully! ${fontMap.size} glyphs mapped.")
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
fun getGlyph(character: Char): FontGlyph {
|
|
430
|
+
return fontMap[character] ?: FontGlyph(6, 26) // Default width=6, height=26
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
data class FontGlyph(val width: Int, val height: Int)
|
|
434
|
+
|
|
435
|
+
private data class GlyphData(val codePoint: Int, val char: Char, val width: Int, val height: Int)
|
|
436
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
package com.mentra.bluetoothsdk.utils;
|
|
2
|
+
|
|
3
|
+
import java.util.Locale;
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 16-byte K900 file name for incident log payloads relayed over BLE (must match ASG
|
|
7
|
+
* {@code IncidentLogBleRelayNaming}).
|
|
8
|
+
*/
|
|
9
|
+
public final class IncidentLogBleRelayNaming {
|
|
10
|
+
|
|
11
|
+
private static final int SUFFIX_LEN = 15;
|
|
12
|
+
|
|
13
|
+
private IncidentLogBleRelayNaming() {}
|
|
14
|
+
|
|
15
|
+
public static String bleFileBaseName(String incidentId, char prefix) {
|
|
16
|
+
if (incidentId == null || incidentId.isEmpty()) {
|
|
17
|
+
return prefix + "000000000000000";
|
|
18
|
+
}
|
|
19
|
+
String compact = incidentId.replace("-", "").toLowerCase(Locale.US);
|
|
20
|
+
if (compact.length() < SUFFIX_LEN) {
|
|
21
|
+
StringBuilder sb = new StringBuilder(compact);
|
|
22
|
+
while (sb.length() < SUFFIX_LEN) {
|
|
23
|
+
sb.append('0');
|
|
24
|
+
}
|
|
25
|
+
compact = sb.toString();
|
|
26
|
+
}
|
|
27
|
+
return prefix + compact.substring(0, SUFFIX_LEN);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
package com.mentra.bluetoothsdk.utils;
|
|
2
|
+
|
|
3
|
+
import android.util.Log;
|
|
4
|
+
|
|
5
|
+
import java.io.IOException;
|
|
6
|
+
import java.util.concurrent.TimeUnit;
|
|
7
|
+
|
|
8
|
+
import okhttp3.HttpUrl;
|
|
9
|
+
import okhttp3.MediaType;
|
|
10
|
+
import okhttp3.OkHttpClient;
|
|
11
|
+
import okhttp3.Request;
|
|
12
|
+
import okhttp3.RequestBody;
|
|
13
|
+
import okhttp3.Response;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* POSTs incident log JSON (from BLE relay) using the same path as glasses direct upload.
|
|
17
|
+
*/
|
|
18
|
+
public final class IncidentLogBleUploadService {
|
|
19
|
+
|
|
20
|
+
private static final String TAG = "IncidentLogBleUpload";
|
|
21
|
+
|
|
22
|
+
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
|
23
|
+
|
|
24
|
+
private IncidentLogBleUploadService() {}
|
|
25
|
+
|
|
26
|
+
public interface Callback {
|
|
27
|
+
void onDone(boolean success, String message);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public static void upload(String apiBaseUrl, String incidentId, String authToken,
|
|
31
|
+
byte[] jsonUtf8, Callback callback) {
|
|
32
|
+
new Thread(() -> {
|
|
33
|
+
try {
|
|
34
|
+
if (authToken == null || authToken.isEmpty()) {
|
|
35
|
+
callback.onDone(false, "no auth token");
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
HttpUrl baseHttpUrl = HttpUrl.parse(apiBaseUrl != null ? apiBaseUrl.trim() : "");
|
|
39
|
+
if (baseHttpUrl == null) {
|
|
40
|
+
callback.onDone(false, "empty or malformed api base url");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
HttpUrl url = baseHttpUrl.newBuilder()
|
|
44
|
+
.addPathSegment("api")
|
|
45
|
+
.addPathSegment("incidents")
|
|
46
|
+
.addPathSegment(incidentId)
|
|
47
|
+
.addPathSegment("logs")
|
|
48
|
+
.build();
|
|
49
|
+
RequestBody body = RequestBody.create(jsonUtf8, JSON);
|
|
50
|
+
OkHttpClient client = new OkHttpClient.Builder()
|
|
51
|
+
.connectTimeout(20, TimeUnit.SECONDS)
|
|
52
|
+
.writeTimeout(60, TimeUnit.SECONDS)
|
|
53
|
+
.readTimeout(60, TimeUnit.SECONDS)
|
|
54
|
+
.build();
|
|
55
|
+
Request request = new Request.Builder()
|
|
56
|
+
.url(url)
|
|
57
|
+
.header("Authorization", "Bearer " + authToken)
|
|
58
|
+
.post(body)
|
|
59
|
+
.build();
|
|
60
|
+
try (Response response = client.newCall(request).execute()) {
|
|
61
|
+
if (response.isSuccessful()) {
|
|
62
|
+
Log.i(TAG, "Incident BLE relay upload OK: " + url);
|
|
63
|
+
callback.onDone(true, null);
|
|
64
|
+
} else {
|
|
65
|
+
String msg = "HTTP " + response.code();
|
|
66
|
+
Log.e(TAG, "Incident BLE relay upload failed: " + msg + " " + url);
|
|
67
|
+
callback.onDone(false, msg);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
} catch (IOException e) {
|
|
71
|
+
Log.e(TAG, "Incident BLE relay upload IO error", e);
|
|
72
|
+
callback.onDone(false, e.getMessage());
|
|
73
|
+
}
|
|
74
|
+
}).start();
|
|
75
|
+
}
|
|
76
|
+
}
|