2 * Copyright (c) 2010-2024 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
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
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.dscalarm.internal.discovery;
15 import java.io.BufferedReader;
16 import java.io.IOException;
17 import java.io.InputStreamReader;
18 import java.net.InetAddress;
19 import java.net.InetSocketAddress;
20 import java.net.NetworkInterface;
21 import java.net.Socket;
22 import java.net.SocketException;
23 import java.net.SocketTimeoutException;
25 import org.apache.commons.net.util.SubnetUtils;
26 import org.apache.commons.net.util.SubnetUtils.SubnetInfo;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
31 * This class is responsible for discovering the EyezOn Envisalink 3/2DS Ethernet interface.
33 * @author Russell Stephens - Initial Contribution
36 public class EnvisalinkBridgeDiscovery {
37 private final Logger logger = LoggerFactory.getLogger(EnvisalinkBridgeDiscovery.class);
39 static final int ENVISALINK_BRIDGE_PORT = 4025;
40 static final int CONNECTION_TIMEOUT = 10;
41 static final int SO_TIMEOUT = 15000;
42 static final String ENVISALINK_DISCOVERY_RESPONSE = "505";
44 private DSCAlarmBridgeDiscovery dscAlarmBridgeDiscovery = null;
45 private String ipAddress;
50 public EnvisalinkBridgeDiscovery(DSCAlarmBridgeDiscovery dscAlarmBridgeDiscovery) {
51 this.dscAlarmBridgeDiscovery = dscAlarmBridgeDiscovery;
55 * Method for Bridge Discovery.
57 public synchronized void discoverBridge() {
58 logger.debug("Starting Envisalink Bridge Discovery.");
60 SubnetUtils subnetUtils = null;
61 SubnetInfo subnetInfo = null;
66 InetAddress localHost = InetAddress.getLocalHost();
67 NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
68 subnetUtils = new SubnetUtils(localHost.getHostAddress() + "/"
69 + networkInterface.getInterfaceAddresses().get(0).getNetworkPrefixLength());
70 subnetInfo = subnetUtils.getInfo();
71 lowIP = convertIPToNumber(subnetInfo.getLowAddress());
72 highIP = convertIPToNumber(subnetInfo.getHighAddress());
73 } catch (IllegalArgumentException e) {
74 logger.warn("discoverBridge(): Illegal Argument Exception - {}", e.toString());
76 } catch (Exception e) {
77 logger.warn("discoverBridge(): Error - Unable to get Subnet Information! {}", e.toString());
81 logger.debug(" Local IP Address: {} - {}", subnetInfo.getAddress(),
82 convertIPToNumber(subnetInfo.getAddress()));
83 logger.debug(" Subnet: {} - {}", subnetInfo.getNetworkAddress(),
84 convertIPToNumber(subnetInfo.getNetworkAddress()));
85 logger.debug(" Network Prefix: {}", subnetInfo.getCidrSignature().split("/")[1]);
86 logger.debug(" Network Mask: {}", subnetInfo.getNetmask());
87 logger.debug(" Low IP: {}", convertNumberToIP(lowIP));
88 logger.debug(" High IP: {}", convertNumberToIP(highIP));
90 for (long ip = lowIP; ip <= highIP; ip++) {
91 try (Socket socket = new Socket()) {
92 ipAddress = convertNumberToIP(ip);
94 socket.setReuseAddress(true);
95 socket.setReceiveBufferSize(32);
96 socket.connect(new InetSocketAddress(ipAddress, ENVISALINK_BRIDGE_PORT), CONNECTION_TIMEOUT);
97 if (socket.isConnected()) {
99 socket.setSoTimeout(SO_TIMEOUT);
100 try (BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()))) {
101 message = input.readLine();
102 } catch (SocketTimeoutException e) {
103 logger.debug("discoverBridge(): No Message Read from Socket at [{}] - {}", ipAddress,
106 } catch (Exception e) {
107 logger.debug("discoverBridge(): Exception Reading from Socket at [{}]! {}", ipAddress,
112 if (message.substring(0, 3).equals(ENVISALINK_DISCOVERY_RESPONSE)) {
113 logger.debug("discoverBridge(): Bridge Found - [{}]! Message - '{}'", ipAddress, message);
114 dscAlarmBridgeDiscovery.addEnvisalinkBridge(ipAddress);
116 logger.debug("discoverBridge(): No Response from Connection - [{}]! Message - '{}'",
120 } catch (IllegalArgumentException e) {
121 logger.debug("discoverBridge(): Illegal Argument Exception - {}", e.toString());
122 } catch (SocketTimeoutException e) {
123 logger.trace("discoverBridge(): No Connection on Port 4025! [{}]", ipAddress);
124 } catch (SocketException e) {
125 logger.debug("discoverBridge(): Socket Exception! [{}] - {}", ipAddress, e.toString());
126 } catch (IOException e) {
127 logger.debug("discoverBridge(): IO Exception! [{}] - {}", ipAddress, e.toString());
133 * Convert an IP address to a number.
138 private long convertIPToNumber(String ipAddress) {
139 String[] octets = ipAddress.split("\\.");
141 if (octets.length != 4) {
142 throw new IllegalArgumentException("Invalid IP address: " + ipAddress);
147 for (int i = 3; i >= 0; i--) {
148 long octet = Long.parseLong(octets[3 - i]);
150 if (octet != (octet & 0xff)) {
151 throw new IllegalArgumentException("Invalid IP address: " + ipAddress);
154 ip |= octet << (i * 8);
161 * Convert a number to an IP address.
166 private String convertNumberToIP(long ip) {
167 StringBuilder ipAddress = new StringBuilder(15);
169 for (int i = 0; i < 4; i++) {
171 ipAddress.insert(0, Long.toString(ip & 0xff));
174 ipAddress.insert(0, '.');
180 return ipAddress.toString();