/** * Copyright (c) 2010-2016, openHAB.org and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.neohub.internal; import static java.nio.charset.StandardCharsets.US_ASCII; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.InetSocketAddress; import java.net.Socket; import org.apache.commons.io.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * NeoHubConnector handles the ASCII based TCP communication between openhab and * neohub. * * @author Sebastian Prehn * @since 1.5.0 */ public class NeoHubConnector { private static final Logger logger = LoggerFactory.getLogger(NeoHubConnector.class); /** * Name of host or IP to connect to. */ private final String hostname; /** * The port to connect to. */ private final int port; /** * Maximum time in ms to wait for neohub's response. Defaults to 5000ms. */ private final int timeout = 5000; public NeoHubConnector(final String hostname, final int port) { this.hostname = hostname; this.port = port; } /** * Sends the message over the network and provides the response to the * response handler. * * @param msg * message to neohub * @param handler * handler to process the response, may be <code>null</code> * @return result of handler or <code>null</code> if network problem * occurred */ public <T> T sendMessage(final String msg, final ResponseHandler<T> handler) { final StringBuilder response = new StringBuilder(); final Socket socket = new Socket(); try { socket.connect(new InetSocketAddress(hostname, port), timeout); final InputStreamReader in = new InputStreamReader(socket.getInputStream(), US_ASCII); final OutputStreamWriter out = new OutputStreamWriter(socket.getOutputStream(), US_ASCII); logger.debug(">> {}", msg); out.write(msg); out.write(0); // NUL terminate the command string out.flush(); int l; while ((l = in.read()) > 0) {// NUL termination & end of stream (-1) response.append((char) l); } } catch (final IOException e) { logger.error("Failed to connect to neohub [host '{}' port '{}' timeout '{}']", new Object[] { hostname, port, timeout }); logger.debug("Failed to connect to neohub.", e); return null; } finally { IOUtils.closeQuietly(socket); } final String responseStr = response.toString(); logger.debug("<< {}", responseStr); if (handler != null) { return handler.onResponse(responseStr); } else { return null; } } }