mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-09 02:03:24 +10:00
Merge branch 'main' into feature/usb
This commit is contained in:
@@ -2311,7 +2311,7 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
case pushCodeNewAdvert:
|
||||
debugPrint('Got New CONTACT');
|
||||
// It's the same format as respCodeContact, so we can reuse the handler
|
||||
_handleContact(frame);
|
||||
_handleContact(frame, isContact: false);
|
||||
break;
|
||||
case respCodeContact:
|
||||
debugPrint('Got CONTACT');
|
||||
@@ -2660,7 +2660,7 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void _handleContact(Uint8List frame) {
|
||||
void _handleContact(Uint8List frame, {bool isContact = true}) {
|
||||
final contact = Contact.fromFrame(frame);
|
||||
if (contact != null) {
|
||||
if (contact.type == advTypeRepeater) {
|
||||
@@ -2699,11 +2699,23 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
tag: 'Connector',
|
||||
);
|
||||
} else {
|
||||
_contacts.add(contact);
|
||||
appLogger.info(
|
||||
'Added new contact ${contact.name}: pathLen=${contact.pathLength}',
|
||||
tag: 'Connector',
|
||||
);
|
||||
if ((_autoAddUsers && contact.type == advTypeChat) ||
|
||||
(_autoAddRepeaters && contact.type == advTypeRepeater) ||
|
||||
(_autoAddRoomServers && contact.type == advTypeRoom) ||
|
||||
(_autoAddSensors && contact.type == advTypeSensor) ||
|
||||
isContact) {
|
||||
_contacts.add(contact);
|
||||
appLogger.info(
|
||||
'Added new contact ${contact.name}: pathLen=${contact.pathLength}',
|
||||
tag: 'Connector',
|
||||
);
|
||||
} else {
|
||||
appLogger.info(
|
||||
"Discovered contact ${contact.name} (type ${contact.typeLabel}) not added due to auto-add settings",
|
||||
tag: 'Connector',
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
_knownContactKeys.add(contact.publicKeyHex);
|
||||
_loadMessagesForContact(contact.publicKeyHex);
|
||||
@@ -4275,44 +4287,40 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
|
||||
void _handleRxData(Uint8List frame) {
|
||||
final packet = BufferReader(frame);
|
||||
double snr = 0.0;
|
||||
int routeType = 0;
|
||||
int payloadType = 0;
|
||||
Uint8List pathBytes = Uint8List(0);
|
||||
Uint8List payload = Uint8List(0);
|
||||
try {
|
||||
packet.skipBytes(1); // Skip frame type byte
|
||||
snr = packet.readInt8() / 4.0;
|
||||
final snr = packet.readInt8() / 4.0;
|
||||
packet.skipBytes(1); // Skip RSSI byte
|
||||
//final rssi = packet.readByte();
|
||||
final header = packet.readByte();
|
||||
routeType = header & 0x03;
|
||||
payloadType = (header >> 2) & 0x0F;
|
||||
final routeType = header & 0x03;
|
||||
final payloadType = (header >> 2) & 0x0F;
|
||||
if (routeType == _routeTransportFlood ||
|
||||
routeType == _routeTransportDirect) {
|
||||
packet.skipBytes(4); // Skip transport-specific bytes
|
||||
}
|
||||
//final payloadVer = (header >> 6) & 0x03;
|
||||
final pathLen = packet.readByte();
|
||||
pathBytes = packet.readBytes(pathLen);
|
||||
payload = packet.readBytes(packet.remaining);
|
||||
final pathBytes = packet.readBytes(pathLen);
|
||||
final payload = packet.readBytes(packet.remaining);
|
||||
|
||||
final rawPacket = frame.sublist(3);
|
||||
switch (payloadType) {
|
||||
case payloadTypeADVERT:
|
||||
_handlePayloadAdvertReceived(
|
||||
rawPacket,
|
||||
payload,
|
||||
pathBytes,
|
||||
routeType,
|
||||
snr,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
} catch (e) {
|
||||
appLogger.warn('Malformed RX frame: $e', tag: 'Connector');
|
||||
return;
|
||||
}
|
||||
final rawPacket = frame.sublist(3);
|
||||
switch (payloadType) {
|
||||
case payloadTypeADVERT:
|
||||
_handlePayloadAdvertReceived(
|
||||
rawPacket,
|
||||
payload,
|
||||
pathBytes,
|
||||
routeType,
|
||||
snr,
|
||||
);
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
|
||||
void importContact(Uint8List frame) {
|
||||
@@ -4379,7 +4387,7 @@ class MeshCoreConnector extends ChangeNotifier {
|
||||
publicKey: publicKey,
|
||||
name: name,
|
||||
type: type,
|
||||
pathLength: pathBytes.length,
|
||||
pathLength: pathBytes.isEmpty ? -1 : pathBytes.length,
|
||||
path: Uint8List.fromList(
|
||||
pathBytes.reversed.toList(),
|
||||
), // Store path in reverse for easier use in outgoing messages
|
||||
|
||||
@@ -4,6 +4,7 @@ import 'dart:typed_data';
|
||||
// Buffer Reader - sequential binary data reader with pointer tracking
|
||||
class BufferReader {
|
||||
int _pointer = 0;
|
||||
int _lastPointer = 0;
|
||||
final Uint8List _buffer;
|
||||
|
||||
BufferReader(Uint8List data) : _buffer = Uint8List.fromList(data);
|
||||
@@ -13,6 +14,7 @@ class BufferReader {
|
||||
int readByte() => readBytes(1)[0];
|
||||
|
||||
Uint8List readBytes(int count) {
|
||||
_lastPointer = _pointer;
|
||||
if (_pointer + count > _buffer.length) {
|
||||
throw RangeError(
|
||||
'Attempted to read $count bytes at offset $_pointer, but only $remaining bytes remaining in buffer of length ${_buffer.length}',
|
||||
@@ -24,6 +26,7 @@ class BufferReader {
|
||||
}
|
||||
|
||||
void skipBytes(int count) {
|
||||
_lastPointer = _pointer;
|
||||
if (_pointer + count > _buffer.length) {
|
||||
throw RangeError(
|
||||
'Attempted to skip $count bytes at offset $_pointer, but only $remaining bytes remaining in buffer of length ${_buffer.length}',
|
||||
@@ -35,6 +38,7 @@ class BufferReader {
|
||||
Uint8List readRemainingBytes() => readBytes(remaining);
|
||||
|
||||
String readString() {
|
||||
_lastPointer = _pointer;
|
||||
final value = readRemainingBytes();
|
||||
try {
|
||||
return utf8.decode(Uint8List.fromList(value), allowMalformed: true);
|
||||
@@ -43,7 +47,8 @@ class BufferReader {
|
||||
}
|
||||
}
|
||||
|
||||
String readCString(int maxLength) {
|
||||
String readCStringGreedy(int maxLength) {
|
||||
_lastPointer = _pointer;
|
||||
final value = <int>[];
|
||||
final bytes = readBytes(maxLength);
|
||||
for (final byte in bytes) {
|
||||
@@ -57,6 +62,24 @@ class BufferReader {
|
||||
}
|
||||
}
|
||||
|
||||
String readCString(int maxLength) {
|
||||
final backupPointer = _pointer;
|
||||
final value = <int>[];
|
||||
int counter = 0;
|
||||
while (counter < maxLength) {
|
||||
final byte = readByte();
|
||||
if (byte == 0) break;
|
||||
value.add(byte);
|
||||
counter++;
|
||||
}
|
||||
_lastPointer = backupPointer;
|
||||
try {
|
||||
return utf8.decode(Uint8List.fromList(value), allowMalformed: true);
|
||||
} catch (e) {
|
||||
return String.fromCharCodes(value); // Latin-1 fallback
|
||||
}
|
||||
}
|
||||
|
||||
int readUInt8() => readBytes(1).buffer.asByteData().getUint8(0);
|
||||
int readInt8() => readBytes(1).buffer.asByteData().getInt8(0);
|
||||
int readUInt16LE() =>
|
||||
@@ -78,6 +101,9 @@ class BufferReader {
|
||||
if ((value & 0x800000) != 0) value -= 0x1000000;
|
||||
return value;
|
||||
}
|
||||
|
||||
void resetPointer() => _pointer = 0;
|
||||
void rewind() => _pointer = _lastPointer;
|
||||
}
|
||||
|
||||
// Buffer Writer - accumulating binary data builder
|
||||
|
||||
Reference in New Issue
Block a user