feat: update message polling to return ByteArray and enhance logging for debugging

This commit is contained in:
Nedifinita
2025-12-06 02:00:26 +08:00
parent f009d43d75
commit 8507029499
5 changed files with 49 additions and 38 deletions

View File

@@ -221,15 +221,15 @@ void decodeBatch()
alpha_bit_buffer = (alpha_bit_buffer << 20) | messageBits; alpha_bit_buffer = (alpha_bit_buffer << 20) | messageBits;
alpha_bit_buffer_bits += 20; 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; unsigned char c = (alpha_bit_buffer >> (alpha_bit_buffer_bits - 8)) & 0xff;
c = reverse(c) >> (32 - 7); c = reverse(c) >> (32 - 8);
if (c != 0 && c != 0x3 && c != 0x4) if (c != 0 && c != 0x3 && c != 0x4)
{ {
alpha_msg.push_back(c); alpha_msg.push_back(c);
} }
alpha_bit_buffer_bits -= 7; alpha_bit_buffer_bits -= 8;
if (alpha_bit_buffer_bits == 0) if (alpha_bit_buffer_bits == 0)
{ {
alpha_bit_buffer = 0; alpha_bit_buffer = 0;

View File

@@ -5,6 +5,7 @@
#include <mutex> #include <mutex>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
#include <iomanip>
#include <chrono> #include <chrono>
#include <unistd.h> #include <unistd.h>
#include <arpa/inet.h> #include <arpa/inet.h>
@@ -134,7 +135,7 @@ Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_clearMessageBuffer(JNIEnv
alpha_msg.clear(); alpha_msg.clear();
} }
extern "C" JNIEXPORT jstring JNICALL extern "C" JNIEXPORT jbyteArray JNICALL
Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_pollMessages(JNIEnv *env, jobject) Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_pollMessages(JNIEnv *env, jobject)
{ {
std::lock_guard<std::mutex> demodLock(demodDataMutex); std::lock_guard<std::mutex> demodLock(demodDataMutex);
@@ -142,13 +143,17 @@ Java_org_noxylva_lbjconsole_flutter_AudioInputHandler_pollMessages(JNIEnv *env,
if (messageBuffer.empty()) if (messageBuffer.empty())
{ {
return env->NewStringUTF(""); return env->NewByteArray(0);
} }
std::ostringstream ss; std::ostringstream ss;
for (auto &msg : messageBuffer) for (auto &msg : messageBuffer)
ss << msg << "\n"; ss << msg << "\n";
messageBuffer.clear(); 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 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; 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*/) Java_org_noxylva_lbjconsole_flutter_RtlTcpChannelHandler_pollMessages(JNIEnv *env, jobject /*this*/)
{ {
std::lock_guard<std::mutex> demodLock(demodDataMutex); std::lock_guard<std::mutex> demodLock(demodDataMutex);
@@ -166,13 +171,17 @@ Java_org_noxylva_lbjconsole_flutter_RtlTcpChannelHandler_pollMessages(JNIEnv *en
if (messageBuffer.empty()) if (messageBuffer.empty())
{ {
return env->NewStringUTF(""); return env->NewByteArray(0);
} }
std::ostringstream ss; std::ostringstream ss;
for (auto &msg : messageBuffer) for (auto &msg : messageBuffer)
ss << msg << "\n"; ss << msg << "\n";
messageBuffer.clear(); 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) void clientThread(std::string host, int port)
@@ -260,6 +269,13 @@ void clientThread(std::string host, int port)
std::ostringstream ss; std::ostringstream ss;
std::lock_guard<std::mutex> msgLock(msgMutex); std::lock_guard<std::mutex> 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; std::string message_content;
if (function_bits == 3) { if (function_bits == 3) {
message_content = alpha_msg; message_content = alpha_msg;

View File

@@ -51,7 +51,7 @@ class AudioInputHandler(private val context: Context) : MethodChannel.MethodCall
} }
private external fun nativePushAudio(data: ShortArray, size: Int) private external fun nativePushAudio(data: ShortArray, size: Int)
private external fun pollMessages(): String private external fun pollMessages(): ByteArray
private external fun clearMessageBuffer() private external fun clearMessageBuffer()
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { 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 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 regex = "\\[MSG\\]\\s*(\\d+)\\|(-?\\d+)\\|(.*)".toRegex()
val statusMap = mutableMapOf<String, Any?>() val statusMap = mutableMapOf<String, Any?>()
@@ -106,10 +107,7 @@ class AudioInputHandler(private val context: Context) : MethodChannel.MethodCall
val dataMap = mutableMapOf<String, Any?>() val dataMap = mutableMapOf<String, Any?>()
dataMap["address"] = match.groupValues[1] dataMap["address"] = match.groupValues[1]
dataMap["func"] = match.groupValues[2] dataMap["func"] = match.groupValues[2]
dataMap["numeric"] = match.groupValues[3]
val gbkBytes = match.groupValues[3].toByteArray(Charsets.ISO_8859_1)
val utf8String = String(gbkBytes, Charset.forName("GBK"))
dataMap["numeric"] = utf8String
eventSink?.success(dataMap) eventSink?.success(dataMap)
} catch (e: Exception) { } catch (e: Exception) {

View File

@@ -10,7 +10,7 @@ import java.nio.charset.Charset
class RtlTcpChannelHandler : EventChannel.StreamHandler { class RtlTcpChannelHandler : EventChannel.StreamHandler {
private external fun startClientAsync(host: String, port: String) 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 nativeStopClient()
private external fun getSignalStrength(): Double private external fun getSignalStrength(): Double
private external fun isConnected(): Boolean private external fun isConnected(): Boolean
@@ -92,21 +92,22 @@ class RtlTcpChannelHandler : EventChannel.StreamHandler {
0.0 0.0
} }
val logs = try { val logsBytes = try {
pollMessages() pollMessages()
} catch (e: Exception) { } catch (e: Exception) {
android.util.Log.e("RTL-TCP", "pollMessages() failed", e) 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 (logsBytes.isNotEmpty()) {
if (logs.isNotEmpty()) { val preview = if (logsBytes.size > 200) "${logsBytes.size} bytes" else logsBytes.contentToString()
val preview = if (logs.length > 1000) logs.substring(0, 1000) + "..." else logs android.util.Log.d("RTL-TCP", "pollBytes: $preview")
android.util.Log.d("RTL-TCP", "pollLogs: $preview")
} }
val logs = if (logsBytes.isNotEmpty()) String(logsBytes, Charsets.ISO_8859_1) else ""
if (connected != lastConnectedState) { if (connected != lastConnectedState) {
val statusMap = mutableMapOf<String, Any?>() val statusMap = mutableMapOf<String, Any?>()
statusMap["connected"] = connected statusMap["connected"] = connected
@@ -124,23 +125,12 @@ class RtlTcpChannelHandler : EventChannel.StreamHandler {
try { try {
val addr = match.groupValues[1] val addr = match.groupValues[1]
val func = match.groupValues[2] val func = match.groupValues[2]
val raw = match.groupValues[3] val content = 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 dataMap = mutableMapOf<String, Any?>() val dataMap = mutableMapOf<String, Any?>()
dataMap["address"] = addr dataMap["address"] = addr
dataMap["func"] = func dataMap["func"] = func
dataMap["numeric"] = utf8String dataMap["numeric"] = content
dataMap["magsqRaw"] = strength dataMap["magsqRaw"] = strength
try { try {

View File

@@ -64,8 +64,13 @@ class _LbJState {
String _gbkToUtf8(List<int> gbkBytes) { String _gbkToUtf8(List<int> gbkBytes) {
try { try {
final validBytes = gbkBytes.where((b) => b != 0).toList(); 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) { } catch (e) {
print('gbk decode error: $e');
return ""; return "";
} }
} }
@@ -99,6 +104,8 @@ class _LbJState {
String buffer = numeric; String buffer = numeric;
if (buffer.length < 50) return; if (buffer.length < 50) return;
_info2Hex = _recodeBCD(buffer); _info2Hex = _recodeBCD(buffer);
print('info2 raw: $buffer');
print('info2 hex: $_info2Hex');
if (_info2Hex.length >= 4) { if (_info2Hex.length >= 4) {
try { try {