]> git.basschouten.com Git - openhab-addons.git/blob
e629c39949473f16e1248b2dd98192e4dc98d180
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 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.rotel.internal.communication;
14
15 import java.io.InterruptedIOException;
16 import java.util.Arrays;
17
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;
22
23 /**
24  * A class that reads messages from the Rotel device in a dedicated thread
25  *
26  * @author Laurent Garnier - Initial contribution
27  */
28 @NonNullByDefault
29 public class RotelReaderThread extends Thread {
30
31     private final Logger logger = LoggerFactory.getLogger(RotelReaderThread.class);
32
33     private static final int READ_BUFFER_SIZE = 16;
34
35     private RotelConnector connector;
36
37     /**
38      * Constructor
39      *
40      * @param connector the object that should handle the received message
41      * @param threadName the name of the thread
42      */
43     public RotelReaderThread(RotelConnector connector, String threadName) {
44         super(threadName);
45         this.connector = connector;
46     }
47
48     @Override
49     public void run() {
50         logger.debug("Data listener started");
51
52         RotelProtocol protocol = connector.getProtocol();
53         final int size = (protocol == RotelProtocol.HEX)
54                 ? (6 + connector.getModel().getRespNbChars() + connector.getModel().getRespNbFlags())
55                 : 64;
56         byte[] readDataBuffer = new byte[READ_BUFFER_SIZE];
57         byte[] dataBuffer = new byte[size];
58         boolean startCodeReached = false;
59         int count = 0;
60         int index = 0;
61         final char terminatingChar = (protocol == RotelProtocol.ASCII_V1) ? '!' : '$';
62
63         try {
64             while (!Thread.interrupted()) {
65                 int len = connector.readInput(readDataBuffer);
66                 if (len > 0) {
67                     for (int i = 0; i < len; i++) {
68                         if (protocol == RotelProtocol.HEX) {
69                             if (readDataBuffer[i] == RotelConnector.START) {
70                                 startCodeReached = true;
71                                 count = 0;
72                                 index = 0;
73                             }
74                             if (startCodeReached) {
75                                 if (index < size) {
76                                     dataBuffer[index++] = readDataBuffer[i];
77                                 }
78                                 if (index == 2) {
79                                     count = readDataBuffer[i];
80                                 } else if ((count > 0) && (index == (count + 3))) {
81                                     if ((readDataBuffer[i] & 0x000000FF) == 0x000000FD) {
82                                         count++;
83                                     } else {
84                                         byte[] msg = Arrays.copyOf(dataBuffer, index);
85                                         connector.handleIncomingMessage(msg);
86                                         startCodeReached = false;
87                                     }
88                                 }
89                             }
90                         } else {
91                             if (index < size) {
92                                 dataBuffer[index++] = readDataBuffer[i];
93                             }
94                             if (readDataBuffer[i] == terminatingChar) {
95                                 if (index >= size) {
96                                     dataBuffer[index - 1] = (byte) terminatingChar;
97                                 }
98                                 byte[] msg = Arrays.copyOf(dataBuffer, index);
99                                 connector.handleIncomingMessage(msg);
100                                 index = 0;
101                             }
102                         }
103                     }
104                 }
105             }
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);
112         }
113
114         logger.debug("Data listener stopped");
115     }
116 }