2 * Copyright (c) 2010-2022 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.ekey.internal.api;
15 import java.io.IOException;
16 import java.net.DatagramPacket;
17 import java.net.DatagramSocket;
18 import java.net.InetAddress;
19 import java.net.UnknownHostException;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.ekey.internal.handler.EkeyHandler;
24 import org.openhab.core.thing.ThingStatus;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
29 * This Class provides the DatagramSocket that listens for eKey packets on the network
30 * This will run in a thread and can be interrupted by calling <code>stopListener()<code>
31 * Before starting the thread initialization is required (mode, ip, port and deliminator)
33 * @author Hans-Jörg Merk - Initial contribution
36 public class EkeyUdpPacketReceiver {
38 private final Logger logger = LoggerFactory.getLogger(EkeyUdpPacketReceiver.class);
40 private final int buffersize = 1024;
41 private final String ipAddress;
42 private final int port;
43 private final String readerThreadName;
45 private @Nullable DatagramSocket socket;
47 private @Nullable EkeyPacketListener packetListener;
49 private boolean connected = false;
51 public EkeyUdpPacketReceiver(final String ipAddress, final int port, final String readerThreadName) {
52 this.ipAddress = ipAddress;
54 this.readerThreadName = readerThreadName;
57 public void openConnection() throws IOException {
60 EkeyPacketListener listener = this.packetListener;
62 socket = new DatagramSocket(port);
64 Thread udpListener = new Thread(new UDPListener());
65 udpListener.setName(readerThreadName);
66 udpListener.setDaemon(true);
70 if (listener != null) {
71 listener.connectionStatusChanged(ThingStatus.ONLINE, null);
75 public void closeConnection() {
78 DatagramSocket localSocket = socket;
79 if (localSocket != null) {
83 } catch (Exception exception) {
84 logger.debug("closeConnection(): Error closing connection - {}", exception.getMessage());
88 private class UDPListener implements Runnable {
91 * Run method. Runs the MessageListener thread
95 logger.debug("Starting ekey Packet Receiver");
97 DatagramSocket localSocket = socket;
99 if (localSocket == null) {
100 throw new IllegalStateException("Cannot access socket.");
103 byte[] lastPacket = null;
104 DatagramPacket packet = new DatagramPacket(new byte[buffersize], buffersize);
105 packet.setData(new byte[buffersize]);
107 while (isConnected()) {
109 logger.trace("Listen for incoming packet");
110 localSocket.receive(packet);
111 logger.trace("Packet received - {}", packet.getData());
112 } catch (IOException exception) {
113 logger.debug("Exception during packet read - {}", exception.getMessage());
115 InetAddress sourceIp;
117 sourceIp = InetAddress.getByName(ipAddress);
118 if (packet.getAddress().equals(sourceIp)) {
119 lastPacket = packet.getData();
120 readMessage(lastPacket);
122 logger.warn("Packet received from unknown source- {}", packet.getData());
124 } catch (UnknownHostException e) {
125 logger.debug("Exception during address conversion - {}", e.getMessage());
131 public void readMessage(byte[] message) {
132 EkeyPacketListener listener = this.packetListener;
134 if (listener != null && message.length != 0) {
135 listener.messageReceived(message);
139 public void addEkeyPacketListener(EkeyPacketListener listener) {
140 if (this.packetListener == null) {
141 this.packetListener = listener;
145 public void setConnected(boolean connected) {
146 this.connected = connected;
149 public boolean isConnected() {
150 return this.connected;
153 public void removeEkeyPacketListener(EkeyHandler ekeyHandler) {
154 if (this.packetListener != null) {
155 this.packetListener = null;