]> git.basschouten.com Git - openhab-addons.git/blob
1d80f19ccdf5222d8269afbe0da7fe2952f1b2d5
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2021 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.xmppclient.internal;
14
15 import java.io.IOException;
16 import java.util.HashSet;
17 import java.util.Set;
18
19 import org.jivesoftware.smack.AbstractXMPPConnection;
20 import org.jivesoftware.smack.ConnectionListener;
21 import org.jivesoftware.smack.ReconnectionManager;
22 import org.jivesoftware.smack.SmackException;
23 import org.jivesoftware.smack.XMPPConnection;
24 import org.jivesoftware.smack.XMPPException;
25 import org.jivesoftware.smack.chat2.Chat;
26 import org.jivesoftware.smack.chat2.ChatManager;
27 import org.jivesoftware.smack.chat2.IncomingChatMessageListener;
28 import org.jivesoftware.smack.packet.Message;
29 import org.jivesoftware.smack.tcp.XMPPTCPConnection;
30 import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;
31 import org.jivesoftware.smackx.disco.ServiceDiscoveryManager;
32 import org.jivesoftware.smackx.disco.packet.DiscoverInfo.Identity;
33 import org.jxmpp.jid.EntityBareJid;
34 import org.jxmpp.jid.impl.JidCreate;
35 import org.jxmpp.stringprep.XmppStringprepException;
36 import org.openhab.binding.xmppclient.internal.handler.XMPPClientMessageSubscriber;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40 /**
41  * The {@link XMPPClient} is lib for handling XMPP connection and messaging
42  *
43  * @author Pavel Gololobov - Initial contribution
44  */
45 public class XMPPClient implements IncomingChatMessageListener, ConnectionListener {
46     private final Logger logger = LoggerFactory.getLogger(XMPPClient.class);
47     private AbstractXMPPConnection connection;
48     private ChatManager chatManager;
49     private Set<XMPPClientMessageSubscriber> subscribers = new HashSet<>();
50
51     public void subscribe(XMPPClientMessageSubscriber channel) {
52         logger.debug("Channel {} subscribed", channel.getName());
53         subscribers.add(channel);
54     }
55
56     public void unsubscribe(XMPPClientMessageSubscriber channel) {
57         logger.debug("Channel {} unsubscribed", channel.getName());
58         subscribers.remove(channel);
59     }
60
61     public void connect(String host, Integer port, String login, String domain, String password)
62             throws XMPPException, SmackException, IOException {
63         disconnect();
64         String serverHost = domain;
65         if ((host != null) && !host.isEmpty()) {
66             serverHost = host;
67         }
68
69         XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration.builder() //
70                 .setHost(serverHost) //
71                 .setPort(port) //
72                 .setUsernameAndPassword(login, password) //
73                 .setXmppDomain(domain) //
74                 .build();
75
76         connection = new XMPPTCPConnection(config);
77         connection.addConnectionListener(this);
78
79         ReconnectionManager reconnectionManager = ReconnectionManager.getInstanceFor(connection);
80         reconnectionManager.enableAutomaticReconnection();
81
82         Identity identity = new Identity("client", "openHAB", "bot");
83         ServiceDiscoveryManager sdm = ServiceDiscoveryManager.getInstanceFor(connection);
84         sdm.setIdentity(identity);
85
86         try {
87             connection.connect().login();
88         } catch (InterruptedException ex) {
89         }
90
91         chatManager = ChatManager.getInstanceFor(connection);
92         chatManager.addIncomingListener(this);
93     }
94
95     public void disconnect() {
96         if (connection != null) {
97             connection.disconnect();
98         }
99     }
100
101     public void sendMessage(String to, String message) {
102         if (connection == null) {
103             logger.warn("XMPP connection is null");
104             return;
105         }
106         if (chatManager == null) {
107             logger.warn("XMPP chatManager is null");
108             return;
109         }
110         try {
111             EntityBareJid jid = JidCreate.entityBareFrom(to);
112             Chat chat = chatManager.chatWith(jid);
113             chat.send(message);
114         } catch (XmppStringprepException | SmackException.NotConnectedException | InterruptedException e) {
115             logger.info("XMPP message sending error", e);
116         }
117     }
118
119     @Override
120     public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
121         logger.debug("XMPP {} says {}", from.asBareJid().toString(), message.getBody());
122         for (XMPPClientMessageSubscriber subscriber : subscribers) {
123             logger.debug("Push to subscriber {}", subscriber.getName());
124             subscriber.processMessage(from.asBareJid().toString(), message.getBody());
125         }
126     }
127
128     @Override
129     public void connected(XMPPConnection connection) {
130         logger.debug("Connected to XMPP server.");
131     }
132
133     @Override
134     public void authenticated(XMPPConnection connection, boolean resumed) {
135         logger.debug("Authenticated to XMPP server.");
136     }
137
138     @Override
139     public void connectionClosed() {
140         logger.debug("XMPP connection was closed.");
141     }
142
143     @Override
144     public void connectionClosedOnError(Exception e) {
145         logger.debug("Connection to XMPP server was lost.");
146         if (connection != null) {
147             connection.disconnect();
148             try {
149                 connection.connect().login();
150             } catch (SmackException | IOException | XMPPException | InterruptedException ex) {
151                 logger.info("XMPP connection error", ex);
152             }
153         }
154     }
155 }