2 * Copyright (c) 2010-2020 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.epsonprojector.internal.connector;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.net.Socket;
19 import java.nio.charset.StandardCharsets;
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.epsonprojector.internal.EpsonProjectorException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
28 * Connector for TCP communication.
30 * @author Pauli Anttila - Initial contribution
31 * @author Michael Lobstein - Improvements for OH3
34 public class EpsonProjectorTcpConnector implements EpsonProjectorConnector {
36 private final Logger logger = LoggerFactory.getLogger(EpsonProjectorTcpConnector.class);
37 private final String ip;
38 private final int port;
40 private @Nullable Socket socket = null;
41 private @Nullable InputStream in = null;
42 private @Nullable OutputStream out = null;
44 public EpsonProjectorTcpConnector(String ip, int port) {
50 public void connect() throws EpsonProjectorException {
51 logger.debug("Open connection to address'{}:{}'", ip, port);
54 Socket socket = new Socket(ip, port);
56 in = socket.getInputStream();
57 out = socket.getOutputStream();
58 } catch (IOException e) {
59 throw new EpsonProjectorException(e);
64 public void disconnect() throws EpsonProjectorException {
65 OutputStream out = this.out;
68 logger.debug("Close tcp out stream");
71 } catch (IOException e) {
72 logger.debug("Error occurred when closing tcp out stream: {}", e.getMessage());
76 InputStream in = this.in;
78 logger.debug("Close tcp in stream");
81 } catch (IOException e) {
82 logger.debug("Error occurred when closing tcp in stream: {}", e.getMessage());
86 Socket socket = this.socket;
88 logger.debug("Closing socket");
91 } catch (IOException e) {
92 logger.debug("Error occurred when closing tcp socket: {}", e.getMessage());
100 logger.debug("Closed");
104 public String sendMessage(String data, int timeout) throws EpsonProjectorException {
105 InputStream in = this.in;
106 OutputStream out = this.out;
108 if (in == null || out == null) {
116 // flush input stream
117 if (in.markSupported()) {
120 while (in.available() > 0) {
121 int availableBytes = in.available();
123 if (availableBytes > 0) {
124 byte[] tmpData = new byte[availableBytes];
125 in.read(tmpData, 0, availableBytes);
129 return sendMmsg(data, timeout);
133 } catch (IOException e) {
134 logger.debug("IO error occurred...reconnect and resend once: {}", e.getMessage());
139 return sendMmsg(data, timeout);
140 } catch (IOException e1) {
141 throw new EpsonProjectorException(e);
146 private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
149 InputStream in = this.in;
150 OutputStream out = this.out;
152 if (in != null && out != null) {
153 out.write(data.getBytes(StandardCharsets.US_ASCII));
154 out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
157 long startTime = System.currentTimeMillis();
158 long elapsedTime = 0;
160 while (elapsedTime < timeout) {
161 int availableBytes = in.available();
162 if (availableBytes > 0) {
163 byte[] tmpData = new byte[availableBytes];
164 int readBytes = in.read(tmpData, 0, availableBytes);
165 resp = resp.concat(new String(tmpData, 0, readBytes, StandardCharsets.US_ASCII));
167 if (resp.contains(":")) {
173 } catch (InterruptedException e) {
174 throw new EpsonProjectorException(e);
178 elapsedTime = System.currentTimeMillis() - startTime;