]> git.basschouten.com Git - openhab-addons.git/blob
34fc953ceb8d5fcea0ee565cb18ec1630a3e2beb
[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.insteon.internal.driver;
14
15 import java.io.EOFException;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.OutputStream;
19
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.eclipse.jdt.annotation.Nullable;
22 import org.openhab.binding.insteon.internal.driver.hub.HubIOStream;
23 import org.openhab.core.io.transport.serial.SerialPortManager;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * Abstract class for implementation for I/O stream with anything that looks
29  * like a PLM (e.g. the insteon hubs, serial/usb connection etc)
30  *
31  * @author Bernd Pfrommer - Initial contribution
32  * @author Daniel Pfrommer - openHAB 1 insteonplm binding
33  * @author Rob Nielsen - Port to openHAB 2 insteon binding
34  */
35 @NonNullByDefault
36 @SuppressWarnings("null")
37 public abstract class IOStream {
38     private static final Logger logger = LoggerFactory.getLogger(IOStream.class);
39     protected @Nullable InputStream in = null;
40     protected @Nullable OutputStream out = null;
41     private volatile boolean stopped = false;
42
43     public void start() {
44         stopped = false;
45     }
46
47     public void stop() {
48         stopped = true;
49     }
50
51     /**
52      * read data from iostream
53      *
54      * @param b byte array (output)
55      * @param offset offset for placement into byte array
56      * @param readSize size to read
57      * @return number of bytes read
58      */
59     public int read(byte[] b, int offset, int readSize) throws InterruptedException, IOException {
60         int len = 0;
61         while (!stopped && len < 1) {
62             len = in.read(b, offset, readSize);
63             if (len == -1) {
64                 throw new EOFException();
65             }
66
67             if (Thread.interrupted()) {
68                 throw new InterruptedException();
69             }
70         }
71         return (len);
72     }
73
74     /**
75      * Write data to iostream
76      *
77      * @param b byte array to write
78      */
79     public void write(byte @Nullable [] b) throws IOException {
80         out.write(b);
81     }
82
83     /**
84      * Opens the IOStream
85      *
86      * @return true if open was successful, false if not
87      */
88     public abstract boolean open();
89
90     /**
91      * Closes the IOStream
92      */
93     public abstract void close();
94
95     /**
96      * Creates an IOStream from an allowed config string:
97      *
98      * /dev/ttyXYZ (serial port like e.g. usb: /dev/ttyUSB0 or alias /dev/insteon)
99      *
100      * /hub2/user:password@myinsteonhub.mydomain.com:25105,poll_time=1000 (insteon hub2 (2014))
101      *
102      * /hub/myinsteonhub.mydomain.com:9761
103      *
104      * /tcp/serialportserver.mydomain.com:port (serial port exposed via tcp, eg. ser2net)
105      *
106      * @param config
107      * @return reference to IOStream
108      */
109
110     public static IOStream create(@Nullable SerialPortManager serialPortManager, String config) {
111         if (config.startsWith("/hub2/")) {
112             return makeHub2014Stream(config);
113         } else if (config.startsWith("/hub/") || config.startsWith("/tcp/")) {
114             return makeTCPStream(config);
115         } else {
116             return new SerialIOStream(serialPortManager, config);
117         }
118     }
119
120     private static HubIOStream makeHub2014Stream(String config) {
121         @Nullable
122         String user = null;
123         @Nullable
124         String pass = null;
125         int pollTime = 1000; // poll time in milliseconds
126
127         // Get rid of the /hub2/ part and split off options at the end
128         String[] parts = config.substring(6).split(",");
129
130         // Parse the first part, the address
131         String[] adr = parts[0].split("@");
132         String[] hostPort;
133         if (adr.length > 1) {
134             String[] userPass = adr[0].split(":");
135             user = userPass[0];
136             pass = userPass[1];
137             hostPort = adr[1].split(":");
138         } else {
139             hostPort = parts[0].split(":");
140         }
141         HostPort hp = new HostPort(hostPort, 25105);
142         // check if additional options are given
143         if (parts.length > 1) {
144             if (parts[1].trim().startsWith("poll_time")) {
145                 pollTime = Integer.parseInt(parts[1].split("=")[1].trim());
146             }
147         }
148         return new HubIOStream(hp.host, hp.port, pollTime, user, pass);
149     }
150
151     private static TcpIOStream makeTCPStream(String config) {
152         // Get rid of the /hub/ part and split off options at the end, if any
153         String[] parts = config.substring(5).split(",");
154         String[] hostPort = parts[0].split(":");
155         HostPort hp = new HostPort(hostPort, 9761);
156         return new TcpIOStream(hp.host, hp.port);
157     }
158
159     @NonNullByDefault
160     private static class HostPort {
161         public String host = "localhost";
162         public int port = -1;
163
164         HostPort(String[] hostPort, int defaultPort) {
165             port = defaultPort;
166             host = hostPort[0];
167             try {
168                 if (hostPort.length > 1) {
169                     port = Integer.parseInt(hostPort[1]);
170                 }
171             } catch (NumberFormatException e) {
172                 logger.warn("bad format for port {} ", hostPort[1], e);
173             }
174         }
175     }
176 }