]> git.basschouten.com Git - openhab-addons.git/blob
301fefb8e1755241b991933a84907ee1231b3584
[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.neohub.internal;
14
15 import static java.nio.charset.StandardCharsets.US_ASCII;
16
17 import java.io.IOException;
18 import java.io.InputStreamReader;
19 import java.io.OutputStreamWriter;
20 import java.net.InetSocketAddress;
21 import java.net.Socket;
22
23 import org.eclipse.jdt.annotation.NonNullByDefault;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Handles the ASCII based communication via TCP socket between openHAB and NeoHub
29  *
30  * @author Sebastian Prehn - Initial contribution
31  * @author Andrew Fiddian-Green - Refactoring for openHAB v2.x
32  *
33  */
34 @NonNullByDefault
35 public class NeoHubSocket extends NeoHubSocketBase {
36
37     private final Logger logger = LoggerFactory.getLogger(NeoHubSocket.class);
38
39     public NeoHubSocket(NeoHubConfiguration config) {
40         super(config);
41     }
42
43     @Override
44     public synchronized String sendMessage(final String requestJson) throws IOException, NeoHubException {
45         IOException caughtException = null;
46         StringBuilder builder = new StringBuilder();
47
48         try (Socket socket = new Socket()) {
49             int port = config.portNumber > 0 ? config.portNumber : NeoHubBindingConstants.PORT_TCP;
50             socket.connect(new InetSocketAddress(config.hostName, port), config.socketTimeout * 1000);
51             socket.setSoTimeout(config.socketTimeout * 1000);
52
53             try (InputStreamReader reader = new InputStreamReader(socket.getInputStream(), US_ASCII);
54                     OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream(), US_ASCII)) {
55                 if (logger.isDebugEnabled()) {
56                     logger.debug("sending {} characters..", requestJson.length());
57                     logger.debug(">> {}", requestJson);
58                 }
59
60                 writer.write(requestJson);
61                 writer.write(0); // NULL terminate the command string
62                 writer.flush();
63                 socket.shutdownOutput();
64
65                 if (logger.isTraceEnabled()) {
66                     logger.trace("sent {} characters..", requestJson.length());
67                 }
68
69                 int inChar;
70                 boolean done = false;
71                 // read until end of stream
72                 while ((inChar = reader.read()) != -1) {
73                     // a JSON block is terminated by a newline or NULL
74                     if (!(done |= (inChar == '\n') || (inChar == 0))) {
75                         builder.append((char) inChar);
76                     }
77                 }
78             }
79         } catch (IOException e) {
80             // catch IOExceptions here, and save them to be re-thrown later
81             caughtException = e;
82         }
83
84         String responseJson = builder.toString();
85
86         if (logger.isTraceEnabled()) {
87             logger.trace("received {} characters..", responseJson.length());
88             logger.trace("<< {}", responseJson);
89         } else
90
91         if (logger.isDebugEnabled()) {
92             logger.debug("received {} characters (set log level to TRACE to see full string)..", responseJson.length());
93             logger.debug("<< {} ...", responseJson.substring(0, Math.min(responseJson.length(), 30)));
94         }
95
96         // if any type of Exception was caught above, re-throw it again to the caller
97         if (caughtException != null) {
98             throw caughtException;
99         }
100
101         if (responseJson.isEmpty()) {
102             throw new NeoHubException("empty response string");
103         }
104
105         return responseJson;
106     }
107
108     @Override
109     public void close() {
110         // nothing to do
111     }
112 }