mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Upgrade flutter packages and limit
This commit is contained in:
@@ -11,7 +11,6 @@ import 'voice_provider.dart';
|
||||
import 'image_provider.dart' as ip;
|
||||
import 'helpers/fragment_ack_wait_registry.dart';
|
||||
import 'helpers/session_metadata_restore.dart';
|
||||
import '../services/tile_cache_service.dart';
|
||||
import '../services/location_tracking_service.dart';
|
||||
import '../services/packet_capture_storage_service.dart';
|
||||
import '../models/contact.dart';
|
||||
@@ -24,6 +23,7 @@ import '../utils/voice_message_parser.dart';
|
||||
import '../utils/image_message_parser.dart';
|
||||
import '../utils/media_swarm_protocol.dart';
|
||||
import '../utils/message_airtime_estimator.dart';
|
||||
import '../utils/fast_gps_packet.dart';
|
||||
|
||||
/// Main App Provider - coordinates all other providers
|
||||
class AppProvider with ChangeNotifier {
|
||||
@@ -35,7 +35,6 @@ class AppProvider with ChangeNotifier {
|
||||
final ChannelsProvider channelsProvider;
|
||||
final VoiceProvider voiceProvider;
|
||||
final ip.ImageProvider imageProvider;
|
||||
final TileCacheService tileCacheService;
|
||||
final LocationTrackingService locationTrackingService =
|
||||
LocationTrackingService();
|
||||
final PacketCaptureStorageService packetCaptureStorageService =
|
||||
@@ -79,6 +78,7 @@ class AppProvider with ChangeNotifier {
|
||||
final Map<String, Future<bool>> _pendingMediaSwarmFetches = {};
|
||||
final Map<String, Map<String, MediaSwarmAvailability>>
|
||||
_pendingMediaSwarmResponses = {};
|
||||
bool _fastLocationScreenActive = false;
|
||||
Timer? _packetCaptureFlushTimer;
|
||||
String? _lastPersistedPacketSignature;
|
||||
bool _isPersistingPacketCapture = false;
|
||||
@@ -91,10 +91,8 @@ class AppProvider with ChangeNotifier {
|
||||
required this.channelsProvider,
|
||||
required this.voiceProvider,
|
||||
required this.imageProvider,
|
||||
required this.tileCacheService,
|
||||
}) {
|
||||
_setupCallbacks();
|
||||
_initializeTileCache();
|
||||
_initializeLocationTracking();
|
||||
_loadSimpleMode();
|
||||
_loadMapEnabled();
|
||||
@@ -436,16 +434,6 @@ class AppProvider with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize tile cache service
|
||||
Future<void> _initializeTileCache() async {
|
||||
try {
|
||||
await tileCacheService.initialize();
|
||||
debugPrint('Tile cache initialized');
|
||||
} catch (e) {
|
||||
debugPrint('Error initializing tile cache: $e');
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize location tracking service
|
||||
Future<void> _initializeLocationTracking() async {
|
||||
try {
|
||||
@@ -473,6 +461,10 @@ class AppProvider with ChangeNotifier {
|
||||
);
|
||||
};
|
||||
|
||||
locationTrackingService.onFastLocationUpdate = (position, reason) {
|
||||
unawaited(_sendFastLocationUpdate(position, reason: reason));
|
||||
};
|
||||
|
||||
debugPrint('✅ [AppProvider] Location tracking service initialized');
|
||||
} catch (e) {
|
||||
debugPrint('❌ [AppProvider] Error initializing location tracking: $e');
|
||||
@@ -836,6 +828,18 @@ class AppProvider with ChangeNotifier {
|
||||
// Magic 0x69 'i' = image fetch request; 0x56 'V' = voice packet.
|
||||
// Magic 0x49 'I' = image packet.
|
||||
connectionProvider.onRawDataReceived = (payload, snrRaw, rssiDbm) {
|
||||
final fastGpsPacket = FastGpsPacket.tryParseBinary(payload);
|
||||
if (fastGpsPacket != null) {
|
||||
final sender = _resolveContactByPrefixHex(fastGpsPacket.senderKey6);
|
||||
if (sender != null) {
|
||||
contactsProvider.updateFastGps(
|
||||
sender.publicKey.sublist(0, 6),
|
||||
fastGpsPacket,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final rawProbeRequest = RawRouteProbeRequest.tryParseBinary(payload);
|
||||
if (rawProbeRequest != null) {
|
||||
debugPrint(
|
||||
@@ -1382,6 +1386,46 @@ class AppProvider with ChangeNotifier {
|
||||
return contactsProvider.findContactByPrefixHex(prefixHex.toLowerCase());
|
||||
}
|
||||
|
||||
void setFastLocationUiActive(bool isActive) {
|
||||
if (_fastLocationScreenActive == isActive) return;
|
||||
_fastLocationScreenActive = isActive;
|
||||
locationTrackingService.setFastLocationActiveUse(isActive);
|
||||
}
|
||||
|
||||
Future<void> _sendFastLocationUpdate(
|
||||
dynamic position, {
|
||||
required String reason,
|
||||
}) async {
|
||||
if (!connectionProvider.deviceInfo.isConnected) {
|
||||
return;
|
||||
}
|
||||
|
||||
final publicKey = connectionProvider.deviceInfo.publicKey;
|
||||
if (publicKey == null || publicKey.length < 6) {
|
||||
return;
|
||||
}
|
||||
|
||||
final senderKey6 = publicKey
|
||||
.sublist(0, 6)
|
||||
.map((b) => b.toRadixString(16).padLeft(2, '0'))
|
||||
.join();
|
||||
final packet = FastGpsPacket(
|
||||
senderKey6: senderKey6,
|
||||
latitude: position.latitude as double,
|
||||
longitude: position.longitude as double,
|
||||
timestampSeconds: DateTime.now().millisecondsSinceEpoch ~/ 1000,
|
||||
);
|
||||
debugPrint(
|
||||
'📍 [AppProvider] Sending fast GPS update ($reason): '
|
||||
'${position.latitude}, ${position.longitude}',
|
||||
);
|
||||
try {
|
||||
await connectionProvider.sendRawPrivateMulticast(packet.encodeBinary());
|
||||
} catch (e) {
|
||||
debugPrint('⚠️ [AppProvider] Fast GPS send failed: $e');
|
||||
}
|
||||
}
|
||||
|
||||
Contact? _resolveVoiceFetchRequester(VoiceFetchRequest request) {
|
||||
final liveContact = _resolveContactByPrefixHex(request.requesterKey6);
|
||||
if (liveContact != null) {
|
||||
@@ -2294,6 +2338,7 @@ class AppProvider with ChangeNotifier {
|
||||
locationTrackingService.onBroadcastSent = null;
|
||||
locationTrackingService.onError = null;
|
||||
locationTrackingService.onTrackingStateChanged = null;
|
||||
locationTrackingService.onFastLocationUpdate = null;
|
||||
// Dispose the location tracking service to stop GPS stream and clean up resources
|
||||
locationTrackingService.dispose();
|
||||
for (final timer in _voiceMissingRetryTimers.values) {
|
||||
|
||||
@@ -1290,6 +1290,19 @@ class ConnectionProvider with ChangeNotifier {
|
||||
);
|
||||
}
|
||||
|
||||
/// Send a raw private zero-hop payload.
|
||||
///
|
||||
/// This wraps the raw custom transport using an empty path to match the
|
||||
/// firmware's private multicast behavior.
|
||||
Future<void> sendRawPrivateMulticast(Uint8List payload) async {
|
||||
if (!_activeService.isConnected) return;
|
||||
await _activeService.sendRawVoicePacket(
|
||||
contactPathLen: 0,
|
||||
contactPath: Uint8List(0),
|
||||
payload: payload,
|
||||
);
|
||||
}
|
||||
|
||||
/// Request telemetry from contact
|
||||
///
|
||||
/// COMPATIBILITY NOTE: This method sends CMD_SEND_TELEMETRY_REQ (39).
|
||||
|
||||
@@ -4,6 +4,7 @@ import '../models/contact.dart';
|
||||
import '../models/message_contact_location.dart';
|
||||
import '../services/cayenne_lpp_parser.dart';
|
||||
import '../services/contact_storage_service.dart';
|
||||
import '../utils/fast_gps_packet.dart';
|
||||
import '../utils/key_comparison.dart';
|
||||
|
||||
class PendingAdvert {
|
||||
@@ -464,6 +465,42 @@ class ContactsProvider with ChangeNotifier {
|
||||
}
|
||||
}
|
||||
|
||||
void updateFastGps(Uint8List publicKeyPrefix, FastGpsPacket packet) {
|
||||
final contact = _findContactByPrefix(publicKeyPrefix);
|
||||
if (contact == null) {
|
||||
debugPrint(
|
||||
'⚠️ [ContactsProvider] Fast GPS sender not found: ${packet.senderKey6}',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
final updatedTelemetry = _mergeTelemetryForContact(
|
||||
existingTelemetry: contact.telemetry,
|
||||
incomingTelemetry: ContactTelemetry(
|
||||
gpsLocation: LatLng(packet.latitude, packet.longitude),
|
||||
batteryPercentage: null,
|
||||
batteryMilliVolts: null,
|
||||
temperature: null,
|
||||
timestamp: DateTime.fromMillisecondsSinceEpoch(
|
||||
packet.timestampSeconds * 1000,
|
||||
),
|
||||
humidity: null,
|
||||
pressure: null,
|
||||
extraSensorData: null,
|
||||
),
|
||||
);
|
||||
|
||||
final updatedContact = contact.copyWith(
|
||||
telemetry: updatedTelemetry,
|
||||
lastAdvert: packet.timestampSeconds,
|
||||
advLat: _coordinateToAdvertMicrodegrees(packet.latitude),
|
||||
advLon: _coordinateToAdvertMicrodegrees(packet.longitude),
|
||||
);
|
||||
_contacts[contact.publicKeyHex] = updatedContact;
|
||||
_persistContacts();
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
bool _isInvalidTelemetryGps(LatLng? location) {
|
||||
if (location == null) return false;
|
||||
final lat = location.latitude;
|
||||
|
||||
Reference in New Issue
Block a user