Add (partial) support for IoT XEPs

That is XEP-0323, -0324, -0325, and -0347.

SMACK-727.
filetransferTypos
Florian Schmaus 6 years ago
parent d1fe5c2933
commit b91978dcc4
  1. 2
      documentation/developer/integrationtest.md
  2. 8
      documentation/extensions/index.md
  3. 116
      documentation/extensions/iot.md
  4. 6
      smack-core/src/main/java/org/jivesoftware/smack/ReconnectionManager.java
  5. 8
      smack-core/src/main/java/org/jivesoftware/smack/packet/EmptyResultIQ.java
  6. 13
      smack-core/src/main/java/org/jivesoftware/smack/packet/IQ.java
  7. 4
      smack-core/src/main/java/org/jivesoftware/smack/packet/Presence.java
  8. 9
      smack-core/src/main/java/org/jivesoftware/smack/util/ParserUtils.java
  9. 4
      smack-core/src/main/java/org/jivesoftware/smack/util/XmlStringBuilder.java
  10. 28
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/IoTException.java
  11. 42
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/IoTManager.java
  12. 161
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/Thing.java
  13. 149
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/IoTControlManager.java
  14. 29
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/ThingControlRequest.java
  15. 23
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/Constants.java
  16. 48
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetRequest.java
  17. 41
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/IoTSetResponse.java
  18. 38
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/SetBoolData.java
  19. 92
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/SetData.java
  20. 38
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/SetDoubleData.java
  21. 38
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/SetIntData.java
  22. 38
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/SetLongData.java
  23. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/element/package-info.java
  24. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/package-info.java
  25. 82
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/provider/IoTSetRequestProvider.java
  26. 30
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/provider/IoTSetResponseProvider.java
  27. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/control/provider/package-info.java
  28. 210
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/IoTDataManager.java
  29. 23
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/ThingMomentaryReadOutRequest.java
  30. 27
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/ThingMomentaryReadOutResult.java
  31. 23
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/Constants.java
  32. 111
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataField.java
  33. 54
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataReadOutAccepted.java
  34. 54
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTDataRequest.java
  35. 92
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/IoTFieldsExtension.java
  36. 63
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/NodeElement.java
  37. 59
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/TimestampElement.java
  38. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/element/package-info.java
  39. 48
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/filter/IoTFieldsExtensionFilter.java
  40. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/filter/package-info.java
  41. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/package-info.java
  42. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTDataReadOutAcceptedProvider.java
  43. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTDataRequestProvider.java
  44. 136
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/IoTFieldsExtensionProvider.java
  45. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/data/provider/package-info.java
  46. 27
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/AbstractThingStateChangeListener.java
  47. 38
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTClaimedException.java
  48. 420
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/IoTDiscoveryManager.java
  49. 95
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/ThingState.java
  50. 25
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/ThingStateChangeListener.java
  51. 23
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/Constants.java
  52. 66
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTClaimed.java
  53. 62
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTDisown.java
  54. 53
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTDisowned.java
  55. 52
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTMine.java
  56. 54
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTRegister.java
  57. 67
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTRemove.java
  58. 57
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTRemoved.java
  59. 41
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/IoTUnregister.java
  60. 78
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/Tag.java
  61. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/element/package-info.java
  62. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/package-info.java
  63. 36
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTClaimedProvider.java
  64. 36
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTDisownProvider.java
  65. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTDisownedProvider.java
  66. 62
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRegisterProvider.java
  67. 42
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRemoveProvider.java
  68. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTRemovedProvider.java
  69. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/IoTUnregisterProvider.java
  70. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/discovery/provider/package-info.java
  71. 105
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/element/NodeInfo.java
  72. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/element/package-info.java
  73. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/package-info.java
  74. 35
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/parser/NodeInfoParser.java
  75. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/parser/package-info.java
  76. 319
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/IoTProvisioningManager.java
  77. 32
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCache.java
  78. 37
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/ClearCacheResponse.java
  79. 23
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/Constants.java
  80. 41
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/IoTIsFriend.java
  81. 52
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/IoTIsFriendResponse.java
  82. 59
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/Unfriend.java
  83. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/element/package-info.java
  84. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/package-info.java
  85. 31
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/ClearCacheProvider.java
  86. 31
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/ClearCacheResponseProvider.java
  87. 34
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/IoTIsFriendProvider.java
  88. 37
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/IoTIsFriendResponseProvider.java
  89. 33
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/UnfriendProvider.java
  90. 21
      smack-experimental/src/main/java/org/jivesoftware/smackx/iot/provisioning/provider/package-info.java
  91. 93
      smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.providers
  92. 5
      smack-experimental/src/main/resources/org.jivesoftware.smack.experimental/experimental.xml
  93. 8
      smack-im/src/main/java/org/jivesoftware/smack/roster/Roster.java
  94. 33
      smack-im/src/main/java/org/jivesoftware/smack/roster/RosterEntry.java
  95. 83
      smack-im/src/main/java/org/jivesoftware/smack/roster/RosterUtil.java
  96. 1
      smack-integration-test/build.gradle
  97. 3
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntTest.java
  98. 6
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/AbstractSmackIntegrationTest.java
  99. 32
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/Configuration.java
  100. 5
      smack-integration-test/src/main/java/org/igniterealtime/smack/inttest/SmackIntegrationTestEnvironment.java
  101. Some files were not shown because too many files have changed in this diff Show More

@ -55,6 +55,8 @@ debug=true
| accountOnePassword | Password of the first XMPP account |
| accountTwoUsername | Username of the second XMPP account |
| accountTwoPassword | Password of the second XMPP account |
| accountThreeUsername | Username of the third XMPP account |
| accountThreePassword | Password of the third XMPP account |
| debug | 'true' to enable debug output |
| enabledTests | List of enabled tests |
| disabledTests | List of disabled tests |

@ -1,4 +1,4 @@
Smack Extensions User Manual
smackSmack Extensions User Manual
============================
The XMPP protocol includes a base protocol and many optional extensions
@ -77,8 +77,12 @@ Experimental Smack Extensions and currently supported XEPs of smack-experimental
| Name | XEP | Description |
|---------------------------------------------|----------------------------------------------------------|----------------------------------------------------------------------------------------------------------|
| Message Carbons | [XEP-0280](http://xmpp.org/extensions/xep-0280.html) | Keep all IM clients for a user engaged in a conversation, by carbon-copy outbound messages to all interested resources.
| [HTTP over XMPP transport](hoxt.md) | [XEP-0332](http://xmpp.org/extensions/xep-0332.html) | Allows to transport HTTP communication over XMPP peer-to-peer networks. |
| [Internet of Things - Sensor Data](iot.md) | [XEP-0323](http://xmpp.org/extensions/xep-0323.html) | Sensor data interchange over XMPP. |
| [Internet of Things - Provisioning](iot.md) | [XEP-0324](http://xmpp.org/extensions/xep-0324.html) | Provisioning, access rights and user priviliges for the Internet of Things. |
| [Internet of Things - Control](iot.md) | [XEP-0325](http://xmpp.org/extensions/xep-0325.html) | Describes how to control devices or actuators in an XMPP-based sensor netowrk. |
| [HTTP over XMPP transport](hoxt.md) | [XEP-0332](http://xmpp.org/extensions/xep-0332.html) | Allows to transport HTTP communication over XMPP peer-to-peer networks. |
| JSON Containers | [XEP-0335](http://xmpp.org/extensions/xep-0335.html) | Encapsulation of JSON data within XMPP Stanzas. |
| [Internet of Things - Discovery](iot.md) | [XEP-0347](http://xmpp.org/extensions/xep-0347.html) | Describes how Things can be installed and discovered by their owners. |
| Google GCM JSON payload | n/a | Semantically the same as XEP-0335: JSON Containers |
| Client State Indication | [XEP-0352](http://xmpp.org/extensions/xep-0352.html) | A way for the client to indicate its active/inactive state. |

@ -0,0 +1,116 @@
Internet of Things (XEP-0323, -0324, -0325, -0347)
==================================================
The Internet of Things (IoT) XEPs are an experimental open standard how XMPP can be used for IoT. They currently consists of
- XEP-0323 Sensor Data
- XEP-0324 Provisioning
- XEP-0325 Control
- XEP-0326 Concentrators
- XEP-0347 Discovery
Smack only supports a subset of the functionality described by the XEPs!
Thing Builder
-------------
The `org.jivesoftware.smackx.iot.Thing` class acts as basic entity representing a single "Thing" which can used to retrieve data from or to send control commands to. `Things` are constructed using a builder API.
Reading data from things
------------------------
For example, we can build a Thing which provides the current temperature with
```java
Thing dataThing = Thing.builder().setKey(key).setSerialNumber(sn).setMomentaryReadOutRequestHandler(new ThingMomentaryReadOutRequest() {
@Override
public void momentaryReadOutRequest(ThingMomentaryReadOutResult callback) {
int temp = getCurrentTemperature();
IoTDataField.IntField field = new IntField("temperature", temp);
callback.momentaryReadOut(Collections.singletonList(field));
}
}).build();
```
While not strictly required, most things are identified via a key and serial number. We also build the thing with a "momentary read out request handler" which when triggered, retrieved the current temperature and reports it back to the requestor.
After the `Thing` is build, it needs to be made available so that other entities within the federated XMPP network can use it. Right now, we only intall the Thing in the `IoTDataManager`, which means the thing will act on read out requests but not be managed by a provisioning server.
```java
IoTDataManager iotDataManager = IoTDataManager.getInstanceFor(connection);
iotDataManager.installThing(thing);
```
The data can be read out also by using the `IoTDataManager`:
```java
FullJid jid = …
List<IoTFieldsExtension> values = iotDataManager.requestMomentaryValuesReadOut(jid);
```
Now you have to unwrap the `IoTDataField` instances from the `IoTFieldsExtension`. Note that Smack currently only supports a subset of the specified data types.
Controlling a thing
-------------------
Things can also be controlled, e.g. to turn on a light. Let's create thing which can be used to turn the light on and off.
```java
Thing controlThing = Thing.builder().setKey(key).setSerialNumber(sn).setControlRequestHandler(new ThingControlRequest() {
@Override
public void processRequest(Jid from, Collection<SetData> setData) throws XMPPErrorException {
for (final SetData data : setData) {
if (!data.getName().equals("light")) continue;
if (!(data instanceof SetBoolData)) continue;
SetBoolData boolData = (SetBoolData) data;
setLight(boolData.getBooleanValue());
}
}
}).build();
```
No we have to install this thing into the `IoTControlManager`:
```java
IoTControlManager iotControlManager = IoTControlManager.getInstanceFor(connection);
iotControlManager.installThing(thing);
```
The `IoTControlManager` can also be used to control a thing:
```java
FullJid jid = …
SetData setData = new SetBoolData("light", true);
iotControlManager.setUsingIq(jid, setData);
```
Smack currently only supports a subset of the possible data types for set data.
Discovery
---------
You may wondered how a full JIDs of things can be determined. One approach is using the discovery mechanisms specified in XEP-0347. Smack provides the `IoTDiscoveryManager` as API for this.
For example, instead of just installing the previous things in the `IoTDataManager` and/or `IoTControlManager`, we could also use the `IoTDiscoveryManger` to register the thing with a registry. Doing thing also installs the thing in the `IoTDataManager` and the `IoTControlManager`.
```java
IoTDiscoveryManager iotDiscoveryManager = IoTDiscoveryManager.getInstanceFor(connection);
iotDiscovyerManager.registerThing(thing);
```
The registry will now make the thing known to a broader audience, and available for a potential owner.
The `IoTDiscoveryManager` can also be used to claim, disown, remove and unregister a thing.
Provisioning
------------
Things can usually only be used by other things if they are friends. Since a thing normally can't decide on its own if an incoming friendship request should be granted or not, we can delegate this decission to a provisioning service. Smack provides the `IoTProvisinoManager` to deal with friendship and provisioning.
For example, if you want to befriend another thing:
```java
BareJid jid = …
IoTProvisioningManager iotProvisioningManager = IoTProvisioningManager.getInstanceFor(connection);
iotProvisioningManager.sendFriendshipRequest(jid);
```

@ -238,7 +238,11 @@ public final class ReconnectionManager {
// Makes a reconnection attempt
try {
if (isReconnectionPossible(connection)) {
connection.connect();
try {
connection.connect();
} catch (SmackException.AlreadyConnectedException e) {
LOGGER.log(Level.FINER, "Connection was already connected on reconnection attempt", e);
}
}
// TODO Starting with Smack 4.2, connect() will no
// longer login automatically. So change this and the

@ -25,13 +25,7 @@ public class EmptyResultIQ extends IQ {
public EmptyResultIQ(IQ request) {
this();
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
throw new IllegalArgumentException(
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
}
setStanzaId(request.getStanzaId());
setFrom(request.getTo());
setTo(request.getFrom());
initialzeAsResultFor(request);
}
@Override

@ -215,6 +215,17 @@ public abstract class IQ extends Stanza {
*/
protected abstract IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml);
protected final void initialzeAsResultFor(IQ request) {
if (!(request.getType() == Type.get || request.getType() == Type.set)) {
throw new IllegalArgumentException(
"IQ must be of type 'set' or 'get'. Original IQ: " + request.toXML());
}
setStanzaId(request.getStanzaId());
setFrom(request.getTo());
setTo(request.getFrom());
setType(Type.result);
}
/**
* Convenience method to create a new empty {@link Type#result IQ.Type.result}
* IQ based on a {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}
@ -289,9 +300,7 @@ public abstract class IQ extends Stanza {
* @throws IllegalArgumentException if the IQ stanza(/packet) does not have a type of
* {@link Type#get IQ.Type.get} or {@link Type#set IQ.Type.set}.
* @return a new {@link Type#error IQ.Type.error} IQ based on the originating IQ.
* @deprecated use {@link #createErrorResponse(IQ, org.jivesoftware.smack.packet.XMPPError.Builder)} instead.
*/
@Deprecated
public static ErrorIQ createErrorResponse(final IQ request, final XMPPError error) {
return createErrorResponse(request, XMPPError.getBuilder(error));
}

@ -73,6 +73,8 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
* @param type the type.
*/
public Presence(Type type) {
// Ensure that the stanza ID is set by calling super().
super();
setType(type);
}
@ -85,6 +87,8 @@ public final class Presence extends Stanza implements TypedCloneable<Presence> {
* @param mode the mode type for this presence update.
*/
public Presence(Type type, String status, int priority, Mode mode) {
// Ensure that the stanza ID is set by calling super().
super();
setType(type);
setStatus(status);
setPriority(priority);

@ -23,6 +23,7 @@ import java.text.ParseException;
import java.util.Date;
import java.util.Locale;
import org.jivesoftware.smack.SmackException;
import org.jxmpp.jid.EntityBareJid;
import org.jxmpp.jid.Jid;
import org.jxmpp.jid.impl.JidCreate;
@ -122,6 +123,14 @@ public class ParserUtils {
}
}
public static int getIntegerAttributeOrThrow(XmlPullParser parser, String name, String throwMessage) throws SmackException {
Integer res = getIntegerAttribute(parser, name);
if (res == null) {
throw new SmackException(throwMessage);
}
return res;
}
public static Integer getIntegerAttribute(XmlPullParser parser, String name) {
String valueString = parser.getAttributeValue("", name);
if (valueString == null)

@ -238,6 +238,10 @@ public class XmlStringBuilder implements Appendable, CharSequence {
return this;
}
public XmlStringBuilder attribute(String name, boolean bool) {
return attribute(name, Boolean.toString(bool));
}
/**
* Add a new attribute to this builder, with the {@link java.util.Date} instance as its value,
* which will get formated with {@link XmppDateTime#formatXEP0082Date(Date)}.

@ -0,0 +1,28 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot;
import org.jivesoftware.smack.SmackException;
public class IoTException extends SmackException {
/**
*
*/
private static final long serialVersionUID = 1L;
}

@ -0,0 +1,42 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot;
import java.util.Map;
import java.util.WeakHashMap;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.XMPPConnection;
public final class IoTManager extends Manager {
private static final Map<XMPPConnection, IoTManager> INSTANCES = new WeakHashMap<>();
public static synchronized IoTManager getInstanceFor(XMPPConnection connection) {
IoTManager manager = INSTANCES.get(connection);
if (manager == null) {
manager = new IoTManager(connection);
INSTANCES.put(connection, manager);
}
return manager;
}
private IoTManager(XMPPConnection connection) {
super(connection);
}
}

@ -0,0 +1,161 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import org.jivesoftware.smackx.iot.control.ThingControlRequest;
import org.jivesoftware.smackx.iot.data.ThingMomentaryReadOutRequest;
import org.jivesoftware.smackx.iot.discovery.element.Tag;
import org.jivesoftware.smackx.iot.discovery.element.Tag.Type;
import org.jivesoftware.smackx.iot.element.NodeInfo;
public final class Thing {
private final HashMap<String, Tag> metaTags;
private final boolean selfOwned;
private final NodeInfo nodeInfo;
private final ThingMomentaryReadOutRequest momentaryReadOutRequestHandler;
private final ThingControlRequest controlRequestHandler;
private Thing(Builder builder) {
this.metaTags = builder.metaTags;
this.selfOwned = builder.selfOwned;
this.nodeInfo = builder.nodeInfo;
this.momentaryReadOutRequestHandler = builder.momentaryReadOutRequest;
this.controlRequestHandler = builder.controlRequest;
}
public Collection<Tag> getMetaTags() {
return metaTags.values();
}
public boolean isSelfOwened() {
return selfOwned;
}
public NodeInfo getNodeInfo() {
return nodeInfo;
}
public String getNodeId() {
return nodeInfo.getNodeId();
}
public String getSourceId() {
return nodeInfo.getSourceId();
}
public String getCacheType() {
return nodeInfo.getCacheType();
}
public ThingMomentaryReadOutRequest getMomentaryReadOutRequestHandler() {
return momentaryReadOutRequestHandler;
}
public ThingControlRequest getControlRequestHandler() {
return controlRequestHandler;
}
private String toStringCache;
@Override
public String toString() {
if (toStringCache == null) {
StringBuilder sb = new StringBuilder();
sb.append( "Thing " + nodeInfo + " [");
Iterator<Tag> it = metaTags.values().iterator();
while (it.hasNext()) {
Tag tag = it.next();
sb.append(tag);
if (it.hasNext()) {
sb.append(' ');
}
}
sb.append(']');
toStringCache = sb.toString();
}
return toStringCache;
}
public static Builder builder() {
return new Builder();
}
public static class Builder {
private HashMap<String, Tag> metaTags = new HashMap<>();
private boolean selfOwned;
private NodeInfo nodeInfo = NodeInfo.EMPTY;
private ThingMomentaryReadOutRequest momentaryReadOutRequest;
private ThingControlRequest controlRequest;
public Builder setSerialNumber(String sn) {
final String name = "SN";
Tag tag = new Tag(name, Type.str, sn);
metaTags.put(name, tag);
return this;
}
public Builder setKey(String key) {
final String name = "KEY";
Tag tag = new Tag(name, Type.str, key);
metaTags.put(name, tag);
return this;
}
public Builder setManufacturer(String manufacturer) {
final String name = "MAN";
Tag tag = new Tag(name, Type.str, manufacturer);
metaTags.put(name, tag);
return this;
}
public Builder setModel(String model) {
final String name = "MODEL";
Tag tag = new Tag(name, Type.str, model);
metaTags.put(name, tag);
return this;
}
public Builder setVersion(String version) {
final String name = "V";
Tag tag = new Tag(name, Type.num, version);
metaTags.put(name, tag);
return this;
}
public Builder setMomentaryReadOutRequestHandler(ThingMomentaryReadOutRequest momentaryReadOutRequestHandler) {
this.momentaryReadOutRequest = momentaryReadOutRequestHandler;
return this;
}
public Builder setControlRequestHandler(ThingControlRequest controlRequest) {
this.controlRequest = controlRequest;
return this;
}
public Thing build() {
return new Thing(this);
}
}
}

@ -0,0 +1,149 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smackx.iot.Thing;
import org.jivesoftware.smackx.iot.control.element.IoTSetRequest;
import org.jivesoftware.smackx.iot.control.element.IoTSetResponse;
import org.jivesoftware.smackx.iot.control.element.SetData;
import org.jivesoftware.smackx.iot.element.NodeInfo;
import org.jxmpp.jid.FullJid;
/**
* A manger for XEP-0325: Internet of Things - Control.
*
* @author Florian Schmaus {@literal <flo@geekplace.eu>}
* @see <a href="http://xmpp.org/extensions/xep-0325.html">XEP-0323: Internet of Things - Control</a>
*/
public final class IoTControlManager extends Manager {
private static final Map<XMPPConnection, IoTControlManager> INSTANCES = new WeakHashMap<>();
/**
* Get the manger instance responsible for the given connection.
*
* @param connection the XMPP connection.
* @return a manager instance.
*/
public static synchronized IoTControlManager getInstanceFor(XMPPConnection connection) {
IoTControlManager manager = INSTANCES.get(connection);
if (manager == null) {
manager = new IoTControlManager(connection);
INSTANCES.put(connection, manager);
}
return manager;
}
private final Map<NodeInfo, Thing> things = new ConcurrentHashMap<>();
private IoTControlManager(XMPPConnection connection) {
super(connection);
connection.registerIQRequestHandler(new AbstractIqRequestHandler(IoTSetRequest.ELEMENT, IoTSetRequest.NAMESPACE, IQ.Type.set, Mode.async) {
@Override
public IQ handleIQRequest(IQ iqRequest) {
// TODO Lookup thing and provide data.
IoTSetRequest iotSetRequest = (IoTSetRequest) iqRequest;
// TODO Add support for multiple things(/NodeInfos).
final Thing thing = things.get(NodeInfo.EMPTY);
if (thing == null) {
// TODO return error if not at least one thing registered.
return null;
}
ThingControlRequest controlRequest = thing.getControlRequestHandler();
if (controlRequest == null) {
// TODO return error if no request handler for things.
return null;
}
try {
controlRequest.processRequest(iotSetRequest.getFrom(), iotSetRequest.getSetData());
} catch (XMPPErrorException e) {
return IQ.createErrorResponse(iotSetRequest, e.getXMPPError());
}
return new IoTSetResponse(iotSetRequest);
}
});
}
/**
* Control a thing by sending a collection of {@link SetData} instructions.
*
* @param jid
* @param data
* @return
* @throws NoResponseException
* @throws XMPPErrorException
* @throws NotConnectedException
* @throws InterruptedException
* @see #setUsingIq(FullJid, Collection)
*/
public IoTSetResponse setUsingIq(FullJid jid, SetData data) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
return setUsingIq(jid, Collections.singleton(data));
}
/**
* Control a thing by sending a collection of {@link SetData} instructions.
*
* @param jid the thing to control.
* @param data a collection of {@link SetData} instructions.
* @return the {@link IoTSetResponse} if successful.
* @throws NoResponseException
* @throws XMPPErrorException
* @throws NotConnectedException
* @throws InterruptedException
*/
public IoTSetResponse setUsingIq(FullJid jid, Collection<SetData> data) throws NoResponseException, XMPPErrorException, NotConnectedException, InterruptedException {
IoTSetRequest request = new IoTSetRequest(data);
request.setTo(jid);
IoTSetResponse response = connection().createPacketCollectorAndSend(request).nextResultOrThrow();
return response;
}
/**
* Install a thing in the manager. Activates control functionality (if provided by the thing).
*
* @param thing the thing to install.
*/
public void installThing(Thing thing) {
things.put(thing.getNodeInfo(), thing);
}
public Thing uninstallThing(Thing thing) {
return uninstallThing(thing.getNodeInfo());
}
public Thing uninstallThing(NodeInfo nodeInfo) {
return things.remove(nodeInfo);
}
}

@ -0,0 +1,29 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control;
import java.util.Collection;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smackx.iot.control.element.SetData;
import org.jxmpp.jid.Jid;
public interface ThingControlRequest {
public void processRequest(Jid from, Collection<SetData> setData) throws XMPPErrorException;
}

@ -0,0 +1,23 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
public class Constants {
public static final String IOT_CONTROL_NAMESPACE = "urn:xmpp:iot:control";
}

@ -0,0 +1,48 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
import java.util.Collection;
import java.util.Collections;
import org.jivesoftware.smack.packet.IQ;
public class IoTSetRequest extends IQ {
public static final String ELEMENT = "set";
public static final String NAMESPACE = Constants.IOT_CONTROL_NAMESPACE;
private final Collection<SetData> setData;
public IoTSetRequest(Collection<SetData> setData) {
super(ELEMENT, NAMESPACE);
setType(Type.set);
this.setData = Collections.unmodifiableCollection(setData);
}
public Collection<SetData> getSetData() {
return setData;
}
@Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.rightAngleBracket();
xml.append(setData);
return xml;
}
}

@ -0,0 +1,41 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
import org.jivesoftware.smack.packet.IQ;
public class IoTSetResponse extends IQ {
public static final String ELEMENT = "setResponse";
public static final String NAMESPACE = Constants.IOT_CONTROL_NAMESPACE;
public IoTSetResponse() {
super(ELEMENT, NAMESPACE);
}
public IoTSetResponse(IoTSetRequest iotSetRequest) {
this();
initialzeAsResultFor(iotSetRequest);
}
@Override
protected IQChildElementXmlStringBuilder getIQChildElementBuilder(IQChildElementXmlStringBuilder xml) {
xml.setEmptyElement();
return xml;
}
}

@ -0,0 +1,38 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
public class SetBoolData extends SetData {
public SetBoolData(String name, boolean value) {
this(name, Boolean.toString(value));
booleanCache = value;
}
protected SetBoolData(String name, String value) {
super(name, Type.BOOL, value);
}
private Boolean booleanCache;
public Boolean getBooleanValue() {
if (booleanCache != null) {
booleanCache = Boolean.valueOf(getValue());
}
return booleanCache;
}
}

@ -0,0 +1,92 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
import java.util.Locale;
import org.jivesoftware.smack.packet.NamedElement;
import org.jivesoftware.smack.util.XmlStringBuilder;
public abstract class SetData implements NamedElement {
public enum Type {
BOOL,
INT,
LONG,
DOUBLE,
;
private String toStringCache;
private Type() {
toStringCache = this.name().toLowerCase(Locale.US);
}
@Override
public String toString() {
return toStringCache;
}
}
protected SetData(String name, Type type, String value) {
this.name = name;
this.type = type;
this.value = value;
}
private final String name;
private final Type type;
private final String value;
public final String getName() {
return name;
}
public final String getValue() {
return value;
}
public final Type getType() {
return type;
}
/**
* Returns the root element name.
*
* @return the element name.
*/
@Override
public final String getElementName() {
return getType().toString();
}
/**
* Returns the XML representation of this Element.
*
* @return the stanza(/packet) extension as XML.
*/
@Override
public final XmlStringBuilder toXML() {
XmlStringBuilder xml = new XmlStringBuilder(this);
xml.attribute("name", name);
xml.attribute("value", value);
xml.closeEmptyElement();
return xml;
}
}

@ -0,0 +1,38 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
public class SetDoubleData extends SetData {
public SetDoubleData(String name, double value) {
this(name, Double.toString(value));
doubleCache = value;
}
protected SetDoubleData(String name, String value) {
super(name, Type.DOUBLE, value);
}
private Double doubleCache;
public Double getDoubleValue() {
if (doubleCache != null) {
doubleCache = Double.valueOf(getValue());
}
return doubleCache;
}
}

@ -0,0 +1,38 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
public class SetIntData extends SetData {
public SetIntData(String name, int value) {
this(name, Integer.toString(value));
integerCache = value;
}
protected SetIntData(String name, String value) {
super(name, Type.INT, value);
}
private Integer integerCache;
public Integer getIntegerValue() {
if (integerCache != null) {
integerCache = Integer.valueOf(getValue());
}
return integerCache;
}
}

@ -0,0 +1,38 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.element;
public class SetLongData extends SetData {
public SetLongData(String name, long value) {
this(name, Long.toString(value));
longCache = value;
}
protected SetLongData(String name, String value) {
super(name, Type.LONG, value);
}
private Long longCache;
public Long getLongValue() {
if (longCache != null) {
longCache = Long.valueOf(getValue());
}
return longCache;
}
}

@ -0,0 +1,21 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Smack's API for XMPP IoT.
*/
package org.jivesoftware.smackx.iot.control.element;

@ -0,0 +1,21 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Smack's API for XMPP IoT.
*/
package org.jivesoftware.smackx.iot.control;

@ -0,0 +1,82 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.provider;
import java.util.ArrayList;
import java.util.List;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smackx.iot.control.element.IoTSetRequest;
import org.jivesoftware.smackx.iot.control.element.SetBoolData;
import org.jivesoftware.smackx.iot.control.element.SetData;
import org.jivesoftware.smackx.iot.control.element.SetDoubleData;
import org.jivesoftware.smackx.iot.control.element.SetIntData;
import org.jivesoftware.smackx.iot.control.element.SetLongData;
import org.xmlpull.v1.XmlPullParser;
public class IoTSetRequestProvider extends IQProvider<IoTSetRequest> {
@Override
public IoTSetRequest parse(XmlPullParser parser, int initialDepth) throws Exception {
List<SetData> data = new ArrayList<>(4);
outerloop: while (true) {
final int eventType = parser.next();
final String name = parser.getName();
switch (eventType) {
case XmlPullParser.START_TAG:
switch (name) {
case "bool": {
String valueName = parser.getAttributeValue(null, "name");
String valueString = parser.getAttributeValue(null, "value");
boolean value = Boolean.parseBoolean(valueString);
data.add(new SetBoolData(valueName, value));
}
break;
case "double": {
String valueName = parser.getAttributeValue(null, "name");
String valueString = parser.getAttributeValue(null, "value");
double value = Double.parseDouble(valueString);
data.add(new SetDoubleData(valueName, value));
}
break;
case "int": {
String valueName = parser.getAttributeValue(null, "name");
String valueString = parser.getAttributeValue(null, "value");
int value = Integer.parseInt(valueString);
data.add(new SetIntData(valueName, value));
}
break;
case "long": {
String valueName = parser.getAttributeValue(null, "name");
String valueString = parser.getAttributeValue(null, "value");
long value = Long.parseLong(valueString);
data.add(new SetLongData(valueName, value));
}
break;
}
break;
case XmlPullParser.END_TAG:
if (parser.getDepth() == initialDepth) {
break outerloop;
}
break;
}
}
return new IoTSetRequest(data);
}
}

@ -0,0 +1,30 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.control.provider;
import org.jivesoftware.smack.provider.IQProvider;
import org.jivesoftware.smackx.iot.control.element.IoTSetResponse;
import org.xmlpull.v1.XmlPullParser;
public class IoTSetResponseProvider extends IQProvider<IoTSetResponse> {
@Override
public IoTSetResponse parse(XmlPullParser parser, int initialDepth) throws Exception {
return new IoTSetResponse();
}
}

@ -0,0 +1,21 @@
/**
*
* Copyright © 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Smack's API for XMPP IoT.
*/
package org.jivesoftware.smackx.iot.control.provider;

@ -0,0 +1,210 @@
/**
*
* Copyright 2016 Florian Schmaus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.iot.data;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.WeakHashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jivesoftware.smack.ConnectionCreationListener;
import org.jivesoftware.smack.Manager;
import org.jivesoftware.smack.PacketCollector;
import org.jivesoftware.smack.SmackException.NoResponseException;
import org.jivesoftware.smack.SmackException.NotConnectedException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPConnectionRegistry;
import org.jivesoftware.smack.XMPPException.XMPPErrorException;
import org.jivesoftware.smack.filter.StanzaFilter;
import org.jivesoftware.smack.iqrequest.AbstractIqRequestHandler;
import org.jivesoftware.smack.iqrequest.IQRequestHandler.Mode;
import org.jivesoftware.smack.packet.IQ;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.iot.Thing;
import org.jivesoftware.smackx.iot.data.element.IoTDataField;
import org.jivesoftware.smackx.iot.data.element.IoTDataReadOutAccepted;
import org.jivesoftware.smackx.iot.data.element.IoTDataRequest;
import org.jivesoftware.smackx.iot.data.elemen