]> git.basschouten.com Git - openhab-addons.git/blob
f9b7f04ce88521e3715035af02d17f0ce554f7bc
[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.souliss.internal.protocol;
14
15 import java.net.BindException;
16 import java.net.DatagramPacket;
17 import java.net.DatagramSocket;
18 import java.net.InetSocketAddress;
19 import java.net.SocketTimeoutException;
20 import java.nio.channels.DatagramChannel;
21
22 import org.eclipse.jdt.annotation.NonNullByDefault;
23 import org.eclipse.jdt.annotation.Nullable;
24 import org.openhab.binding.souliss.internal.discovery.DiscoverResult;
25 import org.openhab.binding.souliss.internal.handler.SoulissGatewayHandler;
26 import org.openhab.core.thing.Bridge;
27 import org.openhab.core.util.HexUtils;
28 import org.slf4j.Logger;
29 import org.slf4j.LoggerFactory;
30
31 /**
32  * This class provide receive packet from network
33  *
34  * @author Tonino Fazio - Initial contribution
35  * @author Luca Calcaterra - Refactor for OH3
36  * @author Alessandro Del Pex - Souliss App
37  */
38 @NonNullByDefault
39 public class UDPListenDiscoverRunnable implements Runnable {
40
41     protected boolean bExit = false;
42     private @Nullable UDPDecoder decoder = null;
43
44     private final Logger logger = LoggerFactory.getLogger(UDPListenDiscoverRunnable.class);
45
46     private @Nullable SoulissGatewayHandler gwHandler;
47
48     public UDPListenDiscoverRunnable(Bridge bridge, @Nullable DiscoverResult pDiscoverResult) {
49         this.gwHandler = (SoulissGatewayHandler) bridge.getHandler();
50         decoder = new UDPDecoder(bridge, pDiscoverResult);
51     }
52
53     @Override
54     public void run() {
55         DatagramSocket socket = null;
56
57         while (!Thread.currentThread().isInterrupted()) {
58             try {
59                 // open socket for listening...
60                 var channel = DatagramChannel.open();
61                 socket = channel.socket();
62
63                 socket.setReuseAddress(true);
64                 socket.setBroadcast(true);
65
66                 var localGwHandler = this.gwHandler;
67                 if (localGwHandler != null) {
68                     var sa = new InetSocketAddress(localGwHandler.getGwConfig().preferredLocalPortNumber);
69                     socket.bind(sa);
70
71                     var buf = new byte[200];
72                     // receive request
73                     final var packet = new DatagramPacket(buf, buf.length);
74                     socket.setSoTimeout(60000);
75                     socket.receive(packet);
76                     buf = packet.getData();
77
78                     // **************** DECODER ********************
79                     logger.debug("Packet received (port {}) {}", socket.getLocalPort(), HexUtils.bytesToHex(buf));
80
81                     var localDecoder = this.decoder;
82                     if (localDecoder != null) {
83                         localDecoder.decodeVNetDatagram(packet);
84                     }
85                 }
86
87             } catch (BindException e) {
88                 logger.warn("UDP Port busy, Souliss already listening? {} ", e.getLocalizedMessage());
89                 try {
90                     if (socket != null && !socket.isClosed()) {
91                         socket.close();
92                     }
93                 } catch (Exception e1) {
94                     logger.warn("UDP socket close failed: {} ", e1.getLocalizedMessage());
95                 }
96             } catch (SocketTimeoutException e2) {
97                 logger.warn("UDP SocketTimeoutException close: {}", e2.getLocalizedMessage());
98                 if (socket != null && !socket.isClosed()) {
99                     socket.close();
100                 }
101             } catch (Exception ee) {
102                 logger.warn("Exception receiving-decoding message: {} ", ee.getLocalizedMessage());
103                 if (socket != null && !socket.isClosed()) {
104                     socket.close();
105                 }
106             } finally {
107                 var localGwHandler = this.gwHandler;
108                 if (socket != null && !socket.isClosed()) {
109                     socket.close();
110                 } else if ((socket == null) && (localGwHandler != null)) {
111                     localGwHandler.setBridgeStatus(false);
112                 }
113             }
114         }
115     }
116 }