]> git.basschouten.com Git - openhab-addons.git/commitdiff
Added possiblity to send WOL Requests to configured Hostname, also removed unnecessar...
authorJonathan S <37658347+J0nathan-S@users.noreply.github.com>
Sun, 19 Sep 2021 19:55:39 +0000 (21:55 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Sep 2021 19:55:39 +0000 (21:55 +0200)
Signed-off-by: Jonathan Saxen <jonathan@saxen.info>
bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/WakeOnLanPacketSender.java
bundles/org.openhab.binding.network/src/main/java/org/openhab/binding/network/internal/handler/NetworkHandler.java
bundles/org.openhab.binding.network/src/test/java/org/openhab/binding/network/internal/WakeOnLanPacketSenderTest.java

index 603c640ed1c7af981225def148f84af37081492d..4e9da808cda49f1b0f0a79a6cf34c93229a3f712 100644 (file)
 package org.openhab.binding.network.internal;
 
 import java.io.IOException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
+import java.net.*;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.function.Consumer;
 import java.util.stream.Stream;
 
+import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jdt.annotation.NonNullByDefault;
 import org.eclipse.jdt.annotation.Nullable;
 import org.openhab.core.net.NetUtil;
@@ -50,12 +47,28 @@ public class WakeOnLanPacketSender {
     private final Logger logger = LoggerFactory.getLogger(WakeOnLanPacketSender.class);
 
     private final String macAddress;
+
+    @Nullable
+    private final String hostname;
+
+    @Nullable
+    private final Integer port;
+
     private byte @Nullable [] magicPacket;
     private final Consumer<byte[]> magicPacketSender;
 
+    public WakeOnLanPacketSender(String macAddress, @Nullable String hostname, @Nullable Integer port) {
+        this.macAddress = macAddress;
+        this.hostname = hostname;
+        this.port = port;
+        this.magicPacketSender = this::sendMagicPacket;
+    }
+
     public WakeOnLanPacketSender(String macAddress) {
         this.macAddress = macAddress;
-        this.magicPacketSender = this::broadcastMagicPacket;
+        this.hostname = null;
+        this.port = null;
+        this.magicPacketSender = this::sendMagicPacket;
     }
 
     /**
@@ -63,6 +76,8 @@ public class WakeOnLanPacketSender {
      */
     WakeOnLanPacketSender(String macAddress, Consumer<byte[]> magicPacketSender) {
         this.macAddress = macAddress;
+        this.hostname = null;
+        this.port = null;
         this.magicPacketSender = magicPacketSender;
     }
 
@@ -96,26 +111,46 @@ public class WakeOnLanPacketSender {
         return bytes;
     }
 
-    private void broadcastMagicPacket(byte[] magicPacket) {
+    private void sendMagicPacket(byte[] magicPacket) {
         try (DatagramSocket socket = new DatagramSocket()) {
-            broadcastAddressStream().forEach(broadcastAddress -> {
-                try {
-                    DatagramPacket packet = new DatagramPacket(magicPacket, MAGIC_PACKET_BYTE_SIZE, broadcastAddress,
-                            WOL_UDP_PORT);
-                    socket.send(packet);
-                    logger.debug("Wake-on-LAN packet sent (MAC address: {}, broadcast address: {})", macAddress,
-                            broadcastAddress.getHostAddress());
-                } catch (IOException e) {
-                    logger.debug("Failed to send Wake-on-LAN packet (MAC address: {}, broadcast address: {})",
-                            macAddress, broadcastAddress.getHostAddress(), e);
-                }
-            });
-            logger.info("Wake-on-LAN packets sent (MAC address: {})", macAddress);
+            if (StringUtils.isEmpty(hostname)) {
+                broadcastMagicPacket(magicPacket, socket);
+            } else {
+                SocketAddress socketAddress = new InetSocketAddress(this.hostname,
+                        Objects.requireNonNullElse(this.port, WOL_UDP_PORT));
+                sendMagicPacketToIp(magicPacket, socket, socketAddress);
+            }
         } catch (SocketException e) {
             logger.error("Failed to open Wake-on-LAN datagram socket", e);
         }
     }
 
+    private void broadcastMagicPacket(byte[] magicPacket, DatagramSocket socket) {
+        broadcastAddressStream().forEach(broadcastAddress -> {
+            try {
+                DatagramPacket packet = new DatagramPacket(magicPacket, MAGIC_PACKET_BYTE_SIZE, broadcastAddress,
+                        WOL_UDP_PORT);
+                socket.send(packet);
+                logger.debug("Wake-on-LAN packet sent (MAC address: {}, broadcast address: {})", macAddress,
+                        broadcastAddress.getHostAddress());
+            } catch (IOException e) {
+                logger.debug("Failed to send Wake-on-LAN packet (MAC address: {}, broadcast address: {})", macAddress,
+                        broadcastAddress.getHostAddress(), e);
+            }
+        });
+        logger.info("Wake-on-LAN packets sent (MAC address: {})", macAddress);
+    }
+
+    private void sendMagicPacketToIp(byte[] magicPacket, DatagramSocket socket, SocketAddress ip) {
+        DatagramPacket packet = new DatagramPacket(magicPacket, MAGIC_PACKET_BYTE_SIZE, ip);
+        try {
+            socket.send(packet);
+        } catch (IOException e) {
+            logger.debug("Failed to send Wake-on-LAN packet (MAC address: {}, address: {})", macAddress, ip, e);
+        }
+        logger.info("Wake-on-LAN packets sent (MAC address: {}, IP address: {})", macAddress, ip);
+    }
+
     private Stream<InetAddress> broadcastAddressStream() {
         return NetUtil.getAllBroadcastAddresses().stream().map(address -> {
             try {
index a2cf48c1517fa8f1140de75ce32c81f4749699d7..f27fe42033c70c215fa18b6a4ddcf453abe0d29f 100644 (file)
@@ -198,7 +198,8 @@ public class NetworkHandler extends BaseThingHandler
         presenceDetection.setRefreshInterval(handlerConfiguration.refreshInterval.longValue());
         presenceDetection.setTimeout(handlerConfiguration.timeout.intValue());
 
-        wakeOnLanPacketSender = new WakeOnLanPacketSender(handlerConfiguration.macAddress);
+        wakeOnLanPacketSender = new WakeOnLanPacketSender(handlerConfiguration.macAddress,
+                handlerConfiguration.hostname, handlerConfiguration.port);
 
         updateStatus(ThingStatus.ONLINE);
         presenceDetection.startAutomaticRefresh(scheduler);
index 505c9d0331a6876de4c8249affc70ef78c8abb4f..517521d4464bd254210d67f40fe8b263492f5047 100644 (file)
@@ -17,9 +17,12 @@ import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.openhab.binding.network.internal.WakeOnLanPacketSender.*;
 
+import java.io.IOException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
 import java.util.Arrays;
-import java.util.concurrent.TimeUnit;
 
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 import org.openhab.core.util.HexUtils;
@@ -29,7 +32,7 @@ import org.openhab.core.util.HexUtils;
  *
  * @author Wouter Born - Initial contribution
  */
-@Timeout(value = 10, unit = TimeUnit.SECONDS)
+@Timeout(value = 10)
 public class WakeOnLanPacketSenderTest {
 
     private void assertValidMagicPacket(byte[] macBytes, byte[] packet) {
@@ -79,6 +82,49 @@ public class WakeOnLanPacketSenderTest {
         assertValidMagicPacket(HexUtils.hexToBytes("6f70656e4841"), actualPacket);
     }
 
+    @Test
+    public void sendWithHostnameAndPort() throws IOException, InterruptedException {
+        sendWOLTest("127.0.0.1", 4444);
+    }
+
+    @Test
+    public void sendWithHostnameAndPortNull() throws IOException, InterruptedException {
+        sendWOLTest("127.0.0.1", null);
+    }
+
+    @Test
+    public void sendWithHostnameNullAndPortNull() throws IOException, InterruptedException {
+        sendWOLTest(null, null);
+    }
+
+    @Test
+    public void sendWithHostnameNull() throws IOException, InterruptedException {
+        sendWOLTest(null, 4444);
+    }
+
+    private void sendWOLTest(String hostname, Integer port) throws InterruptedException, IOException {
+        DatagramSocket socket = new DatagramSocket(4444);
+
+        byte[] buf = new byte[256];
+        DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);
+
+        while (socket.isClosed()) {
+            Thread.sleep(100);
+        }
+
+        WakeOnLanPacketSender sender = new WakeOnLanPacketSender("6f70656e4841", hostname, port);
+        sender.sendPacket();
+
+        // This Test is only applicable for IP Requests
+        if (hostname != null && port != null) {
+            socket.receive(datagramPacket);
+        }
+
+        socket.close();
+
+        Assertions.assertTrue(datagramPacket.getData().length > 0);
+    }
+
     @Test
     public void sendWithEmptyMacAddressThrowsException() {
         assertThrows(IllegalStateException.class, () -> new WakeOnLanPacketSender("").sendPacket());