autoconnect on fly mode (does not work yet)
This commit is contained in:
@@ -6,14 +6,19 @@ sealed class MlrsNetworkEvent {
|
||||
const MlrsNetworkEvent();
|
||||
}
|
||||
|
||||
/// Das Netz ist verfuegbar (Nutzer hat den Systemdialog bestaetigt).
|
||||
/// Das Netz ist verfuegbar (Nutzer hat den Systemdialog bestaetigt, oder
|
||||
/// Android hat eine zuvor bewilligte exakte SSID still erneut verbunden).
|
||||
/// [gatewayAddress] ist die Gateway-Adresse des Netzes, falls ermittelbar -
|
||||
/// dient als Vorbelegung der Zieladresse, bevor eine Gegenstelle aus dem
|
||||
/// Verkehr gelernt wurde (Doku Abschnitt 3).
|
||||
/// Verkehr gelernt wurde (Doku Abschnitt 3). [ssid] ist die tatsaechliche
|
||||
/// SSID des verbundenen Netzes, falls ermittelbar - wird gemerkt, damit
|
||||
/// kuenftige Verbindungen exakt (statt per Praefix) angefragt werden koennen
|
||||
/// (siehe [MlrsNetworkController.requestNetwork]).
|
||||
class MlrsNetworkAvailable extends MlrsNetworkEvent {
|
||||
const MlrsNetworkAvailable({this.gatewayAddress});
|
||||
const MlrsNetworkAvailable({this.gatewayAddress, this.ssid});
|
||||
|
||||
final String? gatewayAddress;
|
||||
final String? ssid;
|
||||
}
|
||||
|
||||
/// Die Anfrage konnte nicht erfuellt werden (Nutzer hat den Systemdialog
|
||||
@@ -79,9 +84,13 @@ abstract class MlrsNetworkController {
|
||||
Stream<MlrsNetworkEvent> get events;
|
||||
|
||||
/// Loest `ConnectivityManager.requestNetwork()` mit einem
|
||||
/// `WifiNetworkSpecifier` aus, dessen SSID-Muster auf [ssidPrefix] passt.
|
||||
/// `WifiNetworkSpecifier` aus. Ist [preferredSsid] gesetzt (zuvor
|
||||
/// erfolgreich verbundene, gemerkte SSID), wird exakt danach gefragt -
|
||||
/// Android kann das dann ohne erneuten Systemdialog automatisch bewilligen
|
||||
/// (Doku Abschnitt 8: "Verbindung automatisch herstellen"). Sonst wird
|
||||
/// [ssidPrefix] als Praefix-Muster verwendet (zeigt immer den Dialog).
|
||||
/// Das Ergebnis kommt asynchron ueber [events] (available/unavailable).
|
||||
Future<void> requestNetwork(String ssidPrefix);
|
||||
Future<void> requestNetwork(String ssidPrefix, {String? preferredSsid});
|
||||
|
||||
/// Meldet den Callback ab und geht damit von der aktuellen Anfrage
|
||||
/// zurueck - keine weiteren [events] danach, bis erneut angefragt wird.
|
||||
@@ -139,6 +148,7 @@ class MethodChannelMlrsNetworkController implements MlrsNetworkController {
|
||||
return switch (map['type']) {
|
||||
'available' => MlrsNetworkAvailable(
|
||||
gatewayAddress: map['gatewayAddress'] as String?,
|
||||
ssid: map['ssid'] as String?,
|
||||
),
|
||||
'lost' => const MlrsNetworkLost(),
|
||||
_ => const MlrsNetworkUnavailable(),
|
||||
@@ -155,8 +165,11 @@ class MethodChannelMlrsNetworkController implements MlrsNetworkController {
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> requestNetwork(String ssidPrefix) => _methodChannel
|
||||
.invokeMethod('requestNetwork', {'ssidPrefix': ssidPrefix});
|
||||
Future<void> requestNetwork(String ssidPrefix, {String? preferredSsid}) =>
|
||||
_methodChannel.invokeMethod('requestNetwork', {
|
||||
'ssidPrefix': ssidPrefix,
|
||||
'exactSsid': preferredSsid,
|
||||
});
|
||||
|
||||
@override
|
||||
Future<void> releaseNetwork() => _methodChannel.invokeMethod('releaseNetwork');
|
||||
|
||||
@@ -32,16 +32,22 @@ class UdpTransport implements LinkTransport {
|
||||
required Future<String?> Function() getHost,
|
||||
required Future<int> Function() getPort,
|
||||
required Future<String> Function() getSsidPrefix,
|
||||
required Future<String?> Function() getRememberedSsid,
|
||||
required Future<void> Function(String ssid) rememberSsid,
|
||||
MlrsNetworkController? networkController,
|
||||
}) : _getHost = getHost,
|
||||
_getPort = getPort,
|
||||
_getSsidPrefix = getSsidPrefix,
|
||||
_getRememberedSsid = getRememberedSsid,
|
||||
_rememberSsid = rememberSsid,
|
||||
_networkController =
|
||||
networkController ?? MethodChannelMlrsNetworkController();
|
||||
|
||||
final Future<String?> Function() _getHost;
|
||||
final Future<int> Function() _getPort;
|
||||
final Future<String> Function() _getSsidPrefix;
|
||||
final Future<String?> Function() _getRememberedSsid;
|
||||
final Future<void> Function(String ssid) _rememberSsid;
|
||||
final MlrsNetworkController _networkController;
|
||||
|
||||
final _incomingController = StreamController<Uint8List>.broadcast();
|
||||
@@ -54,6 +60,7 @@ class UdpTransport implements LinkTransport {
|
||||
int? _boundPort;
|
||||
bool _socketOpen = false;
|
||||
bool? _staConcurrencySupported;
|
||||
String? _connectedSsid;
|
||||
|
||||
LinkState _state = LinkState.disconnected;
|
||||
LinkErrorReason? _lastErrorReason;
|
||||
@@ -85,6 +92,13 @@ class UdpTransport implements LinkTransport {
|
||||
/// nicht ermittelbar (API < 30, Doku Abschnitt 4/8).
|
||||
bool? get staConcurrencySupported => _staConcurrencySupported;
|
||||
|
||||
/// Tatsaechliche SSID des verbundenen Netzes, sobald von Android
|
||||
/// ermittelbar (Doku Abschnitt 8: "verbundenes WLAN anzeigen"). Wird bei
|
||||
/// jedem erfolgreichen [connect] auch dauerhaft gemerkt (siehe
|
||||
/// [_rememberSsid]), damit kuenftige Verbindungen exakt statt per Praefix
|
||||
/// angefragt werden koennen.
|
||||
String? get connectedSsid => _connectedSsid;
|
||||
|
||||
@override
|
||||
Future<void> connect() async {
|
||||
_lastErrorReason = null;
|
||||
@@ -92,13 +106,17 @@ class UdpTransport implements LinkTransport {
|
||||
_setState(LinkState.connecting);
|
||||
|
||||
final ssidPrefix = await _getSsidPrefix();
|
||||
final rememberedSsid = await _getRememberedSsid();
|
||||
final firstEvent = Completer<MlrsNetworkEvent>();
|
||||
final requestSub = _networkController.events.listen((event) {
|
||||
if (!firstEvent.isCompleted) firstEvent.complete(event);
|
||||
});
|
||||
|
||||
try {
|
||||
await _networkController.requestNetwork(ssidPrefix);
|
||||
await _networkController.requestNetwork(
|
||||
ssidPrefix,
|
||||
preferredSsid: rememberedSsid,
|
||||
);
|
||||
final event = await firstEvent.future;
|
||||
await requestSub.cancel();
|
||||
|
||||
@@ -115,6 +133,11 @@ class UdpTransport implements LinkTransport {
|
||||
// unten, nicht erst danach (Doku Abschnitt 8).
|
||||
_networkLossSub = _networkController.events.listen(_onNetworkEvent);
|
||||
|
||||
_connectedSsid = available.ssid;
|
||||
if (available.ssid != null) {
|
||||
await _rememberSsid(available.ssid!);
|
||||
}
|
||||
|
||||
final configuredHost = await _getHost();
|
||||
final configuredPort = await _getPort();
|
||||
final prefillHost = (configuredHost != null && configuredHost.isNotEmpty)
|
||||
@@ -170,6 +193,7 @@ class UdpTransport implements LinkTransport {
|
||||
_packetSub?.cancel();
|
||||
_packetSub = null;
|
||||
_boundPort = null;
|
||||
_connectedSsid = null;
|
||||
if (_socketOpen) {
|
||||
_socketOpen = false;
|
||||
unawaited(_networkController.closeSocket());
|
||||
@@ -193,6 +217,7 @@ class UdpTransport implements LinkTransport {
|
||||
await _packetSub?.cancel();
|
||||
_packetSub = null;
|
||||
_boundPort = null;
|
||||
_connectedSsid = null;
|
||||
if (_socketOpen) {
|
||||
_socketOpen = false;
|
||||
await _networkController.closeSocket();
|
||||
@@ -220,9 +245,14 @@ class UdpTransport implements LinkTransport {
|
||||
_packetSub?.cancel();
|
||||
if (_socketOpen) {
|
||||
_socketOpen = false;
|
||||
unawaited(_networkController.closeSocket());
|
||||
// dispose() darf nie eine unbehandelte Future-Exception hinterlassen -
|
||||
// z.B. wirft der Platform-Channel MissingPluginException, wenn
|
||||
// ueberhaupt kein natives Gegenstueck existiert (Tests, Web/Desktop-
|
||||
// UI-Vorschau). Der Aufrufer kann an dieser Stelle ohnehin nicht mehr
|
||||
// reagieren.
|
||||
unawaited(_networkController.closeSocket().catchError((_) {}));
|
||||
}
|
||||
unawaited(_networkController.releaseNetwork());
|
||||
unawaited(_networkController.releaseNetwork().catchError((_) {}));
|
||||
_networkController.dispose();
|
||||
_incomingController.close();
|
||||
_stateController.close();
|
||||
|
||||
Reference in New Issue
Block a user