mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-12 00:40:28 +00:00
Include client repeat info
This commit is contained in:
@@ -86,6 +86,10 @@ class DeviceInfo {
|
|||||||
final String? manufacturerModel;
|
final String? manufacturerModel;
|
||||||
final String? semanticVersion;
|
final String? semanticVersion;
|
||||||
|
|
||||||
|
// Repeat mode (firmware v9+)
|
||||||
|
final bool? clientRepeat;
|
||||||
|
final List<({int lower, int upper})>? allowedRepeatFreqRanges;
|
||||||
|
|
||||||
DeviceInfo({
|
DeviceInfo({
|
||||||
this.deviceId,
|
this.deviceId,
|
||||||
this.deviceName,
|
this.deviceName,
|
||||||
@@ -119,6 +123,8 @@ class DeviceInfo {
|
|||||||
this.firmwareBuildDate,
|
this.firmwareBuildDate,
|
||||||
this.manufacturerModel,
|
this.manufacturerModel,
|
||||||
this.semanticVersion,
|
this.semanticVersion,
|
||||||
|
this.clientRepeat,
|
||||||
|
this.allowedRepeatFreqRanges,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Check if device is connected
|
/// Check if device is connected
|
||||||
@@ -238,6 +244,8 @@ class DeviceInfo {
|
|||||||
String? firmwareBuildDate,
|
String? firmwareBuildDate,
|
||||||
String? manufacturerModel,
|
String? manufacturerModel,
|
||||||
String? semanticVersion,
|
String? semanticVersion,
|
||||||
|
bool? clientRepeat,
|
||||||
|
List<({int lower, int upper})>? allowedRepeatFreqRanges,
|
||||||
}) {
|
}) {
|
||||||
return DeviceInfo(
|
return DeviceInfo(
|
||||||
deviceId: deviceId ?? this.deviceId,
|
deviceId: deviceId ?? this.deviceId,
|
||||||
@@ -272,6 +280,8 @@ class DeviceInfo {
|
|||||||
firmwareBuildDate: firmwareBuildDate ?? this.firmwareBuildDate,
|
firmwareBuildDate: firmwareBuildDate ?? this.firmwareBuildDate,
|
||||||
manufacturerModel: manufacturerModel ?? this.manufacturerModel,
|
manufacturerModel: manufacturerModel ?? this.manufacturerModel,
|
||||||
semanticVersion: semanticVersion ?? this.semanticVersion,
|
semanticVersion: semanticVersion ?? this.semanticVersion,
|
||||||
|
clientRepeat: clientRepeat ?? this.clientRepeat,
|
||||||
|
allowedRepeatFreqRanges: allowedRepeatFreqRanges ?? this.allowedRepeatFreqRanges,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -535,6 +535,7 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
firmwareBuildDate: deviceInfo['firmwareBuildDate'] as String?,
|
firmwareBuildDate: deviceInfo['firmwareBuildDate'] as String?,
|
||||||
manufacturerModel: deviceInfo['manufacturerModel'] as String?,
|
manufacturerModel: deviceInfo['manufacturerModel'] as String?,
|
||||||
semanticVersion: deviceInfo['semanticVersion'] as String?,
|
semanticVersion: deviceInfo['semanticVersion'] as String?,
|
||||||
|
clientRepeat: deviceInfo['clientRepeat'] as bool?,
|
||||||
);
|
);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
debugPrint('✅ [Provider] Device info updated with DeviceInfo');
|
debugPrint('✅ [Provider] Device info updated with DeviceInfo');
|
||||||
@@ -624,6 +625,12 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_bleService.onAllowedRepeatFreqReceived = (ranges) {
|
||||||
|
debugPrint('📥 [Provider] Received AllowedRepeatFreq: $ranges');
|
||||||
|
_deviceInfo = _deviceInfo.copyWith(allowedRepeatFreqRanges: ranges);
|
||||||
|
notifyListeners();
|
||||||
|
};
|
||||||
|
|
||||||
_bleService.onTxActivity = () {
|
_bleService.onTxActivity = () {
|
||||||
_txActivity = true;
|
_txActivity = true;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
@@ -1652,6 +1659,7 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
required int bandwidth,
|
required int bandwidth,
|
||||||
required int spreadingFactor,
|
required int spreadingFactor,
|
||||||
required int codingRate,
|
required int codingRate,
|
||||||
|
bool? repeat,
|
||||||
}) async {
|
}) async {
|
||||||
if (!_bleService.isConnected) {
|
if (!_bleService.isConnected) {
|
||||||
_error = 'Not connected to device';
|
_error = 'Not connected to device';
|
||||||
@@ -1665,6 +1673,7 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
bandwidth: bandwidth,
|
bandwidth: bandwidth,
|
||||||
spreadingFactor: spreadingFactor,
|
spreadingFactor: spreadingFactor,
|
||||||
codingRate: codingRate,
|
codingRate: codingRate,
|
||||||
|
repeat: repeat,
|
||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_error = 'Failed to set radio params: $e';
|
_error = 'Failed to set radio params: $e';
|
||||||
@@ -1672,6 +1681,16 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Request the list of allowed repeat frequency ranges from the device (firmware v9+)
|
||||||
|
Future<void> getAllowedRepeatFreq() async {
|
||||||
|
if (!_bleService.isConnected) return;
|
||||||
|
try {
|
||||||
|
await _bleService.getAllowedRepeatFreq();
|
||||||
|
} catch (e) {
|
||||||
|
debugPrint('Failed to get allowed repeat freq: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Set transmit power
|
/// Set transmit power
|
||||||
Future<void> setTxPower(int powerDbm) async {
|
Future<void> setTxPower(int powerDbm) async {
|
||||||
if (!_bleService.isConnected) {
|
if (!_bleService.isConnected) {
|
||||||
@@ -1725,6 +1744,8 @@ class ConnectionProvider with ChangeNotifier {
|
|||||||
try {
|
try {
|
||||||
// The device query command triggers a SelfInfo response
|
// The device query command triggers a SelfInfo response
|
||||||
await _bleService.refreshDeviceInfo();
|
await _bleService.refreshDeviceInfo();
|
||||||
|
// Also request allowed repeat frequencies (firmware v9+, no-op on older firmware)
|
||||||
|
await _bleService.getAllowedRepeatFreq();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
_error = 'Failed to refresh device info: $e';
|
_error = 'Failed to refresh device info: $e';
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class _DeviceConfigScreenState extends State<DeviceConfigScreen> {
|
|||||||
late TextEditingController _txPowerController;
|
late TextEditingController _txPowerController;
|
||||||
|
|
||||||
bool _telemetryEnabled = false;
|
bool _telemetryEnabled = false;
|
||||||
|
bool _repeatEnabled = false;
|
||||||
String _selectedBandwidth = '62.5 kHz';
|
String _selectedBandwidth = '62.5 kHz';
|
||||||
int _selectedSpreadingFactor = 8;
|
int _selectedSpreadingFactor = 8;
|
||||||
int _selectedCodingRate = 8;
|
int _selectedCodingRate = 8;
|
||||||
@@ -85,6 +86,17 @@ class _DeviceConfigScreenState extends State<DeviceConfigScreen> {
|
|||||||
_telemetryEnabled =
|
_telemetryEnabled =
|
||||||
(deviceInfo.advLat != null && deviceInfo.advLat! != 0) ||
|
(deviceInfo.advLat != null && deviceInfo.advLat! != 0) ||
|
||||||
(deviceInfo.advLon != null && deviceInfo.advLon! != 0);
|
(deviceInfo.advLon != null && deviceInfo.advLon! != 0);
|
||||||
|
|
||||||
|
// Initialize repeat mode from device info (firmware v9+)
|
||||||
|
_repeatEnabled = deviceInfo.clientRepeat ?? false;
|
||||||
|
|
||||||
|
// Fetch allowed repeat frequencies on open if device supports repeat mode
|
||||||
|
if (deviceInfo.clientRepeat != null &&
|
||||||
|
deviceInfo.allowedRepeatFreqRanges == null) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
context.read<ConnectionProvider>().getAllowedRepeatFreq();
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -263,6 +275,7 @@ class _DeviceConfigScreenState extends State<DeviceConfigScreen> {
|
|||||||
bandwidth: _bandwidthToValue(_selectedBandwidth),
|
bandwidth: _bandwidthToValue(_selectedBandwidth),
|
||||||
spreadingFactor: _selectedSpreadingFactor,
|
spreadingFactor: _selectedSpreadingFactor,
|
||||||
codingRate: _selectedCodingRate,
|
codingRate: _selectedCodingRate,
|
||||||
|
repeat: deviceInfo.clientRepeat != null ? _repeatEnabled : null,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save TX power
|
// Save TX power
|
||||||
@@ -702,6 +715,29 @@ class _DeviceConfigScreenState extends State<DeviceConfigScreen> {
|
|||||||
),
|
),
|
||||||
keyboardType: TextInputType.number,
|
keyboardType: TextInputType.number,
|
||||||
),
|
),
|
||||||
|
|
||||||
|
// Repeat Mode (firmware v9+)
|
||||||
|
if (deviceInfo.clientRepeat != null) ...[
|
||||||
|
const SizedBox(height: 8),
|
||||||
|
SwitchListTile(
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
title: const Text('Client Repeat Mode'),
|
||||||
|
subtitle: deviceInfo.allowedRepeatFreqRanges != null &&
|
||||||
|
deviceInfo.allowedRepeatFreqRanges!.isNotEmpty
|
||||||
|
? Text(
|
||||||
|
'Allowed: ${deviceInfo.allowedRepeatFreqRanges!.map((r) => r.lower == r.upper ? '${(r.lower / 1000).toStringAsFixed(3)} MHz' : '${(r.lower / 1000).toStringAsFixed(3)}–${(r.upper / 1000).toStringAsFixed(3)} MHz').join(', ')}',
|
||||||
|
)
|
||||||
|
: const Text(
|
||||||
|
'Repeat packets on behalf of nearby nodes',
|
||||||
|
),
|
||||||
|
value: _repeatEnabled,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() {
|
||||||
|
_repeatEnabled = value;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user