]> git.basschouten.com Git - openhab-addons.git/blob
35f54d8b227956a60e8809e0ebd044ac4045df31
[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.lcn.internal.connection;
14
15 import java.io.IOException;
16 import java.net.InetSocketAddress;
17 import java.net.StandardSocketOptions;
18 import java.nio.channels.AsynchronousSocketChannel;
19 import java.nio.channels.CompletionHandler;
20
21 import org.eclipse.jdt.annotation.NonNullByDefault;
22 import org.eclipse.jdt.annotation.Nullable;
23 import org.openhab.binding.lcn.internal.common.LcnException;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
26
27 /**
28  * This state is active during the socket creation, host name resolving and waiting for the TCP connection to become
29  * established.
30  *
31  * @author Fabian Wolter - Initial Contribution
32  */
33 @NonNullByDefault
34 public class ConnectionStateConnecting extends AbstractConnectionState {
35     private final Logger logger = LoggerFactory.getLogger(ConnectionStateConnecting.class);
36
37     public ConnectionStateConnecting(ConnectionStateMachine context) {
38         super(context);
39     }
40
41     @Override
42     public void startWorking() {
43         connection.clearRuntimeData();
44
45         logger.debug("Connecting to {}:{} ...", connection.getSettings().getAddress(),
46                 connection.getSettings().getPort());
47
48         try {
49             // Open Channel by using the system-wide default AynchronousChannelGroup.
50             // So, Threads are used or re-used on demand by the JVM.
51             AsynchronousSocketChannel channel = AsynchronousSocketChannel.open();
52             // Do not wait until some buffer is filled, send PCK commands immediately
53             channel.setOption(StandardSocketOptions.TCP_NODELAY, true);
54             connection.setSocketChannel(channel);
55
56             InetSocketAddress address = new InetSocketAddress(connection.getSettings().getAddress(),
57                     connection.getSettings().getPort());
58
59             if (address.isUnresolved()) {
60                 throw new LcnException("Could not resolve hostname");
61             }
62
63             channel.connect(address, null, new CompletionHandler<@Nullable Void, @Nullable Void>() {
64                 @Override
65                 public void completed(@Nullable Void result, @Nullable Void attachment) {
66                     connection.readAndProcess();
67                     nextState(ConnectionStateSendUsername::new);
68                 }
69
70                 @Override
71                 public void failed(@Nullable Throwable e, @Nullable Void attachment) {
72                     handleConnectionFailure(e);
73                 }
74             });
75         } catch (IOException | LcnException e) {
76             handleConnectionFailure(e);
77         }
78     }
79
80     private void handleConnectionFailure(@Nullable Throwable e) {
81         String message;
82         if (e != null) {
83             logger.warn("Could not connect to {}:{}: {}", connection.getSettings().getAddress(),
84                     connection.getSettings().getPort(), e.getMessage());
85             message = e.getMessage();
86         } else {
87             message = "";
88         }
89         connection.getCallback().onOffline(message);
90         context.handleConnectionFailed(e);
91     }
92
93     @Override
94     public void onPckMessageReceived(String data) {
95         // nothing
96     }
97 }