]> git.basschouten.com Git - openhab-addons.git/blob
aea7eefc4951bd455f44860b513b3331212f4b52
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2020 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.epsonprojector.internal.connector;
14
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;
20
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;
26
27 /**
28  * Connector for TCP communication.
29  *
30  * @author Pauli Anttila - Initial contribution
31  * @author Michael Lobstein - Improvements for OH3
32  */
33 @NonNullByDefault
34 public class EpsonProjectorTcpConnector implements EpsonProjectorConnector {
35
36     private final Logger logger = LoggerFactory.getLogger(EpsonProjectorTcpConnector.class);
37     private final String ip;
38     private final int port;
39
40     private @Nullable Socket socket = null;
41     private @Nullable InputStream in = null;
42     private @Nullable OutputStream out = null;
43
44     public EpsonProjectorTcpConnector(String ip, int port) {
45         this.ip = ip;
46         this.port = port;
47     }
48
49     @Override
50     public void connect() throws EpsonProjectorException {
51         logger.debug("Open connection to address'{}:{}'", ip, port);
52
53         try {
54             Socket socket = new Socket(ip, port);
55             this.socket = socket;
56             in = socket.getInputStream();
57             out = socket.getOutputStream();
58         } catch (IOException e) {
59             throw new EpsonProjectorException(e);
60         }
61     }
62
63     @Override
64     public void disconnect() throws EpsonProjectorException {
65         OutputStream out = this.out;
66
67         if (out != null) {
68             logger.debug("Close tcp out stream");
69             try {
70                 out.close();
71             } catch (IOException e) {
72                 logger.debug("Error occurred when closing tcp out stream: {}", e.getMessage());
73             }
74         }
75
76         InputStream in = this.in;
77         if (in != null) {
78             logger.debug("Close tcp in stream");
79             try {
80                 in.close();
81             } catch (IOException e) {
82                 logger.debug("Error occurred when closing tcp in stream: {}", e.getMessage());
83             }
84         }
85
86         Socket socket = this.socket;
87         if (socket != null) {
88             logger.debug("Closing socket");
89             try {
90                 socket.close();
91             } catch (IOException e) {
92                 logger.debug("Error occurred when closing tcp socket: {}", e.getMessage());
93             }
94         }
95
96         this.socket = null;
97         this.out = null;
98         this.in = null;
99
100         logger.debug("Closed");
101     }
102
103     @Override
104     public String sendMessage(String data, int timeout) throws EpsonProjectorException {
105         InputStream in = this.in;
106         OutputStream out = this.out;
107
108         if (in == null || out == null) {
109             connect();
110             in = this.in;
111             out = this.out;
112         }
113
114         try {
115             if (in != null) {
116                 // flush input stream
117                 if (in.markSupported()) {
118                     in.reset();
119                 } else {
120                     while (in.available() > 0) {
121                         int availableBytes = in.available();
122
123                         if (availableBytes > 0) {
124                             byte[] tmpData = new byte[availableBytes];
125                             in.read(tmpData, 0, availableBytes);
126                         }
127                     }
128                 }
129                 return sendMmsg(data, timeout);
130             } else {
131                 return "";
132             }
133         } catch (IOException e) {
134             logger.debug("IO error occurred...reconnect and resend once: {}", e.getMessage());
135             disconnect();
136             connect();
137
138             try {
139                 return sendMmsg(data, timeout);
140             } catch (IOException e1) {
141                 throw new EpsonProjectorException(e);
142             }
143         }
144     }
145
146     private String sendMmsg(String data, int timeout) throws IOException, EpsonProjectorException {
147         String resp = "";
148
149         InputStream in = this.in;
150         OutputStream out = this.out;
151
152         if (in != null && out != null) {
153             out.write(data.getBytes(StandardCharsets.US_ASCII));
154             out.write("\r\n".getBytes(StandardCharsets.US_ASCII));
155             out.flush();
156
157             long startTime = System.currentTimeMillis();
158             long elapsedTime = 0;
159
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));
166
167                     if (resp.contains(":")) {
168                         return resp;
169                     }
170                 } else {
171                     try {
172                         Thread.sleep(100);
173                     } catch (InterruptedException e) {
174                         throw new EpsonProjectorException(e);
175                     }
176                 }
177
178                 elapsedTime = System.currentTimeMillis() - startTime;
179             }
180         }
181         return resp;
182     }
183 }