]> git.basschouten.com Git - openhab-addons.git/blob
0a176ecb1136379f7ea3ee485515c0e75a11dc26
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2023 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.tplinksmarthome.internal;
14
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.OutputStream;
18 import java.net.Socket;
19 import java.net.UnknownHostException;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
25
26 /**
27  * This class acts as and interface to the physical device.
28  *
29  * @author Christian Fischer - Initial contribution
30  * @author Hilbrand Bouwkamp - Reorganized code and put connection in single class
31  */
32 @NonNullByDefault
33 public class Connection {
34
35     public static final int TP_LINK_SMART_HOME_PORT = 9999;
36     private static final int SOCKET_TIMEOUT_MILLISECONDS = 2_000;
37
38     private final Logger logger = LoggerFactory.getLogger(Connection.class);
39
40     private @Nullable String ipAddress;
41
42     /**
43      * Initializes a connection to the given ip address.
44      *
45      * @param ipAddress ip address of the connection
46      */
47     public Connection(@Nullable final String ipAddress) {
48         this.ipAddress = ipAddress;
49     }
50
51     /**
52      * Set the ip address to connect to.
53      *
54      * @param ipAddress The ip address to connect to
55      */
56     public void setIpAddress(final String ipAddress) {
57         this.ipAddress = ipAddress;
58     }
59
60     /**
61      * Sends the command, which is a json string, encrypted to the device and decrypts the json result and returns it
62      *
63      * @param command json command to send to the device
64      * @return decrypted returned json result from the device
65      * @throws IOException exception in case device not reachable
66      */
67     public synchronized String sendCommand(final String command) throws IOException {
68         logger.trace("Executing command: {}", command);
69         try (Socket socket = createSocket(); final OutputStream outputStream = socket.getOutputStream()) {
70             outputStream.write(CryptUtil.encryptWithLength(command));
71             final String response = readReturnValue(socket);
72
73             logger.trace("Command response: {}", response);
74             return response;
75         }
76     }
77
78     /**
79      * Reads and decrypts result returned from the device.
80      *
81      * @param socket socket to read result from
82      * @return decrypted result
83      * @throws IOException exception in case device not reachable
84      */
85     private String readReturnValue(final Socket socket) throws IOException {
86         try (InputStream is = socket.getInputStream()) {
87             return CryptUtil.decryptWithLength(is);
88         }
89     }
90
91     /**
92      * Wrapper around socket creation to make mocking possible.
93      *
94      * @return new Socket instance
95      * @throws UnknownHostException exception in case the host could not be determined
96      * @throws IOException exception in case device not reachable
97      */
98     protected Socket createSocket() throws UnknownHostException, IOException {
99         if (ipAddress == null) {
100             throw new IOException("Ip address not set. Wait for discovery or manually trigger discovery process.");
101         }
102         final Socket socket = new Socket(ipAddress, TP_LINK_SMART_HOME_PORT);
103
104         socket.setSoTimeout(SOCKET_TIMEOUT_MILLISECONDS);
105         return socket;
106     }
107 }