2 * Copyright (c) 2010-2023 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.souliss.internal.protocol;
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;
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;
32 * This class provide receive packet from network
34 * @author Tonino Fazio - Initial contribution
35 * @author Luca Calcaterra - Refactor for OH3
36 * @author Alessandro Del Pex - Souliss App
39 public class UDPListenDiscoverRunnable implements Runnable {
41 protected boolean bExit = false;
42 private @Nullable UDPDecoder decoder = null;
44 private final Logger logger = LoggerFactory.getLogger(UDPListenDiscoverRunnable.class);
46 private @Nullable SoulissGatewayHandler gwHandler;
48 public UDPListenDiscoverRunnable(Bridge bridge, @Nullable DiscoverResult pDiscoverResult) {
49 this.gwHandler = (SoulissGatewayHandler) bridge.getHandler();
50 decoder = new UDPDecoder(bridge, pDiscoverResult);
55 DatagramSocket socket = null;
57 while (!Thread.currentThread().isInterrupted()) {
59 // open socket for listening...
60 var channel = DatagramChannel.open();
61 socket = channel.socket();
63 socket.setReuseAddress(true);
64 socket.setBroadcast(true);
66 var localGwHandler = this.gwHandler;
67 if (localGwHandler != null) {
68 var sa = new InetSocketAddress(localGwHandler.getGwConfig().preferredLocalPortNumber);
71 var buf = new byte[200];
73 final var packet = new DatagramPacket(buf, buf.length);
74 socket.setSoTimeout(60000);
75 socket.receive(packet);
76 buf = packet.getData();
78 // **************** DECODER ********************
79 logger.debug("Packet received (port {}) {}", socket.getLocalPort(), HexUtils.bytesToHex(buf));
81 var localDecoder = this.decoder;
82 if (localDecoder != null) {
83 localDecoder.decodeVNetDatagram(packet);
87 } catch (BindException e) {
88 logger.warn("UDP Port busy, Souliss already listening? {} ", e.getLocalizedMessage());
90 if (socket != null && !socket.isClosed()) {
93 } catch (Exception e1) {
94 logger.warn("UDP socket close failed: {} ", e1.getLocalizedMessage());
96 } catch (SocketTimeoutException e2) {
97 logger.warn("UDP SocketTimeoutException close: {}", e2.getLocalizedMessage());
98 if (socket != null && !socket.isClosed()) {
101 } catch (Exception ee) {
102 logger.warn("Exception receiving-decoding message: {} ", ee.getLocalizedMessage());
103 if (socket != null && !socket.isClosed()) {
107 var localGwHandler = this.gwHandler;
108 if (socket != null && !socket.isClosed()) {
110 } else if ((socket == null) && (localGwHandler != null)) {
111 localGwHandler.setBridgeStatus(false);