mirror of
https://github.com/vanitasvitae/Smack.git
synced 2024-12-06 19:02:07 +01:00
Add (partial) support for IoT XEPs
That is XEP-0323, -0324, -0325, and -0347. SMACK-727.
This commit is contained in:
parent
d1fe5c2933
commit
b91978dcc4
110 changed files with 5395 additions and 40 deletions
|
@ -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. |
|
||||
|
||||
|
|
116
documentation/extensions/iot.md
Normal file
116
documentation/extensions/iot.md
Normal file
|
@ -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
|
||||
|