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.dsmr.internal.device.connector;
15 import java.io.BufferedInputStream;
16 import java.io.IOException;
17 import java.io.InputStream;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.eclipse.jdt.annotation.Nullable;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
25 * Base class for connectors. Reads data from an input stream. Subclasses should implement connection specific methods
26 * and trigger the reading of the data.
28 * @author M. Volaart - Initial contribution
29 * @author Hilbrand Bouwkamp - Major refactoring. Code moved around from other classes.
32 class DSMRBaseConnector {
34 private final Logger logger = LoggerFactory.getLogger(DSMRBaseConnector.class);
37 * Listener to send received data and errors to.
39 protected final DSMRConnectorListener dsmrConnectorListener;
42 * 1Kbyte buffer for storing received data.
44 private final byte[] buffer = new byte[1024]; // 1K
47 * Read lock to have 1 process reading at a time.
49 private final Object readLock = new Object();
52 * Keeps track of the open state of the connector.
56 public DSMRBaseConnector(DSMRConnectorListener connectorListener) {
57 this.dsmrConnectorListener = connectorListener;
61 * Input stream reading the Serial port.
63 private @Nullable BufferedInputStream inputStream;
66 * Opens the connector with the given stream to read data from.
68 * @param inputStream input stream to read data from
69 * @throws IOException throws exception in case input stream is null
71 protected void open(@Nullable InputStream inputStream) throws IOException {
72 if (inputStream == null) {
73 throw new IOException("Inputstream is null");
75 this.inputStream = new BufferedInputStream(inputStream);
80 * @return Returns true if connector is in state open
82 protected boolean isOpen() {
87 * Closes the connector.
89 protected void close() {
91 if (inputStream != null) {
94 } catch (IOException ioe) {
95 logger.debug("Failed to close reader", ioe);
102 * Reads available data from the input stream.
104 protected void handleDataAvailable() {
106 synchronized (readLock) {
107 BufferedInputStream localInputStream = inputStream;
109 if (localInputStream != null) {
110 int bytesAvailable = localInputStream.available();
111 while (bytesAvailable > 0) {
112 int bytesAvailableRead = localInputStream.read(buffer, 0,
113 Math.min(bytesAvailable, buffer.length));
115 if (open && bytesAvailableRead > 0) {
116 dsmrConnectorListener.handleData(buffer, bytesAvailableRead);
118 logger.debug("Expected bytes {} to read, but {} bytes were read", bytesAvailable,
121 bytesAvailable = localInputStream.available();
125 } catch (IOException e) {
126 dsmrConnectorListener.handleErrorEvent(DSMRConnectorErrorEvent.READ_ERROR);
127 logger.debug("Exception on read data", e);