]> git.basschouten.com Git - openhab-addons.git/blob
38cf98c554a85ba82e0be032f1d133071f726890
[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.ekey.internal.api;
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.UnknownHostException;
20
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;
27
28 /**
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)
32  *
33  * @author Hans-Jörg Merk - Initial contribution
34  */
35 @NonNullByDefault
36 public class EkeyUdpPacketReceiver {
37
38     private final Logger logger = LoggerFactory.getLogger(EkeyUdpPacketReceiver.class);
39
40     private final int buffersize = 1024;
41     private final String ipAddress;
42     private final int port;
43     private final String readerThreadName;
44
45     private @Nullable DatagramSocket socket;
46
47     private @Nullable EkeyPacketListener packetListener;
48
49     private boolean connected = false;
50
51     public EkeyUdpPacketReceiver(final String ipAddress, final int port, final String readerThreadName) {
52         this.ipAddress = ipAddress;
53         this.port = port;
54         this.readerThreadName = readerThreadName;
55     }
56
57     public void openConnection() throws IOException {
58         closeConnection();
59
60         EkeyPacketListener listener = this.packetListener;
61
62         socket = new DatagramSocket(port);
63
64         Thread udpListener = new Thread(new UDPListener());
65         udpListener.setName(readerThreadName);
66         udpListener.setDaemon(true);
67         udpListener.start();
68
69         setConnected(true);
70         if (listener != null) {
71             listener.connectionStatusChanged(ThingStatus.ONLINE, null);
72         }
73     }
74
75     public void closeConnection() {
76         setConnected(false);
77         try {
78             DatagramSocket localSocket = socket;
79             if (localSocket != null) {
80                 localSocket.close();
81                 localSocket = null;
82             }
83         } catch (Exception exception) {
84             logger.debug("closeConnection(): Error closing connection - {}", exception.getMessage());
85         }
86     }
87
88     private class UDPListener implements Runnable {
89
90         /**
91          * Run method. Runs the MessageListener thread
92          */
93         @Override
94         public void run() {
95             logger.debug("Starting ekey Packet Receiver");
96
97             DatagramSocket localSocket = socket;
98
99             if (localSocket == null) {
100                 throw new IllegalStateException("Cannot access socket.");
101             }
102
103             byte[] lastPacket = null;
104             DatagramPacket packet = new DatagramPacket(new byte[buffersize], buffersize);
105             packet.setData(new byte[buffersize]);
106
107             while (isConnected()) {
108                 try {
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());
114                 }
115                 InetAddress sourceIp;
116                 try {
117                     sourceIp = InetAddress.getByName(ipAddress);
118                     if (packet.getAddress().equals(sourceIp)) {
119                         lastPacket = packet.getData();
120                         readMessage(lastPacket);
121                     } else {
122                         logger.warn("Packet received from unknown source- {}", packet.getData());
123                     }
124                 } catch (UnknownHostException e) {
125                     logger.debug("Exception during address conversion - {}", e.getMessage());
126                 }
127             }
128         }
129     }
130
131     public void readMessage(byte[] message) {
132         EkeyPacketListener listener = this.packetListener;
133
134         if (listener != null && message.length != 0) {
135             listener.messageReceived(message);
136         }
137     }
138
139     public void addEkeyPacketListener(EkeyPacketListener listener) {
140         if (this.packetListener == null) {
141             this.packetListener = listener;
142         }
143     }
144
145     public void setConnected(boolean connected) {
146         this.connected = connected;
147     }
148
149     public boolean isConnected() {
150         return this.connected;
151     }
152
153     public void removeEkeyPacketListener(EkeyHandler ekeyHandler) {
154         if (this.packetListener != null) {
155             this.packetListener = null;
156         }
157     }
158 }