Matthias Nott
2026-03-21 fa34201bc07e5312ff0c6825933cd02ce7900254
lib/services/wol_service.dart
....@@ -32,9 +32,18 @@
3232 return packet.toBytes();
3333 }
3434
35
+ /// Derive subnet broadcast from an IP address (e.g., 192.168.1.100 → 192.168.1.255).
36
+ static String? _subnetBroadcast(String? ip) {
37
+ if (ip == null || ip.isEmpty) return null;
38
+ final parts = ip.split('.');
39
+ if (parts.length != 4) return null;
40
+ return '${parts[0]}.${parts[1]}.${parts[2]}.255';
41
+ }
42
+
3543 /// Send a Wake-on-LAN packet for the given MAC address.
36
- /// Broadcasts to 255.255.255.255:9 and optionally to a subnet broadcast.
37
- static Future<void> wake(String macAddress, {String? subnetBroadcast}) async {
44
+ /// Broadcasts to 255.255.255.255 and subnet broadcast derived from localHost.
45
+ /// Sends on ports 7 and 9 for maximum compatibility.
46
+ static Future<void> wake(String macAddress, {String? localHost}) async {
3847 final macBytes = _parseMac(macAddress);
3948 if (macBytes == null) {
4049 throw ArgumentError('Invalid MAC address: $macAddress');
....@@ -48,25 +57,31 @@
4857 );
4958 socket.broadcastEnabled = true;
5059
51
- // Send to broadcast address
52
- final broadcastAddr = InternetAddress('255.255.255.255');
53
- socket.send(packet, broadcastAddr, 9);
60
+ final targets = <InternetAddress>[
61
+ InternetAddress('255.255.255.255'),
62
+ ];
5463
55
- // Also send to subnet broadcast if provided
56
- if (subnetBroadcast != null && subnetBroadcast.isNotEmpty) {
64
+ // Add subnet broadcast derived from localHost
65
+ final subnet = _subnetBroadcast(localHost);
66
+ if (subnet != null) {
5767 try {
58
- final subnetAddr = InternetAddress(subnetBroadcast);
59
- socket.send(packet, subnetAddr, 9);
60
- } catch (_) {
61
- // Ignore invalid subnet broadcast address
62
- }
68
+ targets.add(InternetAddress(subnet));
69
+ } catch (_) {}
6370 }
6471
65
- // Send a few extra packets for reliability
66
- await Future.delayed(const Duration(milliseconds: 100));
67
- socket.send(packet, broadcastAddr, 9);
68
- await Future.delayed(const Duration(milliseconds: 100));
69
- socket.send(packet, broadcastAddr, 9);
72
+ // Send to all targets on both common WoL ports
73
+ for (final addr in targets) {
74
+ socket.send(packet, addr, 9);
75
+ socket.send(packet, addr, 7);
76
+ }
77
+
78
+ // Repeat for reliability
79
+ for (var i = 0; i < 3; i++) {
80
+ await Future.delayed(const Duration(milliseconds: 100));
81
+ for (final addr in targets) {
82
+ socket.send(packet, addr, 9);
83
+ }
84
+ }
7085
7186 socket.close();
7287 }