]> git.basschouten.com Git - openhab-addons.git/blob
c4069d9875e805715989a1ef17c8ff295bba6d95
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.magentatv.internal.network;
14
15 import java.io.IOException;
16 import java.net.DatagramPacket;
17 import java.net.DatagramSocket;
18 import java.net.InetAddress;
19 import java.net.NetworkInterface;
20 import java.net.SocketException;
21 import java.net.UnknownHostException;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.eclipse.jdt.annotation.Nullable;
25 import org.openhab.binding.magentatv.internal.MagentaTVException;
26 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory;
28
29 /**
30  * The {@link MagentaTVNetwork} supplies network functions.
31  *
32  * @author Markus Michels - Initial contribution
33  */
34 @NonNullByDefault
35 public class MagentaTVNetwork {
36     private final Logger logger = LoggerFactory.getLogger(MagentaTVNetwork.class);
37
38     private String localIP = "";
39     private String localPort = "";
40     private String localMAC = "";
41     private @Nullable NetworkInterface localInterface;
42
43     /**
44      * Init local network interface, determine local IP and MAC address
45      *
46      * @param networkAddressService
47      * @return
48      */
49     public void initLocalNet(String localIP, String localPort) throws MagentaTVException {
50         try {
51             if (localIP.isEmpty() || "0.0.0.0".equals(localIP) || "127.0.0.1".equals(localIP)) {
52                 throw new MagentaTVException("Unable to detect local IP address!");
53             }
54             this.localPort = localPort;
55             this.localIP = localIP;
56
57             // get MAC address
58             InetAddress ip = InetAddress.getByName(localIP);
59             localInterface = NetworkInterface.getByInetAddress(ip);
60             if (localInterface != null) {
61                 byte[] mac = localInterface.getHardwareAddress();
62                 StringBuilder sb = new StringBuilder();
63                 for (int i = 0; i < mac.length; i++) {
64                     sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? ":" : ""));
65                 }
66                 localMAC = sb.toString().toUpperCase();
67                 logger.debug("Local IP address={}, Local MAC address = {}", localIP, localMAC);
68                 return;
69             }
70         } catch (UnknownHostException | SocketException e) {
71             throw new MagentaTVException(e);
72         }
73
74         throw new MagentaTVException(
75                 "Unable to get local IP / MAC address, check network settings in openHAB system configuration!");
76     }
77
78     @Nullable
79     public NetworkInterface getLocalInterface() {
80         return localInterface;
81     }
82
83     public String getLocalIP() {
84         return localIP;
85     }
86
87     public String getLocalPort() {
88         return localPort;
89     }
90
91     public String getLocalMAC() {
92         return localMAC;
93     }
94
95     public static final int WOL_PORT = 9;
96
97     /**
98      * Send a Wake-on-LAN packet
99      *
100      * @param ipAddr destination ip
101      * @param macAddress destination MAC address
102      * @throws MagentaTVException
103      */
104     public void sendWakeOnLAN(String ipAddr, String macAddress) throws MagentaTVException {
105         try {
106             byte[] macBytes = getMacBytes(macAddress);
107             byte[] bytes = new byte[6 + 16 * macBytes.length];
108             for (int i = 0; i < 6; i++) {
109                 bytes[i] = (byte) 0xff;
110             }
111             for (int i = 6; i < bytes.length; i += macBytes.length) {
112                 System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
113             }
114
115             InetAddress address = InetAddress.getByName(ipAddr);
116             DatagramPacket packet = new DatagramPacket(bytes, bytes.length, address, WOL_PORT);
117             try (DatagramSocket socket = new DatagramSocket()) {
118                 socket.send(packet);
119             }
120
121             logger.debug("Wake-on-LAN packet sent to {} / {}", ipAddr, macAddress);
122         } catch (IOException e) {
123             throw new MagentaTVException(e, "Unable to send Wake-on-LAN packet to {} / {}", ipAddr, macAddress);
124         }
125     }
126
127     /**
128      * Convert MAC address from string to byte array
129      *
130      * @param macStr MAC address as string
131      * @return MAC address as byte array
132      * @throws IllegalArgumentException
133      */
134     private static byte[] getMacBytes(String macStr) throws IllegalArgumentException {
135         byte[] bytes = new byte[6];
136         String[] hex = macStr.split("(\\:|\\-)");
137         if (hex.length != 6) {
138             throw new IllegalArgumentException("Invalid MAC address.");
139         }
140         try {
141             for (int i = 0; i < 6; i++) {
142                 bytes[i] = (byte) Integer.parseInt(hex[i], 16);
143             }
144         } catch (NumberFormatException e) {
145             throw new IllegalArgumentException("Invalid hex digit in MAC address.", e);
146         }
147         return bytes;
148     }
149 }