feat: update message polling to return ByteArray and enhance logging for debugging
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user