2 * Copyright (c) 2010-2021 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.rotel.internal.communication;
15 import java.io.InterruptedIOException;
16 import java.util.Arrays;
18 import org.eclipse.jdt.annotation.NonNullByDefault;
19 import org.openhab.binding.rotel.internal.RotelException;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
24 * A class that reads messages from the Rotel device in a dedicated thread
26 * @author Laurent Garnier - Initial contribution
29 public class RotelReaderThread extends Thread {
31 private final Logger logger = LoggerFactory.getLogger(RotelReaderThread.class);
33 private static final int READ_BUFFER_SIZE = 16;
35 private RotelConnector connector;
40 * @param connector the object that should handle the received message
41 * @param threadName the name of the thread
43 public RotelReaderThread(RotelConnector connector, String threadName) {
45 this.connector = connector;
50 logger.debug("Data listener started");
52 RotelProtocol protocol = connector.getProtocol();
53 final int size = (protocol == RotelProtocol.HEX)
54 ? (6 + connector.getModel().getRespNbChars() + connector.getModel().getRespNbFlags())
56 byte[] readDataBuffer = new byte[READ_BUFFER_SIZE];
57 byte[] dataBuffer = new byte[size];
58 boolean startCodeReached = false;
61 final char terminatingChar = (protocol == RotelProtocol.ASCII_V1) ? '!' : '$';
64 while (!Thread.interrupted()) {
65 int len = connector.readInput(readDataBuffer);
67 for (int i = 0; i < len; i++) {
68 if (protocol == RotelProtocol.HEX) {
69 if (readDataBuffer[i] == RotelConnector.START) {
70 startCodeReached = true;
74 if (startCodeReached) {
76 dataBuffer[index++] = readDataBuffer[i];
79 count = readDataBuffer[i];
80 } else if ((count > 0) && (index == (count + 3))) {
81 if ((readDataBuffer[i] & 0x000000FF) == 0x000000FD) {
84 byte[] msg = Arrays.copyOf(dataBuffer, index);
85 connector.handleIncomingMessage(msg);
86 startCodeReached = false;
92 dataBuffer[index++] = readDataBuffer[i];
94 if (readDataBuffer[i] == terminatingChar) {
96 dataBuffer[index - 1] = (byte) terminatingChar;
98 byte[] msg = Arrays.copyOf(dataBuffer, index);
99 connector.handleIncomingMessage(msg);
106 } catch (InterruptedIOException e) {
107 Thread.currentThread().interrupt();
108 logger.debug("Interrupted via InterruptedIOException");
109 } catch (RotelException e) {
110 logger.debug("Reading failed: {}", e.getMessage(), e);
111 connector.handleIncomingMessage(RotelConnector.READ_ERROR);
114 logger.debug("Data listener stopped");