diff --git a/EasyModbus/.classpath b/EasyModbus/.classpath index d95cd7e..f56f9df 100644 --- a/EasyModbus/.classpath +++ b/EasyModbus/.classpath @@ -1,11 +1,21 @@ <?xml version="1.0" encoding="UTF-8"?> <classpath> - <classpathentry kind="src" path="src"> + <classpathentry including="**/*.java" kind="src" output="target/classes" path="src"> <attributes> <attribute name="org.eclipse.jdt.launching.CLASSPATH_ATTR_LIBRARY_PATH_ENTRY" value="C:/Users/Admin/OneDrive/EasyModbusJavaGit/EasyModbus/lib"/> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> </attributes> </classpathentry> - <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> - <classpathentry exported="true" kind="lib" path="C:/Users/Admin/OneDrive/EasyModbusJavaGit/EasyModbus/lib/jssc.jar"/> - <classpathentry kind="output" path="bin"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> </classpath> diff --git a/EasyModbus/.gitignore b/EasyModbus/.gitignore index 852a6f7..92532f8 100644 --- a/EasyModbus/.gitignore +++ b/EasyModbus/.gitignore @@ -1,4 +1,5 @@ -/doc/ -/EasyModbus/ -/nbproject/ -/manifest.mf +/doc/ +/EasyModbus/ +/nbproject/ +/manifest.mf +/target/ diff --git a/EasyModbus/.project b/EasyModbus/.project index 7d794ab..63d02de 100644 --- a/EasyModbus/.project +++ b/EasyModbus/.project @@ -10,8 +10,14 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> <nature>org.eclipse.jdt.core.javanature</nature> </natures> </projectDescription> diff --git a/EasyModbus/.settings/org.eclipse.jdt.core.prefs b/EasyModbus/.settings/org.eclipse.jdt.core.prefs index 6aa22b2..8c7b5f8 100644 --- a/EasyModbus/.settings/org.eclipse.jdt.core.prefs +++ b/EasyModbus/.settings/org.eclipse.jdt.core.prefs @@ -8,6 +8,8 @@ org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary= org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable org.eclipse.jdt.core.compiler.annotation.nullable.secondary= org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning org.eclipse.jdt.core.compiler.problem.autoboxing=ignore org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning @@ -93,3 +95,4 @@ org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/EasyModbus/.settings/org.eclipse.m2e.core.prefs b/EasyModbus/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000..14b697b --- /dev/null +++ b/EasyModbus/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/EasyModbus/lib/jssc.jar b/EasyModbus/lib/jssc.jar deleted file mode 100644 index c0ca297..0000000 Binary files a/EasyModbus/lib/jssc.jar and /dev/null differ diff --git a/EasyModbus/pom.xml b/EasyModbus/pom.xml new file mode 100644 index 0000000..f6b586c --- /dev/null +++ b/EasyModbus/pom.xml @@ -0,0 +1,42 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>EasyModbus</groupId> + <artifactId>EasyModbus</artifactId> + <version>0.0.1-SNAPSHOT</version> + <dependencies> + <!-- https://mvnrepository.com/artifact/org.eclipse.paho/org.eclipse.paho.client.mqttv3 --> + <dependency> + <groupId>org.eclipse.paho</groupId> + <artifactId>org.eclipse.paho.client.mqttv3</artifactId> + <version>1.2.0</version> + </dependency> + <dependency> + <groupId>org.scream3r</groupId> + <artifactId>jssc</artifactId> + <version>2.8.0</version> + </dependency> + </dependencies> + <build> + <sourceDirectory>src</sourceDirectory> + <resources> + <resource> + <directory>src</directory> + <excludes> + <exclude>**/*.java</exclude> + </excludes> + </resource> + </resources> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.7.0</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> +</project> \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/BufferedMessage.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/BufferedMessage.java deleted file mode 100644 index e01e61a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/BufferedMessage.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Initial Contribution for Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3; - -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; - -/** - * A BufferedMessage contains an MqttWire Message and token - * it allows both message and token to be buffered when the client - * is in resting state - */ -public class BufferedMessage { - - private MqttWireMessage message; - private MqttToken token; - - public BufferedMessage(MqttWireMessage message, MqttToken token){ - this.message = message; - this.token = token; - } - - public MqttWireMessage getMessage() { - return message; - } - - public MqttToken getToken() { - return token; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/DisconnectedBufferOptions.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/DisconnectedBufferOptions.java deleted file mode 100644 index 21ea06e..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/DisconnectedBufferOptions.java +++ /dev/null @@ -1,91 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Initial Contribution for Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3; - -/** - * Holds the set of options that govern the behaviour - * of Offline (or Disconnected) buffering of messages - */ -public class DisconnectedBufferOptions { - - /** - * The default size of the disconnected buffer - */ - public static final int DISCONNECTED_BUFFER_SIZE_DEFAULT = 5000; - - public static final boolean DISCONNECTED_BUFFER_ENABLED_DEFAULT = false; - - public static final boolean PERSIST_DISCONNECTED_BUFFER_DEFAULT = false; - - public static final boolean DELETE_OLDEST_MESSAGES_DEFAULT = false; - - private int bufferSize = DISCONNECTED_BUFFER_SIZE_DEFAULT; - private boolean bufferEnabled = DISCONNECTED_BUFFER_ENABLED_DEFAULT; - private boolean persistBuffer = PERSIST_DISCONNECTED_BUFFER_DEFAULT; - private boolean deleteOldestMessages = DELETE_OLDEST_MESSAGES_DEFAULT; - - /** - * Constructs a new <code>DisconnectedBufferOptions</code> object using the - * default values. - * - * The defaults are: - * <ul> - * <li>The disconnected buffer is disabled</li> - * <li>The buffer holds 5000 messages</li> - * <li>The buffer is not persisted</li> - * <li>Once the buffer is full, old messages are not deleted</li> - * </ul> - * More information about these values can be found in the setter methods. - */ - public DisconnectedBufferOptions() { - // Do Nothing. - } - - public int getBufferSize() { - return bufferSize; - } - - public void setBufferSize(int bufferSize) { - if (bufferSize < 1) { - throw new IllegalArgumentException(); - } - this.bufferSize = bufferSize; - } - - public boolean isBufferEnabled() { - return bufferEnabled; - } - - public void setBufferEnabled(boolean bufferEnabled) { - this.bufferEnabled = bufferEnabled; - } - - public boolean isPersistBuffer() { - return persistBuffer; - } - - public void setPersistBuffer(boolean persistBuffer) { - this.persistBuffer = persistBuffer; - } - - public boolean isDeleteOldestMessages() { - return deleteOldestMessages; - } - - public void setDeleteOldestMessages(boolean deleteOldestMessages) { - this.deleteOldestMessages = deleteOldestMessages; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttActionListener.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttActionListener.java deleted file mode 100644 index 51f1e58..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttActionListener.java +++ /dev/null @@ -1,30 +0,0 @@ -package org.eclipse.paho.client.mqttv3; - -/** - * Implementors of this interface will be notified when an asynchronous action completes. - * - * <p>A listener is registered on an MqttToken and a token is associated - * with an action like connect or publish. When used with tokens on the MqttAsyncClient - * the listener will be called back on the MQTT client's thread. The listener will be informed - * if the action succeeds or fails. It is important that the listener returns control quickly - * otherwise the operation of the MQTT client will be stalled. - * </p> - */ -public interface IMqttActionListener { - /** - * This method is invoked when an action has completed successfully. - * @param asyncActionToken associated with the action that has completed - */ - public void onSuccess(IMqttToken asyncActionToken ); - /** - * This method is invoked when an action fails. - * If a client is disconnected while an action is in progress - * onFailure will be called. For connections - * that use cleanSession set to false, any QoS 1 and 2 messages that - * are in the process of being delivered will be delivered to the requested - * quality of service next time the client connects. - * @param asyncActionToken associated with the action that has failed - * @param exception thrown by the action that has failed - */ - public void onFailure(IMqttToken asyncActionToken, Throwable exception); -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttAsyncClient.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttAsyncClient.java deleted file mode 100644 index b0a1e32..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttAsyncClient.java +++ /dev/null @@ -1,875 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013, 2015 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - */ - -package org.eclipse.paho.client.mqttv3; - -/** - * Enables an application to communicate with an MQTT server using non-blocking methods. - * <p> - * It provides applications a simple programming interface to all features of the MQTT version 3.1 - * specification including: - * </p> - * <ul> - * <li>connect - * <li>publish - * <li>subscribe - * <li>unsubscribe - * <li>disconnect - * </ul> - * <p> - * There are two styles of MQTT client, this one and {@link IMqttClient}.</p> - * <ul> - * <li>IMqttAsyncClient provides a set of non-blocking methods that return control to the - * invoking application after initial validation of parameters and state. The main processing is - * performed in the background so as not to block the application program's thread. This non- - * blocking approach is handy when the application needs to carry on processing while the - * MQTT action takes place. For instance connecting to an MQTT server can take time, using - * the non-blocking connect method allows an application to display a busy indicator while the - * connect action takes place in the background. Non blocking methods are particularly useful - * in event oriented programs and graphical programs where invoking methods that take time - * to complete on the the main or GUI thread can cause problems. The non-blocking interface - * can also be used in blocking form.</li> - * <li>IMqttClient provides a set of methods that block and return control to the application - * program once the MQTT action has completed. It is a thin layer that sits on top of the - * IMqttAsyncClient implementation and is provided mainly for compatibility with earlier - * versions of the MQTT client. In most circumstances it is recommended to use IMqttAsyncClient - * based clients which allow an application to mix both non-blocking and blocking calls. </li> - * </ul> - * <p> - * An application is not restricted to using one style if an IMqttAsyncClient based client is used - * as both blocking and non-blocking methods can be used in the same application. If an IMqttClient - * based client is used then only blocking methods are available to the application. - * For more details on the blocking client see {@link IMqttClient}</p> - * - * <p>There are two forms of non-blocking method: - * <ol> - * <li> - * <pre> - * IMqttToken token = asyncClient.method(parms) - * </pre> - * <p>In this form the method returns a token that can be used to track the - * progress of the action (method). The method provides a waitForCompletion() - * method that once invoked will block until the action completes. Once - * completed there are method on the token that can be used to check if the - * action completed successfully or not. For example - * to wait until a connect completes:</p> - * <pre> - * IMqttToken conToken; - * conToken = asyncClient.client.connect(conToken); - * ... do some work... - * conToken.waitForCompletion(); - * </pre> - * <p>To turn a method into a blocking invocation the following form can be used:</p> - * <pre> - * IMqttToken token; - * token = asyncClient.method(parms).waitForCompletion(); - * </pre> - * </li> - * - * <li> - * <pre> - * IMqttToken token method(parms, Object userContext, IMqttActionListener callback) - * </pre> - * <p>In this form a callback is registered with the method. The callback will be - * notified when the action succeeds or fails. The callback is invoked on the thread - * managed by the MQTT client so it is important that processing is minimised in the - * callback. If not the operation of the MQTT client will be inhibited. For example - * to be notified (called back) when a connect completes:</p> - * <pre> - * IMqttToken conToken; - * conToken = asyncClient.connect("some context",new new MqttAsyncActionListener() { - * public void onSuccess(IMqttToken asyncActionToken) { - * log("Connected"); - * } - * - * public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - * log ("connect failed" +exception); - * } - * }); - * </pre> - * <p>An optional context object can be passed into the method which will then be made - * available in the callback. The context is stored by the MQTT client) in the token - * which is then returned to the invoker. The token is provided to the callback methods - * where the context can then be accessed. - * </p> - * </li> - * </ol> - * <p>To understand when the delivery of a message is complete either of the two methods above - * can be used to either wait on or be notified when the publish completes. An alternative is to - * use the {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)} method which will - * also be notified when a message has been delivered to the requested quality of service.</p> - * - */ -public interface IMqttAsyncClient { - /** - * Connects to an MQTT server using the default options. - * <p>The default options are specified in {@link MqttConnectOptions} class. - * </p> - * - * @throws MqttSecurityException for security related problems - * @throws MqttException for non security related problems - * @return token used to track and wait for the connect to complete. The token - * will be passed to the callback methods if a callback is set. - * @see #connect(MqttConnectOptions, Object, IMqttActionListener) - */ - public IMqttToken connect() throws MqttException, MqttSecurityException; - - /** - * Connects to an MQTT server using the provided connect options. - * <p>The connection will be established using the options specified in the - * {@link MqttConnectOptions} parameter. - * </p> - * - * @param options a set of connection parameters that override the defaults. - * @throws MqttSecurityException for security related problems - * @throws MqttException for non security related problems - * @return token used to track and wait for the connect to complete. The token - * will be passed to any callback that has been set. - * @see #connect(MqttConnectOptions, Object, IMqttActionListener) - */ - public IMqttToken connect(MqttConnectOptions options) throws MqttException, MqttSecurityException ; - /** - * Connects to an MQTT server using the default options. - * <p>The default options are specified in {@link MqttConnectOptions} class. - * </p> - * - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when the connect completes. Use - * null if not required. - * @throws MqttSecurityException for security related problems - * @throws MqttException for non security related problems - * @return token used to track and wait for the connect to complete. The token - * will be passed to any callback that has been set. - * @see #connect(MqttConnectOptions, Object, IMqttActionListener) - */ - public IMqttToken connect(Object userContext, IMqttActionListener callback) throws MqttException, MqttSecurityException; - - - /** - * Connects to an MQTT server using the specified options. - * <p>The server to connect to is specified on the constructor. - * It is recommended to call {@link #setCallback(MqttCallback)} prior to - * connecting in order that messages destined for the client can be accepted - * as soon as the client is connected. - * </p> - * <p>The method returns control before the connect completes. Completion can - * be tracked by: - * </p> - * <ul> - * <li>Waiting on the returned token {@link IMqttToken#waitForCompletion()} or</li> - * <li>Passing in a callback {@link IMqttActionListener}</li> - * </ul> - * - * @param options a set of connection parameters that override the defaults. - * @param userContext optional object for used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when the connect completes. Use - * null if not required. - * @return token used to track and wait for the connect to complete. The token - * will be passed to any callback that has been set. - * @throws MqttSecurityException for security related problems - * @throws MqttException for non security related problems including communication errors - */ - public IMqttToken connect(MqttConnectOptions options, Object userContext, IMqttActionListener callback) throws MqttException, MqttSecurityException; - - /** - * Disconnects from the server. - * <p>An attempt is made to quiesce the client allowing outstanding - * work to complete before disconnecting. It will wait - * for a maximum of 30 seconds for work to quiesce before disconnecting. - * This method must not be called from inside {@link MqttCallback} methods. - * </p> - * - * @return token used to track and wait for disconnect to complete. The token - * will be passed to any callback that has been set. - * @throws MqttException for problems encountered while disconnecting - * @see #disconnect(long, Object, IMqttActionListener) - */ - public IMqttToken disconnect( ) throws MqttException; - - /** - * Disconnects from the server. - * <p>An attempt is made to quiesce the client allowing outstanding - * work to complete before disconnecting. It will wait - * for a maximum of the specified quiesce time for work to complete before disconnecting. - * This method must not be called from inside {@link MqttCallback} methods. - * </p> - * @param quiesceTimeout the amount of time in milliseconds to allow for - * existing work to finish before disconnecting. A value of zero or less - * means the client will not quiesce. - * @return token used to track and wait for disconnect to complete. The token - * will be passed to the callback methods if a callback is set. - * @throws MqttException for problems encountered while disconnecting - * @see #disconnect(long, Object, IMqttActionListener) - */ - public IMqttToken disconnect(long quiesceTimeout) throws MqttException; - - /** - * Disconnects from the server. - * <p>An attempt is made to quiesce the client allowing outstanding - * work to complete before disconnecting. It will wait - * for a maximum of 30 seconds for work to quiesce before disconnecting. - * This method must not be called from inside {@link MqttCallback} methods. - * </p> - * - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when the disconnect completes. Use - * null if not required. - * @return token used to track and wait for the disconnect to complete. The token - * will be passed to any callback that has been set. - * @throws MqttException for problems encountered while disconnecting - * @see #disconnect(long, Object, IMqttActionListener) - */ - public IMqttToken disconnect( Object userContext, IMqttActionListener callback) throws MqttException; - - /** - * Disconnects from the server. - * <p> - * The client will wait for {@link MqttCallback} methods to - * complete. It will then wait for up to the quiesce timeout to allow for - * work which has already been initiated to complete. For instance when a QoS 2 - * message has started flowing to the server but the QoS 2 flow has not completed.It - * prevents new messages being accepted and does not send any messages that have - * been accepted but not yet started delivery across the network to the server. When - * work has completed or after the quiesce timeout, the client will disconnect from - * the server. If the cleanSession flag was set to false and is set to false the - * next time a connection is made QoS 1 and 2 messages that - * were not previously delivered will be delivered.</p> - * <p>This method must not be called from inside {@link MqttCallback} methods.</p> - * <p>The method returns control before the disconnect completes. Completion can - * be tracked by: - * </p> - * <ul> - * <li>Waiting on the returned token {@link IMqttToken#waitForCompletion()} or</li> - * <li>Passing in a callback {@link IMqttActionListener}</li> - * </ul> - * - * @param quiesceTimeout the amount of time in milliseconds to allow for - * existing work to finish before disconnecting. A value of zero or less - * means the client will not quiesce. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when the disconnect completes. Use - * null if not required. - * @return token used to track and wait for the connect to complete. The token - * will be passed to any callback that has been set. - * @throws MqttException for problems encountered while disconnecting - */ - public IMqttToken disconnect(long quiesceTimeout, Object userContext, IMqttActionListener callback) throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. It will wait for a maximum of 30 seconds for work to quiesce before disconnecting and - * wait for a maximum of 10 seconds for sending the disconnect packet to server. - * - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly() throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. It will wait for a maximum of 30 seconds for work to quiesce before disconnecting. - * - * @param disconnectTimeout the amount of time in milliseconds to allow send disconnect packet to server. - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly(long disconnectTimeout) throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. - * - * @param quiesceTimeout the amount of time in milliseconds to allow for existing work to finish before - * disconnecting. A value of zero or less means the client will not quiesce. - * @param disconnectTimeout the amount of time in milliseconds to allow send disconnect packet to server. - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout) throws MqttException; - - /** - * Determines if this client is currently connected to the server. - * - * @return <code>true</code> if connected, <code>false</code> otherwise. - */ - public boolean isConnected(); - - /** - * Returns the client ID used by this client. - * <p>All clients connected to the - * same server or server farm must have a unique ID. - * </p> - * - * @return the client ID used by this client. - */ - public String getClientId(); - - /** - * Returns the address of the server used by this client. - * <p>The format of the returned String is the same as that used on the constructor. - * </p> - * - * @return the server's address, as a URI String. - * @see MqttAsyncClient#MqttAsyncClient(String, String) - */ - public String getServerURI(); - - /** - * Publishes a message to a topic on the server. - * <p>A convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. - * </p> - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param payload the byte array to use as the payload - * @param qos the Quality of Service to deliver the message at. Valid values are 0, 1 or 2. - * @param retained whether or not this message should be retained by the server. - * @return token used to track and wait for the publish to complete. The token - * will be passed to any callback that has been set. - * @throws MqttPersistenceException when a problem occurs storing the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws MqttException for other errors encountered while publishing the message. - * For instance if too many messages are being processed. - * @see #publish(String, MqttMessage, Object, IMqttActionListener) - * @see MqttMessage#setQos(int) - * @see MqttMessage#setRetained(boolean) - */ - public IMqttDeliveryToken publish(String topic, byte[] payload, int qos, - boolean retained ) throws MqttException, MqttPersistenceException; - - /** - * Publishes a message to a topic on the server. - * <p>A convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. - * </p> - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param payload the byte array to use as the payload - * @param qos the Quality of Service to deliver the message at. Valid values are 0, 1 or 2. - * @param retained whether or not this message should be retained by the server. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when message delivery - * hsa completed to the requested quality of service - * @return token used to track and wait for the publish to complete. The token - * will be passed to any callback that has been set. - * @throws MqttPersistenceException when a problem occurs storing the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws MqttException for other errors encountered while publishing the message. - * For instance client not connected. - * @see #publish(String, MqttMessage, Object, IMqttActionListener) - * @see MqttMessage#setQos(int) - * @see MqttMessage#setRetained(boolean) - */ - public IMqttDeliveryToken publish(String topic, byte[] payload, int qos, - boolean retained, Object userContext, IMqttActionListener callback ) throws MqttException, MqttPersistenceException; - - /** - * Publishes a message to a topic on the server. - * Takes an {@link MqttMessage} message and delivers it to the server at the - * requested quality of service. - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param message to deliver to the server - * @return token used to track and wait for the publish to complete. The token - * will be passed to any callback that has been set. - * @throws MqttPersistenceException when a problem occurs storing the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws MqttException for other errors encountered while publishing the message. - * For instance client not connected. - * @see #publish(String, MqttMessage, Object, IMqttActionListener) - */ - public IMqttDeliveryToken publish(String topic, MqttMessage message ) throws MqttException, MqttPersistenceException; - - /** - * Publishes a message to a topic on the server. - * <p> - * Once this method has returned cleanly, the message has been accepted for publication by the - * client and will be delivered on a background thread. - * In the event the connection fails or the client stops. Messages will be delivered to the - * requested quality of service once the connection is re-established to the server on condition that: - * </p> - * <ul> - * <li>The connection is re-established with the same clientID - * <li>The original connection was made with (@link MqttConnectOptions#setCleanSession(boolean)} - * set to false - * <li>The connection is re-established with (@link MqttConnectOptions#setCleanSession(boolean)} - * set to false - * <li>Depending when the failure occurs QoS 0 messages may not be delivered. - * </ul> - * - * <p>When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:</p> - * - * <ul> - * <li>A topic must be at least one character long.</li> - * <li>Topic names are case sensitive. For example, <em>ACCOUNTS</em> and <em>Accounts</em> are - * two different topics.</li> - * <li>Topic names can include the space character. For example, <em>Accounts - * payable</em> is a valid topic.</li> - * <li>A leading "/" creates a distinct topic. For example, <em>/finance</em> is - * different from <em>finance</em>. <em>/finance</em> matches "+/+" and "/+", but - * not "+".</li> - * <li>Do not include the null character (Unicode <pre>\x0000</pre>) in - * any topic.</li> - * </ul> - * - * <p>The following principles apply to the construction and content of a topic - * tree:</p> - * <ul> - * <li>The length is limited to 64k but within that there are no limits to the - * number of levels in a topic tree.</li> - * <li>There can be any number of root nodes; that is, there can be any number - * of topic trees.</li> - * </ul> - * - * <p>The method returns control before the publish completes. Completion can - * be tracked by: - * </p> - * <ul> - * <li>Setting an {@link IMqttAsyncClient#setCallback(MqttCallback)} where the - * {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)} - * method will be called.</li> - * <li>Waiting on the returned token {@link MqttToken#waitForCompletion()} or</li> - * <li>Passing in a callback {@link IMqttActionListener} to this method</li> - * </ul> - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param message to deliver to the server - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when message delivery - * has completed to the requested quality of service - * @return token used to track and wait for the publish to complete. The token - * will be passed to callback methods if set. - * @throws MqttPersistenceException when a problem occurs storing the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws MqttException for other errors encountered while publishing the message. - * For instance client not connected. - * @see MqttMessage - */ - public IMqttDeliveryToken publish(String topic, MqttMessage message, - Object userContext, IMqttActionListener callback) throws MqttException, MqttPersistenceException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String topicFilter, int qos) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when subscribe - * has completed - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String topicFilter, int qos, Object userContext, IMqttActionListener callback) - throws MqttException; - - /** - * Subscribe to multiple topics, each of which may include wildcards. - * - * <p>Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.</p> - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos) throws MqttException; - - /** - * Subscribes to multiple topics, each of which may include wildcards. - * <p>Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.</p> - * <p>The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - * </p> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:</p> - * - * <ul> - * <li>The client disconnects</li> - * <li>An unsubscribe method is called to un-subscribe the topic</li> - * </ul> - * - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>An unsubscribe method is called to unsubscribe the topic</li> - * <li>The next time the client connects with cleanSession set to true</li> - * </ul> - * <p> - * With cleanSession set to false the MQTT server will store messages on - * behalf of the client when the client is not connected. The next time the - * client connects with the <b>same client ID</b> the server will - * deliver the stored messages to the client. - * </p> - * - * <p>The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.</p> - * <p>The topic level separator is used to introduce structure into the topic, and - * can therefore be specified within the topic for that purpose. The multi-level - * wildcard and single-level wildcard can be used for subscriptions, but they - * cannot be used within a topic by the publisher of a message. - * <dl> - * <dt>Topic level separator</dt> - * <dd>The forward slash (/) is used to separate each level within - * a topic tree and provide a hierarchical structure to the topic space. The - * use of the topic level separator is significant when the two wildcard characters - * are encountered in topics specified by subscribers.</dd> - * - * <dt>Multi-level wildcard</dt> - * <dd><p>The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * <span><span class="filepath">finance/stock/ibm/#</span></span>, you receive - * messages on these topics:</p> - * <ul> - * <li>finance/stock/ibm</li> - * <li>finance/stock/ibm/closingprice</li> - * <li>finance/stock/ibm/currentprice</li> - * </ul> - * <p>The multi-level wildcard - * can represent zero or more levels. Therefore, <em>finance/#</em> can also match - * the singular <em>finance</em>, where <em>#</em> represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.</p> - * - * <p>The <span>multi-level</span> wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, <em>#</em> and <em>finance/#</em> are both valid, but <em>finance#</em> is - * not valid. <span>The multi-level wildcard must be the last character - * used within the topic tree. For example, <em>finance/#</em> is valid but - * <em>finance/#/closingprice</em> is not valid.</span></p></dd> - * - * <dt>Single-level wildcard</dt> - * <dd><p>The plus sign (+) is a wildcard character that matches only one topic - * level. For example, <em>finance/stock/+</em> matches - * <em>finance/stock/ibm</em> and <em>finance/stock/xyz</em>, - * but not <em>finance/stock/ibm/closingprice</em>. Also, because the single-level - * wildcard matches only a single level, <em>finance/+</em> does not match <em>finance</em>.</p> - * - * <p>Use - * the single-level wildcard at any level in the topic tree, and in conjunction - * with the multilevel wildcard. Specify the single-level wildcard next to the - * topic level separator, except when it is specified on its own. Therefore, - * <em>+</em> and <em>finance/+</em> are both valid, but <em>finance+</em> is - * not valid. <span>The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, <em>finance/+</em> and <em>finance/+/ibm</em> are both valid.</span></p> - * </dd> - * </dl> - * <p>The method returns control before the subscribe completes. Completion can - * be tracked by:</p> - * <ul> - * <li>Waiting on the supplied token {@link MqttToken#waitForCompletion()} or</li> - * <li>Passing in a callback {@link IMqttActionListener} to this method</li> - * </ul> - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards - * @param qos the maximum quality of service to subscribe each topic at.Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when subscribe - * has completed - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - * @throws IllegalArgumentException if the two supplied arrays are not the same size. - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos, Object userContext, IMqttActionListener callback) - throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when subscribe - * has completed - * @param messageListener a callback to handle incoming messages - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String topicFilter, int qos, Object userContext, IMqttActionListener callback, IMqttMessageListener messageListener) throws MqttException; - - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListener a callback to handle incoming messages - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String topicFilter, int qos, IMqttMessageListener messageListener) throws MqttException; - - - /** - * Subscribe to multiple topics, each of which may include wildcards. - * - * <p>Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.</p> - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListeners one or more callbacks to handle incoming messages - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) throws MqttException; - - - /** - * Subscribe to multiple topics, each of which may include wildcards. - * - * <p>Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.</p> - * - * @see #subscribe(String[], int[], Object, IMqttActionListener) - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when subscribe - * has completed - * @param messageListeners one or more callbacks to handle incoming messages - * @return token used to track and wait for the subscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos, Object userContext, IMqttActionListener callback, IMqttMessageListener[] messageListeners) throws MqttException; - - - /** - * Requests the server unsubscribe the client from a topic. - * - * @see #unsubscribe(String[], Object, IMqttActionListener) - * @param topicFilter the topic to unsubscribe from. It must match a topicFilter - * specified on an earlier subscribe. - * @return token used to track and wait for the unsubscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error unregistering the subscription. - */ - public IMqttToken unsubscribe(String topicFilter) throws MqttException; - - /** - * Requests the server unsubscribe the client from one or more topics. - * - * @see #unsubscribe(String[], Object, IMqttActionListener) - * - * @param topicFilters one or more topics to unsubscribe from. Each topicFilter - * must match one specified on an earlier subscribe. * - * @return token used to track and wait for the unsubscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error unregistering the subscription. - */ - public IMqttToken unsubscribe(String[] topicFilters) throws MqttException; - - /** - * Requests the server unsubscribe the client from a topics. - * - * @see #unsubscribe(String[], Object, IMqttActionListener) - * - * @param topicFilter the topic to unsubscribe from. It must match a topicFilter - * specified on an earlier subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when unsubscribe - * has completed - * @return token used to track and wait for the unsubscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error unregistering the subscription. - */ - public IMqttToken unsubscribe(String topicFilter, Object userContext, IMqttActionListener callback) - throws MqttException; - - /** - * Requests the server unsubscribe the client from one or more topics. - * <p> - * Unsubcribing is the opposite of subscribing. When the server receives the - * unsubscribe request it looks to see if it can find a matching subscription for the - * client and then removes it. After this point the server will send no more - * messages to the client for this subscription. - * </p> - * <p>The topic(s) specified on the unsubscribe must match the topic(s) - * specified in the original subscribe request for the unsubscribe to succeed - * </p> - * <p>The method returns control before the unsubscribe completes. Completion can - * be tracked by: - * </p> - * - * <ul> - * <li>Waiting on the returned token {@link MqttToken#waitForCompletion()} or</li> - * <li>Passing in a callback {@link IMqttActionListener} to this method</li> - * </ul> - * - * @param topicFilters one or more topics to unsubscribe from. Each topicFilter - * must match one specified on an earlier subscribe. - * @param userContext optional object used to pass context to the callback. Use - * null if not required. - * @param callback optional listener that will be notified when unsubscribe - * has completed - * @return token used to track and wait for the unsubscribe to complete. The token - * will be passed to callback methods if set. - * @throws MqttException if there was an error unregistering the subscription. - */ - public IMqttToken unsubscribe(String[] topicFilters, Object userContext, IMqttActionListener callback) - throws MqttException; - - - /** - * Sets a callback listener to use for events that happen asynchronously. - * <p>There are a number of events that the listener will be notified about. - * These include: - * </p> - * <ul> - * <li>A new message has arrived and is ready to be processed</li> - * <li>The connection to the server has been lost</li> - * <li>Delivery of a message to the server has completed</li> - * </ul> - * <p>Other events that track the progress of an individual operation such - * as connect and subscribe can be tracked using the {@link MqttToken} returned from - * each non-blocking method or using setting a {@link IMqttActionListener} on the - * non-blocking method.<p> - * @see MqttCallback - * @param callback which will be invoked for certain asynchronous events - */ - public void setCallback(MqttCallback callback); - - /** - * Returns the delivery tokens for any outstanding publish operations. - * <p>If a client has been restarted and there are messages that were in the - * process of being delivered when the client stopped this method - * returns a token for each in-flight message enabling the delivery to be tracked - * Alternately the {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)} - * callback can be used to track the delivery of outstanding messages. - * </p> - * <p>If a client connects with cleanSession true then there will be no - * delivery tokens as the cleanSession option deletes all earlier state. - * For state to be remembered the client must connect with cleanSession - * set to false</P> - * @return zero or more delivery tokens - */ - public IMqttDeliveryToken[] getPendingDeliveryTokens(); - - /** - * If manualAcks is set to true, then on completion of the messageArrived callback - * the MQTT acknowledgements are not sent. You must call messageArrivedComplete - * to send those acknowledgements. This allows finer control over when the acks are - * sent. The default behaviour, when manualAcks is false, is to send the MQTT - * acknowledgements automatically at the successful completion of the messageArrived - * callback method. - * @param manualAcks if set to true MQTT acknowledgements are not sent - */ - public void setManualAcks(boolean manualAcks); - - /** - * Indicate that the application has completed processing the message with id messageId. - * This will cause the MQTT acknowledgement to be sent to the server. - * @param messageId the MQTT message id to be acknowledged - * @param qos the MQTT QoS of the message to be acknowledged - * @throws MqttException if there was a problem sending the acknowledgement - */ - public void messageArrivedComplete(int messageId, int qos) throws MqttException; - - /** - * Close the client - * Releases all resource associated with the client. After the client has - * been closed it cannot be reused. For instance attempts to connect will fail. - * @throws MqttException if the client is not disconnected. - */ - public void close() throws MqttException; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttClient.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttClient.java deleted file mode 100644 index 810dfed..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttClient.java +++ /dev/null @@ -1,966 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2015 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - */ - -package org.eclipse.paho.client.mqttv3; - -/** - * Enables an application to communicate with an MQTT server using blocking methods. - * <p> - * This interface allows applications to utilize all features of the MQTT version 3.1 - * specification including:</p> - * <ul> - * <li>connect - * <li>publish - * <li>subscribe - * <li>unsubscribe - * <li>disconnect - * </ul> - * <p> - * There are two styles of MQTT client, this one and {@link IMqttAsyncClient}.</p> - * <ul> - * <li>IMqttClient provides a set of methods that block and return control to the application - * program once the MQTT action has completed.</li> - * <li>IMqttAsyncClient provides a set of non-blocking methods that return control to the - * invoking application after initial validation of parameters and state. The main processing is - * performed in the background so as not to block the application programs thread. This non - * blocking approach is handy when the application wants to carry on processing while the - * MQTT action takes place. For instance connecting to an MQTT server can take time, using - * the non-blocking connect method allows an application to display a busy indicator while the - * connect action is occurring. Non-blocking methods are particularly useful in event-oriented - * programs and graphical programs where issuing methods that take time to complete on the the - * main or GUI thread can cause problems.</li> - * </ul> - * <p> - * The non-blocking client can also be used in a blocking form by turning a non-blocking - * method into a blocking invocation using the following pattern:</p> - * <pre> - * IMqttToken token; - * token = asyncClient.method(parms).waitForCompletion(); - * </pre> - * <p> - * Using the non-blocking client allows an application to use a mixture of blocking and - * non-blocking styles. Using the blocking client only allows an application to use one - * style. The blocking client provides compatibility with earlier versions - * of the MQTT client.</p> - */ -public interface IMqttClient { //extends IMqttAsyncClient { - /** - * Connects to an MQTT server using the default options. - * <p>The default options are specified in {@link MqttConnectOptions} class. - * </p> - * - * @throws MqttSecurityException when the server rejects the connect for security - * reasons - * @throws MqttException for non security related problems - * @see #connect(MqttConnectOptions) - */ - public void connect() throws MqttSecurityException, MqttException; - - /** - * Connects to an MQTT server using the specified options. - * <p>The server to connect to is specified on the constructor. - * It is recommended to call {@link #setCallback(MqttCallback)} prior to - * connecting in order that messages destined for the client can be accepted - * as soon as the client is connected. - * </p> - * <p>This is a blocking method that returns once connect completes</p> - * - * @param options a set of connection parameters that override the defaults. - * @throws MqttSecurityException when the server rejects the connect for security - * reasons - * @throws MqttException for non security related problems including communication errors - */ - public void connect(MqttConnectOptions options) throws MqttSecurityException, MqttException; - - /** - * Connects to an MQTT server using the specified options. - * <p>The server to connect to is specified on the constructor. - * It is recommended to call {@link #setCallback(MqttCallback)} prior to - * connecting in order that messages destined for the client can be accepted - * as soon as the client is connected. - * </p> - * <p>This is a blocking method that returns once connect completes</p> - * - * @param options a set of connection parameters that override the defaults. - * @return the MqttToken used for the call. Can be used to obtain the session present flag - * @throws MqttSecurityException when the server rejects the connect for security - * reasons - * @throws MqttException for non security related problems including communication errors - */ -public IMqttToken connectWithResult(MqttConnectOptions options) throws MqttSecurityException, MqttException; - - /** - * Disconnects from the server. - * <p>An attempt is made to quiesce the client allowing outstanding - * work to complete before disconnecting. It will wait - * for a maximum of 30 seconds for work to quiesce before disconnecting. - * This method must not be called from inside {@link MqttCallback} methods. - * </p> - * - * <p>This is a blocking method that returns once disconnect completes</p> - * - * @throws MqttException if a problem is encountered while disconnecting - */ - public void disconnect() throws MqttException; - - /** - * Disconnects from the server. - * <p> - * The client will wait for all {@link MqttCallback} methods to - * complete. It will then wait for up to the quiesce timeout to allow for - * work which has already been initiated to complete - for example, it will - * wait for the QoS 2 flows from earlier publications to complete. When work has - * completed or after the quiesce timeout, the client will disconnect from - * the server. If the cleanSession flag was set to false and is set to false the - * next time a connection is made QoS 1 and 2 messages that - * were not previously delivered will be delivered.</p> - * - * <p>This is a blocking method that returns once disconnect completes</p> - * - * @param quiesceTimeout the amount of time in milliseconds to allow for - * existing work to finish before disconnecting. A value of zero or less - * means the client will not quiesce. - * @throws MqttException if a problem is encountered while disconnecting - */ - public void disconnect(long quiesceTimeout) throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. It will wait for a maximum of 30 seconds for work to quiesce before disconnecting and - * wait for a maximum of 10 seconds for sending the disconnect packet to server. - * - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly() throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. It will wait for a maximum of 30 seconds for work to quiesce before disconnecting. - * - * @param disconnectTimeout the amount of time in milliseconds to allow send disconnect packet to server. - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly(long disconnectTimeout) throws MqttException; - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. - * - * @param quiesceTimeout the amount of time in milliseconds to allow for existing work to finish before - * disconnecting. A value of zero or less means the client will not quiesce. - * @param disconnectTimeout the amount of time in milliseconds to allow send disconnect packet to server. - * @throws MqttException if any unexpected error - * @since 0.4.1 - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards using a QoS of 1. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @throws MqttException if there was an error registering the subscription. - * @throws MqttSecurityException if the client is not authorized to register the subscription - */ - public void subscribe(String topicFilter) throws MqttException, MqttSecurityException; - - /** - * Subscribes to a one or more topics, which may include wildcards using a QoS of 1. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilters the topic to subscribe to, which can include wildcards. - * @throws MqttException if there was an error registering the subscription. - */ - public void subscribe(String[] topicFilters) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @throws MqttException if there was an error registering the subscription. - */ - public void subscribe(String topicFilter, int qos) throws MqttException; - - /** - * Subscribes to multiple topics, each of which may include wildcards. - * <p>The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - * </p> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either: - * </p> - * <ul> - * <li>The client disconnects</li> - * <li>An unsubscribe method is called to un-subscribe the topic</li> - * </ul> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>An unsubscribe method is called to unsubscribe the topic</li> - * <li>The client connects with cleanSession set to true</li> - * </ul> - * <p> - * With cleanSession set to false the MQTT server will store messages on - * behalf of the client when the client is not connected. The next time the - * client connects with the <b>same client ID</b> the server will - * deliver the stored messages to the client. - * </p> - * - * <p>The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.</p> - * <p>The topic level separator is used to introduce structure into the topic, and - * can therefore be specified within the topic for that purpose. The multi-level - * wildcard and single-level wildcard can be used for subscriptions, but they - * cannot be used within a topic by the publisher of a message. - * <dl> - * <dt>Topic level separator</dt> - * <dd>The forward slash (/) is used to separate each level within - * a topic tree and provide a hierarchical structure to the topic space. The - * use of the topic level separator is significant when the two wildcard characters - * are encountered in topics specified by subscribers.</dd> - * - * <dt>Multi-level wildcard</dt> - * <dd><p>The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * <span><span class="filepath">finance/stock/ibm/#</span></span>, you receive - * messages on these topics:</p> - * <ul> - * <li><pre>finance/stock/ibm</pre></li> - * <li><pre>finance/stock/ibm/closingprice</pre></li> - * <li><pre>finance/stock/ibm/currentprice</pre></li> - * </ul> - * - * <p>The multi-level wildcard - * can represent zero or more levels. Therefore, <em>finance/#</em> can also match - * the singular <em>finance</em>, where <em>#</em> represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.</p> - * - * <p>The <span>multi-level</span> wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, <em>#</em> and <em>finance/#</em> are both valid, but <em>finance#</em> is - * not valid. <span>The multi-level wildcard must be the last character - * used within the topic tree. For example, <em>finance/#</em> is valid but - * <em>finance/#/closingprice</em> is not valid.</span></p></dd> - * - * <dt>Single-level wildcard</dt> - * <dd><p>The plus sign (+) is a wildcard character that matches only one topic - * level. For example, <em>finance/stock/+</em> matches - * <em>finance/stock/ibm</em> and <em>finance/stock/xyz</em>, - * but not <em>finance/stock/ibm/closingprice</em>. Also, because the single-level - * wildcard matches only a single level, <em>finance/+</em> does not match <em>finance</em>.</p> - * - * <p>Use - * the single-level wildcard at any level in the topic tree, and in conjunction - * with the multilevel wildcard. Specify the single-level wildcard next to the - * topic level separator, except when it is specified on its own. Therefore, - * <em>+</em> and <em>finance/+</em> are both valid, but <em>finance+</em> is - * not valid. <span>The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, <em>finance/+</em> and <em>finance/+/ibm</em> are both valid.</span></p> - * </dd> - * </dl> - * - * <p>This is a blocking method that returns once subscribe completes</p> - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards. - * @param qos the maximum quality of service to subscribe each topic at.Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @throws MqttException if there was an error registering the subscription. - * @throws IllegalArgumentException if the two supplied arrays are not the same size. - */ - public void subscribe(String[] topicFilters, int[] qos) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards using a QoS of 1. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param messageListener a callback to handle incoming messages - * @throws MqttException if there was an error registering the subscription. - * @throws MqttSecurityException if the client is not authorized to register the subscription - */ -public void subscribe(String topicFilter, IMqttMessageListener messageListener) throws MqttException, MqttSecurityException; - - /** - * Subscribes to a one or more topics, which may include wildcards using a QoS of 1. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilters the topic to subscribe to, which can include wildcards. - * @param messageListeners one or more callbacks to handle incoming messages - * @throws MqttException if there was an error registering the subscription. - */ -public void subscribe(String[] topicFilters, IMqttMessageListener[] messageListeners) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribe(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListener a callback to handle incoming messages - * @throws MqttException if there was an error registering the subscription. - */ -public void subscribe(String topicFilter, int qos, IMqttMessageListener messageListener) throws MqttException; - - /** - * Subscribes to multiple topics, each of which may include wildcards. - * <p>The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - * </p> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>The client disconnects</li> - * <li>An unsubscribe method is called to un-subscribe the topic</li> - * </ul> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>An unsubscribe method is called to unsubscribe the topic</li> - * <li>The client connects with cleanSession set to true</li> - * </ul> - * <p> - * With cleanSession set to false the MQTT server will store messages on - * behalf of the client when the client is not connected. The next time the - * client connects with the <b>same client ID</b> the server will - * deliver the stored messages to the client. - * </p> - * - * <p>The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.</p> - * <p>The topic level separator is used to introduce structure into the topic, and - * can therefore be specified within the topic for that purpose. The multi-level - * wildcard and single-level wildcard can be used for subscriptions, but they - * cannot be used within a topic by the publisher of a message. - * <dl> - * <dt>Topic level separator</dt> - * <dd>The forward slash (/) is used to separate each level within - * a topic tree and provide a hierarchical structure to the topic space. The - * use of the topic level separator is significant when the two wildcard characters - * are encountered in topics specified by subscribers.</dd> - * - * <dt>Multi-level wildcard</dt> - * <dd><p>The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * <span><span class="filepath">finance/stock/ibm/#</span></span>, you receive - * messages on these topics:</p> - * <ul> - * <li><pre>finance/stock/ibm</pre></li> - * <li><pre>finance/stock/ibm/closingprice</pre></li> - * <li><pre>finance/stock/ibm/currentprice</pre></li> - * </ul> - * <p>The multi-level wildcard - * can represent zero or more levels. Therefore, <em>finance/#</em> can also match - * the singular <em>finance</em>, where <em>#</em> represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.</p> - * - * <p>The <span>multi-level</span> wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, <em>#</em> and <em>finance/#</em> are both valid, but <em>finance#</em> is - * not valid. <span>The multi-level wildcard must be the last character - * used within the topic tree. For example, <em>finance/#</em> is valid but - * <em>finance/#/closingprice</em> is not valid.</span></p></dd> - * - * <dt>Single-level wildcard</dt> - * <dd><p>The plus sign (+) is a wildcard character that matches only one topic - * level. For example, <em>finance/stock/+</em> matches - * <em>finance/stock/ibm</em> and <em>finance/stock/xyz</em>, - * but not <em>finance/stock/ibm/closingprice</em>. Also, because the single-level - * wildcard matches only a single level, <em>finance/+</em> does not match <em>finance</em>.</p> - * - * <p>Use - * the single-level wildcard at any level in the topic tree, and in conjunction - * with the multilevel wildcard. Specify the single-level wildcard next to the - * topic level separator, except when it is specified on its own. Therefore, - * <em>+</em> and <em>finance/+</em> are both valid, but <em>finance+</em> is - * not valid. <span>The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, <em>finance/+</em> and <em>finance/+/ibm</em> are both valid.</span></p> - * </dd> - * </dl> - * - * <p>This is a blocking method that returns once subscribe completes</p> - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards. - * @param qos the maximum quality of service to subscribe each topic at.Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListeners one or more callbacks to handle incoming messages - * @throws MqttException if there was an error registering the subscription. - * @throws IllegalArgumentException if the two supplied arrays are not the same size. - */ - public void subscribe(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards using a QoS of 1. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String topicFilter) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards using a QoS of 1. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param messageListener a callback to handle incoming messages - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String topicFilter, IMqttMessageListener messageListener) throws MqttException; - - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String topicFilter, int qos) throws MqttException; - - /** - * Subscribe to a topic, which may include wildcards. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilter the topic to subscribe to, which can include wildcards. - * @param qos the maximum quality of service at which to subscribe. Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListener a callback to handle incoming messages - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String topicFilter, int qos, IMqttMessageListener messageListener) throws MqttException; - - /** - * Subscribes to a one or more topics, which may include wildcards using a QoS of 1. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilters the topic to subscribe to, which can include wildcards. - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String[] topicFilters) throws MqttException; - - /** - * Subscribes to a one or more topics, which may include wildcards using a QoS of 1. - * - * @see #subscribeWithResponse(String[], int[]) - * - * @param topicFilters the topic to subscribe to, which can include wildcards. - * @param messageListeners one or more callbacks to handle incoming messages - * @return token used to track the subscribe after it has completed. - * @throws MqttException if there was an error registering the subscription. - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, IMqttMessageListener[] messageListeners) throws MqttException; - - /** - * Subscribes to multiple topics, each of which may include wildcards. - * <p>The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - * </p> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>The client disconnects</li> - * <li>An unsubscribe method is called to un-subscribe the topic</li> - * </ul> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>An unsubscribe method is called to unsubscribe the topic</li> - * <li>The client connects with cleanSession set to true</li> - * </ul> - * <p> - * With cleanSession set to false the MQTT server will store messages on - * behalf of the client when the client is not connected. The next time the - * client connects with the <b>same client ID</b> the server will - * deliver the stored messages to the client. - * </p> - * - * <p>The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.</p> - * <p>The topic level separator is used to introduce structure into the topic, and - * can therefore be specified within the topic for that purpose. The multi-level - * wildcard and single-level wildcard can be used for subscriptions, but they - * cannot be used within a topic by the publisher of a message. - * <dl> - * <dt>Topic level separator</dt> - * <dd>The forward slash (/) is used to separate each level within - * a topic tree and provide a hierarchical structure to the topic space. The - * use of the topic level separator is significant when the two wildcard characters - * are encountered in topics specified by subscribers.</dd> - * - * <dt>Multi-level wildcard</dt> - * <dd><p>The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * <span><span class="filepath">finance/stock/ibm/#</span></span>, you receive - * messages on these topics:</p> - * <ul> - * <li><pre>finance/stock/ibm</pre></li> - * <li><pre>finance/stock/ibm/closingprice</pre></li> - * <li><pre>finance/stock/ibm/currentprice</pre></li> - * </ul> - * <p>The multi-level wildcard - * can represent zero or more levels. Therefore, <em>finance/#</em> can also match - * the singular <em>finance</em>, where <em>#</em> represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.</p> - * - * <p>The <span>multi-level</span> wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, <em>#</em> and <em>finance/#</em> are both valid, but <em>finance#</em> is - * not valid. <span>The multi-level wildcard must be the last character - * used within the topic tree. For example, <em>finance/#</em> is valid but - * <em>finance/#/closingprice</em> is not valid.</span></p></dd> - * - * <dt>Single-level wildcard</dt> - * <dd><p>The plus sign (+) is a wildcard character that matches only one topic - * level. For example, <em>finance/stock/+</em> matches - * <em>finance/stock/ibm</em> and <em>finance/stock/xyz</em>, - * but not <em>finance/stock/ibm/closingprice</em>. Also, because the single-level - * wildcard matches only a single level, <em>finance/+</em> does not match <em>finance</em>.</p> - * - * <p>Use - * the single-level wildcard at any level in the topic tree, and in conjunction - * with the multilevel wildcard. Specify the single-level wildcard next to the - * topic level separator, except when it is specified on its own. Therefore, - * <em>+</em> and <em>finance/+</em> are both valid, but <em>finance+</em> is - * not valid. <span>The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, <em>finance/+</em> and <em>finance/+/ibm</em> are both valid.</span></p> - * </dd> - * </dl> - * - * <p>This is a blocking method that returns once subscribe completes</p> - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards. - * @param qos the maximum quality of service to subscribe each topic at.Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @throws MqttException if there was an error registering the subscription. - * @return token used to track the subscribe after it has completed. - * @throws IllegalArgumentException if the two supplied arrays are not the same size. - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, int[] qos) throws MqttException; - - /** - * Subscribes to multiple topics, each of which may include wildcards. - * <p>The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - * </p> - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>The client disconnects</li> - * <li>An unsubscribe method is called to un-subscribe the topic</li> - * </ul> - * - * <p> - * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:</p> - * <ul> - * <li>An unsubscribe method is called to unsubscribe the topic</li> - * <li>The client connects with cleanSession set to true</li> - * </ul> - * <p> - * With cleanSession set to false the MQTT server will store messages on - * behalf of the client when the client is not connected. The next time the - * client connects with the <b>same client ID</b> the server will - * deliver the stored messages to the client. - * </p> - * - * <p>The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.</p> - * <p>The topic level separator is used to introduce structure into the topic, and - * can therefore be specified within the topic for that purpose. The multi-level - * wildcard and single-level wildcard can be used for subscriptions, but they - * cannot be used within a topic by the publisher of a message. - * <dl> - * <dt>Topic level separator</dt> - * <dd>The forward slash (/) is used to separate each level within - * a topic tree and provide a hierarchical structure to the topic space. The - * use of the topic level separator is significant when the two wildcard characters - * are encountered in topics specified by subscribers.</dd> - * - * <dt>Multi-level wildcard</dt> - * <dd><p>The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * <span><span class="filepath">finance/stock/ibm/#</span></span>, you receive - * messages on these topics:</p> - * <ul> - * <li><pre>finance/stock/ibm</pre></li> - * <li><pre>finance/stock/ibm/closingprice</pre></li> - * <li><pre>finance/stock/ibm/currentprice</pre></li> - * </ul> - * <p>The multi-level wildcard - * can represent zero or more levels. Therefore, <em>finance/#</em> can also match - * the singular <em>finance</em>, where <em>#</em> represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.</p> - * - * <p>The <span>multi-level</span> wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, <em>#</em> and <em>finance/#</em> are both valid, but <em>finance#</em> is - * not valid. <span>The multi-level wildcard must be the last character - * used within the topic tree. For example, <em>finance/#</em> is valid but - * <em>finance/#/closingprice</em> is not valid.</span></p></dd> - * - * <dt>Single-level wildcard</dt> - * <dd><p>The plus sign (+) is a wildcard character that matches only one topic - * level. For example, <em>finance/stock/+</em> matches - * <em>finance/stock/ibm</em> and <em>finance/stock/xyz</em>, - * but not <em>finance/stock/ibm/closingprice</em>. Also, because the single-level - * wildcard matches only a single level, <em>finance/+</em> does not match <em>finance</em>.</p> - * - * <p>Use - * the single-level wildcard at any level in the topic tree, and in conjunction - * with the multilevel wildcard. Specify the single-level wildcard next to the - * topic level separator, except when it is specified on its own. Therefore, - * <em>+</em> and <em>finance/+</em> are both valid, but <em>finance+</em> is - * not valid. <span>The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, <em>finance/+</em> and <em>finance/+/ibm</em> are both valid.</span></p> - * </dd> - * </dl> - - * - * <p>This is a blocking method that returns once subscribe completes</p> - * - * @param topicFilters one or more topics to subscribe to, which can include wildcards. - * @param qos the maximum quality of service to subscribe each topic at.Messages - * published at a lower quality of service will be received at the published - * QoS. Messages published at a higher quality of service will be received using - * the QoS specified on the subscribe. - * @param messageListeners one or more callbacks to handle incoming messages - * @throws MqttException if there was an error registering the subscription. - * @return token used to track the subscribe after it has completed. - * @throws IllegalArgumentException if the two supplied arrays are not the same size. - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) throws MqttException; - - /** - * Requests the server unsubscribe the client from a topic. - * - * @see #unsubscribe(String[]) - * @param topicFilter the topic to unsubscribe from. It must match a topicFilter - * specified on the subscribe. - * @throws MqttException if there was an error unregistering the subscription. - */ - public void unsubscribe(String topicFilter) throws MqttException; - - /** - * Requests the server unsubscribe the client from one or more topics. - * <p> - * Unsubcribing is the opposite of subscribing. When the server receives the - * unsubscribe request it looks to see if it can find a subscription for the - * client and then removes it. After this point the server will send no more - * messages to the client for this subscription. - * </p> - * <p>The topic(s) specified on the unsubscribe must match the topic(s) - * specified in the original subscribe request for the subscribe to succeed - * </p> - * - * <p>This is a blocking method that returns once unsubscribe completes</p> - * - * @param topicFilters one or more topics to unsubscribe from. Each topicFilter - * must match one specified on a subscribe - * @throws MqttException if there was an error unregistering the subscription. - */ - public void unsubscribe(String[] topicFilters) throws MqttException; - - - /** - * Publishes a message to a topic on the server and return once it is delivered. - * <p>This is a convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. All other values in the - * message will be set to the defaults. - * </p> - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param payload the byte array to use as the payload - * @param qos the Quality of Service to deliver the message at. Valid values are 0, 1 or 2. - * @param retained whether or not this message should be retained by the server. - * @throws MqttPersistenceException when a problem with storing the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws MqttException for other errors encountered while publishing the message. - * For instance client not connected. - * @see #publish(String, MqttMessage) - * @see MqttMessage#setQos(int) - * @see MqttMessage#setRetained(boolean) - */ - public void publish(String topic, byte[] payload, int qos, boolean retained) throws MqttException, MqttPersistenceException; - - /** - * Publishes a message to a topic on the server. - * <p> - * Delivers a message to the server at the requested quality of service and returns control - * once the message has been delivered. In the event the connection fails or the client - * stops, any messages that are in the process of being delivered will be delivered once - * a connection is re-established to the server on condition that:</p> - * <ul> - * <li>The connection is re-established with the same clientID</li> - * <li>The original connection was made with (@link MqttConnectOptions#setCleanSession(boolean)} - * set to false</li> - * <li>The connection is re-established with (@link MqttConnectOptions#setCleanSession(boolean)} - * set to false</li> - * </ul> - * <p>In the event that the connection breaks or the client stops it is still possible to determine - * when the delivery of the message completes. Prior to re-establishing the connection to the server:</p> - * <ul> - * <li>Register a {@link #setCallback(MqttCallback)} callback on the client and the delivery complete - * callback will be notified once a delivery of a message completes - * <li>or call {@link #getPendingDeliveryTokens()} which will return a token for each message that - * is in-flight. The token can be used to wait for delivery to complete. - * </ul> - * - * <p>When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:</p> - * - * <ul> - * <li>A topic must be at least one character long.</li> - * <li>Topic names are case sensitive. For example, <em>ACCOUNTS</em> and <em>Accounts</em> are - * two different topics.</li> - * <li>Topic names can include the space character. For example, <em>Accounts - * payable</em> is a valid topic.</li> - * <li>A leading "/" creates a distinct topic. For example, <em>/finance</em> is - * different from <em>finance</em>. <em>/finance</em> matches "+/+" and "/+", but - * not "+".</li> - * <li>Do not include the null character (Unicode<pre> \x0000</pre>) in - * any topic.</li> - * </ul> - * - * <p>The following principles apply to the construction and content of a topic - * tree:</p> - * - * <ul> - * <li>The length is limited to 64k but within that there are no limits to the - * number of levels in a topic tree.</li> - * <li>There can be any number of root nodes; that is, there can be any number - * of topic trees.</li> - * </ul> - * - * - * <p>This is a blocking method that returns once publish completes</p> * - * - * @param topic to deliver the message to, for example "finance/stock/ibm". - * @param message to delivery to the server - * @throws MqttPersistenceException when a problem with storing the message - * @throws MqttException for other errors encountered while publishing the message. - * For instance client not connected. - */ - public void publish(String topic, MqttMessage message) throws MqttException, MqttPersistenceException; - - /** - * Sets the callback listener to use for events that happen asynchronously. - * <p>There are a number of events that listener will be notified about. These include:</p> - * <ul> - * <li>A new message has arrived and is ready to be processed</li> - * <li>The connection to the server has been lost</li> - * <li>Delivery of a message to the server has completed.</li> - * </ul> - * <p>Other events that track the progress of an individual operation such - * as connect and subscribe can be tracked using the {@link MqttToken} passed to the - * operation<p> - * @see MqttCallback - * @param callback the class to callback when for events related to the client - */ - public void setCallback(MqttCallback callback); - - /** - * Get a topic object which can be used to publish messages. - * <p>An alternative method that should be used in preference to this one when publishing a message is:</p> - * <ul> - * <li>{@link MqttClient#publish(String, MqttMessage)} to publish a message in a blocking manner - * <li>or use publish methods on the non-blocking client like {@link IMqttAsyncClient#publish(String, MqttMessage, Object, IMqttActionListener)} - * </ul> - * <p>When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:</p> - * - * <ul> - * <li>A topic must be at least one character long.</li> - * <li>Topic names are case sensitive. For example, <em>ACCOUNTS</em> and <em>Accounts</em> are - * two different topics.</li> - * <li>Topic names can include the space character. For example, <em>Accounts - * payable</em> is a valid topic.</li> - * <li>A leading "/" creates a distinct topic. For example, <em>/finance</em> is - * different from <em>finance</em>. <em>/finance</em> matches "+/+" and "/+", but - * not "+".</li> - * <li>Do not include the null character (Unicode<pre> \x0000</pre>) in - * any topic.</li> - * </ul> - * - * <p>The following principles apply to the construction and content of a topic - * tree:</p> - * - * <ul> - * <li>The length is limited to 64k but within that there are no limits to the - * number of levels in a topic tree.</li> - * <li>There can be any number of root nodes; that is, there can be any number - * of topic trees.</li> - * </ul> - * - * @param topic the topic to use, for example "finance/stock/ibm". - * @return an MqttTopic object, which can be used to publish messages to - * the topic. - * @throws IllegalArgumentException if the topic contains a '+' or '#' - * wildcard character. - */ - public MqttTopic getTopic(String topic); - - /** - * Determines if this client is currently connected to the server. - * - * @return <code>true</code> if connected, <code>false</code> otherwise. - */ - public boolean isConnected(); - - /** - * Returns the client ID used by this client. - * <p>All clients connected to the - * same server or server farm must have a unique ID. - * </p> - * - * @return the client ID used by this client. - */ - public String getClientId(); - - /** - * Returns the address of the server used by this client, as a URI. - * <p>The format is the same as specified on the constructor. - * </p> - * - * @return the server's address, as a URI String. - * @see MqttAsyncClient#MqttAsyncClient(String, String) - */ - public String getServerURI(); - - /** - * Returns the delivery tokens for any outstanding publish operations. - * <p>If a client has been restarted and there are messages that were in the - * process of being delivered when the client stopped this method will - * return a token for each message enabling the delivery to be tracked - * Alternately the {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)} - * callback can be used to track the delivery of outstanding messages. - * </p> - * <p>If a client connects with cleanSession true then there will be no - * delivery tokens as the cleanSession option deletes all earlier state. - * For state to be remembered the client must connect with cleanSession - * set to false</P> - * @return zero or more delivery tokens - */ - public IMqttDeliveryToken[] getPendingDeliveryTokens(); - - /** - * If manualAcks is set to true, then on completion of the messageArrived callback - * the MQTT acknowledgements are not sent. You must call messageArrivedComplete - * to send those acknowledgements. This allows finer control over when the acks are - * sent. The default behaviour, when manualAcks is false, is to send the MQTT - * acknowledgements automatically at the successful completion of the messageArrived - * callback method. - * @param manualAcks if set to true, MQTT acknowledgements are not sent. - */ - public void setManualAcks(boolean manualAcks); - - /** - * Indicate that the application has completed processing the message with id messageId. - * This will cause the MQTT acknowledgement to be sent to the server. - * @param messageId the MQTT message id to be acknowledged - * @param qos the MQTT QoS of the message to be acknowledged - * @throws MqttException if there was a problem sending the acknowledgement - */ - public void messageArrivedComplete(int messageId, int qos) throws MqttException; - - /** - * Close the client - * Releases all resource associated with the client. After the client has - * been closed it cannot be reused. For instance attempts to connect will fail. - * @throws MqttException if the client is not disconnected. - */ - public void close() throws MqttException; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttDeliveryToken.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttDeliveryToken.java deleted file mode 100644 index 8d74de9..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttDeliveryToken.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.eclipse.paho.client.mqttv3; -/** - * Provides a mechanism for tracking the delivery of a message. - * - * <p>A subclass of IMqttToken that allows the delivery of a message to be tracked. - * Unlike instances of IMqttToken delivery tokens can be used across connection - * and client restarts. This enables the delivery of a messages to be tracked - * after failures. There are two approaches - * <ul> - * <li>A list of delivery tokens for in-flight messages can be obtained using - * {@link IMqttAsyncClient#getPendingDeliveryTokens()}. The waitForCompletion - * method can then be used to block until the delivery is complete. - * <li>A {@link MqttCallback} can be set on the client. Once a message has been - * delivered the {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)} method will - * be called withe delivery token being passed as a parameter. - * </ul> - * <p> - * An action is in progress until either:</p> - * <ul> - * <li>isComplete() returns true or </li> - * <li>getException() is not null. If a client shuts down before delivery is complete - * an exception is returned. As long as the Java Runtime is not stopped a delivery token - * is valid across a connection disconnect and reconnect. In the event the client - * is shut down the getPendingDeliveryTokens method can be used once the client is - * restarted to obtain a list of delivery tokens for inflight messages.</li> - * </ul> - * - */ - -public interface IMqttDeliveryToken extends IMqttToken { - /** - * Returns the message associated with this token. - * <p>Until the message has been delivered, the message being delivered will - * be returned. Once the message has been delivered <code>null</code> will be - * returned. - * @return the message associated with this token or null if already delivered. - * @throws MqttException if there was a problem completing retrieving the message - */ - public MqttMessage getMessage() throws MqttException; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttMessageListener.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttMessageListener.java deleted file mode 100644 index 10ae31a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttMessageListener.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Ian Craggs - initial API and implementation and/or initial documentation - */ - -package org.eclipse.paho.client.mqttv3; - -/** - * Implementers of this interface will be notified when a message arrives. - * - */ -public interface IMqttMessageListener { - /** - * This method is called when a message arrives from the server. - * - * <p> - * This method is invoked synchronously by the MQTT client. An - * acknowledgment is not sent back to the server until this - * method returns cleanly.</p> - * <p> - * If an implementation of this method throws an <code>Exception</code>, then the - * client will be shut down. When the client is next re-connected, any QoS - * 1 or 2 messages will be redelivered by the server.</p> - * <p> - * Any additional messages which arrive while an - * implementation of this method is running, will build up in memory, and - * will then back up on the network.</p> - * <p> - * If an application needs to persist data, then it - * should ensure the data is persisted prior to returning from this method, as - * after returning from this method, the message is considered to have been - * delivered, and will not be reproducible.</p> - * <p> - * It is possible to send a new message within an implementation of this callback - * (for example, a response to this message), but the implementation must not - * disconnect the client, as it will be impossible to send an acknowledgment for - * the message being processed, and a deadlock will occur.</p> - * - * @param topic name of the topic on the message was published to - * @param message the actual message. - * @throws Exception if a terminal error has occurred, and the client should be - * shut down. - */ - public void messageArrived(String topic, MqttMessage message) throws Exception; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttToken.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttToken.java deleted file mode 100644 index d19ccde..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/IMqttToken.java +++ /dev/null @@ -1,163 +0,0 @@ -/************************************************************************** - * Copyright (c) 2009, 2012 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - */ -package org.eclipse.paho.client.mqttv3; - -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; - -/** - * Provides a mechanism for tracking the completion of an asynchronous task. - * - * <p>When using the asynchronous/non-blocking MQTT programming interface all - * methods/operations that take any time (and in particular those that involve - * any network operation) return control to the caller immediately. The operation - * then proceeds to run in the background so as not to block the invoking thread. - * An IMqttToken is used to track the state of the operation. An application can use the - * token to wait for an operation to complete. A token is passed to callbacks - * once the operation completes and provides context linking it to the original - * request. A token is associated with a single operation.</p> - * <p> - * An action is in progress until either:</p> - * <ul> - * <li>isComplete() returns true or</li> - * <li>getException() is not null.</li> - * </ul> - * - */ -public interface IMqttToken { - - /** - * Blocks the current thread until the action this token is associated with has - * completed. - * - * @throws MqttException if there was a problem with the action associated with the token. - * @see #waitForCompletion(long) - */ - public void waitForCompletion() throws MqttException; - - /** - * Blocks the current thread until the action this token is associated with has - * completed. - * <p>The timeout specifies the maximum time it will block for. If the action - * completes before the timeout then control returns immediately, if not - * it will block until the timeout expires. </p> - * <p>If the action being tracked fails or the timeout expires an exception will - * be thrown. In the event of a timeout the action may complete after timeout. - * </p> - * - * @param timeout the maximum amount of time to wait for, in milliseconds. - * @throws MqttException if there was a problem with the action associated with the token. - */ - public void waitForCompletion(long timeout) throws MqttException; - - /** - * Returns whether or not the action has finished. - * <p>True will be returned both in the case where the action finished successfully - * and in the case where it failed. If the action failed {@link #getException()} will - * be non null. - * </p> - * @return whether or not the action has finished. - */ - public boolean isComplete(); - - /** - * Returns an exception providing more detail if an operation failed. - * <p>While an action in in progress and when an action completes successfully - * null will be returned. Certain errors like timeout or shutting down will not - * set the exception as the action has not failed or completed at that time - * </p> - * @return exception may return an exception if the operation failed. Null will be - * returned while action is in progress and if action completes successfully. - */ - public MqttException getException(); - - /** - * Register a listener to be notified when an action completes. - * <p>Once a listener is registered it will be invoked when the action the token - * is associated with either succeeds or fails. - * </p> - * @param listener to be invoked once the action completes - */ - public void setActionCallback(IMqttActionListener listener); - - /** - * Return the async listener for this token. - * @return listener that is set on the token or null if a listener is not registered. - */ - public IMqttActionListener getActionCallback(); - - /** - * Returns the MQTT client that is responsible for processing the asynchronous - * action - * @return the client - */ - public IMqttAsyncClient getClient(); - - /** - * Returns the topic string(s) for the action being tracked by this - * token. If the action has not been initiated or the action has not - * topic associated with it such as connect then null will be returned. - * - * @return the topic string(s) for the subscribe being tracked by this token or null - */ - public String[] getTopics(); - - /** - * Store some context associated with an action. - * <p>Allows the caller of an action to store some context that can be - * accessed from within the ActionListener associated with the action. This - * can be useful when the same ActionListener is associated with multiple - * actions</p> - * @param userContext to associate with an action - */ - public void setUserContext(Object userContext); - - /** - * Retrieve the context associated with an action. - * <p>Allows the ActionListener associated with an action to retrieve any context - * that was associated with the action when the action was invoked. If not - * context was provided null is returned. </p> - - * @return Object context associated with an action or null if there is none. - */ - public Object getUserContext(); - - /** - * Returns the message ID of the message that is associated with the token. - * A message id of zero will be returned for tokens associated with - * connect, disconnect and ping operations as there can only ever - * be one of these outstanding at a time. For other operations - * the MQTT message id flowed over the network. - * @return the message ID of the message that is associated with the token - */ - public int getMessageId(); - - /** - * @return the granted QoS list from a suback - */ - public int[] getGrantedQos(); - - /** - * @return the session present flag from a connack - */ - public boolean getSessionPresent(); - - /** - * @return the response wire message - */ - public MqttWireMessage getResponse(); - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttAsyncClient.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttAsyncClient.java deleted file mode 100644 index ae5150b..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttAsyncClient.java +++ /dev/null @@ -1,1610 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - * James Sutton - Bug 459142 - WebSocket support for the Java client. - * James Sutton - Automatic Reconnect & Offline Buffering. - */ - -package org.eclipse.paho.client.mqttv3; - -import java.lang.reflect.Field; -import java.net.URI; -import java.net.URISyntaxException; -import java.util.Hashtable; -import java.util.Properties; -import java.util.Timer; -import java.util.TimerTask; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLSocketFactory; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; -import org.eclipse.paho.client.mqttv3.internal.ConnectActionListener; -import org.eclipse.paho.client.mqttv3.internal.DisconnectedMessageBuffer; -import org.eclipse.paho.client.mqttv3.internal.ExceptionHelper; -import org.eclipse.paho.client.mqttv3.internal.NetworkModule; -import org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule; -import org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule; -import org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory; -import org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketNetworkModule; -import org.eclipse.paho.client.mqttv3.internal.websocket.WebSocketSecureNetworkModule; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttDisconnect; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttSubscribe; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttUnsubscribe; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; -import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence; -import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; -import org.eclipse.paho.client.mqttv3.util.Debug; - -/** - * Lightweight client for talking to an MQTT server using non-blocking methods - * that allow an operation to run in the background. - * - * <p> - * This class implements the non-blocking {@link IMqttAsyncClient} client - * interface allowing applications to initiate MQTT actions and then carry on - * working while the MQTT action completes on a background thread. This - * implementation is compatible with all Java SE runtimes from 1.7 and up. - * </p> - * <p> - * An application can connect to an MQTT server using: - * </p> - * <ul> - * <li>A plain TCP socket - * <li>A secure SSL/TLS socket - * </ul> - * - * <p> - * To enable messages to be delivered even across network and client restarts - * messages need to be safely stored until the message has been delivered at the - * requested quality of service. A pluggable persistence mechanism is provided - * to store the messages. - * </p> - * <p> - * By default {@link MqttDefaultFilePersistence} is used to store messages to a - * file. If persistence is set to null then messages are stored in memory and - * hence can be lost if the client, Java runtime or device shuts down. - * </p> - * <p> - * If connecting with {@link MqttConnectOptions#setCleanSession(boolean)} set to - * true it is safe to use memory persistence as all state is cleared when a - * client disconnects. If connecting with cleanSession set to false in order to - * provide reliable message delivery then a persistent message store such as the - * default one should be used. - * </p> - * <p> - * The message store interface is pluggable. Different stores can be used by - * implementing the {@link MqttClientPersistence} interface and passing it to - * the clients constructor. - * </p> - * - * @see IMqttAsyncClient - */ -public class MqttAsyncClient implements IMqttAsyncClient { - private static final String CLASS_NAME = MqttAsyncClient.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private static final String CLIENT_ID_PREFIX = "paho"; - private static final long QUIESCE_TIMEOUT = 30000; // ms - private static final long DISCONNECT_TIMEOUT = 10000; // ms - private static final char MIN_HIGH_SURROGATE = '\uD800'; - private static final char MAX_HIGH_SURROGATE = '\uDBFF'; - private String clientId; - private String serverURI; - protected ClientComms comms; - private Hashtable topics; - private MqttClientPersistence persistence; - private MqttCallback mqttCallback; - private MqttConnectOptions connOpts; - private Object userContext; - private Timer reconnectTimer; // Automatic reconnect timer - private static int reconnectDelay = 1000; // Reconnect delay, starts at 1 - // second - private boolean reconnecting = false; - private static Object clientLock = new Object(); // Simple lock - - private ScheduledExecutorService executorService; - - /** - * Create an MqttAsyncClient that is used to communicate with an MQTT - * server. - * <p> - * The address of a server can be specified on the constructor. - * Alternatively a list containing one or more servers can be specified - * using the {@link MqttConnectOptions#setServerURIs(String[]) - * setServerURIs} method on MqttConnectOptions. - * - * <p> - * The <code>serverURI</code> parameter is typically used with the the - * <code>clientId</code> parameter to form a key. The key is used to store - * and reference messages while they are being delivered. Hence the - * serverURI specified on the constructor must still be specified even if a - * list of servers is specified on an MqttConnectOptions object. The - * serverURI on the constructor must remain the same across restarts of the - * client for delivery of messages to be maintained from a given client to a - * given server or set of servers. - * - * <p> - * The address of the server to connect to is specified as a URI. Two types - * of connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. For example: - * </p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p> - * If the port is not specified, it will default to 1883 for - * <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less - * that 65535 characters. It must be unique across all clients connecting to - * the same server. The clientId is used by the server to store data related - * to the client, hence it is important that the clientId remain the same - * when connecting to a server if durable subscriptions or reliable - * messaging are required. - * <p> - * A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client - * identifier is used by the server to identify a client when it reconnects, - * the client must use the same identifier between connections if durable - * subscriptions or reliable delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - - * applications can use - * {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply a - * factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL - * settings as a simple Java Properties using - * {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust - * stores.</li> - * </ul> - * - * <p> - * In Java ME, the platform settings are used for SSL connections. - * </p> - * - * <p> - * An instance of the default persistence mechanism - * {@link MqttDefaultFilePersistence} is used by the client. To specify a - * different persistence mechanism or to turn off persistence, use the - * {@link #MqttAsyncClient(String, String, MqttClientPersistence)} - * constructor. - * - * @param serverURI - * the address of the server to connect to, specified as a URI. - * Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId - * a client identifier that is unique on the server being - * connected to - * @throws IllegalArgumentException - * if the URI does not start with "tcp://", "ssl://" or - * "local://". - * @throws IllegalArgumentException - * if the clientId is null or is greater than 65535 characters - * in length - * @throws MqttException - * if any other problem was encountered - */ - public MqttAsyncClient(String serverURI, String clientId) throws MqttException { - this(serverURI, clientId, new MqttDefaultFilePersistence()); - } - - /** - * Create an MqttAsyncClient that is used to communicate with an MQTT - * server. - * <p> - * The address of a server can be specified on the constructor. - * Alternatively a list containing one or more servers can be specified - * using the {@link MqttConnectOptions#setServerURIs(String[]) - * setServerURIs} method on MqttConnectOptions. - * - * <p> - * The <code>serverURI</code> parameter is typically used with the the - * <code>clientId</code> parameter to form a key. The key is used to store - * and reference messages while they are being delivered. Hence the - * serverURI specified on the constructor must still be specified even if a - * list of servers is specified on an MqttConnectOptions object. The - * serverURI on the constructor must remain the same across restarts of the - * client for delivery of messages to be maintained from a given client to a - * given server or set of servers. - * - * <p> - * The address of the server to connect to is specified as a URI. Two types - * of connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. For example: - * </p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p> - * If the port is not specified, it will default to 1883 for - * <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less - * that 65535 characters. It must be unique across all clients connecting to - * the same server. The clientId is used by the server to store data related - * to the client, hence it is important that the clientId remain the same - * when connecting to a server if durable subscriptions or reliable - * messaging are required. - * <p> - * A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client - * identifier is used by the server to identify a client when it reconnects, - * the client must use the same identifier between connections if durable - * subscriptions or reliable delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - - * applications can use - * {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply a - * factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL - * settings as a simple Java Properties using - * {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust - * stores.</li> - * </ul> - * - * <p> - * In Java ME, the platform settings are used for SSL connections. - * </p> - * <p> - * A persistence mechanism is used to enable reliable messaging. For - * messages sent at qualities of service (QoS) 1 or 2 to be reliably - * delivered, messages must be stored (on both the client and server) until - * the delivery of the message is complete. If messages are not safely - * stored when being delivered then a failure in the client or server can - * result in lost messages. A pluggable persistence mechanism is supported - * via the {@link MqttClientPersistence} interface. An implementer of this - * interface that safely stores messages must be specified in order for - * delivery of messages to be reliable. In addition - * {@link MqttConnectOptions#setCleanSession(boolean)} must be set to false. - * In the event that only QoS 0 messages are sent or received or - * cleanSession is set to true then a safe store is not needed. - * </p> - * <p> - * An implementation of file-based persistence is provided in class - * {@link MqttDefaultFilePersistence} which will work in all Java SE based - * systems. If no persistence is needed, the persistence parameter can be - * explicitly set to <code>null</code>. - * </p> - * - * @param serverURI - * the address of the server to connect to, specified as a URI. - * Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId - * a client identifier that is unique on the server being - * connected to - * @param persistence - * the persistence class to use to store in-flight message. If - * null then the default persistence mechanism is used - * @throws MqttException - * if any other problem was encountered - */ - public MqttAsyncClient(String serverURI, String clientId, MqttClientPersistence persistence) throws MqttException { - this(serverURI, clientId, persistence, new TimerPingSender()); - } - - public MqttAsyncClient(String serverURI, String clientId, MqttClientPersistence persistence, - MqttPingSender pingSender) throws MqttException { - this(serverURI, clientId, persistence, pingSender, null); - } - - /** - * Create an MqttAsyncClient that is used to communicate with an MQTT - * server. - * <p> - * The address of a server can be specified on the constructor. - * Alternatively a list containing one or more servers can be specified - * using the {@link MqttConnectOptions#setServerURIs(String[]) - * setServerURIs} method on MqttConnectOptions. - * - * <p> - * The <code>serverURI</code> parameter is typically used with the the - * <code>clientId</code> parameter to form a key. The key is used to store - * and reference messages while they are being delivered. Hence the - * serverURI specified on the constructor must still be specified even if a - * list of servers is specified on an MqttConnectOptions object. The - * serverURI on the constructor must remain the same across restarts of the - * client for delivery of messages to be maintained from a given client to a - * given server or set of servers. - * - * <p> - * The address of the server to connect to is specified as a URI. Two types - * of connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. For example: - * </p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p> - * If the port is not specified, it will default to 1883 for - * <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less - * that 65535 characters. It must be unique across all clients connecting to - * the same server. The clientId is used by the server to store data related - * to the client, hence it is important that the clientId remain the same - * when connecting to a server if durable subscriptions or reliable - * messaging are required. - * <p> - * A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client - * identifier is used by the server to identify a client when it reconnects, - * the client must use the same identifier between connections if durable - * subscriptions or reliable delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - - * applications can use - * {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply a - * factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL - * settings as a simple Java Properties using - * {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust - * stores.</li> - * </ul> - * - * <p> - * In Java ME, the platform settings are used for SSL connections. - * </p> - * <p> - * A persistence mechanism is used to enable reliable messaging. For - * messages sent at qualities of service (QoS) 1 or 2 to be reliably - * delivered, messages must be stored (on both the client and server) until - * the delivery of the message is complete. If messages are not safely - * stored when being delivered then a failure in the client or server can - * result in lost messages. A pluggable persistence mechanism is supported - * via the {@link MqttClientPersistence} interface. An implementer of this - * interface that safely stores messages must be specified in order for - * delivery of messages to be reliable. In addition - * {@link MqttConnectOptions#setCleanSession(boolean)} must be set to false. - * In the event that only QoS 0 messages are sent or received or - * cleanSession is set to true then a safe store is not needed. - * </p> - * <p> - * An implementation of file-based persistence is provided in class - * {@link MqttDefaultFilePersistence} which will work in all Java SE based - * systems. If no persistence is needed, the persistence parameter can be - * explicitly set to <code>null</code>. - * </p> - * - * @param serverURI - * the address of the server to connect to, specified as a URI. - * Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId - * a client identifier that is unique on the server being - * connected to - * @param persistence - * the persistence class to use to store in-flight message. If - * null then the default persistence mechanism is used - * @param pingSender - * Custom {@link MqttPingSender} implementation. - * @param executorService - * used for managing threads. If null then a newFixedThreadPool - * is used. - * @throws IllegalArgumentException - * if the URI does not start with "tcp://", "ssl://" or - * "local://" - * @throws IllegalArgumentException - * if the clientId is null or is greater than 65535 characters - * in length - * @throws MqttException - * if any other problem was encountered - */ - public MqttAsyncClient(String serverURI, String clientId, MqttClientPersistence persistence, - MqttPingSender pingSender, ScheduledExecutorService executorService) throws MqttException { - final String methodName = "MqttAsyncClient"; - - log.setResourceName(clientId); - - if (clientId == null) { // Support empty client Id, 3.1.1 standard - throw new IllegalArgumentException("Null clientId"); - } - // Count characters, surrogate pairs count as one character. - int clientIdLength = 0; - for (int i = 0; i < clientId.length() - 1; i++) { - if (Character_isHighSurrogate(clientId.charAt(i))) - i++; - clientIdLength++; - } - if (clientIdLength > 65535) { - throw new IllegalArgumentException("ClientId longer than 65535 characters"); - } - - MqttConnectOptions.validateURI(serverURI); - - this.serverURI = serverURI; - this.clientId = clientId; - - this.persistence = persistence; - if (this.persistence == null) { - this.persistence = new MemoryPersistence(); - } - - this.executorService = executorService; - if (this.executorService == null) { - this.executorService = Executors.newScheduledThreadPool(10); - } - - // @TRACE 101=<init> ClientID={0} ServerURI={1} PersistenceType={2} - log.fine(CLASS_NAME, methodName, "101", new Object[] { clientId, serverURI, persistence }); - - this.persistence.open(clientId, serverURI); - this.comms = new ClientComms(this, this.persistence, pingSender, this.executorService); - this.persistence.close(); - this.topics = new Hashtable(); - - } - - /** - * @param ch - * the character to check. - * @return returns 'true' if the character is a high-surrogate code unit - */ - protected static boolean Character_isHighSurrogate(char ch) { - return (ch >= MIN_HIGH_SURROGATE) && (ch <= MAX_HIGH_SURROGATE); - } - - /** - * Factory method to create an array of network modules, one for each of the - * supplied URIs - * - * @param address - * the URI for the server. - * @param options - * the {@link MqttConnectOptions} for the connection. - * @return a network module appropriate to the specified address. - * @throws MqttException - * if an exception occurs creating the network Modules - * @throws MqttSecurityException - * if an issue occurs creating an SSL / TLS Socket - */ - protected NetworkModule[] createNetworkModules(String address, MqttConnectOptions options) - throws MqttException, MqttSecurityException { - final String methodName = "createNetworkModules"; - // @TRACE 116=URI={0} - log.fine(CLASS_NAME, methodName, "116", new Object[] { address }); - - NetworkModule[] networkModules = null; - String[] serverURIs = options.getServerURIs(); - String[] array = null; - if (serverURIs == null) { - array = new String[] { address }; - } else if (serverURIs.length == 0) { - array = new String[] { address }; - } else { - array = serverURIs; - } - - networkModules = new NetworkModule[array.length]; - for (int i = 0; i < array.length; i++) { - networkModules[i] = createNetworkModule(array[i], options); - } - - log.fine(CLASS_NAME, methodName, "108"); - return networkModules; - } - - /** - * Factory method to create the correct network module, based on the - * supplied address URI. - * - * @param address the URI for the server. - * @param options Connect options - * @return a network module appropriate to the specified address. - */ - private NetworkModule createNetworkModule(String address, MqttConnectOptions options) throws MqttException, MqttSecurityException { - final String methodName = "createNetworkModule"; - // @TRACE 115=URI={0} - log.fine(CLASS_NAME,methodName, "115", new Object[] {address}); - - NetworkModule netModule; - SocketFactory factory = options.getSocketFactory(); - - int serverURIType = MqttConnectOptions.validateURI(address); - - URI uri; - try { - uri = new URI(address); - // If the returned uri contains no host and the address contains underscores, - // then it's likely that Java did not parse the URI - if(uri.getHost() == null && address.contains("_")){ - try { - final Field hostField = URI.class.getDeclaredField("host"); - hostField.setAccessible(true); - // Get everything after the scheme:// - String shortAddress = address.substring(uri.getScheme().length() + 3); - hostField.set(uri, getHostName(shortAddress)); - - } catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) { - throw ExceptionHelper.createMqttException(e.getCause()); - } - - } - } catch (URISyntaxException e) { - throw new IllegalArgumentException("Malformed URI: " + address + ", " + e.getMessage()); - } - - String host = uri.getHost(); - int port = uri.getPort(); // -1 if not defined - - switch (serverURIType) { - case MqttConnectOptions.URI_TYPE_TCP : - if (port == -1) { - port = 1883; - } - if (factory == null) { - factory = SocketFactory.getDefault(); - } - else if (factory instanceof SSLSocketFactory) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH); - } - netModule = new TCPNetworkModule(factory, host, port, clientId); - ((TCPNetworkModule)netModule).setConnectTimeout(options.getConnectionTimeout()); - break; - case MqttConnectOptions.URI_TYPE_SSL: - if (port == -1) { - port = 8883; - } - SSLSocketFactoryFactory factoryFactory = null; - if (factory == null) { -// try { - factoryFactory = new SSLSocketFactoryFactory(); - Properties sslClientProps = options.getSSLProperties(); - if (null != sslClientProps) - factoryFactory.initialize(sslClientProps, null); - factory = factoryFactory.createSocketFactory(null); -// } -// catch (MqttDirectException ex) { -// throw ExceptionHelper.createMqttException(ex.getCause()); -// } - } - else if ((factory instanceof SSLSocketFactory) == false) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH); - } - - // Create the network module... - netModule = new SSLNetworkModule((SSLSocketFactory) factory, host, port, clientId); - ((SSLNetworkModule)netModule).setSSLhandshakeTimeout(options.getConnectionTimeout()); - ((SSLNetworkModule)netModule).setSSLHostnameVerifier(options.getSSLHostnameVerifier()); - // Ciphers suites need to be set, if they are available - if (factoryFactory != null) { - String[] enabledCiphers = factoryFactory.getEnabledCipherSuites(null); - if (enabledCiphers != null) { - ((SSLNetworkModule) netModule).setEnabledCiphers(enabledCiphers); - } - } - break; - case MqttConnectOptions.URI_TYPE_WS: - if (port == -1) { - port = 80; - } - if (factory == null) { - factory = SocketFactory.getDefault(); - } - else if (factory instanceof SSLSocketFactory) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH); - } - netModule = new WebSocketNetworkModule(factory, address, host, port, clientId); - ((WebSocketNetworkModule)netModule).setConnectTimeout(options.getConnectionTimeout()); - break; - case MqttConnectOptions.URI_TYPE_WSS: - if (port == -1) { - port = 443; - } - SSLSocketFactoryFactory wSSFactoryFactory = null; - if (factory == null) { - wSSFactoryFactory = new SSLSocketFactoryFactory(); - Properties sslClientProps = options.getSSLProperties(); - if (null != sslClientProps) - wSSFactoryFactory.initialize(sslClientProps, null); - factory = wSSFactoryFactory.createSocketFactory(null); - - } - else if ((factory instanceof SSLSocketFactory) == false) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_SOCKET_FACTORY_MISMATCH); - } - - // Create the network module... - netModule = new WebSocketSecureNetworkModule((SSLSocketFactory) factory, address, host, port, clientId); - ((WebSocketSecureNetworkModule)netModule).setSSLhandshakeTimeout(options.getConnectionTimeout()); - // Ciphers suites need to be set, if they are available - if (wSSFactoryFactory != null) { - String[] enabledCiphers = wSSFactoryFactory.getEnabledCipherSuites(null); - if (enabledCiphers != null) { - ((SSLNetworkModule) netModule).setEnabledCiphers(enabledCiphers); - } - } - break; - default: - // This shouldn't happen, as long as validateURI() has been called. - log.fine(CLASS_NAME,methodName, "119", new Object[] {address}); - netModule = null; - } - return netModule; - } - - private String getHostName(String uri) { - int portIndex = uri.indexOf(':'); - if (portIndex == -1) { - portIndex = uri.indexOf('/'); - } - if (portIndex == -1) { - portIndex = uri.length(); - } - return uri.substring(0, portIndex); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#connect(java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken connect(Object userContext, IMqttActionListener callback) - throws MqttException, MqttSecurityException { - return this.connect(new MqttConnectOptions(), userContext, callback); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#connect() - */ - public IMqttToken connect() throws MqttException, MqttSecurityException { - return this.connect(null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#connect(org.eclipse.paho. - * client.mqttv3.MqttConnectOptions) - */ - public IMqttToken connect(MqttConnectOptions options) throws MqttException, MqttSecurityException { - return this.connect(options, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#connect(org.eclipse.paho. - * client.mqttv3.MqttConnectOptions, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken connect(MqttConnectOptions options, Object userContext, IMqttActionListener callback) - throws MqttException, MqttSecurityException { - final String methodName = "connect"; - if (comms.isConnected()) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CONNECTED); - } - if (comms.isConnecting()) { - throw new MqttException(MqttException.REASON_CODE_CONNECT_IN_PROGRESS); - } - if (comms.isDisconnecting()) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING); - } - if (comms.isClosed()) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_CLOSED); - } - if (options == null) { - options = new MqttConnectOptions(); - } - this.connOpts = options; - this.userContext = userContext; - final boolean automaticReconnect = options.isAutomaticReconnect(); - - // @TRACE 103=cleanSession={0} connectionTimeout={1} TimekeepAlive={2} - // userName={3} password={4} will={5} userContext={6} callback={7} - log.fine(CLASS_NAME, methodName, "103", - new Object[] { Boolean.valueOf(options.isCleanSession()), new Integer(options.getConnectionTimeout()), - new Integer(options.getKeepAliveInterval()), options.getUserName(), - ((null == options.getPassword()) ? "[null]" : "[notnull]"), - ((null == options.getWillMessage()) ? "[null]" : "[notnull]"), userContext, callback }); - comms.setNetworkModules(createNetworkModules(serverURI, options)); - comms.setReconnectCallback(new MqttReconnectCallback(automaticReconnect)); - - // Insert our own callback to iterate through the URIs till the connect - // succeeds - MqttToken userToken = new MqttToken(getClientId()); - ConnectActionListener connectActionListener = new ConnectActionListener(this, persistence, comms, options, - userToken, userContext, callback, reconnecting); - userToken.setActionCallback(connectActionListener); - userToken.setUserContext(this); - - // If we are using the MqttCallbackExtended, set it on the - // connectActionListener - if (this.mqttCallback instanceof MqttCallbackExtended) { - connectActionListener.setMqttCallbackExtended((MqttCallbackExtended) this.mqttCallback); - } - - comms.setNetworkModuleIndex(0); - connectActionListener.connect(); - - return userToken; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnect(java.lang. - * Object, org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken disconnect(Object userContext, IMqttActionListener callback) throws MqttException { - return this.disconnect(QUIESCE_TIMEOUT, userContext, callback); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnect() - */ - public IMqttToken disconnect() throws MqttException { - return this.disconnect(null, null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnect(long) - */ - public IMqttToken disconnect(long quiesceTimeout) throws MqttException { - return this.disconnect(quiesceTimeout, null, null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnect(long, - * java.lang.Object, org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken disconnect(long quiesceTimeout, Object userContext, IMqttActionListener callback) - throws MqttException { - final String methodName = "disconnect"; - // @TRACE 104=> quiesceTimeout={0} userContext={1} callback={2} - log.fine(CLASS_NAME, methodName, "104", new Object[] { new Long(quiesceTimeout), userContext, callback }); - - MqttToken token = new MqttToken(getClientId()); - token.setActionCallback(callback); - token.setUserContext(userContext); - - MqttDisconnect disconnect = new MqttDisconnect(); - try { - comms.disconnect(disconnect, quiesceTimeout, token); - } catch (MqttException ex) { - // @TRACE 105=< exception - log.fine(CLASS_NAME, methodName, "105", null, ex); - throw ex; - } - // @TRACE 108=< - log.fine(CLASS_NAME, methodName, "108"); - - return token; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly() - */ - public void disconnectForcibly() throws MqttException { - disconnectForcibly(QUIESCE_TIMEOUT, DISCONNECT_TIMEOUT); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly(long) - */ - public void disconnectForcibly(long disconnectTimeout) throws MqttException { - disconnectForcibly(QUIESCE_TIMEOUT, disconnectTimeout); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly(long, - * long) - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout) throws MqttException { - comms.disconnectForcibly(quiesceTimeout, disconnectTimeout); - } - - /** - * Disconnects from the server forcibly to reset all the states. Could be - * useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none - * MQTT server and it will certainly fail to send the disconnect packet. - * - * @param quiesceTimeout - * the amount of time in milliseconds to allow for existing work - * to finish before disconnecting. A value of zero or less means - * the client will not quiesce. - * @param disconnectTimeout - * the amount of time in milliseconds to allow send disconnect - * packet to server. - * @param sendDisconnectPacket - * if true, will send the disconnect packet to the server - * @throws MqttException - * if any unexpected error - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout, boolean sendDisconnectPacket) - throws MqttException { - comms.disconnectForcibly(quiesceTimeout, disconnectTimeout, sendDisconnectPacket); - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#isConnected() - */ - public boolean isConnected() { - return comms.isConnected(); - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#getClientId() - */ - public String getClientId() { - return clientId; - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#getServerURI() - */ - public String getServerURI() { - return serverURI; - } - - /** - * Returns the currently connected Server URI Implemented due to: - * https://bugs.eclipse.org/bugs/show_bug.cgi?id=481097 - * - * Where getServerURI only returns the URI that was provided in - * MqttAsyncClient's constructor, getCurrentServerURI returns the URI of the - * Server that the client is currently connected to. This would be different - * in scenarios where multiple server URIs have been provided to the - * MqttConnectOptions. - * - * @return the currently connected server URI - */ - public String getCurrentServerURI() { - return comms.getNetworkModules()[comms.getNetworkModuleIndex()].getServerURI(); - } - - /** - * Get a topic object which can be used to publish messages. - * <p> - * There are two alternative methods that should be used in preference to - * this one when publishing a message: - * </p> - * <ul> - * <li>{@link MqttAsyncClient#publish(String, MqttMessage)} to publish a - * message in a non-blocking manner or</li> - * <li>{@link MqttClient#publish(String, MqttMessage)} to publish a message - * in a blocking manner</li> - * </ul> - * <p> - * When you build an application, the design of the topic tree should take - * into account the following principles of topic name syntax and semantics: - * </p> - * - * <ul> - * <li>A topic must be at least one character long.</li> - * <li>Topic names are case sensitive. For example, <em>ACCOUNTS</em> and - * <em>Accounts</em> are two different topics.</li> - * <li>Topic names can include the space character. For example, - * <em>Accounts payable</em> is a valid topic.</li> - * <li>A leading "/" creates a distinct topic. For example, - * <em>/finance</em> is different from <em>finance</em>. <em>/finance</em> - * matches "+/+" and "/+", but not "+".</li> - * <li>Do not include the null character (Unicode \x0000) in any topic.</li> - * </ul> - * - * <p> - * The following principles apply to the construction and content of a topic - * tree: - * </p> - * - * <ul> - * <li>The length is limited to 64k but within that there are no limits to - * the number of levels in a topic tree.</li> - * <li>There can be any number of root nodes; that is, there can be any - * number of topic trees.</li> - * </ul> - * - * @param topic - * the topic to use, for example "finance/stock/ibm". - * @return an MqttTopic object, which can be used to publish messages to the - * topic. - * @throws IllegalArgumentException - * if the topic contains a '+' or '#' wildcard character. - */ - protected MqttTopic getTopic(String topic) { - MqttTopic.validate(topic, false/* wildcards NOT allowed */); - - MqttTopic result = (MqttTopic) topics.get(topic); - if (result == null) { - result = new MqttTopic(topic, comms); - topics.put(topic, result); - } - return result; - } - - /* - * (non-Javadoc) Check and send a ping if needed. <p>By default, client - * sends PingReq to server to keep the connection to server. For some - * platforms which cannot use this mechanism, such as Android, developer - * needs to handle the ping request manually with this method. </p> - * - * @throws MqttException for other errors encountered while publishing the - * message. - */ - public IMqttToken checkPing(Object userContext, IMqttActionListener callback) throws MqttException { - final String methodName = "ping"; - MqttToken token; - // @TRACE 117=> - log.fine(CLASS_NAME, methodName, "117"); - - token = comms.checkForActivity(); - // @TRACE 118=< - log.fine(CLASS_NAME, methodName, "118"); - - return token; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String, int, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken subscribe(String topicFilter, int qos, Object userContext, IMqttActionListener callback) - throws MqttException { - return this.subscribe(new String[] { topicFilter }, new int[] { qos }, userContext, callback); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String, int) - */ - public IMqttToken subscribe(String topicFilter, int qos) throws MqttException { - return this.subscribe(new String[] { topicFilter }, new int[] { qos }, null, null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String[], int[]) - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos) throws MqttException { - return this.subscribe(topicFilters, qos, null, null); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String[], int[], java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos, Object userContext, IMqttActionListener callback) - throws MqttException { - final String methodName = "subscribe"; - - if (topicFilters.length != qos.length) { - throw new IllegalArgumentException(); - } - - // remove any message handlers for individual topics - for (int i = 0; i < topicFilters.length; ++i) { - this.comms.removeMessageListener(topicFilters[i]); - } - - // Only Generate Log string if we are logging at FINE level - if (log.isLoggable(Logger.FINE)) { - StringBuffer subs = new StringBuffer(); - for (int i = 0; i < topicFilters.length; i++) { - if (i > 0) { - subs.append(", "); - } - subs.append("topic=").append(topicFilters[i]).append(" qos=").append(qos[i]); - - // Check if the topic filter is valid before subscribing - MqttTopic.validate(topicFilters[i], true/* allow wildcards */); - } - // @TRACE 106=Subscribe topicFilter={0} userContext={1} callback={2} - log.fine(CLASS_NAME, methodName, "106", new Object[] { subs.toString(), userContext, callback }); - } - - MqttToken token = new MqttToken(getClientId()); - token.setActionCallback(callback); - token.setUserContext(userContext); - token.internalTok.setTopics(topicFilters); - - MqttSubscribe register = new MqttSubscribe(topicFilters, qos); - - comms.sendNoWait(register, token); - // @TRACE 109=< - log.fine(CLASS_NAME, methodName, "109"); - - return token; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String, int, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken subscribe(String topicFilter, int qos, Object userContext, IMqttActionListener callback, - IMqttMessageListener messageListener) throws MqttException { - - return this.subscribe(new String[] { topicFilter }, new int[] { qos }, userContext, callback, - new IMqttMessageListener[] { messageListener }); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String, int) - */ - public IMqttToken subscribe(String topicFilter, int qos, IMqttMessageListener messageListener) - throws MqttException { - return this.subscribe(new String[] { topicFilter }, new int[] { qos }, null, null, - new IMqttMessageListener[] { messageListener }); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#subscribe(java.lang. - * String[], int[]) - */ - public IMqttToken subscribe(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) - throws MqttException { - return this.subscribe(topicFilters, qos, null, null, messageListeners); - } - - public IMqttToken subscribe(String[] topicFilters, int[] qos, Object userContext, IMqttActionListener callback, - IMqttMessageListener[] messageListeners) throws MqttException { - - if ((messageListeners.length != qos.length) || (qos.length != topicFilters.length)) { - throw new IllegalArgumentException(); - } - - IMqttToken token = this.subscribe(topicFilters, qos, userContext, callback); - - // add message handlers to the list for this client - for (int i = 0; i < topicFilters.length; ++i) { - this.comms.setMessageListener(topicFilters[i], messageListeners[i]); - } - - return token; - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#unsubscribe(java.lang. - * String, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken unsubscribe(String topicFilter, Object userContext, IMqttActionListener callback) - throws MqttException { - return unsubscribe(new String[] { topicFilter }, userContext, callback); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#unsubscribe(java.lang. - * String) - */ - public IMqttToken unsubscribe(String topicFilter) throws MqttException { - return unsubscribe(new String[] { topicFilter }, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#unsubscribe(java.lang. - * String[]) - */ - public IMqttToken unsubscribe(String[] topicFilters) throws MqttException { - return unsubscribe(topicFilters, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#unsubscribe(java.lang. - * String[], java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttToken unsubscribe(String[] topicFilters, Object userContext, IMqttActionListener callback) - throws MqttException { - final String methodName = "unsubscribe"; - - // Only Generate Log string if we are logging at FINE level - if (log.isLoggable(Logger.FINE)) { - String subs = ""; - for (int i = 0; i < topicFilters.length; i++) { - if (i > 0) { - subs += ", "; - } - subs += topicFilters[i]; - } - - // @TRACE 107=Unsubscribe topic={0} userContext={1} callback={2} - log.fine(CLASS_NAME, methodName, "107", new Object[] { subs, userContext, callback }); - } - - for (int i = 0; i < topicFilters.length; i++) { - // Check if the topic filter is valid before unsubscribing - // Although we already checked when subscribing, but invalid - // topic filter is meanless for unsubscribing, just prohibit it - // to reduce unnecessary control packet send to broker. - MqttTopic.validate(topicFilters[i], true/* allow wildcards */); - } - - // remove message handlers from the list for this client - for (int i = 0; i < topicFilters.length; ++i) { - this.comms.removeMessageListener(topicFilters[i]); - } - - MqttToken token = new MqttToken(getClientId()); - token.setActionCallback(callback); - token.setUserContext(userContext); - token.internalTok.setTopics(topicFilters); - - MqttUnsubscribe unregister = new MqttUnsubscribe(topicFilters); - - comms.sendNoWait(unregister, token); - // @TRACE 110=< - log.fine(CLASS_NAME, methodName, "110"); - - return token; - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#setCallback(MqttCallback) - */ - public void setCallback(MqttCallback callback) { - this.mqttCallback = callback; - comms.setCallback(callback); - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#setManualAcks(manualAcks) - */ - public void setManualAcks(boolean manualAcks) { - comms.setManualAcks(manualAcks); - } - - public void messageArrivedComplete(int messageId, int qos) throws MqttException { - comms.messageArrivedComplete(messageId, qos); - } - - /** - * Returns a randomly generated client identifier based on the the fixed - * prefix (paho) and the system time. - * <p> - * When cleanSession is set to false, an application must ensure it uses the - * same client identifier when it reconnects to the server to resume state - * and maintain assured message delivery. - * </p> - * - * @return a generated client identifier - * @see MqttConnectOptions#setCleanSession(boolean) - */ - public static String generateClientId() { - // length of nanoTime = 15, so total length = 19 < 65535(defined in - // spec) - return CLIENT_ID_PREFIX + System.nanoTime(); - - } - - /* - * (non-Javadoc) - * - * @see IMqttAsyncClient#getPendingDeliveryTokens() - */ - public IMqttDeliveryToken[] getPendingDeliveryTokens() { - return comms.getPendingDeliveryTokens(); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#publish(java.lang.String, - * byte[], int, boolean, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttDeliveryToken publish(String topic, byte[] payload, int qos, boolean retained, Object userContext, - IMqttActionListener callback) throws MqttException, MqttPersistenceException { - MqttMessage message = new MqttMessage(payload); - message.setQos(qos); - message.setRetained(retained); - return this.publish(topic, message, userContext, callback); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#publish(java.lang.String, - * byte[], int, boolean) - */ - public IMqttDeliveryToken publish(String topic, byte[] payload, int qos, boolean retained) - throws MqttException, MqttPersistenceException { - return this.publish(topic, payload, qos, retained, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#publish(java.lang.String, - * org.eclipse.paho.client.mqttv3.MqttMessage) - */ - public IMqttDeliveryToken publish(String topic, MqttMessage message) - throws MqttException, MqttPersistenceException { - return this.publish(topic, message, null, null); - } - - /* - * (non-Javadoc) - * - * @see - * org.eclipse.paho.client.mqttv3.IMqttAsyncClient#publish(java.lang.String, - * org.eclipse.paho.client.mqttv3.MqttMessage, java.lang.Object, - * org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public IMqttDeliveryToken publish(String topic, MqttMessage message, Object userContext, - IMqttActionListener callback) throws MqttException, MqttPersistenceException { - final String methodName = "publish"; - // @TRACE 111=< topic={0} message={1}userContext={1} callback={2} - log.fine(CLASS_NAME, methodName, "111", new Object[] { topic, userContext, callback }); - - // Checks if a topic is valid when publishing a message. - MqttTopic.validate(topic, false/* wildcards NOT allowed */); - - MqttDeliveryToken token = new MqttDeliveryToken(getClientId()); - token.setActionCallback(callback); - token.setUserContext(userContext); - token.setMessage(message); - token.internalTok.setTopics(new String[] { topic }); - - MqttPublish pubMsg = new MqttPublish(topic, message); - comms.sendNoWait(pubMsg, token); - - // @TRACE 112=< - log.fine(CLASS_NAME, methodName, "112"); - - return token; - } - - /** - * User triggered attempt to reconnect - * - * @throws MqttException - * if there is an issue with reconnecting - */ - public void reconnect() throws MqttException { - final String methodName = "reconnect"; - // @Trace 500=Attempting to reconnect client: {0} - log.fine(CLASS_NAME, methodName, "500", new Object[] { this.clientId }); - // Some checks to make sure that we're not attempting to reconnect an - // already connected client - if (comms.isConnected()) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CONNECTED); - } - if (comms.isConnecting()) { - throw new MqttException(MqttException.REASON_CODE_CONNECT_IN_PROGRESS); - } - if (comms.isDisconnecting()) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING); - } - if (comms.isClosed()) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_CLOSED); - } - // We don't want to spam the server - stopReconnectCycle(); - - attemptReconnect(); - } - - /** - * Attempts to reconnect the client to the server. If successful it will - * make sure that there are no further reconnects scheduled. However if the - * connect fails, the delay will double up to 128 seconds and will - * re-schedule the reconnect for after the delay. - * - * Any thrown exceptions are logged but not acted upon as it is assumed that - * they are being thrown due to the server being offline and so reconnect - * attempts will continue. - */ - private void attemptReconnect() { - final String methodName = "attemptReconnect"; - // @Trace 500=Attempting to reconnect client: {0} - log.fine(CLASS_NAME, methodName, "500", new Object[] { this.clientId }); - try { - connect(this.connOpts, this.userContext, new MqttReconnectActionListener(methodName)); - } catch (MqttSecurityException ex) { - // @TRACE 804=exception - log.fine(CLASS_NAME, methodName, "804", null, ex); - } catch (MqttException ex) { - // @TRACE 804=exception - log.fine(CLASS_NAME, methodName, "804", null, ex); - } - } - - private void startReconnectCycle() { - String methodName = "startReconnectCycle"; - // @Trace 503=Start reconnect timer for client: {0}, delay: {1} - log.fine(CLASS_NAME, methodName, "503", new Object[] { this.clientId, new Long(reconnectDelay) }); - reconnectTimer = new Timer("MQTT Reconnect: " + clientId); - reconnectTimer.schedule(new ReconnectTask(), reconnectDelay); - } - - private void stopReconnectCycle() { - String methodName = "stopReconnectCycle"; - // @Trace 504=Stop reconnect timer for client: {0} - log.fine(CLASS_NAME, methodName, "504", new Object[] { this.clientId }); - synchronized (clientLock) { - if (this.connOpts.isAutomaticReconnect()) { - if (reconnectTimer != null) { - reconnectTimer.cancel(); - reconnectTimer = null; - } - reconnectDelay = 1000; // Reset Delay Timer - } - } - } - - private class ReconnectTask extends TimerTask { - private static final String methodName = "ReconnectTask.run"; - - public void run() { - // @Trace 506=Triggering Automatic Reconnect attempt. - log.fine(CLASS_NAME, methodName, "506"); - attemptReconnect(); - } - } - - class MqttReconnectCallback implements MqttCallbackExtended { - - final boolean automaticReconnect; - - MqttReconnectCallback(boolean isAutomaticReconnect) { - automaticReconnect = isAutomaticReconnect; - } - - public void connectionLost(Throwable cause) { - if (automaticReconnect) { - // Automatic reconnect is set so make sure comms is in resting - // state - comms.setRestingState(true); - reconnecting = true; - startReconnectCycle(); - } - } - - public void messageArrived(String topic, MqttMessage message) throws Exception { - } - - public void deliveryComplete(IMqttDeliveryToken token) { - } - - public void connectComplete(boolean reconnect, String serverURI) { - } - - } - - class MqttReconnectActionListener implements IMqttActionListener { - - final String methodName; - - MqttReconnectActionListener(String methodName) { - this.methodName = methodName; - } - - public void onSuccess(IMqttToken asyncActionToken) { - // @Trace 501=Automatic Reconnect Successful: {0} - log.fine(CLASS_NAME, methodName, "501", new Object[] { asyncActionToken.getClient().getClientId() }); - comms.setRestingState(false); - stopReconnectCycle(); - } - - public void onFailure(IMqttToken asyncActionToken, Throwable exception) { - // @Trace 502=Automatic Reconnect failed, rescheduling: {0} - log.fine(CLASS_NAME, methodName, "502", new Object[] { asyncActionToken.getClient().getClientId() }); - if (reconnectDelay < 128000) { - reconnectDelay = reconnectDelay * 2; - } - rescheduleReconnectCycle(reconnectDelay); - } - - private void rescheduleReconnectCycle(int delay) { - String reschedulemethodName = methodName + ":rescheduleReconnectCycle"; - // @Trace 505=Rescheduling reconnect timer for client: {0}, delay: - // {1} - log.fine(CLASS_NAME, reschedulemethodName, "505", - new Object[] { MqttAsyncClient.this.clientId, String.valueOf(reconnectDelay) }); - synchronized (clientLock) { - if (MqttAsyncClient.this.connOpts.isAutomaticReconnect()) { - if (reconnectTimer != null) { - reconnectTimer.schedule(new ReconnectTask(), delay); - } else { - // The previous reconnect timer was cancelled - reconnectDelay = delay; - startReconnectCycle(); - } - } - } - } - - } - - /** - * Sets the DisconnectedBufferOptions for this client - * - * @param bufferOpts - * the {@link DisconnectedBufferOptions} - */ - public void setBufferOpts(DisconnectedBufferOptions bufferOpts) { - this.comms.setDisconnectedMessageBuffer(new DisconnectedMessageBuffer(bufferOpts)); - } - - /** - * Returns the number of messages in the Disconnected Message Buffer - * - * @return Count of messages in the buffer - */ - public int getBufferedMessageCount() { - return this.comms.getBufferedMessageCount(); - } - - /** - * Returns a message from the Disconnected Message Buffer - * - * @param bufferIndex - * the index of the message to be retrieved. - * @return the message located at the bufferIndex - */ - public MqttMessage getBufferedMessage(int bufferIndex) { - return this.comms.getBufferedMessage(bufferIndex); - } - - /** - * Deletes a message from the Disconnected Message Buffer - * - * @param bufferIndex - * the index of the message to be deleted. - */ - public void deleteBufferedMessage(int bufferIndex) { - this.comms.deleteBufferedMessage(bufferIndex); - } - - /** - * Returns the current number of outgoing in-flight messages being sent by - * the client. Note that this number cannot be guaranteed to be 100% - * accurate as some messages may have been sent or queued in the time taken - * for this method to return. - * - * @return the current number of in-flight messages. - */ - public int getInFlightMessageCount() { - return this.comms.getActualInFlight(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#close() - */ - public void close() throws MqttException { - close(false); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#close() - */ - public void close(boolean force) throws MqttException { - final String methodName = "close"; - // @TRACE 113=< - log.fine(CLASS_NAME, methodName, "113"); - comms.close(force); - // @TRACE 114=> - log.fine(CLASS_NAME, methodName, "114"); - - } - - /** - * Return a debug object that can be used to help solve problems. - * - * @return the {@link Debug} object - */ - public Debug getDebug() { - return new Debug(clientId, comms); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallback.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallback.java deleted file mode 100644 index 21d9c10..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallback.java +++ /dev/null @@ -1,79 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - - -/** - * Enables an application to be notified when asynchronous - * events related to the client occur. - * Classes implementing this interface - * can be registered on both types of client: {@link IMqttClient#setCallback(MqttCallback)} - * and {@link IMqttAsyncClient#setCallback(MqttCallback)} - */ -public interface MqttCallback { - /** - * This method is called when the connection to the server is lost. - * - * @param cause the reason behind the loss of connection. - */ - public void connectionLost(Throwable cause); - - /** - * This method is called when a message arrives from the server. - * - * <p> - * This method is invoked synchronously by the MQTT client. An - * acknowledgment is not sent back to the server until this - * method returns cleanly.</p> - * <p> - * If an implementation of this method throws an <code>Exception</code>, then the - * client will be shut down. When the client is next re-connected, any QoS - * 1 or 2 messages will be redelivered by the server.</p> - * <p> - * Any additional messages which arrive while an - * implementation of this method is running, will build up in memory, and - * will then back up on the network.</p> - * <p> - * If an application needs to persist data, then it - * should ensure the data is persisted prior to returning from this method, as - * after returning from this method, the message is considered to have been - * delivered, and will not be reproducible.</p> - * <p> - * It is possible to send a new message within an implementation of this callback - * (for example, a response to this message), but the implementation must not - * disconnect the client, as it will be impossible to send an acknowledgment for - * the message being processed, and a deadlock will occur.</p> - * - * @param topic name of the topic on the message was published to - * @param message the actual message. - * @throws Exception if a terminal error has occurred, and the client should be - * shut down. - */ - public void messageArrived(String topic, MqttMessage message) throws Exception; - - /** - * Called when delivery for a message has been completed, and all - * acknowledgments have been received. For QoS 0 messages it is - * called once the message has been handed to the network for - * delivery. For QoS 1 it is called when PUBACK is received and - * for QoS 2 when PUBCOMP is received. The token will be the same - * token as that returned when the message was published. - * - * @param token the delivery token associated with the message. - */ - public void deliveryComplete(IMqttDeliveryToken token); - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallbackExtended.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallbackExtended.java deleted file mode 100644 index 7c7adf2..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttCallbackExtended.java +++ /dev/null @@ -1,34 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Initial Contribution for Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3; - -/** - * Extension of {@link MqttCallback} to allow new callbacks - * without breaking the API for existing applications. - * Classes implementing this interface can be registered on - * both types of client: {@link IMqttClient#setCallback(MqttCallback)} - * and {@link IMqttAsyncClient#setCallback(MqttCallback)} - */ -public interface MqttCallbackExtended extends MqttCallback { - - /** - * Called when the connection to the server is completed successfully. - * @param reconnect If true, the connection was the result of automatic reconnect. - * @param serverURI The server URI that the connection was made to. - */ - public void connectComplete(boolean reconnect, String serverURI); - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClient.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClient.java deleted file mode 100644 index c878441..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClient.java +++ /dev/null @@ -1,735 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2015 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - */ -package org.eclipse.paho.client.mqttv3; - -import java.util.Properties; -import java.util.concurrent.ScheduledExecutorService; - -import javax.net.SocketFactory; - -import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; -import org.eclipse.paho.client.mqttv3.util.Debug; - -/** - * Lightweight client for talking to an MQTT server using methods that block - * until an operation completes. - * - * <p>This class implements the blocking {@link IMqttClient} client interface where all - * actions block until they have completed (or timed out). - * This implementation is compatible with all Java SE runtimes from 1.7 and up. - * </p> - * <p>An application can connect to an MQTT server using:</p> - * <ul> - * <li>A plain TCP socket - * <li>An secure SSL/TLS socket - * </ul> - * - * <p>To enable messages to be delivered even across network and client restarts - * messages need to be safely stored until the message has been delivered at the requested - * quality of service. A pluggable persistence mechanism is provided to store the messages. - * </p> - * <p>By default {@link MqttDefaultFilePersistence} is used to store messages to a file. - * If persistence is set to null then messages are stored in memory and hence can be lost - * if the client, Java runtime or device shuts down. - * </p> - * <p>If connecting with {@link MqttConnectOptions#setCleanSession(boolean)} set to true it - * is safe to use memory persistence as all state it cleared when a client disconnects. If - * connecting with cleanSession set to false, to provide reliable message delivery - * then a persistent message store should be used such as the default one. </p> - * <p>The message store interface is pluggable. Different stores can be used by implementing - * the {@link MqttClientPersistence} interface and passing it to the clients constructor. - * </p> - * - * @see IMqttClient - */ -public class MqttClient implements IMqttClient { //), DestinationProvider { - //private static final String CLASS_NAME = MqttClient.class.getName(); - //private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - protected MqttAsyncClient aClient = null; // Delegate implementation to MqttAsyncClient - protected long timeToWait = -1; // How long each method should wait for action to complete - - /** - * Create an MqttClient that can be used to communicate with an MQTT server. - * <p> - * The address of a server can be specified on the constructor. Alternatively - * a list containing one or more servers can be specified using the - * {@link MqttConnectOptions#setServerURIs(String[]) setServerURIs} method - * on MqttConnectOptions. - * - * <p>The <code>serverURI</code> parameter is typically used with the - * the <code>clientId</code> parameter to form a key. The key - * is used to store and reference messages while they are being delivered. - * Hence the serverURI specified on the constructor must still be specified even if a list - * of servers is specified on an MqttConnectOptions object. - * The serverURI on the constructor must remain the same across - * restarts of the client for delivery of messages to be maintained from a given - * client to a given server or set of servers. - * - * <p>The address of the server to connect to is specified as a URI. Two types of - * connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. - * For example:</p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p> - * If the port is not specified, it will - * default to 1883 for <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less that 65535 characters. - * It must be unique across all clients connecting to the same - * server. The clientId is used by the server to store data related to the client, - * hence it is important that the clientId remain the same when connecting to a server - * if durable subscriptions or reliable messaging are required. - * <p>A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client identifier - * is used by the server to identify a client when it reconnects, the client must use the - * same identifier between connections if durable subscriptions or reliable - * delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust stores.</li> - * </ul> - * - * <p>In Java ME, the platform settings are used for SSL connections.</p> - * - * <p>An instance of the default persistence mechanism {@link MqttDefaultFilePersistence} - * is used by the client. To specify a different persistence mechanism or to turn - * off persistence, use the {@link #MqttClient(String, String, MqttClientPersistence)} - * constructor. - * - * @param serverURI the address of the server to connect to, specified as a URI. Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId a client identifier that is unique on the server being connected to - * @throws IllegalArgumentException if the URI does not start with - * "tcp://", "ssl://" or "local://". - * @throws IllegalArgumentException if the clientId is null or is greater than 65535 characters in length - * @throws MqttException if any other problem was encountered - */ - public MqttClient(String serverURI, String clientId) throws MqttException { - this(serverURI,clientId, new MqttDefaultFilePersistence()); - } - - /** - * Create an MqttClient that can be used to communicate with an MQTT server. - * <p> - * The address of a server can be specified on the constructor. Alternatively - * a list containing one or more servers can be specified using the - * {@link MqttConnectOptions#setServerURIs(String[]) setServerURIs} method - * on MqttConnectOptions. - * - * <p>The <code>serverURI</code> parameter is typically used with the - * the <code>clientId</code> parameter to form a key. The key - * is used to store and reference messages while they are being delivered. - * Hence the serverURI specified on the constructor must still be specified even if a list - * of servers is specified on an MqttConnectOptions object. - * The serverURI on the constructor must remain the same across - * restarts of the client for delivery of messages to be maintained from a given - * client to a given server or set of servers. - * - * <p>The address of the server to connect to is specified as a URI. Two types of - * connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. - * For example:</p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p> - * If the port is not specified, it will - * default to 1883 for <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less that 65535 characters. - * It must be unique across all clients connecting to the same - * server. The clientId is used by the server to store data related to the client, - * hence it is important that the clientId remain the same when connecting to a server - * if durable subscriptions or reliable messaging are required. - * <p>A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client identifier - * is used by the server to identify a client when it reconnects, the client must use the - * same identifier between connections if durable subscriptions or reliable - * delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust stores.</li> - * </ul> - * - * <p>In Java ME, the platform settings are used for SSL connections.</p> - * <p> - * A persistence mechanism is used to enable reliable messaging. - * For messages sent at qualities of service (QoS) 1 or 2 to be reliably delivered, - * messages must be stored (on both the client and server) until the delivery of the message - * is complete. If messages are not safely stored when being delivered then - * a failure in the client or server can result in lost messages. A pluggable - * persistence mechanism is supported via the {@link MqttClientPersistence} - * interface. An implementer of this interface that safely stores messages - * must be specified in order for delivery of messages to be reliable. In - * addition {@link MqttConnectOptions#setCleanSession(boolean)} must be set - * to false. In the event that only QoS 0 messages are sent or received or - * cleanSession is set to true then a safe store is not needed. - * </p> - * <p>An implementation of file-based persistence is provided in - * class {@link MqttDefaultFilePersistence} which will work in all Java SE based - * systems. If no persistence is needed, the persistence parameter - * can be explicitly set to <code>null</code>.</p> - * - * @param serverURI the address of the server to connect to, specified as a URI. Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId a client identifier that is unique on the server being connected to - * @param persistence the persistence class to use to store in-flight message. If null then the - * default persistence mechanism is used - * @throws IllegalArgumentException if the URI does not start with - * "tcp://", "ssl://" or "local://" - * @throws IllegalArgumentException if the clientId is null or is greater than 65535 characters in length - * @throws MqttException if any other problem was encountered - */ - public MqttClient(String serverURI, String clientId, MqttClientPersistence persistence) throws MqttException { - aClient = new MqttAsyncClient(serverURI, clientId, persistence); - } - - /** - * Create an MqttClient that can be used to communicate with an MQTT server. - * <p> - * The address of a server can be specified on the constructor. Alternatively - * a list containing one or more servers can be specified using the - * {@link MqttConnectOptions#setServerURIs(String[]) setServerURIs} method - * on MqttConnectOptions. - * - * <p>The <code>serverURI</code> parameter is typically used with the - * the <code>clientId</code> parameter to form a key. The key - * is used to store and reference messages while they are being delivered. - * Hence the serverURI specified on the constructor must still be specified even if a list - * of servers is specified on an MqttConnectOptions object. - * The serverURI on the constructor must remain the same across - * restarts of the client for delivery of messages to be maintained from a given - * client to a given server or set of servers. - * - * <p>The address of the server to connect to is specified as a URI. Two types of - * connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. - * For example: - * </p> - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * <p>If the port is not specified, it will - * default to 1883 for <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * </p> - * - * <p> - * A client identifier <code>clientId</code> must be specified and be less that 65535 characters. - * It must be unique across all clients connecting to the same - * server. The clientId is used by the server to store data related to the client, - * hence it is important that the clientId remain the same when connecting to a server - * if durable subscriptions or reliable messaging are required. - * <p>A convenience method is provided to generate a random client id that - * should satisfy this criteria - {@link #generateClientId()}. As the client identifier - * is used by the server to identify a client when it reconnects, the client must use the - * same identifier between connections if durable subscriptions or reliable - * delivery of messages is required. - * </p> - * <p> - * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - * </p> - * <ul> - * <li><strong>Supplying an <code>SSLSocketFactory</code></strong> - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.</li> - * <li><strong>SSL Properties</strong> - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.</li> - * <li><strong>Use JVM settings</strong> - There are a number of standard - * Java system properties that can be used to configure key and trust stores.</li> - * </ul> - * - * <p>In Java ME, the platform settings are used for SSL connections.</p> - * <p> - * A persistence mechanism is used to enable reliable messaging. - * For messages sent at qualities of service (QoS) 1 or 2 to be reliably delivered, - * messages must be stored (on both the client and server) until the delivery of the message - * is complete. If messages are not safely stored when being delivered then - * a failure in the client or server can result in lost messages. A pluggable - * persistence mechanism is supported via the {@link MqttClientPersistence} - * interface. An implementer of this interface that safely stores messages - * must be specified in order for delivery of messages to be reliable. In - * addition {@link MqttConnectOptions#setCleanSession(boolean)} must be set - * to false. In the event that only QoS 0 messages are sent or received or - * cleanSession is set to true then a safe store is not needed. - * </p> - * <p>An implementation of file-based persistence is provided in - * class {@link MqttDefaultFilePersistence} which will work in all Java SE based - * systems. If no persistence is needed, the persistence parameter - * can be explicitly set to <code>null</code>.</p> - * - * @param serverURI the address of the server to connect to, specified as a URI. Can be overridden using - * {@link MqttConnectOptions#setServerURIs(String[])} - * @param clientId a client identifier that is unique on the server being connected to - * @param persistence the persistence class to use to store in-flight message. If null then the - * default persistence mechanism is used - * @param executorService used for managing threads. If null then a newFixedThreadPool is used. - * @throws IllegalArgumentException if the URI does not start with - * "tcp://", "ssl://" or "local://" - * @throws IllegalArgumentException if the clientId is null or is greater than 65535 characters in length - * @throws MqttException if any other problem was encountered - */ - public MqttClient(String serverURI, String clientId, MqttClientPersistence persistence, ScheduledExecutorService executorService) throws MqttException { - aClient = new MqttAsyncClient(serverURI, clientId, persistence, new ScheduledExecutorPingSender(executorService), executorService); - } - - /* - * @see IMqttClient#connect() - */ - public void connect() throws MqttSecurityException, MqttException { - this.connect(new MqttConnectOptions()); - } - - /* - * @see IMqttClient#connect(MqttConnectOptions) - */ - public void connect(MqttConnectOptions options) throws MqttSecurityException, MqttException { - aClient.connect(options, null, null).waitForCompletion(getTimeToWait()); - } - - /* - * @see IMqttClient#connect(MqttConnectOptions) - */ - public IMqttToken connectWithResult(MqttConnectOptions options) throws MqttSecurityException, MqttException { - IMqttToken tok = aClient.connect(options, null, null); - tok.waitForCompletion(getTimeToWait()); - return tok; - } - - /* - * @see IMqttClient#disconnect() - */ - public void disconnect() throws MqttException { - aClient.disconnect().waitForCompletion(); - } - - /* - * @see IMqttClient#disconnect(long) - */ - public void disconnect(long quiesceTimeout) throws MqttException { - aClient.disconnect(quiesceTimeout, null, null).waitForCompletion(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly() - */ - public void disconnectForcibly() throws MqttException { - aClient.disconnectForcibly(); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly(long) - */ - public void disconnectForcibly(long disconnectTimeout) throws MqttException { - aClient.disconnectForcibly(disconnectTimeout); - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.paho.client.mqttv3.IMqttAsyncClient#disconnectForcibly(long, long) - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout) throws MqttException { - aClient.disconnectForcibly(quiesceTimeout, disconnectTimeout); - } - - /** - * Disconnects from the server forcibly to reset all the states. Could be useful when disconnect attempt failed. - * <p> - * Because the client is able to establish the TCP/IP connection to a none MQTT server and it will certainly fail to - * send the disconnect packet. - * - * @param quiesceTimeout the amount of time in milliseconds to allow for existing work to finish before - * disconnecting. A value of zero or less means the client will not quiesce. - * @param disconnectTimeout the amount of time in milliseconds to allow send disconnect packet to server. - * @param sendDisconnectPacket if true, will send the disconnect packet to the server - * @throws MqttException if any unexpected error - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout, boolean sendDisconnectPacket) throws MqttException { - aClient.disconnectForcibly(quiesceTimeout, disconnectTimeout, sendDisconnectPacket); - } - - /* - * @see IMqttClient#subscribe(String) - */ - public void subscribe(String topicFilter) throws MqttException { - this.subscribe(new String[] {topicFilter}, new int[] {1}); - } - - /* - * @see IMqttClient#subscribe(String[]) - */ - public void subscribe(String[] topicFilters) throws MqttException { - int[] qos = new int[topicFilters.length]; - for (int i=0; i<qos.length; i++) { - qos[i] = 1; - } - this.subscribe(topicFilters, qos); - } - - /* - * @see IMqttClient#subscribe(String, int) - */ - public void subscribe(String topicFilter, int qos) throws MqttException { - this.subscribe(new String[] {topicFilter}, new int[] {qos}); - } - - /* - * @see IMqttClient#subscribe(String[], int[]) - */ - public void subscribe(String[] topicFilters, int[] qos) throws MqttException { - IMqttToken tok = aClient.subscribe(topicFilters, qos, null, null); - tok.waitForCompletion(getTimeToWait()); - int[] grantedQos = tok.getGrantedQos(); - for (int i = 0; i < grantedQos.length; ++i) { - qos[i] = grantedQos[i]; - } - if (grantedQos.length == 1 && qos[0] == 0x80) { - throw new MqttException(MqttException.REASON_CODE_SUBSCRIBE_FAILED); - } - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#subscribe(java.lang.String, int, java.lang.Object, org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public void subscribe(String topicFilter, IMqttMessageListener messageListener) throws MqttException { - this.subscribe(new String[] {topicFilter}, new int[] {1}, new IMqttMessageListener[] {messageListener}); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#subscribe(java.lang.String, int, java.lang.Object, org.eclipse.paho.client.mqttv3.IMqttActionListener) - */ - public void subscribe(String[] topicFilters, IMqttMessageListener[] messageListeners) throws MqttException { - int[] qos = new int[topicFilters.length]; - for (int i=0; i<qos.length; i++) { - qos[i] = 1; - } - this.subscribe(topicFilters, qos, messageListeners); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#subscribe(java.lang.String, int) - */ - public void subscribe(String topicFilter, int qos, IMqttMessageListener messageListener) throws MqttException { - this.subscribe(new String[] {topicFilter}, new int[] {qos}, new IMqttMessageListener[] {messageListener}); - } - - - public void subscribe(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) throws MqttException { - this.subscribe(topicFilters, qos); - - // add message handlers to the list for this client - for (int i = 0; i < topicFilters.length; ++i) { - aClient.comms.setMessageListener(topicFilters[i], messageListeners[i]); - } - } - - /* - * @see IMqttClient#subscribeWithResponse(String) - */ - public IMqttToken subscribeWithResponse(String topicFilter) throws MqttException { - return this.subscribeWithResponse(new String[] {topicFilter}, new int[] {1}); - } - - /* - * @see IMqttClient#subscribeWithResponse(String, IMqttMessageListener) - */ - public IMqttToken subscribeWithResponse(String topicFilter, IMqttMessageListener messageListener) throws MqttException { - return this.subscribeWithResponse(new String[] {topicFilter}, new int[] {1}, new IMqttMessageListener[] {messageListener}); - } - - /* - * @see IMqttClient#subscribeWithResponse(String, int) - */ - public IMqttToken subscribeWithResponse(String topicFilter, int qos) throws MqttException { - return this.subscribeWithResponse(new String[] {topicFilter}, new int[] {qos}); - } - - /* - * @see IMqttClient#subscribeWithResponse(String, int, IMqttMessageListener) - */ - public IMqttToken subscribeWithResponse(String topicFilter, int qos, IMqttMessageListener messageListener) - throws MqttException { - return this.subscribeWithResponse(new String[] {topicFilter}, new int[] {qos}, new IMqttMessageListener[] {messageListener}); - } - - /* - * @see IMqttClient#subscribeWithResponse(String[]) - */ - public IMqttToken subscribeWithResponse(String[] topicFilters) throws MqttException { - int[] qos = new int[topicFilters.length]; - for (int i=0; i<qos.length; i++) { - qos[i] = 1; - } - return this.subscribeWithResponse(topicFilters, qos); - } - - /* - * @see IMqttClient#subscribeWithResponse(String[], IMqttMessageListener[]) - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, IMqttMessageListener[] messageListeners) - throws MqttException { - int[] qos = new int[topicFilters.length]; - for (int i=0; i<qos.length; i++) { - qos[i] = 1; - } - return this.subscribeWithResponse(topicFilters, qos, messageListeners); - } - - /* - * @see IMqttClient#subscribeWithResponse(String[], int[]) - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, int[] qos) throws MqttException { - IMqttToken tok = aClient.subscribe(topicFilters, qos, null, null); - tok.waitForCompletion(getTimeToWait()); - return tok; - } - - /* - * @see IMqttClient#subscribeWithResponse(String[], int[], IMqttMessageListener[]) - */ - public IMqttToken subscribeWithResponse(String[] topicFilters, int[] qos, IMqttMessageListener[] messageListeners) - throws MqttException { - IMqttToken tok = this.subscribeWithResponse(topicFilters, qos); - - // add message handlers to the list for this client - for (int i = 0; i < topicFilters.length; ++i) { - aClient.comms.setMessageListener(topicFilters[i], messageListeners[i]); - } - return tok; - } - - /* - * @see IMqttClient#unsubscribe(String) - */ - public void unsubscribe(String topicFilter) throws MqttException { - unsubscribe(new String[] {topicFilter}); - } - - /* - * @see IMqttClient#unsubscribe(String[]) - */ - public void unsubscribe(String[] topicFilters) throws MqttException { - // message handlers removed in the async client unsubscribe below - aClient.unsubscribe(topicFilters, null,null).waitForCompletion(getTimeToWait()); - } - - /* - * @see IMqttClient#publishBlock(String, byte[], int, boolean) - */ - public void publish(String topic, byte[] payload,int qos, boolean retained) throws MqttException, - MqttPersistenceException { - MqttMessage message = new MqttMessage(payload); - message.setQos(qos); - message.setRetained(retained); - this.publish(topic, message); - } - - /* - * @see IMqttClient#publishBlock(String, MqttMessage) - */ - public void publish(String topic, MqttMessage message) throws MqttException, - MqttPersistenceException { - aClient.publish(topic, message, null, null).waitForCompletion(getTimeToWait()); - } - - /** - * Set the maximum time to wait for an action to complete. - * <p>Set the maximum time to wait for an action to complete before - * returning control to the invoking application. Control is returned - * when:</p> - * <ul> - * <li>the action completes</li> - * <li>or when the timeout if exceeded</li> - * <li>or when the client is disconnect/shutdown</li> - * </ul> - * <p> - * The default value is -1 which means the action will not timeout. - * In the event of a timeout the action carries on running in the - * background until it completes. The timeout is used on methods that - * block while the action is in progress. - * </p> - * @param timeToWaitInMillis before the action times out. A value or 0 or -1 will wait until - * the action finishes and not timeout. - * @throws IllegalArgumentException if timeToWaitInMillis is invalid - */ - public void setTimeToWait(long timeToWaitInMillis) throws IllegalArgumentException{ - if (timeToWaitInMillis < -1) { - throw new IllegalArgumentException(); - } - this.timeToWait = timeToWaitInMillis; - } - - /** - * Return the maximum time to wait for an action to complete. - * @return the time to wait - * @see MqttClient#setTimeToWait(long) - */ - public long getTimeToWait() { - return this.timeToWait; - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#close() - */ - public void close() throws MqttException { - aClient.close(false); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#close() - */ - public void close(boolean force) throws MqttException { - aClient.close(force); - } - - - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#getClientId() - */ - public String getClientId() { - return aClient.getClientId(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#getPendingDeliveryTokens() - */ - public IMqttDeliveryToken[] getPendingDeliveryTokens() { - return aClient.getPendingDeliveryTokens(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#getServerURI() - */ - public String getServerURI() { - return aClient.getServerURI(); - } - - /** - * Returns the currently connected Server URI - * Implemented due to: https://bugs.eclipse.org/bugs/show_bug.cgi?id=481097 - * - * Where getServerURI only returns the URI that was provided in - * MqttAsyncClient's constructor, getCurrentServerURI returns the URI of the - * Server that the client is currently connected to. This would be different in scenarios - * where multiple server URIs have been provided to the MqttConnectOptions. - * - * @return the currently connected server URI - */ - public String getCurrentServerURI(){ - return aClient.getCurrentServerURI(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#getTopic(java.lang.String) - */ - public MqttTopic getTopic(String topic) { - return aClient.getTopic(topic); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#isConnected() - */ - public boolean isConnected() { - return aClient.isConnected(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#setCallback(org.eclipse.paho.client.mqttv3.MqttCallback) - */ - public void setCallback(MqttCallback callback) { - aClient.setCallback(callback); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.IMqttClient#setCallback(org.eclipse.paho.client.mqttv3.MqttCallback) - */ - public void setManualAcks(boolean manualAcks) { - aClient.setManualAcks(manualAcks); - } - - public void messageArrivedComplete(int messageId, int qos) throws MqttException { - aClient.messageArrivedComplete(messageId, qos); - } - - /** - * Returns a randomly generated client identifier based on the current user's login - * name and the system time. - * <p>When cleanSession is set to false, an application must ensure it uses the - * same client identifier when it reconnects to the server to resume state and maintain - * assured message delivery.</p> - * @return a generated client identifier - * @see MqttConnectOptions#setCleanSession(boolean) - */ - public static String generateClientId() { - return MqttAsyncClient.generateClientId(); - } - - /** - * Will attempt to reconnect to the server after the client has lost connection. - * @throws MqttException if an error occurs attempting to reconnect - */ - public void reconnect() throws MqttException { - aClient.reconnect(); - } - - /** - * Return a debug object that can be used to help solve problems. - * @return the {@link Debug} Object. - */ - public Debug getDebug() { - return (aClient.getDebug()); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClientPersistence.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClientPersistence.java deleted file mode 100644 index 071846c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttClientPersistence.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -import java.util.Enumeration; - -/** - * Represents a persistent data store, used to store outbound and inbound messages while they - * are in flight, enabling delivery to the QoS specified. You can specify an implementation - * of this interface using {@link MqttClient#MqttClient(String, String, MqttClientPersistence)}, - * which the {@link MqttClient} will use to persist QoS 1 and 2 messages. - * <p> - * If the methods defined throw the MqttPersistenceException then the state of the data persisted - * should remain as prior to the method being called. For example, if {@link #put(String, MqttPersistable)} - * throws an exception at any point then the data will be assumed to not be in the persistent store. - * Similarly if {@link #remove(String)} throws an exception then the data will be - * assumed to still be held in the persistent store.</p> - * <p> - * It is up to the persistence interface to log any exceptions or error information - * which may be required when diagnosing a persistence failure.</p> - */ -public interface MqttClientPersistence { - /** - * Initialise the persistent store. - * If a persistent store exists for this client ID then open it, otherwise - * create a new one. If the persistent store is already open then just return. - * An application may use the same client ID to connect to many different - * servers, so the client ID in conjunction with the - * connection will uniquely identify the persistence store required. - * - * @param clientId The client for which the persistent store should be opened. - * @param serverURI The connection string as specified when the MQTT client instance was created. - * @throws MqttPersistenceException if there was a problem opening the persistent store. - */ - public void open(String clientId, String serverURI) throws MqttPersistenceException; - - /** - * Close the persistent store that was previously opened. - * This will be called when a client application disconnects from the broker. - * @throws MqttPersistenceException if an error occurs closing the persistence store. - */ - public void close() throws MqttPersistenceException; - - /** - * Puts the specified data into the persistent store. - * @param key the key for the data, which will be used later to retrieve it. - * @param persistable the data to persist - * @throws MqttPersistenceException if there was a problem putting the data - * into the persistent store. - */ - public void put(String key, MqttPersistable persistable) throws MqttPersistenceException; - - /** - * Gets the specified data out of the persistent store. - * @param key the key for the data, which was used when originally saving it. - * @return the un-persisted data - * @throws MqttPersistenceException if there was a problem getting the data - * from the persistent store. - */ - public MqttPersistable get(String key) throws MqttPersistenceException; - - /** - * Remove the data for the specified key. - * @param key The key for the data to remove - * @throws MqttPersistenceException if there was a problem removing the data. - */ - public void remove(String key) throws MqttPersistenceException; - - /** - * Returns an Enumeration over the keys in this persistent data store. - * @return an enumeration of {@link String} objects. - * @throws MqttPersistenceException if there was a problem getting they keys - */ - public Enumeration keys() throws MqttPersistenceException; - - /** - * Clears persistence, so that it no longer contains any persisted data. - * @throws MqttPersistenceException if there was a problem clearing all data from the persistence store - */ - public void clear() throws MqttPersistenceException; - - /** - * Returns whether or not data is persisted using the specified key. - * @param key the key for data, which was used when originally saving it. - * @return True if the persistence store contains the key - * @throws MqttPersistenceException if there was a problem checking whether they key existed. - */ - public boolean containsKey(String key) throws MqttPersistenceException; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttConnectOptions.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttConnectOptions.java deleted file mode 100644 index 2e16b7a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttConnectOptions.java +++ /dev/null @@ -1,633 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * James Sutton - Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3; - -import java.util.Properties; - -import javax.net.SocketFactory; -import javax.net.ssl.HostnameVerifier; - -import org.eclipse.paho.client.mqttv3.util.Debug; - -import java.net.URI; -import java.net.URISyntaxException; - -/** - * Holds the set of options that control how the client connects to a server. - */ -public class MqttConnectOptions { - /** - * The default keep alive interval in seconds if one is not specified - */ - public static final int KEEP_ALIVE_INTERVAL_DEFAULT = 60; - /** - * The default connection timeout in seconds if one is not specified - */ - public static final int CONNECTION_TIMEOUT_DEFAULT = 30; - /** - * The default max inflight if one is not specified - */ - public static final int MAX_INFLIGHT_DEFAULT = 10; - /** - * The default clean session setting if one is not specified - */ - public static final boolean CLEAN_SESSION_DEFAULT = true; - /** - * The default MqttVersion is 3.1.1 first, dropping back to 3.1 if that fails - */ - public static final int MQTT_VERSION_DEFAULT = 0; - /** - * Mqtt Version 3.1 - */ - public static final int MQTT_VERSION_3_1 = 3; - /** - * Mqtt Version 3.1.1 - */ - public static final int MQTT_VERSION_3_1_1 = 4; - - protected static final int URI_TYPE_TCP = 0; - protected static final int URI_TYPE_SSL = 1; - protected static final int URI_TYPE_LOCAL = 2; - protected static final int URI_TYPE_WS = 3; - protected static final int URI_TYPE_WSS = 4; - - private int keepAliveInterval = KEEP_ALIVE_INTERVAL_DEFAULT; - private int maxInflight = MAX_INFLIGHT_DEFAULT; - private String willDestination = null; - private MqttMessage willMessage = null; - private String userName; - private char[] password; - private SocketFactory socketFactory; - private Properties sslClientProps = null; - private HostnameVerifier sslHostnameVerifier = null; - private boolean cleanSession = CLEAN_SESSION_DEFAULT; - private int connectionTimeout = CONNECTION_TIMEOUT_DEFAULT; - private String[] serverURIs = null; - private int MqttVersion = MQTT_VERSION_DEFAULT; - private boolean automaticReconnect = false; - - /** - * Constructs a new <code>MqttConnectOptions</code> object using the - * default values. - * - * The defaults are: - * <ul> - * <li>The keepalive interval is 60 seconds</li> - * <li>Clean Session is true</li> - * <li>The message delivery retry interval is 15 seconds</li> - * <li>The connection timeout period is 30 seconds</li> - * <li>No Will message is set</li> - * <li>A standard SocketFactory is used</li> - * </ul> - * More information about these values can be found in the setter methods. - */ - public MqttConnectOptions() { - } - - /** - * Returns the password to use for the connection. - * @return the password to use for the connection. - */ - public char[] getPassword() { - return password; - } - - /** - * Sets the password to use for the connection. - * @param password A Char Array of the password - */ - public void setPassword(char[] password) { - this.password = password; - } - - /** - * Returns the user name to use for the connection. - * @return the user name to use for the connection. - */ - public String getUserName() { - return userName; - } - - /** - * Sets the user name to use for the connection. - * @param userName The Username as a String - * @throws IllegalArgumentException if the user name is blank or only - * contains whitespace characters. - */ - public void setUserName(String userName) { - if ((userName != null) && (userName.trim().equals(""))) { - throw new IllegalArgumentException(); - } - this.userName = userName; - } - - /** - * Sets the "Last Will and Testament" (LWT) for the connection. - * In the event that this client unexpectedly loses its connection to the - * server, the server will publish a message to itself using the supplied - * details. - * - * @param topic the topic to publish to. - * @param payload the byte payload for the message. - * @param qos the quality of service to publish the message at (0, 1 or 2). - * @param retained whether or not the message should be retained. - */ - public void setWill(MqttTopic topic, byte[] payload, int qos, boolean retained) { - String topicS = topic.getName(); - validateWill(topicS, payload); - this.setWill(topicS, new MqttMessage(payload), qos, retained); - } - - /** - * Sets the "Last Will and Testament" (LWT) for the connection. - * In the event that this client unexpectedly loses its connection to the - * server, the server will publish a message to itself using the supplied - * details. - * - * @param topic the topic to publish to. - * @param payload the byte payload for the message. - * @param qos the quality of service to publish the message at (0, 1 or 2). - * @param retained whether or not the message should be retained. - */ - public void setWill(String topic, byte[] payload, int qos, boolean retained) { - validateWill(topic, payload); - this.setWill(topic, new MqttMessage(payload), qos, retained); - } - - - /** - * Validates the will fields. - */ - private void validateWill(String dest, Object payload) { - if ((dest == null) || (payload == null)) { - throw new IllegalArgumentException(); - } - - MqttTopic.validate(dest, false/*wildcards NOT allowed*/); - } - - /** - * Sets up the will information, based on the supplied parameters. - * - * @param topic the topic to send the LWT message to - * @param msg the {@link MqttMessage} to send - * @param qos the QoS Level to send the message at - * @param retained whether the message should be retained or not - */ - protected void setWill(String topic, MqttMessage msg, int qos, boolean retained) { - willDestination = topic; - willMessage = msg; - willMessage.setQos(qos); - willMessage.setRetained(retained); - // Prevent any more changes to the will message - willMessage.setMutable(false); - } - - /** - * Returns the "keep alive" interval. - * @see #setKeepAliveInterval(int) - * @return the keep alive interval. - */ - public int getKeepAliveInterval() { - return keepAliveInterval; - } - - /** - * Returns the MQTT version. - * @see #setMqttVersion(int) - * @return the MQTT version. - */ - public int getMqttVersion() { - return MqttVersion; - } - - /** - * Sets the "keep alive" interval. - * This value, measured in seconds, defines the maximum time interval - * between messages sent or received. It enables the client to - * detect if the server is no longer available, without - * having to wait for the TCP/IP timeout. The client will ensure - * that at least one message travels across the network within each - * keep alive period. In the absence of a data-related message during - * the time period, the client sends a very small "ping" message, which - * the server will acknowledge. - * A value of 0 disables keepalive processing in the client. - * <p>The default value is 60 seconds</p> - * - * @param keepAliveInterval the interval, measured in seconds, must be >= 0. - * @throws IllegalArgumentException if the keepAliveInterval was invalid - */ - public void setKeepAliveInterval(int keepAliveInterval)throws IllegalArgumentException { - if (keepAliveInterval <0 ) { - throw new IllegalArgumentException(); - } - this.keepAliveInterval = keepAliveInterval; - } - - /** - * Returns the "max inflight". - * The max inflight limits to how many messages we can send without receiving acknowledgments. - * @see #setMaxInflight(int) - * @return the max inflight - */ - public int getMaxInflight() { - return maxInflight; - } - - /** - * Sets the "max inflight". - * please increase this value in a high traffic environment. - * <p>The default value is 10</p> - * @param maxInflight the number of maxInfligt messages - */ - public void setMaxInflight(int maxInflight) { - if (maxInflight < 0) { - throw new IllegalArgumentException(); - } - this.maxInflight = maxInflight; - } - - /** - * Returns the connection timeout value. - * @see #setConnectionTimeout(int) - * @return the connection timeout value. - */ - public int getConnectionTimeout() { - return connectionTimeout; - } - - /** - * Sets the connection timeout value. - * This value, measured in seconds, defines the maximum time interval - * the client will wait for the network connection to the MQTT server to be established. - * The default timeout is 30 seconds. - * A value of 0 disables timeout processing meaning the client will wait until the - * network connection is made successfully or fails. - * @param connectionTimeout the timeout value, measured in seconds. It must be >0; - */ - public void setConnectionTimeout(int connectionTimeout) { - if (connectionTimeout <0 ) { - throw new IllegalArgumentException(); - } - this.connectionTimeout = connectionTimeout; - } - - /** - * Returns the socket factory that will be used when connecting, or - * <code>null</code> if one has not been set. - * @return The Socket Factory - */ - public SocketFactory getSocketFactory() { - return socketFactory; - } - - /** - * Sets the <code>SocketFactory</code> to use. This allows an application - * to apply its own policies around the creation of network sockets. If - * using an SSL connection, an <code>SSLSocketFactory</code> can be used - * to supply application-specific security settings. - * @param socketFactory the factory to use. - */ - public void setSocketFactory(SocketFactory socketFactory) { - this.socketFactory = socketFactory; - } - - /** - * Returns the topic to be used for last will and testament (LWT). - * @return the MqttTopic to use, or <code>null</code> if LWT is not set. - * @see #setWill(MqttTopic, byte[], int, boolean) - */ - public String getWillDestination() { - return willDestination; - } - - /** - * Returns the message to be sent as last will and testament (LWT). - * The returned object is "read only". Calling any "setter" methods on - * the returned object will result in an - * <code>IllegalStateException</code> being thrown. - * @return the message to use, or <code>null</code> if LWT is not set. - */ - public MqttMessage getWillMessage() { - return willMessage; - } - - /** - * Returns the SSL properties for the connection. - * @return the properties for the SSL connection - */ - public Properties getSSLProperties() { - return sslClientProps; - } - - /** - * Sets the SSL properties for the connection. - * <p>Note that these - * properties are only valid if an implementation of the Java - * Secure Socket Extensions (JSSE) is available. These properties are - * <em>not</em> used if a SocketFactory has been set using - * {@link #setSocketFactory(SocketFactory)}. - * The following properties can be used:</p> - * <dl> - * <dt>com.ibm.ssl.protocol</dt> - * <dd>One of: SSL, SSLv3, TLS, TLSv1, SSL_TLS.</dd> - * <dt>com.ibm.ssl.contextProvider - * <dd>Underlying JSSE provider. For example "IBMJSSE2" or "SunJSSE"</dd> - * - * <dt>com.ibm.ssl.keyStore</dt> - * <dd>The name of the file that contains the KeyStore object that you - * want the KeyManager to use. For example /mydir/etc/key.p12</dd> - * - * <dt>com.ibm.ssl.keyStorePassword</dt> - * <dd>The password for the KeyStore object that you want the KeyManager to use. - * The password can either be in plain-text, - * or may be obfuscated using the static method: - * <code>com.ibm.micro.security.Password.obfuscate(char[] password)</code>. - * This obfuscates the password using a simple and insecure XOR and Base64 - * encoding mechanism. Note that this is only a simple scrambler to - * obfuscate clear-text passwords.</dd> - * - * <dt>com.ibm.ssl.keyStoreType</dt> - * <dd>Type of key store, for example "PKCS12", "JKS", or "JCEKS".</dd> - * - * <dt>com.ibm.ssl.keyStoreProvider</dt> - * <dd>Key store provider, for example "IBMJCE" or "IBMJCEFIPS".</dd> - * - * <dt>com.ibm.ssl.trustStore</dt> - * <dd>The name of the file that contains the KeyStore object that you - * want the TrustManager to use.</dd> - * - * <dt>com.ibm.ssl.trustStorePassword</dt> - * <dd>The password for the TrustStore object that you want the - * TrustManager to use. The password can either be in plain-text, - * or may be obfuscated using the static method: - * <code>com.ibm.micro.security.Password.obfuscate(char[] password)</code>. - * This obfuscates the password using a simple and insecure XOR and Base64 - * encoding mechanism. Note that this is only a simple scrambler to - * obfuscate clear-text passwords.</dd> - * - * <dt>com.ibm.ssl.trustStoreType</dt> - * <dd>The type of KeyStore object that you want the default TrustManager to use. - * Same possible values as "keyStoreType".</dd> - * - * <dt>com.ibm.ssl.trustStoreProvider</dt> - * <dd>Trust store provider, for example "IBMJCE" or "IBMJCEFIPS".</dd> - * - * <dt>com.ibm.ssl.enabledCipherSuites</dt> - * <dd>A list of which ciphers are enabled. Values are dependent on the provider, - * for example: SSL_RSA_WITH_AES_128_CBC_SHA;SSL_RSA_WITH_3DES_EDE_CBC_SHA.</dd> - * - * <dt>com.ibm.ssl.keyManager</dt> - * <dd>Sets the algorithm that will be used to instantiate a KeyManagerFactory object - * instead of using the default algorithm available in the platform. Example values: - * "IbmX509" or "IBMJ9X509". - * </dd> - * - * <dt>com.ibm.ssl.trustManager</dt> - * <dd>Sets the algorithm that will be used to instantiate a TrustManagerFactory object - * instead of using the default algorithm available in the platform. Example values: - * "PKIX" or "IBMJ9X509". - * </dd> - * </dl> - * @param props The SSL {@link Properties} - */ - public void setSSLProperties(Properties props) { - this.sslClientProps = props; - } - - /** - * Returns the HostnameVerifier for the SSL connection. - * @return the HostnameVerifier for the SSL connection - */ - public HostnameVerifier getSSLHostnameVerifier() { - return sslHostnameVerifier; - } - - /** - * Sets the HostnameVerifier for the SSL connection. Note that it will be - * used after handshake on a connection and you should do actions by - * yourserlf when hostname is verified error. - * <p> - * There is no default HostnameVerifier - * </p> - * @param hostnameVerifier the {@link HostnameVerifier} - */ - public void setSSLHostnameVerifier(HostnameVerifier hostnameVerifier) { - this.sslHostnameVerifier = hostnameVerifier; - } - - /** - * Returns whether the client and server should remember state for the client across reconnects. - * @return the clean session flag - */ - public boolean isCleanSession() { - return this.cleanSession; - } - - /** - * Sets whether the client and server should remember state across restarts and reconnects. - * <ul> - * <li>If set to false both the client and server will maintain state across - * restarts of the client, the server and the connection. As state is maintained: - * <ul> - * <li>Message delivery will be reliable meeting - * the specified QOS even if the client, server or connection are restarted. - * <li> The server will treat a subscription as durable. - * </ul> - * <li>If set to true the client and server will not maintain state across - * restarts of the client, the server or the connection. This means - * <ul> - * <li>Message delivery to the specified QOS cannot be maintained if the - * client, server or connection are restarted - * <li>The server will treat a subscription as non-durable - * </ul> - * </ul> - * @param cleanSession Set to True to enable cleanSession - */ - public void setCleanSession(boolean cleanSession) { - this.cleanSession = cleanSession; - } - - /** - * Return a list of serverURIs the client may connect to - * @return the serverURIs or null if not set - */ - public String[] getServerURIs() { - return serverURIs; - } - - /** - * Set a list of one or more serverURIs the client may connect to. - * <p> - * Each <code>serverURI</code> specifies the address of a server that the client may - * connect to. Two types of - * connection are supported <code>tcp://</code> for a TCP connection and - * <code>ssl://</code> for a TCP connection secured by SSL/TLS. - * For example: - * <ul> - * <li><code>tcp://localhost:1883</code></li> - * <li><code>ssl://localhost:8883</code></li> - * </ul> - * If the port is not specified, it will - * default to 1883 for <code>tcp://</code>" URIs, and 8883 for <code>ssl://</code> URIs. - * <p> - * If serverURIs is set then it overrides the serverURI parameter passed in on the - * constructor of the MQTT client. - * <p> - * When an attempt to connect is initiated the client will start with the first - * serverURI in the list and work through - * the list until a connection is established with a server. If a connection cannot be made to - * any of the servers then the connect attempt fails. - * <p> - * Specifying a list of servers that a client may connect to has several uses: - * <ol> - * <li>High Availability and reliable message delivery - * <p>Some MQTT servers support a high availability feature where two or more - * "equal" MQTT servers share state. An MQTT client can connect to any of the "equal" - * servers and be assured that messages are reliably delivered and durable subscriptions - * are maintained no matter which server the client connects to.</p> - * <p>The cleansession flag must be set to false if durable subscriptions and/or reliable - * message delivery is required.</p></li> - * <li>Hunt List - * <p>A set of servers may be specified that are not "equal" (as in the high availability - * option). As no state is shared across the servers reliable message delivery and - * durable subscriptions are not valid. The cleansession flag must be set to true if the - * hunt list mode is used</p></li> - * </ol> - * @param array of serverURIs - */ - public void setServerURIs(String[] array) { - for (int i = 0; i < array.length; i++) { - validateURI(array[i]); - } - this.serverURIs = array; - } - - /** - * Validate a URI - * @param srvURI The Server URI - * @return the URI type - */ - public static int validateURI(String srvURI) { - try { - URI vURI = new URI(srvURI); - if ("ws".equals(vURI.getScheme())){ - return URI_TYPE_WS; - } - else if ("wss".equals(vURI.getScheme())) { - return URI_TYPE_WSS; - } - - if ((vURI.getPath() == null) || vURI.getPath().isEmpty()) { - // No op path must be empty - } - else { - throw new IllegalArgumentException(srvURI); - } - if ("tcp".equals(vURI.getScheme())) { - return URI_TYPE_TCP; - } - else if ("ssl".equals(vURI.getScheme())) { - return URI_TYPE_SSL; - } - else if ("local".equals(vURI.getScheme())) { - return URI_TYPE_LOCAL; - } - else { - throw new IllegalArgumentException(srvURI); - } - } catch (URISyntaxException ex) { - throw new IllegalArgumentException(srvURI); - } - } - - /** - * Sets the MQTT version. - * The default action is to connect with version 3.1.1, - * and to fall back to 3.1 if that fails. - * Version 3.1.1 or 3.1 can be selected specifically, with no fall back, - * by using the MQTT_VERSION_3_1_1 or MQTT_VERSION_3_1 options respectively. - * - * @param MqttVersion the version of the MQTT protocol. - * @throws IllegalArgumentException If the MqttVersion supplied is invalid - */ - public void setMqttVersion(int MqttVersion)throws IllegalArgumentException { - if (MqttVersion != MQTT_VERSION_DEFAULT && - MqttVersion != MQTT_VERSION_3_1 && - MqttVersion != MQTT_VERSION_3_1_1) { - throw new IllegalArgumentException(); - } - this.MqttVersion = MqttVersion; - } - - /** - * Returns whether the client will automatically attempt to reconnect to the - * server if the connection is lost - * @return the automatic reconnection flag. - */ - public boolean isAutomaticReconnect() { - return automaticReconnect; - } - - /** - * Sets whether the client will automatically attempt to reconnect to the - * server if the connection is lost. - * <ul> - * <li>If set to false, the client will not attempt to automatically - * reconnect to the server in the event that the connection is lost.</li> - * <li>If set to true, in the event that the connection is lost, the client - * will attempt to reconnect to the server. It will initially wait 1 second before - * it attempts to reconnect, for every failed reconnect attempt, the delay will double - * until it is at 2 minutes at which point the delay will stay at 2 minutes.</li> - * </ul> - * @param automaticReconnect If set to True, Automatic Reconnect will be enabled - */ - public void setAutomaticReconnect(boolean automaticReconnect) { - this.automaticReconnect = automaticReconnect; - } - - - /** - * @return The Debug Properties - */ - public Properties getDebug() { - final String strNull="null"; - Properties p = new Properties(); - p.put("MqttVersion", new Integer(getMqttVersion())); - p.put("CleanSession", Boolean.valueOf(isCleanSession())); - p.put("ConTimeout", new Integer(getConnectionTimeout())); - p.put("KeepAliveInterval", new Integer(getKeepAliveInterval())); - p.put("UserName", (getUserName() == null) ? strNull : getUserName()); - p.put("WillDestination", (getWillDestination() == null) ? strNull : getWillDestination()); - if (getSocketFactory()==null) { - p.put("SocketFactory", strNull); - } else { - p.put("SocketFactory", getSocketFactory()); - } - if (getSSLProperties()==null) { - p.put("SSLProperties", strNull); - } else { - p.put("SSLProperties", getSSLProperties()); - } - return p; - } - - public String toString() { - return Debug.dumpProperties(getDebug(), "Connection options"); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttDeliveryToken.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttDeliveryToken.java deleted file mode 100644 index f2bb574..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttDeliveryToken.java +++ /dev/null @@ -1,53 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -/** - * Provides a mechanism to track the delivery progress of a message. - * - * <p> - * Used to track the the delivery progress of a message when a publish is - * executed in a non-blocking manner (run in the background)</p> - * - * @see MqttToken - */ -public class MqttDeliveryToken extends MqttToken implements IMqttDeliveryToken { - - - public MqttDeliveryToken() { - super(); - } - - public MqttDeliveryToken(String logContext) { - super(logContext); - } - - /** - * Returns the message associated with this token. - * <p>Until the message has been delivered, the message being delivered will - * be returned. Once the message has been delivered <code>null</code> will be - * returned. - * @return the message associated with this token or null if already delivered. - * @throws MqttException if there was a problem completing retrieving the message - */ - public MqttMessage getMessage() throws MqttException { - return internalTok.getMessage(); - } - - protected void setMessage(MqttMessage msg) { - internalTok.setMessage(msg); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttException.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttException.java deleted file mode 100644 index f9f88f4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttException.java +++ /dev/null @@ -1,239 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - * James Sutton - Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3; - -import org.eclipse.paho.client.mqttv3.internal.MessageCatalog; - -/** - * Thrown if an error occurs communicating with the server. - */ -public class MqttException extends Exception { - private static final long serialVersionUID = 300L; - - /** - * Client encountered an exception. Use the {@link #getCause()} - * method to get the underlying reason. - */ - public static final short REASON_CODE_CLIENT_EXCEPTION = 0x00; - - // CONNACK return codes - /** The protocol version requested is not supported by the server. */ - public static final short REASON_CODE_INVALID_PROTOCOL_VERSION = 0x01; - /** The server has rejected the supplied client ID */ - public static final short REASON_CODE_INVALID_CLIENT_ID = 0x02; - /** The broker was not available to handle the request. */ - public static final short REASON_CODE_BROKER_UNAVAILABLE = 0x03; - /** Authentication with the server has failed, due to a bad user name or password. */ - public static final short REASON_CODE_FAILED_AUTHENTICATION = 0x04; - /** Not authorized to perform the requested operation */ - public static final short REASON_CODE_NOT_AUTHORIZED = 0x05; - - /** An unexpected error has occurred. */ - public static final short REASON_CODE_UNEXPECTED_ERROR = 0x06; - - /** Error from subscribe - returned from the server. */ - public static final short REASON_CODE_SUBSCRIBE_FAILED = 0x80; - - /** - * Client timed out while waiting for a response from the server. - * The server is no longer responding to keep-alive messages. - */ - public static final short REASON_CODE_CLIENT_TIMEOUT = 32000; - - /** - * Internal error, caused by no new message IDs being available. - */ - public static final short REASON_CODE_NO_MESSAGE_IDS_AVAILABLE = 32001; - - /** - * Client timed out while waiting to write messages to the server. - */ - public static final short REASON_CODE_WRITE_TIMEOUT = 32002; - - /** - * The client is already connected. - */ - public static final short REASON_CODE_CLIENT_CONNECTED = 32100; - - /** - * The client is already disconnected. - */ - public static final short REASON_CODE_CLIENT_ALREADY_DISCONNECTED = 32101; - /** - * The client is currently disconnecting and cannot accept any new work. - * This can occur when waiting on a token, and then disconnecting the client. - * If the message delivery does not complete within the quiesce timeout - * period, then the waiting token will be notified with an exception. - */ - public static final short REASON_CODE_CLIENT_DISCONNECTING = 32102; - - /** Unable to connect to server */ - public static final short REASON_CODE_SERVER_CONNECT_ERROR = 32103; - - /** - * The client is not connected to the server. The {@link MqttClient#connect()} - * or {@link MqttClient#connect(MqttConnectOptions)} method must be called - * first. It is also possible that the connection was lost - see - * {@link MqttClient#setCallback(MqttCallback)} for a way to track lost - * connections. - */ - public static final short REASON_CODE_CLIENT_NOT_CONNECTED = 32104; - - /** - * Server URI and supplied <code>SocketFactory</code> do not match. - * URIs beginning <code>tcp://</code> must use a <code>javax.net.SocketFactory</code>, - * and URIs beginning <code>ssl://</code> must use a <code>javax.net.ssl.SSLSocketFactory</code>. - */ - public static final short REASON_CODE_SOCKET_FACTORY_MISMATCH = 32105; - - /** - * SSL configuration error. - */ - public static final short REASON_CODE_SSL_CONFIG_ERROR = 32106; - - /** - * Thrown when an attempt to call {@link MqttClient#disconnect()} has been - * made from within a method on {@link MqttCallback}. These methods are invoked - * by the client's thread, and must not be used to control disconnection. - * - * @see MqttCallback#messageArrived(String, MqttMessage) - */ - public static final short REASON_CODE_CLIENT_DISCONNECT_PROHIBITED = 32107; - - /** - * Protocol error: the message was not recognized as a valid MQTT packet. - * Possible reasons for this include connecting to a non-MQTT server, or - * connecting to an SSL server port when the client isn't using SSL. - */ - public static final short REASON_CODE_INVALID_MESSAGE = 32108; - - /** - * The client has been unexpectedly disconnected from the server. The {@link #getCause() cause} - * will provide more details. - */ - public static final short REASON_CODE_CONNECTION_LOST = 32109; - - /** - * A connect operation in already in progress, only one connect can happen - * at a time. - */ - public static final short REASON_CODE_CONNECT_IN_PROGRESS = 32110; - - /** - * The client is closed - no operations are permitted on the client in this - * state. New up a new client to continue. - */ - public static final short REASON_CODE_CLIENT_CLOSED = 32111; - - /** - * A request has been made to use a token that is already associated with - * another action. If the action is complete the reset() can ve called on the - * token to allow it to be reused. - */ - public static final short REASON_CODE_TOKEN_INUSE = 32201; - - /** - * A request has been made to send a message but the maximum number of inflight - * messages has already been reached. Once one or more messages have been moved - * then new messages can be sent. - */ - public static final short REASON_CODE_MAX_INFLIGHT = 32202; - - /** - * The Client has attempted to publish a message whilst in the 'resting' / offline - * state with Disconnected Publishing enabled, however the buffer is full and - * deleteOldestMessages is disabled, therefore no more messages can be published - * until the client reconnects, or the application deletes buffered message - * manually. - */ - public static final short REASON_CODE_DISCONNECTED_BUFFER_FULL = 32203; - - private int reasonCode; - private Throwable cause; - - /** - * Constructs a new <code>MqttException</code> with the specified code - * as the underlying reason. - * @param reasonCode the reason code for the exception. - */ - public MqttException(int reasonCode) { - super(); - this.reasonCode = reasonCode; - } - - /** - * Constructs a new <code>MqttException</code> with the specified - * <code>Throwable</code> as the underlying reason. - * @param cause the underlying cause of the exception. - */ - public MqttException(Throwable cause) { - super(); - this.reasonCode = REASON_CODE_CLIENT_EXCEPTION; - this.cause = cause; - } - - /** - * Constructs a new <code>MqttException</code> with the specified - * <code>Throwable</code> as the underlying reason. - * @param reason the reason code for the exception. - * @param cause the underlying cause of the exception. - */ - public MqttException(int reason, Throwable cause) { - super(); - this.reasonCode = reason; - this.cause = cause; - } - - - /** - * Returns the reason code for this exception. - * @return the code representing the reason for this exception. - */ - public int getReasonCode() { - return reasonCode; - } - - /** - * Returns the underlying cause of this exception, if available. - * @return the Throwable that was the root cause of this exception, - * which may be <code>null</code>. - */ - public Throwable getCause() { - return cause; - } - - /** - * Returns the detail message for this exception. - * @return the detail message, which may be <code>null</code>. - */ - public String getMessage() { - return MessageCatalog.getMessage(reasonCode); - } - - /** - * Returns a <code>String</code> representation of this exception. - * @return a <code>String</code> representation of this exception. - */ - public String toString() { - String result = getMessage() + " (" + reasonCode + ")"; - if (cause != null) { - result = result + " - " + cause.toString(); - } - return result; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttMessage.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttMessage.java deleted file mode 100644 index 06926e4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttMessage.java +++ /dev/null @@ -1,246 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - ack control (bug 472172) - */ -package org.eclipse.paho.client.mqttv3; - -/** - * An MQTT message holds the application payload and options - * specifying how the message is to be delivered - * The message includes a "payload" (the body of the message) - * represented as a byte[]. - */ -public class MqttMessage { - - private boolean mutable = true; - private byte[] payload; - private int qos = 1; - private boolean retained = false; - private boolean dup = false; - private int messageId; - - /** - * Utility method to validate the supplied QoS value. - * @param qos The QoS Level - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - */ - public static void validateQos(int qos) { - if ((qos < 0) || (qos > 2)) { - throw new IllegalArgumentException(); - } - } - - /** - * Constructs a message with an empty payload, and all other values - * set to defaults. - * - * The defaults are: - * <ul> - * <li>Message QoS set to 1</li> - * <li>Message will not be "retained" by the server</li> - * </ul> - */ - public MqttMessage() { - setPayload(new byte[]{}); - } - - /** - * Constructs a message with the specified byte array as a payload, - * and all other values set to defaults. - * @param payload The Bytearray of the payload - */ - public MqttMessage(byte[] payload) { - setPayload(payload); - } - - /** - * Returns the payload as a byte array. - * - * @return the payload as a byte array. - */ - public byte[] getPayload() { - return payload; - } - - /** - * Clears the payload, resetting it to be empty. - * @throws IllegalStateException if this message cannot be edited - */ - public void clearPayload() { - checkMutable(); - this.payload = new byte[] {}; - } - - /** - * Sets the payload of this message to be the specified byte array. - * - * @param payload the payload for this message. - * @throws IllegalStateException if this message cannot be edited - * @throws NullPointerException if no payload is provided - */ - public void setPayload(byte[] payload) { - checkMutable(); - if (payload == null) { - throw new NullPointerException(); - } - this.payload = payload; - } - - /** - * Returns whether or not this message should be/was retained by the server. - * For messages received from the server, this method returns whether or not - * the message was from a current publisher, or was "retained" by the server as - * the last message published on the topic. - * - * @return <code>true</code> if the message should be, or was, retained by - * the server. - * @see #setRetained(boolean) - */ - public boolean isRetained() { - return retained; - } - - /** - * Whether or not the publish message should be retained by the messaging engine. - * Sending a message with retained set to <code>true</code> and with an empty - * byte array as the payload e.g. <code>new byte[0]</code> will clear the - * retained message from the server. The default value is <code>false</code> - * - * @param retained whether or not the messaging engine should retain the message. - * @throws IllegalStateException if this message cannot be edited - */ - public void setRetained(boolean retained) { - checkMutable(); - this.retained = retained; - } - - /** - * Returns the quality of service for this message. - * @return the quality of service to use, either 0, 1, or 2. - * @see #setQos(int) - */ - public int getQos() { - return qos; - } - - /** - * Sets the quality of service for this message. - * <ul> - * <li>Quality of Service 0 - indicates that a message should - * be delivered at most once (zero or one times). The message will not be persisted to disk, - * and will not be acknowledged across the network. This QoS is the fastest, - * but should only be used for messages which are not valuable - note that - * if the server cannot process the message (for example, there - * is an authorization problem), then an - * {@link MqttCallback#deliveryComplete(IMqttDeliveryToken)}. - * Also known as "fire and forget".</li> - * - * <li>Quality of Service 1 - indicates that a message should - * be delivered at least once (one or more times). The message can only be delivered safely if - * it can be persisted, so the application must supply a means of - * persistence using <code>MqttConnectOptions</code>. - * If a persistence mechanism is not specified, the message will not be - * delivered in the event of a client failure. - * The message will be acknowledged across the network. - * This is the default QoS.</li> - * - * <li>Quality of Service 2 - indicates that a message should - * be delivered once. The message will be persisted to disk, and will - * be subject to a two-phase acknowledgement across the network. - * The message can only be delivered safely if - * it can be persisted, so the application must supply a means of - * persistence using <code>MqttConnectOptions</code>. - * If a persistence mechanism is not specified, the message will not be - * delivered in the event of a client failure.</li> - * - *</ul> - * If persistence is not configured, QoS 1 and 2 messages will still be delivered - * in the event of a network or server problem as the client will hold state in memory. - * If the MQTT client is shutdown or fails and persistence is not configured then - * delivery of QoS 1 and 2 messages can not be maintained as client-side state will - * be lost. - * - * @param qos the "quality of service" to use. Set to 0, 1, 2. - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @throws IllegalStateException if this message cannot be edited - */ - public void setQos(int qos) { - checkMutable(); - validateQos(qos); - this.qos = qos; - } - - /** - * Returns a string representation of this message's payload. - * Makes an attempt to return the payload as a string. As the - * MQTT client has no control over the content of the payload - * it may fail. - * @return a string representation of this message. - */ - public String toString() { - return new String(payload); - } - - /** - * Sets the mutability of this object (whether or not its values can be - * changed. - * @param mutable <code>true</code> if the values can be changed, - * <code>false</code> to prevent them from being changed. - */ - protected void setMutable(boolean mutable) { - this.mutable = mutable; - } - - protected void checkMutable() throws IllegalStateException { - if (!mutable) { - throw new IllegalStateException(); - } - } - - protected void setDuplicate(boolean dup) { - this.dup = dup; - } - - /** - * Returns whether or not this message might be a duplicate of one which has - * already been received. This will only be set on messages received from - * the server. - * @return <code>true</code> if the message might be a duplicate. - */ - public boolean isDuplicate() { - return this.dup; - } - - /** - * This is only to be used internally to provide the MQTT id of a message - * received from the server. Has no effect when publishing messages. - * @param messageId The Message ID - */ - public void setId(int messageId) { - this.messageId = messageId; - } - - /** - * Returns the MQTT id of the message. This is only applicable to messages - * received from the server. - * @return the MQTT id of the message - */ - public int getId() { - return this.messageId; - } - - - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistable.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistable.java deleted file mode 100644 index 95120a1..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistable.java +++ /dev/null @@ -1,102 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -/** - * Represents an object used to pass data to be persisted across the - * {@link org.eclipse.paho.client.mqttv3.MqttClientPersistence MqttClientPersistence} - * interface. - * <p> - * When data is passed across the interface the header and payload are - * separated, so that unnecessary message copies may be avoided. - * For example, if a 10 MB payload was published it would be inefficient - * to create a byte array a few bytes larger than 10 MB and copy the - * MQTT message header and payload into a contiguous byte array.</p> - * <p> - * When the request to persist data is made a separate byte array and offset - * is passed for the header and payload. Only the data between - * offset and length need be persisted. - * So for example, a message to be persisted consists of a header byte - * array starting at offset 1 and length 4, plus a payload byte array - * starting at offset 30 and length 40000. There are three ways in which - * the persistence implementation may return data to the client on - * recovery:</p> - * <ul> - * <li>It could return the data as it was passed in - * originally, with the same byte arrays and offsets.</li> - * <li>It could safely just persist and return the bytes from the offset - * for the specified length. For example, return a header byte array with - * offset 0 and length 4, plus a payload byte array with offset 0 and length - * 40000</li> - * <li>It could return the header and payload as a contiguous byte array - * with the header bytes preceeding the payload. The contiguous byte array - * should be set as the header byte array, with the payload byte array being - * null. For example, return a single byte array with offset 0 - * and length 40004. - * This is useful when recovering from a file where the header and payload - * could be written as a contiguous stream of bytes.</li> - * </ul> - */ -public interface MqttPersistable { - - /** - * Returns the header bytes in an array. - * The bytes start at {@link #getHeaderOffset()} - * and continue for {@link #getHeaderLength()}. - * @return the header bytes. - * @throws MqttPersistenceException if an error occurs getting the Header Bytes - */ - public byte[] getHeaderBytes() throws MqttPersistenceException; - - /** - * Returns the length of the header. - * @return the header length - * @throws MqttPersistenceException if an error occurs getting the Header length - */ - public int getHeaderLength() throws MqttPersistenceException; - - /** - * Returns the offset of the header within the byte array returned by {@link #getHeaderBytes()}. - * @return the header offset. - * @throws MqttPersistenceException if an error occurs getting the Header offset - * - */ - public int getHeaderOffset() throws MqttPersistenceException; - - /** - * Returns the payload bytes in an array. - * The bytes start at {@link #getPayloadOffset()} - * and continue for {@link #getPayloadLength()}. - * @return the payload bytes. - * @throws MqttPersistenceException if an error occurs getting the Payload Bytes - */ - public byte[] getPayloadBytes() throws MqttPersistenceException; - - /** - * Returns the length of the payload. - * @return the payload length. - * @throws MqttPersistenceException if an error occurs getting the Payload length - */ - public int getPayloadLength() throws MqttPersistenceException; - - /** - * Returns the offset of the payload within the byte array returned by {@link #getPayloadBytes()}. - * @return the payload offset. - * @throws MqttPersistenceException if an error occurs getting the Payload Offset - * - */ - public int getPayloadOffset() throws MqttPersistenceException; -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistenceException.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistenceException.java deleted file mode 100644 index e5c142a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPersistenceException.java +++ /dev/null @@ -1,60 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -/** - * This exception is thrown by the implementor of the persistence - * interface if there is a problem reading or writing persistent data. - */ -public class MqttPersistenceException extends MqttException { - private static final long serialVersionUID = 300L; - - /** Persistence is already being used by another client. */ - public static final short REASON_CODE_PERSISTENCE_IN_USE = 32200; - - /** - * Constructs a new <code>MqttPersistenceException</code> - */ - public MqttPersistenceException() { - super(REASON_CODE_CLIENT_EXCEPTION); - } - - /** - * Constructs a new <code>MqttPersistenceException</code> with the specified code - * as the underlying reason. - * @param reasonCode the reason code for the exception. - */ - public MqttPersistenceException(int reasonCode) { - super(reasonCode); - } - /** - * Constructs a new <code>MqttPersistenceException</code> with the specified - * <code>Throwable</code> as the underlying reason. - * @param cause the underlying cause of the exception. - */ - public MqttPersistenceException(Throwable cause) { - super(cause); - } - /** - * Constructs a new <code>MqttPersistenceException</code> with the specified - * <code>Throwable</code> as the underlying reason. - * @param reason the reason code for the exception. - * @param cause the underlying cause of the exception. - */ - public MqttPersistenceException(int reason, Throwable cause) { - super(reason, cause); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPingSender.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPingSender.java deleted file mode 100644 index 27c090c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttPingSender.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - */ - -package org.eclipse.paho.client.mqttv3; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; - -/** - * Represents an object used to send ping packet to MQTT broker - * every keep alive interval. - */ -public interface MqttPingSender { - - /** - * Initial method. Pass interal state of current client in. - * @param comms The core of the client, which holds the state information for pending and in-flight messages. - */ - public void init(ClientComms comms); - - /** - * Start ping sender. It will be called after connection is success. - */ - public void start(); - - /** - * Stop ping sender. It is called if there is any errors or connection shutdowns. - */ - public void stop(); - - /** - * Schedule next ping in certain delay. - * @param delayInMilliseconds delay in milliseconds. - */ - public void schedule(long delayInMilliseconds); - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttSecurityException.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttSecurityException.java deleted file mode 100644 index a5791ce..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttSecurityException.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -/** - * Thrown when a client is not authorized to perform an operation, or - * if there is a problem with the security configuration. - */ -public class MqttSecurityException extends MqttException { - private static final long serialVersionUID = 300L; - - /** - * Constructs a new <code>MqttSecurityException</code> with the specified code - * as the underlying reason. - * @param reasonCode the reason code for the exception. - */ - public MqttSecurityException(int reasonCode) { - super(reasonCode); - } - - /** - * Constructs a new <code>MqttSecurityException</code> with the specified - * <code>Throwable</code> as the underlying reason. - * @param cause the underlying cause of the exception. - */ - public MqttSecurityException(Throwable cause) { - super(cause); - } - /** - * Constructs a new <code>MqttSecurityException</code> with the specified - * code and <code>Throwable</code> as the underlying reason. - * @param reasonCode the reason code for the exception. - * @param cause the underlying cause of the exception. - */ - public MqttSecurityException(int reasonCode, Throwable cause) { - super(reasonCode, cause); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttToken.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttToken.java deleted file mode 100644 index 3352835..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttToken.java +++ /dev/null @@ -1,101 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributions: - * Ian Craggs - MQTT 3.1.1 support - */ - -package org.eclipse.paho.client.mqttv3; - -import org.eclipse.paho.client.mqttv3.internal.Token; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; - -/** - * Provides a mechanism for tracking the completion of an asynchronous action. - * <p> - * A token that implements the ImqttToken interface is returned from all non-blocking - * method with the exception of publish. - * </p> - * - * @see IMqttToken - */ - -public class MqttToken implements IMqttToken { - /** - * A reference to the the class that provides most of the implementation of the - * MqttToken. MQTT application programs must not use the internal class. - */ - public Token internalTok = null; - - public MqttToken() { - } - - public MqttToken(String logContext) { - internalTok = new Token(logContext); - } - - public MqttException getException() { - return internalTok.getException(); - } - - public boolean isComplete() { - return internalTok.isComplete(); - } - - public void setActionCallback(IMqttActionListener listener) { - internalTok.setActionCallback(listener); - - } - public IMqttActionListener getActionCallback() { - return internalTok.getActionCallback(); - } - - public void waitForCompletion() throws MqttException { - internalTok.waitForCompletion(-1); - } - - public void waitForCompletion(long timeout) throws MqttException { - internalTok.waitForCompletion(timeout); - } - - public IMqttAsyncClient getClient() { - return internalTok.getClient(); - } - - public String[] getTopics() { - return internalTok.getTopics(); - } - - public Object getUserContext() { - return internalTok.getUserContext(); - } - - public void setUserContext(Object userContext) { - internalTok.setUserContext(userContext); - } - - public int getMessageId() { - return internalTok.getMessageID(); - } - - public int[] getGrantedQos() { - return internalTok.getGrantedQos(); - } - - public boolean getSessionPresent() { - return internalTok.getSessionPresent(); - } - - public MqttWireMessage getResponse() { - return internalTok.getResponse(); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttTopic.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttTopic.java deleted file mode 100644 index 404e961..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/MqttTopic.java +++ /dev/null @@ -1,284 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3; - -import java.io.UnsupportedEncodingException; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.util.Strings; - -/** - * Represents a topic destination, used for publish/subscribe messaging. - */ -public class MqttTopic { - - /** - * The forward slash (/) is used to separate each level within a topic tree - * and provide a hierarchical structure to the topic space. The use of the - * topic level separator is significant when the two wildcard characters are - * encountered in topics specified by subscribers. - */ - public static final String TOPIC_LEVEL_SEPARATOR = "/"; - - /** - * Multi-level wildcard The number sign (#) is a wildcard character that - * matches any number of levels within a topic. - */ - public static final String MULTI_LEVEL_WILDCARD = "#"; - - /** - * Single-level wildcard The plus sign (+) is a wildcard character that - * matches only one topic level. - */ - public static final String SINGLE_LEVEL_WILDCARD = "+"; - - /** - * Multi-level wildcard pattern(/#) - */ - public static final String MULTI_LEVEL_WILDCARD_PATTERN = TOPIC_LEVEL_SEPARATOR + MULTI_LEVEL_WILDCARD; - - /** - * Topic wildcards (#+) - */ - public static final String TOPIC_WILDCARDS = MULTI_LEVEL_WILDCARD + SINGLE_LEVEL_WILDCARD; - - //topic name and topic filter length range defined in the spec - private static final int MIN_TOPIC_LEN = 1; - private static final int MAX_TOPIC_LEN = 65535; - private static final char NUL = '\u0000'; - - private ClientComms comms; - private String name; - - /** - * @param name The Name of the topic - * @param comms The {@link ClientComms} - */ - public MqttTopic(String name, ClientComms comms) { - this.comms = comms; - this.name = name; - } - - /** - * Publishes a message on the topic. This is a convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. All other values in the - * message will be set to the defaults. - - * @param payload the byte array to use as the payload - * @param qos the Quality of Service. Valid values are 0, 1 or 2. - * @param retained whether or not this message should be retained by the server. - * @return {@link MqttDeliveryToken} - * @throws MqttException If an error occurs publishing the message - * @throws MqttPersistenceException If an error occurs persisting the message - * @throws IllegalArgumentException if value of QoS is not 0, 1 or 2. - * @see #publish(MqttMessage) - * @see MqttMessage#setQos(int) - * @see MqttMessage#setRetained(boolean) - */ - public MqttDeliveryToken publish(byte[] payload, int qos, boolean retained) throws MqttException, MqttPersistenceException { - MqttMessage message = new MqttMessage(payload); - message.setQos(qos); - message.setRetained(retained); - return this.publish(message); - } - - /** - * Publishes the specified message to this topic, but does not wait for delivery - * of the message to complete. The returned {@link MqttDeliveryToken token} can be used - * to track the delivery status of the message. Once this method has - * returned cleanly, the message has been accepted for publication by the - * client. Message delivery will be completed in the background when a connection - * is available. - * - * @param message the message to publish - * @return an MqttDeliveryToken for tracking the delivery of the message - * @throws MqttException if an error occurs publishing the message - * @throws MqttPersistenceException if an error occurs persisting the message - */ - public MqttDeliveryToken publish(MqttMessage message) throws MqttException, MqttPersistenceException { - MqttDeliveryToken token = new MqttDeliveryToken(comms.getClient().getClientId()); - token.setMessage(message); - comms.sendNoWait(createPublish(message), token); - token.internalTok.waitUntilSent(); - return token; - } - - /** - * Returns the name of the queue or topic. - * - * @return the name of this destination. - */ - public String getName() { - return name; - } - - /** - * Create a PUBLISH packet from the specified message. - */ - private MqttPublish createPublish(MqttMessage message) { - return new MqttPublish(this.getName(), message); - } - - /** - * Returns a string representation of this topic. - * @return a string representation of this topic. - */ - public String toString() { - return getName(); - } - - /** - * Validate the topic name or topic filter - * - * @param topicString topic name or filter - * @param wildcardAllowed true if validate topic filter, false otherwise - * @throws IllegalArgumentException if the topic is invalid - */ - public static void validate(String topicString, boolean wildcardAllowed) - throws IllegalArgumentException{ - int topicLen = 0; - try { - topicLen = topicString.getBytes("UTF-8").length; - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e.getMessage()); - } - - // Spec: length check - // - All Topic Names and Topic Filters MUST be at least one character - // long - // - Topic Names and Topic Filters are UTF-8 encoded strings, they MUST - // NOT encode to more than 65535 bytes - if (topicLen < MIN_TOPIC_LEN || topicLen > MAX_TOPIC_LEN) { - throw new IllegalArgumentException(String.format("Invalid topic length, should be in range[%d, %d]!", - new Object[] { new Integer(MIN_TOPIC_LEN), new Integer(MAX_TOPIC_LEN) })); - } - - // ******************************************************************************* - // 1) This is a topic filter string that can contain wildcard characters - // ******************************************************************************* - if (wildcardAllowed) { - // Only # or + - if (Strings.equalsAny(topicString, new String[] { MULTI_LEVEL_WILDCARD, SINGLE_LEVEL_WILDCARD })) { - return; - } - - // 1) Check multi-level wildcard - // Rule: - // The multi-level wildcard can be specified only on its own or next - // to the topic level separator character. - - // - Can only contains one multi-level wildcard character - // - The multi-level wildcard must be the last character used within - // the topic tree - if (Strings.countMatches(topicString, MULTI_LEVEL_WILDCARD) > 1 - || (topicString.contains(MULTI_LEVEL_WILDCARD) && !topicString - .endsWith(MULTI_LEVEL_WILDCARD_PATTERN))) { - throw new IllegalArgumentException( - "Invalid usage of multi-level wildcard in topic string: " - + topicString); - } - - // 2) Check single-level wildcard - // Rule: - // The single-level wildcard can be used at any level in the topic - // tree, and in conjunction with the - // multilevel wildcard. It must be used next to the topic level - // separator, except when it is specified on - // its own. - validateSingleLevelWildcard(topicString); - - return; - } - - // ******************************************************************************* - // 2) This is a topic name string that MUST NOT contains any wildcard characters - // ******************************************************************************* - if (Strings.containsAny(topicString, TOPIC_WILDCARDS)) { - throw new IllegalArgumentException( - "The topic name MUST NOT contain any wildcard characters (#+)"); - } - } - - private static void validateSingleLevelWildcard(String topicString) { - char singleLevelWildcardChar = SINGLE_LEVEL_WILDCARD.charAt(0); - char topicLevelSeparatorChar = TOPIC_LEVEL_SEPARATOR.charAt(0); - - char[] chars = topicString.toCharArray(); - int length = chars.length; - char prev = NUL, next = NUL; - for (int i = 0; i < length; i++) { - prev = (i - 1 >= 0) ? chars[i - 1] : NUL; - next = (i + 1 < length) ? chars[i + 1] : NUL; - - if (chars[i] == singleLevelWildcardChar) { - // prev and next can be only '/' or none - if (prev != topicLevelSeparatorChar && prev != NUL || next != topicLevelSeparatorChar && next != NUL) { - throw new IllegalArgumentException(String.format( - "Invalid usage of single-level wildcard in topic string '%s'!", - new Object[] { topicString })); - - } - } - } - } - - /** - * Check the supplied topic name and filter match - * - * @param topicFilter topic filter: wildcards allowed - * @param topicName topic name: wildcards not allowed - * @return true if the topic matches the filter - * @throws IllegalArgumentException if the topic name or filter is invalid - */ - public static boolean isMatched(String topicFilter, String topicName) - throws IllegalArgumentException { - int curn = 0, - curf = 0; - int curn_end = topicName.length(); - int curf_end = topicFilter.length(); - - MqttTopic.validate(topicFilter, true); - MqttTopic.validate(topicName, false); - - if (topicFilter.equals(topicName)) { - return true; - } - - while (curf < curf_end && curn < curn_end) - { - if (topicName.charAt(curn) == '/' && topicFilter.charAt(curf) != '/') - break; - if (topicFilter.charAt(curf) != '+' && topicFilter.charAt(curf) != '#' && - topicFilter.charAt(curf) != topicName.charAt(curn)) - break; - if (topicFilter.charAt(curf) == '+') - { // skip until we meet the next separator, or end of string - int nextpos = curn + 1; - while (nextpos < curn_end && topicName.charAt(nextpos) != '/') - nextpos = ++curn + 1; - } - else if (topicFilter.charAt(curf) == '#') - curn = curn_end - 1; // skip until end of string - curf++; - curn++; - }; - - return (curn == curn_end) && (curf == curf_end); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/ScheduledExecutorPingSender.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/ScheduledExecutorPingSender.java deleted file mode 100644 index 511909c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/ScheduledExecutorPingSender.java +++ /dev/null @@ -1,92 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * Copyright (c) 2017 BMW Car IT GmbH. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - */ - -package org.eclipse.paho.client.mqttv3; - -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Default ping sender implementation - * - * <p>This class implements the {@link IMqttPingSender} pinger interface - * allowing applications to send ping packet to server every keep alive interval. - * </p> - * - * @see MqttPingSender - */ -public class ScheduledExecutorPingSender implements MqttPingSender { - private static final String CLASS_NAME = ScheduledExecutorPingSender.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private ClientComms comms; - private ScheduledExecutorService executorService; - private ScheduledFuture scheduledFuture; - private String clientid; - - public ScheduledExecutorPingSender(ScheduledExecutorService executorService) { - if (executorService == null) { - throw new IllegalArgumentException("ExecutorService cannot be null."); - } - this.executorService = executorService; - } - - public void init(ClientComms comms) { - if (comms == null) { - throw new IllegalArgumentException("ClientComms cannot be null."); - } - this.comms = comms; - clientid = comms.getClient().getClientId(); - } - - public void start() { - final String methodName = "start"; - - //@Trace 659=start timer for client:{0} - log.fine(CLASS_NAME, methodName, "659", new Object[]{ clientid }); - //Check ping after first keep alive interval. - schedule(comms.getKeepAlive()); - } - - public void stop() { - final String methodName = "stop"; - //@Trace 661=stop - log.fine(CLASS_NAME, methodName, "661", null); - if (scheduledFuture != null) { - scheduledFuture.cancel(true); - } - } - - public void schedule(long delayInMilliseconds) { - scheduledFuture = executorService.schedule(new PingRunnable(), delayInMilliseconds, TimeUnit.MILLISECONDS); - } - - private class PingRunnable implements Runnable { - private static final String methodName = "PingTask.run"; - - public void run() { - String originalThreadName = Thread.currentThread().getName(); - Thread.currentThread().setName("MQTT Ping: " + clientid); - //@Trace 660=Check schedule at {0} - log.fine(CLASS_NAME, methodName, "660", new Object[]{ new Long(System.currentTimeMillis()) }); - comms.checkForActivity(); - Thread.currentThread().setName(originalThreadName); - } - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/TimerPingSender.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/TimerPingSender.java deleted file mode 100644 index 4c93212..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/TimerPingSender.java +++ /dev/null @@ -1,80 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - */ - -package org.eclipse.paho.client.mqttv3; - -import java.util.Timer; -import java.util.TimerTask; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Default ping sender implementation - * - * <p>This class implements the {@link MqttPingSender} pinger interface - * allowing applications to send ping packet to server every keep alive interval. - * </p> - * - * @see MqttPingSender - */ -public class TimerPingSender implements MqttPingSender { - private static final String CLASS_NAME = TimerPingSender.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - private ClientComms comms; - private Timer timer; - - public void init(ClientComms comms) { - if (comms == null) { - throw new IllegalArgumentException("ClientComms cannot be null."); - } - this.comms = comms; - } - - public void start() { - final String methodName = "start"; - String clientid = comms.getClient().getClientId(); - - //@Trace 659=start timer for client:{0} - log.fine(CLASS_NAME, methodName, "659", new Object[]{clientid}); - - timer = new Timer("MQTT Ping: " + clientid); - //Check ping after first keep alive interval. - timer.schedule(new PingTask(), comms.getKeepAlive()); - } - - public void stop() { - final String methodName = "stop"; - //@Trace 661=stop - log.fine(CLASS_NAME, methodName, "661", null); - if(timer != null){ - timer.cancel(); - } - } - - public void schedule(long delayInMilliseconds) { - timer.schedule(new PingTask(), delayInMilliseconds); - } - - private class PingTask extends TimerTask { - private static final String methodName = "PingTask.run"; - - public void run() { - //@Trace 660=Check schedule at {0} - log.fine(CLASS_NAME, methodName, "660", new Object[]{new Long(System.currentTimeMillis())}); - comms.checkForActivity(); - } - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientComms.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientComms.java deleted file mode 100644 index 542d9df..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientComms.java +++ /dev/null @@ -1,881 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - * James Sutton - checkForActivity Token (bug 473928) - * James Sutton - Automatic Reconnect & Offline Buffering. - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.util.Enumeration; -import java.util.Properties; -import java.util.Vector; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.TimeUnit; - -import org.eclipse.paho.client.mqttv3.BufferedMessage; -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.IMqttAsyncClient; -import org.eclipse.paho.client.mqttv3.IMqttMessageListener; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; -import org.eclipse.paho.client.mqttv3.MqttClientPersistence; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; -import org.eclipse.paho.client.mqttv3.MqttPingSender; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.MqttTopic; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttConnack; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttConnect; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttDisconnect; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Handles client communications with the server. Sends and receives MQTT V3 - * messages. - */ -public class ClientComms { - public static String VERSION = "${project.version}"; - public static String BUILD_LEVEL = "L${build.level}"; - private static final String CLASS_NAME = ClientComms.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - private static final byte CONNECTED = 0; - private static final byte CONNECTING = 1; - private static final byte DISCONNECTING = 2; - private static final byte DISCONNECTED = 3; - private static final byte CLOSED = 4; - - private IMqttAsyncClient client; - private int networkModuleIndex; - private NetworkModule[] networkModules; - private CommsReceiver receiver; - private CommsSender sender; - private CommsCallback callback; - private ClientState clientState; - private MqttConnectOptions conOptions; - private MqttClientPersistence persistence; - private MqttPingSender pingSender; - private CommsTokenStore tokenStore; - private boolean stoppingComms = false; - - private byte conState = DISCONNECTED; - private Object conLock = new Object(); // Used to synchronize connection state - private boolean closePending = false; - private boolean resting = false; - private DisconnectedMessageBuffer disconnectedMessageBuffer; - - private ExecutorService executorService; - - /** - * Creates a new ClientComms object, using the specified module to handle - * the network calls. - * @param client The {@link IMqttAsyncClient} - * @param persistence the {@link MqttClientPersistence} layer. - * @param pingSender the {@link MqttPingSender} - * @param executorService the {@link ExecutorService} - * @throws MqttException if an exception occurs whilst communicating with the server - */ - public ClientComms(IMqttAsyncClient client, MqttClientPersistence persistence, MqttPingSender pingSender, ExecutorService executorService) throws MqttException { - this.conState = DISCONNECTED; - this.client = client; - this.persistence = persistence; - this.pingSender = pingSender; - this.pingSender.init(this); - this.executorService = executorService; - - this.tokenStore = new CommsTokenStore(getClient().getClientId()); - this.callback = new CommsCallback(this); - this.clientState = new ClientState(persistence, tokenStore, this.callback, this, pingSender); - - callback.setClientState(clientState); - log.setResourceName(getClient().getClientId()); - } - - CommsReceiver getReceiver() { - return receiver; - } - - private void shutdownExecutorService() { - String methodName = "shutdownExecutorService"; - executorService.shutdown(); - try { - if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) { - executorService.shutdownNow(); - if (!executorService.awaitTermination(1, TimeUnit.SECONDS)) { - log.fine(CLASS_NAME, methodName, "executorService did not terminate"); - } - } - } catch (InterruptedException ie) { - executorService.shutdownNow(); - Thread.currentThread().interrupt(); - } - } - - /** - * Sends a message to the server. Does not check if connected this validation must be done - * by invoking routines. - * @param message - * @param token - * @throws MqttException - */ - void internalSend(MqttWireMessage message, MqttToken token) throws MqttException { - final String methodName = "internalSend"; - //@TRACE 200=internalSend key={0} message={1} token={2} - log.fine(CLASS_NAME, methodName, "200", new Object[]{message.getKey(), message, token}); - - if (token.getClient() == null ) { - // Associate the client with the token - also marks it as in use. - token.internalTok.setClient(getClient()); - } else { - // Token is already in use - cannot reuse - //@TRACE 213=fail: token in use: key={0} message={1} token={2} - log.fine(CLASS_NAME, methodName, "213", new Object[]{message.getKey(), message, token}); - - throw new MqttException(MqttException.REASON_CODE_TOKEN_INUSE); - } - - try { - // Persist if needed and send the message - this.clientState.send(message, token); - } catch(MqttException e) { - if (message instanceof MqttPublish) { - this.clientState.undo((MqttPublish)message); - } - throw e; - } - } - - /** - * Sends a message to the broker if in connected state, but only waits for the message to be - * stored, before returning. - * @param message The {@link MqttWireMessage} to send - * @param token The {@link MqttToken} to send. - * @throws MqttException if an error occurs sending the message - */ - public void sendNoWait(MqttWireMessage message, MqttToken token) throws MqttException { - final String methodName = "sendNoWait"; - if (isConnected() || - (!isConnected() && message instanceof MqttConnect) || - (isDisconnecting() && message instanceof MqttDisconnect)) { - if(disconnectedMessageBuffer != null && disconnectedMessageBuffer.getMessageCount() != 0){ - //@TRACE 507=Client Connected, Offline Buffer available, but not empty. Adding message to buffer. message={0} - log.fine(CLASS_NAME, methodName, "507", new Object[] {message.getKey()}); - if(disconnectedMessageBuffer.isPersistBuffer()){ - this.clientState.persistBufferedMessage(message); - } - disconnectedMessageBuffer.putMessage(message, token); - } else { - this.internalSend(message, token); - } - } else if(disconnectedMessageBuffer != null) { - //@TRACE 508=Offline Buffer available. Adding message to buffer. message={0} - log.fine(CLASS_NAME, methodName, "508", new Object[] {message.getKey()}); - if(disconnectedMessageBuffer.isPersistBuffer()){ - this.clientState.persistBufferedMessage(message); - } - disconnectedMessageBuffer.putMessage(message, token); - } else { - //@TRACE 208=failed: not connected - log.fine(CLASS_NAME, methodName, "208"); - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED); - } - } - - /** - * Close and tidy up. - * - * Call each main class and let it tidy up e.g. releasing the token - * store which normally survives a disconnect. - * @throws MqttException if not disconnected - */ - public void close(boolean force) throws MqttException { - final String methodName = "close"; - synchronized (conLock) { - if (!isClosed()) { - // Must be disconnected before close can take place or if we are being forced - if (!isDisconnected() || force) { - //@TRACE 224=failed: not disconnected - log.fine(CLASS_NAME, methodName, "224"); - - if (isConnecting()) { - throw new MqttException(MqttException.REASON_CODE_CONNECT_IN_PROGRESS); - } else if (isConnected()) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CONNECTED); - } else if (isDisconnecting()) { - closePending = true; - return; - } - } - - conState = CLOSED; - shutdownExecutorService(); - // ShutdownConnection has already cleaned most things - clientState.close(); - clientState = null; - callback = null; - persistence = null; - sender = null; - pingSender = null; - receiver = null; - networkModules = null; - conOptions = null; - tokenStore = null; - } - } - } - - /** - * Sends a connect message and waits for an ACK or NACK. - * Connecting is a special case which will also start up the - * network connection, receive thread, and keep alive thread. - * @param options The {@link MqttConnectOptions} for the connection - * @param token The {@link MqttToken} to track the connection - * @throws MqttException if an error occurs when connecting - */ - public void connect(MqttConnectOptions options, MqttToken token) throws MqttException { - final String methodName = "connect"; - synchronized (conLock) { - if (isDisconnected() && !closePending) { - //@TRACE 214=state=CONNECTING - log.fine(CLASS_NAME,methodName,"214"); - - conState = CONNECTING; - - conOptions = options; - - MqttConnect connect = new MqttConnect(client.getClientId(), - conOptions.getMqttVersion(), - conOptions.isCleanSession(), - conOptions.getKeepAliveInterval(), - conOptions.getUserName(), - conOptions.getPassword(), - conOptions.getWillMessage(), - conOptions.getWillDestination()); - - this.clientState.setKeepAliveSecs(conOptions.getKeepAliveInterval()); - this.clientState.setCleanSession(conOptions.isCleanSession()); - this.clientState.setMaxInflight(conOptions.getMaxInflight()); - - tokenStore.open(); - ConnectBG conbg = new ConnectBG(this, token, connect, executorService); - conbg.start(); - } - else { - // @TRACE 207=connect failed: not disconnected {0} - log.fine(CLASS_NAME,methodName,"207", new Object[] {new Byte(conState)}); - if (isClosed() || closePending) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_CLOSED); - } else if (isConnecting()) { - throw new MqttException(MqttException.REASON_CODE_CONNECT_IN_PROGRESS); - } else if (isDisconnecting()) { - throw new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING); - } else { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CONNECTED); - } - } - } - } - - public void connectComplete( MqttConnack cack, MqttException mex) throws MqttException { - final String methodName = "connectComplete"; - int rc = cack.getReturnCode(); - synchronized (conLock) { - if (rc == 0) { - // We've successfully connected - // @TRACE 215=state=CONNECTED - log.fine(CLASS_NAME,methodName,"215"); - - conState = CONNECTED; - return; - } - } - - // @TRACE 204=connect failed: rc={0} - log.fine(CLASS_NAME,methodName,"204", new Object[]{new Integer(rc)}); - throw mex; - } - - /** - * Shuts down the connection to the server. - * This may have been invoked as a result of a user calling disconnect or - * an abnormal disconnection. The method may be invoked multiple times - * in parallel as each thread when it receives an error uses this method - * to ensure that shutdown completes successfully. - * @param token the {@link MqttToken} To track closing the connection - * @param reason the {@link MqttException} thrown requiring the connection to be shut down. - */ - public void shutdownConnection(MqttToken token, MqttException reason) { - final String methodName = "shutdownConnection"; - boolean wasConnected; - MqttToken endToken = null; //Token to notify after disconnect completes - - // This method could concurrently be invoked from many places only allow it - // to run once. - synchronized(conLock) { - if (stoppingComms || closePending || isClosed()) { - return; - } - stoppingComms = true; - - //@TRACE 216=state=DISCONNECTING - log.fine(CLASS_NAME,methodName,"216"); - - wasConnected = (isConnected() || isDisconnecting()); - conState = DISCONNECTING; - } - - // Update the token with the reason for shutdown if it - // is not already complete. - if (token != null && !token.isComplete()) { - token.internalTok.setException(reason); - } - - // Stop the thread that is used to call the user back - // when actions complete - if (callback!= null) {callback.stop(); } - - // Stop the thread that handles inbound work from the network - if (receiver != null) {receiver.stop();} - - // Stop the network module, send and receive now not possible - try { - if (networkModules != null) { - NetworkModule networkModule = networkModules[networkModuleIndex]; - if (networkModule != null) { - networkModule.stop(); - } - } - } catch (Exception ioe) { - // Ignore as we are shutting down - } - - // Stop any new tokens being saved by app and throwing an exception if they do - tokenStore.quiesce(new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING)); - - // Notify any outstanding tokens with the exception of - // con or discon which may be returned and will be notified at - // the end - endToken = handleOldTokens(token, reason); - - try { - // Clean session handling and tidy up - clientState.disconnected(reason); - if (clientState.getCleanSession()) - callback.removeMessageListeners(); - }catch(Exception ex) { - // Ignore as we are shutting down - } - - if (sender != null) { sender.stop(); } - - if (pingSender != null){ - pingSender.stop(); - } - - try { - if(disconnectedMessageBuffer == null && persistence != null){ - persistence.close(); - } - - }catch(Exception ex) { - // Ignore as we are shutting down - } - // All disconnect logic has been completed allowing the - // client to be marked as disconnected. - synchronized(conLock) { - //@TRACE 217=state=DISCONNECTED - log.fine(CLASS_NAME,methodName,"217"); - - conState = DISCONNECTED; - stoppingComms = false; - } - - // Internal disconnect processing has completed. If there - // is a disconnect token or a connect in error notify - // it now. This is done at the end to allow a new connect - // to be processed and now throw a currently disconnecting error. - // any outstanding tokens and unblock any waiters - if (endToken != null & callback != null) { - callback.asyncOperationComplete(endToken); - } - - if (wasConnected && callback != null) { - // Let the user know client has disconnected either normally or abnormally - callback.connectionLost(reason); - } - - // While disconnecting, close may have been requested - try it now - synchronized(conLock) { - if (closePending) { - try { - close(true); - } catch (Exception e) { // ignore any errors as closing - } - } - } - } - - // Tidy up. There may be tokens outstanding as the client was - // not disconnected/quiseced cleanly! Work out what tokens still - // need to be notified and waiters unblocked. Store the - // disconnect or connect token to notify after disconnect is - // complete. - private MqttToken handleOldTokens(MqttToken token, MqttException reason) { - final String methodName = "handleOldTokens"; - //@TRACE 222=> - log.fine(CLASS_NAME,methodName,"222"); - - MqttToken tokToNotifyLater = null; - try { - // First the token that was related to the disconnect / shutdown may - // not be in the token table - temporarily add it if not - if (token != null) { - if (tokenStore.getToken(token.internalTok.getKey())==null) { - tokenStore.saveToken(token, token.internalTok.getKey()); - } - } - - Vector toksToNot = clientState.resolveOldTokens(reason); - Enumeration toksToNotE = toksToNot.elements(); - while(toksToNotE.hasMoreElements()) { - MqttToken tok = (MqttToken)toksToNotE.nextElement(); - - if (tok.internalTok.getKey().equals(MqttDisconnect.KEY) || - tok.internalTok.getKey().equals(MqttConnect.KEY)) { - // Its con or discon so remember and notify @ end of disc routine - tokToNotifyLater = tok; - } else { - // notify waiters and callbacks of outstanding tokens - // that a problem has occurred and disconnect is in - // progress - callback.asyncOperationComplete(tok); - } - } - }catch(Exception ex) { - // Ignore as we are shutting down - } - return tokToNotifyLater; - } - - public void disconnect(MqttDisconnect disconnect, long quiesceTimeout, MqttToken token) throws MqttException { - final String methodName = "disconnect"; - synchronized (conLock){ - if (isClosed()) { - //@TRACE 223=failed: in closed state - log.fine(CLASS_NAME,methodName,"223"); - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_CLOSED); - } else if (isDisconnected()) { - //@TRACE 211=failed: already disconnected - log.fine(CLASS_NAME,methodName,"211"); - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_ALREADY_DISCONNECTED); - } else if (isDisconnecting()) { - //@TRACE 219=failed: already disconnecting - log.fine(CLASS_NAME,methodName,"219"); - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING); - } else if (Thread.currentThread() == callback.getThread()) { - //@TRACE 210=failed: called on callback thread - log.fine(CLASS_NAME,methodName,"210"); - // Not allowed to call disconnect() from the callback, as it will deadlock. - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_DISCONNECT_PROHIBITED); - } - - //@TRACE 218=state=DISCONNECTING - log.fine(CLASS_NAME,methodName,"218"); - conState = DISCONNECTING; - DisconnectBG discbg = new DisconnectBG(disconnect,quiesceTimeout,token, executorService); - discbg.start(); - } - } - - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout) throws MqttException { - disconnectForcibly(quiesceTimeout, disconnectTimeout, true); - } - - /** - * Disconnect the connection and reset all the states. - * @param quiesceTimeout How long to wait whilst quiesing before messages are deleted. - * @param disconnectTimeout How long to wait whilst disconnecting - * @param sendDisconnectPacket If true, will send a disconnect packet - * @throws MqttException if an error occurs whilst disconnecting - */ - public void disconnectForcibly(long quiesceTimeout, long disconnectTimeout, boolean sendDisconnectPacket) throws MqttException { - // Allow current inbound and outbound work to complete - if (clientState != null) { - clientState.quiesce(quiesceTimeout); - } - MqttToken token = new MqttToken(client.getClientId()); - try { - // Send disconnect packet - if(sendDisconnectPacket) { - internalSend(new MqttDisconnect(), token); - - // Wait util the disconnect packet sent with timeout - token.waitForCompletion(disconnectTimeout); - } - } - catch (Exception ex) { - // ignore, probably means we failed to send the disconnect packet. - } - finally { - token.internalTok.markComplete(null, null); - shutdownConnection(token, null); - } - } - - public boolean isConnected() { - synchronized (conLock) { - return conState == CONNECTED; - } - } - - public boolean isConnecting() { - synchronized (conLock) { - return conState == CONNECTING; - } - } - - public boolean isDisconnected() { - synchronized (conLock) { - return conState == DISCONNECTED; - } - } - - public boolean isDisconnecting() { - synchronized (conLock) { - return conState == DISCONNECTING; - } - } - - public boolean isClosed() { - synchronized (conLock) { - return conState == CLOSED; - } - } - - public boolean isResting() { - synchronized (conLock) { - return resting; - } - } - - - public void setCallback(MqttCallback mqttCallback) { - this.callback.setCallback(mqttCallback); - } - - public void setReconnectCallback(MqttCallbackExtended callback){ - this.callback.setReconnectCallback(callback); - } - - public void setManualAcks(boolean manualAcks) { - this.callback.setManualAcks(manualAcks); - } - - public void messageArrivedComplete(int messageId, int qos) throws MqttException { - this.callback.messageArrivedComplete(messageId, qos); - } - - public void setMessageListener(String topicFilter, IMqttMessageListener messageListener) { - this.callback.setMessageListener(topicFilter, messageListener); - } - - public void removeMessageListener(String topicFilter) { - this.callback.removeMessageListener(topicFilter); - } - - protected MqttTopic getTopic(String topic) { - return new MqttTopic(topic, this); - } - public void setNetworkModuleIndex(int index) { - this.networkModuleIndex = index; - } - public int getNetworkModuleIndex() { - return networkModuleIndex; - } - public NetworkModule[] getNetworkModules() { - return networkModules; - } - public void setNetworkModules(NetworkModule[] networkModules) { - this.networkModules = networkModules; - } - public MqttDeliveryToken[] getPendingDeliveryTokens() { - return tokenStore.getOutstandingDelTokens(); - } - - protected void deliveryComplete(MqttPublish msg) throws MqttPersistenceException { - this.clientState.deliveryComplete(msg); - } - - protected void deliveryComplete(int messageId) throws MqttPersistenceException { - this.clientState.deliveryComplete(messageId); - } - - public IMqttAsyncClient getClient() { - return client; - } - - public long getKeepAlive() { - return this.clientState.getKeepAlive(); - } - - public ClientState getClientState() { - return clientState; - } - - public MqttConnectOptions getConOptions() { - return conOptions; - } - - public Properties getDebug() { - Properties props = new Properties(); - props.put("conState", new Integer(conState)); - props.put("serverURI", getClient().getServerURI()); - props.put("callback", callback); - props.put("stoppingComms", new Boolean(stoppingComms)); - return props; - } - - - - // Kick off the connect processing in the background so that it does not block. For instance - // the socket could take time to create. - private class ConnectBG implements Runnable { - ClientComms clientComms = null; - MqttToken conToken; - MqttConnect conPacket; - private String threadName; - - ConnectBG(ClientComms cc, MqttToken cToken, MqttConnect cPacket, ExecutorService executorService) { - clientComms = cc; - conToken = cToken; - conPacket = cPacket; - threadName = "MQTT Con: "+getClient().getClientId(); - } - - void start() { - executorService.execute(this); - } - - public void run() { - Thread.currentThread().setName(threadName); - final String methodName = "connectBG:run"; - MqttException mqttEx = null; - //@TRACE 220=> - log.fine(CLASS_NAME, methodName, "220"); - - try { - // Reset an exception on existing delivery tokens. - // This will have been set if disconnect occured before delivery was - // fully processed. - MqttDeliveryToken[] toks = tokenStore.getOutstandingDelTokens(); - for (int i=0; i<toks.length; i++) { - toks[i].internalTok.setException(null); - } - - // Save the connect token in tokenStore as failure can occur before send - tokenStore.saveToken(conToken,conPacket); - - // Connect to the server at the network level e.g. TCP socket and then - // start the background processing threads before sending the connect - // packet. - NetworkModule networkModule = networkModules[networkModuleIndex]; - networkModule.start(); - receiver = new CommsReceiver(clientComms, clientState, tokenStore, networkModule.getInputStream()); - receiver.start("MQTT Rec: "+getClient().getClientId(), executorService); - sender = new CommsSender(clientComms, clientState, tokenStore, networkModule.getOutputStream()); - sender.start("MQTT Snd: "+getClient().getClientId(), executorService); - callback.start("MQTT Call: "+getClient().getClientId(), executorService); - internalSend(conPacket, conToken); - } catch (MqttException ex) { - //@TRACE 212=connect failed: unexpected exception - log.fine(CLASS_NAME, methodName, "212", null, ex); - mqttEx = ex; - } catch (Exception ex) { - //@TRACE 209=connect failed: unexpected exception - log.fine(CLASS_NAME, methodName, "209", null, ex); - mqttEx = ExceptionHelper.createMqttException(ex); - } - - if (mqttEx != null) { - shutdownConnection(conToken, mqttEx); - } - } - } - - // Kick off the disconnect processing in the background so that it does not block. For instance - // the quiesce - private class DisconnectBG implements Runnable { - MqttDisconnect disconnect; - long quiesceTimeout; - MqttToken token; - private String threadName; - - DisconnectBG(MqttDisconnect disconnect, long quiesceTimeout, MqttToken token, ExecutorService executorService) { - this.disconnect = disconnect; - this.quiesceTimeout = quiesceTimeout; - this.token = token; - } - - void start() { - threadName = "MQTT Disc: "+getClient().getClientId(); - executorService.execute(this); - } - - public void run() { - Thread.currentThread().setName(threadName); - final String methodName = "disconnectBG:run"; - //@TRACE 221=> - log.fine(CLASS_NAME, methodName, "221"); - - // Allow current inbound and outbound work to complete - clientState.quiesce(quiesceTimeout); - try { - internalSend(disconnect, token); - token.internalTok.waitUntilSent(); - } - catch (MqttException ex) { - } - finally { - token.internalTok.markComplete(null, null); - shutdownConnection(token, null); - } - } - } - - /* - * Check and send a ping if needed and check for ping timeout. - * Need to send a ping if nothing has been sent or received - * in the last keepalive interval. - */ - public MqttToken checkForActivity(){ - return this.checkForActivity(null); - } - - /* - * Check and send a ping if needed and check for ping timeout. - * Need to send a ping if nothing has been sent or received - * in the last keepalive interval. - * Passes an IMqttActionListener to ClientState.checkForActivity - * so that the callbacks are attached as soon as the token is created - * (Bug 473928) - */ - public MqttToken checkForActivity(IMqttActionListener pingCallback){ - MqttToken token = null; - try{ - token = clientState.checkForActivity(pingCallback); - }catch(MqttException e){ - handleRunException(e); - }catch(Exception e){ - handleRunException(e); - } - return token; - } - - private void handleRunException(Exception ex) { - final String methodName = "handleRunException"; - //@TRACE 804=exception - log.fine(CLASS_NAME,methodName,"804",null, ex); - MqttException mex; - if ( !(ex instanceof MqttException)) { - mex = new MqttException(MqttException.REASON_CODE_CONNECTION_LOST, ex); - } else { - mex = (MqttException)ex; - } - - shutdownConnection(null, mex); - } - - /** - * When Automatic reconnect is enabled, we want ClientComs to enter the - * 'resting' state if disconnected. This will allow us to publish messages - * @param resting if true, resting is enabled - */ - public void setRestingState(boolean resting) { - this.resting = resting; - } - - public void setDisconnectedMessageBuffer(DisconnectedMessageBuffer disconnectedMessageBuffer) { - this.disconnectedMessageBuffer = disconnectedMessageBuffer; - } - - public int getBufferedMessageCount(){ - return this.disconnectedMessageBuffer.getMessageCount(); - } - - public MqttMessage getBufferedMessage(int bufferIndex){ - MqttPublish send = (MqttPublish) this.disconnectedMessageBuffer.getMessage(bufferIndex).getMessage(); - return send.getMessage(); - } - - public void deleteBufferedMessage(int bufferIndex){ - this.disconnectedMessageBuffer.deleteMessage(bufferIndex); - } - - - /** - * When the client connects, we want to send all messages from the - * buffer first before allowing the user to send any messages - */ - public void notifyConnect() { - final String methodName = "notifyConnect"; - if(disconnectedMessageBuffer != null){ - //@TRACE 509=Client Connected, Offline Buffer Available. Sending Buffered Messages. - log.fine(CLASS_NAME, methodName, "509"); - - disconnectedMessageBuffer.setPublishCallback(new ReconnectDisconnectedBufferCallback(methodName)); - executorService.execute(disconnectedMessageBuffer); - } - } - - class ReconnectDisconnectedBufferCallback implements IDisconnectedBufferCallback{ - - final String methodName; - - ReconnectDisconnectedBufferCallback(String methodName) { - this.methodName = methodName; - } - - public void publishBufferedMessage(BufferedMessage bufferedMessage) throws MqttException { - if (isConnected()) { - while(clientState.getActualInFlight() >= (clientState.getMaxInFlight()-1)){ - // We need to Yield to the other threads to allow the in flight messages to clear - Thread.yield(); - - } - //@TRACE 510=Publising Buffered message message={0} - log.fine(CLASS_NAME, methodName, "510", new Object[] {bufferedMessage.getMessage().getKey()}); - internalSend(bufferedMessage.getMessage(), bufferedMessage.getToken()); - // Delete from persistence if in there - clientState.unPersistBufferedMessage(bufferedMessage.getMessage()); - } else { - //@TRACE 208=failed: not connected - log.fine(CLASS_NAME, methodName, "208"); - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_NOT_CONNECTED); - } - } - } - - public int getActualInFlight() { - return this.clientState.getActualInFlight(); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientDefaults.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientDefaults.java deleted file mode 100644 index 9b876c7..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientDefaults.java +++ /dev/null @@ -1,20 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -public class ClientDefaults { - public static final int MAX_MSG_SIZE = 1024 * 1024 * 256; // 256 MB -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientState.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientState.java deleted file mode 100644 index 5376937..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ClientState.java +++ /dev/null @@ -1,1401 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2017 IBM Corp and others. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - fix duplicate message id (Bug 466853) - * Ian Craggs - ack control (bug 472172) - * James Sutton - Ping Callback (bug 473928) - * Ian Craggs - fix for NPE bug 470718 - * James Sutton - Automatic Reconnect & Offline Buffering - * Jens Reimann - Fix issue #370 - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.EOFException; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Properties; -import java.util.Vector; - -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.MqttClientPersistence; -import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.MqttPersistable; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; -import org.eclipse.paho.client.mqttv3.MqttPingSender; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttConnack; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttConnect; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPingReq; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPingResp; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubComp; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubRec; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubRel; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttSuback; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttSubscribe; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttUnsubAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttUnsubscribe; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * The core of the client, which holds the state information for pending and - * in-flight messages. - * - * Messages that have been accepted for delivery are moved between several objects - * while being delivered. - * - * 1) When the client is not running messages are stored in a persistent store that - * implements the MqttClientPersistent Interface. The default is MqttDefaultFilePersistencew - * which stores messages safely across failures and system restarts. If no persistence - * is specified there is a fall back to MemoryPersistence which will maintain the messages - * while the Mqtt client is instantiated. - * - * 2) When the client or specifically ClientState is instantiated the messages are - * read from the persistent store into: - * - outboundqos2 hashtable if a QoS 2 PUBLISH or PUBREL - * - outboundqos1 hashtable if a QoS 1 PUBLISH - * (see restoreState) - * - * 3) On Connect, copy messages from the outbound hashtables to the pendingMessages or - * pendingFlows vector in messageid order. - * - Initial message publish goes onto the pendingmessages buffer. - * - PUBREL goes onto the pendingflows buffer - * (see restoreInflightMessages) - * - * 4) Sender thread reads messages from the pendingflows and pendingmessages buffer - * one at a time. The message is removed from the pendingbuffer but remains on the - * outbound* hashtable. The hashtable is the place where the full set of outstanding - * messages are stored in memory. (Persistence is only used at start up) - * - * 5) Receiver thread - receives wire messages: - * - if QoS 1 then remove from persistence and outboundqos1 - * - if QoS 2 PUBREC send PUBREL. Updating the outboundqos2 entry with the PUBREL - * and update persistence. - * - if QoS 2 PUBCOMP remove from persistence and outboundqos2 - * - * Notes: - * because of the multithreaded nature of the client it is vital that any changes to this - * class take concurrency into account. For instance as soon as a flow / message is put on - * the wire it is possible for the receiving thread to receive the ack and to be processing - * the response before the sending side has finished processing. For instance a connect may - * be sent, the conack received before the connect notify send has been processed! - * - */ -public class ClientState { - private static final String CLASS_NAME = ClientState.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - private static final String PERSISTENCE_SENT_PREFIX = "s-"; - private static final String PERSISTENCE_SENT_BUFFERED_PREFIX = "sb-"; - private static final String PERSISTENCE_CONFIRMED_PREFIX = "sc-"; - private static final String PERSISTENCE_RECEIVED_PREFIX = "r-"; - - private static final int MIN_MSG_ID = 1; // Lowest possible MQTT message ID to use - private static final int MAX_MSG_ID = 65535; // Highest possible MQTT message ID to use - private int nextMsgId = MIN_MSG_ID - 1; // The next available message ID to use - private Hashtable inUseMsgIds; // Used to store a set of in-use message IDs - - volatile private Vector pendingMessages; - volatile private Vector pendingFlows; - - private CommsTokenStore tokenStore; - private ClientComms clientComms = null; - private CommsCallback callback = null; - private long keepAlive; - private boolean cleanSession; - private MqttClientPersistence persistence; - - private int maxInflight = 0; - private int actualInFlight = 0; - private int inFlightPubRels = 0; - - private Object queueLock = new Object(); - private Object quiesceLock = new Object(); - private boolean quiescing = false; - - private long lastOutboundActivity = 0; - private long lastInboundActivity = 0; - private long lastPing = 0; - private MqttWireMessage pingCommand; - private Object pingOutstandingLock = new Object(); - private int pingOutstanding = 0; - - private boolean connected = false; - - private Hashtable outboundQoS2 = null; - private Hashtable outboundQoS1 = null; - private Hashtable outboundQoS0 = null; - private Hashtable inboundQoS2 = null; - - private MqttPingSender pingSender = null; - - protected ClientState(MqttClientPersistence persistence, CommsTokenStore tokenStore, - CommsCallback callback, ClientComms clientComms, MqttPingSender pingSender) throws MqttException { - - log.setResourceName(clientComms.getClient().getClientId()); - log.finer(CLASS_NAME, "<Init>", "" ); - - inUseMsgIds = new Hashtable(); - pendingFlows = new Vector(); - outboundQoS2 = new Hashtable(); - outboundQoS1 = new Hashtable(); - outboundQoS0 = new Hashtable(); - inboundQoS2 = new Hashtable(); - pingCommand = new MqttPingReq(); - inFlightPubRels = 0; - actualInFlight = 0; - - this.persistence = persistence; - this.callback = callback; - this.tokenStore = tokenStore; - this.clientComms = clientComms; - this.pingSender = pingSender; - - restoreState(); - } - - protected void setMaxInflight(int maxInflight) { - this.maxInflight = maxInflight; - pendingMessages = new Vector(this.maxInflight); - } - protected void setKeepAliveSecs(long keepAliveSecs) { - this.keepAlive = keepAliveSecs*1000; - } - protected long getKeepAlive() { - return this.keepAlive; - } - protected void setCleanSession(boolean cleanSession) { - this.cleanSession = cleanSession; - } - protected boolean getCleanSession() { - return this.cleanSession; - } - - private String getSendPersistenceKey(MqttWireMessage message) { - return PERSISTENCE_SENT_PREFIX + message.getMessageId(); - } - - private String getSendConfirmPersistenceKey(MqttWireMessage message) { - return PERSISTENCE_CONFIRMED_PREFIX + message.getMessageId(); - } - - private String getReceivedPersistenceKey(MqttWireMessage message) { - return PERSISTENCE_RECEIVED_PREFIX + message.getMessageId(); - } - - private String getReceivedPersistenceKey(int messageId) { - return PERSISTENCE_RECEIVED_PREFIX + messageId; - } - - private String getSendBufferedPersistenceKey(MqttWireMessage message){ - return PERSISTENCE_SENT_BUFFERED_PREFIX + message.getMessageId(); - } - - protected void clearState() throws MqttException { - final String methodName = "clearState"; - //@TRACE 603=clearState - log.fine(CLASS_NAME, methodName,">"); - - persistence.clear(); - inUseMsgIds.clear(); - pendingMessages.clear(); - pendingFlows.clear(); - outboundQoS2.clear(); - outboundQoS1.clear(); - outboundQoS0.clear(); - inboundQoS2.clear(); - tokenStore.clear(); - } - - private MqttWireMessage restoreMessage(String key, MqttPersistable persistable) throws MqttException { - final String methodName = "restoreMessage"; - MqttWireMessage message = null; - - try { - message = MqttWireMessage.createWireMessage(persistable); - } - catch (MqttException ex) { - //@TRACE 602=key={0} exception - log.fine(CLASS_NAME, methodName, "602", new Object[] {key}, ex); - if (ex.getCause() instanceof EOFException) { - // Premature end-of-file means that the message is corrupted - if (key != null) { - persistence.remove(key); - } - } - else { - throw ex; - } - } - //@TRACE 601=key={0} message={1} - log.fine(CLASS_NAME, methodName, "601", new Object[]{key,message}); - return message; - } - - /** - * Inserts a new message to the list, ensuring that list is ordered from lowest to highest in terms of the message id's. - * @param list the list to insert the message into - * @param newMsg the message to insert into the list - */ - private void insertInOrder(Vector list, MqttWireMessage newMsg) { - int newMsgId = newMsg.getMessageId(); - for (int i = 0; i < list.size(); i++) { - MqttWireMessage otherMsg = (MqttWireMessage) list.elementAt(i); - int otherMsgId = otherMsg.getMessageId(); - if (otherMsgId > newMsgId) { - list.insertElementAt(newMsg, i); - return; - } - } - list.addElement(newMsg); - } - - /** - * Produces a new list with the messages properly ordered according to their message id's. - * @param list the list containing the messages to produce a new reordered list for - * - this will not be modified or replaced, i.e., be read-only to this method - * @return a new reordered list - */ - private Vector reOrder(Vector list) { - - // here up the new list - Vector newList = new Vector(); - - if (list.size() == 0) { - return newList; // nothing to reorder - } - - int previousMsgId = 0; - int largestGap = 0; - int largestGapMsgIdPosInList = 0; - for (int i = 0; i < list.size(); i++) { - int currentMsgId = ((MqttWireMessage) list.elementAt(i)).getMessageId(); - if (currentMsgId - previousMsgId > largestGap) { - largestGap = currentMsgId - previousMsgId; - largestGapMsgIdPosInList = i; - } - previousMsgId = currentMsgId; - } - int lowestMsgId = ((MqttWireMessage) list.elementAt(0)).getMessageId(); - int highestMsgId = previousMsgId; // last in the sorted list - - // we need to check that the gap after highest msg id to the lowest msg id is not beaten - if (MAX_MSG_ID - highestMsgId + lowestMsgId > largestGap) { - largestGapMsgIdPosInList = 0; - } - - // starting message has been located, let's start from this point on - for (int i = largestGapMsgIdPosInList; i < list.size(); i++) { - newList.addElement(list.elementAt(i)); - } - - // and any wrapping back to the beginning - for (int i = 0; i < largestGapMsgIdPosInList; i++) { - newList.addElement(list.elementAt(i)); - } - - return newList; - } - - /** - * Restores the state information from persistence. - * @throws MqttException if an exception occurs whilst restoring state - */ - protected void restoreState() throws MqttException { - final String methodName = "restoreState"; - Enumeration messageKeys = persistence.keys(); - MqttPersistable persistable; - String key; - int highestMsgId = nextMsgId; - Vector orphanedPubRels = new Vector(); - //@TRACE 600=> - log.fine(CLASS_NAME, methodName, "600"); - - while (messageKeys.hasMoreElements()) { - key = (String) messageKeys.nextElement(); - persistable = persistence.get(key); - MqttWireMessage message = restoreMessage(key, persistable); - if (message != null) { - if (key.startsWith(PERSISTENCE_RECEIVED_PREFIX)) { - //@TRACE 604=inbound QoS 2 publish key={0} message={1} - log.fine(CLASS_NAME,methodName,"604", new Object[]{key,message}); - - // The inbound messages that we have persisted will be QoS 2 - inboundQoS2.put(new Integer(message.getMessageId()),message); - } else if (key.startsWith(PERSISTENCE_SENT_PREFIX)) { - MqttPublish sendMessage = (MqttPublish) message; - highestMsgId = Math.max(sendMessage.getMessageId(), highestMsgId); - if (persistence.containsKey(getSendConfirmPersistenceKey(sendMessage))) { - MqttPersistable persistedConfirm = persistence.get(getSendConfirmPersistenceKey(sendMessage)); - // QoS 2, and CONFIRM has already been sent... - // NO DUP flag is allowed for 3.1.1 spec while it's not clear for 3.1 spec - // So we just remove DUP - MqttPubRel confirmMessage = (MqttPubRel) restoreMessage(key, persistedConfirm); - if (confirmMessage != null) { - // confirmMessage.setDuplicate(true); // REMOVED - //@TRACE 605=outbound QoS 2 pubrel key={0} message={1} - log.fine(CLASS_NAME,methodName, "605", new Object[]{key,message}); - - outboundQoS2.put(new Integer(confirmMessage.getMessageId()), confirmMessage); - } else { - //@TRACE 606=outbound QoS 2 completed key={0} message={1} - log.fine(CLASS_NAME,methodName, "606", new Object[]{key,message}); - } - } else { - // QoS 1 or 2, with no CONFIRM sent... - // Put the SEND to the list of pending messages, ensuring message ID ordering... - sendMessage.setDuplicate(true); - if (sendMessage.getMessage().getQos() == 2) { - //@TRACE 607=outbound QoS 2 publish key={0} message={1} - log.fine(CLASS_NAME,methodName, "607", new Object[]{key,message}); - - outboundQoS2.put(new Integer(sendMessage.getMessageId()),sendMessage); - } else { - //@TRACE 608=outbound QoS 1 publish key={0} message={1} - log.fine(CLASS_NAME,methodName, "608", new Object[]{key,message}); - - outboundQoS1.put(new Integer(sendMessage.getMessageId()),sendMessage); - } - } - MqttDeliveryToken tok = tokenStore.restoreToken(sendMessage); - tok.internalTok.setClient(clientComms.getClient()); - inUseMsgIds.put(new Integer(sendMessage.getMessageId()),new Integer(sendMessage.getMessageId())); - } else if(key.startsWith(PERSISTENCE_SENT_BUFFERED_PREFIX)){ - - // Buffered outgoing messages that have not yet been sent at all - MqttPublish sendMessage = (MqttPublish) message; - highestMsgId = Math.max(sendMessage.getMessageId(), highestMsgId); - if(sendMessage.getMessage().getQos() == 2){ - //@TRACE 607=outbound QoS 2 publish key={0} message={1} - log.fine(CLASS_NAME,methodName, "607", new Object[]{key,message}); - outboundQoS2.put(new Integer(sendMessage.getMessageId()),sendMessage); - } else if(sendMessage.getMessage().getQos() == 1){ - //@TRACE 608=outbound QoS 1 publish key={0} message={1} - log.fine(CLASS_NAME,methodName, "608", new Object[]{key,message}); - - outboundQoS1.put(new Integer(sendMessage.getMessageId()),sendMessage); - - } else { - //@TRACE 511=outbound QoS 0 publish key={0} message={1} - log.fine(CLASS_NAME,methodName, "511", new Object[]{key,message}); - outboundQoS0.put(new Integer(sendMessage.getMessageId()), sendMessage); - // Because there is no Puback, we have to trust that this is enough to send the message - persistence.remove(key); - - } - - MqttDeliveryToken tok = tokenStore.restoreToken(sendMessage); - tok.internalTok.setClient(clientComms.getClient()); - inUseMsgIds.put(new Integer(sendMessage.getMessageId()),new Integer(sendMessage.getMessageId())); - - - } else if (key.startsWith(PERSISTENCE_CONFIRMED_PREFIX)) { - MqttPubRel pubRelMessage = (MqttPubRel) message; - if (!persistence.containsKey(getSendPersistenceKey(pubRelMessage))) { - orphanedPubRels.addElement(key); - } - } - } - } - - messageKeys = orphanedPubRels.elements(); - while(messageKeys.hasMoreElements()) { - key = (String) messageKeys.nextElement(); - //@TRACE 609=removing orphaned pubrel key={0} - log.fine(CLASS_NAME,methodName, "609", new Object[]{key}); - - persistence.remove(key); - } - - nextMsgId = highestMsgId; - } - - private void restoreInflightMessages() { - final String methodName = "restoreInflightMessages"; - pendingMessages = new Vector(this.maxInflight); - pendingFlows = new Vector(); - - Enumeration keys = outboundQoS2.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - MqttWireMessage msg = (MqttWireMessage) outboundQoS2.get(key); - if (msg instanceof MqttPublish) { - //@TRACE 610=QoS 2 publish key={0} - log.fine(CLASS_NAME,methodName, "610", new Object[]{key}); - // set DUP flag only for PUBLISH, but NOT for PUBREL (spec 3.1.1) - msg.setDuplicate(true); - insertInOrder(pendingMessages, (MqttPublish)msg); - } else if (msg instanceof MqttPubRel) { - //@TRACE 611=QoS 2 pubrel key={0} - log.fine(CLASS_NAME,methodName, "611", new Object[]{key}); - - insertInOrder(pendingFlows, (MqttPubRel)msg); - } - } - keys = outboundQoS1.keys(); - while (keys.hasMoreElements()) { - Object key = keys.nextElement(); - MqttPublish msg = (MqttPublish)outboundQoS1.get(key); - msg.setDuplicate(true); - //@TRACE 612=QoS 1 publish key={0} - log.fine(CLASS_NAME,methodName, "612", new Object[]{key}); - - insertInOrder(pendingMessages, msg); - } - keys = outboundQoS0.keys(); - while(keys.hasMoreElements()){ - Object key = keys.nextElement(); - MqttPublish msg = (MqttPublish)outboundQoS0.get(key); - //@TRACE 512=QoS 0 publish key={0} - log.fine(CLASS_NAME,methodName, "512", new Object[]{key}); - insertInOrder(pendingMessages, msg); - - } - - this.pendingFlows = reOrder(pendingFlows); - this.pendingMessages = reOrder(pendingMessages); - } - - /** - * Submits a message for delivery. This method will block until there is - * room in the inFlightWindow for the message. The message is put into - * persistence before returning. - * - * @param message the message to send - * @param token the token that can be used to track delivery of the message - * @throws MqttException if an exception occurs whilst sending the message - */ - public void send(MqttWireMessage message, MqttToken token) throws MqttException { - final String methodName = "send"; - if (message.isMessageIdRequired() && (message.getMessageId() == 0)) { - if(message instanceof MqttPublish && (((MqttPublish) message).getMessage().getQos() != 0)){ - message.setMessageId(getNextMessageId()); - }else if(message instanceof MqttPubAck || - message instanceof MqttPubRec || - message instanceof MqttPubRel || - message instanceof MqttPubComp || - message instanceof MqttSubscribe || - message instanceof MqttSuback || - message instanceof MqttUnsubscribe || - message instanceof MqttUnsubAck){ - message.setMessageId(getNextMessageId()); - } - } - if (token != null ) { - try { - token.internalTok.setMessageID(message.getMessageId()); - } catch (Exception e) { - } - } - - if (message instanceof MqttPublish) { - synchronized (queueLock) { - if (actualInFlight >= this.maxInflight) { - //@TRACE 613= sending {0} msgs at max inflight window - log.fine(CLASS_NAME, methodName, "613", new Object[]{new Integer(actualInFlight)}); - - throw new MqttException(MqttException.REASON_CODE_MAX_INFLIGHT); - } - - MqttMessage innerMessage = ((MqttPublish) message).getMessage(); - //@TRACE 628=pending publish key={0} qos={1} message={2} - log.fine(CLASS_NAME,methodName,"628", new Object[]{new Integer(message.getMessageId()), new Integer(innerMessage.getQos()), message}); - - switch(innerMessage.getQos()) { - case 2: - outboundQoS2.put(new Integer(message.getMessageId()), message); - persistence.put(getSendPersistenceKey(message), (MqttPublish) message); - break; - case 1: - outboundQoS1.put(new Integer(message.getMessageId()), message); - persistence.put(getSendPersistenceKey(message), (MqttPublish) message); - break; - } - tokenStore.saveToken(token, message); - pendingMessages.addElement(message); - queueLock.notifyAll(); - } - } else { - //@TRACE 615=pending send key={0} message {1} - log.fine(CLASS_NAME,methodName,"615", new Object[]{new Integer(message.getMessageId()), message}); - - if (message instanceof MqttConnect) { - synchronized (queueLock) { - // Add the connect action at the head of the pending queue ensuring it jumps - // ahead of any of other pending actions. - tokenStore.saveToken(token, message); - pendingFlows.insertElementAt(message,0); - queueLock.notifyAll(); - } - } else { - if (message instanceof MqttPingReq) { - this.pingCommand = message; - } - else if (message instanceof MqttPubRel) { - outboundQoS2.put(new Integer(message.getMessageId()), message); - persistence.put(getSendConfirmPersistenceKey(message), (MqttPubRel) message); - } - else if (message instanceof MqttPubComp) { - persistence.remove(getReceivedPersistenceKey(message)); - } - - synchronized (queueLock) { - if ( !(message instanceof MqttAck )) { - tokenStore.saveToken(token, message); - } - pendingFlows.addElement(message); - queueLock.notifyAll(); - } - } - } - } - - /** - * Persists a buffered message to the persistence layer - * - * @param message The {@link MqttWireMessage} to persist - */ - public void persistBufferedMessage(MqttWireMessage message) { - final String methodName = "persistBufferedMessage"; - String key = getSendBufferedPersistenceKey(message); - - // Because the client will have disconnected, we will want to re-open persistence - try { - message.setMessageId(getNextMessageId()); - key = getSendBufferedPersistenceKey(message); - try { - persistence.put(key, (MqttPublish) message); - } catch (MqttPersistenceException mpe){ - //@TRACE 515=Could not Persist, attempting to Re-Open Persistence Store - log.fine(CLASS_NAME,methodName, "515"); - persistence.open(this.clientComms.getClient().getClientId(), this.clientComms.getClient().getServerURI()); - persistence.put(key, (MqttPublish) message); - } - //@TRACE 513=Persisted Buffered Message key={0} - log.fine(CLASS_NAME,methodName, "513", new Object[]{key}); - } catch (MqttException ex){ - //@TRACE 514=Failed to persist buffered message key={0} - log.warning(CLASS_NAME,methodName, "513", new Object[]{key}); - } - } - - /** - * @param message The {@link MqttWireMessage} to un-persist - */ - public void unPersistBufferedMessage(MqttWireMessage message){ - final String methodName = "unPersistBufferedMessage"; - try{ - //@TRACE 517=Un-Persisting Buffered message key={0} - log.fine(CLASS_NAME,methodName, "517", new Object[]{message.getKey()}); - persistence.remove(getSendBufferedPersistenceKey(message)); - } catch (MqttPersistenceException mpe){ - //@TRACE 518=Failed to Un-Persist Buffered message key={0} - log.fine(CLASS_NAME,methodName, "518", new Object[]{message.getKey()}); - } - - } - - /** - * This removes the MqttSend message from the outbound queue and persistence. - * @param message the {@link MqttPublish} message to be removed - * @throws MqttPersistenceException if an exception occurs whilst removing the message - */ - protected void undo(MqttPublish message) throws MqttPersistenceException { - final String methodName = "undo"; - synchronized (queueLock) { - //@TRACE 618=key={0} QoS={1} - log.fine(CLASS_NAME,methodName,"618", new Object[]{new Integer(message.getMessageId()), new Integer(message.getMessage().getQos())}); - - if (message.getMessage().getQos() == 1) { - outboundQoS1.remove(new Integer(message.getMessageId())); - } else { - outboundQoS2.remove(new Integer(message.getMessageId())); - } - pendingMessages.removeElement(message); - persistence.remove(getSendPersistenceKey(message)); - tokenStore.removeToken(message); - if(message.getMessage().getQos() > 0){ - //Free this message Id so it can be used again - releaseMessageId(message.getMessageId()); - //Set the messageId to 0 so if it's ever retried, it will get a new messageId - message.setMessageId(0); - } - - checkQuiesceLock(); - } - } - - /** - * Check and send a ping if needed and check for ping timeout. - * Need to send a ping if nothing has been sent or received - * in the last keepalive interval. It is important to check for - * both sent and received packets in order to catch the case where an - * app is solely sending QoS 0 messages or receiving QoS 0 messages. - * QoS 0 message are not good enough for checking a connection is - * alive as they are one way messages. - * - * If a ping has been sent but no data has been received in the - * last keepalive interval then the connection is deamed to be broken. - * @param pingCallback The {@link IMqttActionListener} to be called - * @return token of ping command, null if no ping command has been sent. - * @throws MqttException if an exception occurs during the Ping - */ - public MqttToken checkForActivity(IMqttActionListener pingCallback) throws MqttException { - final String methodName = "checkForActivity"; - //@TRACE 616=checkForActivity entered - log.fine(CLASS_NAME,methodName,"616", new Object[]{}); - - synchronized (quiesceLock) { - // ref bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=440698 - // No ping while quiescing - if (quiescing) { - return null; - } - } - - MqttToken token = null; - long nextPingTime = getKeepAlive(); - - if (connected && this.keepAlive > 0) { - long time = System.currentTimeMillis(); - //Reduce schedule frequency since System.currentTimeMillis is no accurate, add a buffer - //It is 1/10 in minimum keepalive unit. - int delta = 100; - - // ref bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=446663 - synchronized (pingOutstandingLock) { - - // Is the broker connection lost because the broker did not reply to my ping? - if (pingOutstanding > 0 && (time - lastInboundActivity >= keepAlive + delta)) { - // lastInboundActivity will be updated once receiving is done. - // Add a delta, since the timer and System.currentTimeMillis() is not accurate. - // A ping is outstanding but no packet has been received in KA so connection is deemed broken - //@TRACE 619=Timed out as no activity, keepAlive={0} lastOutboundActivity={1} lastInboundActivity={2} time={3} lastPing={4} - log.severe(CLASS_NAME,methodName,"619", new Object[]{new Long(this.keepAlive),new Long(lastOutboundActivity),new Long(lastInboundActivity), new Long(time), new Long(lastPing)}); - - // A ping has already been sent. At this point, assume that the - // broker has hung and the TCP layer hasn't noticed. - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_CLIENT_TIMEOUT); - } - - // Is the broker connection lost because I could not get any successful write for 2 keepAlive intervals? - if (pingOutstanding == 0 && (time - lastOutboundActivity >= 2*keepAlive)) { - - // I am probably blocked on a write operations as I should have been able to write at least a ping message - log.severe(CLASS_NAME,methodName,"642", new Object[]{new Long(this.keepAlive),new Long(lastOutboundActivity),new Long(lastInboundActivity), new Long(time), new Long(lastPing)}); - - // A ping has not been sent but I am not progressing on the current write operation. - // At this point, assume that the broker has hung and the TCP layer hasn't noticed. - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_WRITE_TIMEOUT); - } - - // 1. Is a ping required by the client to verify whether the broker is down? - // Condition: ((pingOutstanding == 0 && (time - lastInboundActivity >= keepAlive + delta))) - // In this case only one ping is sent. If not confirmed, client will assume a lost connection to the broker. - // 2. Is a ping required by the broker to keep the client alive? - // Condition: (time - lastOutboundActivity >= keepAlive - delta) - // In this case more than one ping outstanding may be necessary. - // This would be the case when receiving a large message; - // the broker needs to keep receiving a regular ping even if the ping response are queued after the long message - // If lacking to do so, the broker will consider my connection lost and cut my socket. - if ((pingOutstanding == 0 && (time - lastInboundActivity >= keepAlive - delta)) || - (time - lastOutboundActivity >= keepAlive - delta)) { - - //@TRACE 620=ping needed. keepAlive={0} lastOutboundActivity={1} lastInboundActivity={2} - log.fine(CLASS_NAME,methodName,"620", new Object[]{new Long(this.keepAlive),new Long(lastOutboundActivity),new Long(lastInboundActivity)}); - - // pingOutstanding++; // it will be set after the ping has been written on the wire - // lastPing = time; // it will be set after the ping has been written on the wire - token = new MqttToken(clientComms.getClient().getClientId()); - if(pingCallback != null){ - token.setActionCallback(pingCallback); - } - tokenStore.saveToken(token, pingCommand); - pendingFlows.insertElementAt(pingCommand, 0); - - nextPingTime = getKeepAlive(); - - //Wake sender thread since it may be in wait state (in ClientState.get()) - notifyQueueLock(); - } - else { - log.fine(CLASS_NAME, methodName, "634", null); - nextPingTime = Math.max(1, getKeepAlive() - (time - lastOutboundActivity)); - } - } - //@TRACE 624=Schedule next ping at {0} - log.fine(CLASS_NAME, methodName,"624", new Object[]{new Long(nextPingTime)}); - pingSender.schedule(nextPingTime); - } - - return token; - } - - /** - * This returns the next piece of work, ie message, for the CommsSender - * to send over the network. - * Calls to this method block until either: - * - there is a message to be sent - * - the keepAlive interval is exceeded, which triggers a ping message - * to be returned - * - {@link ClientState#disconnected(MqttException)} is called - * @return the next message to send, or null if the client is disconnected - * @throws MqttException if an exception occurs whilst returning the next piece of work - */ - protected MqttWireMessage get() throws MqttException { - final String methodName = "get"; - MqttWireMessage result = null; - - synchronized (queueLock) { - while (result == null) { - - // If there is no work wait until there is work. - // If the inflight window is full and no flows are pending wait until space is freed. - // In both cases queueLock will be notified. - if ((pendingMessages.isEmpty() && pendingFlows.isEmpty()) || - (pendingFlows.isEmpty() && actualInFlight >= this.maxInflight)) { - try { - //@TRACE 644=wait for new work or for space in the inflight window - log.fine(CLASS_NAME,methodName, "644"); - - queueLock.wait(); - - //@TRACE 647=new work or ping arrived - log.fine(CLASS_NAME,methodName, "647"); - } catch (InterruptedException e) { - } - } - - // Handle the case where not connected. This should only be the case if: - // - in the process of disconnecting / shutting down - // - in the process of connecting - if (!connected && - (pendingFlows.isEmpty() || !((MqttWireMessage)pendingFlows.elementAt(0) instanceof MqttConnect))) { - //@TRACE 621=no outstanding flows and not connected - log.fine(CLASS_NAME,methodName,"621"); - - return null; - } - - // Check if there is a need to send a ping to keep the session alive. - // Note this check is done before processing messages. If not done first - // an app that only publishes QoS 0 messages will prevent keepalive processing - // from functioning. -// checkForActivity(); //Use pinger, don't check here - - // Now process any queued flows or messages - if (!pendingFlows.isEmpty()) { - // Process the first "flow" in the queue - result = (MqttWireMessage)pendingFlows.remove(0); - if (result instanceof MqttPubRel) { - inFlightPubRels++; - - //@TRACE 617=+1 inflightpubrels={0} - log.fine(CLASS_NAME,methodName,"617", new Object[]{new Integer(inFlightPubRels)}); - } - - checkQuiesceLock(); - } else if (!pendingMessages.isEmpty()) { - - // If the inflight window is full then messages are not - // processed until the inflight window has space. - if (actualInFlight < this.maxInflight) { - // The in flight window is not full so process the - // first message in the queue - result = (MqttWireMessage)pendingMessages.elementAt(0); - pendingMessages.removeElementAt(0); - actualInFlight++; - - //@TRACE 623=+1 actualInFlight={0} - log.fine(CLASS_NAME,methodName,"623",new Object[]{new Integer(actualInFlight)}); - } else { - //@TRACE 622=inflight window full - log.fine(CLASS_NAME,methodName,"622"); - } - } - } - } - return result; - } - - public void setKeepAliveInterval(long interval) { - this.keepAlive = interval; - } - - public void notifySentBytes(int sentBytesCount) { - final String methodName = "notifySentBytes"; - if (sentBytesCount > 0) { - this.lastOutboundActivity = System.currentTimeMillis(); - } - // @TRACE 643=sent bytes count={0} - log.fine(CLASS_NAME, methodName, "643", new Object[] { - new Integer(sentBytesCount) }); - } - - - /** - * Called by the CommsSender when a message has been sent - * @param message the {@link MqttWireMessage} to notify - */ - protected void notifySent(MqttWireMessage message) { - final String methodName = "notifySent"; - - this.lastOutboundActivity = System.currentTimeMillis(); - //@TRACE 625=key={0} - log.fine(CLASS_NAME,methodName,"625",new Object[]{message.getKey()}); - - MqttToken token = tokenStore.getToken(message); - token.internalTok.notifySent(); - if (message instanceof MqttPingReq) { - synchronized (pingOutstandingLock) { - long time = System.currentTimeMillis(); - synchronized (pingOutstandingLock) { - lastPing = time; - pingOutstanding++; - } - //@TRACE 635=ping sent. pingOutstanding: {0} - log.fine(CLASS_NAME,methodName,"635",new Object[]{ new Integer(pingOutstanding)}); - } - } - else if (message instanceof MqttPublish) { - if (((MqttPublish)message).getMessage().getQos() == 0) { - // once a QoS 0 message is sent we can clean up its records straight away as - // we won't be hearing about it again - token.internalTok.markComplete(null, null); - callback.asyncOperationComplete(token); - decrementInFlight(); - releaseMessageId(message.getMessageId()); - tokenStore.removeToken(message); - checkQuiesceLock(); - } - } - } - - private void decrementInFlight() { - final String methodName = "decrementInFlight"; - synchronized (queueLock) { - actualInFlight--; - //@TRACE 646=-1 actualInFlight={0} - log.fine(CLASS_NAME,methodName,"646",new Object[]{new Integer(actualInFlight)}); - - if (!checkQuiesceLock()) { - queueLock.notifyAll(); - } - } - } - - protected boolean checkQuiesceLock() { - final String methodName = "checkQuiesceLock"; -// if (quiescing && actualInFlight == 0 && pendingFlows.size() == 0 && inFlightPubRels == 0 && callback.isQuiesced()) { - int tokC = tokenStore.count(); - if (quiescing && tokC == 0 && pendingFlows.size() == 0 && callback.isQuiesced()) { - //@TRACE 626=quiescing={0} actualInFlight={1} pendingFlows={2} inFlightPubRels={3} callbackQuiesce={4} tokens={5} - log.fine(CLASS_NAME,methodName,"626",new Object[]{new Boolean(quiescing), new Integer(actualInFlight), new Integer(pendingFlows.size()), new Integer(inFlightPubRels), Boolean.valueOf(callback.isQuiesced()), new Integer(tokC)}); - synchronized (quiesceLock) { - quiesceLock.notifyAll(); - } - return true; - } - return false; - } - - public void notifyReceivedBytes(int receivedBytesCount) { - final String methodName = "notifyReceivedBytes"; - if (receivedBytesCount > 0) { - this.lastInboundActivity = System.currentTimeMillis(); - } - // @TRACE 630=received bytes count={0} - log.fine(CLASS_NAME, methodName, "630", new Object[] { - new Integer(receivedBytesCount) }); - } - - /** - * Called by the CommsReceiver when an ack has arrived. - * - * @param ack The {@link MqttAck} that has arrived - * @throws MqttException if an exception occurs when sending / notifying - */ - protected void notifyReceivedAck(MqttAck ack) throws MqttException { - final String methodName = "notifyReceivedAck"; - this.lastInboundActivity = System.currentTimeMillis(); - - // @TRACE 627=received key={0} message={1} - log.fine(CLASS_NAME, methodName, "627", new Object[] { - new Integer(ack.getMessageId()), ack }); - - MqttToken token = tokenStore.getToken(ack); - MqttException mex = null; - - if (token == null) { - // @TRACE 662=no message found for ack id={0} - log.fine(CLASS_NAME, methodName, "662", new Object[] { - new Integer(ack.getMessageId())}); - } else if (ack instanceof MqttPubRec) { - // Complete the QoS 2 flow. Unlike all other - // flows, QoS is a 2 phase flow. The second phase sends a - // PUBREL - the operation is not complete until a PUBCOMP - // is received - MqttPubRel rel = new MqttPubRel((MqttPubRec) ack); - this.send(rel, token); - } else if (ack instanceof MqttPubAck || ack instanceof MqttPubComp) { - // QoS 1 & 2 notify users of result before removing from - // persistence - notifyResult(ack, token, mex); - // Do not remove publish / delivery token at this stage - // do this when the persistence is removed later - } else if (ack instanceof MqttPingResp) { - synchronized (pingOutstandingLock) { - pingOutstanding = Math.max(0, pingOutstanding-1); - notifyResult(ack, token, mex); - if (pingOutstanding == 0) { - tokenStore.removeToken(ack); - } - } - //@TRACE 636=ping response received. pingOutstanding: {0} - log.fine(CLASS_NAME,methodName,"636",new Object[]{ new Integer(pingOutstanding)}); - } else if (ack instanceof MqttConnack) { - int rc = ((MqttConnack) ack).getReturnCode(); - if (rc == 0) { - synchronized (queueLock) { - if (cleanSession) { - clearState(); - // Add the connect token back in so that users can be - // notified when connect completes. - tokenStore.saveToken(token,ack); - } - inFlightPubRels = 0; - actualInFlight = 0; - restoreInflightMessages(); - connected(); - } - } else { - mex = ExceptionHelper.createMqttException(rc); - throw mex; - } - - clientComms.connectComplete((MqttConnack) ack, mex); - notifyResult(ack, token, mex); - tokenStore.removeToken(ack); - - // Notify the sender thread that there maybe work for it to do now - synchronized (queueLock) { - queueLock.notifyAll(); - } - } else { - notifyResult(ack, token, mex); - releaseMessageId(ack.getMessageId()); - tokenStore.removeToken(ack); - } - - checkQuiesceLock(); - } - - /** - * Called by the CommsReceiver when a message has been received. - * Handles inbound messages and other flows such as PUBREL. - * - * @param message The {@link MqttWireMessage} that has been received - * @throws MqttException when an exception occurs whilst notifying - */ - protected void notifyReceivedMsg(MqttWireMessage message) throws MqttException { - final String methodName = "notifyReceivedMsg"; - this.lastInboundActivity = System.currentTimeMillis(); - - // @TRACE 651=received key={0} message={1} - log.fine(CLASS_NAME, methodName, "651", new Object[] { - new Integer(message.getMessageId()), message }); - - if (!quiescing) { - if (message instanceof MqttPublish) { - MqttPublish send = (MqttPublish) message; - switch (send.getMessage().getQos()) { - case 0: - case 1: - if (callback != null) { - callback.messageArrived(send); - } - break; - case 2: - persistence.put(getReceivedPersistenceKey(message), - (MqttPublish) message); - inboundQoS2.put(new Integer(send.getMessageId()), send); - this.send(new MqttPubRec(send), null); - break; - - default: - //should NOT reach here - } - } else if (message instanceof MqttPubRel) { - MqttPublish sendMsg = (MqttPublish) inboundQoS2 - .get(new Integer(message.getMessageId())); - if (sendMsg != null) { - if (callback != null) { - callback.messageArrived(sendMsg); - } - } else { - // Original publish has already been delivered. - MqttPubComp pubComp = new MqttPubComp(message - .getMessageId()); - this.send(pubComp, null); - } - } - } - } - - - /** - * Called when waiters and callbacks have processed the message. For - * messages where delivery is complete the message can be removed from - * persistence and counters adjusted accordingly. Also tidy up by removing - * token from store... - * - * @param token The {@link MqttToken} that will be used to notify - * @throws MqttException if an exception occurs during notification - */ - protected void notifyComplete(MqttToken token) throws MqttException { - - final String methodName = "notifyComplete"; - - MqttWireMessage message = token.internalTok.getWireMessage(); - - if (message != null && message instanceof MqttAck) { - - // @TRACE 629=received key={0} token={1} message={2} - log.fine(CLASS_NAME, methodName, "629", new Object[] { - new Integer(message.getMessageId()), token, message }); - - MqttAck ack = (MqttAck) message; - - if (ack instanceof MqttPubAck) { - - // QoS 1 - user notified now remove from persistence... - persistence.remove(getSendPersistenceKey(message)); - persistence.remove(getSendBufferedPersistenceKey(message)); - outboundQoS1.remove(new Integer(ack.getMessageId())); - decrementInFlight(); - releaseMessageId(message.getMessageId()); - tokenStore.removeToken(message); - // @TRACE 650=removed Qos 1 publish. key={0} - log.fine(CLASS_NAME, methodName, "650", - new Object[] { new Integer(ack.getMessageId()) }); - } else if (ack instanceof MqttPubComp) { - // QoS 2 - user notified now remove from persistence... - persistence.remove(getSendPersistenceKey(message)); - persistence.remove(getSendConfirmPersistenceKey(message)); - persistence.remove(getSendBufferedPersistenceKey(message)); - outboundQoS2.remove(new Integer(ack.getMessageId())); - - inFlightPubRels--; - decrementInFlight(); - releaseMessageId(message.getMessageId()); - tokenStore.removeToken(message); - - // @TRACE 645=removed QoS 2 publish/pubrel. key={0}, -1 inFlightPubRels={1} - log.fine(CLASS_NAME, methodName, "645", new Object[] { - new Integer(ack.getMessageId()), - new Integer(inFlightPubRels) }); - } - - checkQuiesceLock(); - } - } - - protected void notifyResult(MqttWireMessage ack, MqttToken token, MqttException ex) { - final String methodName = "notifyResult"; - // unblock any threads waiting on the token - token.internalTok.markComplete(ack, ex); - token.internalTok.notifyComplete(); - - // Let the user know an async operation has completed and then remove the token - if (ack != null && ack instanceof MqttAck && !(ack instanceof MqttPubRec)) { - //@TRACE 648=key{0}, msg={1}, excep={2} - log.fine(CLASS_NAME,methodName, "648", new Object [] {token.internalTok.getKey(), ack, ex}); - callback.asyncOperationComplete(token); - } - // There are cases where there is no ack as the operation failed before - // an ack was received - if (ack == null ) { - //@TRACE 649=key={0},excep={1} - log.fine(CLASS_NAME,methodName, "649", new Object [] { token.internalTok.getKey(), ex}); - callback.asyncOperationComplete(token); - } - } - - /** - * Called when the client has successfully connected to the broker - */ - public void connected() { - final String methodName = "connected"; - //@TRACE 631=connected - log.fine(CLASS_NAME, methodName, "631"); - this.connected = true; - - pingSender.start(); //Start ping thread when client connected to server. - } - - /** - * Called during shutdown to work out if there are any tokens still - * to be notified and waiters to be unblocked. Notifying and unblocking - * takes place after most shutdown processing has completed. The tokenstore - * is tidied up so it only contains outstanding delivery tokens which are - * valid after reconnect (if clean session is false) - * @param reason The root cause of the disconnection, or null if it is a clean disconnect - * @return {@link Vector} - */ - public Vector resolveOldTokens(MqttException reason) { - final String methodName = "resolveOldTokens"; - //@TRACE 632=reason {0} - log.fine(CLASS_NAME,methodName,"632", new Object[] {reason}); - - // If any outstanding let the user know the reason why it is still - // outstanding by putting the reason shutdown is occurring into the - // token. - MqttException shutReason = reason; - if (reason == null) { - shutReason = new MqttException(MqttException.REASON_CODE_CLIENT_DISCONNECTING); - } - - // Set the token up so it is ready to be notified after disconnect - // processing has completed. Do not - // remove the token from the store if it is a delivery token, it is - // valid after a reconnect. - Vector outT = tokenStore.getOutstandingTokens(); - Enumeration outTE = outT.elements(); - while (outTE.hasMoreElements()) { - MqttToken tok = (MqttToken)outTE.nextElement(); - synchronized (tok) { - if (!tok.isComplete() && !tok.internalTok.isCompletePending() && tok.getException() == null) { - tok.internalTok.setException(shutReason); - } - } - if (!(tok instanceof MqttDeliveryToken)) { - // If not a delivery token it is not valid on - // restart so remove - tokenStore.removeToken(tok.internalTok.getKey()); - } - } - return outT; - } - - /** - * Called when the client has been disconnected from the broker. - * @param reason The root cause of the disconnection, or null if it is a clean disconnect - */ - public void disconnected(MqttException reason) { - final String methodName = "disconnected"; - //@TRACE 633=disconnected - log.fine(CLASS_NAME,methodName,"633", new Object[] {reason}); - - this.connected = false; - - try { - if (cleanSession) { - clearState(); - } - - pendingMessages.clear(); - pendingFlows.clear(); - synchronized (pingOutstandingLock) { - // Reset pingOutstanding to allow reconnects to assume no previous ping. - pingOutstanding = 0; - } - } catch (MqttException e) { - // Ignore as we have disconnected at this point - } - } - - /** - * Releases a message ID back into the pool of available message IDs. - * If the supplied message ID is not in use, then nothing will happen. - * - * @param msgId A message ID that can be freed up for re-use. - */ - private synchronized void releaseMessageId(int msgId) { - inUseMsgIds.remove(new Integer(msgId)); - } - - /** - * Get the next MQTT message ID that is not already in use, and marks - * it as now being in use. - * - * @return the next MQTT message ID to use - */ - private synchronized int getNextMessageId() throws MqttException { - int startingMessageId = nextMsgId; - // Allow two complete passes of the message ID range. This gives - // any asynchronous releases a chance to occur - int loopCount = 0; - do { - nextMsgId++; - if ( nextMsgId > MAX_MSG_ID ) { - nextMsgId = MIN_MSG_ID; - } - if (nextMsgId == startingMessageId) { - loopCount++; - if (loopCount == 2) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_NO_MESSAGE_IDS_AVAILABLE); - } - } - } while( inUseMsgIds.containsKey( new Integer(nextMsgId) ) ); - Integer id = new Integer(nextMsgId); - inUseMsgIds.put(id, id); - return nextMsgId; - } - - /** - * Quiesce the client state, preventing any new messages getting sent, - * and preventing the callback on any newly received messages. - * After the timeout expires, delete any pending messages except for - * outbound ACKs, and wait for those ACKs to complete. - * @param timeout How long to wait during Quiescing - */ - public void quiesce(long timeout) { - final String methodName = "quiesce"; - // If the timeout is greater than zero t - if (timeout > 0 ) { - //@TRACE 637=timeout={0} - log.fine(CLASS_NAME,methodName, "637",new Object[]{new Long(timeout)}); - synchronized (queueLock) { - this.quiescing = true; - } - // We don't want to handle any new inbound messages - callback.quiesce(); - notifyQueueLock(); - - synchronized (quiesceLock) { - try { - // If token count is not zero there is outbound work to process and - // if pending flows is not zero there is outstanding work to complete and - // if call back is not quiseced there it needs to complete. - int tokc = tokenStore.count(); - if (tokc > 0 || pendingFlows.size() >0 || !callback.isQuiesced()) { - //@TRACE 639=wait for outstanding: actualInFlight={0} pendingFlows={1} inFlightPubRels={2} tokens={3} - log.fine(CLASS_NAME, methodName,"639", new Object[]{new Integer(actualInFlight), new Integer(pendingFlows.size()), new Integer(inFlightPubRels), new Integer(tokc)}); - - // wait for outstanding in flight messages to complete and - // any pending flows to complete - quiesceLock.wait(timeout); - } - } - catch (InterruptedException ex) { - // Don't care, as we're shutting down anyway - } - } - - // Quiesce time up or inflight messages delivered. Ensure pending delivery - // vectors are cleared ready for disconnect to be sent as the final flow. - synchronized (queueLock) { - pendingMessages.clear(); - pendingFlows.clear(); - quiescing = false; - actualInFlight = 0; - } - //@TRACE 640=finished - log.fine(CLASS_NAME, methodName, "640"); - } - } - - public void notifyQueueLock() { - final String methodName = "notifyQueueLock"; - synchronized (queueLock) { - //@TRACE 638=notifying queueLock holders - log.fine(CLASS_NAME,methodName,"638"); - queueLock.notifyAll(); - } - } - - protected void deliveryComplete(MqttPublish message) throws MqttPersistenceException { - final String methodName = "deliveryComplete"; - - //@TRACE 641=remove publish from persistence. key={0} - log.fine(CLASS_NAME,methodName,"641", new Object[]{new Integer(message.getMessageId())}); - - persistence.remove(getReceivedPersistenceKey(message)); - inboundQoS2.remove(new Integer(message.getMessageId())); - } - - protected void deliveryComplete(int messageId) throws MqttPersistenceException { - final String methodName = "deliveryComplete"; - - //@TRACE 641=remove publish from persistence. key={0} - log.fine(CLASS_NAME,methodName,"641", new Object[]{new Integer(messageId)}); - - persistence.remove(getReceivedPersistenceKey(messageId)); - inboundQoS2.remove(new Integer(messageId)); - } - - public int getActualInFlight(){ - return actualInFlight; - } - - public int getMaxInFlight(){ - return maxInflight; - } - - /** - * Tidy up - * - ensure that tokens are released as they are maintained over a - * disconnect / connect cycle. - */ - protected void close() { - inUseMsgIds.clear(); - if (pendingMessages != null) { - pendingMessages.clear(); - } - pendingFlows.clear(); - outboundQoS2.clear(); - outboundQoS1.clear(); - outboundQoS0.clear(); - inboundQoS2.clear(); - tokenStore.clear(); - inUseMsgIds = null; - pendingMessages = null; - pendingFlows = null; - outboundQoS2 = null; - outboundQoS1 = null; - outboundQoS0 = null; - inboundQoS2 = null; - tokenStore = null; - callback = null; - clientComms = null; - persistence = null; - pingCommand = null; - } - - public Properties getDebug() { - Properties props = new Properties(); - props.put("In use msgids", inUseMsgIds); - props.put("pendingMessages", pendingMessages); - props.put("pendingFlows", pendingFlows); - props.put("maxInflight", new Integer(maxInflight)); - props.put("nextMsgID", new Integer(nextMsgId)); - props.put("actualInFlight", new Integer(actualInFlight)); - props.put("inFlightPubRels", new Integer(inFlightPubRels)); - props.put("quiescing", Boolean.valueOf(quiescing)); - props.put("pingoutstanding", new Integer(pingOutstanding)); - props.put("lastOutboundActivity", new Long(lastOutboundActivity)); - props.put("lastInboundActivity", new Long(lastInboundActivity)); - props.put("outboundQoS2", outboundQoS2); - props.put("outboundQoS1", outboundQoS1); - props.put("outboundQoS0", outboundQoS0); - props.put("inboundQoS2", inboundQoS2); - props.put("tokens", tokenStore); - return props; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsCallback.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsCallback.java deleted file mode 100644 index bb6d77c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsCallback.java +++ /dev/null @@ -1,506 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - per subscription message handlers (bug 466579) - * Ian Craggs - ack control (bug 472172) - * James Sutton - Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; - -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.IMqttMessageListener; -import org.eclipse.paho.client.mqttv3.MqttCallback; -import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; -import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.MqttTopic; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubComp; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Bridge between Receiver and the external API. This class gets called by - * Receiver, and then converts the comms-centric MQTT message objects into ones - * understood by the external API. - */ -public class CommsCallback implements Runnable { - private static final String CLASS_NAME = CommsCallback.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private static final int INBOUND_QUEUE_SIZE = 10; - private MqttCallback mqttCallback; - private MqttCallbackExtended reconnectInternalCallback; - private Hashtable callbacks; // topicFilter -> messageHandler - private ClientComms clientComms; - private Vector messageQueue; - private Vector completeQueue; - public boolean running = false; - private boolean quiescing = false; - private Object lifecycle = new Object(); - private Thread callbackThread; - private Object workAvailable = new Object(); - private Object spaceAvailable = new Object(); - private ClientState clientState; - private boolean manualAcks = false; - private String threadName; - private final Semaphore runningSemaphore = new Semaphore(1); - private Future callbackFuture; - - CommsCallback(ClientComms clientComms) { - this.clientComms = clientComms; - this.messageQueue = new Vector(INBOUND_QUEUE_SIZE); - this.completeQueue = new Vector(INBOUND_QUEUE_SIZE); - this.callbacks = new Hashtable(); - log.setResourceName(clientComms.getClient().getClientId()); - } - - public void setClientState(ClientState clientState) { - this.clientState = clientState; - } - - /** - * Starts up the Callback thread. - * @param threadName The name of the thread - * @param executorService the {@link ExecutorService} - */ - public void start(String threadName, ExecutorService executorService) { - this.threadName = threadName; - synchronized (lifecycle) { - if (!running) { - // Preparatory work before starting the background thread. - // For safety ensure any old events are cleared. - messageQueue.clear(); - completeQueue.clear(); - - running = true; - quiescing = false; - callbackFuture = executorService.submit(this); - } - } - } - - /** - * Stops the callback thread. - * This call will block until stop has completed. - */ - public void stop() { - final String methodName = "stop"; - synchronized (lifecycle) { - if (callbackFuture != null) { - callbackFuture.cancel(true); - } - if (running) { - // @TRACE 700=stopping - log.fine(CLASS_NAME, methodName, "700"); - running = false; - if (!Thread.currentThread().equals(callbackThread)) { - try { - synchronized (workAvailable) { - // @TRACE 701=notify workAvailable and wait for run - // to finish - log.fine(CLASS_NAME, methodName, "701"); - workAvailable.notifyAll(); - } - // Wait for the thread to finish. - runningSemaphore.acquire(); - } catch (InterruptedException ex) { - } finally { - runningSemaphore.release(); - } - } - } - callbackThread = null; - // @TRACE 703=stopped - log.fine(CLASS_NAME, methodName, "703"); - } - } - - public void setCallback(MqttCallback mqttCallback) { - this.mqttCallback = mqttCallback; - } - - public void setReconnectCallback(MqttCallbackExtended callback){ - this.reconnectInternalCallback = callback; - } - - public void setManualAcks(boolean manualAcks) { - this.manualAcks = manualAcks; - } - - public void run() { - final String methodName = "run"; - callbackThread = Thread.currentThread(); - callbackThread.setName(threadName); - - try { - runningSemaphore.acquire(); - } catch (InterruptedException e) { - running = false; - return; - } - - while (running) { - try { - // If no work is currently available, then wait until there is some... - try { - synchronized (workAvailable) { - if (running && messageQueue.isEmpty() - && completeQueue.isEmpty()) { - // @TRACE 704=wait for workAvailable - log.fine(CLASS_NAME, methodName, "704"); - workAvailable.wait(); - } - } - } catch (InterruptedException e) { - } - - if (running) { - // Check for deliveryComplete callbacks... - MqttToken token = null; - synchronized (completeQueue) { - if (!completeQueue.isEmpty()) { - // First call the delivery arrived callback if needed - token = (MqttToken) completeQueue.elementAt(0); - completeQueue.removeElementAt(0); - } - } - if (null != token) { - handleActionComplete(token); - } - - // Check for messageArrived callbacks... - MqttPublish message = null; - synchronized (messageQueue) { - if (!messageQueue.isEmpty()) { - // Note, there is a window on connect where a publish - // could arrive before we've - // finished the connect logic. - message = (MqttPublish) messageQueue.elementAt(0); - - messageQueue.removeElementAt(0); - } - } - if (null != message) { - handleMessage(message); - } - } - - if (quiescing) { - clientState.checkQuiesceLock(); - } - - } catch (Throwable ex) { - // Users code could throw an Error or Exception e.g. in the case - // of class NoClassDefFoundError - // @TRACE 714=callback threw exception - log.fine(CLASS_NAME, methodName, "714", null, ex); - running = false; - clientComms.shutdownConnection(null, new MqttException(ex)); - } finally { - runningSemaphore.release(); - synchronized (spaceAvailable) { - // Notify the spaceAvailable lock, to say that there's now - // some space on the queue... - - // @TRACE 706=notify spaceAvailable - log.fine(CLASS_NAME, methodName, "706"); - spaceAvailable.notifyAll(); - } - } - } - } - - private void handleActionComplete(MqttToken token) - throws MqttException { - final String methodName = "handleActionComplete"; - synchronized (token) { - // @TRACE 705=callback and notify for key={0} - log.fine(CLASS_NAME, methodName, "705", new Object[] { token.internalTok.getKey() }); - if (token.isComplete()) { - // Finish by doing any post processing such as delete - // from persistent store but only do so if the action - // is complete - clientState.notifyComplete(token); - } - - // Unblock any waiters and if pending complete now set completed - token.internalTok.notifyComplete(); - - if (!token.internalTok.isNotified()) { - // If a callback is registered and delivery has finished - // call delivery complete callback. - if ( mqttCallback != null - && token instanceof MqttDeliveryToken - && token.isComplete()) { - mqttCallback.deliveryComplete((MqttDeliveryToken) token); - } - // Now call async action completion callbacks - fireActionEvent(token); - } - - // Set notified so we don't tell the user again about this action. - if ( token.isComplete() ){ - if ( token instanceof MqttDeliveryToken || token.getActionCallback() instanceof IMqttActionListener ) { - token.internalTok.setNotified(true); - } - } - - - - } - } - - /** - * This method is called when the connection to the server is lost. If there - * is no cause then it was a clean disconnect. The connectionLost callback - * will be invoked if registered and run on the thread that requested - * shutdown e.g. receiver or sender thread. If the request was a user - * initiated disconnect then the disconnect token will be notified. - * - * @param cause the reason behind the loss of connection. - */ - public void connectionLost(MqttException cause) { - final String methodName = "connectionLost"; - // If there was a problem and a client callback has been set inform - // the connection lost listener of the problem. - try { - if (mqttCallback != null && cause != null) { - // @TRACE 708=call connectionLost - log.fine(CLASS_NAME, methodName, "708", new Object[] { cause }); - mqttCallback.connectionLost(cause); - } - if(reconnectInternalCallback != null && cause != null){ - reconnectInternalCallback.connectionLost(cause); - } - } catch (java.lang.Throwable t) { - // Just log the fact that a throwable has caught connection lost - // is called during shutdown processing so no need to do anything else - // @TRACE 720=exception from connectionLost {0} - log.fine(CLASS_NAME, methodName, "720", new Object[] { t }); - } - } - - /** - * An action has completed - if a completion listener has been set on the - * token then invoke it with the outcome of the action. - * - * @param token The {@link MqttToken} that has completed - */ - public void fireActionEvent(MqttToken token) { - final String methodName = "fireActionEvent"; - - if (token != null) { - IMqttActionListener asyncCB = token.getActionCallback(); - if (asyncCB != null) { - if (token.getException() == null) { - // @TRACE 716=call onSuccess key={0} - log.fine(CLASS_NAME, methodName, "716", - new Object[] { token.internalTok.getKey() }); - asyncCB.onSuccess(token); - } else { - // @TRACE 717=call onFailure key {0} - log.fine(CLASS_NAME, methodName, "716", - new Object[] { token.internalTok.getKey() }); - asyncCB.onFailure(token, token.getException()); - } - } - } - } - - /** - * This method is called when a message arrives on a topic. Messages are - * only added to the queue for inbound messages if the client is not - * quiescing. - * - * @param sendMessage - * the MQTT SEND message. - */ - public void messageArrived(MqttPublish sendMessage) { - final String methodName = "messageArrived"; - if (mqttCallback != null || callbacks.size() > 0) { - // If we already have enough messages queued up in memory, wait - // until some more queue space becomes available. This helps - // the client protect itself from getting flooded by messages - // from the server. - synchronized (spaceAvailable) { - while (running && !quiescing && messageQueue.size() >= INBOUND_QUEUE_SIZE) { - try { - // @TRACE 709=wait for spaceAvailable - log.fine(CLASS_NAME, methodName, "709"); - spaceAvailable.wait(200); - } catch (InterruptedException ex) { - } - } - } - if (!quiescing) { - messageQueue.addElement(sendMessage); - // Notify the CommsCallback thread that there's work to do... - synchronized (workAvailable) { - // @TRACE 710=new msg avail, notify workAvailable - log.fine(CLASS_NAME, methodName, "710"); - workAvailable.notifyAll(); - } - } - } - } - - /** - * Let the call back thread quiesce. Prevent new inbound messages being - * added to the process queue and let existing work quiesce. (until the - * thread is told to shutdown). - */ - public void quiesce() { - final String methodName = "quiesce"; - this.quiescing = true; - synchronized (spaceAvailable) { - // @TRACE 711=quiesce notify spaceAvailable - log.fine(CLASS_NAME, methodName, "711"); - // Unblock anything waiting for space... - spaceAvailable.notifyAll(); - } - } - - public boolean isQuiesced() { - if (quiescing && completeQueue.size() == 0 && messageQueue.size() == 0) { - return true; - } - return false; - } - - private void handleMessage(MqttPublish publishMessage) - throws MqttException, Exception { - final String methodName = "handleMessage"; - // If quisecing process any pending messages. - - String destName = publishMessage.getTopicName(); - - // @TRACE 713=call messageArrived key={0} topic={1} - log.fine(CLASS_NAME, methodName, "713", new Object[] { - new Integer(publishMessage.getMessageId()), destName }); - deliverMessage(destName, publishMessage.getMessageId(), - publishMessage.getMessage()); - - if (!this.manualAcks) { - if (publishMessage.getMessage().getQos() == 1) { - this.clientComms.internalSend(new MqttPubAck(publishMessage), - new MqttToken(clientComms.getClient().getClientId())); - } else if (publishMessage.getMessage().getQos() == 2) { - this.clientComms.deliveryComplete(publishMessage); - MqttPubComp pubComp = new MqttPubComp(publishMessage); - this.clientComms.internalSend(pubComp, new MqttToken( - clientComms.getClient().getClientId())); - } - } - } - - public void messageArrivedComplete(int messageId, int qos) - throws MqttException { - if (qos == 1) { - this.clientComms.internalSend(new MqttPubAck(messageId), - new MqttToken(clientComms.getClient().getClientId())); - } else if (qos == 2) { - this.clientComms.deliveryComplete(messageId); - MqttPubComp pubComp = new MqttPubComp(messageId); - this.clientComms.internalSend(pubComp, new MqttToken( - clientComms.getClient().getClientId())); - } - } - - public void asyncOperationComplete(MqttToken token) { - final String methodName = "asyncOperationComplete"; - - if (running) { - // invoke callbacks on callback thread - completeQueue.addElement(token); - synchronized (workAvailable) { - // @TRACE 715=new workAvailable. key={0} - log.fine(CLASS_NAME, methodName, "715", new Object[] { token.internalTok.getKey() }); - workAvailable.notifyAll(); - } - } else { - // invoke async callback on invokers thread - try { - handleActionComplete(token); - } catch (Throwable ex) { - // Users code could throw an Error or Exception e.g. in the case - // of class NoClassDefFoundError - // @TRACE 719=callback threw ex: - log.fine(CLASS_NAME, methodName, "719", null, ex); - - // Shutdown likely already in progress but no harm to confirm - clientComms.shutdownConnection(null, new MqttException(ex)); - } - - } - } - - /** - * Returns the thread used by this callback. - * @return The {@link Thread} - */ - protected Thread getThread() { - return callbackThread; - } - - - public void setMessageListener(String topicFilter, IMqttMessageListener messageListener) { - this.callbacks.put(topicFilter, messageListener); - } - - - public void removeMessageListener(String topicFilter) { - this.callbacks.remove(topicFilter); // no exception thrown if the filter was not present - } - - public void removeMessageListeners() { - this.callbacks.clear(); - } - - - protected boolean deliverMessage(String topicName, int messageId, MqttMessage aMessage) throws Exception - { - boolean delivered = false; - - Enumeration keys = callbacks.keys(); - while (keys.hasMoreElements()) { - String topicFilter = (String)keys.nextElement(); - if (MqttTopic.isMatched(topicFilter, topicName)) { - aMessage.setId(messageId); - ((IMqttMessageListener)(callbacks.get(topicFilter))).messageArrived(topicName, aMessage); - delivered = true; - } - } - - /* if the message hasn't been delivered to a per subscription handler, give it to the default handler */ - if (mqttCallback != null && !delivered) { - aMessage.setId(messageId); - mqttCallback.messageArrived(topicName, aMessage); - delivered = true; - } - - return delivered; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsReceiver.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsReceiver.java deleted file mode 100644 index 5bd2db4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsReceiver.java +++ /dev/null @@ -1,206 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.IOException; -import java.io.InputStream; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttInputStream; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubComp; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPubRec; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Receives MQTT packets from the server. - */ -public class CommsReceiver implements Runnable { - private static final String CLASS_NAME = CommsReceiver.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private boolean running = false; - private Object lifecycle = new Object(); - private ClientState clientState = null; - private ClientComms clientComms = null; - private MqttInputStream in; - private CommsTokenStore tokenStore = null; - private Thread recThread = null; - private volatile boolean receiving; - private final Semaphore runningSemaphore = new Semaphore(1); - private String threadName; - private Future receiverFuture; - - - public CommsReceiver(ClientComms clientComms, ClientState clientState,CommsTokenStore tokenStore, InputStream in) { - this.in = new MqttInputStream(clientState, in); - this.clientComms = clientComms; - this.clientState = clientState; - this.tokenStore = tokenStore; - log.setResourceName(clientComms.getClient().getClientId()); - } - - /** - * Starts up the Receiver's thread. - * @param threadName the thread name. - * @param executorService used to execute the thread - */ - public void start(String threadName, ExecutorService executorService) { - this.threadName = threadName; - final String methodName = "start"; - //@TRACE 855=starting - log.fine(CLASS_NAME,methodName, "855"); - synchronized (lifecycle) { - if (!running) { - running = true; - receiverFuture = executorService.submit(this); - } - } - } - - /** - * Stops the Receiver's thread. This call will block. - */ - public void stop() { - final String methodName = "stop"; - synchronized (lifecycle) { - if (receiverFuture != null) { - receiverFuture.cancel(true); - } - //@TRACE 850=stopping - log.fine(CLASS_NAME,methodName, "850"); - if (running) { - running = false; - receiving = false; - if (!Thread.currentThread().equals(recThread)) { - try { - // Wait for the thread to finish. - runningSemaphore.acquire(); - } - catch (InterruptedException ex) { - } finally { - runningSemaphore.release(); - } - } - } - } - recThread = null; - //@TRACE 851=stopped - log.fine(CLASS_NAME,methodName,"851"); - } - - /** - * Run loop to receive messages from the server. - */ - public void run() { - recThread = Thread.currentThread(); - recThread.setName(threadName); - final String methodName = "run"; - MqttToken token = null; - - try { - runningSemaphore.acquire(); - } catch (InterruptedException e) { - running = false; - return; - } - - while (running && (in != null)) { - try { - //@TRACE 852=network read message - log.fine(CLASS_NAME,methodName,"852"); - receiving = in.available() > 0; - MqttWireMessage message = in.readMqttWireMessage(); - receiving = false; - - // instanceof checks if message is null - if (message instanceof MqttAck) { - token = tokenStore.getToken(message); - if (token!=null) { - synchronized (token) { - // Ensure the notify processing is done under a lock on the token - // This ensures that the send processing can complete before the - // receive processing starts! ( request and ack and ack processing - // can occur before request processing is complete if not! - clientState.notifyReceivedAck((MqttAck)message); - } - } else if(message instanceof MqttPubRec || message instanceof MqttPubComp || message instanceof MqttPubAck) { - //This is an ack for a message we no longer have a ticket for. - //This probably means we already received this message and it's being send again - //because of timeouts, crashes, disconnects, restarts etc. - //It should be safe to ignore these unexpected messages. - log.fine(CLASS_NAME, methodName, "857"); - } else { - // It its an ack and there is no token then something is not right. - // An ack should always have a token assoicated with it. - throw new MqttException(MqttException.REASON_CODE_UNEXPECTED_ERROR); - } - } else { - if (message != null) { - // A new message has arrived - clientState.notifyReceivedMsg(message); - } - } - } - catch (MqttException ex) { - //@TRACE 856=Stopping, MQttException - log.fine(CLASS_NAME,methodName,"856",null,ex); - running = false; - // Token maybe null but that is handled in shutdown - clientComms.shutdownConnection(token, ex); - } - catch (IOException ioe) { - //@TRACE 853=Stopping due to IOException - log.fine(CLASS_NAME,methodName,"853"); - - running = false; - // An EOFException could be raised if the broker processes the - // DISCONNECT and ends the socket before we complete. As such, - // only shutdown the connection if we're not already shutting down. - if (!clientComms.isDisconnecting()) { - clientComms.shutdownConnection(token, new MqttException(MqttException.REASON_CODE_CONNECTION_LOST, ioe)); - } - } - finally { - receiving = false; - runningSemaphore.release(); - } - } - - //@TRACE 854=< - log.fine(CLASS_NAME,methodName,"854"); - } - - public boolean isRunning() { - return running; - } - - /** - * Returns the receiving state. - * - * @return true if the receiver is receiving data, false otherwise. - */ - public boolean isReceiving() { - return receiving; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsSender.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsSender.java deleted file mode 100644 index 3697a98..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsSender.java +++ /dev/null @@ -1,190 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.IOException; -import java.io.OutputStream; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Future; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttDisconnect; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttOutputStream; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - - -public class CommsSender implements Runnable { - private static final String CLASS_NAME = CommsSender.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - //Sends MQTT packets to the server on its own thread - private boolean running = false; - private Object lifecycle = new Object(); - private ClientState clientState = null; - private MqttOutputStream out; - private ClientComms clientComms = null; - private CommsTokenStore tokenStore = null; - private Thread sendThread = null; - - private String threadName; - private final Semaphore runningSemaphore = new Semaphore(1); - private Future senderFuture; - - public CommsSender(ClientComms clientComms, ClientState clientState, CommsTokenStore tokenStore, OutputStream out) { - this.out = new MqttOutputStream(clientState, out); - this.clientComms = clientComms; - this.clientState = clientState; - this.tokenStore = tokenStore; - log.setResourceName(clientComms.getClient().getClientId()); - } - - /** - * Starts up the Sender thread. - * @param threadName the threadname - * @param executorService used to execute the thread - */ - public void start(String threadName, ExecutorService executorService) { - this.threadName = threadName; - synchronized (lifecycle) { - if (!running) { - running = true; - senderFuture = executorService.submit(this); - } - } - } - - /** - * Stops the Sender's thread. This call will block. - */ - public void stop() { - final String methodName = "stop"; - - synchronized (lifecycle) { - if (senderFuture != null) { - senderFuture.cancel(true); - } - //@TRACE 800=stopping sender - log.fine(CLASS_NAME,methodName,"800"); - if (running) { - running = false; - if (!Thread.currentThread().equals(sendThread)) { - try { - while (running) { - // first notify get routine to finish - clientState.notifyQueueLock(); - // Wait for the thread to finish. - runningSemaphore.tryAcquire(100, TimeUnit.MILLISECONDS); - } - } catch (InterruptedException ex) { - } finally { - runningSemaphore.release(); - } - } - } - sendThread=null; - //@TRACE 801=stopped - log.fine(CLASS_NAME,methodName,"801"); - } - } - - public void run() { - sendThread = Thread.currentThread(); - sendThread.setName(threadName); - final String methodName = "run"; - MqttWireMessage message = null; - - try { - runningSemaphore.acquire(); - } catch (InterruptedException e) { - running = false; - return; - } - - try { - while (running && (out != null)) { - try { - message = clientState.get(); - if (message != null) { - //@TRACE 802=network send key={0} msg={1} - log.fine(CLASS_NAME,methodName,"802", new Object[] {message.getKey(),message}); - - if (message instanceof MqttAck) { - out.write(message); - out.flush(); - } else { - MqttToken token = tokenStore.getToken(message); - // While quiescing the tokenstore can be cleared so need - // to check for null for the case where clear occurs - // while trying to send a message. - if (token != null) { - synchronized (token) { - out.write(message); - try { - out.flush(); - } catch (IOException ex) { - // The flush has been seen to fail on disconnect of a SSL socket - // as disconnect is in progress this should not be treated as an error - if (!(message instanceof MqttDisconnect)) { - throw ex; - } - } - clientState.notifySent(message); - } - } - } - } else { // null message - //@TRACE 803=get message returned null, stopping} - log.fine(CLASS_NAME,methodName,"803"); - - running = false; - } - } catch (MqttException me) { - handleRunException(message, me); - } catch (Exception ex) { - handleRunException(message, ex); - } - } // end while - } finally { - running = false; - runningSemaphore.release(); - } - - //@TRACE 805=< - log.fine(CLASS_NAME, methodName,"805"); - - } - - private void handleRunException(MqttWireMessage message, Exception ex) { - final String methodName = "handleRunException"; - //@TRACE 804=exception - log.fine(CLASS_NAME,methodName,"804",null, ex); - MqttException mex; - if ( !(ex instanceof MqttException)) { - mex = new MqttException(MqttException.REASON_CODE_CONNECTION_LOST, ex); - } else { - mex = (MqttException)ex; - } - - running = false; - clientComms.shutdownConnection(null, mex); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsTokenStore.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsTokenStore.java deleted file mode 100644 index dcd5ea4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/CommsTokenStore.java +++ /dev/null @@ -1,254 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Vector; - -import org.eclipse.paho.client.mqttv3.MqttDeliveryToken; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttPublish; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - - -/** - * Provides a "token" based system for storing and tracking actions across - * multiple threads. - * When a message is sent, a token is associated with the message - * and saved using the {@link CommsTokenStore#saveToken(MqttToken, MqttWireMessage)} method. Anyone interested - * in tacking the state can call one of the wait methods on the token or using - * the asynchronous listener callback method on the operation. - * The {@link CommsReceiver} class, on another thread, reads responses back from - * the network. It uses the response to find the relevant token, which it can then - * notify. - * - * Note: - * Ping, connect and disconnect do not have a unique message id as - * only one outstanding request of each type is allowed to be outstanding - */ -public class CommsTokenStore { - private static final String CLASS_NAME = CommsTokenStore.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - // Maps message-specific data (usually message IDs) to tokens - private Hashtable tokens; - private String logContext; - private MqttException closedResponse = null; - - public CommsTokenStore(String logContext) { - final String methodName = "<Init>"; - - log.setResourceName(logContext); - this.tokens = new Hashtable(); - this.logContext = logContext; - //@TRACE 308=<> - log.fine(CLASS_NAME,methodName,"308");//,new Object[]{message}); - - } - - /** - * Based on the message type that has just been received return the associated - * token from the token store or null if one does not exist. - * @param message whose token is to be returned - * @return token for the requested message - */ - public MqttToken getToken(MqttWireMessage message) { - String key = message.getKey(); - return (MqttToken)tokens.get(key); - } - - public MqttToken getToken(String key) { - return (MqttToken)tokens.get(key); - } - - - public MqttToken removeToken(MqttWireMessage message) { - if (message != null) { - return removeToken(message.getKey()); - } - return null; - } - - public MqttToken removeToken(String key) { - final String methodName = "removeToken"; - //@TRACE 306=key={0} - log.fine(CLASS_NAME,methodName,"306",new Object[]{key}); - - if ( null != key ){ - return (MqttToken) tokens.remove(key); - } - - return null; - } - - /** - * Restores a token after a client restart. This method could be called - * for a SEND of CONFIRM, but either way, the original SEND is what's - * needed to re-build the token. - * @param message The {@link MqttPublish} message to restore - * @return {@link MqttDeliveryToken} - */ - protected MqttDeliveryToken restoreToken(MqttPublish message) { - final String methodName = "restoreToken"; - MqttDeliveryToken token; - synchronized(tokens) { - String key = new Integer(message.getMessageId()).toString(); - if (this.tokens.containsKey(key)) { - token = (MqttDeliveryToken)this.tokens.get(key); - //@TRACE 302=existing key={0} message={1} token={2} - log.fine(CLASS_NAME,methodName, "302",new Object[]{key, message,token}); - } else { - token = new MqttDeliveryToken(logContext); - token.internalTok.setKey(key); - this.tokens.put(key, token); - //@TRACE 303=creating new token key={0} message={1} token={2} - log.fine(CLASS_NAME,methodName,"303",new Object[]{key, message, token}); - } - } - return token; - } - - // For outbound messages store the token in the token store - // For pubrel use the existing publish token - protected void saveToken(MqttToken token, MqttWireMessage message) throws MqttException { - final String methodName = "saveToken"; - - synchronized(tokens) { - if (closedResponse == null) { - String key = message.getKey(); - //@TRACE 300=key={0} message={1} - log.fine(CLASS_NAME,methodName,"300",new Object[]{key, message}); - - saveToken(token,key); - } else { - throw closedResponse; - } - } - } - - protected void saveToken(MqttToken token, String key) { - final String methodName = "saveToken"; - - synchronized(tokens) { - //@TRACE 307=key={0} token={1} - log.fine(CLASS_NAME,methodName,"307",new Object[]{key,token.toString()}); - token.internalTok.setKey(key); - this.tokens.put(key, token); - } - } - - protected void quiesce(MqttException quiesceResponse) { - final String methodName = "quiesce"; - - synchronized(tokens) { - //@TRACE 309=resp={0} - log.fine(CLASS_NAME,methodName,"309",new Object[]{quiesceResponse}); - - closedResponse = quiesceResponse; - } - } - - public void open() { - final String methodName = "open"; - - synchronized(tokens) { - //@TRACE 310=> - log.fine(CLASS_NAME,methodName,"310"); - - closedResponse = null; - } - } - - public MqttDeliveryToken[] getOutstandingDelTokens() { - final String methodName = "getOutstandingDelTokens"; - - synchronized(tokens) { - //@TRACE 311=> - log.fine(CLASS_NAME,methodName,"311"); - - Vector list = new Vector(); - Enumeration enumeration = tokens.elements(); - MqttToken token; - while(enumeration.hasMoreElements()) { - token = (MqttToken)enumeration.nextElement(); - if (token != null - && token instanceof MqttDeliveryToken - && !token.internalTok.isNotified()) { - - list.addElement(token); - } - } - - MqttDeliveryToken[] result = new MqttDeliveryToken[list.size()]; - return (MqttDeliveryToken[]) list.toArray(result); - } - } - - public Vector getOutstandingTokens() { - final String methodName = "getOutstandingTokens"; - - synchronized(tokens) { - //@TRACE 312=> - log.fine(CLASS_NAME,methodName,"312"); - - Vector list = new Vector(); - Enumeration enumeration = tokens.elements(); - MqttToken token; - while(enumeration.hasMoreElements()) { - token = (MqttToken)enumeration.nextElement(); - if (token != null) { - list.addElement(token); - } - } - return list; - } - } - - /** - * Empties the token store without notifying any of the tokens. - */ - public void clear() { - final String methodName = "clear"; - //@TRACE 305=> {0} tokens - log.fine(CLASS_NAME, methodName, "305", new Object[] {new Integer(tokens.size())}); - synchronized(tokens) { - tokens.clear(); - } - } - - public int count() { - synchronized(tokens) { - return tokens.size(); - } - } - public String toString() { - String lineSep = System.getProperty("line.separator","\n"); - StringBuffer toks = new StringBuffer(); - synchronized(tokens) { - Enumeration enumeration = tokens.elements(); - MqttToken token; - while(enumeration.hasMoreElements()) { - token = (MqttToken)enumeration.nextElement(); - toks.append("{"+token.internalTok+"}"+lineSep); - } - return toks.toString(); - } - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ConnectActionListener.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ConnectActionListener.java deleted file mode 100644 index aa6bb8d..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ConnectActionListener.java +++ /dev/null @@ -1,200 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Ian Craggs - MQTT 3.1.1 support - * Ian Craggs - fix bug 469527 - * James Sutton - Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.IMqttToken; -import org.eclipse.paho.client.mqttv3.MqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttCallbackExtended; -import org.eclipse.paho.client.mqttv3.MqttClientPersistence; -import org.eclipse.paho.client.mqttv3.MqttConnectOptions; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; -import org.eclipse.paho.client.mqttv3.MqttToken; - -/** - * <p>This class handles the connection of the AsyncClient to one of the available URLs.</p> - * <p>The URLs are supplied as either the singleton when the client is created, or as a list in the connect options.</p> - * <p>This class uses its own onSuccess and onFailure callbacks in preference to the user supplied callbacks.</p> - * <p>An attempt is made to connect to each URL in the list until either a connection attempt succeeds or all the URLs have been tried</p> - * <p>If a connection succeeds then the users token is notified and the users onSuccess callback is called.</p> - * <p>If a connection fails then another URL in the list is attempted, otherwise the users token is notified - * and the users onFailure callback is called</p> - */ -public class ConnectActionListener implements IMqttActionListener { - - private MqttClientPersistence persistence; - private MqttAsyncClient client; - private ClientComms comms; - private MqttConnectOptions options; - private MqttToken userToken; - private Object userContext; - private IMqttActionListener userCallback; - private int originalMqttVersion; - private MqttCallbackExtended mqttCallbackExtended; - private boolean reconnect; - -/** - * @param persistence The {@link MqttClientPersistence} layer - * @param client the {@link MqttAsyncClient} - * @param comms {@link ClientComms} - * @param options the {@link MqttConnectOptions} - * @param userToken the {@link MqttToken} - * @param userContext the User Context Object - * @param userCallback the {@link IMqttActionListener} as the callback for the user - * @param reconnect If true, this is a reconnect attempt - */ - public ConnectActionListener( - MqttAsyncClient client, - MqttClientPersistence persistence, - ClientComms comms, - MqttConnectOptions options, - MqttToken userToken, - Object userContext, - IMqttActionListener userCallback, - boolean reconnect) { - this.persistence = persistence; - this.client = client; - this.comms = comms; - this.options = options; - this.userToken = userToken; - this.userContext = userContext; - this.userCallback = userCallback; - this.originalMqttVersion = options.getMqttVersion(); - this.reconnect = reconnect; - } - - /** - * If the connect succeeded then call the users onSuccess callback - * - * @param token the {@link IMqttToken} from the successful connection - */ - public void onSuccess(IMqttToken token) { - if (originalMqttVersion == MqttConnectOptions.MQTT_VERSION_DEFAULT) { - options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_DEFAULT); - } - userToken.internalTok.markComplete(token.getResponse(), null); - userToken.internalTok.notifyComplete(); - userToken.internalTok.setClient(this.client); // fix bug 469527 - maybe should be set elsewhere? - - comms.notifyConnect(); - - if (userCallback != null) { - userToken.setUserContext(userContext); - userCallback.onSuccess(userToken); - } - - if(mqttCallbackExtended != null){ - String serverURI = comms.getNetworkModules()[comms.getNetworkModuleIndex()].getServerURI(); - mqttCallbackExtended.connectComplete(reconnect, serverURI); - } - - - } - - /** - * The connect failed, so try the next URI on the list. - * If there are no more URIs, then fail the overall connect. - * - * @param token the {@link IMqttToken} from the failed connection attempt - * @param exception the {@link Throwable} exception from the failed connection attempt - */ - public void onFailure(IMqttToken token, Throwable exception) { - - int numberOfURIs = comms.getNetworkModules().length; - int index = comms.getNetworkModuleIndex(); - - if ((index + 1) < numberOfURIs || (originalMqttVersion == MqttConnectOptions.MQTT_VERSION_DEFAULT && options.getMqttVersion() == MqttConnectOptions.MQTT_VERSION_3_1_1)) { - - if (originalMqttVersion == MqttConnectOptions.MQTT_VERSION_DEFAULT) { - if (options.getMqttVersion() == MqttConnectOptions.MQTT_VERSION_3_1_1) { - options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1); - } - else { - options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1); - comms.setNetworkModuleIndex(index + 1); - } - } - else { - comms.setNetworkModuleIndex(index + 1); - } - try { - connect(); - } - catch (MqttPersistenceException e) { - onFailure(token, e); // try the next URI in the list - } - } - else { - if (originalMqttVersion == MqttConnectOptions.MQTT_VERSION_DEFAULT) { - options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_DEFAULT); - } - MqttException ex; - if (exception instanceof MqttException) { - ex = (MqttException) exception; - } - else { - ex = new MqttException(exception); - } - userToken.internalTok.markComplete(null, ex); - userToken.internalTok.notifyComplete(); - userToken.internalTok.setClient(this.client); // fix bug 469527 - maybe should be set elsewhere? - - if (userCallback != null) { - userToken.setUserContext(userContext); - userCallback.onFailure(userToken, exception); - } - } - } - - /** - * Start the connect processing - * @throws MqttPersistenceException if an error is thrown whilst setting up persistence - */ - public void connect() throws MqttPersistenceException { - MqttToken token = new MqttToken(client.getClientId()); - token.setActionCallback(this); - token.setUserContext(this); - - persistence.open(client.getClientId(), client.getServerURI()); - - if (options.isCleanSession()) { - persistence.clear(); - } - - if (options.getMqttVersion() == MqttConnectOptions.MQTT_VERSION_DEFAULT) { - options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1_1); - } - - try { - comms.connect(options, token); - } - catch (MqttException e) { - onFailure(token, e); - } - } - - /** - * Set the MqttCallbackExtened callback to receive connectComplete callbacks - * @param mqttCallbackExtended the {@link MqttCallbackExtended} to be called when the connection completes - */ - public void setMqttCallbackExtended(MqttCallbackExtended mqttCallbackExtended) { - this.mqttCallbackExtended = mqttCallbackExtended; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DestinationProvider.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DestinationProvider.java deleted file mode 100644 index 39a9059..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DestinationProvider.java +++ /dev/null @@ -1,31 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.MqttTopic; - -/** - * This interface exists to act as a common type for - * MqttClient and MqttMIDPClient so they can be passed to - * ClientComms without either client class need to know - * about the other. - * Specifically, this allows the MIDP client to work - * without the non-MIDP MqttClient/MqttConnectOptions - * classes being present. - */ -public interface DestinationProvider { - public MqttTopic getTopic(String topic); -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DisconnectedMessageBuffer.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DisconnectedMessageBuffer.java deleted file mode 100644 index 14425e4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/DisconnectedMessageBuffer.java +++ /dev/null @@ -1,128 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Initial Contribution for Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.util.ArrayList; - -import org.eclipse.paho.client.mqttv3.BufferedMessage; -import org.eclipse.paho.client.mqttv3.DisconnectedBufferOptions; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttToken; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -public class DisconnectedMessageBuffer implements Runnable { - - private static final String CLASS_NAME = "DisconnectedMessageBuffer"; - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - private DisconnectedBufferOptions bufferOpts; - private ArrayList buffer; - private Object bufLock = new Object(); // Used to synchronise the buffer - private IDisconnectedBufferCallback callback; - - public DisconnectedMessageBuffer(DisconnectedBufferOptions options){ - this.bufferOpts = options; - buffer = new ArrayList(); - } - - /** - * This will add a new message to the offline buffer, - * if the buffer is full and deleteOldestMessages is enabled - * then the 0th item in the buffer will be deleted and the - * new message will be added. If it is not enabled then an - * MqttException will be thrown. - * @param message the {@link MqttWireMessage} that will be buffered - * @param token the associated {@link MqttToken} - * @throws MqttException if the Buffer is full - */ - public void putMessage(MqttWireMessage message, MqttToken token) throws MqttException{ - BufferedMessage bufferedMessage = new BufferedMessage(message, token); - synchronized (bufLock) { - if(buffer.size() < bufferOpts.getBufferSize()){ - buffer.add(bufferedMessage); - } else if(bufferOpts.isDeleteOldestMessages() == true){ - buffer.remove(0); - buffer.add(bufferedMessage); - }else { - throw new MqttException(MqttException.REASON_CODE_DISCONNECTED_BUFFER_FULL); - } - } - } - - /** - * Retrieves a message from the buffer at the given index. - * @param messageIndex the index of the message to be retrieved in the buffer - * @return the {@link BufferedMessage} - */ - public BufferedMessage getMessage(int messageIndex){ - synchronized (bufLock) { - return((BufferedMessage) buffer.get(messageIndex)); - } - } - - - /** - * Removes a message from the buffer - * @param messageIndex the index of the message to be deleted in the buffer - */ - public void deleteMessage(int messageIndex){ - synchronized (bufLock) { - buffer.remove(messageIndex); - } - } - - /** - * Returns the number of messages currently in the buffer - * @return The count of messages in the buffer - */ - public int getMessageCount() { - synchronized (bufLock) { - return buffer.size(); - } - } - - /** - * Flushes the buffer of messages into an open connection - */ - public void run() { - final String methodName = "run"; - // @TRACE 516=Restoring all buffered messages. - log.fine(CLASS_NAME, methodName, "516"); - while(getMessageCount() > 0){ - try { - BufferedMessage bufferedMessage = getMessage(0); - callback.publishBufferedMessage(bufferedMessage); - // Publish was successful, remove message from buffer. - deleteMessage(0); - } catch (MqttException ex) { - // Error occurred attempting to publish buffered message likely because the client is not connected - // @TRACE 517=Error occured attempting to publish buffered message due to disconnect. - log.warning(CLASS_NAME, methodName, "517"); - break; - } - } - } - - public void setPublishCallback(IDisconnectedBufferCallback callback) { - this.callback = callback; - } - - public boolean isPersistBuffer(){ - return bufferOpts.isPersistBuffer(); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ExceptionHelper.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ExceptionHelper.java deleted file mode 100644 index 02b4c41..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ExceptionHelper.java +++ /dev/null @@ -1,62 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttSecurityException; - -/** - * Utility class to help create exceptions of the correct type. - */ -public class ExceptionHelper { - public static MqttException createMqttException(int reasonCode) { - if ((reasonCode == MqttException.REASON_CODE_FAILED_AUTHENTICATION) || - (reasonCode == MqttException.REASON_CODE_NOT_AUTHORIZED)) { - return new MqttSecurityException(reasonCode); - } - - return new MqttException(reasonCode); - } - - public static MqttException createMqttException(Throwable cause) { - if (cause.getClass().getName().equals("java.security.GeneralSecurityException")) { - return new MqttSecurityException(cause); - } - return new MqttException(cause); - } - - /** - * Returns whether or not the specified class is available to the current - * class loader. This is used to protect the code against using Java SE - * APIs on Java ME. - * @param className The name of the class - * @return If true, the class is available - */ - public static boolean isClassAvailable(String className) { - boolean result = false; - try { - Class.forName(className); - result = true; - } - catch (ClassNotFoundException ex) { - } - return result; - } - - // Utility classes should not have a public or default constructor. - private ExceptionHelper() { - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/FileLock.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/FileLock.java deleted file mode 100644 index ebad8bb..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/FileLock.java +++ /dev/null @@ -1,96 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; -/** - * FileLock - used to obtain a lock that can be used to prevent other MQTT clients - * using the same persistent store. If the lock is already held then an exception - * is thrown. - * - * Some Java runtimes such as JME MIDP do not support file locking or even - * the Java classes that support locking. The class is coded to both compile - * and work on all Java runtimes. In Java runtimes that do not support - * locking it will look as though a lock has been obtained but in reality - * no lock has been obtained. - */ -import java.io.File; -import java.io.IOException; -import java.io.RandomAccessFile; -import java.lang.reflect.Method; - -public class FileLock { - private File lockFile; - private RandomAccessFile file; - private Object fileLock; - - /** - * Creates an NIO FileLock on the specified file if on a suitable Java runtime. - * @param clientDir the a File of the directory to contain the lock file. - * @param lockFilename name of the the file to lock - * @throws Exception if the lock could not be obtained for any reason - */ - public FileLock(File clientDir, String lockFilename) throws Exception { - // Create a file to obtain a lock on. - lockFile = new File(clientDir,lockFilename); - if (ExceptionHelper.isClassAvailable("java.nio.channels.FileLock")) { - try { - this.file = new RandomAccessFile(lockFile,"rw"); - Method m = file.getClass().getMethod("getChannel",new Class[]{}); - Object channel = m.invoke(file,new Object[]{}); - m = channel.getClass().getMethod("tryLock",new Class[]{}); - this.fileLock = m.invoke(channel, new Object[]{}); - } catch(NoSuchMethodException nsme) { - this.fileLock = null; - } catch(IllegalArgumentException iae) { - this.fileLock = null; - } catch(IllegalAccessException iae) { - this.fileLock = null; - } - if (fileLock == null) { - // Lock not obtained - release(); - throw new Exception("Problem obtaining file lock"); - } - } - } - - /** - * Releases the lock. - */ - public void release() { - try { - if (fileLock != null) { - Method m = fileLock.getClass().getMethod("release",new Class[]{}); - m.invoke(fileLock, new Object[]{}); - fileLock = null; - } - } catch (Exception e) { - // Ignore exceptions - } - if (file != null) { - try { - file.close(); - } catch (IOException e) { - } - file = null; - } - - if (lockFile != null && lockFile.exists()) { - lockFile.delete(); - } - lockFile = null; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/IDisconnectedBufferCallback.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/IDisconnectedBufferCallback.java deleted file mode 100644 index f38df43..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/IDisconnectedBufferCallback.java +++ /dev/null @@ -1,25 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Initial Contribution for Automatic Reconnect & Offline Buffering - */ -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.BufferedMessage; -import org.eclipse.paho.client.mqttv3.MqttException; - -public interface IDisconnectedBufferCallback { - - public void publishBufferedMessage(BufferedMessage bufferedMessage) throws MqttException; - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MessageCatalog.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MessageCatalog.java deleted file mode 100644 index a0df46d..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MessageCatalog.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -/** - * Catalog of human readable error messages. - */ -public abstract class MessageCatalog { - private static MessageCatalog INSTANCE = null; - - public static final String getMessage(int id) { - if (INSTANCE == null) { - if (ExceptionHelper.isClassAvailable("java.util.ResourceBundle")) { - try { - // Hide this class reference behind reflection so that the class does not need to - // be present when compiled on midp - INSTANCE = (MessageCatalog)Class.forName("org.eclipse.paho.client.mqttv3.internal.ResourceBundleCatalog").newInstance(); - } catch (Exception e) { - return ""; - } - } else if (ExceptionHelper.isClassAvailable("org.eclipse.paho.client.mqttv3.internal.MIDPCatalog")){ - try { - INSTANCE = (MessageCatalog)Class.forName("org.eclipse.paho.client.mqttv3.internal.MIDPCatalog").newInstance(); - } catch (Exception e) { - return ""; - } - } - } - return INSTANCE.getLocalizedMessage(id); - } - - protected abstract String getLocalizedMessage(int id); -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MqttPersistentData.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MqttPersistentData.java deleted file mode 100644 index 8ab04c1..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/MqttPersistentData.java +++ /dev/null @@ -1,98 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.MqttPersistable; - -public class MqttPersistentData implements MqttPersistable { - // Message key - private String key = null; - - // Message header - private byte[] header = null; - private int hOffset = 0; - private int hLength = 0; - - // Message payload - private byte[] payload = null; - private int pOffset = 0; - private int pLength = 0; - - /** - * Construct a data object to pass across the MQTT client persistence interface. - * - * When this Object is passed to the persistence implementation the key is - * used by the client to identify the persisted data to which further - * update or deletion requests are targeted.<BR> - * When this Object is created for returning to the client when it is - * recovering its state from persistence the key is not required to be set. - * The client can determine the key from the data. - * @param key The key which identifies this data - * @param header The message header - * @param hOffset The start offset of the header bytes in header. - * @param hLength The length of the header in the header bytes array. - * @param payload The message payload - * @param pOffset The start offset of the payload bytes in payload. - * @param pLength The length of the payload in the payload bytes array - * when persisting the message. - */ - public MqttPersistentData( String key, - byte[] header, - int hOffset, - int hLength, - byte[] payload, - int pOffset, - int pLength) { - this.key = key; - this.header = header; - this.hOffset = hOffset; - this.hLength = hLength; - this.payload = payload; - this.pOffset = pOffset; - this.pLength = pLength; - } - - public String getKey() { - return key; - } - - public byte[] getHeaderBytes() { - return header; - } - - public int getHeaderLength() { - return hLength; - } - - public int getHeaderOffset() { - return hOffset; - } - - public byte[] getPayloadBytes() { - return payload; - } - - public int getPayloadLength() { - if ( payload == null ) { - return 0; - } - return pLength; - } - - public int getPayloadOffset() { - return pOffset; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/NetworkModule.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/NetworkModule.java deleted file mode 100644 index 33ba774..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/NetworkModule.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; - -import org.eclipse.paho.client.mqttv3.MqttException; - - -public interface NetworkModule { - public void start() throws IOException, MqttException; - - public InputStream getInputStream() throws IOException; - - public OutputStream getOutputStream() throws IOException; - - public void stop() throws IOException; - - public String getServerURI(); -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ResourceBundleCatalog.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ResourceBundleCatalog.java deleted file mode 100644 index 64160ca..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/ResourceBundleCatalog.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -public class ResourceBundleCatalog extends MessageCatalog { - - private ResourceBundle bundle; - - public ResourceBundleCatalog() { - //MAY throws MissingResourceException - bundle = ResourceBundle.getBundle("org.eclipse.paho.client.mqttv3.internal.nls.messages"); - } - - protected String getLocalizedMessage(int id) { - try { - return bundle.getString(Integer.toString(id)); - } catch(MissingResourceException mre) { - return "MqttException"; - } - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/SSLNetworkModule.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/SSLNetworkModule.java deleted file mode 100644 index a20f3c6..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/SSLNetworkModule.java +++ /dev/null @@ -1,120 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.IOException; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.SSLSession; -import javax.net.ssl.SSLSocket; -import javax.net.ssl.SSLSocketFactory; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * A network module for connecting over SSL. - */ -public class SSLNetworkModule extends TCPNetworkModule { - private static final String CLASS_NAME = SSLNetworkModule.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - private String[] enabledCiphers; - private int handshakeTimeoutSecs; - private HostnameVerifier hostnameVerifier; - - private String host; - private int port; - /** - * Constructs a new SSLNetworkModule using the specified host and - * port. The supplied SSLSocketFactory is used to supply the network - * socket. - * @param factory the {@link SSLSocketFactory} to be used in this SSLNetworkModule - * @param host the Hostname of the Server - * @param port the Port of the Server - * @param resourceContext Resource Context - */ - public SSLNetworkModule(SSLSocketFactory factory, String host, int port, String resourceContext) { - super(factory, host, port, resourceContext); - this.host = host; - this.port = port; - log.setResourceName(resourceContext); - } - - /** - * Returns the enabled cipher suites. - * @return a string array of enabled Cipher suites - */ - public String[] getEnabledCiphers() { - return enabledCiphers; - } - - /** - * Sets the enabled cipher suites on the underlying network socket. - * @param enabledCiphers a String array of cipher suites to enable - */ - public void setEnabledCiphers(String[] enabledCiphers) { - final String methodName = "setEnabledCiphers"; - this.enabledCiphers = enabledCiphers; - if ((socket != null) && (enabledCiphers != null)) { - if (log.isLoggable(Logger.FINE)) { - String ciphers = ""; - for (int i=0;i<enabledCiphers.length;i++) { - if (i>0) { - ciphers+=","; - } - ciphers+=enabledCiphers[i]; - } - //@TRACE 260=setEnabledCiphers ciphers={0} - log.fine(CLASS_NAME,methodName,"260",new Object[]{ciphers}); - } - ((SSLSocket) socket).setEnabledCipherSuites(enabledCiphers); - } - } - - public void setSSLhandshakeTimeout(int timeout) { - super.setConnectTimeout(timeout); - this.handshakeTimeoutSecs = timeout; - } - - public HostnameVerifier getSSLHostnameVerifier() { - return hostnameVerifier; - } - - public void setSSLHostnameVerifier(HostnameVerifier hostnameVerifier) { - this.hostnameVerifier = hostnameVerifier; - } - - public void start() throws IOException, MqttException { - super.start(); - setEnabledCiphers(enabledCiphers); - int soTimeout = socket.getSoTimeout(); - // RTC 765: Set a timeout to avoid the SSL handshake being blocked indefinitely - socket.setSoTimeout(this.handshakeTimeoutSecs*1000); - ((SSLSocket)socket).startHandshake(); - if (hostnameVerifier != null) { - SSLSession session = ((SSLSocket)socket).getSession(); - hostnameVerifier.verify(host, session); - } - // reset timeout to default value - socket.setSoTimeout(soTimeout); - } - - public String getServerURI() { - return "ssl://" + host + ":" + port; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/TCPNetworkModule.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/TCPNetworkModule.java deleted file mode 100644 index 51fb346..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/TCPNetworkModule.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.ConnectException; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; -import java.net.SocketAddress; - -import javax.net.SocketFactory; -import javax.net.ssl.SSLSocketFactory; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * A network module for connecting over TCP. - */ -public class TCPNetworkModule implements NetworkModule { - private static final String CLASS_NAME = TCPNetworkModule.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - protected Socket socket; - private SocketFactory factory; - private String host; - private int port; - private int conTimeout; - - /** - * Constructs a new TCPNetworkModule using the specified host and - * port. The supplied SocketFactory is used to supply the network - * socket. - * @param factory the {@link SocketFactory} to be used to set up this connection - * @param host The server hostname - * @param port The server port - * @param resourceContext The Resource Context - */ - public TCPNetworkModule(SocketFactory factory, String host, int port, String resourceContext) { - log.setResourceName(resourceContext); - this.factory = factory; - this.host = host; - this.port = port; - - } - - /** - * Starts the module, by creating a TCP socket to the server. - * @throws IOException if there is an error creating the socket - * @throws MqttException if there is an error connecting to the server - */ - public void start() throws IOException, MqttException { - final String methodName = "start"; - try { -// InetAddress localAddr = InetAddress.getLocalHost(); -// socket = factory.createSocket(host, port, localAddr, 0); - // @TRACE 252=connect to host {0} port {1} timeout {2} - log.fine(CLASS_NAME,methodName, "252", new Object[] {host, new Integer(port), new Long(conTimeout*1000)}); - SocketAddress sockaddr = new InetSocketAddress(host, port); - if (factory instanceof SSLSocketFactory) { - // SNI support - Socket tempsocket = new Socket(); - tempsocket.connect(sockaddr, conTimeout*1000); - socket = ((SSLSocketFactory)factory).createSocket(tempsocket, host, port, true); - } else { - socket = factory.createSocket(); - socket.connect(sockaddr, conTimeout*1000); - } - - // SetTcpNoDelay was originally set ot true disabling Nagle's algorithm. - // This should not be required. -// socket.setTcpNoDelay(true); // TCP_NODELAY on, which means we do not use Nagle's algorithm - } - catch (ConnectException ex) { - //@TRACE 250=Failed to create TCP socket - log.fine(CLASS_NAME,methodName,"250",null,ex); - throw new MqttException(MqttException.REASON_CODE_SERVER_CONNECT_ERROR, ex); - } - } - - public InputStream getInputStream() throws IOException { - return socket.getInputStream(); - } - - public OutputStream getOutputStream() throws IOException { - return socket.getOutputStream(); - } - - /** - * Stops the module, by closing the TCP socket. - * @throws IOException if there is an error closing the socket - */ - public void stop() throws IOException { - if (socket != null) { - // CDA: an attempt is made to stop the receiver cleanly before closing the socket. - // If the socket is forcibly closed too early, the blocking socket read in - // the receiver thread throws a SocketException. - // While this causes the receiver thread to exit, it also invalidates the - // SSL session preventing to perform an accelerated SSL handshake in the - // next connection. - // - // Also note that due to the blocking socket reads in the receiver thread, - // it's not possible to interrupt the thread. Using non blocking reads in - // combination with a socket timeout (see setSoTimeout()) would be a better approach. - // - // Please note that the Javadoc only says that an EOF is returned on - // subsequent reads of the socket stream. - // Anyway, at least with Oracle Java SE 7 on Linux systems, this causes a blocked read - // to return EOF immediately. - // This workaround should not cause any harm in general but you might - // want to move it in SSLNetworkModule. - - socket.shutdownInput(); - socket.close(); - } - } - - /** - * Set the maximum time to wait for a socket to be established - * @param timeout The connection timeout - */ - public void setConnectTimeout(int timeout) { - this.conTimeout = timeout; - } - - public String getServerURI() { - return "tcp://" + host + ":" + port; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/Token.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/Token.java deleted file mode 100644 index b0c7a7a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/Token.java +++ /dev/null @@ -1,394 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Ian Craggs - MQTT 3.1.1 support - */ - -package org.eclipse.paho.client.mqttv3.internal; - -import org.eclipse.paho.client.mqttv3.IMqttActionListener; -import org.eclipse.paho.client.mqttv3.IMqttAsyncClient; -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttAck; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttConnack; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttSuback; -import org.eclipse.paho.client.mqttv3.internal.wire.MqttWireMessage; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -public class Token { - private static final String CLASS_NAME = Token.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - - private volatile boolean completed = false; - private boolean pendingComplete = false; - private boolean sent = false; - - private Object responseLock = new Object(); - private Object sentLock = new Object(); - - protected MqttMessage message = null; - private MqttWireMessage response = null; - private MqttException exception = null; - private String[] topics = null; - - private String key; - - private IMqttAsyncClient client = null; - private IMqttActionListener callback = null; - - private Object userContext = null; - - private int messageID = 0; - private boolean notified = false; - - public Token(String logContext) { - log.setResourceName(logContext); - } - - public int getMessageID() { - return messageID; - } - - public void setMessageID(int messageID) { - this.messageID = messageID; - } - - public boolean checkResult() throws MqttException { - if ( getException() != null) { - throw getException(); - } - return true; - } - - public MqttException getException() { - return exception; - } - - public boolean isComplete() { - return completed; - } - - protected boolean isCompletePending() { - return pendingComplete; - } - - protected boolean isInUse() { - return (getClient() != null && !isComplete()); - } - - public void setActionCallback(IMqttActionListener listener) { - this.callback = listener; - - } - public IMqttActionListener getActionCallback() { - return callback; - } - - public void waitForCompletion() throws MqttException { - waitForCompletion(-1); - } - - public void waitForCompletion(long timeout) throws MqttException { - final String methodName = "waitForCompletion"; - //@TRACE 407=key={0} wait max={1} token={2} - log.fine(CLASS_NAME,methodName, "407",new Object[]{getKey(), new Long(timeout), this}); - - MqttWireMessage resp = waitForResponse(timeout); - if (resp == null && !completed) { - //@TRACE 406=key={0} timed out token={1} - log.fine(CLASS_NAME,methodName, "406",new Object[]{getKey(), this}); - exception = new MqttException(MqttException.REASON_CODE_CLIENT_TIMEOUT); - throw exception; - } - checkResult(); - } - - /** - * Waits for the message delivery to complete, but doesn't throw an exception - * in the case of a NACK. It does still throw an exception if something else - * goes wrong (e.g. an IOException). This is used for packets like CONNECT, - * which have useful information in the ACK that needs to be accessed. - * @return the {@link MqttWireMessage} - * @throws MqttException if there is an error whilst waiting for the response - */ - protected MqttWireMessage waitForResponse() throws MqttException { - return waitForResponse(-1); - } - - protected MqttWireMessage waitForResponse(long timeout) throws MqttException { - final String methodName = "waitForResponse"; - synchronized (responseLock) { - //@TRACE 400=>key={0} timeout={1} sent={2} completed={3} hasException={4} response={5} token={6} - log.fine(CLASS_NAME, methodName, "400",new Object[]{getKey(), new Long(timeout),new Boolean(sent),new Boolean(completed),(exception==null)?"false":"true",response,this},exception); - - while (!this.completed) { - if (this.exception == null) { - try { - //@TRACE 408=key={0} wait max={1} - log.fine(CLASS_NAME,methodName,"408",new Object[] {getKey(),new Long(timeout)}); - - if (timeout <= 0) { - responseLock.wait(); - } else { - responseLock.wait(timeout); - } - } catch (InterruptedException e) { - exception = new MqttException(e); - } - } - if (!this.completed) { - if (this.exception != null) { - //@TRACE 401=failed with exception - log.fine(CLASS_NAME,methodName,"401",null,exception); - throw exception; - } - - if (timeout > 0) { - // time up and still not completed - break; - } - } - } - } - //@TRACE 402=key={0} response={1} - log.fine(CLASS_NAME,methodName, "402",new Object[]{getKey(), this.response}); - return this.response; - } - - /** - * Mark the token as complete and ready for users to be notified. - * @param msg response message. Optional - there are no response messages for some flows - * @param ex if there was a problem store the exception in the token. - */ - protected void markComplete(MqttWireMessage msg, MqttException ex) { - final String methodName = "markComplete"; - //@TRACE 404=>key={0} response={1} excep={2} - log.fine(CLASS_NAME,methodName,"404",new Object[]{getKey(),msg,ex}); - - synchronized(responseLock) { - // ACK means that everything was OK, so mark the message for garbage collection. - if (msg instanceof MqttAck) { - this.message = null; - } - this.pendingComplete = true; - this.response = msg; - this.exception = ex; - } - } - /** - * Notifies this token that a response message (an ACK or NACK) has been - * received. - */ - protected void notifyComplete() { - final String methodName = "notifyComplete"; - //@TRACE 411=>key={0} response={1} excep={2} - log.fine(CLASS_NAME,methodName,"404",new Object[]{getKey(),this.response, this.exception}); - - synchronized (responseLock) { - // If pending complete is set then normally the token can be marked - // as complete and users notified. An abnormal error may have - // caused the client to shutdown beween pending complete being set - // and notifying the user. In this case - the action must be failed. - if (exception == null && pendingComplete) { - completed = true; - pendingComplete = false; - } else { - pendingComplete = false; - } - - responseLock.notifyAll(); - } - synchronized (sentLock) { - sent=true; - sentLock.notifyAll(); - } - } - -// /** -// * Notifies this token that an exception has occurred. This is only -// * used for things like IOException, and not for MQTT NACKs. -// */ -// protected void notifyException() { -// final String methodName = "notifyException"; -// //@TRACE 405=token={0} excep={1} -// log.fine(CLASS_NAME,methodName, "405",new Object[]{this,this.exception}); -// synchronized (responseLock) { -// responseLock.notifyAll(); -// } -// synchronized (sentLock) { -// sentLock.notifyAll(); -// } -// } - - public void waitUntilSent() throws MqttException { - final String methodName = "waitUntilSent"; - synchronized (sentLock) { - synchronized (responseLock) { - if (this.exception != null) { - throw this.exception; - } - } - while (!sent) { - try { - //@TRACE 409=wait key={0} - log.fine(CLASS_NAME,methodName, "409",new Object[]{getKey()}); - - sentLock.wait(); - } catch (InterruptedException e) { - } - } - - while (!sent) { - if (this.exception == null) { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_UNEXPECTED_ERROR); - } - throw this.exception; - } - } - } - - /** - * Notifies this token that the associated message has been sent - * (i.e. written to the TCP/IP socket). - */ - protected void notifySent() { - final String methodName = "notifySent"; - //@TRACE 403=> key={0} - log.fine(CLASS_NAME, methodName, "403",new Object[]{getKey()}); - synchronized (responseLock) { - this.response = null; - this.completed = false; - } - synchronized (sentLock) { - sent = true; - sentLock.notifyAll(); - } - } - - public IMqttAsyncClient getClient() { - return client; - } - - protected void setClient(IMqttAsyncClient client) { - this.client = client; - } - - public void reset() throws MqttException { - final String methodName = "reset"; - if (isInUse() ) { - // Token is already in use - cannot reset - throw new MqttException(MqttException.REASON_CODE_TOKEN_INUSE); - } - //@TRACE 410=> key={0} - log.fine(CLASS_NAME, methodName, "410",new Object[]{getKey()}); - - client = null; - completed = false; - response = null; - sent = false; - exception = null; - userContext = null; - } - - public MqttMessage getMessage() { - return message; - } - - public MqttWireMessage getWireMessage() { - return response; - } - - - public void setMessage(MqttMessage msg) { - this.message = msg; - } - - public String[] getTopics() { - return topics; - } - - public void setTopics(String[] topics) { - this.topics = topics; - } - - public Object getUserContext() { - return userContext; - } - - public void setUserContext(Object userContext) { - this.userContext = userContext; - } - - public void setKey(String key) { - this.key = key; - } - - public String getKey() { - return key; - } - - public void setException(MqttException exception) { - synchronized(responseLock) { - this.exception = exception; - } - } - - public boolean isNotified() { - return notified; - } - - public void setNotified(boolean notified) { - this.notified = notified; - } - - public String toString() { - StringBuffer tok = new StringBuffer(); - tok.append("key=").append(getKey()); - tok.append(" ,topics="); - if (getTopics() != null) { - for (int i=0; i<getTopics().length; i++) { - tok.append(getTopics()[i]).append(", "); - } - } - tok.append(" ,usercontext=").append(getUserContext()); - tok.append(" ,isComplete=").append(isComplete()); - tok.append(" ,isNotified=").append(isNotified()); - tok.append(" ,exception=").append(getException()); - tok.append(" ,actioncallback=").append(getActionCallback()); - - return tok.toString(); - } - - public int[] getGrantedQos() { - int[] val = new int[0]; - if (response instanceof MqttSuback) { - val = ((MqttSuback)response).getGrantedQos(); - } - return val; - } - - public boolean getSessionPresent() { - boolean val = false; - if (response instanceof MqttConnack) { - val = ((MqttConnack)response).getSessionPresent(); - } - return val; - } - - public MqttWireMessage getResponse() { - return response; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/logcat.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/logcat.properties deleted file mode 100644 index b7d0754..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/logcat.properties +++ /dev/null @@ -1,169 +0,0 @@ -0=MQTT Catalog -101=<init> ClientID={0} ServerURI={1} PersistenceType={2} -103=cleanSession={0} connectionTimeout={1} TimekeepAlive={2} userName={3} password={4} will={5} userContext={6} callback={7} -104=> quiesceTimeout={0} userContext={1} callback={2} -105=< exception -106=Subscribe topicFilter={0} userContext={1} callback={2} -107=Unsubscribe topic={0} userContext={1} callback={2} -108=< -109=< -110=< -111=< topic={0} message={1}userContext={1} callback={2} -112=< -113=< -114=> -115=URI={0} -116=URI={0} -117=> -118=<200=internalSend key={0} message={1} token={2} -119=Invalid URI Provided that could not be used to create a NetworkModule: {0} -204=connect failed: rc={0} -207=connect failed: not disconnected {0} -208=failed: not connected -209=connect failed: unexpected exception -210=failed: called on callback thread -211=failed: already disconnected -212=connect failed: unexpected exception -213=fail: token in use: key={0} message={1} token={2} -214=state=CONNECTING -215=state=CONNECTED -216=state=DISCONNECTING -217=state=DISCONNECTED -218=state=DISCONNECTING -219=failed: already disconnecting -220=> -221=> -222=> -223=failed: in closed state -224=failed: not disconnected -250=Failed to create TCP socket -252=connect to host {0} port {1} timeout {2} -260=setEnabledCiphers ciphers={0} -300=key={0} message={1} -302=existing key={0} message={1} token={2} -303=creating new token key={0} message={1} token={2} -305=> {0} tokens -306=key={0} -307=key={0} token={1} -308=<> -309=resp={0} -310=> -311=> -312=> -400=>key={0} timeout={1} sent={2} completed={3} hasException={4} response={5} token={6} -401=failed with exception -402=key={0} response={1} -403=> key={0} -404=>key={0} response={1} excep={2} -406=key={0} timed out token={1} -407=key={0} wait max={1} token={2} -408=key={0} wait max={1} -409=wait key={0} -410=> key={0} -411=>key={0} response={1} excep={2} -500=Attempting to reconnect client: {0} -501=Automatic Reconnect Successful: {0} -502=Automatic Reconnect failed, rescheduling: {0} -503=Start reconnect timer for client: {0}, delay: {1} -504=Stop reconnect timer for client: {0} -505=Rescheduling reconnect timer for client: {0}, delay: {1} -506=Triggering Automatic Reconnect attempt. -507=Client Connected, Offline Buffer available, but not empty. Adding message to buffer. message={0} -508=Client Resting, Offline Buffer available. Adding message to buffer. message={0} -509=Client Reconnected, Offline Buffer Available. Sending Buffered Messages. -510=Publising Buffered message message={0} -511=outbound QoS 0 publish key={0} message={1} -512=QoS 0 publish key={0} -513=Persisted Buffered Message key={0} -514=Failed to persist buffered message key={0} -515=Could not Persist, attempting to Re-Open Persistence Store -516=Restoring all buffered messages. -517=Un-Persisting Buffered message key={0} -518=Failed to Un-Persist Buffered message key={0} -529=Sent {0} -600=> -601=key={0} message={1} -602=key={0} exception -603=clearState -604=inbound QoS 2 publish key={0} message={1} -605=outbound QoS 2 pubrel key={0} message={1} -606=outbound QoS 2 completed key={0} message={1} -607=outbound QoS 2 publish key={0} message={1} -608=outbound QoS 1 publish key={0} message={1} -609=removing orphaned pubrel key={0} -610=QoS 2 publish key={0} -611=QoS 2 pubrel key={0} -612=QoS 1 publish key={0} -613= sending {0} msgs at max inflight window -615=pending send key={0} message {1} -616=checkForActivity entered -617=+1 inflightpubrels={0} -618=key={0} QoS={1} -619=Timed out as no activity, keepAlive={0} lastOutboundActivity={1} lastInboundActivity={2} time={3} lastPing={4} -620=ping needed. keepAlive={0} lastOutboundActivity={1} lastInboundActivity={2} -621=no outstanding flows and not connected -622=inflight window full -623=+1 actualInFlight={0} -624=Schedule next ping at {0} -625=key={0} -626=quiescing={0} actualInFlight={1} pendingFlows={2} inFlightPubRels={3} callbackQuiesce={4} tokens={5} -627=received key={0} message={1} -628=pending publish key={0} qos={1} message={2} -629=received key={0} token={1} message={2} -630=received bytes count={0} -631=connected -632=reason {0} -633=disconnected -634=ping not needed yet. Schedule next ping -635=ping sent. pingOutstanding: {0} -636=ping response received. pingOutstanding: {0} -637=timeout={0} -638=notifying queueLock holders -639=wait for outstanding: actualInFlight={0} pendingFlows={1} inFlightPubRels={2} tokens={3} -640=finished -641=remove publish from persistence. key={0} -642=Timed out as no write activity, keepAlive={0} lastOutboundActivity={1} lastInboundActivity={2} time={3} lastPing={4} -643=sent bytes count={0} -644=wait for new work or for space in the inflight window -645=removed QoS 2 publish/pubrel. key={0}, -1 inFlightPubRels={1} -646=-1 actualInFlight={0} -647=new work or ping arrived -648=key{0}, msg={1}, excep={2} -649=key={0},excep={1} -650=removed Qos 1 publish. key={0} -651=received key={0} message={1} -659=start timer for client:{0} -660=Check schedule at {0} -661=stop -662=no message found for ack id={0} -700=stopping -701=notify workAvailable and wait for run -703=stopped -704=wait for workAvailable -705=callback and notify for key={0} -706=notify spaceAvailable -708=call connectionLost -709=wait for spaceAvailable -710=new msg avail, notify workAvailable -711=quiesce notify spaceAvailable -713=call messageArrived key={0} topic={1} -714=callback threw exception -715=new workAvailable. key={0} -716=call onSuccess key={0} -717=call onFailure key {0} -719=callback threw ex: -720=exception from connectionLost {0} -800=stopping sender -801=stopped -802=network send key={0} msg={1} -803=get message returned null, stopping} -804=exception -805=< -850=stopping -851=stopped -852=network read message -853=Stopping due to IOException -854=< -855=starting -856=Stopping, MQttException -857=Unknown PubAck, PubComp or PubRec received. Ignoring. diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages.properties deleted file mode 100644 index d119133..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages.properties +++ /dev/null @@ -1,37 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Invalid protocol version -2=Invalid client ID -3=Broker unavailable -4=Bad user name or password -5=Not authorized to connect -6=Unexpected error -32000=Timed out waiting for a response from the server -32001=Internal error, caused by no new message IDs being available -32002=Timed out while waiting to write messages to the server -32100=Client is connected -32101=Client is disconnected -32102=Client is currently disconnecting -32103=Unable to connect to server -32104=Client is not connected -32105=The specified SocketFactory type does not match the broker URI -32106=SSL configuration error -32107=Disconnecting is not allowed from a callback method -32108=Unrecognized packet -32109=Connection lost -32110=Connect already in progress -32111=Client is closed -32200=Persistence already in use -32201=Token already in use -32202=Too many publishes in progress diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_cs.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_cs.properties deleted file mode 100644 index c746dd1..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_cs.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Neplatn\u00e1 verze protokolu -2=Neplatn\u00e9 ID klienta -3=Nedostupn\u00fd zprost\u0159edkovatel -4=Chybn\u00e9 jm\u00e9no u\u017eivatele nebo heslo -5=Chyb\u00ed autorizace pro p\u0159ipojen\u00ed -6=Neo\u010dek\u00e1van\u00e1 chyba -32000=Vypr\u0161en\u00ed \u010dasov\u00e9ho limitu pro odpov\u011b\u010f ze serveru -32100=Klient je p\u0159ipojen -32101=Klient je odpojen -32102=Klient se aktu\u00e1ln\u011b odpojuje -32103=Nelze se p\u0159ipojit k serveru -32104=Klient nen\u00ed p\u0159ipojen -32105=Ur\u010den\u00fd typ polo\u017eky SocketFactory neodpov\u00edd\u00e1 identifik\u00e1toru URI zprost\u0159edkovatele. -32106=Chyba konfigurace zabezpe\u010den\u00ed SSL -32107=Z metody zp\u011btn\u00e9ho vol\u00e1n\u00ed nen\u00ed povoleno odpojen\u00ed -32108=Nerozpoznan\u00fd paket -32109=P\u0159ipojen\u00ed bylo ztraceno. -32110=P\u0159ipojen\u00ed ji\u017e prob\u00edh\u00e1 -32111=Klient je zav\u0159en -32200=Perzistence je ji\u017e pou\u017e\u00edv\u00e1na. -32201=Token se ji\u017e pou\u017e\u00edv\u00e1 -32202=Prob\u00edh\u00e1 p\u0159\u00edli\u0161 mnoho publikov\u00e1n\u00ed diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_de.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_de.properties deleted file mode 100644 index bdd4d48..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_de.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Protokollversion ung\u00fcltig -2=Client-ID ung\u00fcltig -3=Broker nicht verf\u00fcgbar -4=Benutzername oder Kennwort falsch -5=Keine Berechtigung f\u00fcr Verbindung -6=Unerwarteter Fehler -32000=Zeitlimit\u00fcberschreitung beim Warten auf eine Antwort vom Server -32100=Verbindung zu Client ist hergestellt -32101=Verbindung zu Client ist getrennt -32102=Verbindung zu Client wird derzeit getrennt -32103=Verbindung zu Server kann nicht hergestellt werden -32104=Keine Verbindung zu Client -32105=Der angegebene Socket-Factorytyp entspricht nicht der Broker-URI -32106=SSL-Konfigurationsfehler -32107=Trennung einer Verbindung \u00fcber eine Callback-Methode ist nicht zul\u00e4ssig -32108=Paket nicht erkannt -32109=Verbindung wurde getrennt -32110=Verbindungsherstellung wird ausgef\u00fchrt -32111=Client ist geschlossen -32200=Persistenz wird bereits verwendet -32201=Token wird bereits verwendet -32202=Zu viele Ver\u00f6ffentlichungen werden ausgef\u00fchrt diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_es.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_es.properties deleted file mode 100644 index 7517e09..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_es.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Versi\u00f3n de protocolo incorrecta -2=Identificador de cliente incorrecto -3=Intermediario no disponible -4=Nombre de usuario o contrase\u00f1a incorrecto -5=No autorizado a conectarse -6=Error inesperado -32000=Tiempo de espera excedido al esperar una respuesta del servidor -32100=El cliente est\u00e1 conectado -32101=El cliente est\u00e1 desconectado -32102=El cliente se est\u00e1 desconectando -32103=No es posible conectarse al servidor -32104=El cliente no est\u00e1 conectado -32105=El tipo SocketFactory especificado no coincide con el URI del intermediario -32106=Error de configuraci\u00f3n SSL -32107=No se permite la desconexi\u00f3n desde un m\u00e9todo de devoluci\u00f3n de llamada -32108=Paquete no reconocido -32109=Se ha perdido la conexi\u00f3n -32110=Conexi\u00f3n ya en curso -32111=El cliente est\u00e1 cerrado -32200=La persistencia ya se est\u00e1 utilizando -32201=La se\u00f1al ya se est\u00e1 utilizando -32202=Demasiadas publicaciones en curso diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_fr.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_fr.properties deleted file mode 100644 index d7b42e4..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_fr.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Version de protocole incorrecte -2=ID client incorrect -3=Courtier indisponible -4=Nom d'utilisateur ou mot de passe incorrect -5=L'utilisateur n'est pas autoris\u00e9 \u00e0 se connecter -6=Erreur inattendue. -32000=Expiration du d\u00e9lai d'attente d'une r\u00e9ponse du serveur -32100=Client connect\u00e9 -32101=Client d\u00e9connect\u00e9 -32102=Client en cours de d\u00e9connexion -32103=Impossible de se connecter au serveur -32104=Client non connect\u00e9 -32105=Le type SocketFactory sp\u00e9cifi\u00e9 ne correspond pas \u00e0 l'URI de courtier -32106=Erreur de configuration SSL -32107=D\u00e9connexion non autoris\u00e9e pour une m\u00e9thode de rappel -32108=Paquet non reconnu -32109=Connexion perdue -32110=Connexion d\u00e9j\u00e0 en cours -32111=Client ferm\u00e9 -32200=La persistance est d\u00e9j\u00e0 en cours d'utilisation -32201=Jeton d\u00e9j\u00e0 en cours d'utilisation -32202=Trop de publications en cours diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_hu.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_hu.properties deleted file mode 100644 index dc4cfe6..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_hu.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\u00c9rv\u00e9nytelen protokoll v\u00e1ltozat -2=\u00c9rv\u00e9nytelen \u00fcgyf\u00e9lazonos\u00edt\u00f3 -3=K\u00f6zvet\u00edt\u0151 nem el\u00e9rhet\u0151 -4=Rossz felhaszn\u00e1l\u00f3i n\u00e9v vagy jelsz\u00f3 -5=Nem jogosult csatlakozni -6=V\u00e1ratlan hiba -32000=T\u00fall\u00e9pte a megengedett id\u0151t a kiszolg\u00e1l\u00f3 v\u00e1lasz\u00e1ra v\u00e1rva -32100=Az \u00fcgyf\u00e9l csatlakoztatva van -32101=Az \u00fcgyf\u00e9l sz\u00e9tkapcsolt -32102=Az \u00fcgyf\u00e9l \u00e9pp megszak\u00edtja a kapcsolatot -32103=Nem lehet kapcsol\u00f3dni a kiszolg\u00e1l\u00f3hoz -32104=Az \u00fcgyf\u00e9l nincs csatlakoztatva -32105=A megadott SocketFactory t\u00edpus nem illeszkedik a k\u00f6zvet\u00edt\u0151 URI azonos\u00edt\u00f3hoz -32106=SSL konfigur\u00e1ci\u00f3s hiba -32107=A megszak\u00edt\u00e1s visszah\u00edv\u00e1s met\u00f3dusb\u00f3l nem enged\u00e9lyezett -32108=Ismeretlen csomag -32109=Kapcsolat elveszett -32110=A csatlakoz\u00e1s m\u00e1r folyamatban van -32111=Az \u00fcgyf\u00e9l bez\u00e1r\u00e1sra ker\u00fclt -32200=A megmarad\u00f3 \u00e1llapot m\u00e1r haszn\u00e1latban van -32201=A token m\u00e1r haszn\u00e1latban van. -32202=T\u00fal sok k\u00f6zz\u00e9t\u00e9tel van folyamatban diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_it.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_it.properties deleted file mode 100644 index e0dcfcc..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_it.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Versione di protocollo non valida -2=ID client non valido -3=Broker non disponibile -4=Nome utente o password non validi -5=Non autorizzato per la connessione -6=Errore imprevisto -32000=Scaduto in attesa di una risposta dal server -32100=Client connesso -32101=Client disconnesso -32102=Client in fase di disconnessione -32103=Impossibile effettuare la connessione al server -32104=Client non connesso -32105=Il tipo SocketFactory specificato non corrisponde all'URI del broker -32106=Errore di configurazione SSL -32107=Disconnessione non consentita da un metodo callback -32108=Pacchetto non riconosciuto -32109=Connessione persa -32110=Connessione gi\u00e0 in corso -32111=Client chiuso -32200=Persistenza gi\u00e0 in uso -32201=Token gi\u00e0 in uso -32202=Numero eccessivo di pubblicazioni in corso diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ja.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ja.properties deleted file mode 100644 index 9f78d2a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ja.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\u7121\u52b9\u306a\u30d7\u30ed\u30c8\u30b3\u30eb\u30fb\u30d0\u30fc\u30b8\u30e7\u30f3\u3067\u3059 -2=\u7121\u52b9\u306a\u30af\u30e9\u30a4\u30a2\u30f3\u30c8 ID \u3067\u3059 -3=\u30d6\u30ed\u30fc\u30ab\u30fc\u304c\u4f7f\u7528\u4e0d\u53ef\u3067\u3059 -4=\u9593\u9055\u3063\u305f\u30e6\u30fc\u30b6\u30fc\u540d\u307e\u305f\u306f\u30d1\u30b9\u30ef\u30fc\u30c9\u3067\u3059 -5=\u63a5\u7d9a\u3059\u308b\u6a29\u9650\u304c\u3042\u308a\u307e\u305b\u3093 -6=\u4e88\u671f\u3057\u306a\u3044\u30a8\u30e9\u30fc -32000=\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u306e\u5fdc\u7b54\u5f85\u6a5f\u304c\u30bf\u30a4\u30e0\u30a2\u30a6\u30c8\u306b\u306a\u308a\u307e\u3057\u305f -32100=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u63a5\u7d9a\u3057\u307e\u3057\u305f -32101=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3092\u5207\u65ad\u3057\u307e\u3057\u305f -32102=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u73fe\u5728\u5207\u65ad\u4e2d\u3067\u3059 -32103=\u30b5\u30fc\u30d0\u30fc\u306b\u63a5\u7d9a\u3067\u304d\u307e\u305b\u3093 -32104=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u63a5\u7d9a\u3055\u308c\u3066\u3044\u307e\u305b\u3093 -32105=\u6307\u5b9a\u3055\u308c\u305f SocketFactory \u30bf\u30a4\u30d7\u306f\u30d6\u30ed\u30fc\u30ab\u30fc URI \u3068\u4e00\u81f4\u3057\u307e\u305b\u3093 -32106=SSL \u69cb\u6210\u30a8\u30e9\u30fc\u3067\u3059 -32107=\u30b3\u30fc\u30eb\u30d0\u30c3\u30af\u30fb\u30e1\u30bd\u30c3\u30c9\u304b\u3089\u306e\u5207\u65ad\u306f\u8a31\u53ef\u3055\u308c\u307e\u305b\u3093 -32108=\u8b58\u5225\u3055\u308c\u3066\u3044\u306a\u3044\u30d1\u30b1\u30c3\u30c8\u3067\u3059 -32109=\u63a5\u7d9a\u55aa\u5931 -32110=\u63a5\u7d9a\u51e6\u7406\u306f\u65e2\u306b\u9032\u884c\u4e2d\u3067\u3059 -32111=\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u30af\u30ed\u30fc\u30ba\u3055\u308c\u307e\u3057\u305f -32200=\u30d1\u30fc\u30b7\u30b9\u30bf\u30f3\u30b9\u306f\u3059\u3067\u306b\u4f7f\u7528\u4e2d\u3067\u3059\u3002 -32201=\u30c8\u30fc\u30af\u30f3\u306f\u65e2\u306b\u4f7f\u7528\u4e2d\u3067\u3059 -32202=\u51e6\u7406\u4e2d\u306e\u30d1\u30d6\u30ea\u30c3\u30b7\u30e5\u304c\u591a\u3059\u304e\u307e\u3059 diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ko.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ko.properties deleted file mode 100644 index 2209928..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ko.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\uc62c\ubc14\ub974\uc9c0 \uc54a\uc740 \ud504\ub85c\ud1a0\ucf5c \ubc84\uc804 -2=\uc62c\ubc14\ub974\uc9c0 \uc54a\uc740 \ud074\ub77c\uc774\uc5b8\ud2b8 ID -3=\ube0c\ub85c\ucee4 \uc0ac\uc6a9 \ubd88\uac00\ub2a5 -4=\uc798\ubabb\ub41c \uc0ac\uc6a9\uc790 \uc774\ub984 \ub610\ub294 \ube44\ubc00\ubc88\ud638 -5=\uc5f0\uacb0\ud560 \uc218 \uc788\ub294 \uad8c\ud55c\uc774 \ubd80\uc5ec\ub418\uc9c0 \uc54a\uc74c -6=\uc608\uc0c1\uce58 \ubabb\ud55c \uc624\ub958 -32000=\uc11c\ubc84\uc5d0\uc11c \uc751\ub2f5\uc744 \uae30\ub2e4\ub9ac\ub294 \uc911 \uc81c\ud55c\uc2dc\uac04 \ucd08\uacfc -32100=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc5f0\uacb0\ub428 -32101=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc5f0\uacb0\uc774 \ub04a\uae40 -32102=\ud604\uc7ac \ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc5f0\uacb0\uc744 \ub04a\ub294 \uc911 -32103=\uc11c\ubc84\uc5d0 \uc5f0\uacb0\ud560 \uc218 \uc5c6\uc74c -32104=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \uc5f0\uacb0\ub418\uc9c0 \uc54a\uc74c -32105=\uc9c0\uc815\ub41c SocketFactory \uc720\ud615\uc774 \ube0c\ub85c\ucee4 URI\uc640 \uc77c\uce58\ud558\uc9c0 \uc54a\uc74c -32106=SSL \uad6c\uc131 \uc624\ub958 -32107=\ucf5c\ubc31 \uba54\uc18c\ub4dc\ub85c\ubd80\ud130 \uc5f0\uacb0\uc744 \ub04a\ub294 \uac83\uc774 \ud5c8\uc6a9\ub418\uc9c0 \uc54a\uc74c -32108=\uc778\uc2dd\ub418\uc9c0 \uc54a\uc740 \ud328\ud0b7 -32109=\uc5f0\uacb0 \uc720\uc2e4 -32110=\uc5f0\uacb0\uc774 \uc774\ubbf8 \uc9c4\ud589 \uc911\uc784 -32111=\ud074\ub77c\uc774\uc5b8\ud2b8\uac00 \ub2eb\ud798 -32200=\uc9c0\uc18d \ud30c\uc77c\uc744 \uc774\ubbf8 \uc0ac\uc6a9 \uc911 -32201=\ud1a0\ud070\uc774 \uc774\ubbf8 \uc0ac\uc6a9 \uc911\uc784 -32202=\ub108\ubb34 \ub9ce\uc740 \ubc1c\ud589\uc774 \uc9c4\ud589 \uc911\uc784 diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pl.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pl.properties deleted file mode 100644 index 255175c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pl.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Niepoprawna wersja protoko\u0142u -2=Niepoprawny identyfikator klienta -3=Broker niedost\u0119pny -4=Niepoprawna nazwa u\u017cytkownika lub has\u0142o -5=Brak autoryzacji do nawi\u0105zania po\u0142\u0105czenia -6=Nieoczekiwany b\u0142\u0105d -32000=Przekroczono limit czasu oczekiwania na odpowied\u017a z serwera -32100=Po\u0142\u0105czenie z klientem zosta\u0142o nawi\u0105zane -32101=Po\u0142\u0105czenie z klientem zosta\u0142o roz\u0142\u0105czone -32102=Klient roz\u0142\u0105cza si\u0119 -32103=Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia z serwerem -32104=Po\u0142\u0105czenie z klientem nie jest nawi\u0105zane -32105=Podany typ fabryki SocketFactory nie jest zgodny z identyfikatorem URI brokera -32106=B\u0142\u0105d konfiguracji protoko\u0142u SSL -32107=Roz\u0142\u0105czenie nie jest dozwolone w metodzie procedury zwrotnej -32108=Nierozpoznany pakiet -32109=Utracono po\u0142\u0105czenie -32110=Operacja nawi\u0105zywania po\u0142\u0105czenia jest ju\u017c w toku -32111=Klient zosta\u0142 zamkni\u0119ty -32200=Trwa\u0142o\u015b\u0107 jest ju\u017c w u\u017cyciu -32201=Znacznik jest ju\u017c w u\u017cyciu -32202=Zbyt wiele operacji publikowania jest w toku diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pt_BR.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pt_BR.properties deleted file mode 100644 index f9345ad..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_pt_BR.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=Vers\u00e3o de protocolo inv\u00e1lida -2=ID de cliente inv\u00e1lido -3=Broker indispon\u00edvel -4=Nome de usu\u00e1rio ou senha inv\u00e1lidos -5=N\u00e3o autorizado a conectar -6=Erro inesperado -32000=Tempo limite atingido ao aguardar por uma resposta do servidor -32100=O cliente est\u00e1 conectado -32101=O cliente est\u00e1 desconectado -32102=Cliente desconectando atualmente -32103=N\u00e3o \u00e9 poss\u00edvel se conectar ao servidor -32104=O cliente n\u00e3o est\u00e1 conectado -32105=O tipo SocketFactory especificado n\u00e3o corresponde ao URI do broker -32106=Erro de configura\u00e7\u00e3o de SSL -32107=A desconex\u00e3o n\u00e3o \u00e9 permitida a partir de um m\u00e9todo de retorno de chamada -32108=Pacote n\u00e3o reconhecido -32109=Conex\u00e3o perdida -32110=A conex\u00e3o j\u00e1 est\u00e1 em andamento -32111=O cliente foi encerrado -32200=Persist\u00eancia j\u00e1 em uso -32201=O token j\u00e1 est\u00e1 em uso -32202=Muitas publica\u00e7\u00f5es em andamento diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ru.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ru.properties deleted file mode 100644 index 39fe6b6..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_ru.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 -2=\u041d\u0435\u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0439 \u0418\u0414 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 -3=\u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d -4=\u041e\u0448\u0438\u0431\u043e\u0447\u043d\u043e\u0435 \u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u043f\u0430\u0440\u043e\u043b\u044c -5=\u041d\u0435\u0442 \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 -6=\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 -32000=\u0422\u0430\u043c-\u0430\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 -32100=\u041a\u043b\u0438\u0435\u043d\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d -32101=\u041a\u043b\u0438\u0435\u043d\u0442 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d -32102=\u041a\u043b\u0438\u0435\u043d\u0442 \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f -32103=\u041d\u0435 \u0443\u0434\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 -32104=\u041a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d -32105=\u0422\u0438\u043f SocketFactory \u043d\u0435 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 URI \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430 -32106=\u041e\u0448\u0438\u0431\u043a\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 SSL -32107=\u041e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043d\u0435 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u043e \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 -32108=\u041d\u0435\u0440\u0430\u0441\u043f\u043e\u0437\u043d\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 -32109=\u0421\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u043f\u043e\u0442\u0435\u0440\u044f\u043d\u043e -32110=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 -32111=\u041a\u043b\u0438\u0435\u043d\u0442 \u0437\u0430\u043a\u0440\u044b\u0442 -32200=\u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f -32201=\u041c\u0430\u0440\u043a\u0435\u0440 \u0443\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f -32202=\u0412\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u043c\u043d\u043e\u0433\u043e \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u0439 diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_CN.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_CN.properties deleted file mode 100644 index 8483ef8..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_CN.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\u65e0\u6548\u534f\u8bae\u7248\u672c -2=\u65e0\u6548\u5ba2\u6237\u673a\u6807\u8bc6 -3=\u4ee3\u7406\u7a0b\u5e8f\u4e0d\u53ef\u7528 -4=\u9519\u8bef\u7684\u7528\u6237\u540d\u6216\u5bc6\u7801 -5=\u65e0\u6743\u8fde\u63a5 -6=\u610f\u5916\u9519\u8bef -32000=\u7b49\u5f85\u6765\u81ea\u670d\u52a1\u5668\u7684\u54cd\u5e94\u65f6\u8d85\u65f6 -32100=\u5df2\u8fde\u63a5\u5ba2\u6237\u673a -32101=\u5df2\u65ad\u5f00\u5ba2\u6237\u673a\u8fde\u63a5 -32102=\u5ba2\u6237\u673a\u6b63\u5728\u65ad\u5f00\u8fde\u63a5 -32103=\u65e0\u6cd5\u8fde\u63a5\u81f3\u670d\u52a1\u5668 -32104=\u5ba2\u6237\u673a\u672a\u8fde\u63a5 -32105=\u6307\u5b9a\u7684 SocketFactory \u7c7b\u578b\u4e0e\u4ee3\u7406\u7a0b\u5e8f URI \u4e0d\u5339\u914d -32106=SSL \u914d\u7f6e\u9519\u8bef -32107=\u4e0d\u5141\u8bb8\u901a\u8fc7\u56de\u8c03\u65b9\u6cd5\u65ad\u5f00\u8fde\u63a5 -32108=\u4e0d\u53ef\u8bc6\u522b\u7684\u5305 -32109=\u5df2\u65ad\u5f00\u8fde\u63a5 -32110=\u5df2\u5728\u8fdb\u884c\u8fde\u63a5 -32111=\u5ba2\u6237\u673a\u5df2\u5173\u95ed -32200=\u6301\u4e45\u6027\u5df2\u5728\u4f7f\u7528\u4e2d -32201=\u4ee4\u724c\u5df2\u5728\u4f7f\u7528\u4e2d -32202=\u6b63\u5728\u8fdb\u884c\u8fc7\u591a\u7684\u53d1\u5e03 diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_TW.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_TW.properties deleted file mode 100644 index 846f1b6..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/nls/messages_zh_TW.properties +++ /dev/null @@ -1,35 +0,0 @@ -#/* -# * Copyright (c) 2009, 2012 IBM Corp. -# * -# * 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 -# * -# * Contributors: -# * Dave Locke - initial API and implementation and/or initial documentation -# */ -# NLS_MESSAGEFORMAT_VAR -# NLS_ENCODING=UNICODE -1=\u901a\u8a0a\u5354\u5b9a\u7248\u672c\u7121\u6548 -2=\u7528\u6236\u7aef ID \u7121\u6548 -3=\u5206\u914d\u7ba1\u7406\u7cfb\u7d71\u7121\u6cd5\u4f7f\u7528 -4=\u4f7f\u7528\u8005\u540d\u7a31\u6216\u5bc6\u78bc\u4e0d\u7576 -5=\u672a\u7372\u6388\u6b0a\u9023\u63a5 -6=\u975e\u9810\u671f\u7684\u932f\u8aa4 -32000=\u7b49\u5f85\u4f3a\u670d\u5668\u7684\u56de\u61c9\u6642\u903e\u6642 -32100=\u5df2\u9023\u63a5\u7528\u6236\u7aef -32101=\u5df2\u4e2d\u65b7\u7528\u6236\u7aef\u7684\u9023\u63a5 -32102=\u7528\u6236\u7aef\u76ee\u524d\u6b63\u5728\u4e2d\u65b7\u9023\u7dda -32103=\u7121\u6cd5\u9023\u63a5\u5230\u4f3a\u670d\u5668 -32104=\u7528\u6236\u7aef\u672a\u9023\u63a5 -32105=\u6307\u5b9a\u7684 SocketFactory \u985e\u578b\u8207\u5206\u914d\u7ba1\u7406\u7cfb\u7d71 URI \u4e0d\u7b26 -32106=SSL \u914d\u7f6e\u932f\u8aa4 -32107=\u4e0d\u5bb9\u8a31\u8207\u56de\u547c\u65b9\u6cd5\u4e2d\u65b7\u9023\u7dda -32108=\u5c01\u5305\u7121\u6cd5\u8fa8\u8b58 -32109=\u9023\u7dda\u907a\u5931 -32110=\u9023\u63a5\u5df2\u5728\u9032\u884c\u4e2d -32111=\u5df2\u95dc\u9589\u7528\u6236\u7aef -32200=\u6301\u7e8c\u6027\u5df2\u5728\u4f7f\u7528\u4e2d -32201=\u8a18\u865f\u5df2\u5728\u4f7f\u7528\u4e2d -32202=\u592a\u591a\u767c\u4f48\u9032\u884c\u4e2d diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SSLSocketFactoryFactory.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SSLSocketFactoryFactory.java deleted file mode 100644 index 25d94f2..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SSLSocketFactoryFactory.java +++ /dev/null @@ -1,1358 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.security; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.NoSuchProviderException; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.Properties; -import java.util.Set; -import java.util.Vector; - -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSocketFactory; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -import org.eclipse.paho.client.mqttv3.MqttSecurityException; -import org.eclipse.paho.client.mqttv3.logging.Logger; - - -/** - * An SSLSocketFactoryFactory provides a socket factory and a server socket - * factory that then can be used to create SSL client sockets or SSL server - * sockets. - * <p> - * The SSLSocketFactoryFactory is configured using IBM SSL properties, i.e. - * properties of the format "com.ibm.ssl.propertyName", e.g. - * "com.ibm.ssl.keyStore". The class supports multiple configurations, each - * configuration is identified using a name or configuration ID. The - * configuration ID with "null" is used as a default configuration. When a - * socket factory is being created for a given configuration, properties of that - * configuration are first picked. If a property is not defined there, then that - * property is looked up in the default configuration. Finally, if a property - * element is still not found, then the corresponding system property is - * inspected, i.e. javax.net.ssl.keyStore. If the system property is not set - * either, then the system's default value is used (if available) or an - * exception is thrown. - * <p> - * The SSLSocketFacotryFactory can be reconfigured at any time. A - * reconfiguration does not affect existing socket factories. - * <p> - * All properties share the same key space; i.e. the configuration ID is not - * part of the property keys. - * <p> - * The methods should be called in the following order: - * <ol> - * <li><b>isSupportedOnJVM()</b>: to check whether this class is supported on - * the runtime platform. Not all runtimes support SSL/TLS.</li> - * <li><b>SSLSocketFactoryFactory()</b>: the constructor. Clients - * (in the same JVM) may share an SSLSocketFactoryFactory, or have one each.</li> - * <li><b>initialize(properties, configID)</b>: to initialize this object with - * the required SSL properties for a configuration. This may be called multiple - * times, once for each required configuration.It may be called again to change the required SSL - * properties for a particular configuration</li> - * <li><b>getEnabledCipherSuites(configID)</b>: to later set the enabled - * cipher suites on the socket [see below].</li> - * </ol> - * <ul> - * <li><i>For an MQTT server:</i> - - * <ol> - * <li><b>getKeyStore(configID)</b>: Optionally, to check that if there is no - * keystore, then that all the enabled cipher suits are anonymous.</li> - * <li><b>createServerSocketFactory(configID)</b>: to create an - * SSLServerSocketFactory.</li> - * <li><b>getClientAuthentication(configID)</b>: to later set on the - * SSLServerSocket (itself created from the SSLServerSocketFactory) whether - * client authentication is needed.</li> - * </ol> - * </li> - * <li><i>For an MQTT client:</i> - * <ol> - * <li><b>createSocketFactory(configID)</b>: to create an SSLSocketFactory.</li> - * </ol> - * </li> - * </ul> - */ -public class SSLSocketFactoryFactory { - private static final String CLASS_NAME = "org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory"; - /** - * Property keys specific to the client). - */ - public static final String SSLPROTOCOL="com.ibm.ssl.protocol"; - public static final String JSSEPROVIDER="com.ibm.ssl.contextProvider"; - public static final String KEYSTORE="com.ibm.ssl.keyStore"; - public static final String KEYSTOREPWD="com.ibm.ssl.keyStorePassword"; - public static final String KEYSTORETYPE="com.ibm.ssl.keyStoreType"; - public static final String KEYSTOREPROVIDER="com.ibm.ssl.keyStoreProvider"; - public static final String KEYSTOREMGR="com.ibm.ssl.keyManager"; - public static final String TRUSTSTORE="com.ibm.ssl.trustStore"; - public static final String TRUSTSTOREPWD="com.ibm.ssl.trustStorePassword"; - public static final String TRUSTSTORETYPE="com.ibm.ssl.trustStoreType"; - public static final String TRUSTSTOREPROVIDER="com.ibm.ssl.trustStoreProvider"; - public static final String TRUSTSTOREMGR="com.ibm.ssl.trustManager"; - public static final String CIPHERSUITES="com.ibm.ssl.enabledCipherSuites"; - public static final String CLIENTAUTH="com.ibm.ssl.clientAuthentication"; - - /** - * Property keys used for java system properties - */ - public static final String SYSKEYSTORE="javax.net.ssl.keyStore"; - public static final String SYSKEYSTORETYPE="javax.net.ssl.keyStoreType"; - public static final String SYSKEYSTOREPWD="javax.net.ssl.keyStorePassword"; - public static final String SYSTRUSTSTORE="javax.net.ssl.trustStore"; - public static final String SYSTRUSTSTORETYPE="javax.net.ssl.trustStoreType"; - public static final String SYSTRUSTSTOREPWD="javax.net.ssl.trustStorePassword"; - public static final String SYSKEYMGRALGO="ssl.KeyManagerFactory.algorithm"; - public static final String SYSTRUSTMGRALGO="ssl.TrustManagerFactory.algorithm"; - - - public static final String DEFAULT_PROTOCOL = "TLS"; // "SSL_TLS" is not supported by DesktopEE - - private static final String propertyKeys[] = { SSLPROTOCOL, JSSEPROVIDER, - KEYSTORE, KEYSTOREPWD, KEYSTORETYPE, KEYSTOREPROVIDER, KEYSTOREMGR, - TRUSTSTORE, TRUSTSTOREPWD, TRUSTSTORETYPE, TRUSTSTOREPROVIDER, - TRUSTSTOREMGR, CIPHERSUITES, CLIENTAUTH}; - - private Hashtable configs; // a hashtable that maps configIDs to properties. - - private Properties defaultProperties; - - private static final byte[] key = { (byte) 0x9d, (byte) 0xa7, (byte) 0xd9, - (byte) 0x80, (byte) 0x05, (byte) 0xb8, (byte) 0x89, (byte) 0x9c }; - - private static final String xorTag = "{xor}"; - - private Logger logger = null; - - - /** - * Not all of the JVM/Platforms support all of its - * security features. This method determines if is supported. - * - * @return whether dependent classes can be instantiated on the current - * JVM/platform. - * - * @throws Error - * if any unexpected error encountered whilst checking. Note - * this should not be a ClassNotFoundException, which should - * cause the method to return false. - */ - public static boolean isSupportedOnJVM() throws LinkageError, ExceptionInInitializerError { - String requiredClassname = "javax.net.ssl.SSLServerSocketFactory"; - try { - Class.forName(requiredClassname); - } catch (ClassNotFoundException e) { - return false; - } - return true; - } - - - /** - * Create new instance of class. - * Constructor used by clients. - */ - public SSLSocketFactoryFactory() { - configs = new Hashtable(); - } - - /** - * Create new instance of class. - * Constructor used by the broker. - * @param logger the {@link Logger} to be used - */ - public SSLSocketFactoryFactory(Logger logger) { - this(); - this.logger = logger; - } - - /** - * Checks whether a key belongs to the supported IBM SSL property keys. - * - * @param key - * @return whether a key belongs to the supported IBM SSL property keys. - */ - private boolean keyValid(String key) { - int i = 0; - while (i < propertyKeys.length) { - if (propertyKeys[i].equals(key)) { - break; - } - ++i; - } - return i < propertyKeys.length; - } - - /** - * Checks whether the property keys belong to the supported IBM SSL property - * key set. - * - * @param properties - * @throws IllegalArgumentException - * if any of the properties is not a valid IBM SSL property key. - */ - private void checkPropertyKeys(Properties properties) - throws IllegalArgumentException { - Set keys = properties.keySet(); - Iterator i = keys.iterator(); - while (i.hasNext()) { - String k = (String) i.next(); - if (!keyValid(k)) { - throw new IllegalArgumentException(k + " is not a valid IBM SSL property key."); - } - } - } - - /** - * Convert byte array to char array, where each char is constructed from two - * bytes. - * - * @param b - * byte array - * @return char array - */ - public static char[] toChar(byte[] b) { - if(b==null) return null; - char[] c= new char[b.length/2]; - int i=0; int j=0; - while(i<b.length) { - c[j++] = (char) ((b[i++] & 0xFF) + ((b[i++] & 0xFF)<<8)); - } - return c; - } - - /** - * Convert char array to byte array, where each char is split into two - * bytes. - * - * @param c - * char array - * @return byte array - */ - public static byte[] toByte(char[] c) { - if(c==null) return null; - byte[] b=new byte[c.length*2]; - int i=0; int j=0; - while(j<c.length) { - b[i++] = (byte) (c[j] & 0xFF); - b[i++] = (byte) ((c[j++] >> 8)& 0xFF); - } - return b; - } - - /** - * Obfuscates the password using a simple and not very secure XOR mechanism. - * This should not be used for cryptographical purpose, it's a simple - * scrambler to obfuscate clear-text passwords. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#deObfuscate - * - * @param password - * The password to be encrypted, as a char[] array. - * @return An obfuscated password as a String. - */ - public static String obfuscate(char[] password) { - if (password == null) - return null; - byte[] bytes = toByte(password); - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte) ((bytes[i] ^ key[i % key.length]) & 0x00ff); - } - String encryptedValue = xorTag - + new String(SimpleBase64Encoder.encode(bytes)); - return encryptedValue; - } - - /** - * The inverse operation of obfuscate: returns a cleartext password that was - * previously obfuscated using the XOR scrambler. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#obfuscate - * - * @param ePassword - * An obfuscated password. - * @return An array of char, containing the clear text password. - */ - public static char[] deObfuscate(String ePassword) { - if (ePassword == null) - return null; - byte[] bytes = null; - try { - bytes = SimpleBase64Encoder.decode(ePassword.substring(xorTag - .length())); - } catch (Exception e) { - return null; - } - - for (int i = 0; i < bytes.length; i++) { - bytes[i] = (byte) ((bytes[i] ^ key[i % key.length]) & 0x00ff); - } - return toChar(bytes); - } - - /** - * Converts an array of ciphers into a single String. - * - * @param ciphers - * The array of cipher names. - * @return A string containing the name of the ciphers, separated by comma. - */ - public static String packCipherSuites(String[] ciphers) { - String cipherSet=null; - if (ciphers != null) { - StringBuffer buf = new StringBuffer(); - for (int i = 0; i < ciphers.length; i++) { - buf.append(ciphers[i]); - if (i < ciphers.length - 1) { - buf.append(','); - } - } - cipherSet = buf.toString(); - } - return cipherSet; - } - - /** - * Inverse operation of packCipherSuites: converts a string of cipher names - * into an array of cipher names - * - * @param ciphers - * A list of ciphers, separated by comma. - * @return An array of string, each string containing a single cipher name. - */ - public static String[] unpackCipherSuites(String ciphers) { - // can't use split as split is not available on all java platforms. - if(ciphers==null) return null; - Vector c=new Vector(); - int i=ciphers.indexOf(','); - int j=0; - // handle all commas. - while(i>-1) { - // add stuff before and up to (but not including) the comma. - c.add(ciphers.substring(j, i)); - j=i+1; // skip the comma. - i=ciphers.indexOf(',',j); - } - // add last element after the comma or only element if no comma is present. - c.add(ciphers.substring(j)); - String[] s = new String[c.size()]; - c.toArray(s); - return s; - } - - /** - * Obfuscate any key & trust store passwords within the given properties. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#obfuscate - * - * @param p - * properties - */ - private void convertPassword(Properties p) { - String pw = p.getProperty(KEYSTOREPWD); - if (pw != null && !pw.startsWith(xorTag)) { - String epw = obfuscate(pw.toCharArray()); - p.put(KEYSTOREPWD, epw); - } - pw = p.getProperty(TRUSTSTOREPWD); - if (pw != null && !pw.startsWith(xorTag)) { - String epw = obfuscate(pw.toCharArray()); - p.put(TRUSTSTOREPWD, epw); - } - } - - /** - * Returns the properties object for configuration configID or creates a new - * one if required. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return the properties object for configuration configID - */ -// private Properties getOrCreate(String configID) { -// Properties res = null; -// if (configID == null) { -// if (this.defaultProperties == null) { -// this.defaultProperties = new Properties(); -// } -// res = this.defaultProperties; -// } else { -// res = (Properties) this.configs.get(configID); -// if (res == null) { -// res = new Properties(); -// this.configs.put(configID, res); -// } -// } -// return res; -// } - - /** - * Initializes the SSLSocketFactoryFactory with the provided properties for - * the provided configuration. - * - * @param props - * A properties object containing IBM SSL properties that are - * qualified by one or more configuration identifiers. - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @throws IllegalArgumentException - * if any of the properties is not a valid IBM SSL property key. - */ - public void initialize(Properties props, String configID) - throws IllegalArgumentException { - checkPropertyKeys(props); - // copy the properties. - Properties p = new Properties(); - p.putAll(props); - convertPassword(p); - if (configID != null) { - this.configs.put(configID, p); - } else { - this.defaultProperties = p; - } - } - - /** - * Merges the given IBM SSL properties into the existing configuration, - * overwriting existing properties. This method is used to selectively - * change properties for a given configuration. The method throws an - * IllegalArgumentException if any of the properties is not a valid IBM SSL - * property key. - * - * @param props - * A properties object containing IBM SSL properties - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @throws IllegalArgumentException - * if any of the properties is not a valid IBM SSL property key. - */ - public void merge(Properties props, String configID) - throws IllegalArgumentException { - checkPropertyKeys(props); - Properties p = this.defaultProperties; - if (configID != null) { - p = (Properties) this.configs.get(configID); - } - if (p == null) { - p = new Properties(); - } - convertPassword(props); - p.putAll(props); - if (configID != null) { - this.configs.put(configID, p); - } else { - this.defaultProperties = p; - } - - } - - /** - * Remove the configuration of a given configuration identifier. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return true, if the configuation could be removed. - */ - public boolean remove(String configID) { - boolean res = false; - if (configID != null) { - res = this.configs.remove(configID) != null; - } else { - if(null != this.defaultProperties) { - res = true; - this.defaultProperties = null; - } - } - return res; - } - - /** - * Returns the configuration of the SSLSocketFactoryFactory for a given - * configuration. Note that changes in the property are reflected in the - * SSLSocketFactoryFactory. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return A property object containing the current configuration of the - * SSLSocketFactoryFactory. Note that it could be null. - */ - public Properties getConfiguration(String configID) { - return (Properties) (configID == null ? this.defaultProperties - : this.configs.get(configID)); - } - - /** - * @return Returns the set of configuration IDs that exist in the SSLSocketFactoryFactory. - */ -// public String[] getConfigurationIDs() { -// Set s = this.configs.keySet(); -// String[] configs = new String[s.size()]; -// configs = (String[]) s.toArray(configs); -// return configs; -// } - - /** - * If the value is not null, then put it in the properties object using the - * key. If the value is null, then remove the entry in the properties object - * with the key. - * - * @param p - * @param key - * @param value - */ -// private final void putOrRemove(Properties p, String key, String value) { -// if (value == null) { -// p.remove(key); -// } else { -// p.put(key, value); -// } -// } - - /** - * Sets the SSL protocol variant. If protocol is NULL then an existing value - * will be removed. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param protocol - * One of SSL, SSLv3, TLS, TLSv1, SSL_TLS - */ -// public void setSSLProtocol(String configID, String protocol) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, SSLPROTOCOL, protocol); -// } - - /** - * Sets the JSSE context provider. If provider is null, then an existing - * value will be removed. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param provider - * The JSSE provider. For example "IBMJSSE2" or "SunJSSE". - */ -// public void setJSSEProvider(String configID, String provider) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, JSSEPROVIDER, provider); -// } - - /** - * Sets the filename of the keyStore object. A null value is ignored. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param keyStore - * A filename that points to a valid keystore. - */ -// public void setKeyStore(String configID, String keyStore) { -// if (keyStore == null) -// return; -// Properties p = getOrCreate(configID); -// putOrRemove(p, KEYSTORE, keyStore); -// } - - /** - * Sets the password that is used for the keystore. The password must be - * provided in plain text, but it will be stored internally in a scrambled - * XOR format. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#obfuscate - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param password - * The keystore password - */ -// public void setKeyStorePassword(String configID, char[] password) { -// if (password == null) -// return; -// Properties p = getOrCreate(configID); -// // convert password, using XOR-based scrambling. -// String ePasswd = obfuscate(password); -// for(int i=0;i<password.length;i++) { -// password[i]=' '; -// } -// putOrRemove(p, KEYSTOREPWD, ePasswd); -// } - - /** - * Sets the keystore provider. The corresponding provider must be installed - * in the system. Example values: "IBMJCE" or "IBMJCEFIPS". - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param provider - * The name of a java cryptography extension - */ -// public void setKeyStoreProvider(String configID, String provider) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, KEYSTOREPROVIDER, provider); -// } - - /** - * Sets the keystore type. For example, PKCS12, JKS or JCEKS. The types that - * are supported depend on the keystore provider. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param type - * The keystore type - */ -// public void setKeyStoreType(String configID, String type) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, KEYSTORETYPE, type); -// } - - /** - * Sets a custom key manager and the algorithm that it uses. The keymanager - * is specified in the format "algorithm|provider", for example - * "IbmX509|IBMJSSE2". The provider might be empty, in which case the - * default provider is configured with the specified algorithm. The key - * manager must implement the javax.net.ssl.X509KeyManager interface. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param keymanager - * An algorithm, provider pair as secified above. - */ -// public void setCustomKeyManager(String configID, String keymanager) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, CUSTOMKEYMGR, keymanager); -// } - - /** - * Sets the filename of the truststore object. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param trustStore - * A filename that points to a valid truststore. - */ -// public void setTrustStore(String configID, String trustStore) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, TRUSTSTORE, trustStore); -// } - - /** - * Sets the password that is used for the truststore. The password must be - * provided in plain text, but it will be stored internally in a scrambled - * XOR format. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#obfuscate - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param password - * The truststore password. - */ -// public void setTrustStorePassword(String configID, char[] password) { -// Properties p = getOrCreate(configID); -// // convert password, using XOR-based scrambling. -// String ePasswd = obfuscate(password); -// for(int i=0;i<password.length;i++) { -// password[i]=' '; -// } -// putOrRemove(p, TRUSTSTOREPWD, ePasswd); -// } - - /** - * Sets the truststore provider. The corresponding provider must be - * installed in the system. Example values: "IBMJCE" or "IBMJCEFIPS". - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param provider - * The name of a java cryptography extension. - */ -// public void setTrustStoreProvider(String configID, String provider) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, TRUSTSTOREPROVIDER, provider); -// } - - /** - * Sets the truststore type. For example, PKCS12, JKS or JCEKS. The types - * that are supported depend on the truststore provider. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param type - * The truststore type. - */ -// public void setTrustStoreType(String configID, String type) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, TRUSTSTORETYPE, type); -// } - - /** - * Sets a custom trust managers and the algorithm that it uses. The - * trustmanager is specified in the format "algorithm|provider", for example - * "IbmX509|IBMJSSE2". The provider might be empty, in which case the - * default provider is configured with the specified algorithm. The trust - * manager must implement the javax.net.ssl.X509TrustManager interface. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param trustmanager - * An algorithm, provider pair as secified above. - */ -// public void setCustomTrustManager(String configID, String trustmanager) { -// Properties p = getOrCreate(configID); -// putOrRemove(p, CUSTOMTRUSTMGR, trustmanager); -// } - - /** - * Sets the list of enabled ciphers. For a list of acceptable values, see - * the documentation of the underlying JSSE. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param ciphers - * An array of cipher suite names such as - * SSL_RSA_WITH_AES_128_CBC_SHA. - */ -// public void setEnabledCipherSuites(String configID, String[] ciphers) { -// if (ciphers == null) -// return; -// Properties p = getOrCreate(configID); -// String cipherSet = packCipherSuites(ciphers); -// putOrRemove(p, CIPHERSUITES, cipherSet); -// } - - /** - * Specifies whether the client is required to provide a valid certificate - * to the client during SSL negotiation. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param clientAuth - * true, if clients are required to authenticate, false - * otherwise. - */ -// public void setClientAuthentication(String configID, boolean clientAuth) { -// Properties p = getOrCreate(configID); -// p.put(CLIENTAUTH, Boolean.toString(clientAuth)); -// } - - /** - * Returns the property of a given key or null if it doesn't exist. It first - * scans the indicated configuration, then the default configuration, then - * the system properties. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param ibmKey - * @param sysProperty - * The key for the System property. - * @return the property of a given key or null if it doesn't exist. - */ - private String getProperty(String configID, String ibmKey, String sysProperty) { - String res = null; - res = getPropertyFromConfig(configID, ibmKey); - if ( res != null ) { - return res; - } - // scan system property, if it exists. - if (sysProperty != null) { - res = System.getProperty(sysProperty); - } - return res; - } - - /** - * Returns the property of a given key or null if it doesn't exist. It first - * scans the indicated configuration, then the default configuration - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @param ibmKey - * @return the property of a given key or null if it doesn't exist. It first - * scans the indicated configuration, then the default configuration - */ - private String getPropertyFromConfig(String configID, String ibmKey) { - String res = null; - Properties p =null; - if(configID!=null) {; - p = (Properties) configs.get(configID); - } - if (p != null) { - res = p.getProperty(ibmKey); - if (res != null) - return res; - } - // not found in config. try default properties. - p = (Properties) this.defaultProperties; - if (p != null) { - res = p.getProperty(ibmKey); - if (res != null) - return res; - } - return res; - } - - /** - * Gets the SSL protocol variant of the indicated configuration or the - * default configuration. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The SSL protocol variant. - */ - public String getSSLProtocol(String configID) { - return getProperty(configID, SSLPROTOCOL, null); - } - - /** - * Gets the JSSE provider of the indicated configuration - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The JSSE provider. - */ - public String getJSSEProvider(String configID) { - return getProperty(configID, JSSEPROVIDER, null); - } - -// /** -// * Get the XPD Keystore if running on the XPD platform (otherwise null). -// * -// * @return the XPD Keystore if running on the XPD platform (otherwise null). -// * @throws MqttDirectException -// */ -// private KeyStore getXPDKeystore() throws MqttDirectException { -// KeyStore keyStore = null; -// try { -// Class secPlatClass = Class.forName("com.ibm.rcp.security.auth.SecurePlatform"); -// Method m = secPlatClass.getMethod("getKeyStore", null); -// Object secPlat = m.invoke(null,null); // getKeyStore is static -// m = secPlatClass.getMethod("isLoggedIn", null); -// Boolean b = (Boolean) m.invoke(secPlat, null); -// if (b.booleanValue()) { -// // login to secure platform was done. -// m = secPlatClass.getMethod("getKeyStore", null); -// keyStore = (KeyStore) m.invoke(secPlat, null); -// } -// } catch (ClassNotFoundException e) { -// /* -// * DEVELOPER NOTE: This is not an error. This means that we are not -// * running on XPD runtime and therefore we can not get XPD keystore. -// * [Next step for the caller, is try to get the keystore from System -// * properties (see getKeyStore() method).] -// */ -// } catch (IllegalAccessException e) { -// Object[] inserts = { e.getLocalizedMessage() }; -// throw new MqttSSLInitException(3026, inserts, e); -// } catch (SecurityException e) { -// Object[] inserts = { e.getLocalizedMessage() }; -// throw new MqttSSLInitException(3026, inserts, e); -// } catch (NoSuchMethodException e) { -// Object[] inserts = { e.getLocalizedMessage() }; -// throw new MqttSSLInitException(3026, inserts, e); -// } catch (IllegalArgumentException e) { -// Object[] inserts = { e.getLocalizedMessage() }; -// throw new MqttSSLInitException(3026, inserts, e); -// } catch (InvocationTargetException e) { -// Object[] inserts = { e.getLocalizedMessage() }; -// throw new MqttSSLInitException(3026, inserts, e); -// } -// return keyStore; -// } - - /** - * Gets the name of the keystore file that is used. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The name of the file that contains the keystore. - */ - public String getKeyStore(String configID) { //throws MqttDirectException { - String ibmKey = KEYSTORE; - String sysProperty = SYSKEYSTORE; - - String res = null; - res = getPropertyFromConfig(configID, ibmKey); - if ( res != null ) { - return res; - } - -// // check for the XPD keystore here -// if ( ibmKey != null && ibmKey.equals(KEYSTORE) ) { -// KeyStore keyStore = getXPDKeystore(); -// if (keyStore != null) -// return res = "Lotus Expeditor"; -// } - - // scan system property, if it exists. - if (sysProperty != null) { - res = System.getProperty(sysProperty); - } - - return res; - } - - /** - * Gets the plain-text password that is used for the keystore. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The password in plain text. - */ - public char[] getKeyStorePassword(String configID) { - String pw = getProperty(configID, KEYSTOREPWD, SYSKEYSTOREPWD); - char[] r=null; - if (pw!=null) { - if (pw.startsWith(xorTag)) { - r = deObfuscate(pw); - } else { - r = pw.toCharArray(); - } - } - return r; - } - - /** - * Gets the type of keystore. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The keystore type. - */ - public String getKeyStoreType(String configID) { - return getProperty(configID, KEYSTORETYPE, SYSKEYSTORETYPE); - } - - /** - * Gets the keystore provider. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The name of the keystore provider. - */ - public String getKeyStoreProvider(String configID) { - return getProperty(configID, KEYSTOREPROVIDER, null); - } - - /** - * Gets the key manager algorithm that is used. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The key manager algorithm. - */ - public String getKeyManager(String configID) { - return getProperty(configID, KEYSTOREMGR, SYSKEYMGRALGO); - } - - /** - * Gets the name of the truststore file that is used. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The name of the file that contains the truststore. - */ - public String getTrustStore(String configID) { - return getProperty(configID, TRUSTSTORE, SYSTRUSTSTORE); - } - - /** - * Gets the plain-text password that is used for the truststore. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The password in plain text. - */ - public char[] getTrustStorePassword(String configID) { - String pw = getProperty(configID, TRUSTSTOREPWD, SYSTRUSTSTOREPWD); - char[] r=null; - if (pw!=null) { - if(pw.startsWith(xorTag)) { - r = deObfuscate(pw); - } else { - r = pw.toCharArray(); - } - } - return r; - } - - /** - * Gets the type of truststore. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The truststore type. - */ - public String getTrustStoreType(String configID) { - return getProperty(configID, TRUSTSTORETYPE, null); - } - - /** - * Gets the truststore provider. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The name of the truststore provider. - */ - public String getTrustStoreProvider(String configID) { - return getProperty(configID, TRUSTSTOREPROVIDER, null); - } - - /** - * Gets the trust manager algorithm that is used. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return The trust manager algorithm. - */ - public String getTrustManager(String configID) { - return getProperty(configID, TRUSTSTOREMGR, SYSTRUSTMGRALGO); - } - - /** - * Returns an array with the enabled ciphers. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return an array with the enabled ciphers - */ - public String[] getEnabledCipherSuites(String configID) { - String ciphers = getProperty(configID, CIPHERSUITES, null); - String[] res = unpackCipherSuites(ciphers); - return res; - } - - /** - * Returns whether client authentication is required. - * - * @param configID - * The configuration identifier for selecting a configuration or - * null for the default configuration. - * @return true, if clients are required to authenticate, false otherwise. - */ - public boolean getClientAuthentication(String configID) { - String auth = getProperty(configID, CLIENTAUTH, null); - boolean res = false; - if (auth != null) { - res = Boolean.valueOf(auth).booleanValue(); - } - return res; - } - - /** - * Initializes key- and truststore. Returns an SSL context factory. If no - * SSLProtocol is already set, uses DEFAULT_PROTOCOL - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#DEFAULT_PROTOCOL - * - * @param configID - * The configuration ID - * @return An SSL context factory. - * @throws MqttDirectException - */ - private SSLContext getSSLContext(String configID) - throws MqttSecurityException{ - final String METHOD_NAME = "getSSLContext"; - SSLContext ctx = null; - - String protocol = getSSLProtocol(configID); - if (protocol == null) { - protocol = DEFAULT_PROTOCOL; - } - if (logger != null) { - // 12000 "SSL initialization: configID = {0}, protocol = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12000", new Object[] {configID!=null ? configID : "null (broker defaults)", - protocol}); - } - - String provider = getJSSEProvider(configID); - try { - if (provider == null) { - ctx = SSLContext.getInstance(protocol); - } else { - ctx = SSLContext.getInstance(protocol, provider); - } - if (logger != null) { - // 12001 "SSL initialization: configID = {0}, provider = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12001", new Object[] {configID!=null ? configID : "null (broker defaults)", - ctx.getProvider().getName()}); - } - - String keyStoreName = getProperty(configID, KEYSTORE, null); - KeyStore keyStore=null; - KeyManagerFactory keyMgrFact=null; - KeyManager[] keyMgr=null; -// if(keyStoreName==null) { -// // try to instantiate XPD keyStore. -// keyStore=getXPDKeystore(); -// if (logger != null) { -// if (keyStore == null) { -// // 12002 "SSL initialization: configID = {0}, XPD keystore not available" -// logger.fine(CLASS_NAME, METHOD_NAME, "12002", new Object[]{configID!=null ? configID : "null (broker defaults)"}); -// } else { -// // 12003 "SSL initialization: configID = {0}, XPD keystore available" -// logger.fine(CLASS_NAME, METHOD_NAME, "12003", new Object[]{configID!=null ? configID : "null (broker defaults)"}); -// } -// } -// } - - if(keyStore==null) { - if(keyStoreName==null) { - /* - * No keystore in config, XPD keystore not available. Try to - * get config from system properties. - */ - keyStoreName = getProperty(configID, KEYSTORE, SYSKEYSTORE); - } - if (logger != null) { - // 12004 "SSL initialization: configID = {0}, keystore = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12004", new Object[]{configID!=null ? configID : "null (broker defaults)", - keyStoreName!=null ? keyStoreName : "null"}); - } - - char[] keyStorePwd=getKeyStorePassword(configID); - if (logger != null) { - // 12005 "SSL initialization: configID = {0}, keystore password = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12005", new Object[]{configID!=null ? configID : "null (broker defaults)", - keyStorePwd!=null ? obfuscate(keyStorePwd) : "null"}); - } - - String keyStoreType=getKeyStoreType(configID); - if(keyStoreType==null) { - keyStoreType = KeyStore.getDefaultType(); - } - if (logger != null) { - // 12006 "SSL initialization: configID = {0}, keystore type = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12006", new Object[]{configID!=null ? configID : "null (broker defaults)", - keyStoreType!=null ? keyStoreType : "null"}); - } - - String keyMgrAlgo = KeyManagerFactory.getDefaultAlgorithm(); - String keyMgrProvider = getKeyStoreProvider(configID); - String keyManager = getKeyManager(configID); - if (keyManager != null) { - keyMgrAlgo = keyManager; - } - - if(keyStoreName!=null && keyStoreType!=null && keyMgrAlgo!=null) { - try { - keyStore=KeyStore.getInstance(keyStoreType); - keyStore.load(new FileInputStream(keyStoreName), keyStorePwd); - if(keyMgrProvider!=null) { - keyMgrFact = KeyManagerFactory.getInstance(keyMgrAlgo, keyMgrProvider); - } else { - keyMgrFact = KeyManagerFactory.getInstance(keyMgrAlgo); - } - if (logger != null) { - // 12010 "SSL initialization: configID = {0}, keystore manager algorithm = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12010", new Object[]{configID!=null ? configID : "null (broker defaults)", - keyMgrAlgo!=null ? keyMgrAlgo : "null"}); - // 12009 "SSL initialization: configID = {0}, keystore manager provider = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12009", new Object[]{configID!=null ? configID : "null (broker defaults)", - keyMgrFact.getProvider().getName()}); - } - keyMgrFact.init(keyStore, keyStorePwd); - keyMgr=keyMgrFact.getKeyManagers(); - } catch (KeyStoreException e) { - throw new MqttSecurityException(e); - } catch (CertificateException e) { - throw new MqttSecurityException(e); - } catch (FileNotFoundException e) { - throw new MqttSecurityException(e); - } catch (IOException e) { - throw new MqttSecurityException(e); - } catch (UnrecoverableKeyException e) { - throw new MqttSecurityException(e); - } - } - } - // keystore loaded, keymanagers instantiated if possible - // now the same for the truststore. - String trustStoreName = getTrustStore(configID); - if (logger != null) { - // 12011 "SSL initialization: configID = {0}, truststore = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12011", new Object[]{configID!=null ? configID : "null (broker defaults)", - trustStoreName!=null ? trustStoreName : "null"}); - } - KeyStore trustStore=null; - TrustManagerFactory trustMgrFact=null; - TrustManager[] trustMgr=null; - char[] trustStorePwd=getTrustStorePassword(configID); - if (logger != null) { - // 12012 "SSL initialization: configID = {0}, truststore password = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12012", new Object[]{configID!=null ? configID : "null (broker defaults)", - trustStorePwd!=null ? obfuscate(trustStorePwd) : "null"}); - } - String trustStoreType=getTrustStoreType(configID); - if(trustStoreType==null) { - trustStoreType = KeyStore.getDefaultType(); - } - if (logger != null) { - // 12013 "SSL initialization: configID = {0}, truststore type = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12013", new Object[]{configID!=null ? configID : "null (broker defaults)", - trustStoreType!=null ? trustStoreType : "null"}); - } - - String trustMgrAlgo = TrustManagerFactory.getDefaultAlgorithm(); - String trustMgrProvider = getTrustStoreProvider(configID); - String trustManager = getTrustManager(configID); - if (trustManager != null) { - trustMgrAlgo = trustManager; - } - - if(trustStoreName!=null && trustStoreType!=null && trustMgrAlgo!=null) { - try { - trustStore=KeyStore.getInstance(trustStoreType); - trustStore.load(new FileInputStream(trustStoreName), trustStorePwd); - if(trustMgrProvider!=null) { - trustMgrFact = TrustManagerFactory.getInstance(trustMgrAlgo, trustMgrProvider); - } else { - trustMgrFact = TrustManagerFactory.getInstance(trustMgrAlgo); - } - if (logger != null) { - - // 12017 "SSL initialization: configID = {0}, truststore manager algorithm = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12017", new Object[]{configID!=null ? configID : "null (broker defaults)", - trustMgrAlgo!=null ? trustMgrAlgo : "null"}); - - // 12016 "SSL initialization: configID = {0}, truststore manager provider = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12016", new Object[]{configID!=null ? configID : "null (broker defaults)", - trustMgrFact.getProvider().getName()}); - } - trustMgrFact.init(trustStore); - trustMgr=trustMgrFact.getTrustManagers(); - } catch (KeyStoreException e) { - throw new MqttSecurityException(e); - } catch (CertificateException e) { - throw new MqttSecurityException(e); - } catch (FileNotFoundException e) { - throw new MqttSecurityException(e); - } catch (IOException e) { - throw new MqttSecurityException(e); - } - } - // done. - ctx.init(keyMgr, trustMgr, null); - } catch (NoSuchAlgorithmException e) { - throw new MqttSecurityException(e); - } catch (NoSuchProviderException e) { - throw new MqttSecurityException(e); - } catch (KeyManagementException e) { - throw new MqttSecurityException(e); - } - return ctx; - } - -// /** -// * Returns an SSL server socket factory for the given configuration. If no -// * SSLProtocol is already set, uses DEFAULT_PROTOCOL. Throws -// * IllegalArgumentException if the server socket factory could not be -// * created due to underlying configuration problems. -// * -// * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#DEFAULT_PROTOCOL -// * -// * @param configID -// * The configuration identifier for selecting a configuration. -// * @return An SSLServerSocketFactory -// * @throws MqttDirectException -// */ -// public SSLServerSocketFactory createServerSocketFactory(String configID) -// throws MqttDirectException { -// final String METHOD_NAME = "createServerSocketFactory"; -// SSLContext ctx = getSSLContext(configID); -// if (logger != null) { -// // 12018 "SSL initialization: configID = {0}, application-enabled cipher suites = {1}" -// logger.fine(CLASS_NAME, METHOD_NAME, "12018", new Object[]{configID!=null ? configID : "null (broker defaults)", -// getEnabledCipherSuites(configID)!=null ? getProperty(configID, CIPHERSUITES, null) : "null (using platform-enabled cipher suites)"}); -// -// // 12019 "SSL initialization: configID = {0}, client authentication = {1}" -// logger.fine(CLASS_NAME, METHOD_NAME, "12019", new Object[]{configID!=null ? configID : "null (broker defaults)", -// new Boolean (getClientAuthentication(configID)).toString()}); -// } -// -// return ctx.getServerSocketFactory(); -// } - - /** - * Returns an SSL socket factory for the given configuration. If no - * SSLProtocol is already set, uses DEFAULT_PROTOCOL. Throws - * IllegalArgumentException if the socket factory could not be created due - * to underlying configuration problems. - * - * @see org.eclipse.paho.client.mqttv3.internal.security.SSLSocketFactoryFactory#DEFAULT_PROTOCOL - * @param configID - * The configuration identifier for selecting a configuration. - * @return An SSLSocketFactory - * @throws MqttSecurityException if an error occurs whilst creating the {@link SSLSocketFactory} - */ - public SSLSocketFactory createSocketFactory(String configID) - throws MqttSecurityException { - final String METHOD_NAME = "createSocketFactory"; - SSLContext ctx = getSSLContext(configID); - if (logger != null) { - // 12020 "SSL initialization: configID = {0}, application-enabled cipher suites = {1}" - logger.fine(CLASS_NAME, METHOD_NAME, "12020", new Object[]{configID!=null ? configID : "null (broker defaults)", - getEnabledCipherSuites(configID)!=null ? getProperty(configID, CIPHERSUITES, null) : "null (using platform-enabled cipher suites)"}); - } - - return ctx.getSocketFactory(); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SimpleBase64Encoder.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SimpleBase64Encoder.java deleted file mode 100644 index 414e496..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/security/SimpleBase64Encoder.java +++ /dev/null @@ -1,127 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.security; - -public class SimpleBase64Encoder { - - // if this string is changed, then the decode method must also be adapted. - private static final String PWDCHARS_STRING = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - private static final char[] PWDCHARS_ARRAY = PWDCHARS_STRING.toCharArray(); - - /** - * Encodes an array of byte into a string of printable ASCII characters - * using a base-64 encoding. - * @param bytes The array of bytes to e encoded - * @return The encoded array. - */ - public static String encode(byte[] bytes) { - // Allocate a string buffer. - int len = bytes.length; - final StringBuffer encoded = new StringBuffer((len+2)/3*4); - int i=0; - int j=len; - while(j>=3){ - encoded.append(to64((((bytes[i] & 0xff) << 16) - | (int) ((bytes[i+1] & 0xff) << 8) | (int) (bytes[i+2] & 0xff)),4)); - i+=3; - j-=3; - } - // j==2 | j==1 | j==0 - if(j==2) { - // there is a rest of 2 bytes. This encodes into 3 chars. - encoded.append(to64(((bytes[i] &0xff)<<8) | ((bytes[i+1] & 0xff)),3)); - } - if(j==1) { - // there is a rest of 1 byte. This encodes into 1 char. - encoded.append(to64(((bytes[i] & 0xff)),2)); - } - return encoded.toString(); - } - - public static byte[] decode(String string) { - byte[] encoded=string.getBytes(); - int len=encoded.length; - byte[] decoded=new byte[len*3/4]; - int i=0; - int j=len; - int k=0; - while(j>=4) { - long d=from64(encoded, i, 4); - j-=4; - i+=4; - for(int l=2;l>=0;l--) { - decoded[k+l]=(byte) (d & 0xff); - d=d >>8; - } - k+=3; - } - // j==3 | j==2 - if(j==3) { - long d=from64(encoded, i, 3); - for(int l=1;l>=0;l--) { - decoded[k+l]=(byte) (d & 0xff); - d=d >>8; - } - } - if(j==2) { - long d=from64(encoded, i, 2); - decoded[k]=(byte) (d & 0xff); - } - return decoded; - } - - /* the core conding routine. Translates an input integer into - * a string of the given length.*/ - private final static String to64(long input, int size) { - final StringBuffer result = new StringBuffer(size); - while (size > 0) { - size--; - result.append(PWDCHARS_ARRAY[((int) (input & 0x3f))]); - input = input >> 6; - } - return result.toString(); - } - - /* - * The reverse operation of to64 - */ - private final static long from64(byte[] encoded, int idx, int size) { - long res=0; - int f=0; - while(size>0) { - size--; - long r=0; - // convert encoded[idx] back into a 6-bit value. - byte d=encoded[idx++]; - if(d=='/') { - r=1; - } - if(d>='0' && d<='9') { - r=2+d-'0'; - } - if(d>='A' && d<='Z') { - r=12+d-'A'; - } - if(d>='a' && d<='z') { - r=38+d-'a'; - } - res=res+((long)r << f); - f+=6; - } - return res; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/Base64.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/Base64.java deleted file mode 100644 index 6503b81..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/Base64.java +++ /dev/null @@ -1,97 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.util.prefs.AbstractPreferences; -import java.util.prefs.BackingStoreException; - -public class Base64 { - - private static final Base64 instance = new Base64(); - private static final Base64Encoder encoder = instance.new Base64Encoder(); - - public static String encode (String s){ - encoder.putByteArray("akey", s.getBytes()); - String result = encoder.getBase64String(); - return result; - } - - public static String encodeBytes (byte[] b){ - encoder.putByteArray("aKey", b); - String result = encoder.getBase64String(); - return result; - - } - - public class Base64Encoder extends AbstractPreferences { - - private String base64String = null; - - public Base64Encoder() { - super(null, ""); - } - - - protected void putSpi(String key, String value) { - base64String = value; - } - - public String getBase64String() { - return base64String; - } - - - protected String getSpi(String key) { - return null; - } - - - protected void removeSpi(String key) { - } - - - protected void removeNodeSpi() throws BackingStoreException { - - } - - - protected String[] keysSpi() throws BackingStoreException { - return null; - } - - - protected String[] childrenNamesSpi() throws BackingStoreException { - return null; - } - - - protected AbstractPreferences childSpi(String name) { - return null; - } - - - protected void syncSpi() throws BackingStoreException { - - } - - - protected void flushSpi() throws BackingStoreException { - - } - - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/ExtendedByteArrayOutputStream.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/ExtendedByteArrayOutputStream.java deleted file mode 100644 index 2caee99..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/ExtendedByteArrayOutputStream.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -import org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule; - -class ExtendedByteArrayOutputStream extends ByteArrayOutputStream { - - final WebSocketNetworkModule webSocketNetworkModule; - final WebSocketSecureNetworkModule webSocketSecureNetworkModule; - - ExtendedByteArrayOutputStream(WebSocketNetworkModule module) { - this.webSocketNetworkModule = module; - this.webSocketSecureNetworkModule = null; - } - - ExtendedByteArrayOutputStream(WebSocketSecureNetworkModule module) { - this.webSocketNetworkModule = null; - this.webSocketSecureNetworkModule = module; - } - - public void flush() throws IOException { - final ByteBuffer byteBuffer; - synchronized (this) { - byteBuffer = ByteBuffer.wrap(toByteArray()); - reset(); - } - WebSocketFrame frame = new WebSocketFrame((byte)0x02, true, byteBuffer.array()); - byte[] rawFrame = frame.encodeFrame(); - getSocketOutputStream().write(rawFrame); - getSocketOutputStream().flush(); - - } - - OutputStream getSocketOutputStream() throws IOException { - - if(webSocketNetworkModule != null ){ - return webSocketNetworkModule.getSocketOutputStream(); - } - if(webSocketSecureNetworkModule != null){ - return webSocketSecureNetworkModule.getSocketOutputStream(); - } - return null; - } - -} \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/HandshakeFailedException.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/HandshakeFailedException.java deleted file mode 100644 index c9f9427..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/HandshakeFailedException.java +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -public class HandshakeFailedException extends Exception { - - private static final long serialVersionUID = 1L; - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketFrame.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketFrame.java deleted file mode 100644 index acc5185..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketFrame.java +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.IOException; -import java.io.InputStream; -import java.nio.ByteBuffer; -import java.security.SecureRandom; - -public class WebSocketFrame { - - public static final int frameLengthOverhead = 6; - - private byte opcode; - private boolean fin; - private byte payload[]; - private boolean closeFlag = false; - - public byte getOpcode() { - return opcode; - } - - public boolean isFin() { - return fin; - } - - public byte[] getPayload() { - return payload; - } - - public boolean isCloseFlag() { - return closeFlag; - } - - - /** - * Initialise a new WebSocketFrame - * @param opcode WebSocket Opcode - * @param fin If it's final - * @param payload The payload - */ - public WebSocketFrame(byte opcode, boolean fin, byte[] payload){ - this.opcode = opcode; - this.fin = fin; - this.payload = payload; - } - - - /** - * Initialise WebSocketFrame from raw Data - * @param rawFrame The raw byte buffer - */ - public WebSocketFrame (byte[] rawFrame){ - - ByteBuffer buffer = ByteBuffer.wrap(rawFrame); - - // First Byte: Fin, Reserved, Opcode - byte b = buffer.get(); - setFinAndOpCode(b); - - // Second Byte Masked & Initial Length - b = buffer.get(); - boolean masked = ((b & 0x80) != 0); - int payloadLength = (byte)(0x7F & b); - int byteCount = 0; - if(payloadLength == 0X7F){ - // 8 Byte Extended payload length - byteCount = 8; - } else if (payloadLength == 0X7E){ - // 2 bytes extended payload length - byteCount = 2; - } - - // Decode the extended payload length - while (--byteCount > 0){ - b = buffer.get(); - payloadLength |= (b & 0xFF) << (8 * byteCount); - } - - // Get the Masking key if masked - byte maskingKey[] = null; - if(masked) { - maskingKey = new byte[4]; - buffer.get(maskingKey,0,4); - } - this.payload = new byte[payloadLength]; - buffer.get(this.payload,0,payloadLength); - - // Demask payload if needed - if(masked) - { - for(int i = 0; i < this.payload.length; i++){ - this.payload[i] ^= maskingKey[i % 4]; - } - } - return; - } - - - /** - * Sets the frames Fin flag and opcode. - * @param incomingByte - */ - private void setFinAndOpCode(byte incomingByte){ - this.fin = ((incomingByte & 0x80) !=0); - // Reserved bits, unused right now. - // boolean rsv1 = ((incomingByte & 0x40) != 0); - // boolean rsv2 = ((incomingByte & 0x20) != 0); - // boolean rsv3 = ((incomingByte & 0x10) != 0); - this.opcode = (byte)(incomingByte & 0x0F); - - } - - /** - * Takes an input stream and parses it into a Websocket frame. - * @param input The incoming {@link InputStream} - * @throws IOException if an exception occurs whilst reading the input stream - */ - public WebSocketFrame(InputStream input) throws IOException { - byte firstByte = (byte) input.read(); - setFinAndOpCode(firstByte); - if(this.opcode == 2){ - byte maskLengthByte = (byte) input.read(); - boolean masked = ((maskLengthByte & 0x80) != 0); - int payloadLength = (byte)(0x7F & maskLengthByte); - int byteCount = 0; - if(payloadLength == 0X7F){ - // 8 Byte Extended payload length - byteCount = 8; - } else if (payloadLength == 0X7E){ - // 2 bytes extended payload length - byteCount = 2; - } - - // Decode the payload length - if(byteCount > 0){ - payloadLength = 0; - } - while (--byteCount >= 0){ - maskLengthByte = (byte) input.read(); - payloadLength |= (maskLengthByte & 0xFF) << (8 * byteCount); - } - - // Get the masking key - byte maskingKey[] = null; - if(masked) { - maskingKey = new byte[4]; - input.read(maskingKey,0,4); - } - - this.payload = new byte[payloadLength]; - int offsetIndex = 0; - int tempLength = payloadLength; - int bytesRead = 0; - while (offsetIndex != payloadLength){ - bytesRead = input.read(this.payload,offsetIndex,tempLength); - offsetIndex += bytesRead; - tempLength -= bytesRead; - } - - - // Demask if needed - if(masked) - { - for(int i = 0; i < this.payload.length; i++){ - this.payload[i] ^= maskingKey[i % 4]; - } - } - return; - } else if(this.opcode == 8){ - // Closing connection with server - closeFlag = true; - } else { - throw new IOException("Invalid Frame: Opcode: " +this.opcode); - } - - - } - - - /** - * Encodes the this WebSocketFrame into a byte array. - * @return byte array - */ - public byte[] encodeFrame(){ - int length = this.payload.length + frameLengthOverhead; - // Calculating overhead - if(this.payload.length > 65535){ - length += 8; - } else if(this.payload.length >= 126) { - length += 2; - } - - ByteBuffer buffer = ByteBuffer.allocate(length); - appendFinAndOpCode(buffer, this.opcode, this.fin); - byte mask[] = generateMaskingKey(); - appendLengthAndMask(buffer, this.payload.length, mask); - - for(int i = 0; i < this.payload.length; i ++){ - buffer.put((byte)(this.payload[i] ^=mask[i % 4])); - } - - buffer.flip(); - return buffer.array(); - } - - /** - * Appends the Length and Mask to the buffer - * @param buffer the outgoing {@link ByteBuffer} - * @param length the length of the frame - * @param mask The WebSocket Mask - */ - public static void appendLengthAndMask(ByteBuffer buffer, int length, byte mask[]){ - if(mask != null){ - appendLength(buffer, length, true); - buffer.put(mask); - } else { - appendLength(buffer, length, false); - } - } - - - /** - * Appends the Length of the payload to the buffer - * @param buffer - * @param length - * @param b - */ - private static void appendLength(ByteBuffer buffer, int length, boolean masked) { - - if(length < 0){ - throw new IllegalArgumentException("Length cannot be negative"); - } - - byte b = (masked?(byte)0x80:0x00); - if(length > 0xFFFF){ - buffer.put((byte) (b | 0x7F)); - buffer.put((byte)0x00); - buffer.put((byte)0x00); - buffer.put((byte)0x00); - buffer.put((byte)0x00); - buffer.put((byte)((length >> 24) & 0xFF)); - buffer.put((byte)((length >> 16) & 0xFF)); - buffer.put((byte)((length >> 8) & 0xFF)); - buffer.put((byte)(length & 0xFF)); - } else if(length >= 0x7E){ - buffer.put((byte)(b | 0x7E)); - buffer.put((byte)(length >> 8)); - buffer.put((byte)(length & 0xFF)); - } else { - buffer.put((byte)(b | length)); - } - } - - /** - * Appends the Fin flag and the OpCode - * @param buffer The outgoing buffer - * @param opcode The Websocket OpCode - * @param fin if this is a final frame - */ - public static void appendFinAndOpCode(ByteBuffer buffer, byte opcode, boolean fin){ - byte b = 0x00; - // Add Fin flag - if(fin){ - b |= 0x80; - } - //RSV 1,2,3 aren't important - - // Add opcode - b |= opcode & 0x0F; - buffer.put(b); - } - - /** - * Generates a random masking key - * Nothing super secure, but enough - * for websockets. - * @return ByteArray containing the key; - */ - public static byte[] generateMaskingKey(){ - SecureRandom secureRandomGenerator = new SecureRandom(); - int a = secureRandomGenerator.nextInt(255); - int b = secureRandomGenerator.nextInt(255); - int c = secureRandomGenerator.nextInt(255); - int d = secureRandomGenerator.nextInt(255); - return new byte[] {(byte) a,(byte) b,(byte) c,(byte) d}; - } - - - - - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketHandshake.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketHandshake.java deleted file mode 100644 index 92be901..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketHandshake.java +++ /dev/null @@ -1,215 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintWriter; -import java.net.URI; -import java.net.URISyntaxException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Map; -import java.util.UUID; -/** - * Helper class to execute a WebSocket Handshake. - */ -public class WebSocketHandshake { - - // Do not change: https://tools.ietf.org/html/rfc6455#section-1.3 - private static final String ACCEPT_SALT = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - private static final String SHA1_PROTOCOL = "SHA1"; - private static final String HTTP_HEADER_SEC_WEBSOCKET_ACCEPT = "sec-websocket-accept"; - private static final String HTTP_HEADER_UPGRADE = "upgrade"; - private static final String HTTP_HEADER_UPGRADE_WEBSOCKET = "websocket"; - private static final String EMPTY = ""; - private static final String LINE_SEPARATOR = "\r\n"; - - private static final String HTTP_HEADER_CONNECTION = "connection"; - private static final String HTTP_HEADER_CONNECTION_VALUE = "upgrade"; - private static final String HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL = "sec-websocket-protocol"; - - InputStream input; - OutputStream output; - String uri; - String host; - int port; - - - public WebSocketHandshake(InputStream input, OutputStream output, String uri, String host, int port){ - this.input = input; - this.output = output; - this.uri = uri; - this.host = host; - this.port = port; - } - - - /** - * Executes a Websocket Handshake. - * Will throw an IOException if the handshake fails - * @throws IOException thrown if an exception occurs during the handshake - */ - public void execute() throws IOException { - byte[] key = new byte[16]; - System.arraycopy(UUID.randomUUID().toString().getBytes(), 0, key, 0, 16); - String b64Key = Base64.encodeBytes(key); - sendHandshakeRequest(b64Key); - receiveHandshakeResponse(b64Key); - } - - /** - * Builds and sends the HTTP Header GET Request - * for the socket. - * @param key Base64 encoded key - * @throws IOException - */ - private void sendHandshakeRequest(String key) throws IOException{ - try { - String path = "/mqtt"; - URI srvUri = new URI(uri); - if (srvUri.getRawPath() != null && !srvUri.getRawPath().isEmpty()) { - path = srvUri.getRawPath(); - if (srvUri.getRawQuery() != null && !srvUri.getRawQuery().isEmpty()) { - path += "?" + srvUri.getRawQuery(); - } - } - - PrintWriter pw = new PrintWriter(output); - pw.print("GET " + path + " HTTP/1.1" + LINE_SEPARATOR); - if (port != 80 && port != 443) { - pw.print("Host: " + host + ":" + port + LINE_SEPARATOR); - } - else { - pw.print("Host: " + host + LINE_SEPARATOR); - } - - pw.print("Upgrade: websocket" + LINE_SEPARATOR); - pw.print("Connection: Upgrade" + LINE_SEPARATOR); - pw.print("Sec-WebSocket-Key: " + key + LINE_SEPARATOR); - pw.print("Sec-WebSocket-Protocol: mqtt" + LINE_SEPARATOR); - pw.print("Sec-WebSocket-Version: 13" + LINE_SEPARATOR); - - String userInfo = srvUri.getUserInfo(); - if(userInfo != null) { - pw.print("Authorization: Basic " + Base64.encode(userInfo) + LINE_SEPARATOR); - } - - pw.print(LINE_SEPARATOR); - pw.flush(); - } catch (URISyntaxException e) { - throw new IllegalStateException(e.getMessage()); - } - } - - /** - * Receives the Handshake response and verifies that it is valid. - * @param key Base64 encoded key - * @throws IOException - */ - private void receiveHandshakeResponse(String key) throws IOException { - BufferedReader in = new BufferedReader(new InputStreamReader(input)); - ArrayList responseLines = new ArrayList(); - String line = in.readLine(); - if(line == null){ - throw new IOException("WebSocket Response header: Invalid response from Server, It may not support WebSockets."); - } - while(!line.equals(EMPTY) ) { - responseLines.add(line); - line = in.readLine(); - } - Map headerMap = getHeaders(responseLines); - - String connectionHeader = (String) headerMap.get(HTTP_HEADER_CONNECTION); - if (connectionHeader == null || connectionHeader.equalsIgnoreCase(HTTP_HEADER_CONNECTION_VALUE)) { - throw new IOException("WebSocket Response header: Incorrect connection header"); - } - - String upgradeHeader = (String) headerMap.get(HTTP_HEADER_UPGRADE); - if(upgradeHeader == null || !upgradeHeader.toLowerCase().contains(HTTP_HEADER_UPGRADE_WEBSOCKET)){ - throw new IOException("WebSocket Response header: Incorrect upgrade."); - } - - String secWebsocketProtocolHeader = (String) headerMap.get(HTTP_HEADER_SEC_WEBSOCKET_PROTOCOL); - if (secWebsocketProtocolHeader == null) { - throw new IOException("WebSocket Response header: empty sec-websocket-protocol"); - } - - if(!headerMap.containsKey(HTTP_HEADER_SEC_WEBSOCKET_ACCEPT)){ - throw new IOException("WebSocket Response header: Missing Sec-WebSocket-Accept"); - } - - try { - verifyWebSocketKey(key, (String)headerMap.get(HTTP_HEADER_SEC_WEBSOCKET_ACCEPT)); - } catch (NoSuchAlgorithmException e) { - throw new IOException(e.getMessage()); - } catch (HandshakeFailedException e) { - throw new IOException("WebSocket Response header: Incorrect Sec-WebSocket-Key"); - } - - } - - /** - * Returns a Hashmap of HTTP headers - * @param ArrayList<String> of headers - * @return A Hashmap<String, String> of the headers - */ - private Map getHeaders(ArrayList headers){ - Map headerMap = new HashMap(); - for(int i = 1; i < headers.size(); i++){ - String headerPre = (String) headers.get(i); - String[] header = headerPre.split(":"); - headerMap.put(header[0].toLowerCase(), header[1]); - } - return headerMap; - } - - /** - * Verifies that the Accept key provided is correctly built from the - * original key sent. - * @param key - * @param accept - * @throws NoSuchAlgorithmException - * @throws HandshakeFailedException - */ - private void verifyWebSocketKey(String key, String accept) throws NoSuchAlgorithmException, HandshakeFailedException{ - // We build up the accept in the same way the server should - // then we check that the response is the same. - byte[] sha1Bytes = sha1(key + ACCEPT_SALT); - String encodedSha1Bytes = Base64.encodeBytes(sha1Bytes).trim(); - if(!encodedSha1Bytes.equals(accept.trim())){ - throw new HandshakeFailedException(); - } - } - - /** - * Returns the sha1 byte array of the provided string. - * @param input - * @return - * @throws NoSuchAlgorithmException - */ - private byte[] sha1(String input) throws NoSuchAlgorithmException { - MessageDigest mDigest = MessageDigest.getInstance(SHA1_PROTOCOL); - byte[] result = mDigest.digest(input.getBytes()); - return result; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketNetworkModule.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketNetworkModule.java deleted file mode 100644 index 5524a31..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketNetworkModule.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.nio.ByteBuffer; - -import javax.net.SocketFactory; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -public class WebSocketNetworkModule extends TCPNetworkModule { - - private static final String CLASS_NAME = WebSocketNetworkModule.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private String uri; - private String host; - private int port; - private PipedInputStream pipedInputStream; - private WebSocketReceiver webSocketReceiver; - ByteBuffer recievedPayload; - - /** - * Overrides the flush method. - * This allows us to encode the MQTT payload into a WebSocket - * Frame before passing it through to the real socket. - */ - private ByteArrayOutputStream outputStream = new ExtendedByteArrayOutputStream(this); - - public WebSocketNetworkModule(SocketFactory factory, String uri, String host, int port, String resourceContext){ - super(factory, host, port, resourceContext); - this.uri = uri; - this.host = host; - this.port = port; - this.pipedInputStream = new PipedInputStream(); - - log.setResourceName(resourceContext); - } - - public void start() throws IOException, MqttException { - super.start(); - WebSocketHandshake handshake = new WebSocketHandshake(getSocketInputStream(), getSocketOutputStream(), uri, host, port); - handshake.execute(); - this.webSocketReceiver = new WebSocketReceiver(getSocketInputStream(), pipedInputStream); - webSocketReceiver.start("webSocketReceiver"); - } - - OutputStream getSocketOutputStream() throws IOException { - return super.getOutputStream(); - } - - InputStream getSocketInputStream() throws IOException { - return super.getInputStream(); - } - - public InputStream getInputStream() throws IOException { - return pipedInputStream; - } - - public OutputStream getOutputStream() throws IOException { - return outputStream; - } - - /** - * Stops the module, by closing the TCP socket. - */ - public void stop() throws IOException { - // Creating Close Frame - WebSocketFrame frame = new WebSocketFrame((byte)0x08, true, "1000".getBytes()); - byte[] rawFrame = frame.encodeFrame(); - getSocketOutputStream().write(rawFrame); - getSocketOutputStream().flush(); - - if(webSocketReceiver != null){ - webSocketReceiver.stop(); - } - super.stop(); - } - - public String getServerURI() { - return "ws://" + host + ":" + port; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketReceiver.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketReceiver.java deleted file mode 100644 index 9052240..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketReceiver.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.IOException; -import java.io.InputStream; -import java.io.PipedInputStream; -import java.io.PipedOutputStream; - -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -public class WebSocketReceiver implements Runnable{ - - private static final String CLASS_NAME = WebSocketReceiver.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private boolean running = false; - private boolean stopping = false; - private Object lifecycle = new Object(); - private InputStream input; - private Thread receiverThread = null; - private volatile boolean receiving; - private PipedOutputStream pipedOutputStream; - - public WebSocketReceiver(InputStream input, PipedInputStream pipedInputStream) throws IOException{ - this.input = input; - this.pipedOutputStream = new PipedOutputStream(); - pipedInputStream.connect(pipedOutputStream); - } - - /** - * Starts up the WebSocketReceiver's thread - * @param threadName The name of the thread - */ - public void start(String threadName){ - final String methodName = "start"; - //@TRACE 855=starting - log.fine(CLASS_NAME, methodName, "855"); - synchronized (lifecycle) { - if(!running) { - running = true; - receiverThread = new Thread(this, threadName); - receiverThread.start(); - } - } - } - - /** - * Stops this WebSocketReceiver's thread. - * This call will block. - */ - public void stop() { - final String methodName = "stop"; - stopping = true; - boolean closed = false; - synchronized (lifecycle) { - //@TRACE 850=stopping - log.fine(CLASS_NAME,methodName, "850"); - if(running) { - running = false; - receiving = false; - closed = true; - closeOutputStream(); - - } - } - if(closed && !Thread.currentThread().equals(receiverThread)) { - try { - // Wait for the thread to finish - //This must not happen in the synchronized block, otherwise we can deadlock ourselves! - receiverThread.join(); - } catch (InterruptedException ex) { - // Interrupted Exception - } - } - receiverThread = null; - //@TRACE 851=stopped - log.fine(CLASS_NAME, methodName, "851"); - } - - public void run() { - final String methodName = "run"; - - while (running && (input != null)) { - try { - //@TRACE 852=network read message - log.fine(CLASS_NAME, methodName, "852"); - receiving = input.available() > 0; - WebSocketFrame incomingFrame = new WebSocketFrame(input); - if(!incomingFrame.isCloseFlag()){ - for(int i = 0; i < incomingFrame.getPayload().length; i++){ - pipedOutputStream.write(incomingFrame.getPayload()[i]); - } - - pipedOutputStream.flush(); - } else { - if(!stopping){ - throw new IOException("Server sent a WebSocket Frame with the Stop OpCode"); - } - } - - receiving = false; - - } catch (IOException ex) { - // Exception occurred whilst reading the stream. - this.stop(); - } - } - } - - private void closeOutputStream(){ - try { - pipedOutputStream.close(); - } catch (IOException e) { - } - } - - - public boolean isRunning() { - return running; - } - - /** - * Returns the receiving state. - * - * @return true if the receiver is receiving data, false otherwise. - */ - public boolean isReceiving(){ - return receiving; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketSecureNetworkModule.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketSecureNetworkModule.java deleted file mode 100644 index 8224103..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/websocket/WebSocketSecureNetworkModule.java +++ /dev/null @@ -1,105 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * James Sutton - Bug 459142 - WebSocket support for the Java client. - */ -package org.eclipse.paho.client.mqttv3.internal.websocket; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PipedInputStream; -import java.nio.ByteBuffer; - -import javax.net.ssl.SSLSocketFactory; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.internal.SSLNetworkModule; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -public class WebSocketSecureNetworkModule extends SSLNetworkModule{ - - private static final String CLASS_NAME = WebSocketSecureNetworkModule.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private PipedInputStream pipedInputStream; - private WebSocketReceiver webSocketReceiver; - private String uri; - private String host; - private int port; - ByteBuffer recievedPayload; - - /** - * Overrides the flush method. - * This allows us to encode the MQTT payload into a WebSocket - * Frame before passing it through to the real socket. - */ - private ByteArrayOutputStream outputStream = new ExtendedByteArrayOutputStream(this); - - public WebSocketSecureNetworkModule(SSLSocketFactory factory, String uri, String host, int port, String clientId) { - super(factory, host, port, clientId); - this.uri = uri; - this.host = host; - this.port = port; - this.pipedInputStream = new PipedInputStream(); - log.setResourceName(clientId); - } - - public void start() throws IOException, MqttException { - super.start(); - WebSocketHandshake handshake = new WebSocketHandshake(super.getInputStream(), super.getOutputStream(), uri, host, port); - handshake.execute(); - this.webSocketReceiver = new WebSocketReceiver(getSocketInputStream(), pipedInputStream); - webSocketReceiver.start("WssSocketReceiver"); - - } - - OutputStream getSocketOutputStream() throws IOException { - return super.getOutputStream(); - } - - InputStream getSocketInputStream() throws IOException { - return super.getInputStream(); - } - - public InputStream getInputStream() throws IOException { - return pipedInputStream; - } - - public OutputStream getOutputStream() throws IOException { - return outputStream; - } - - public void stop() throws IOException { - // Creating Close Frame - WebSocketFrame frame = new WebSocketFrame((byte)0x08, true, "1000".getBytes()); - byte[] rawFrame = frame.encodeFrame(); - getSocketOutputStream().write(rawFrame); - getSocketOutputStream().flush(); - - if(webSocketReceiver != null){ - webSocketReceiver.stop(); - } - super.stop(); - } - - public String getServerURI() { - return "wss://" + host + ":" + port; - } - - - - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/CountingInputStream.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/CountingInputStream.java deleted file mode 100644 index 5d4eec7..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/CountingInputStream.java +++ /dev/null @@ -1,59 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.IOException; -import java.io.InputStream; - -/** - * An input stream that counts the bytes read from it. - */ -public class CountingInputStream extends InputStream { - private InputStream in; - private int counter; - - /** - * Constructs a new <code>CountingInputStream</code> wrapping the supplied - * input stream. - * @param in The {@link InputStream} - */ - public CountingInputStream(InputStream in) { - this.in = in; - this.counter = 0; - } - - public int read() throws IOException { - int i = in.read(); - if (i != -1) { - counter++; - } - return i; - } - - /** - * @return the number of bytes read since the last reset. - */ - public int getCounter() { - return counter; - } - - /** - * Resets the counter to zero. - */ - public void resetCounter() { - counter = 0; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttAck.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttAck.java deleted file mode 100644 index ffc7f41..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttAck.java +++ /dev/null @@ -1,37 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - - -/** - * Abstract super-class of all acknowledgement messages. - */ -public abstract class MqttAck extends MqttWireMessage { - public MqttAck(byte type) { - super(type); - } - - protected byte getMessageInfo() { - return 0; - } - - /** - * @return String representation of the wire message - */ - public String toString() { - return super.toString() + " msgId " + msgId; - } -} \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnack.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnack.java deleted file mode 100644 index 3d21619..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnack.java +++ /dev/null @@ -1,70 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - -/** - * An on-the-wire representation of an MQTT CONNACK. - */ -public class MqttConnack extends MqttAck { - public static final String KEY = "Con"; - - private int returnCode; - private boolean sessionPresent; - - public MqttConnack(byte info, byte[] variableHeader) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_CONNACK); - ByteArrayInputStream bais = new ByteArrayInputStream(variableHeader); - DataInputStream dis = new DataInputStream(bais); - sessionPresent = (dis.readUnsignedByte() & 0x01) == 0x01; - returnCode = dis.readUnsignedByte(); - dis.close(); - } - - public int getReturnCode() { - return returnCode; - } - - protected byte[] getVariableHeader() throws MqttException { - // Not needed, as the client never encodes a CONNACK - return new byte[0]; - } - - /** - * Returns whether or not this message needs to include a message ID. - */ - public boolean isMessageIdRequired() { - return false; - } - - public String getKey() { - return KEY; - } - - public String toString() { - return super.toString() + " session present:" + sessionPresent + " return code: " + returnCode; - } - - public boolean getSessionPresent() { - return sessionPresent; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnect.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnect.java deleted file mode 100644 index 6dfadfd..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttConnect.java +++ /dev/null @@ -1,168 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; - -/** - * An on-the-wire representation of an MQTT CONNECT message. - */ -public class MqttConnect extends MqttWireMessage { - - public static final String KEY = "Con"; - - private String clientId; - private boolean cleanSession; - private MqttMessage willMessage; - private String userName; - private char[] password; - private int keepAliveInterval; - private String willDestination; - private int MqttVersion; - - /** - * Constructor for an on the wire MQTT connect message - * - * @param info The info byte - * @param data the data byte array - * @throws IOException thrown if an exception occurs when reading the input streams - * @throws MqttException thrown if an exception occurs when decoding UTF-8 - */ - public MqttConnect(byte info, byte[] data) throws IOException, MqttException { - super(MqttWireMessage.MESSAGE_TYPE_CONNECT); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - - String protocol_name = decodeUTF8(dis); - int protocol_version = dis.readByte(); - byte connect_flags = dis.readByte(); - keepAliveInterval = dis.readUnsignedShort(); - clientId = decodeUTF8(dis); - dis.close(); - } - - public MqttConnect(String clientId, int MqttVersion, boolean cleanSession, int keepAliveInterval, String userName, char[] password, MqttMessage willMessage, String willDestination) { - super(MqttWireMessage.MESSAGE_TYPE_CONNECT); - this.clientId = clientId; - this.cleanSession = cleanSession; - this.keepAliveInterval = keepAliveInterval; - this.userName = userName; - this.password = password; - this.willMessage = willMessage; - this.willDestination = willDestination; - this.MqttVersion = MqttVersion; - } - - public String toString() { - String rc = super.toString(); - rc += " clientId " + clientId + " keepAliveInterval " + keepAliveInterval; - return rc; - } - - protected byte getMessageInfo() { - return (byte) 0; - } - - public boolean isCleanSession() { - return cleanSession; - } - - protected byte[] getVariableHeader() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - - if (MqttVersion == 3) { - encodeUTF8(dos,"MQIsdp"); - } - else if (MqttVersion == 4) { - encodeUTF8(dos,"MQTT"); - } - dos.write(MqttVersion); - - byte connectFlags = 0; - - if (cleanSession) { - connectFlags |= 0x02; - } - - if (willMessage != null ) { - connectFlags |= 0x04; - connectFlags |= (willMessage.getQos()<<3); - if (willMessage.isRetained()) { - connectFlags |= 0x20; - } - } - - if (userName != null) { - connectFlags |= 0x80; - if (password != null) { - connectFlags |= 0x40; - } - } - dos.write(connectFlags); - dos.writeShort(keepAliveInterval); - dos.flush(); - return baos.toByteArray(); - } catch(IOException ioe) { - throw new MqttException(ioe); - } - } - - public byte[] getPayload() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - encodeUTF8(dos,clientId); - - if (willMessage != null) { - encodeUTF8(dos,willDestination); - dos.writeShort(willMessage.getPayload().length); - dos.write(willMessage.getPayload()); - } - - if (userName != null) { - encodeUTF8(dos,userName); - if (password != null) { - encodeUTF8(dos,new String(password)); - } - } - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - /** - * Returns whether or not this message needs to include a message ID. - */ - public boolean isMessageIdRequired() { - return false; - } - - public String getKey() { - return KEY; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttDisconnect.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttDisconnect.java deleted file mode 100644 index 9aa618a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttDisconnect.java +++ /dev/null @@ -1,54 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - -/** - * An on-the-wire representation of an MQTT DISCONNECT message. - */ -public class MqttDisconnect extends MqttWireMessage { - public static final String KEY="Disc"; - - public MqttDisconnect() { - super(MqttWireMessage.MESSAGE_TYPE_DISCONNECT); - } - - public MqttDisconnect(byte info, byte[] variableHeader) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_DISCONNECT); - } - - protected byte getMessageInfo() { - return (byte) 0; - } - - protected byte[] getVariableHeader() throws MqttException { - return new byte[0]; - } - - /** - * Returns whether or not this message needs to include a message ID. - */ - public boolean isMessageIdRequired() { - return false; - } - - public String getKey() { - return KEY; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttInputStream.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttInputStream.java deleted file mode 100644 index 3a7b049..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttInputStream.java +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.IOException; -import java.io.InputStream; -import java.net.SocketTimeoutException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.internal.ClientState; -import org.eclipse.paho.client.mqttv3.internal.ExceptionHelper; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - - -/** - * An <code>MqttInputStream</code> lets applications read instances of - * <code>MqttWireMessage</code>. - */ -public class MqttInputStream extends InputStream { - private static final String CLASS_NAME = MqttInputStream.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private ClientState clientState = null; - private DataInputStream in; - private ByteArrayOutputStream bais; - private long remLen; - private long packetLen; - private byte[] packet; - - public MqttInputStream(ClientState clientState, InputStream in) { - this.clientState = clientState; - this.in = new DataInputStream(in); - this.bais = new ByteArrayOutputStream(); - this.remLen = -1; - } - - public int read() throws IOException { - return in.read(); - } - - public int available() throws IOException { - return in.available(); - } - - public void close() throws IOException { - in.close(); - } - - /** - * Reads an <code>MqttWireMessage</code> from the stream. - * If the message cannot be fully read within the socket read timeout, - * a null message is returned and the method can be called again until - * the message is fully read. - * @return The {@link MqttWireMessage} - * @throws IOException if an exception is thrown when reading from the stream - * @throws MqttException if the message is invalid - */ - public MqttWireMessage readMqttWireMessage() throws IOException, MqttException { - final String methodName ="readMqttWireMessage"; - - MqttWireMessage message = null; - try { - // read header - if (remLen < 0) { - // Assume we can read the whole header at once. - // The header is very small so it's likely we - // are able to read it fully or not at all. - // This keeps the parser lean since we don't - // need to cope with a partial header. - // Should we lose synch with the stream, - // the keepalive mechanism would kick in - // closing the connection. - bais.reset(); - - byte first = in.readByte(); - clientState.notifyReceivedBytes(1); - - byte type = (byte) ((first >>> 4) & 0x0F); - if ((type < MqttWireMessage.MESSAGE_TYPE_CONNECT) || - (type > MqttWireMessage.MESSAGE_TYPE_DISCONNECT)) { - // Invalid MQTT message type... - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_INVALID_MESSAGE); - } - remLen = MqttWireMessage.readMBI(in).getValue(); - bais.write(first); - // bit silly, we decode it then encode it - bais.write(MqttWireMessage.encodeMBI(remLen)); - packet = new byte[(int)(bais.size()+remLen)]; - packetLen = 0; - } - - // read remaining packet - if (remLen >= 0) { - // the remaining packet can be read with timeouts - readFully(); - - // reset packet parsing state - remLen = -1; - - byte[] header = bais.toByteArray(); - System.arraycopy(header,0,packet,0, header.length); - message = MqttWireMessage.createWireMessage(packet); - // @TRACE 501= received {0} - log.fine(CLASS_NAME, methodName, "501",new Object[] {message}); - } - } catch (SocketTimeoutException e) { - // ignore socket read timeout - } - - return message; - } - - private void readFully() throws IOException { - int off = bais.size() + (int) packetLen; - int len = (int) (remLen - packetLen); - if (len < 0) - throw new IndexOutOfBoundsException(); - int n = 0; - while (n < len) { - int count = -1; - try { - count = in.read(packet, off + n, len - n); - } catch (SocketTimeoutException e) { - // remember the packet read so far - packetLen += n; - throw e; - } - clientState.notifyReceivedBytes(count); - - if (count < 0) - throw new EOFException(); - n += count; - } - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttOutputStream.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttOutputStream.java deleted file mode 100644 index 95b9cea..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttOutputStream.java +++ /dev/null @@ -1,94 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.BufferedOutputStream; -import java.io.IOException; -import java.io.OutputStream; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.internal.ClientState; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - - -/** - * An <code>MqttOutputStream</code> lets applications write instances of - * <code>MqttWireMessage</code>. - */ -public class MqttOutputStream extends OutputStream { - private static final String CLASS_NAME = MqttOutputStream.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT, CLASS_NAME); - - private ClientState clientState = null; - private BufferedOutputStream out; - - public MqttOutputStream(ClientState clientState, OutputStream out) { - this.clientState = clientState; - this.out = new BufferedOutputStream(out); - } - - public void close() throws IOException { - out.close(); - } - - public void flush() throws IOException { - out.flush(); - } - - public void write(byte[] b) throws IOException { - out.write(b); - clientState.notifySentBytes(b.length); - } - - public void write(byte[] b, int off, int len) throws IOException { - out.write(b, off, len); - clientState.notifySentBytes(len); - } - - public void write(int b) throws IOException { - out.write(b); - } - - /** - * Writes an <code>MqttWireMessage</code> to the stream. - * @param message The {@link MqttWireMessage} to send - * @throws IOException if an exception is thrown when writing to the output stream. - * @throws MqttException if an exception is thrown when getting the header or payload - */ - public void write(MqttWireMessage message) throws IOException, MqttException { - final String methodName = "write"; - byte[] bytes = message.getHeader(); - byte[] pl = message.getPayload(); -// out.write(message.getHeader()); -// out.write(message.getPayload()); - out.write(bytes,0,bytes.length); - clientState.notifySentBytes(bytes.length); - - int offset = 0; - int chunckSize = 1024; - while (offset < pl.length) { - int length = Math.min(chunckSize, pl.length - offset); - out.write(pl, offset, length); - offset += chunckSize; - clientState.notifySentBytes(length); - } - - // @TRACE 529= sent {0} - log.fine(CLASS_NAME, methodName, "529", new Object[]{message}); - } -} - diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPersistableWireMessage.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPersistableWireMessage.java deleted file mode 100644 index c826d87..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPersistableWireMessage.java +++ /dev/null @@ -1,67 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttPersistable; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; - -public abstract class MqttPersistableWireMessage extends MqttWireMessage - implements MqttPersistable { - - public MqttPersistableWireMessage(byte type) { - super(type); - } - - public byte[] getHeaderBytes() throws MqttPersistenceException { - try { - return getHeader(); - } - catch (MqttException ex) { - throw new MqttPersistenceException(ex.getCause()); - } - } - - public int getHeaderLength() throws MqttPersistenceException { - return getHeaderBytes().length; - } - - public int getHeaderOffset() throws MqttPersistenceException{ - return 0; - } - -// public String getKey() throws MqttPersistenceException { -// return new Integer(getMessageId()).toString(); -// } - - public byte[] getPayloadBytes() throws MqttPersistenceException { - try { - return getPayload(); - } - catch (MqttException ex) { - throw new MqttPersistenceException(ex.getCause()); - } - } - - public int getPayloadLength() throws MqttPersistenceException { - return 0; - } - - public int getPayloadOffset() throws MqttPersistenceException { - return 0; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingReq.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingReq.java deleted file mode 100644 index e2472be..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingReq.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - -/** - * An on-the-wire representation of an MQTT PINGREQ message. - */ -public class MqttPingReq extends MqttWireMessage { - public static final String KEY = "Ping"; - - public MqttPingReq() { - super(MqttWireMessage.MESSAGE_TYPE_PINGREQ); - } - - public MqttPingReq(byte info, byte[] variableHeader) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_PINGREQ); - } - - /** - * Returns <code>false</code> as message IDs are not required for MQTT - * PINGREQ messages. - */ - public boolean isMessageIdRequired() { - return false; - } - - protected byte[] getVariableHeader() throws MqttException { - return new byte[0]; - } - - protected byte getMessageInfo() { - return 0; - } - - public String getKey() { - return KEY; - } -} - diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingResp.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingResp.java deleted file mode 100644 index 4f07fc9..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPingResp.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import org.eclipse.paho.client.mqttv3.MqttException; - - -/** - * An on-the-wire representation of an MQTT PINGRESP. - */ -public class MqttPingResp extends MqttAck { - public static final String KEY = "Ping"; - - public MqttPingResp(byte info, byte[] variableHeader) { - super(MqttWireMessage.MESSAGE_TYPE_PINGRESP); - } - - protected byte[] getVariableHeader() throws MqttException { - // Not needed, as the client never encodes a PINGRESP - return new byte[0]; - } - - /** - * Returns whether or not this message needs to include a message ID. - */ - public boolean isMessageIdRequired() { - return false; - } - - public String getKey() { - return KEY; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubAck.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubAck.java deleted file mode 100644 index de3ab5f..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubAck.java +++ /dev/null @@ -1,52 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2015 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - ack control (bug 472172) - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - - - -/** - * An on-the-wire representation of an MQTT PUBACK message. - */ -public class MqttPubAck extends MqttAck { - public MqttPubAck(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_PUBACK); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - dis.close(); - } - - public MqttPubAck(MqttPublish publish) { - super(MqttWireMessage.MESSAGE_TYPE_PUBACK); - msgId = publish.getMessageId(); - } - - public MqttPubAck(int messageId) { - super(MqttWireMessage.MESSAGE_TYPE_PUBACK); - msgId = messageId; - } - - protected byte[] getVariableHeader() throws MqttException { - return encodeMessageId(); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubComp.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubComp.java deleted file mode 100644 index 59c90b0..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubComp.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - - - -/** - * An on-the-wire representation of an MQTT PUBCOMP message. - */ -public class MqttPubComp extends MqttAck { - public MqttPubComp(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_PUBCOMP); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - dis.close(); - } - - public MqttPubComp(MqttPublish publish) { - super(MqttWireMessage.MESSAGE_TYPE_PUBCOMP); - this.msgId = publish.getMessageId(); - } - - public MqttPubComp(int msgId) { - super(MqttWireMessage.MESSAGE_TYPE_PUBCOMP); - this.msgId = msgId; - } - - protected byte[] getVariableHeader() throws MqttException { - return encodeMessageId(); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRec.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRec.java deleted file mode 100644 index f2dac68..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRec.java +++ /dev/null @@ -1,46 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - - - -/** - * An on-the-wire representation of an MQTT PUBREC message. - */ -public class MqttPubRec extends MqttAck { - public MqttPubRec(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_PUBREC); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - dis.close(); - } - - public MqttPubRec(MqttPublish publish) { - super(MqttWireMessage.MESSAGE_TYPE_PUBREC); - msgId = publish.getMessageId(); - } - - protected byte[] getVariableHeader() throws MqttException { - return encodeMessageId(); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRel.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRel.java deleted file mode 100644 index 0db14ff..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPubRel.java +++ /dev/null @@ -1,64 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - -/** - * An on-the-wire representation of an MQTT PUBREL message. - */ -public class MqttPubRel extends MqttPersistableWireMessage { - - /** - * Createa a pubrel message based on a pubrec - * @param pubRec the {@link MqttPubRec} - */ - public MqttPubRel(MqttPubRec pubRec) { - super(MqttWireMessage.MESSAGE_TYPE_PUBREL); - this.setMessageId(pubRec.getMessageId()); - } - - /** - * Creates a pubrel based on a pubrel set of bytes read fro the network - * @param info the info byte - * @param data the byte array - * @throws IOException if an exception occurs whilst reading from the input stream - */ - public MqttPubRel(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_PUBREL); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - dis.close(); - } - - protected byte[] getVariableHeader() throws MqttException { - return encodeMessageId(); - } - - protected byte getMessageInfo() { - return (byte)( 2 | (this.duplicate?8:0)); - } - - public String toString() { - return super.toString() + " msgId " + msgId; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPublish.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPublish.java deleted file mode 100644 index 9c8a278..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttPublish.java +++ /dev/null @@ -1,181 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; - -/** - * An on-the-wire representation of an MQTT SEND message. - */ -public class MqttPublish extends MqttPersistableWireMessage { - - private MqttMessage message; - private String topicName; - - private byte[] encodedPayload = null; - - public MqttPublish(String name, MqttMessage message) { - super(MqttWireMessage.MESSAGE_TYPE_PUBLISH); - topicName = name; - this.message = message; - } - - /** - * Constructs a new MqttPublish object. - * @param info the message info byte - * @param data the variable header and payload bytes - * @throws MqttException if an exception occurs creating the publish - * @throws IOException if an exception occurs creating the publish - */ - public MqttPublish(byte info, byte[] data) throws MqttException, IOException { - super(MqttWireMessage.MESSAGE_TYPE_PUBLISH); - message = new MqttReceivedMessage(); - message.setQos((info >> 1) & 0x03); - if ((info & 0x01) == 0x01) { - message.setRetained(true); - } - if ((info & 0x08) == 0x08) { - ((MqttReceivedMessage) message).setDuplicate(true); - } - - ByteArrayInputStream bais = new ByteArrayInputStream(data); - CountingInputStream counter = new CountingInputStream(bais); - DataInputStream dis = new DataInputStream(counter); - topicName = decodeUTF8(dis); - if (message.getQos() > 0) { - msgId = dis.readUnsignedShort(); - } - byte[] payload = new byte[data.length-counter.getCounter()]; - dis.readFully(payload); - dis.close(); - message.setPayload(payload); - } - - public String toString() { - - // Convert the first few bytes of the payload into a hex string - StringBuffer hex = new StringBuffer(); - byte[] payload = message.getPayload(); - int limit = Math.min(payload.length, 20); - for (int i = 0; i < limit; i++) { - byte b = payload[i]; - String ch = Integer.toHexString(b); - if (ch.length() == 1) { - ch = "0" + ch; - } - hex.append(ch); - } - - // It will not always be possible to convert the binary payload into - // characters, but never-the-less we attempt to do this as it is often - // useful - String string = null; - try { - string = new String(payload, 0, limit, "UTF-8"); - } catch (Exception e) { - string = "?"; - } - - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()); - sb.append(" qos:").append(message.getQos()); - if (message.getQos() > 0) { - sb.append(" msgId:").append(msgId); - } - sb.append(" retained:").append(message.isRetained()); - sb.append(" dup:").append(duplicate); - sb.append(" topic:\"").append(topicName).append("\""); - sb.append(" payload:[hex:").append(hex); - sb.append(" utf8:\"").append(string).append("\""); - sb.append(" length:").append(payload.length).append("]"); - - return sb.toString(); - } - - protected byte getMessageInfo() { - byte info = (byte) (message.getQos() << 1); - if (message.isRetained()) { - info |= 0x01; - } - if (message.isDuplicate() || duplicate ) { - info |= 0x08; - } - - return info; - } - - public String getTopicName() { - return topicName; - } - - public MqttMessage getMessage() { - return message; - } - - protected static byte[] encodePayload(MqttMessage message) { - return message.getPayload(); - } - - public byte[] getPayload() throws MqttException { - if (encodedPayload == null) { - encodedPayload = encodePayload(message); - } - return encodedPayload; - } - - public int getPayloadLength() { - int length = 0; - try { - length = getPayload().length; - } catch(MqttException me) { - } - return length; - } - - public void setMessageId(int msgId) { - super.setMessageId(msgId); - if (message instanceof MqttReceivedMessage) { - ((MqttReceivedMessage)message).setMessageId(msgId); - } - } - - protected byte[] getVariableHeader() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - encodeUTF8(dos, topicName); - if (message.getQos() > 0) { - dos.writeShort(msgId); - } - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public boolean isMessageIdRequired() { - // all publishes require a message ID as it's used as the key to the token store - return true; - } -} \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttReceivedMessage.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttReceivedMessage.java deleted file mode 100644 index d5290e0..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttReceivedMessage.java +++ /dev/null @@ -1,35 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import org.eclipse.paho.client.mqttv3.MqttMessage; - -public class MqttReceivedMessage extends MqttMessage { - - public void setMessageId(int msgId) { - super.setId(msgId); - } - - public int getMessageId() { - return super.getId(); - } - - // This method exists here to get around the protected visibility of the - // super class method. - public void setDuplicate(boolean value) { - super.setDuplicate(value); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSuback.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSuback.java deleted file mode 100644 index cd74a43..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSuback.java +++ /dev/null @@ -1,66 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - * Ian Craggs - MQTT 3.1.1 support - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - - -/** - * An on-the-wire representation of an MQTT SUBACK. - */ -public class MqttSuback extends MqttAck { - private int[] grantedQos; - - public MqttSuback(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_SUBACK); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - int index = 0; - grantedQos = new int[data.length-2]; - int qos = dis.read(); - while (qos != -1) { - grantedQos[index] = qos; - index++; - qos = dis.read(); - } - dis.close(); - } - - protected byte[] getVariableHeader() throws MqttException { - // Not needed, as the client never encodes a SUBACK - return new byte[0]; - } - - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()).append(" granted Qos"); - for (int i = 0; i < grantedQos.length; ++i) { - sb.append(" ").append(grantedQos[i]); - } - return sb.toString(); - } - - public int[] getGrantedQos() { - return grantedQos; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSubscribe.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSubscribe.java deleted file mode 100644 index dcca4b8..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttSubscribe.java +++ /dev/null @@ -1,143 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttMessage; - - -/** - * An on-the-wire representation of an MQTT SUBSCRIBE message. - */ -public class MqttSubscribe extends MqttWireMessage { - private String[] names; - private int[] qos; - private int count; - - /** - * Constructor for an on the wire MQTT subscribe message - * - * @param info the info byte - * @param data the data byte array - * @throws IOException if an exception occurs whilst reading the input stream - */ - public MqttSubscribe(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_SUBSCRIBE); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - - count = 0; - names = new String[10]; - qos = new int[10]; - boolean end = false; - while (!end) { - try { - names[count] = decodeUTF8(dis); - qos[count++] = dis.readByte(); - } catch (Exception e) { - end = true; - } - } - dis.close(); - } - - /** - * Constructor for an on the wire MQTT subscribe message - * @param names - one or more topics to subscribe to - * @param qos - the max QoS that each each topic will be subscribed at - */ - public MqttSubscribe(String[] names, int[] qos) { - super(MqttWireMessage.MESSAGE_TYPE_SUBSCRIBE); - this.names = names; - this.qos = qos; - - if (names.length != qos.length) { - throw new IllegalArgumentException(); - } - this.count = names.length; - - for (int i=0;i<qos.length;i++) { - MqttMessage.validateQos(qos[i]); - } - } - - /** - * @return string representation of this subscribe packet - */ - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()); - sb.append(" names:["); - for (int i = 0; i < count; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append("\"").append(names[i]).append("\""); - } - sb.append("] qos:["); - for (int i = 0; i < count; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append(qos[i]); - } - sb.append("]"); - - return sb.toString(); - } - - protected byte getMessageInfo() { - return (byte) (2 | (duplicate ? 8 : 0)); - } - - protected byte[] getVariableHeader() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeShort(msgId); - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public byte[] getPayload() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - for (int i=0; i<names.length; i++) { - encodeUTF8(dos,names[i]); - dos.writeByte(qos[i]); - } - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public boolean isRetryable() { - return true; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubAck.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubAck.java deleted file mode 100644 index 916188c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubAck.java +++ /dev/null @@ -1,42 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - - -/** - * An on-the-wire representation of an MQTT UNSUBACK. - */ -public class MqttUnsubAck extends MqttAck { - - public MqttUnsubAck(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_UNSUBACK); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - dis.close(); - } - - protected byte[] getVariableHeader() throws MqttException { - // Not needed, as the client never encodes an UNSUBACK - return new byte[0]; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubscribe.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubscribe.java deleted file mode 100644 index 5a6fe99..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttUnsubscribe.java +++ /dev/null @@ -1,119 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; - -/** - * An on-the-wire representation of an MQTT UNSUBSCRIBE message. - */ -public class MqttUnsubscribe extends MqttWireMessage { - - private String[] names; - private int count; - - /** - * Constructs an MqttUnsubscribe - * @param names The topics to unsubscribe from - */ - public MqttUnsubscribe(String[] names) { - super(MqttWireMessage.MESSAGE_TYPE_UNSUBSCRIBE); - this.names = names; - } - - /** - * Constructor for an on the wire MQTT un-subscribe message - * - * @param info the info byte - * @param data the data byte array - * @throws IOException if an exception occurs whilst reading the input stream - */ - public MqttUnsubscribe(byte info, byte[] data) throws IOException { - super(MqttWireMessage.MESSAGE_TYPE_UNSUBSCRIBE); - ByteArrayInputStream bais = new ByteArrayInputStream(data); - DataInputStream dis = new DataInputStream(bais); - msgId = dis.readUnsignedShort(); - - count = 0; - names = new String[10]; - boolean end = false; - while (!end) { - try { - names[count] = decodeUTF8(dis); - } catch (Exception e) { - end = true; - } - } - dis.close(); - } - - /** - * @return string representation of this un-subscribe packet - */ - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(super.toString()); - sb.append(" names:["); - for (int i = 0; i < count; i++) { - if (i > 0) { - sb.append(", "); - } - sb.append("\"" + names[i] + "\""); - } - sb.append("]"); - return sb.toString(); - } - - protected byte getMessageInfo() { - return (byte) (2 | (duplicate ? 8 : 0)); - } - - protected byte[] getVariableHeader() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeShort(msgId); - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public byte[] getPayload() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - for (int i=0; i<names.length; i++) { - encodeUTF8(dos, names[i]); - } - dos.flush(); - return baos.toByteArray(); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public boolean isRetryable() { - return true; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttWireMessage.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttWireMessage.java deleted file mode 100644 index ba1dc00..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MqttWireMessage.java +++ /dev/null @@ -1,359 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.UnsupportedEncodingException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttPersistable; -import org.eclipse.paho.client.mqttv3.internal.ExceptionHelper; - - -/** - * An on-the-wire representation of an MQTT message. - */ -public abstract class MqttWireMessage { - public static final byte MESSAGE_TYPE_CONNECT = 1; - public static final byte MESSAGE_TYPE_CONNACK = 2; - public static final byte MESSAGE_TYPE_PUBLISH = 3; - public static final byte MESSAGE_TYPE_PUBACK = 4; - public static final byte MESSAGE_TYPE_PUBREC = 5; - public static final byte MESSAGE_TYPE_PUBREL = 6; - public static final byte MESSAGE_TYPE_PUBCOMP = 7; - public static final byte MESSAGE_TYPE_SUBSCRIBE = 8; - public static final byte MESSAGE_TYPE_SUBACK = 9; - public static final byte MESSAGE_TYPE_UNSUBSCRIBE = 10; - public static final byte MESSAGE_TYPE_UNSUBACK = 11; - public static final byte MESSAGE_TYPE_PINGREQ = 12; - public static final byte MESSAGE_TYPE_PINGRESP = 13; - public static final byte MESSAGE_TYPE_DISCONNECT = 14; - - protected static final String STRING_ENCODING = "UTF-8"; - - private static final String PACKET_NAMES[] = { "reserved", "CONNECT", "CONNACK", "PUBLISH", - "PUBACK", "PUBREC", "PUBREL", "PUBCOMP", "SUBSCRIBE", "SUBACK", - "UNSUBSCRIBE", "UNSUBACK", "PINGREQ", "PINGRESP", "DISCONNECT" }; - - //The type of the message (e.g. CONNECT, PUBLISH, PUBACK) - private byte type; - //The MQTT message ID - protected int msgId; - - protected boolean duplicate = false; - - - public MqttWireMessage(byte type) { - this.type = type; - // Use zero as the default message ID. Can't use -1, as that is serialized - // as 65535, which would be a valid ID. - this.msgId = 0; - } - - /** - * Sub-classes should override this to encode the message info. - * Only the least-significant four bits will be used. - * @return The Message information byte - */ - protected abstract byte getMessageInfo(); - - /** - * Sub-classes should override this method to supply the payload bytes. - * @return The payload byte array - * @throws MqttException if an exception occurs whilst getting the payload - */ - public byte[] getPayload() throws MqttException { - return new byte[0]; - } - - /** - * @return the type of the message. - */ - public byte getType() { - return type; - } - - /** - * @return the MQTT message ID. - */ - public int getMessageId() { - return msgId; - } - - /** - * Sets the MQTT message ID. - * @param msgId the MQTT message ID - */ - public void setMessageId(int msgId) { - this.msgId = msgId; - } - - /** - * Returns a key associated with the message. For most message types - * this will be unique. For connect, disconnect and ping only one - * message of this type is allowed so a fixed key will be returned - * @return key a key associated with the message - */ - public String getKey() { - return new Integer(getMessageId()).toString(); - } - - public byte[] getHeader() throws MqttException { - try { - int first = ((getType() & 0x0f) << 4) ^ (getMessageInfo() & 0x0f); - byte[] varHeader = getVariableHeader(); - int remLen = varHeader.length + getPayload().length; - - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeByte(first); - dos.write(encodeMBI(remLen)); - dos.write(varHeader); - dos.flush(); - return baos.toByteArray(); - } catch(IOException ioe) { - throw new MqttException(ioe); - } - } - - protected abstract byte[] getVariableHeader() throws MqttException; - - - /** - * @return whether or not this message needs to include a message ID. - */ - public boolean isMessageIdRequired() { - return true; - } - - public static MqttWireMessage createWireMessage(MqttPersistable data) throws MqttException { - byte[] payload = data.getPayloadBytes(); - // The persistable interface allows a message to be restored entirely in the header array - // Need to treat these two arrays as a single array of bytes and use the decoding - // logic to identify the true header/payload split - if (payload == null) { - payload = new byte[0]; - } - MultiByteArrayInputStream mbais = new MultiByteArrayInputStream( - data.getHeaderBytes(), - data.getHeaderOffset(), - data.getHeaderLength(), - payload, - data.getPayloadOffset(), - data.getPayloadLength()); - return createWireMessage(mbais); - } - - public static MqttWireMessage createWireMessage(byte[] bytes) throws MqttException { - ByteArrayInputStream bais = new ByteArrayInputStream(bytes); - return createWireMessage(bais); - } - - private static MqttWireMessage createWireMessage(InputStream inputStream) throws MqttException { - try { - CountingInputStream counter = new CountingInputStream(inputStream); - DataInputStream in = new DataInputStream(counter); - int first = in.readUnsignedByte(); - byte type = (byte) (first >> 4); - byte info = (byte) (first &= 0x0f); - long remLen = readMBI(in).getValue(); - long totalToRead = counter.getCounter() + remLen; - - MqttWireMessage result; - long remainder = totalToRead - counter.getCounter(); - byte[] data = new byte[0]; - // The remaining bytes must be the payload... - if (remainder > 0) { - data = new byte[(int) remainder]; - in.readFully(data, 0, data.length); - } - - if (type == MqttWireMessage.MESSAGE_TYPE_CONNECT) { - result = new MqttConnect(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PUBLISH) { - result = new MqttPublish(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PUBACK) { - result = new MqttPubAck(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PUBCOMP) { - result = new MqttPubComp(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_CONNACK) { - result = new MqttConnack(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PINGREQ) { - result = new MqttPingReq(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PINGRESP) { - result = new MqttPingResp(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_SUBSCRIBE) { - result = new MqttSubscribe(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_SUBACK) { - result = new MqttSuback(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_UNSUBSCRIBE) { - result = new MqttUnsubscribe(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_UNSUBACK) { - result = new MqttUnsubAck(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PUBREL) { - result = new MqttPubRel(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_PUBREC) { - result = new MqttPubRec(info, data); - } - else if (type == MqttWireMessage.MESSAGE_TYPE_DISCONNECT) { - result = new MqttDisconnect(info, data); - } - else { - throw ExceptionHelper.createMqttException(MqttException.REASON_CODE_UNEXPECTED_ERROR); - } - return result; - } catch(IOException io) { - throw new MqttException(io); - } - } - - protected static byte[] encodeMBI( long number) { - int numBytes = 0; - long no = number; - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - // Encode the remaining length fields in the four bytes - do { - byte digit = (byte)(no % 128); - no = no / 128; - if (no > 0) { - digit |= 0x80; - } - bos.write(digit); - numBytes++; - } while ( (no > 0) && (numBytes<4) ); - - return bos.toByteArray(); - } - - /** - * Decodes an MQTT Multi-Byte Integer from the given stream. - * @param in the input stream - * @return {@link MultiByteInteger} - * @throws IOException if an exception occurs when reading the input stream - */ - protected static MultiByteInteger readMBI(DataInputStream in) throws IOException { - byte digit; - long msgLength = 0; - int multiplier = 1; - int count = 0; - - do { - digit = in.readByte(); - count++; - msgLength += ((digit & 0x7F) * multiplier); - multiplier *= 128; - } while ((digit & 0x80) != 0); - - return new MultiByteInteger(msgLength, count); - } - - protected byte[] encodeMessageId() throws MqttException { - try { - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DataOutputStream dos = new DataOutputStream(baos); - dos.writeShort(msgId); - dos.flush(); - return baos.toByteArray(); - } - catch (IOException ex) { - throw new MqttException(ex); - } - } - - public boolean isRetryable() { - return false; - } - - public void setDuplicate(boolean duplicate) { - this.duplicate = duplicate; - } - - /** - * Encodes a String given into UTF-8, before writing this to the DataOutputStream the length of the - * encoded string is encoded into two bytes and then written to the DataOutputStream. @link{DataOutputStream#writeUFT(String)} - * should be no longer used. @link{DataOutputStream#writeUFT(String)} does not correctly encode UTF-16 surrogate characters. - * - * @param dos The stream to write the encoded UTF-8 String to. - * @param stringToEncode The String to be encoded - * @throws MqttException Thrown when an error occurs with either the encoding or writing the data to the stream - */ - protected void encodeUTF8(DataOutputStream dos, String stringToEncode) throws MqttException - { - try { - - byte[] encodedString = stringToEncode.getBytes("UTF-8"); - byte byte1 = (byte) ((encodedString.length >>> 8) & 0xFF); - byte byte2 = (byte) ((encodedString.length >>> 0) & 0xFF); - - - dos.write(byte1); - dos.write(byte2); - dos.write(encodedString); - } - catch(UnsupportedEncodingException ex) - { - throw new MqttException(ex); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - /** - * Decodes a UTF-8 string from the DataInputStream provided. @link(DataInoutStream#readUTF()) should be no longer used, because @link(DataInoutStream#readUTF()) - * does not decode UTF-16 surrogate characters correctly. - * - * @param input The input stream from which to read the encoded string - * @return a decoded String from the DataInputStream - * @throws MqttException thrown when an error occurs with either reading from the stream or - * decoding the encoded string. - */ - protected String decodeUTF8(DataInputStream input) throws MqttException - { - int encodedLength; - try { - encodedLength = input.readUnsignedShort(); - - byte[] encodedString = new byte[encodedLength]; - input.readFully(encodedString); - - return new String(encodedString, "UTF-8"); - } catch (IOException ex) { - throw new MqttException(ex); - } - } - - public String toString() { - return PACKET_NAMES[type]; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteArrayInputStream.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteArrayInputStream.java deleted file mode 100644 index b9b9511..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteArrayInputStream.java +++ /dev/null @@ -1,56 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -import java.io.IOException; -import java.io.InputStream; - -public class MultiByteArrayInputStream extends InputStream { - - private byte[] bytesA; - private int offsetA; - private int lengthA; - private byte[] bytesB; - private int offsetB; - private int lengthB; - - private int pos = 0; - - public MultiByteArrayInputStream(byte[] bytesA, int offsetA, int lengthA, byte[] bytesB, int offsetB, int lengthB) { - this.bytesA = bytesA; - this.bytesB = bytesB; - this.offsetA = offsetA; - this.offsetB = offsetB; - this.lengthA = lengthA; - this.lengthB = lengthB; - } - public int read() throws IOException { - int result = -1; - if (pos<lengthA) { - result = bytesA[offsetA+pos]; - } else if (pos<lengthA+lengthB) { - result = bytesB[offsetB+pos-lengthA]; - } else { - return -1; - } - if (result < 0) { - result += 256; - } - pos++; - return result; - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteInteger.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteInteger.java deleted file mode 100644 index 0b7f2a5..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/internal/wire/MultiByteInteger.java +++ /dev/null @@ -1,48 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.internal.wire; - -/** - * Represents a Multi-Byte Integer (MBI), as defined by the MQTT V3 - * specification. - */ -public class MultiByteInteger { - private long value; - private int length; - - public MultiByteInteger(long value) { - this(value, -1); - } - - public MultiByteInteger(long value, int length) { - this.value = value; - this.length = length; - } - - /** - * @return the number of bytes read when decoding this MBI. - */ - public int getEncodedLength() { - return length; - } - - /** - * @return the value of this MBI. - */ - public long getValue() { - return value; - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/JSR47Logger.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/JSR47Logger.java deleted file mode 100644 index 99bc852..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/JSR47Logger.java +++ /dev/null @@ -1,278 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.logging; -import java.text.MessageFormat; -import java.util.MissingResourceException; -import java.util.ResourceBundle; -import java.util.logging.Handler; -import java.util.logging.LogRecord; -import java.util.logging.MemoryHandler; - -/** - * Implementation of the the logger interface that uses java.uti.logging - * - * A Logger that utilises Java's built in logging facility - java.util.logging. - * <p>A sample java.util.logging properties file - jsr47min.properties is provided that demonstrates - * how to run with a memory based trace facility that runs with minimal performance - * overhead. The memory buffer can be dumped when a log/trace record is written matching - * the MemoryHandlers trigger level or when the push method is invoked on the MemoryHandler. - * {@link org.eclipse.paho.client.mqttv3.util.Debug Debug} provides method to make it easy - * to dump the memory buffer as well as other useful debug info. - */ -public class JSR47Logger implements Logger { - private java.util.logging.Logger julLogger = null; - private ResourceBundle logMessageCatalog = null; - private ResourceBundle traceMessageCatalog = null; - private String catalogID = null; - private String resourceName = null; - private String loggerName = null; - - /** - * - * @param logMsgCatalog The resource bundle associated with this logger - * @param loggerID The suffix for the loggerName (will be appeneded to org.eclipse.paho.client.mqttv3 - * @param resourceContext A context for the logger e.g. clientID or appName... - */ - public void initialise(ResourceBundle logMsgCatalog, String loggerID, String resourceContext ) { - this.traceMessageCatalog = logMessageCatalog; - this.resourceName = resourceContext; -// loggerName = "org.eclipse.paho.client.mqttv3." + ((null == loggerID || 0 == loggerID.length()) ? "internal" : loggerID); - loggerName = loggerID; - this.julLogger = java.util.logging.Logger.getLogger(loggerName); - this.logMessageCatalog = logMsgCatalog; - this.traceMessageCatalog = logMsgCatalog; - this.catalogID = logMessageCatalog.getString("0"); - - } - - public void setResourceName(String logContext) { - this.resourceName = logContext; - } - - public boolean isLoggable(int level) { - return julLogger.isLoggable(mapJULLevel(level)); // || InternalTracer.isLoggable(level); - } - - public void severe(String sourceClass, String sourceMethod, String msg) { - log(SEVERE, sourceClass, sourceMethod, msg, null, null); - } - - public void severe(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - log(SEVERE, sourceClass, sourceMethod, msg, inserts, null); - } - - public void severe(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown) { - log(SEVERE, sourceClass, sourceMethod, msg, inserts, thrown); - } - - public void warning(String sourceClass, String sourceMethod, String msg) { - log(WARNING, sourceClass, sourceMethod, msg, null, null); - } - - public void warning(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - log(WARNING, sourceClass, sourceMethod, msg, inserts, null); - } - - public void warning(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown) { - log(WARNING, sourceClass, sourceMethod, msg, inserts, thrown); - } - - public void info(String sourceClass, String sourceMethod, String msg) { - log(INFO, sourceClass, sourceMethod, msg, null, null); - } - - public void info(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - log(INFO, sourceClass, sourceMethod, msg, inserts, null); - } - - public void info(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown) { - log(INFO, sourceClass, sourceMethod, msg, inserts, thrown); - } - - public void config(String sourceClass, String sourceMethod, String msg) { - log(CONFIG, sourceClass, sourceMethod, msg, null, null); - } - - public void config(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - log(CONFIG, sourceClass, sourceMethod, msg, inserts, null); - } - - public void config(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown) { - log(CONFIG, sourceClass, sourceMethod, msg, inserts, thrown); - } - - public void log(int level, String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown) { -// InternalTracer.log(this.catalogID, level, sourceClass, sourceMethod, msg, inserts, thrown); - java.util.logging.Level julLevel = mapJULLevel(level); - if (julLogger.isLoggable(julLevel)) { - logToJsr47(julLevel, sourceClass, sourceMethod, this.catalogID, this.logMessageCatalog, msg, inserts, thrown); - } - } - -// public void setTrace(Trace trace) { -// InternalTracer.setTrace(trace); -// } - - public void fine(String sourceClass, String sourceMethod, String msg) { - trace(FINE, sourceClass, sourceMethod, msg, null, null); - } - - public void fine(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - trace(FINE, sourceClass, sourceMethod, msg, inserts, null); - } - - public void fine(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex) { - trace(FINE, sourceClass, sourceMethod, msg, inserts, ex); - } - - public void finer(String sourceClass, String sourceMethod, String msg) { - trace(FINER, sourceClass, sourceMethod, msg, null, null); - } - - public void finer(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - trace(FINER, sourceClass, sourceMethod, msg, inserts, null); - } - - public void finer(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex) { - trace(FINER, sourceClass, sourceMethod, msg, inserts, ex); - } - - public void finest(String sourceClass, String sourceMethod, String msg) { - trace(FINEST, sourceClass, sourceMethod, msg, null, null); - } - - public void finest(String sourceClass, String sourceMethod, String msg, Object[] inserts) { - trace(FINEST, sourceClass, sourceMethod, msg, inserts, null); - } - - public void finest(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex) { - trace(FINEST, sourceClass, sourceMethod, msg, inserts, ex); - } - - - public void trace(int level, String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex) { - java.util.logging.Level julLevel = mapJULLevel(level); - boolean isJULLoggable = julLogger.isLoggable(julLevel); -// if (FINE == level || isJULLoggable || InternalTracer.isLoggable(level)) { -// InternalTracer.traceForced(level, sourceClass, sourceMethod, msg, inserts); -// } - if (isJULLoggable) { - logToJsr47(julLevel, sourceClass, sourceMethod, this.catalogID, this.traceMessageCatalog, msg, inserts, ex); - } - } - - - private String getResourceMessage(ResourceBundle messageCatalog, String msg) { - String message; - try { - message = messageCatalog.getString(msg); - } catch (MissingResourceException e) { - // This is acceptable, simply return the given msg string. - message = msg; - } - return message; - } - - private void logToJsr47(java.util.logging.Level julLevel, String sourceClass, String sourceMethod, String catalogName, - ResourceBundle messageCatalog, String msg, Object[] inserts, Throwable thrown) { -// LogRecord logRecord = new LogRecord(julLevel, msg); - String formattedWithArgs = msg; - if (msg.indexOf("=====")== -1) { - formattedWithArgs = MessageFormat.format(getResourceMessage(messageCatalog, msg), inserts); - } - LogRecord logRecord = new LogRecord(julLevel, resourceName + ": " +formattedWithArgs); - - logRecord.setSourceClassName(sourceClass); - logRecord.setSourceMethodName(sourceMethod); - logRecord.setLoggerName(loggerName); -// logRecord.setResourceBundleName(catalogName); -// logRecord.setResourceBundle(messageCatalog); -// if (null != inserts) { -// logRecord.setParameters(inserts); -// } - if (null != thrown) { - logRecord.setThrown(thrown); - } - - julLogger.log(logRecord); - } - - private java.util.logging.Level mapJULLevel(int level) { - java.util.logging.Level julLevel = null; - - switch (level) { - case SEVERE: - julLevel = java.util.logging.Level.SEVERE; - break; - case WARNING: - julLevel = java.util.logging.Level.WARNING; - break; - case INFO: - julLevel = java.util.logging.Level.INFO; - break; - case CONFIG: - julLevel = java.util.logging.Level.CONFIG; - break; - case FINE: - julLevel = java.util.logging.Level.FINE; - break; - case FINER: - julLevel = java.util.logging.Level.FINER; - break; - case FINEST: - julLevel = java.util.logging.Level.FINEST; - break; - - default: - } - - return julLevel; - } - - public String formatMessage(String msg, Object[] inserts) { - String formatString; - try { - formatString = logMessageCatalog.getString(msg); - } catch (MissingResourceException e) { - formatString = msg; - } - return formatString; - } - - public void dumpTrace() { - dumpMemoryTrace47(julLogger); - } - - protected static void dumpMemoryTrace47(java.util.logging.Logger logger) { - MemoryHandler mHand = null; - - if (logger!= null) { - Handler[] handlers = logger.getHandlers(); - - for (int i=0; i<handlers.length; i++) { - if (handlers[i] instanceof java.util.logging.MemoryHandler) { - synchronized (handlers[i]) { - mHand = ((java.util.logging.MemoryHandler)handlers[i]); - mHand.push(); - return; - } // synchronized (handler). - } - } // for handlers... - dumpMemoryTrace47(logger.getParent()); - } - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/Logger.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/Logger.java deleted file mode 100644 index a272195..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/Logger.java +++ /dev/null @@ -1,579 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.logging; - -import java.util.ResourceBundle; - -/** - * A Logger object is used to send log and trace messages to a platform - * specific logging implementation. Loggers are named, using a hierarchical - * dot-separated name-space. - * Logger names can be arbitrary strings, but they should normally be based on - * the component or the package name of the logged component - * - * Logger objects may be obtained by calls on one of the getLogger factory - * methods. These will either create a new Logger or return a suitable existing - * Logger. - * - * <p> - * The int levels define a set of standard logging levels that can be used to - * control logging output. The logging levels are ordered and are specified by - * ordered integers. Enabling logging at a given level also enables logging at - * all higher levels. - * <p> - * Clients should use the the convenience methods such as severe() and fine() or - * one of the predefined level constants such as Logger.SEVERE and Logger.FINE - * with the appropriate log(int level...) or trace(int level...) methods. - * <p> - * The levels in descending order are:</p> - * <ul> - * <li>SEVERE (log - highest value)</li> - * <li>WARNING (log)</li> - * <li>INFO (log)</li> - * <li>CONFIG (log)</li> - * <li>FINE (trace)</li> - * <li>FINER (trace)</li> - * <li>FINEST (trace - lowest value)</li> - * </ul> - * - */ -public interface Logger { - /** - * SEVERE is a message level indicating a serious failure. - * <p> - * In general SEVERE messages should describe events that are of - * considerable importance and which will prevent normal program execution. - * They should be reasonably intelligible to end users and to system - * administrators. - */ - public static final int SEVERE = 1; - /** - * WARNING is a message level indicating a potential problem. - * <p> - * In general WARNING messages should describe events that will be of - * interest to end users or system managers, or which indicate potential - * problems. - */ - public static final int WARNING = 2; - /** - * INFO is a message level for informational messages. - * <p> - * Typically INFO messages will be written to the console or its equivalent. - * So the INFO level should only be used for reasonably significant messages - * that will make sense to end users and system admins. - */ - public static final int INFO = 3; - /** - * CONFIG is a message level for static configuration messages. - * <p> - * CONFIG messages are intended to provide a variety of static configuration - * information, to assist in debugging problems that may be associated with - * particular configurations. For example, CONFIG message might include the - * CPU type, the graphics depth, the GUI look-and-feel, etc. - */ - public static final int CONFIG = 4; - /** - * FINE is a message level providing tracing information. - * <p> - * All of FINE, FINER, and FINEST are intended for relatively detailed - * tracing. The exact meaning of the three levels will vary between - * subsystems, but in general, FINEST should be used for the most voluminous - * detailed output, FINER for somewhat less detailed output, and FINE for - * the lowest volume (and most important) messages. - * <p> - * In general the FINE level should be used for information that will be - * broadly interesting to developers who do not have a specialized interest - * in the specific subsystem. - * <p> - * FINE messages might include things like minor (recoverable) failures. - * Issues indicating potential performance problems are also worth logging - * as FINE. - */ - public static final int FINE = 5; - /** - * FINER indicates a fairly detailed tracing message. By default logging - * calls for entering, returning, or throwing an exception are traced at - * this level. - */ - public static final int FINER = 6; - /** - * FINEST indicates a highly detailed tracing message. - */ - public static final int FINEST = 7; - - public void initialise(ResourceBundle messageCatalog, String loggerID, String resourceName); - - /** - * Set a name that can be used to provide context with each log record. - * This overrides the value passed in on initialise - * @param logContext The Log context name - */ - public void setResourceName(String logContext); - - /** - * Check if a message of the given level would actually be logged by this - * logger. This check is based on the Loggers effective level, which may be - * inherited from its parent. - * - * @param level - * a message logging level. - * @return true if the given message level is currently being logged. - */ - public boolean isLoggable(int level); - - /** - * Log a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. - */ - public void severe(String sourceClass, String sourceMethod, String msg); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void severe(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - * @param thrown - * Throwable associated with log message. - */ - public void severe(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown); - - /** - * Log a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. - */ - public void warning(String sourceClass, String sourceMethod, String msg); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void warning(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - * @param thrown - * Throwable associated with log message. - */ - public void warning(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown); - - /** - * Log a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. - */ - public void info(String sourceClass, String sourceMethod, String msg); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void info(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - * @param thrown - * Throwable associated with log message. - */ - public void info(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown); - - /** - * Log a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. - */ - public void config(String sourceClass, String sourceMethod, String msg); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void config(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - * @param thrown - * Throwable associated with log message. - */ - public void config(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown); - - /** - * Trace a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. - */ - public void fine(String sourceClass, String sourceMethod, String msg); - - /** - * Trace a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. The - * formatter uses java.text.MessageFormat style formatting to - * format parameters, so for example a format string "{0} {1}" - * would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void fine(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - public void fine(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex); - - /** - * Trace a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. - */ - public void finer(String sourceClass, String sourceMethod, String msg); - - /** - * Trace a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. The - * formatter uses java.text.MessageFormat style formatting to - * format parameters, so for example a format string "{0} {1}" - * would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void finer(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - public void finer(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex); - - /** - * Trace a message, specifying source class and method, if the logger is - * currently enabled for the given message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. - */ - public void finest(String sourceClass, String sourceMethod, String msg); - - /** - * Trace a message, specifying source class and method, with an array of - * object arguments, if the logger is currently enabled for the given - * message level. - * - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. The - * formatter uses java.text.MessageFormat style formatting to - * format parameters, so for example a format string "{0} {1}" - * would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - */ - public void finest(String sourceClass, String sourceMethod, String msg, Object[] inserts); - - public void finest(String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex); - - /** - * Log a message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param level - * One of the message level identifiers, e.g. SEVERE. - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message, may be null. - * @param thrown - * Throwable associated with log message. - */ - public void log(int level, String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable thrown); - - /** - * Log a trace message, specifying source class and method, with an array of - * object arguments and a throwable, if the logger is currently enabled for - * the given message level. - * - * @param level - * One of the message level identifiers, e.g. SEVERE. - * @param sourceClass - * Name of class that issued the logging request. - * @param sourceMethod - * Name of method that issued the logging request. - * @param msg - * The key in the message catalog for the message or the actual - * message itself. During formatting, if the logger has a mapping - * for the msg string, then the msg string is replaced by the - * value. Otherwise the original msg string is used. The - * formatter uses java.text.MessageFormat style formatting to - * format parameters, so for example a format string "{0} {1}" - * would format two inserts into the message. - * @param inserts - * Array of parameters to the message, may be null. - * @param ex - * Throwable associated with log message. - */ - public void trace(int level, String sourceClass, String sourceMethod, String msg, Object[] inserts, Throwable ex); - - /** - * Format a log message without causing it to be written to the log. - * - * @param msg - * The key in the message localization catalog for the message or - * the actual message itself. During formatting, if the logger - * has a mapping for the msg string, then the msg string is - * replaced by the localized value. Otherwise the original msg - * string is used. The formatter uses java.text.MessageFormat - * style formatting to format parameters, so for example a format - * string "{0} {1}" would format two inserts into the message. - * @param inserts - * Array of parameters to the message. - * @return The formatted message for the current locale. - */ - public String formatMessage(String msg, Object[] inserts); - - public void dumpTrace(); -} \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/LoggerFactory.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/LoggerFactory.java deleted file mode 100644 index 08ececb..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/LoggerFactory.java +++ /dev/null @@ -1,155 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.logging; - -import java.lang.reflect.Method; - -/** - * LoggerFactory will create a logger instance ready for use by the caller. - * - * The default is to create a logger that utilises the Java's built in - * logging facility java.util.logging (JSR47). It is possible to override - * this for systems where JSR47 is not available or an alternative logging - * facility is needed by using setLogger and passing the the class name of - * a logger that implements {@link Logger} - */ -import java.util.MissingResourceException; -import java.util.ResourceBundle; -/** - * A factory that returns a logger for use by the MQTT client. - * - * The default log and trace facility uses Java's build in log facility:- - * java.util.logging. For systems where this is not available or where - * an alternative logging framework is required the logging facility can be - * replaced using {@link org.eclipse.paho.client.mqttv3.logging.LoggerFactory#setLogger(String)} - * which takes an implementation of the {@link org.eclipse.paho.client.mqttv3.logging.Logger} - * interface. - */ -public class LoggerFactory { - /** - * Default message catalog. - */ - public final static String MQTT_CLIENT_MSG_CAT = "org.eclipse.paho.client.mqttv3.internal.nls.logcat"; - private static final String CLASS_NAME = LoggerFactory.class.getName(); - - private static String overrideloggerClassName = null; - /** - * Default logger that uses java.util.logging. - */ - private static String jsr47LoggerClassName = JSR47Logger.class.getName(); - - /** - * Find or create a logger for a named package/class. - * If a logger has already been created with the given name - * it is returned. Otherwise a new logger is created. By default a logger - * that uses java.util.logging will be returned. - * - * @param messageCatalogName the resource bundle containing the logging messages. - * @param loggerID unique name to identify this logger. - * @return a suitable Logger. - */ - public static Logger getLogger(String messageCatalogName, String loggerID) { - String loggerClassName = overrideloggerClassName; - Logger logger = null; - - if (loggerClassName == null) { - loggerClassName = jsr47LoggerClassName; - } -// logger = getJSR47Logger(ResourceBundle.getBundle(messageCatalogName), loggerID, null) ; - logger = getLogger(loggerClassName, ResourceBundle.getBundle(messageCatalogName), loggerID, null) ; -// } - - if (null == logger) { - throw new MissingResourceException("Error locating the logging class", CLASS_NAME, loggerID); - } - - return logger; - } - - - /** - * Return an instance of a logger - * - * @param the class name of the load to load - * @param messageCatalog the resource bundle containing messages - * @param loggerID an identifier for the logger - * @param resourceName a name or context to associate with this logger instance. - * @return a ready for use logger - */ - private static Logger getLogger(String loggerClassName, ResourceBundle messageCatalog, String loggerID, String resourceName) { //, FFDC ffdc) { - Logger logger = null; - Class logClass = null; - - try { - logClass = Class.forName(loggerClassName); - } catch (NoClassDefFoundError ncdfe) { - return null; - } catch (ClassNotFoundException cnfe) { - return null; - } - if (null != logClass) { - // Now instantiate the log - try { - logger = (Logger)logClass.newInstance(); - } catch (IllegalAccessException e) { - return null; - } catch (InstantiationException e) { - return null; - } catch (ExceptionInInitializerError e) { - return null; - } catch (SecurityException e) { - return null; - } - logger.initialise(messageCatalog, loggerID, resourceName); - } - - return logger; - } - - /** - * When run in JSR47, this allows access to the properties in the logging.properties - * file. - * If not run in JSR47, or the property isn't set, returns null. - * @param name the property to return - * @return the property value, or null if it isn't set or JSR47 isn't being used - */ - public static String getLoggingProperty(String name) { - String result = null; - try { - // Hide behind reflection as java.util.logging is guaranteed to be - // available. - Class logManagerClass = Class.forName("java.util.logging.LogManager"); - Method m1 = logManagerClass.getMethod("getLogManager", new Class[]{}); - Object logManagerInstance = m1.invoke(null, null); - Method m2 = logManagerClass.getMethod("getProperty", new Class[]{String.class}); - result = (String)m2.invoke(logManagerInstance,new Object[]{name}); - } catch(Exception e) { - // Any error, assume JSR47 isn't available and return null - result = null; - } - return result; - } - - /** - * Set the class name of the logger that the LoggerFactory will load - * If not set getLogger will attempt to create a logger - * appropriate for the platform. - * @param loggerClassName - Logger implementation class name to use. - */ - public static void setLogger(String loggerClassName) { - LoggerFactory.overrideloggerClassName = loggerClassName; - } -} \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/SimpleLogFormatter.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/SimpleLogFormatter.java deleted file mode 100644 index 63deded..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/SimpleLogFormatter.java +++ /dev/null @@ -1,104 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - */ - -package org.eclipse.paho.client.mqttv3.logging; - -import java.io.PrintWriter; -import java.io.StringWriter; -import java.text.MessageFormat; -import java.util.Date; -import java.util.logging.Formatter; -import java.util.logging.LogRecord; - -/** - * SimpleLogFormatter prints a single line - * log record in human readable form. - */ -public class SimpleLogFormatter extends Formatter { - - private static final String LS = System.getProperty("line.separator"); - /** - * Constructs a <code>SimpleFormatter</code> object. - */ - public SimpleLogFormatter() { - super(); - } - - /** - * Format the logrecord as a single line with well defined columns. - */ - public String format(LogRecord r) { - StringBuffer sb = new StringBuffer(); - sb.append(r.getLevel().getName()).append("\t"); - sb.append(MessageFormat.format("{0, date, yy-MM-dd} {0, time, kk:mm:ss.SSSS} ", - new Object[] { new Date(r.getMillis()) })+"\t"); - String cnm = r.getSourceClassName(); - String cn=""; - if (cnm != null) { - int cnl = cnm.length(); - if (cnl>20) { - cn = r.getSourceClassName().substring(cnl-19); - } else { - char sp[] = {' '}; - StringBuffer sb1= new StringBuffer().append(cnm); - cn = sb1.append(sp,0, 1).toString(); - } - } - sb.append(cn).append("\t").append(" "); - sb.append(left(r.getSourceMethodName(),23,' ')).append("\t"); - sb.append(r.getThreadID()).append("\t"); - sb.append(formatMessage(r)).append(LS); - if (null != r.getThrown()) { - sb.append("Throwable occurred: "); - Throwable t = r.getThrown(); - PrintWriter pw = null; - try { - StringWriter sw = new StringWriter(); - pw = new PrintWriter(sw); - t.printStackTrace(pw); - sb.append(sw.toString()); - } finally { - if (pw != null) { - try { - pw.close(); - } catch (Exception e) { - // ignore - } - } - } - } - return sb.toString(); - } - - /** - * Left justify a string. - * - * @param s the string to justify - * @param width the field width to justify within - * @param fillChar the character to fill with - * - * @return the justified string. - */ - public static String left(String s, int width, char fillChar) { - if (s.length() >= width) { - return s; - } - StringBuffer sb = new StringBuffer(width); - sb.append(s); - for (int i = width - s.length(); --i >= 0;) { - sb.append(fillChar); - } - return sb.toString(); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/jsr47min.properties b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/jsr47min.properties deleted file mode 100644 index 0626551..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/jsr47min.properties +++ /dev/null @@ -1,83 +0,0 @@ -# Properties file which configures the operation of the JDK logging facility. -# -# The configuration in this file is the suggesgted configuration -# for collecting trace for helping debug problems related to the -# Paho MQTT client. It configures trace to be continuosly collected -# in memory with minimal impact on performance. -# -# When the push trigger (by default a Severe level message) or a -# specific request is made to "push" the in memory trace then it -# is "pushed" to the configured target handler. By default -# this is the standard java.util.logging.FileHandler. The Paho Debug -# class can be used to push the memory trace to its target -# -# To enable trace either: -# - use this properties file as is and set the logging facility up -# to use it by configuring the util logging system property e.g. -# -# >java -Djava.util.logging.config.file=<location>\jsr47min.properties -# -# - This contents of this file can also be merged with another -# java.util.logging config file to ensure provide wider logging -# and trace including Paho trace - -# Global logging properties. -# ------------------------------------------ -# The set of handlers to be loaded upon startup. -# Comma-separated list of class names. -# - Root handlers are not enabled by default - just handlers on the Paho packages. -#handlers=java.util.logging.MemoryHandler,java.util.logging.FileHandler, java.util.logging.ConsoleHandler - -# Default global logging level. -# Loggers and Handlers may override this level -#.level=INFO - -# Loggers -# ------------------------------------------ -# A memoryhandler is attached to the paho packages -# and the level specified to collected all trace related -# to paho packages. This will override any root/global -# level handlers if set. -org.eclipse.paho.client.mqttv3.handlers=java.util.logging.MemoryHandler -org.eclipse.paho.client.mqttv3.level=ALL -# It is possible to set more granular trace on a per class basis e.g. -#org.eclipse.paho.client.mqttv3.internal.ClientComms.level=ALL - -# Handlers -# ----------------------------------------- -# Note: the target handler that is associated with the MemoryHandler is not a root handler -# and hence not returned when getting the handlers from root. It appears accessing -# target handler programatically is not possible as target is a private variable in -# class MemoryHandler -java.util.logging.MemoryHandler.level=FINEST -java.util.logging.MemoryHandler.size=10000 -java.util.logging.MemoryHandler.push=SEVERE -java.util.logging.MemoryHandler.target=java.util.logging.FileHandler -#java.util.logging.MemoryHandler.target=java.util.logging.ConsoleHandler - - -# --- FileHandler --- -# Override of global logging level -java.util.logging.FileHandler.level=ALL - -# Naming style for the output file: -# (The output file is placed in the directory -# defined by the "user.home" System property.) -# See java.util.logging for more options -java.util.logging.FileHandler.pattern=%h/paho%u.log - -# Limiting size of output file in bytes: -java.util.logging.FileHandler.limit=200000 - -# Number of output files to cycle through, by appending an -# integer to the base file name: -java.util.logging.FileHandler.count=3 - -# Style of output (Simple or XML): -java.util.logging.FileHandler.formatter=org.eclipse.paho.client.mqttv3.logging.SimpleLogFormatter - -# --- ConsoleHandler --- -# Override of global logging level -#java.util.logging.ConsoleHandler.level=INFO -#java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter -#java.util.logging.ConsoleHandler.formatter=org.eclipse.paho.client.mqttv3.logging.SimpleLogFormatter diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/package.html b/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/package.html deleted file mode 100644 index a679cf1..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/logging/package.html +++ /dev/null @@ -1,18 +0,0 @@ -<body> -Provides facilities to write and format log and trace to help debug problems. - -<p>The default log and trace facility uses Java's build in log facility:- -java.util.logging. For systems where this is not available or where -an alternative logging framework is required the logging facility can be -replaced using {@link org.eclipse.paho.client.mqttv3.logging.LoggerFactory#setLogger(String)} -which takes an implementation of the {@link org.eclipse.paho.client.mqttv3.logging.Logger} -interface. - -<p>A sample java.util.logging properties file - jsr47min.properties is provided that demonstrates -how to run with a memory based trace facility that runs with minimal performance -overhead. The memory buffer can be dumped when a log/trace record is written matching -the MemoryHandlers trigger level or when the push method is invoked on the MemoryHandler. -{@link org.eclipse.paho.client.mqttv3.util.Debug Debug} provides method to make it easy -to dump the memory buffer as well as other useful debug info. - -</body> \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/package.html b/EasyModbus/src/org/eclipse/paho/client/mqttv3/package.html deleted file mode 100644 index 00ca45c..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/package.html +++ /dev/null @@ -1,136 +0,0 @@ -<body> -Contains a programming interface enabling applications to communicate with an MQTT server. - -<p> -The MQ Telemetry Transport (MQTT) is a lightweight broker-based publish/subscribe -messaging protocol designed to be open, simple, lightweight and easy to implement. -These characteristics make it ideal for use in constrained environments, for example, -but not limited to: -<ul> - <li>Where the network is expensive, has low bandwidth or is unreliable such as mobile and vsat networks - <li>When run on an embedded or mobile device with limited processor, memory or battery -</ul> -<p>Features of the protocol include: -<ul> - <li>The publish/subscribe message pattern to provide one-to-many message - distribution and decoupling of applications - <li>A messaging transport that is agnostic to the content of the payload - <li>The use of TCP/IP to provide network connectivity - <li>The use of SSL/TLS to provide network security and trust - <li>Three qualities of service for message delivery which are maintained across - network, client and server breaks. - <ul> - <li>"At most once", where messages are delivered according to the best efforts - of the underlying TCP/IP network. Message loss or duplication can occur. - This level could be used, for example, with ambient sensor data where it - does not matter if an individual reading is lost as the next one will be published soon after. - <li>"At least once", where messages are assured to arrive but duplicates may occur. - <li>"Exactly once", where message are assured to arrive exactly once. This - level could be used, for example, with billing systems where duplicate or - lost messages could lead to incorrect charges being applied. - </ul> - The quality of service for message delivery is met even if the network connection - breaks, or the client or the server stop while a message is being delivered - <li>A small transport overhead (the fixed-length header is just 2 bytes), and - protocol exchanges minimised to reduce network traffic - <li>A mechanism to notify interested parties to an abnormal disconnection of - a client using the Last Will and Testament feature -</ul> - -<p>The basic means of operating the client is:</p> -<ol> - <li>Create an instance of {@link org.eclipse.paho.client.mqttv3.MqttClient} or - {@link org.eclipse.paho.client.mqttv3.MqttAsyncClient}, providing - the address of an MQTT server and a unique client identifier.</li> - <li><code>connect</code> to the server</li> - <li>Exchange messages with the server: - <ul> - <li><code>publish messages</code> to the server - specifying a <code>topic</code> as the destination on the server</li> - <li><code>subscribe</code> to one more <code>topics</code>. The server will send any messages - it receives on those topics to the client. The client will be informed when a message - arrives via a <code>callback</code> - </ul> - <li><code>disconnect</code> from the server.</li> -</ol> - -<p>The programming model and concepts like the protocol are small and easy to use. Key concepts -to use when creating MQTT application include: -<ul> - <li>Every client instance that connects to an MQTT server must have a unique client identifier. - If a second instance of a client with the same ID connects to a server the first instance will be - disconnected. - <li>For message delivery to be reliable and withstand normal and abnormal network breaks together with client - and server outages the client must use a persistent store to hold messages while they are being delivered. This is - the default case where a file based persistent store - {@link org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence MqttDefaultFilePersistence} is used. - <li>When connecting the {@link org.eclipse.paho.client.mqttv3.MqttConnectOptions#setCleanSession(boolean) cleansession} - option has a big impact on the operation of the client. If set to false: - <ul> - <li>Message delivery will match the quality of service specified when the message was published even across - failures of the network, client or server - <li>The server will store messages for active subscriptions on behalf of the client when the client is not connected. - The server will deliver these messages to the client the next time it connects. - </ul> - If set to true: - <ul> - <li>Any state stored on the client and server related to the client will be cleansed - before the connection is fully started. Subscriptions from earlier sessions will be unsubscribed - and any messages still in-flight from previous sessions will be deleted. - <li>When the client disconnects either as the result of the application requesting a disconnect - or a network failure, state related to the client will be cleansed just as at connect time. - <li>Messages will only be delivered to the quality of service requested at publish time if - the connection is maintained while the message is being delivered - </ul> - <li>When subscribing for messages the subscription can be for an absolute topic or a wildcarded topic. - <li>When unsubscribing the topic to be unsubscribed must match one specified on an earlier subscribe. - <li>There are two MQTT client libraries to choose from: - <ol> - <li>{@link org.eclipse.paho.client.mqttv3.IMqttAsyncClient MqttAsyncClient} which provides a non-blocking interface where - methods return before the requested operation has completed. The completion of the operation - can be monitored by in several ways: - <ul> - <li>Use the {@link org.eclipse.paho.client.mqttv3.IMqttToken#waitForCompletion waitForCompletion} - call on the token returned from the operation. This will block - until the operation completes. - <li>Pass a {@link org.eclipse.paho.client.mqttv3.IMqttActionListener IMqttActionListener} - to the operation. The listener will then be called back when the operation completes. - <li>Set a {@link org.eclipse.paho.client.mqttv3.MqttCallback MqttCallback} on the client. It - will be notified when a message arrives, a message have been delivered to the server and when the - connection to the server is lost. - </ul> - <li>{@link org.eclipse.paho.client.mqttv3.IMqttClient MqttClient} where methods block until - the operation has completed. - </ol> - <li>For both the blocking and non-blocking clients some operations are asynchronous. This includes: - <ul> - <li>Notification that a new message has arrived: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#messageArrived messageArrived}. - <li>Notification that the connection to the server has broken: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#connectionLost connectionLost}. - <li>Notification that a message has been delivered to the server: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#deliveryComplete deliveryComplete}. - </ul> - A client registers interest in these notifications by registering a - {@link org.eclipse.paho.client.mqttv3.MqttCallback MqttCallback} on the client - <li>There are a number of programs that demonstrate the different modes of - writing MQTT applications - <ul> - <li>{@link org.eclipse.paho.sample.mqttv3app.Sample} uses the blocking client interface - <li>{@link org.eclipse.paho.sample.mqttv3app.SampleAsyncCallBack} uses the asynchronous client with - callbacks which are notified when an operation completes - <li>{@link org.eclipse.paho.sample.mqttv3app.SampleAsyncWait} uses the asynchronous client and - shows how to use the token returned from each operation to block until the operation completes. - </ul> - <li>{@link org.eclipse.paho.client.mqttv3.MqttConnectOptions MqttConnectOptions} can be used to override the - default connection options. This includes: - <ul> - <li>Setting the cleansession flag - <li>Specifying a list of MQTT servers that the client can attempt to connect to - <li>Set a keepalive interval - <li>Setting the last will and testament - <li>Setting security credentials - </ul> -</ul> - -</body> \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MemoryPersistence.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MemoryPersistence.java deleted file mode 100644 index c684ddf..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MemoryPersistence.java +++ /dev/null @@ -1,93 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.persist; - -import java.util.Enumeration; -import java.util.Hashtable; - -import org.eclipse.paho.client.mqttv3.MqttClientPersistence; -import org.eclipse.paho.client.mqttv3.MqttPersistable; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; - -/** - * Persistence that uses memory - * - * In cases where reliability is not required across client or device - * restarts memory this memory peristence can be used. In cases where - * reliability is required like when clean session is set to false - * then a non-volatile form of persistence should be used. - * - */ -public class MemoryPersistence implements MqttClientPersistence { - - private Hashtable data; - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#close() - */ - public void close() throws MqttPersistenceException { - data.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#keys() - */ - public Enumeration keys() throws MqttPersistenceException { - return data.keys(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#get(java.lang.String) - */ - public MqttPersistable get(String key) throws MqttPersistenceException { - return (MqttPersistable)data.get(key); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#open(java.lang.String, java.lang.String) - */ - public void open(String clientId, String serverURI) throws MqttPersistenceException { - this.data = new Hashtable(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#put(java.lang.String, org.eclipse.paho.client.mqttv3.MqttPersistable) - */ - public void put(String key, MqttPersistable persistable) throws MqttPersistenceException { - data.put(key, persistable); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#remove(java.lang.String) - */ - public void remove(String key) throws MqttPersistenceException { - data.remove(key); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#clear() - */ - public void clear() throws MqttPersistenceException { - data.clear(); - } - - /* (non-Javadoc) - * @see org.eclipse.paho.client.mqttv3.MqttClientPersistence#containsKey(java.lang.String) - */ - public boolean containsKey(String key) throws MqttPersistenceException { - return data.containsKey(key); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MqttDefaultFilePersistence.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MqttDefaultFilePersistence.java deleted file mode 100644 index 19d3d31..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/MqttDefaultFilePersistence.java +++ /dev/null @@ -1,306 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.persist; - -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FilenameFilter; -import java.io.IOException; -import java.util.Enumeration; -import java.util.Vector; - -import org.eclipse.paho.client.mqttv3.MqttClientPersistence; -import org.eclipse.paho.client.mqttv3.MqttPersistable; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; -import org.eclipse.paho.client.mqttv3.internal.FileLock; -import org.eclipse.paho.client.mqttv3.internal.MqttPersistentData; - -/** - * An implementation of the {@link MqttClientPersistence} interface that provides - * file based persistence. - * - * A directory is specified when the Persistence object is created. When the persistence - * is then opened (see {@link #open(String, String)}), a sub-directory is made beneath the base - * for this client ID and connection key. This allows one persistence base directory - * to be shared by multiple clients. - * - * The sub-directory's name is created from a concatenation of the client ID and connection key - * with any instance of '/', '\\', ':' or ' ' removed. - */ -public class MqttDefaultFilePersistence implements MqttClientPersistence { - private static final String MESSAGE_FILE_EXTENSION = ".msg"; - private static final String MESSAGE_BACKUP_FILE_EXTENSION = ".bup"; - private static final String LOCK_FILENAME = ".lck"; - - private File dataDir; - private File clientDir = null; - private FileLock fileLock = null; - - //TODO - private static FilenameFilter FILENAME_FILTER; - - private static FilenameFilter getFilenameFilter(){ - if(FILENAME_FILTER == null){ - FILENAME_FILTER = new PersistanceFileNameFilter(MESSAGE_FILE_EXTENSION); - } - return FILENAME_FILTER; - } - - public MqttDefaultFilePersistence() { //throws MqttPersistenceException { - this(System.getProperty("user.dir")); - } - - /** - * Create an file-based persistent data store within the specified directory. - * @param directory the directory to use. - */ - public MqttDefaultFilePersistence(String directory) { //throws MqttPersistenceException { - dataDir = new File(directory); - } - - public void open(String clientId, String theConnection) throws MqttPersistenceException { - - if (dataDir.exists() && !dataDir.isDirectory()) { - throw new MqttPersistenceException(); - } else if (!dataDir.exists() ) { - if (!dataDir.mkdirs()) { - throw new MqttPersistenceException(); - } - } - if (!dataDir.canWrite()) { - throw new MqttPersistenceException(); - } - - - StringBuffer keyBuffer = new StringBuffer(); - for (int i=0;i<clientId.length();i++) { - char c = clientId.charAt(i); - if (isSafeChar(c)) { - keyBuffer.append(c); - } - } - keyBuffer.append("-"); - for (int i=0;i<theConnection.length();i++) { - char c = theConnection.charAt(i); - if (isSafeChar(c)) { - keyBuffer.append(c); - } - } - - synchronized (this) { - if (clientDir == null) { - String key = keyBuffer.toString(); - clientDir = new File(dataDir, key); - - if (!clientDir.exists()) { - clientDir.mkdir(); - } - } - - try { - fileLock = new FileLock(clientDir, LOCK_FILENAME); - } catch (Exception e) { - // TODO - This shouldn't be here according to the interface - // See https://github.com/eclipse/paho.mqtt.java/issues/178 - //throw new MqttPersistenceException(MqttPersistenceException.REASON_CODE_PERSISTENCE_IN_USE); - } - - // Scan the directory for .backup files. These will - // still exist if the JVM exited during addMessage, before - // the new message was written to disk and the backup removed. - restoreBackups(clientDir); - } - } - - /** - * Checks whether the persistence has been opened. - * @throws MqttPersistenceException if the persistence has not been opened. - */ - private void checkIsOpen() throws MqttPersistenceException { - if (clientDir == null) { - throw new MqttPersistenceException(); - } - } - - public void close() throws MqttPersistenceException { - - synchronized (this) { - // checkIsOpen(); - if (fileLock != null) { - fileLock.release(); - } - - if (getFiles().length == 0) { - clientDir.delete(); - } - clientDir = null; - } - } - - /** - * Writes the specified persistent data to the previously specified persistence directory. - * This method uses a safe overwrite policy to ensure IO errors do not lose messages. - * @param message The {@link MqttPersistable} message to be persisted - * @throws MqttPersistenceException if an exception occurs whilst persisting the message - */ - public void put(String key, MqttPersistable message) throws MqttPersistenceException { - checkIsOpen(); - File file = new File(clientDir, key+MESSAGE_FILE_EXTENSION); - File backupFile = new File(clientDir, key+MESSAGE_FILE_EXTENSION+MESSAGE_BACKUP_FILE_EXTENSION); - - if (file.exists()) { - // Backup the existing file so the overwrite can be rolled-back - boolean result = file.renameTo(backupFile); - if (!result) { - backupFile.delete(); - file.renameTo(backupFile); - } - } - try { - FileOutputStream fos = new FileOutputStream(file); - fos.write(message.getHeaderBytes(), message.getHeaderOffset(), message.getHeaderLength()); - if (message.getPayloadBytes()!=null) { - fos.write(message.getPayloadBytes(), message.getPayloadOffset(), message.getPayloadLength()); - } - fos.getFD().sync(); - fos.close(); - if (backupFile.exists()) { - // The write has completed successfully, delete the backup - backupFile.delete(); - } - } - catch (IOException ex) { - throw new MqttPersistenceException(ex); - } - finally { - if (backupFile.exists()) { - // The write has failed - restore the backup - boolean result = backupFile.renameTo(file); - if (!result) { - file.delete(); - backupFile.renameTo(file); - } - } - } - } - - public MqttPersistable get(String key) throws MqttPersistenceException { - checkIsOpen(); - MqttPersistable result; - try { - File file = new File(clientDir, key+MESSAGE_FILE_EXTENSION); - FileInputStream fis = new FileInputStream(file); - int size = fis.available(); - byte[] data = new byte[size]; - int read = 0; - while (read<size) { - read += fis.read(data,read,size-read); - } - fis.close(); - result = new MqttPersistentData(key, data, 0, data.length, null, 0, 0); - } - catch(IOException ex) { - throw new MqttPersistenceException(ex); - } - return result; - } - - - /** - * Deletes the data with the specified key from the previously specified persistence directory. - */ - public void remove(String key) throws MqttPersistenceException { - checkIsOpen(); - File file = new File(clientDir, key+MESSAGE_FILE_EXTENSION); - if (file.exists()) { - file.delete(); - } - } - - /** - * Returns all of the persistent data from the previously specified persistence directory. - * @return all of the persistent data from the persistence directory. - * @throws MqttPersistenceException if an exception is thrown whilst getting the keys - */ - public Enumeration keys() throws MqttPersistenceException { - checkIsOpen(); - File[] files = getFiles(); - Vector result = new Vector(files.length); - for (int i=0;i<files.length;i++) { - String filename = files[i].getName(); - String key = filename.substring(0,filename.length()-MESSAGE_FILE_EXTENSION.length()); - result.addElement(key); - } - return result.elements(); - } - - private File[] getFiles() throws MqttPersistenceException { - checkIsOpen(); - File[] files = clientDir.listFiles(getFilenameFilter()); - if (files == null) { - throw new MqttPersistenceException(); - } - return files; - } - - private boolean isSafeChar(char c) { - return Character.isJavaIdentifierPart(c) || c=='-'; - } - - /** - * Identifies any backup files in the specified directory and restores them - * to their original file. This will overwrite any existing file of the same - * name. This is safe as a stray backup file will only exist if a problem - * occured whilst writing to the original file. - * @param dir The directory in which to scan and restore backups - */ - private void restoreBackups(File dir) throws MqttPersistenceException { -//SRES -// File[] files = dir.listFiles(new PersistanceFileFilter(MESSAGE_BACKUP_FILE_EXTENSION)); - -// if (files == null) { -// throw new MqttPersistenceException(); -// } - -// for (int i=0;i<files.length;i++) { -// File originalFile = new File(dir,files[i].getName().substring(0,files[i].getName().length()-MESSAGE_BACKUP_FILE_EXTENSION.length())); -// boolean result = files[i].renameTo(originalFile); -// if (!result) { -// originalFile.delete(); -// files[i].renameTo(originalFile); -// } -// } - } - - public boolean containsKey(String key) throws MqttPersistenceException { - checkIsOpen(); - File file = new File(clientDir, key+MESSAGE_FILE_EXTENSION); - return file.exists(); - } - - public void clear() throws MqttPersistenceException { - -//SRES -// checkIsOpen(); -// File[] files = getFiles(); -// for (int i=0; i<files.length; i++) { -// files[i].delete(); -// } -// clientDir.delete(); - } -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileFilter.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileFilter.java deleted file mode 100644 index a909b0a..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileFilter.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.eclipse.paho.client.mqttv3.persist; - -import java.io.File; -import java.io.FileFilter; - -public class PersistanceFileFilter implements FileFilter{ - - private final String fileExtension; - - public PersistanceFileFilter(String fileExtension){ - this.fileExtension = fileExtension; - } - - public boolean accept(File pathname) { - return pathname.getName().endsWith(fileExtension); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileNameFilter.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileNameFilter.java deleted file mode 100644 index 9d35a43..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/PersistanceFileNameFilter.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.eclipse.paho.client.mqttv3.persist; - -import java.io.File; -import java.io.FilenameFilter; - -public class PersistanceFileNameFilter implements FilenameFilter{ - - private final String fileExtension; - - public PersistanceFileNameFilter(String fileExtension){ - this.fileExtension = fileExtension; - } - - public boolean accept(File dir, String name) { - return name.endsWith(fileExtension); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/package.html b/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/package.html deleted file mode 100644 index dd20b5e..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/persist/package.html +++ /dev/null @@ -1,12 +0,0 @@ -<body> -Contains implementations of the MqttClientPersistence interface. - -<p> -An MQTT client needs a persistence mechanism to store messages while they -are in the process of being delivered. This package contains several -implementations of the interface. If a persistence class is not -specified on the constructor to an MQTT client, -{@link org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence MqttDefaultFilePersistence} -is used by default. - -</body> \ No newline at end of file diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Debug.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Debug.java deleted file mode 100644 index 7958182..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Debug.java +++ /dev/null @@ -1,183 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2009, 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Dave Locke - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.util; - -import java.util.Enumeration; -import java.util.Properties; - -import org.eclipse.paho.client.mqttv3.internal.ClientComms; -import org.eclipse.paho.client.mqttv3.logging.Logger; -import org.eclipse.paho.client.mqttv3.logging.LoggerFactory; - -/** - * Utility to help debug problems with the Paho MQTT client - * Once initialised a call to dumpClientDebug will force any memory trace - * together with pertinent client and system state to the main log facility. - * - * No client wide lock is taken when the dump is progress. This means the - * set of client state may not be consistent as the client can still be - * processing work while the dump is in progress. - */ -public class Debug { - - private static final String CLASS_NAME = ClientComms.class.getName(); - private static final Logger log = LoggerFactory.getLogger(LoggerFactory.MQTT_CLIENT_MSG_CAT,CLASS_NAME); - private static final String separator = "=============="; - private static final String lineSep = System.getProperty("line.separator","\n"); - - private String clientID; - private ClientComms comms; - - /** - * Set the debug facility up for a specific client - * @param clientID the ID of the client being debugged - * @param comms the ClientComms object of the client being debugged - */ - public Debug(String clientID, ClientComms comms) { - this.clientID = clientID; - this.comms = comms; - log.setResourceName(clientID); - } - - /** - * Dump maximum debug info. - * This includes state specific to a client as well - * as debug that is JVM wide like trace and system properties. - * All state is written as debug log entries. - */ - public void dumpClientDebug() { - dumpClientComms(); - dumpConOptions(); - dumpClientState(); - dumpBaseDebug(); - } - - /** - * Dump of JVM wide debug info. - * This includes trace and system properties. - * Includes trace and system properties - */ - public void dumpBaseDebug() { - dumpVersion(); - dumpSystemProperties(); - dumpMemoryTrace(); - } - - /** - * If memory trace is being used a request is made to push it - * to the target handler. - */ - protected void dumpMemoryTrace() { - log.dumpTrace(); - } - - /** - * Dump information that show the version of the MQTT client being used. - */ - protected void dumpVersion() { - StringBuffer vInfo = new StringBuffer(); - vInfo.append(lineSep+separator+" Version Info "+ separator+lineSep); - vInfo.append(left("Version",20,' ') + ": "+ ClientComms.VERSION + lineSep); - vInfo.append(left("Build Level",20,' ') + ": "+ ClientComms.BUILD_LEVEL + lineSep); - vInfo.append(separator+separator+separator+lineSep); - log.fine(CLASS_NAME,"dumpVersion", vInfo.toString()); - } - - /** - * Dump the current set of system.properties to a log record - */ - public void dumpSystemProperties() { - - Properties sysProps = System.getProperties(); - log.fine(CLASS_NAME,"dumpSystemProperties", dumpProperties(sysProps, "SystemProperties").toString()); - } - - /** - * Dump interesting variables from ClientState - */ - public void dumpClientState() { - Properties props = null; - if (comms != null && comms.getClientState() != null ) { - props = comms.getClientState().getDebug(); - log.fine(CLASS_NAME,"dumpClientState", dumpProperties(props, clientID + " : ClientState").toString()); - } - } - - /** - * Dump interesting variables from ClientComms - */ - public void dumpClientComms() { - Properties props = null; - if (comms != null) { - props = comms.getDebug(); - log.fine(CLASS_NAME,"dumpClientComms", dumpProperties(props, clientID + " : ClientComms").toString()); - } - } - - /** - * Dump Connection options - */ - public void dumpConOptions() { - Properties props = null; - if (comms != null) { - props = comms.getConOptions().getDebug(); - log.fine(CLASS_NAME,"dumpConOptions", dumpProperties(props, clientID + " : Connect Options").toString()); - } - } - - - /** - * Return a set of properties as a formatted string - * @param props The Dump Properties - * @param name The associated name - * @return a set of properties as a formatted string - */ - public static String dumpProperties(Properties props, String name) { - - StringBuffer propStr = new StringBuffer(); - Enumeration propsE = props.propertyNames(); - propStr.append(lineSep+separator+" "+name+" "+ separator+lineSep); - while (propsE.hasMoreElements()) { - String key = (String)propsE.nextElement(); - propStr.append(left(key,28,' ') + ": "+ props.get(key)+lineSep); - } - propStr.append(separator+separator+separator+lineSep); - - return propStr.toString(); - } - - /** - * Left justify a string. - * - * @param s the string to justify - * @param width the field width to justify within - * @param fillChar the character to fill with - * - * @return the justified string. - */ - public static String left(String s, int width, char fillChar) { - if (s.length() >= width) { - return s; - } - StringBuffer sb = new StringBuffer(width); - sb.append(s); - for (int i = width - s.length(); --i >= 0;) { - sb.append(fillChar); - } - return sb.toString(); - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Strings.java b/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Strings.java deleted file mode 100644 index 40b31a5..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/Strings.java +++ /dev/null @@ -1,173 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 IBM Corp. - * - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * and Eclipse Distribution License v1.0 which accompany this distribution. - * - * The Eclipse Public License is available at - * http://www.eclipse.org/legal/epl-v10.html - * and the Eclipse Distribution License is available at - * http://www.eclipse.org/org/documents/edl-v10.php. - * - * Contributors: - * Bin Zhang - initial API and implementation and/or initial documentation - */ -package org.eclipse.paho.client.mqttv3.util; - -/** - * String helper - */ -public final class Strings { - // Represents a failed index search. - private static final int INDEX_NOT_FOUND = -1; - - /** - * Checks if the CharSequence equals any character in the given set of characters. - * - * @param cs the CharSequence to check - * @param strs the set of characters to check against - * @return true if equals any - */ - public static boolean equalsAny(CharSequence cs, CharSequence[] strs) { - boolean eq = false; - if (cs == null) { - eq = strs == null; - } - - if (strs != null) { - for (int i = 0; i < strs.length; i++) { - eq = eq || strs[i].equals(cs); - } - } - - return eq; - } - - /** - * Checks if the CharSequence contains any character in the given set of characters. - * - * @param cs the CharSequence to check, may be null - * @param searchChars the chars to search for, may be null - * @return the {@code true} if any of the chars are found, {@code false} if no match or null input - */ - public static boolean containsAny(CharSequence cs, CharSequence searchChars) { - if (searchChars == null) { - return false; - } - return containsAny(cs, toCharArray(searchChars)); - } - - /** - * Checks if the CharSequence contains any character in the given set of characters. - * - * @param cs the CharSequence to check, may be null - * @param searchChars the chars to search for, may be null - * @return the {@code true} if any of the chars are found, {@code false} if no match or null input - */ - public static boolean containsAny(CharSequence cs, char[] searchChars) { - if (isEmpty(cs) || isEmpty(searchChars)) { - return false; - } - int csLength = cs.length(); - int searchLength = searchChars.length; - int csLast = csLength - 1; - int searchLast = searchLength - 1; - for (int i = 0; i < csLength; i++) { - char ch = cs.charAt(i); - for (int j = 0; j < searchLength; j++) { - if (searchChars[j] == ch) { - if (Character.isHighSurrogate(ch)) { - if (j == searchLast) { - // missing low surrogate, fine, like String.indexOf(String) - return true; - } - if (i < csLast && searchChars[j + 1] == cs.charAt(i + 1)) { - return true; - } - } - else { - // ch is in the Basic Multilingual Plane - return true; - } - } - } - } - return false; - } - - - /** - * Checks if a CharSequence is empty ("") or null. - * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is empty or null - */ - public static boolean isEmpty(CharSequence cs) { - return cs == null || cs.length() == 0; - } - - /** - * @param array - */ - private static boolean isEmpty(char[] array) { - return array == null || array.length == 0; - } - - /** - * Green implementation of toCharArray. - * - * @param cs the {@code CharSequence} to be processed - * @return the resulting char array - */ - private static char[] toCharArray(CharSequence cs) { - if (cs instanceof String) { - return ((String) cs).toCharArray(); - } - else { - int sz = cs.length(); - char[] array = new char[cs.length()]; - for (int i = 0; i < sz; i++) { - array[i] = cs.charAt(i); - } - return array; - } - } - - /** - * Counts how many times the substring appears in the larger string. - * - * @param str the CharSequence to check, may be null - * @param sub the substring to count, may be null - * @return the number of occurrences, 0 if either CharSequence is {@code null} - */ - public static int countMatches(CharSequence str, CharSequence sub) { - if (isEmpty(str) || isEmpty(sub)) { - return 0; - } - int count = 0; - int idx = 0; - while ((idx = indexOf(str, sub, idx)) != INDEX_NOT_FOUND) { - count++; - idx += sub.length(); - } - return count; - } - - /** - * Used by the indexOf(CharSequence methods) as a green implementation of indexOf. - * - * @param cs the {@code CharSequence} to be processed - * @param searchChar the {@code CharSequence} to be searched for - * @param start the start index - * @return the index where the search sequence was found - */ - private static int indexOf(CharSequence cs, CharSequence searchChar, int start) { - return cs.toString().indexOf(searchChar.toString(), start); - } - - private Strings() { - // prevented from constructing objects - } - -} diff --git a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/package.html b/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/package.html deleted file mode 100644 index 19c41d8..0000000 --- a/EasyModbus/src/org/eclipse/paho/client/mqttv3/util/package.html +++ /dev/null @@ -1,5 +0,0 @@ -<body> -Provides helpers and utilities. - - -</body> \ No newline at end of file