diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fa54c57 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +/doc/ +/EasyModbus/ +/nbproject/ +/manifest.mf +target +*.iml +.idea diff --git a/EasyModbus/EasyModbus/src/ModbusRTU/ModbusRTU.java b/EasyModbus/EasyModbus/src/ModbusRTU/ModbusRTU.java index 8f3d27a..4de43c0 100644 --- a/EasyModbus/EasyModbus/src/ModbusRTU/ModbusRTU.java +++ b/EasyModbus/EasyModbus/src/ModbusRTU/ModbusRTU.java @@ -2,14 +2,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package ModbusRTU; import java.io.IOException; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java index 4c009ad..f9212e0 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java @@ -2,14 +2,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.modbusclient; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java index 0f4dfb5..b69d0bf 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.modbusclient; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java index c3d062f..0d933f1 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.modbusclient; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java index a6200b3..e0d644a 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java @@ -6,14 +6,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.modbusclient.gui; @@ -28,7 +28,7 @@ import java.awt.event.ItemEvent; /** * - * @author Stefan Roßmann + * @author Stefan Roßmann */ @SuppressWarnings("serial") public class EasyModbusTCPClientExampleGUI extends javax.swing.JFrame diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java index 4ec59bf..241ecf5 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java @@ -2,14 +2,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.modbusclient.gui; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java index 5a36398..2e38758 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java @@ -4,14 +4,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.modbusclient.gui; @@ -26,7 +26,7 @@ import java.awt.event.ItemEvent; /** * - * @author Stefan Roßmann + * @author Stefan Roßmann */ @SuppressWarnings("serial") public class EasyModbusTcpClient extends javax.swing.JFrame diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ClientConnectionThread.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ClientConnectionThread.java index 59eb81d..9e2e446 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ClientConnectionThread.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ClientConnectionThread.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ICoilsChangedDelegator.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ICoilsChangedDelegator.java index a293564..dc5235e 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ICoilsChangedDelegator.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ICoilsChangedDelegator.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/IHoldingRegistersChangedDelegator.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/IHoldingRegistersChangedDelegator.java index 6f0c2bf..0dff03e 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/IHoldingRegistersChangedDelegator.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/IHoldingRegistersChangedDelegator.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ILogDataChangedDelegator.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ILogDataChangedDelegator.java index 34b5262..5e810a6 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ILogDataChangedDelegator.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ILogDataChangedDelegator.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/INumberOfConnectedClientsChangedDelegator.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/INumberOfConnectedClientsChangedDelegator.java index 362b23e..ea7afe3 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/INumberOfConnectedClientsChangedDelegator.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/INumberOfConnectedClientsChangedDelegator.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ListenerThread.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ListenerThread.java index bdcc79c..379a105 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ListenerThread.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ListenerThread.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusProtocoll.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusProtocoll.java index b8638e1..3e4e5ba 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusProtocoll.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusProtocoll.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusServer.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusServer.java index d9740eb..89876c5 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusServer.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ModbusServer.java @@ -2,14 +2,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.server; diff --git a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ProcessReceivedDataThread.java b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ProcessReceivedDataThread.java index 0071894..c67e60a 100644 --- a/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ProcessReceivedDataThread.java +++ b/EasyModbus/EasyModbus/src/de/re/easymodbus/server/ProcessReceivedDataThread.java @@ -3,14 +3,14 @@ * Creative Commons license: Attribution-NoDerivatives 4.0 International (CC BY-ND 4.0) * You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *for any purpose, even commercially. *The licensor cannot revoke these freedoms as long as you follow the license terms. *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. - *No additional restrictions — You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. + *No additional restrictions - You may not apply legal terms or technological measures that legally restrict others from doing anything the license permits. */ package de.re.easymodbus.server; diff --git a/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.html b/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.html index dd71bfa..475467c 100644 --- a/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.html +++ b/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.html @@ -143,7 +143,7 @@

Class EasyModbusTC implements ReceiveDataChangedListener, SendDataChangedListener
Author:
-
Stefan Roßmann
+
Stefan Roßmann
See Also:
Serialized Form
diff --git a/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.html b/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.html index 7ca1bd4..d93f40a 100644 --- a/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.html +++ b/EasyModbus/doc/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.html @@ -143,7 +143,7 @@

Class EasyModbusTcpClientReceiveDataChangedListener, SendDataChangedListener
Author:
-
Stefan Roßmann
+
Stefan Roßmann
See Also:
Serialized Form
diff --git a/EasyModbus/src/ModbusRTU/ModbusRTU.java b/EasyModbus/src/ModbusRTU/ModbusRTU.java deleted file mode 100644 index 91c651d..0000000 --- a/EasyModbus/src/ModbusRTU/ModbusRTU.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * (c) Stefan Roßmann - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . -*/ -package ModbusRTU; -import java.io.IOException; - -import org.eclipse.paho.client.mqttv3.MqttException; -import org.eclipse.paho.client.mqttv3.MqttPersistenceException; - -import de.re.easymodbus.exceptions.ModbusException; -import de.re.easymodbus.modbusclient.ModbusClient; -import jssc.SerialPortException; -import jssc.SerialPortTimeoutException; - -/** - * - * @author SR555 - */ -public class ModbusRTU -{ - public static void main(String args[]) throws IOException, SerialPortException, ModbusException, SerialPortTimeoutException, MqttPersistenceException, MqttException, InterruptedException - { - boolean success = false; - ModbusClient modbusClient = new ModbusClient("127.0.0.1",502); - System.out.println(modbusClient.Available(500)); - modbusClient.Connect(); - while (true) - { - System.out.println(modbusClient.ReadInputRegisters(0, 10)[5]); - //Thread.sleep(200); - } - //modbusClient.WriteMultipleCoils(0, new boolean[] {true,true,true}); - //modbusClient.Disconnect(); - /* - while (success == false) - { - try - { - modbusClient.Connect("127.0.0.1",502); - boolean[] response = modbusClient.ReadCoils(2, 20); - int[] responseint = modbusClient.ReadHoldingRegisters(0, 20); - modbusClient.WriteSingleCoil(0, true); - modbusClient.WriteSingleRegister(200, 456); - modbusClient.WriteMultipleCoils(200, new boolean[]{true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true,true}); - modbusClient.WriteMultipleRegisters(300, new int[]{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}); - for (int i = 0; i < response.length; i++) - { - System.out.println(response[i]); - System.out.println(responseint[i]); - } - success = true; - Thread.sleep(1000); - } - catch (Exception e) - { - e.printStackTrace(); - } - finally - { - modbusClient.Disconnect(); - } - - } - */ - } -} 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 DisconnectedBufferOptions object using the - * default values. - * - * The defaults are: - * - * 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. - * - *

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. - *

- */ -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. - *

- * It provides applications a simple programming interface to all features of the MQTT version 3.1 - * specification including: - *

- * - *

- * There are two styles of MQTT client, this one and {@link IMqttClient}.

- * - *

- * 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}

- * - *

There are two forms of non-blocking method: - *

    - *
  1. - *
    - *     IMqttToken token = asyncClient.method(parms)
    - *     
    - *

    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:

    - *
    - *      IMqttToken conToken;
    - *   	conToken = asyncClient.client.connect(conToken);
    - *     ... do some work...
    - *   	conToken.waitForCompletion();
    - *     
    - *

    To turn a method into a blocking invocation the following form can be used:

    - *
    - *     IMqttToken token;
    - *     token = asyncClient.method(parms).waitForCompletion();
    - *     
    - *
  2. - * - *
  3. - *
    - *     IMqttToken token method(parms, Object userContext, IMqttActionListener callback)
    - *     
    - *

    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:

    - *
    - *     	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);
    - *			}
    - *		  });
    - *      
    - *

    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. - *

    - *
  4. - *
- *

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.

- * - */ -public interface IMqttAsyncClient { - /** - * Connects to an MQTT server using the default options. - *

The default options are specified in {@link MqttConnectOptions} class. - *

- * - * @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. - *

The connection will be established using the options specified in the - * {@link MqttConnectOptions} parameter. - *

- * - * @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. - *

The default options are specified in {@link MqttConnectOptions} class. - *

- * - * @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. - *

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. - *

- *

The method returns control before the connect completes. Completion can - * be tracked by: - *

- * - * - * @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. - *

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. - *

- * - * @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. - *

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. - *

- * @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. - *

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. - *

- * - * @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. - *

- * 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.

- *

This method must not be called from inside {@link MqttCallback} methods.

- *

The method returns control before the disconnect completes. Completion can - * be tracked by: - *

- * - * - * @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. - *

- * 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. - *

- * 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. - *

- * 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 true if connected, false otherwise. - */ - public boolean isConnected(); - - /** - * Returns the client ID used by this client. - *

All clients connected to the - * same server or server farm must have a unique ID. - *

- * - * @return the client ID used by this client. - */ - public String getClientId(); - - /** - * Returns the address of the server used by this client. - *

The format of the returned String is the same as that used on the constructor. - *

- * - * @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. - *

A convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. - *

- * - * @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. - *

A convenience method, which will - * create a new {@link MqttMessage} object with a byte array payload and the - * specified QoS, and then publish it. - *

- * - * @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. - *

- * 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: - *

- * - * - *

When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:

- * - * - * - *

The following principles apply to the construction and content of a topic - * tree:

- * - * - *

The method returns control before the publish completes. Completion can - * be tracked by: - *

- * - * - * @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. - * - *

Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.

- * - * @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. - *

Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.

- *

The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - *

- *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:

- * - * - * - *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when connecting to the server then the subscription remains in place - * until either:

- * - *

- * 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 same client ID the server will - * deliver the stored messages to the client. - *

- * - *

The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.

- *

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. - *

- *
Topic level separator
- *
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.
- * - *
Multi-level wildcard
- *

The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * finance/stock/ibm/#, you receive - * messages on these topics:

- *
    - *
  • finance/stock/ibm
  • - *
  • finance/stock/ibm/closingprice
  • - *
  • finance/stock/ibm/currentprice
  • - *
- *

The multi-level wildcard - * can represent zero or more levels. Therefore, finance/# can also match - * the singular finance, where # represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.

- * - *

The multi-level wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, # and finance/# are both valid, but finance# is - * not valid. The multi-level wildcard must be the last character - * used within the topic tree. For example, finance/# is valid but - * finance/#/closingprice is not valid.

- * - *
Single-level wildcard
- *

The plus sign (+) is a wildcard character that matches only one topic - * level. For example, finance/stock/+ matches - * finance/stock/ibm and finance/stock/xyz, - * but not finance/stock/ibm/closingprice. Also, because the single-level - * wildcard matches only a single level, finance/+ does not match finance.

- * - *

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, - * + and finance/+ are both valid, but finance+ is - * not valid. The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, finance/+ and finance/+/ibm are both valid.

- *
- *
- *

The method returns control before the subscribe completes. Completion can - * be tracked by:

- * - * - * @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. - * - *

Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.

- * - * @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. - * - *

Provides an optimized way to subscribe to multiple topics compared to - * subscribing to each one individually.

- * - * @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. - *

- * 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. - *

- *

The topic(s) specified on the unsubscribe must match the topic(s) - * specified in the original subscribe request for the unsubscribe to succeed - *

- *

The method returns control before the unsubscribe completes. Completion can - * be tracked by: - *

- * - * - * - * @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. - *

There are a number of events that the listener will be notified about. - * These include: - *

- * - *

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.

- * @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. - *

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. - *

- *

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

- * @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. - *

- * This interface allows applications to utilize all features of the MQTT version 3.1 - * specification including:

- * - *

- * There are two styles of MQTT client, this one and {@link IMqttAsyncClient}.

- * - *

- * 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:

- *
- *     IMqttToken token;
- *     token = asyncClient.method(parms).waitForCompletion();
- *     
- *

- * 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.

- */ -public interface IMqttClient { //extends IMqttAsyncClient { - /** - * Connects to an MQTT server using the default options. - *

The default options are specified in {@link MqttConnectOptions} class. - *

- * - * @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. - *

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. - *

- *

This is a blocking method that returns once connect completes

- * - * @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. - *

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. - *

- *

This is a blocking method that returns once connect completes

- * - * @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. - *

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. - *

- * - *

This is a blocking method that returns once disconnect completes

- * - * @throws MqttException if a problem is encountered while disconnecting - */ - public void disconnect() throws MqttException; - - /** - * Disconnects from the server. - *

- * 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.

- * - *

This is a blocking method that returns once disconnect completes

- * - * @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. - *

- * 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. - *

- * 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. - *

- * 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. - *

The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - *

- *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either: - *

- * - *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * 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 same client ID the server will - * deliver the stored messages to the client. - *

- * - *

The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.

- *

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. - *

- *
Topic level separator
- *
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.
- * - *
Multi-level wildcard
- *

The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * finance/stock/ibm/#, you receive - * messages on these topics:

- *
    - *
  • finance/stock/ibm
  • - *
  • finance/stock/ibm/closingprice
  • - *
  • finance/stock/ibm/currentprice
  • - *
- * - *

The multi-level wildcard - * can represent zero or more levels. Therefore, finance/# can also match - * the singular finance, where # represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.

- * - *

The multi-level wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, # and finance/# are both valid, but finance# is - * not valid. The multi-level wildcard must be the last character - * used within the topic tree. For example, finance/# is valid but - * finance/#/closingprice is not valid.

- * - *
Single-level wildcard
- *

The plus sign (+) is a wildcard character that matches only one topic - * level. For example, finance/stock/+ matches - * finance/stock/ibm and finance/stock/xyz, - * but not finance/stock/ibm/closingprice. Also, because the single-level - * wildcard matches only a single level, finance/+ does not match finance.

- * - *

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, - * + and finance/+ are both valid, but finance+ is - * not valid. The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, finance/+ and finance/+/ibm are both valid.

- *
- *
- * - *

This is a blocking method that returns once subscribe completes

- * - * @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. - *

The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - *

- *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * 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 same client ID the server will - * deliver the stored messages to the client. - *

- * - *

The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.

- *

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. - *

- *
Topic level separator
- *
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.
- * - *
Multi-level wildcard
- *

The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * finance/stock/ibm/#, you receive - * messages on these topics:

- *
    - *
  • finance/stock/ibm
  • - *
  • finance/stock/ibm/closingprice
  • - *
  • finance/stock/ibm/currentprice
  • - *
- *

The multi-level wildcard - * can represent zero or more levels. Therefore, finance/# can also match - * the singular finance, where # represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.

- * - *

The multi-level wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, # and finance/# are both valid, but finance# is - * not valid. The multi-level wildcard must be the last character - * used within the topic tree. For example, finance/# is valid but - * finance/#/closingprice is not valid.

- * - *
Single-level wildcard
- *

The plus sign (+) is a wildcard character that matches only one topic - * level. For example, finance/stock/+ matches - * finance/stock/ibm and finance/stock/xyz, - * but not finance/stock/ibm/closingprice. Also, because the single-level - * wildcard matches only a single level, finance/+ does not match finance.

- * - *

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, - * + and finance/+ are both valid, but finance+ is - * not valid. The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, finance/+ and finance/+/ibm are both valid.

- *
- *
- * - *

This is a blocking method that returns once subscribe completes

- * - * @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. - *

The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - *

- *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * 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 same client ID the server will - * deliver the stored messages to the client. - *

- * - *

The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.

- *

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. - *

- *
Topic level separator
- *
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.
- * - *
Multi-level wildcard
- *

The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * finance/stock/ibm/#, you receive - * messages on these topics:

- *
    - *
  • finance/stock/ibm
  • - *
  • finance/stock/ibm/closingprice
  • - *
  • finance/stock/ibm/currentprice
  • - *
- *

The multi-level wildcard - * can represent zero or more levels. Therefore, finance/# can also match - * the singular finance, where # represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.

- * - *

The multi-level wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, # and finance/# are both valid, but finance# is - * not valid. The multi-level wildcard must be the last character - * used within the topic tree. For example, finance/# is valid but - * finance/#/closingprice is not valid.

- * - *
Single-level wildcard
- *

The plus sign (+) is a wildcard character that matches only one topic - * level. For example, finance/stock/+ matches - * finance/stock/ibm and finance/stock/xyz, - * but not finance/stock/ibm/closingprice. Also, because the single-level - * wildcard matches only a single level, finance/+ does not match finance.

- * - *

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, - * + and finance/+ are both valid, but finance+ is - * not valid. The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, finance/+ and finance/+/ibm are both valid.

- *
- *
- * - *

This is a blocking method that returns once subscribe completes

- * - * @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. - *

The {@link #setCallback(MqttCallback)} method - * should be called before this method, otherwise any received messages - * will be discarded. - *

- *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to true - * when when connecting to the server then the subscription remains in place - * until either:

- * - * - *

- * If (@link MqttConnectOptions#setCleanSession(boolean)} was set to false - * when when connecting to the server then the subscription remains in place - * until either:

- * - *

- * 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 same client ID the server will - * deliver the stored messages to the client. - *

- * - *

The "topic filter" string used when subscribing - * may contain special characters, which allow you to subscribe to multiple topics - * at once.

- *

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. - *

- *
Topic level separator
- *
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.
- * - *
Multi-level wildcard
- *

The number sign (#) is a wildcard character that matches - * any number of levels within a topic. For example, if you subscribe to - * finance/stock/ibm/#, you receive - * messages on these topics:

- *
    - *
  • finance/stock/ibm
  • - *
  • finance/stock/ibm/closingprice
  • - *
  • finance/stock/ibm/currentprice
  • - *
- *

The multi-level wildcard - * can represent zero or more levels. Therefore, finance/# can also match - * the singular finance, where # represents zero levels. The topic - * level separator is meaningless in this context, because there are no levels - * to separate.

- * - *

The multi-level wildcard can - * be specified only on its own or next to the topic level separator character. - * Therefore, # and finance/# are both valid, but finance# is - * not valid. The multi-level wildcard must be the last character - * used within the topic tree. For example, finance/# is valid but - * finance/#/closingprice is not valid.

- * - *
Single-level wildcard
- *

The plus sign (+) is a wildcard character that matches only one topic - * level. For example, finance/stock/+ matches - * finance/stock/ibm and finance/stock/xyz, - * but not finance/stock/ibm/closingprice. Also, because the single-level - * wildcard matches only a single level, finance/+ does not match finance.

- * - *

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, - * + and finance/+ are both valid, but finance+ is - * not valid. The single-level wildcard can be used at the end of the - * topic tree or within the topic tree. - * For example, finance/+ and finance/+/ibm are both valid.

- *
- *
- - * - *

This is a blocking method that returns once subscribe completes

- * - * @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. - *

- * 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. - *

- *

The topic(s) specified on the unsubscribe must match the topic(s) - * specified in the original subscribe request for the subscribe to succeed - *

- * - *

This is a blocking method that returns once unsubscribe completes

- * - * @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. - *

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 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. - *

- * 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:

- * - *

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:

- * - * - *

When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:

- * - * - * - *

The following principles apply to the construction and content of a topic - * tree:

- * - * - * - * - *

This is a blocking method that returns once publish completes

* - * - * @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. - *

There are a number of events that listener will be notified about. These include:

- * - *

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

- * @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. - *

An alternative method that should be used in preference to this one when publishing a message is:

- * - *

When building an application, - * the design of the topic tree should take into account the following principles - * of topic name syntax and semantics:

- * - * - * - *

The following principles apply to the construction and content of a topic - * tree:

- * - * - * - * @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 true if connected, false otherwise. - */ - public boolean isConnected(); - - /** - * Returns the client ID used by this client. - *

All clients connected to the - * same server or server farm must have a unique ID. - *

- * - * @return the client ID used by this client. - */ - public String getClientId(); - - /** - * Returns the address of the server used by this client, as a URI. - *

The format is the same as specified on the constructor. - *

- * - * @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. - *

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. - *

- *

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

- * @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. - * - *

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 - *

- *

- * An action is in progress until either:

- * - * - */ - -public interface IMqttDeliveryToken extends IMqttToken { - /** - * Returns the message associated with this token. - *

Until the message has been delivered, the message being delivered will - * be returned. Once the message has been delivered null 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. - * - *

- * This method is invoked synchronously by the MQTT client. An - * acknowledgment is not sent back to the server until this - * method returns cleanly.

- *

- * If an implementation of this method throws an Exception, 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.

- *

- * 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.

- *

- * 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.

- *

- * 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.

- * - * @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. - * - *

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.

- *

- * An action is in progress until either:

- * - * - */ -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. - *

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.

- *

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. - *

- * - * @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. - *

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. - *

- * @return whether or not the action has finished. - */ - public boolean isComplete(); - - /** - * Returns an exception providing more detail if an operation failed. - *

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 - *

- * @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. - *

Once a listener is registered it will be invoked when the action the token - * is associated with either succeeds or fails. - *

- * @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. - *

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

- * @param userContext to associate with an action - */ - public void setUserContext(Object userContext); - - /** - * Retrieve the context associated with an action. - *

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.

- - * @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. - * - *

- * 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. - *

- *

- * An application can connect to an MQTT server using: - *

- * - * - *

- * 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. - *

- *

- * 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. - *

- *

- * 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. - *

- *

- * The message store interface is pluggable. Different stores can be used by - * implementing the {@link MqttClientPersistence} interface and passing it to - * the clients constructor. - *

- * - * @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. - *

- * 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. - * - *

- * The serverURI parameter is typically used with the the - * clientId 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. - * - *

- * The address of the server to connect to is specified as a URI. Two types - * of connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. For example: - *

- * - *

- * If the port is not specified, it will default to 1883 for - * tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

- * 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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- * - * - *

- * In Java ME, the platform settings are used for SSL connections. - *

- * - *

- * 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. - *

- * 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. - * - *

- * The serverURI parameter is typically used with the the - * clientId 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. - * - *

- * The address of the server to connect to is specified as a URI. Two types - * of connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. For example: - *

- * - *

- * If the port is not specified, it will default to 1883 for - * tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

- * 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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- * - * - *

- * In Java ME, the platform settings are used for SSL connections. - *

- *

- * 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. - *

- *

- * 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 null. - *

- * - * @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. - *

- * 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. - * - *

- * The serverURI parameter is typically used with the the - * clientId 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. - * - *

- * The address of the server to connect to is specified as a URI. Two types - * of connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. For example: - *

- * - *

- * If the port is not specified, it will default to 1883 for - * tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

- * 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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- * - * - *

- * In Java ME, the platform settings are used for SSL connections. - *

- *

- * 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. - *

- *

- * 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 null. - *

- * - * @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= 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. - *

- * 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. - *

- * There are two alternative methods that should be used in preference to - * this one when publishing a message: - *

- *
    - *
  • {@link MqttAsyncClient#publish(String, MqttMessage)} to publish a - * message in a non-blocking manner or
  • - *
  • {@link MqttClient#publish(String, MqttMessage)} to publish a message - * in a blocking manner
  • - *
- *

- * When you build an application, the design of the topic tree should take - * into account the following principles of topic name syntax and semantics: - *

- * - *
    - *
  • A topic must be at least one character long.
  • - *
  • Topic names are case sensitive. For example, ACCOUNTS and - * Accounts are two different topics.
  • - *
  • Topic names can include the space character. For example, - * Accounts payable is a valid topic.
  • - *
  • A leading "/" creates a distinct topic. For example, - * /finance is different from finance. /finance - * matches "+/+" and "/+", but not "+".
  • - *
  • Do not include the null character (Unicode \x0000) in any topic.
  • - *
- * - *

- * The following principles apply to the construction and content of a topic - * tree: - *

- * - *
    - *
  • The length is limited to 64k but within that there are no limits to - * the number of levels in a topic tree.
  • - *
  • There can be any number of root nodes; that is, there can be any - * number of topic trees.
  • - *
- * - * @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.

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.

- * - * @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. - *

- * 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. - *

- * - * @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. - * - *

- * This method is invoked synchronously by the MQTT client. An - * acknowledgment is not sent back to the server until this - * method returns cleanly.

- *

- * If an implementation of this method throws an Exception, 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.

- *

- * 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.

- *

- * 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.

- *

- * 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.

- * - * @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. - * - *

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. - *

- *

An application can connect to an MQTT server using:

- *
    - *
  • A plain TCP socket - *
  • An secure SSL/TLS socket - *
- * - *

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. - *

- *

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. - *

- *

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.

- *

The message store interface is pluggable. Different stores can be used by implementing - * the {@link MqttClientPersistence} interface and passing it to the clients constructor. - *

- * - * @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. - *

- * 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. - * - *

The serverURI parameter is typically used with the - * the clientId 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. - * - *

The address of the server to connect to is specified as a URI. Two types of - * connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. - * For example:

- *
    - *
  • tcp://localhost:1883
  • - *
  • ssl://localhost:8883
  • - *
- *

- * If the port is not specified, it will - * default to 1883 for tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- *
    - *
  • Supplying an SSLSocketFactory - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.
  • - *
  • SSL Properties - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.
  • - *
  • Use JVM settings - There are a number of standard - * Java system properties that can be used to configure key and trust stores.
  • - *
- * - *

In Java ME, the platform settings are used for SSL connections.

- * - *

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. - *

- * 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. - * - *

The serverURI parameter is typically used with the - * the clientId 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. - * - *

The address of the server to connect to is specified as a URI. Two types of - * connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. - * For example:

- *
    - *
  • tcp://localhost:1883
  • - *
  • ssl://localhost:8883
  • - *
- *

- * If the port is not specified, it will - * default to 1883 for tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- *
    - *
  • Supplying an SSLSocketFactory - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.
  • - *
  • SSL Properties - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.
  • - *
  • Use JVM settings - There are a number of standard - * Java system properties that can be used to configure key and trust stores.
  • - *
- * - *

In Java ME, the platform settings are used for SSL connections.

- *

- * 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. - *

- *

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 null.

- * - * @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. - *

- * 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. - * - *

The serverURI parameter is typically used with the - * the clientId 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. - * - *

The address of the server to connect to is specified as a URI. Two types of - * connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. - * For example: - *

- *
    - *
  • tcp://localhost:1883
  • - *
  • ssl://localhost:8883
  • - *
- *

If the port is not specified, it will - * default to 1883 for tcp://" URIs, and 8883 for ssl:// URIs. - *

- * - *

- * A client identifier clientId 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. - *

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. - *

- *

- * In Java SE, SSL can be configured in one of several ways, which the - * client will use in the following order: - *

- *
    - *
  • Supplying an SSLSocketFactory - applications can - * use {@link MqttConnectOptions#setSocketFactory(SocketFactory)} to supply - * a factory with the appropriate SSL settings.
  • - *
  • SSL Properties - applications can supply SSL settings as a - * simple Java Properties using {@link MqttConnectOptions#setSSLProperties(Properties)}.
  • - *
  • Use JVM settings - There are a number of standard - * Java system properties that can be used to configure key and trust stores.
  • - *
- * - *

In Java ME, the platform settings are used for SSL connections.

- *

- * 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. - *

- *

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 null.

- * - * @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. - *

- * 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; iSet the maximum time to wait for an action to complete before - * returning control to the invoking application. Control is returned - * when:

- *
    - *
  • the action completes
  • - *
  • or when the timeout if exceeded
  • - *
  • or when the client is disconnect/shutdown
  • - *
- *

- * 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. - *

- * @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. - *

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.

- * @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. - *

- * 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.

- *

- * It is up to the persistence interface to log any exceptions or error information - * which may be required when diagnosing a persistence failure.

- */ -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 MqttConnectOptions object using the - * default values. - * - * The defaults are: - *
    - *
  • The keepalive interval is 60 seconds
  • - *
  • Clean Session is true
  • - *
  • The message delivery retry interval is 15 seconds
  • - *
  • The connection timeout period is 30 seconds
  • - *
  • No Will message is set
  • - *
  • A standard SocketFactory is used
  • - *
- * 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. - *

The default value is 60 seconds

- * - * @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. - *

The default value is 10

- * @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 - * null if one has not been set. - * @return The Socket Factory - */ - public SocketFactory getSocketFactory() { - return socketFactory; - } - - /** - * Sets the SocketFactory to use. This allows an application - * to apply its own policies around the creation of network sockets. If - * using an SSL connection, an SSLSocketFactory 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 null 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 - * IllegalStateException being thrown. - * @return the message to use, or null 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. - *

Note that these - * properties are only valid if an implementation of the Java - * Secure Socket Extensions (JSSE) is available. These properties are - * not used if a SocketFactory has been set using - * {@link #setSocketFactory(SocketFactory)}. - * The following properties can be used:

- *
- *
com.ibm.ssl.protocol
- *
One of: SSL, SSLv3, TLS, TLSv1, SSL_TLS.
- *
com.ibm.ssl.contextProvider - *
Underlying JSSE provider. For example "IBMJSSE2" or "SunJSSE"
- * - *
com.ibm.ssl.keyStore
- *
The name of the file that contains the KeyStore object that you - * want the KeyManager to use. For example /mydir/etc/key.p12
- * - *
com.ibm.ssl.keyStorePassword
- *
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: - * com.ibm.micro.security.Password.obfuscate(char[] password). - * 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.
- * - *
com.ibm.ssl.keyStoreType
- *
Type of key store, for example "PKCS12", "JKS", or "JCEKS".
- * - *
com.ibm.ssl.keyStoreProvider
- *
Key store provider, for example "IBMJCE" or "IBMJCEFIPS".
- * - *
com.ibm.ssl.trustStore
- *
The name of the file that contains the KeyStore object that you - * want the TrustManager to use.
- * - *
com.ibm.ssl.trustStorePassword
- *
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: - * com.ibm.micro.security.Password.obfuscate(char[] password). - * 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.
- * - *
com.ibm.ssl.trustStoreType
- *
The type of KeyStore object that you want the default TrustManager to use. - * Same possible values as "keyStoreType".
- * - *
com.ibm.ssl.trustStoreProvider
- *
Trust store provider, for example "IBMJCE" or "IBMJCEFIPS".
- * - *
com.ibm.ssl.enabledCipherSuites
- *
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.
- * - *
com.ibm.ssl.keyManager
- *
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". - *
- * - *
com.ibm.ssl.trustManager
- *
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". - *
- *
- * @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. - *

- * There is no default HostnameVerifier - *

- * @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. - *
    - *
  • 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: - *
      - *
    • Message delivery will be reliable meeting - * the specified QOS even if the client, server or connection are restarted. - *
    • The server will treat a subscription as durable. - *
    - *
  • If set to true the client and server will not maintain state across - * restarts of the client, the server or the connection. This means - *
      - *
    • Message delivery to the specified QOS cannot be maintained if the - * client, server or connection are restarted - *
    • The server will treat a subscription as non-durable - *
    - *
- * @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. - *

- * Each serverURI specifies the address of a server that the client may - * connect to. Two types of - * connection are supported tcp:// for a TCP connection and - * ssl:// for a TCP connection secured by SSL/TLS. - * For example: - *

    - *
  • tcp://localhost:1883
  • - *
  • ssl://localhost:8883
  • - *
- * If the port is not specified, it will - * default to 1883 for tcp://" URIs, and 8883 for ssl:// URIs. - *

- * If serverURIs is set then it overrides the serverURI parameter passed in on the - * constructor of the MQTT client. - *

- * 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. - *

- * Specifying a list of servers that a client may connect to has several uses: - *

    - *
  1. High Availability and reliable message delivery - *

    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.

    - *

    The cleansession flag must be set to false if durable subscriptions and/or reliable - * message delivery is required.

  2. - *
  3. Hunt List - *

    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

  4. - *
- * @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. - *
    - *
  • If set to false, the client will not attempt to automatically - * reconnect to the server in the event that the connection is lost.
  • - *
  • 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.
  • - *
- * @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. - * - *

- * Used to track the the delivery progress of a message when a publish is - * executed in a non-blocking manner (run in the background)

- * - * @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. - *

Until the message has been delivered, the message being delivered will - * be returned. Once the message has been delivered null 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 SocketFactory do not match. - * URIs beginning tcp:// must use a javax.net.SocketFactory, - * and URIs beginning ssl:// must use a javax.net.ssl.SSLSocketFactory. - */ - 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 MqttException 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 MqttException with the specified - * Throwable 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 MqttException with the specified - * Throwable 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 null. - */ - public Throwable getCause() { - return cause; - } - - /** - * Returns the detail message for this exception. - * @return the detail message, which may be null. - */ - public String getMessage() { - return MessageCatalog.getMessage(reasonCode); - } - - /** - * Returns a String representation of this exception. - * @return a String 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: - *

    - *
  • Message QoS set to 1
  • - *
  • Message will not be "retained" by the server
  • - *
- */ - 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 true 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 true and with an empty - * byte array as the payload e.g. new byte[0] will clear the - * retained message from the server. The default value is false - * - * @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. - *
    - *
  • 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".
  • - * - *
  • 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 MqttConnectOptions. - * 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.
  • - * - *
  • 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 MqttConnectOptions. - * If a persistence mechanism is not specified, the message will not be - * delivered in the event of a client failure.
  • - * - *
- * 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 true if the values can be changed, - * false 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 true 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. - *

- * 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.

- *

- * 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:

- *
    - *
  • It could return the data as it was passed in - * originally, with the same byte arrays and offsets.
  • - *
  • 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
  • - *
  • 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.
  • - *
- */ -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 MqttPersistenceException - */ - public MqttPersistenceException() { - super(REASON_CODE_CLIENT_EXCEPTION); - } - - /** - * Constructs a new MqttPersistenceException 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 MqttPersistenceException with the specified - * Throwable as the underlying reason. - * @param cause the underlying cause of the exception. - */ - public MqttPersistenceException(Throwable cause) { - super(cause); - } - /** - * Constructs a new MqttPersistenceException with the specified - * Throwable 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 MqttSecurityException 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 MqttSecurityException with the specified - * Throwable as the underlying reason. - * @param cause the underlying cause of the exception. - */ - public MqttSecurityException(Throwable cause) { - super(cause); - } - /** - * Constructs a new MqttSecurityException with the specified - * code and Throwable 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. - *

- * A token that implements the ImqttToken interface is returned from all non-blocking - * method with the exception of publish. - *

- * - * @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 - * - *

This class implements the {@link IMqttPingSender} pinger interface - * allowing applications to send ping packet to server every keep alive interval. - *

- * - * @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 - * - *

This class implements the {@link MqttPingSender} pinger interface - * allowing applications to send ping packet to server every keep alive interval. - *

- * - * @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 - 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, "", "" ); - - 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 = ""; - - 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; - -/** - *

This class handles the connection of the AsyncClient to one of the available URLs.

- *

The URLs are supplied as either the singleton when the client is created, or as a list in the connect options.

- *

This class uses its own onSuccess and onFailure callbacks in preference to the user supplied callbacks.

- *

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

- *

If a connection succeeds then the users token is notified and the users onSuccess callback is called.

- *

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

- */ -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.
- * 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;i0) { - 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 - * The SSLSocketFacotryFactory can be reconfigured at any time. A - * reconfiguration does not affect existing socket factories. - *

- * All properties share the same key space; i.e. the configuration ID is not - * part of the property keys. - *

- * The methods should be called in the following order: - *

    - *
  1. isSupportedOnJVM(): to check whether this class is supported on - * the runtime platform. Not all runtimes support SSL/TLS.
  2. - *
  3. SSLSocketFactoryFactory(): the constructor. Clients - * (in the same JVM) may share an SSLSocketFactoryFactory, or have one each.
  4. - *
  5. initialize(properties, configID): 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
  6. - *
  7. getEnabledCipherSuites(configID): to later set the enabled - * cipher suites on the socket [see below].
  8. - *
- *
    - *
  • For an MQTT server: - - *
      - *
    1. getKeyStore(configID): Optionally, to check that if there is no - * keystore, then that all the enabled cipher suits are anonymous.
    2. - *
    3. createServerSocketFactory(configID): to create an - * SSLServerSocketFactory.
    4. - *
    5. getClientAuthentication(configID): to later set on the - * SSLServerSocket (itself created from the SSLServerSocketFactory) whether - * client authentication is needed.
    6. - *
    - *
  • - *
  • For an MQTT client: - *
      - *
    1. createSocketFactory(configID): to create an SSLSocketFactory.
    2. - *
    - *
  • - *
- */ -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> 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=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 of headers - * @return A Hashmap 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 CountingInputStream 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 MqttInputStream lets applications read instances of - * MqttWireMessage. - */ -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 MqttWireMessage 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 MqttOutputStream lets applications write instances of - * MqttWireMessage. - */ -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 MqttWireMessage 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 false 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 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 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> 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 (posA 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 - * 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. - *

- * 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. - *

- * The levels in descending order are:

- *
    - *
  • SEVERE (log - highest value)
  • - *
  • WARNING (log)
  • - *
  • INFO (log)
  • - *
  • CONFIG (log)
  • - *
  • FINE (trace)
  • - *
  • FINER (trace)
  • - *
  • FINEST (trace - lowest value)
  • - *
- * - */ -public interface Logger { - /** - * SEVERE is a message level indicating a serious failure. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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. - *

- * 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 SimpleFormatter 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=\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 @@ - -Provides facilities to write and format log and trace to help debug problems. - -

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. - -

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. - - \ 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 @@ - -Contains a programming interface enabling applications to communicate with an MQTT server. - -

-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: -

    -
  • Where the network is expensive, has low bandwidth or is unreliable such as mobile and vsat networks -
  • When run on an embedded or mobile device with limited processor, memory or battery -
-

Features of the protocol include: -

    -
  • The publish/subscribe message pattern to provide one-to-many message - distribution and decoupling of applications -
  • A messaging transport that is agnostic to the content of the payload -
  • The use of TCP/IP to provide network connectivity -
  • The use of SSL/TLS to provide network security and trust -
  • Three qualities of service for message delivery which are maintained across - network, client and server breaks. -
      -
    • "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. -
    • "At least once", where messages are assured to arrive but duplicates may occur. -
    • "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. -
    - 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 -
  • A small transport overhead (the fixed-length header is just 2 bytes), and - protocol exchanges minimised to reduce network traffic -
  • A mechanism to notify interested parties to an abnormal disconnection of - a client using the Last Will and Testament feature -
- -

The basic means of operating the client is:

-
    -
  1. 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.
  2. -
  3. connect to the server
  4. -
  5. Exchange messages with the server: -
      -
    • publish messages to the server - specifying a topic as the destination on the server
    • -
    • subscribe to one more topics. 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 callback -
    -
  6. disconnect from the server.
  7. -
- -

The programming model and concepts like the protocol are small and easy to use. Key concepts -to use when creating MQTT application include: -

    -
  • 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. -
  • 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. -
  • 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: -
      -
    • Message delivery will match the quality of service specified when the message was published even across - failures of the network, client or server -
    • 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. -
    - If set to true: -
      -
    • 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. -
    • 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. -
    • 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 -
    -
  • When subscribing for messages the subscription can be for an absolute topic or a wildcarded topic. -
  • When unsubscribing the topic to be unsubscribed must match one specified on an earlier subscribe. -
  • There are two MQTT client libraries to choose from: -
      -
    1. {@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: -
        -
      • 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. -
      • Pass a {@link org.eclipse.paho.client.mqttv3.IMqttActionListener IMqttActionListener} - to the operation. The listener will then be called back when the operation completes. -
      • 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. -
      -
    2. {@link org.eclipse.paho.client.mqttv3.IMqttClient MqttClient} where methods block until - the operation has completed. -
    -
  • For both the blocking and non-blocking clients some operations are asynchronous. This includes: -
      -
    • Notification that a new message has arrived: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#messageArrived messageArrived}. -
    • Notification that the connection to the server has broken: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#connectionLost connectionLost}. -
    • Notification that a message has been delivered to the server: - {@link org.eclipse.paho.client.mqttv3.MqttCallback#deliveryComplete deliveryComplete}. -
    - A client registers interest in these notifications by registering a - {@link org.eclipse.paho.client.mqttv3.MqttCallback MqttCallback} on the client -
  • There are a number of programs that demonstrate the different modes of - writing MQTT applications -
      -
    • {@link org.eclipse.paho.sample.mqttv3app.Sample} uses the blocking client interface -
    • {@link org.eclipse.paho.sample.mqttv3app.SampleAsyncCallBack} uses the asynchronous client with - callbacks which are notified when an operation completes -
    • {@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. -
    -
  • {@link org.eclipse.paho.client.mqttv3.MqttConnectOptions MqttConnectOptions} can be used to override the - default connection options. This includes: -
      -
    • Setting the cleansession flag -
    • Specifying a list of MQTT servers that the client can attempt to connect to -
    • Set a keepalive interval -
    • Setting the last will and testament -
    • Setting security credentials -
    -
- - \ 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 -Contains implementations of the MqttClientPersistence interface. - -

-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. - - \ 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 @@ - -Provides helpers and utilities. - - - \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..77a235a --- /dev/null +++ b/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + jar + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + + + de.re.easymodbus + easymodbus + 1.0-SNAPSHOT + + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + 1.2.2 + + + org.scream3r + jssc + 2.8.0 + + + \ No newline at end of file diff --git a/EasyModbus/src/de/re/easymodbus/datatypes/Parity.java b/src/main/java/de/re/easymodbus/datatypes/Parity.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/datatypes/Parity.java rename to src/main/java/de/re/easymodbus/datatypes/Parity.java diff --git a/EasyModbus/src/de/re/easymodbus/datatypes/RegisterOrder.java b/src/main/java/de/re/easymodbus/datatypes/RegisterOrder.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/datatypes/RegisterOrder.java rename to src/main/java/de/re/easymodbus/datatypes/RegisterOrder.java diff --git a/EasyModbus/src/de/re/easymodbus/datatypes/StopBits.java b/src/main/java/de/re/easymodbus/datatypes/StopBits.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/datatypes/StopBits.java rename to src/main/java/de/re/easymodbus/datatypes/StopBits.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/CRCCheckFailedException.java b/src/main/java/de/re/easymodbus/exceptions/CRCCheckFailedException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/CRCCheckFailedException.java rename to src/main/java/de/re/easymodbus/exceptions/CRCCheckFailedException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/ConnectionException.java b/src/main/java/de/re/easymodbus/exceptions/ConnectionException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/ConnectionException.java rename to src/main/java/de/re/easymodbus/exceptions/ConnectionException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/FunctionCodeNotSupportedException.java b/src/main/java/de/re/easymodbus/exceptions/FunctionCodeNotSupportedException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/FunctionCodeNotSupportedException.java rename to src/main/java/de/re/easymodbus/exceptions/FunctionCodeNotSupportedException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/ModbusException.java b/src/main/java/de/re/easymodbus/exceptions/ModbusException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/ModbusException.java rename to src/main/java/de/re/easymodbus/exceptions/ModbusException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/QuantityInvalidException.java b/src/main/java/de/re/easymodbus/exceptions/QuantityInvalidException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/QuantityInvalidException.java rename to src/main/java/de/re/easymodbus/exceptions/QuantityInvalidException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/SerialPortException.java b/src/main/java/de/re/easymodbus/exceptions/SerialPortException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/SerialPortException.java rename to src/main/java/de/re/easymodbus/exceptions/SerialPortException.java diff --git a/EasyModbus/src/de/re/easymodbus/exceptions/StartingAddressInvalidException.java b/src/main/java/de/re/easymodbus/exceptions/StartingAddressInvalidException.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/exceptions/StartingAddressInvalidException.java rename to src/main/java/de/re/easymodbus/exceptions/StartingAddressInvalidException.java diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/DateTime.java b/src/main/java/de/re/easymodbus/modbusclient/DateTime.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusclient/DateTime.java rename to src/main/java/de/re/easymodbus/modbusclient/DateTime.java diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java b/src/main/java/de/re/easymodbus/modbusclient/ModbusClient.java similarity index 99% rename from EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java rename to src/main/java/de/re/easymodbus/modbusclient/ModbusClient.java index 7e29052..8f582a7 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/ModbusClient.java +++ b/src/main/java/de/re/easymodbus/modbusclient/ModbusClient.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -21,12 +21,15 @@ import java.io.*; import java.util.*; +import de.re.easymodbus.datatypes.Parity; +import de.re.easymodbus.datatypes.RegisterOrder; +import de.re.easymodbus.datatypes.StopBits; +import jssc.*; import org.eclipse.paho.client.mqttv3.MqttException; import org.eclipse.paho.client.mqttv3.MqttPersistenceException; import java.io.InputStream; -import jssc.*; -import de.re.easymodbus.datatypes.*; + import de.re.easymodbus.exceptions.ModbusException; import de.re.easymodbus.mqtt.EasyModbus2Mqtt; diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java b/src/main/java/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java similarity index 94% rename from EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java rename to src/main/java/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java index b1dab09..8ed61b0 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java +++ b/src/main/java/de/re/easymodbus/modbusclient/ReceiveDataChangedListener.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java b/src/main/java/de/re/easymodbus/modbusclient/SendDataChangedListener.java similarity index 94% rename from EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java rename to src/main/java/de/re/easymodbus/modbusclient/SendDataChangedListener.java index db52756..bd90ab9 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/SendDataChangedListener.java +++ b/src/main/java/de/re/easymodbus/modbusclient/SendDataChangedListener.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/StoreLogData.java b/src/main/java/de/re/easymodbus/modbusclient/StoreLogData.java similarity index 94% rename from EasyModbus/src/de/re/easymodbus/modbusclient/StoreLogData.java rename to src/main/java/de/re/easymodbus/modbusclient/StoreLogData.java index cc5fa4b..e09d8df 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/StoreLogData.java +++ b/src/main/java/de/re/easymodbus/modbusclient/StoreLogData.java @@ -10,7 +10,7 @@ * Stores Log Data is a File. The Data will be stored in the File logDataYYYYMMDD.txt * Example: logData20170403.txt * - * @author Stefan Roßmann + * @author Stefan Roßmann */ public class StoreLogData diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java similarity index 99% rename from EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java rename to src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java index 055e308..3505a52 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java +++ b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleGUI.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or @@ -28,7 +28,7 @@ import java.awt.event.ActionEvent; /** * - * @author Stefan Roßmann + * @author Stefan Roßmann */ @SuppressWarnings("serial") public class EasyModbusTCPClientExampleGUI extends javax.swing.JFrame diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java similarity index 95% rename from EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java rename to src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java index 01c858e..fbe8688 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java +++ b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTCPClientExampleJava.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java similarity index 96% rename from EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java rename to src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java index 5a36398..2e38758 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java +++ b/src/main/java/de/re/easymodbus/modbusclient/gui/EasyModbusTcpClient.java @@ -4,14 +4,14 @@ * Creative Commons license: Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0) *You are free to: * - *Share — copy and redistribute the material in any medium or format + *Share - copy and redistribute the material in any medium or format *The licensor cannot revoke these freedoms as long as you follow the license terms. * *Under the following terms: * - *Attribution — You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. - *NonCommercial — You may not use the material for commercial purposes. - *NoDerivatives — If you remix, transform, or build upon the material, you may not distribute the modified material. + *Attribution - You must give appropriate credit, provide a link to the license, and indicate if changes were made. You may do so in any reasonable manner, but not in any way that suggests the licensor endorses you or your use. + *NonCommercial - You may not use the material for commercial purposes. + *NoDerivatives - If you remix, transform, or build upon the material, you may not distribute the modified material. */ package de.re.easymodbus.modbusclient.gui; @@ -26,7 +26,7 @@ import java.awt.event.ItemEvent; /** * - * @author Stefan Roßmann + * @author Stefan Roßmann */ @SuppressWarnings("serial") public class EasyModbusTcpClient extends javax.swing.JFrame diff --git a/EasyModbus/src/de/re/easymodbus/modbusclient/gui/Rossmann-Engineering_Logo_klein.png b/src/main/java/de/re/easymodbus/modbusclient/gui/Rossmann-Engineering_Logo_klein.png similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusclient/gui/Rossmann-Engineering_Logo_klein.png rename to src/main/java/de/re/easymodbus/modbusclient/gui/Rossmann-Engineering_Logo_klein.png diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ClientConnectionThread.java b/src/main/java/de/re/easymodbus/modbusserver/ClientConnectionThread.java similarity index 99% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ClientConnectionThread.java rename to src/main/java/de/re/easymodbus/modbusserver/ClientConnectionThread.java index 32d7759..ce7ab30 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ClientConnectionThread.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ClientConnectionThread.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/DataModel.java b/src/main/java/de/re/easymodbus/modbusserver/DataModel.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusserver/DataModel.java rename to src/main/java/de/re/easymodbus/modbusserver/DataModel.java diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java b/src/main/java/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java similarity index 97% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java rename to src/main/java/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java index 1c70f0e..5a96c1e 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ICoilsChangedDelegator.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java b/src/main/java/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java similarity index 97% rename from EasyModbus/src/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java rename to src/main/java/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java index 2d4656e..0fa3d30 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java +++ b/src/main/java/de/re/easymodbus/modbusserver/IHoldingRegistersChangedDelegator.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java b/src/main/java/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java similarity index 97% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java rename to src/main/java/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java index e1d3aaf..6e9fd86 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ILogDataChangedDelegator.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java b/src/main/java/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java similarity index 97% rename from EasyModbus/src/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java rename to src/main/java/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java index 60a7db9..8565257 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java +++ b/src/main/java/de/re/easymodbus/modbusserver/INumberOfConnectedClientsChangedDelegator.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ListenerThread.java b/src/main/java/de/re/easymodbus/modbusserver/ListenerThread.java similarity index 98% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ListenerThread.java rename to src/main/java/de/re/easymodbus/modbusserver/ListenerThread.java index a297030..55e9469 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ListenerThread.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ListenerThread.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ModbusProtocoll.java b/src/main/java/de/re/easymodbus/modbusserver/ModbusProtocoll.java similarity index 98% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ModbusProtocoll.java rename to src/main/java/de/re/easymodbus/modbusserver/ModbusProtocoll.java index c852662..662705b 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ModbusProtocoll.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ModbusProtocoll.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ModbusServer.java b/src/main/java/de/re/easymodbus/modbusserver/ModbusServer.java similarity index 99% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ModbusServer.java rename to src/main/java/de/re/easymodbus/modbusserver/ModbusServer.java index dccf0e4..4830ce7 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ModbusServer.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ModbusServer.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ProcessMQTTThread.java b/src/main/java/de/re/easymodbus/modbusserver/ProcessMQTTThread.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ProcessMQTTThread.java rename to src/main/java/de/re/easymodbus/modbusserver/ProcessMQTTThread.java diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java b/src/main/java/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java similarity index 99% rename from EasyModbus/src/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java rename to src/main/java/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java index d43c6d9..bfb93e1 100644 --- a/EasyModbus/src/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java +++ b/src/main/java/de/re/easymodbus/modbusserver/ProcessReceivedDataThread.java @@ -1,5 +1,5 @@ /* - * (c) Stefan Roßmann + * (c) Stefan Roßmann * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/gui/NewJFrame.form b/src/main/java/de/re/easymodbus/modbusserver/gui/NewJFrame.form similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusserver/gui/NewJFrame.form rename to src/main/java/de/re/easymodbus/modbusserver/gui/NewJFrame.form diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/gui/NewJFrame.java b/src/main/java/de/re/easymodbus/modbusserver/gui/NewJFrame.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusserver/gui/NewJFrame.java rename to src/main/java/de/re/easymodbus/modbusserver/gui/NewJFrame.java diff --git a/EasyModbus/src/de/re/easymodbus/modbusserver/gui/PLCLoggerCompact.jpg b/src/main/java/de/re/easymodbus/modbusserver/gui/PLCLoggerCompact.jpg similarity index 100% rename from EasyModbus/src/de/re/easymodbus/modbusserver/gui/PLCLoggerCompact.jpg rename to src/main/java/de/re/easymodbus/modbusserver/gui/PLCLoggerCompact.jpg diff --git a/EasyModbus/src/de/re/easymodbus/mqtt/EasyModbus2Mqtt.java b/src/main/java/de/re/easymodbus/mqtt/EasyModbus2Mqtt.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/mqtt/EasyModbus2Mqtt.java rename to src/main/java/de/re/easymodbus/mqtt/EasyModbus2Mqtt.java diff --git a/EasyModbus/src/de/re/easymodbus/mqtt/FunctionCode.java b/src/main/java/de/re/easymodbus/mqtt/FunctionCode.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/mqtt/FunctionCode.java rename to src/main/java/de/re/easymodbus/mqtt/FunctionCode.java diff --git a/EasyModbus/src/de/re/easymodbus/mqtt/ProcessData.java b/src/main/java/de/re/easymodbus/mqtt/ProcessData.java similarity index 100% rename from EasyModbus/src/de/re/easymodbus/mqtt/ProcessData.java rename to src/main/java/de/re/easymodbus/mqtt/ProcessData.java