From 85070294999eccf93c34ec0399b8cb0146b71abe Mon Sep 17 00:00:00 2001 From: Nedifinita Date: Sat, 6 Dec 2025 02:00:26 +0800 Subject: [PATCH] feat: update message polling to return ByteArray and enhance logging for debugging --- android/app/src/main/cpp/demod.cpp | 8 ++--- android/app/src/main/cpp/native-lib.cpp | 28 ++++++++++++---- .../lbjconsole/flutter/AudioInputHandler.kt | 10 +++--- .../flutter/RtlTcpChannelHandler.kt | 32 +++++++------------ lib/services/rtl_tcp_service.dart | 9 +++++- 5 files changed, 49 insertions(+), 38 deletions(-) diff --git a/android/app/src/main/cpp/demod.cpp b/android/app/src/main/cpp/demod.cpp index 99809f7..e6946a4 100644 --- a/android/app/src/main/cpp/demod.cpp +++ b/android/app/src/main/cpp/demod.cpp @@ -221,15 +221,15 @@ void decodeBatch() alpha_bit_buffer = (alpha_bit_buffer << 20) | messageBits; alpha_bit_buffer_bits += 20; - while (alpha_bit_buffer_bits >= 7) + while (alpha_bit_buffer_bits >= 8) { - char c = (alpha_bit_buffer >> (alpha_bit_buffer_bits - 7)) & 0x7f; - c = reverse(c) >> (32 - 7); + unsigned char c = (alpha_bit_buffer >> (alpha_bit_buffer_bits - 8)) & 0xff; + c = reverse(c) >> (32 - 8); if (c != 0 && c != 0x3 && c != 0x4) { alpha_msg.push_back(c); } - alpha_bit_buffer_bits -= 7; + alpha_bit_buffer_bits -= 8; if (alpha_bit_buffer_bits == 0) { alpha_bit_buffer = 0; diff --git a/android/app/src/main/cpp/native-lib.cpp b/android/app/src/main/cpp/native-lib.cpp index 3407ac2..8f9e473 100644 --- a/android/app/src/main/cpp/native-lib.cpp +++ b/android/app/src/main/cpp/native-lib.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -134,7 +135,7 @@ Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_clearMessageBuffer(JNIEnv alpha_msg.clear(); } -extern "C" JNIEXPORT jstring JNICALL +extern "C" JNIEXPORT jbyteArray JNICALL Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_pollMessages(JNIEnv *env, jobject) { std::lock_guard demodLock(demodDataMutex); @@ -142,13 +143,17 @@ Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_pollMessages(JNIEnv *env, if (messageBuffer.empty()) { - return env->NewStringUTF(""); + return env->NewByteArray(0); } std::ostringstream ss; for (auto &msg : messageBuffer) ss << msg << "\n"; messageBuffer.clear(); - return env->NewStringUTF(ss.str().c_str()); + + std::string result = ss.str(); + jbyteArray byteArray = env->NewByteArray(result.size()); + env->SetByteArrayRegion(byteArray, 0, result.size(), (const jbyte*)result.c_str()); + return byteArray; } extern "C" JNIEXPORT jboolean JNICALL @@ -157,7 +162,7 @@ Java_org_noxylva_lbjconsole_flutter_RtlTcpChannelHandler_isConnected(JNIEnv *, j return (running && sockfd_atomic.load() >= 0) ? JNI_TRUE : JNI_FALSE; } -extern "C" JNIEXPORT jstring JNICALL +extern "C" JNIEXPORT jbyteArray JNICALL Java_org_noxylva_lbjconsole_flutter_RtlTcpChannelHandler_pollMessages(JNIEnv *env, jobject /*this*/) { std::lock_guard demodLock(demodDataMutex); @@ -166,13 +171,17 @@ Java_org_noxylva_lbjconsole_flutter_RtlTcpChannelHandler_pollMessages(JNIEnv *en if (messageBuffer.empty()) { - return env->NewStringUTF(""); + return env->NewByteArray(0); } std::ostringstream ss; for (auto &msg : messageBuffer) ss << msg << "\n"; messageBuffer.clear(); - return env->NewStringUTF(ss.str().c_str()); + + std::string result = ss.str(); + jbyteArray byteArray = env->NewByteArray(result.size()); + env->SetByteArrayRegion(byteArray, 0, result.size(), (const jbyte*)result.c_str()); + return byteArray; } void clientThread(std::string host, int port) @@ -260,6 +269,13 @@ void clientThread(std::string host, int port) std::ostringstream ss; std::lock_guard msgLock(msgMutex); + std::ostringstream alpha_hex; + for (unsigned char ch : alpha_msg) { + alpha_hex << std::hex << std::uppercase << (int)ch << ","; + } + __android_log_print(ANDROID_LOG_DEBUG, "RTL-TCP", "alpha_msg_bytes: %s", alpha_hex.str().c_str()); + __android_log_print(ANDROID_LOG_DEBUG, "RTL-TCP", "numeric_msg: %s func=%d", numeric_msg.c_str(), function_bits); + std::string message_content; if (function_bits == 3) { message_content = alpha_msg; diff --git a/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/AudioInputHandler.kt b/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/AudioInputHandler.kt index 8befba0..af98509 100644 --- a/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/AudioInputHandler.kt +++ b/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/AudioInputHandler.kt @@ -51,7 +51,7 @@ class AudioInputHandler(private val context: Context) : MethodChannel.MethodCall } private external fun nativePushAudio(data: ShortArray, size: Int) - private external fun pollMessages(): String + private external fun pollMessages(): ByteArray private external fun clearMessageBuffer() override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { @@ -93,7 +93,8 @@ class AudioInputHandler(private val context: Context) : MethodChannel.MethodCall } val recording = isRecording.get() - val logs = pollMessages() + val logsBytes = pollMessages() + val logs = if (logsBytes.isNotEmpty()) String(logsBytes, Charsets.ISO_8859_1) else "" val regex = "\\[MSG\\]\\s*(\\d+)\\|(-?\\d+)\\|(.*)".toRegex() val statusMap = mutableMapOf() @@ -106,10 +107,7 @@ class AudioInputHandler(private val context: Context) : MethodChannel.MethodCall val dataMap = mutableMapOf() dataMap["address"] = match.groupValues[1] dataMap["func"] = match.groupValues[2] - - val gbkBytes = match.groupValues[3].toByteArray(Charsets.ISO_8859_1) - val utf8String = String(gbkBytes, Charset.forName("GBK")) - dataMap["numeric"] = utf8String + dataMap["numeric"] = match.groupValues[3] eventSink?.success(dataMap) } catch (e: Exception) { diff --git a/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/RtlTcpChannelHandler.kt b/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/RtlTcpChannelHandler.kt index a796d25..1793893 100644 --- a/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/RtlTcpChannelHandler.kt +++ b/android/app/src/main/kotlin/org/noxylva/lbjconsole/flutter/RtlTcpChannelHandler.kt @@ -10,7 +10,7 @@ import java.nio.charset.Charset class RtlTcpChannelHandler : EventChannel.StreamHandler { private external fun startClientAsync(host: String, port: String) - private external fun pollMessages(): String + private external fun pollMessages(): ByteArray private external fun nativeStopClient() private external fun getSignalStrength(): Double private external fun isConnected(): Boolean @@ -92,20 +92,21 @@ class RtlTcpChannelHandler : EventChannel.StreamHandler { 0.0 } - val logs = try { + val logsBytes = try { pollMessages() } catch (e: Exception) { android.util.Log.e("RTL-TCP", "pollMessages() failed", e) - "" + ByteArray(0) } - val regex = "\\[MSG\\]\\s*(\\d+)\\|(-?\\d+)\\|(.*)".toRegex() + val regex = "\\[MSG\\]\\s*(\\d+)\\|(-?\\d+)\\|([^\\n]*)".toRegex() - android.util.Log.d("RTL-TCP", "poll: connected=$connected magsqRaw=$strength logsLen=${logs.length}") - if (logs.isNotEmpty()) { - val preview = if (logs.length > 1000) logs.substring(0, 1000) + "..." else logs - android.util.Log.d("RTL-TCP", "pollLogs: $preview") + if (logsBytes.isNotEmpty()) { + val preview = if (logsBytes.size > 200) "${logsBytes.size} bytes" else logsBytes.contentToString() + android.util.Log.d("RTL-TCP", "pollBytes: $preview") } + + val logs = if (logsBytes.isNotEmpty()) String(logsBytes, Charsets.ISO_8859_1) else "" if (connected != lastConnectedState) { val statusMap = mutableMapOf() @@ -124,23 +125,12 @@ class RtlTcpChannelHandler : EventChannel.StreamHandler { try { val addr = match.groupValues[1] val func = match.groupValues[2] - val raw = match.groupValues[3] - android.util.Log.d("RTL-TCP", "msg_match: addr=$addr func=$func raw_len=${raw.length}") - - val gbkBytes = raw.toByteArray(Charsets.ISO_8859_1) - val utf8String = try { - String(gbkBytes, Charset.forName("GBK")) - } catch (e: Exception) { - android.util.Log.e("RTL-TCP", "GBK decode failed", e) - raw - } - - android.util.Log.d("RTL-TCP", "msg_decoded: addr=$addr func=$func numeric=$utf8String") + val content = match.groupValues[3] val dataMap = mutableMapOf() dataMap["address"] = addr dataMap["func"] = func - dataMap["numeric"] = utf8String + dataMap["numeric"] = content dataMap["magsqRaw"] = strength try { diff --git a/lib/services/rtl_tcp_service.dart b/lib/services/rtl_tcp_service.dart index fdfb2bf..700b4a7 100644 --- a/lib/services/rtl_tcp_service.dart +++ b/lib/services/rtl_tcp_service.dart @@ -64,8 +64,13 @@ class _LbJState { String _gbkToUtf8(List gbkBytes) { try { final validBytes = gbkBytes.where((b) => b != 0).toList(); - return gbk.decode(validBytes); + print('gbkBytes: ${validBytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join(',')}'); + + final result = gbk_bytes.decode(validBytes); + print('gbk decoded: $result'); + return result; } catch (e) { + print('gbk decode error: $e'); return ""; } } @@ -99,6 +104,8 @@ class _LbJState { String buffer = numeric; if (buffer.length < 50) return; _info2Hex = _recodeBCD(buffer); + print('info2 raw: $buffer'); + print('info2 hex: $_info2Hex'); if (_info2Hex.length >= 4) { try {