diff --git a/client/client-multi/client-java-core/pom.xml b/client/client-multi/client-java-core/pom.xml
index 0855f9ebbe..5eac3b8935 100644
--- a/client/client-multi/client-java-core/pom.xml
+++ b/client/client-multi/client-java-core/pom.xml
@@ -90,6 +90,16 @@
org.apache.avro
avro
+
+ org.eclipse.californium
+ californium-core
+ 2.0.0-M2
+
+
+ org.eclipse.californium
+ element-connector
+ 2.0.0-M2
+
diff --git a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java
index 2b683c3230..00db66904b 100644
--- a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java
+++ b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/TransportProtocolIdConstants.java
@@ -33,6 +33,13 @@ public class TransportProtocolIdConstants {
private static final int TCP_TRANSPORT_PROTOCOL_VERSION = 1;
public static final TransportProtocolId TCP_TRANSPORT_ID = new TransportProtocolId(
TCP_TRANSPORT_PROTOCOL_ID, TCP_TRANSPORT_PROTOCOL_VERSION);
+ private static final int COAP_TRANSPORT_PROTOCOL_ID = 0x0b5d1174;
+ private static final int COAP_TRANSPORT_PROTOCOL_VERSION = 1;
+ public static final TransportProtocolId COAP_TRANSPORT_ID = new TransportProtocolId(
+ COAP_TRANSPORT_PROTOCOL_ID, COAP_TRANSPORT_PROTOCOL_VERSION);
+
+
+
private TransportProtocolIdConstants() {
}
diff --git a/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java
new file mode 100644
index 0000000000..beae9e6665
--- /dev/null
+++ b/client/client-multi/client-java-core/src/main/java/org/kaaproject/kaa/client/channel/impl/channels/CoapChannel.java
@@ -0,0 +1,244 @@
+/*
+ *
+ * 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.kaaproject.kaa.client.channel.impl.channels;
+
+import org.eclipse.californium.core.CoapClient;
+import org.eclipse.californium.core.CoapResponse;
+import org.eclipse.californium.core.Utils;
+import org.eclipse.californium.core.coap.MediaTypeRegistry;
+import org.kaaproject.kaa.client.channel.ChannelDirection;
+import org.kaaproject.kaa.client.channel.IpTransportInfo;
+import org.kaaproject.kaa.client.channel.KaaDataChannel;
+import org.kaaproject.kaa.client.channel.KaaDataDemultiplexer;
+import org.kaaproject.kaa.client.channel.KaaDataMultiplexer;
+import org.kaaproject.kaa.client.channel.ServerType;
+import org.kaaproject.kaa.client.channel.TransportConnectionInfo;
+import org.kaaproject.kaa.client.channel.TransportProtocolId;
+import org.kaaproject.kaa.client.channel.TransportProtocolIdConstants;
+
+import org.kaaproject.kaa.client.channel.connectivity.ConnectivityChecker;
+import org.kaaproject.kaa.common.TransportType;
+import org.kaaproject.kaa.common.endpoint.security.MessageEncoderDecoder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+
+public class CoapChannel implements KaaDataChannel {
+
+ public static final Logger LOG = LoggerFactory // NOSONAR
+ .getLogger(CoapChannel.class);
+
+ private static final Map SUPPORTED_TYPES = new HashMap();
+
+ static {
+ SUPPORTED_TYPES.put(TransportType.PROFILE, ChannelDirection.BIDIRECTIONAL);
+ SUPPORTED_TYPES.put(TransportType.CONFIGURATION, ChannelDirection.BIDIRECTIONAL);
+ SUPPORTED_TYPES.put(TransportType.NOTIFICATION, ChannelDirection.BIDIRECTIONAL);
+ }
+
+ private static final String CHANNEL_ID = "default_coap_channel";
+ private KaaDataDemultiplexer demultiplexer;
+ private KaaDataMultiplexer multiplexer;
+ private IpTransportInfo currentServer;
+
+ @Override
+ public void sync(TransportType type) {
+ sync(Collections.singleton(type));
+ }
+
+ @Override
+ public void sync(Set types) {
+
+ if (multiplexer == null) {
+ LOG.warn("Can't sync. Channel {} multiplexer is not set", getId());
+ return;
+ }
+ if (demultiplexer == null) {
+ LOG.warn("Can't sync. Channel {} demultiplexer is not set", getId());
+ return;
+ }
+
+ Map typeMap = new HashMap<>(getSupportedTransportTypes().size());
+ for (TransportType type : types) {
+ LOG.info("Processing sync {} for channel [{}]", type, getId());
+ ChannelDirection direction = getSupportedTransportTypes().get(type);
+ if (direction != null) {
+ typeMap.put(type, direction);
+ } else {
+ LOG.error("Unsupported type {} for channel [{}]", type, getId());
+ }
+ for (Map.Entry typeIt : getSupportedTransportTypes().entrySet()) {
+ if (!typeIt.getKey().equals(type)) {
+ typeMap.put(typeIt.getKey(), ChannelDirection.DOWN);
+ }
+ }
+ }
+
+ }
+
+ @Override
+ public void syncAll() {
+ }
+
+ @Override
+ public void syncAck(TransportType type) {
+ LOG.info("Adding sync acknowledgement for type {} as a regular sync for channel [{}]", type, getId());
+ syncAck(Collections.singleton(type));
+ }
+
+ @Override
+ public void syncAck(Set type) {
+ }
+
+ @Override
+ public String getId() {
+ return CHANNEL_ID;
+ }
+
+ @Override
+ public TransportProtocolId getTransportProtocolId() {
+ return TransportProtocolIdConstants.COAP_TRANSPORT_ID;
+ }
+
+ @Override
+ public ServerType getServerType() {
+ return ServerType.OPERATIONS;
+ }
+
+ @Override
+ public void setDemultiplexer(KaaDataDemultiplexer demultiplexer) {
+ if (demultiplexer != null) {
+ this.demultiplexer = demultiplexer;
+ }
+ }
+
+ @Override
+ public void setMultiplexer(KaaDataMultiplexer multiplexer) {
+ if (multiplexer != null) {
+ this.multiplexer = multiplexer;
+ }
+ }
+
+ @Override
+ public void setServer(TransportConnectionInfo server) {
+
+ LOG.info("Setting server [{}] for channel [{}]", server, getId());
+ if (server == null) {
+ LOG.warn("Server is null for Channel [{}].", getId());
+ return;
+ }
+
+ IpTransportInfo oldServer = currentServer;
+ this.currentServer = new IpTransportInfo(server);
+
+ }
+
+ @Override
+ public TransportConnectionInfo getServer() {
+ return currentServer;
+
+ }
+
+ @Override
+ public void setConnectivityChecker(ConnectivityChecker checker) {
+ }
+
+ @Override
+ public Map getSupportedTransportTypes() {
+ return SUPPORTED_TYPES;
+ }
+
+ @Override
+ public void shutdown() {
+ }
+
+ @Override
+ public void pause() {
+ }
+
+ @Override
+ public void resume() {
+ }
+
+ /**
+ *
+ * @param myUri uri of source
+ * @param method CoAP method like POST,GET,...
+ * @param payload Message Payload
+ * @param msgType Confirmable or Non confirmable
+ * @return server response
+ */
+ public CoapResponse sendData(String myUri, String method, String payload, String msgType) {
+ LOG.info("this is SendData function!");
+ URI uri = null;
+
+ if (myUri != null) {
+ // input URI from command line arguments
+ try {
+ uri = new URI(myUri);
+ } catch (URISyntaxException exception) {
+ LOG.info("Invalid URI: " + exception.getMessage());
+ }
+
+ CoapClient client = new CoapClient(uri);
+ LOG.info(" new coap client is registerd");
+
+ CoapResponse response;
+
+ if (msgType == "NON") {
+ client.useNONs();
+ } else {
+ client.useCONs();
+ }
+
+ if (method == "post") {
+ response = client.post(payload, MediaTypeRegistry.TEXT_PLAIN);
+ } else {
+ response = client.get();
+ }
+
+ if (response != null) {
+
+ LOG.info(String.valueOf(response.getCode()));
+ LOG.info(String.valueOf(response.getOptions()));
+ LOG.info(response.getResponseText());
+
+ LOG.info("\nADVANCED\n");
+ // access advanced API with access to more details through .advanced()
+ LOG.info(Utils.prettyPrint(response));
+
+ } else {
+ LOG.info("No response received.");
+ }
+
+ return response;
+ } else {
+ // display help
+ LOG.info("Californium Client");
+ String simpleName = CoapChannel.class.getSimpleName();
+ LOG.info("Usage: " + simpleName + " URI");
+ LOG.info("URI: The CoAP URI of the remote resource to GET");
+ return null;
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index a99bcca2e9..6ee5943bed 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1439,5 +1439,10 @@ Copyright 2014-2016 CyberVision, Inc.
repository.kaaproject.snapshots
http://repository.kaaproject.org/repository/snapshots/
+
+ repo.eclipse.org
+ Californium Repository
+ https://repo.eclipse.org/content/repositories/californium/
+
diff --git a/server/node/pom.xml b/server/node/pom.xml
index c8862fbbd0..aa6ee86c22 100644
--- a/server/node/pom.xml
+++ b/server/node/pom.xml
@@ -101,6 +101,20 @@
config
tcp
+
+
+ org.kaaproject.kaa.server.transports.coap
+ transport
+ 0.11.0-SNAPSHOT
+ coap
+
+
+ org.kaaproject.kaa.server.transports.coap
+ config
+ 0.11.0-SNAPSHOT
+ coap
+
+
org.kaaproject.kaa.server.common
log-shared
diff --git a/server/transports/coap/config/pom.xml b/server/transports/coap/config/pom.xml
new file mode 100644
index 0000000000..ea0ec310f6
--- /dev/null
+++ b/server/transports/coap/config/pom.xml
@@ -0,0 +1,97 @@
+
+
+
+ 4.0.0
+
+ org.kaaproject.kaa.server.transports
+ 0.11.0-SNAPSHOT
+ coap
+
+ org.kaaproject.kaa.server.transports.coap
+ config
+ jar
+
+ Kaa HTTP Transport Config
+ http://kaaproject.org
+
+
+ UTF-8
+ ${basedir}/../../../..
+
+
+
+
+ org.kaaproject.kaa.server.common
+ transport-shared
+
+
+ org.kaaproject.kaa.server.common
+ utils
+
+
+ org.slf4j
+ slf4j-api
+
+
+ org.slf4j
+ log4j-over-slf4j
+
+
+ ch.qos.logback
+ logback-core
+
+
+ ch.qos.logback
+ logback-classic
+
+
+
+
+
+
+ org.apache.avro
+ avro-maven-plugin
+ ${avro.version}
+
+
+ generate-sources
+
+ schema
+
+
+ String
+ ${project.basedir}/src/main/avro/
+ ${project.basedir}/src/main/java/
+ PRIVATE
+
+ *.avsc
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+ coap
+
+
+
+
+
\ No newline at end of file
diff --git a/server/transports/coap/config/src/main/avro/coap.avsc b/server/transports/coap/config/src/main/avro/coap.avsc
new file mode 100644
index 0000000000..8cad291a6b
--- /dev/null
+++ b/server/transports/coap/config/src/main/avro/coap.avsc
@@ -0,0 +1,12 @@
+{
+ "namespace": "org.kaaproject.kaa.server.transport.coap.config.gen",
+ "type": "record",
+ "name": "AvroCoapConfig",
+ "fields": [
+ {"name": "bindInterface", "type": "string"},
+ {"name": "bindPort", "type": "int"},
+ {"name": "publicInterface", "type": "string"},
+ {"name": "publicPort", "type": "int"},
+ {"name": "maxBodySize", "type": "int"}
+ ]
+}
\ No newline at end of file
diff --git a/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java
new file mode 100644
index 0000000000..bbf487de51
--- /dev/null
+++ b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/CoapTransportConfig.java
@@ -0,0 +1,94 @@
+/*
+ *
+ * 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.kaaproject.kaa.server.transport.coap.config;
+
+import org.apache.avro.Schema;
+import org.kaaproject.kaa.server.common.utils.Crc32Util;
+import org.kaaproject.kaa.server.transport.KaaTransportConfig;
+import org.kaaproject.kaa.server.transport.Transport;
+import org.kaaproject.kaa.server.transport.TransportConfig;
+import org.kaaproject.kaa.server.transport.TransportService;
+import org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig;
+
+
+/**
+ * All-args constructor.
+ */
+@KaaTransportConfig
+public class CoapTransportConfig implements TransportConfig {
+
+ private static final String COAP_TRANSPORT_NAME = "org.kaaproject.kaa.server.transport.coap";
+ private static final int COAP_TRANSPORT_ID = Crc32Util.crc32(COAP_TRANSPORT_NAME);
+ private static final String COAP_TRANSPORT_CLASS = "org.kaaproject.kaa.server.transports.coap.transport.CoapTransport";
+ private static final String COAP_TRANSPORT_CONFIG = "coap-transport.config";
+
+ public CoapTransportConfig() {
+ super();
+ }
+
+ /**
+ * Returns the transport id. The transport id must be unique.
+ *
+ * @return the transport id
+ */
+ @Override
+ public int getId() {
+ return COAP_TRANSPORT_ID;
+ }
+
+ /**
+ * Returns the transport name. There is no strict rule for this
+ * name to be unique.
+ *
+ * @return the transport name
+ */
+ @Override
+ public String getName() {
+ return COAP_TRANSPORT_NAME;
+ }
+
+ /**
+ * Returns the class name of the {@link Transport} implementation.
+ *
+ * @return the class name of the {@link Transport} implementation
+ */
+ @Override
+ public String getTransportClass() {
+ return COAP_TRANSPORT_CLASS;
+ }
+
+ /**
+ * Returns the avro schema of the {@link Transport} configuration.
+ *
+ * @return the avro schema of the {@link Transport} configuration
+ */
+ @Override
+ public Schema getConfigSchema() {
+ return AvroCoapConfig.getClassSchema();
+ }
+
+ /**
+ * Returns the configuration file name. This configuration file may
+ * be used by {@link TransportService} to initialize and configure
+ * the corresponding {@link Transport}.
+ *
+ * @return the configuration file name
+ */
+ @Override
+ public String getConfigFileName() {
+ return COAP_TRANSPORT_CONFIG;
+ }
+}
\ No newline at end of file
diff --git a/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java
new file mode 100644
index 0000000000..5c7905bc9c
--- /dev/null
+++ b/server/transports/coap/config/src/main/java/org/kaaproject/kaa/server/transport/coap/config/gen/AvroCoapConfig.java
@@ -0,0 +1,355 @@
+/**
+ * Autogenerated by Avro
+ *
+ * DO NOT EDIT DIRECTLY
+ */
+package org.kaaproject.kaa.server.transport.coap.config.gen;
+@SuppressWarnings("all")
+@org.apache.avro.specific.AvroGenerated
+public class AvroCoapConfig extends org.apache.avro.specific.SpecificRecordBase implements org.apache.avro.specific.SpecificRecord {
+ public static final org.apache.avro.Schema SCHEMA$ = new org.apache.avro.Schema.Parser().parse("{\"type\":\"record\",\"name\":\"AvroCoapConfig\",\"namespace\":\"org.kaaproject.kaa.server.transport.coap.config.gen\",\"fields\":[{\"name\":\"bindInterface\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"bindPort\",\"type\":\"int\"},{\"name\":\"publicInterface\",\"type\":{\"type\":\"string\",\"avro.java.string\":\"String\"}},{\"name\":\"publicPort\",\"type\":\"int\"},{\"name\":\"maxBodySize\",\"type\":\"int\"}]}");
+ public static org.apache.avro.Schema getClassSchema() { return SCHEMA$; }
+ private java.lang.String bindInterface;
+ private int bindPort;
+ private java.lang.String publicInterface;
+ private int publicPort;
+ private int maxBodySize;
+
+ /**
+ * Default constructor. Note that this does not initialize fields
+ * to their default values from the schema. If that is desired then
+ * one should use {@link \#newBuilder()}.
+ */
+ public AvroCoapConfig() {}
+
+ /**
+ * All-args constructor.
+ */
+ public AvroCoapConfig(java.lang.String bindInterface, java.lang.Integer bindPort, java.lang.String publicInterface, java.lang.Integer publicPort, java.lang.Integer maxBodySize) {
+ this.bindInterface = bindInterface;
+ this.bindPort = bindPort;
+ this.publicInterface = publicInterface;
+ this.publicPort = publicPort;
+ this.maxBodySize = maxBodySize;
+ }
+
+ public org.apache.avro.Schema getSchema() { return SCHEMA$; }
+ // Used by DatumWriter. Applications should not call.
+ public java.lang.Object get(int field$) {
+ switch (field$) {
+ case 0: return bindInterface;
+ case 1: return bindPort;
+ case 2: return publicInterface;
+ case 3: return publicPort;
+ case 4: return maxBodySize;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+ // Used by DatumReader. Applications should not call.
+ @SuppressWarnings(value="unchecked")
+ public void put(int field$, java.lang.Object value$) {
+ switch (field$) {
+ case 0: bindInterface = (java.lang.String)value$; break;
+ case 1: bindPort = (java.lang.Integer)value$; break;
+ case 2: publicInterface = (java.lang.String)value$; break;
+ case 3: publicPort = (java.lang.Integer)value$; break;
+ case 4: maxBodySize = (java.lang.Integer)value$; break;
+ default: throw new org.apache.avro.AvroRuntimeException("Bad index");
+ }
+ }
+
+ /**
+ * Gets the value of the 'bindInterface' field.
+ */
+ public java.lang.String getBindInterface() {
+ return bindInterface;
+ }
+
+ /**
+ * Sets the value of the 'bindInterface' field.
+ * @param value the value to set.
+ */
+ public void setBindInterface(java.lang.String value) {
+ this.bindInterface = value;
+ }
+
+ /**
+ * Gets the value of the 'bindPort' field.
+ */
+ public java.lang.Integer getBindPort() {
+ return bindPort;
+ }
+
+ /**
+ * Sets the value of the 'bindPort' field.
+ * @param value the value to set.
+ */
+ public void setBindPort(java.lang.Integer value) {
+ this.bindPort = value;
+ }
+
+ /**
+ * Gets the value of the 'publicInterface' field.
+ */
+ public java.lang.String getPublicInterface() {
+ return publicInterface;
+ }
+
+ /**
+ * Sets the value of the 'publicInterface' field.
+ * @param value the value to set.
+ */
+ public void setPublicInterface(java.lang.String value) {
+ this.publicInterface = value;
+ }
+
+ /**
+ * Gets the value of the 'publicPort' field.
+ */
+ public java.lang.Integer getPublicPort() {
+ return publicPort;
+ }
+
+ /**
+ * Sets the value of the 'publicPort' field.
+ * @param value the value to set.
+ */
+ public void setPublicPort(java.lang.Integer value) {
+ this.publicPort = value;
+ }
+
+ /**
+ * Gets the value of the 'maxBodySize' field.
+ */
+ public java.lang.Integer getMaxBodySize() {
+ return maxBodySize;
+ }
+
+ /**
+ * Sets the value of the 'maxBodySize' field.
+ * @param value the value to set.
+ */
+ public void setMaxBodySize(java.lang.Integer value) {
+ this.maxBodySize = value;
+ }
+
+ /** Creates a new AvroCoapConfig RecordBuilder */
+ public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder() {
+ return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder();
+ }
+
+ /** Creates a new AvroCoapConfig RecordBuilder by copying an existing Builder */
+ public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder other) {
+ return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder(other);
+ }
+
+ /** Creates a new AvroCoapConfig RecordBuilder by copying an existing AvroCoapConfig instance */
+ public static org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder newBuilder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig other) {
+ return new org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder(other);
+ }
+
+ /**
+ * RecordBuilder for AvroCoapConfig instances.
+ */
+ public static class Builder extends org.apache.avro.specific.SpecificRecordBuilderBase
+ implements org.apache.avro.data.RecordBuilder {
+
+ private java.lang.String bindInterface;
+ private int bindPort;
+ private java.lang.String publicInterface;
+ private int publicPort;
+ private int maxBodySize;
+
+ /** Creates a new Builder */
+ private Builder() {
+ super(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.SCHEMA$);
+ }
+
+ /** Creates a Builder by copying an existing Builder */
+ private Builder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder other) {
+ super(other);
+ if (isValidValue(fields()[0], other.bindInterface)) {
+ this.bindInterface = data().deepCopy(fields()[0].schema(), other.bindInterface);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.bindPort)) {
+ this.bindPort = data().deepCopy(fields()[1].schema(), other.bindPort);
+ fieldSetFlags()[1] = true;
+ }
+ if (isValidValue(fields()[2], other.publicInterface)) {
+ this.publicInterface = data().deepCopy(fields()[2].schema(), other.publicInterface);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.publicPort)) {
+ this.publicPort = data().deepCopy(fields()[3].schema(), other.publicPort);
+ fieldSetFlags()[3] = true;
+ }
+ if (isValidValue(fields()[4], other.maxBodySize)) {
+ this.maxBodySize = data().deepCopy(fields()[4].schema(), other.maxBodySize);
+ fieldSetFlags()[4] = true;
+ }
+ }
+
+ /** Creates a Builder by copying an existing AvroCoapConfig instance */
+ private Builder(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig other) {
+ super(org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.SCHEMA$);
+ if (isValidValue(fields()[0], other.bindInterface)) {
+ this.bindInterface = data().deepCopy(fields()[0].schema(), other.bindInterface);
+ fieldSetFlags()[0] = true;
+ }
+ if (isValidValue(fields()[1], other.bindPort)) {
+ this.bindPort = data().deepCopy(fields()[1].schema(), other.bindPort);
+ fieldSetFlags()[1] = true;
+ }
+ if (isValidValue(fields()[2], other.publicInterface)) {
+ this.publicInterface = data().deepCopy(fields()[2].schema(), other.publicInterface);
+ fieldSetFlags()[2] = true;
+ }
+ if (isValidValue(fields()[3], other.publicPort)) {
+ this.publicPort = data().deepCopy(fields()[3].schema(), other.publicPort);
+ fieldSetFlags()[3] = true;
+ }
+ if (isValidValue(fields()[4], other.maxBodySize)) {
+ this.maxBodySize = data().deepCopy(fields()[4].schema(), other.maxBodySize);
+ fieldSetFlags()[4] = true;
+ }
+ }
+
+ /** Gets the value of the 'bindInterface' field */
+ public java.lang.String getBindInterface() {
+ return bindInterface;
+ }
+
+ /** Sets the value of the 'bindInterface' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setBindInterface(java.lang.String value) {
+ validate(fields()[0], value);
+ this.bindInterface = value;
+ fieldSetFlags()[0] = true;
+ return this;
+ }
+
+ /** Checks whether the 'bindInterface' field has been set */
+ public boolean hasBindInterface() {
+ return fieldSetFlags()[0];
+ }
+
+ /** Clears the value of the 'bindInterface' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearBindInterface() {
+ bindInterface = null;
+ fieldSetFlags()[0] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'bindPort' field */
+ public java.lang.Integer getBindPort() {
+ return bindPort;
+ }
+
+ /** Sets the value of the 'bindPort' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setBindPort(int value) {
+ validate(fields()[1], value);
+ this.bindPort = value;
+ fieldSetFlags()[1] = true;
+ return this;
+ }
+
+ /** Checks whether the 'bindPort' field has been set */
+ public boolean hasBindPort() {
+ return fieldSetFlags()[1];
+ }
+
+ /** Clears the value of the 'bindPort' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearBindPort() {
+ fieldSetFlags()[1] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'publicInterface' field */
+ public java.lang.String getPublicInterface() {
+ return publicInterface;
+ }
+
+ /** Sets the value of the 'publicInterface' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setPublicInterface(java.lang.String value) {
+ validate(fields()[2], value);
+ this.publicInterface = value;
+ fieldSetFlags()[2] = true;
+ return this;
+ }
+
+ /** Checks whether the 'publicInterface' field has been set */
+ public boolean hasPublicInterface() {
+ return fieldSetFlags()[2];
+ }
+
+ /** Clears the value of the 'publicInterface' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearPublicInterface() {
+ publicInterface = null;
+ fieldSetFlags()[2] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'publicPort' field */
+ public java.lang.Integer getPublicPort() {
+ return publicPort;
+ }
+
+ /** Sets the value of the 'publicPort' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setPublicPort(int value) {
+ validate(fields()[3], value);
+ this.publicPort = value;
+ fieldSetFlags()[3] = true;
+ return this;
+ }
+
+ /** Checks whether the 'publicPort' field has been set */
+ public boolean hasPublicPort() {
+ return fieldSetFlags()[3];
+ }
+
+ /** Clears the value of the 'publicPort' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearPublicPort() {
+ fieldSetFlags()[3] = false;
+ return this;
+ }
+
+ /** Gets the value of the 'maxBodySize' field */
+ public java.lang.Integer getMaxBodySize() {
+ return maxBodySize;
+ }
+
+ /** Sets the value of the 'maxBodySize' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder setMaxBodySize(int value) {
+ validate(fields()[4], value);
+ this.maxBodySize = value;
+ fieldSetFlags()[4] = true;
+ return this;
+ }
+
+ /** Checks whether the 'maxBodySize' field has been set */
+ public boolean hasMaxBodySize() {
+ return fieldSetFlags()[4];
+ }
+
+ /** Clears the value of the 'maxBodySize' field */
+ public org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig.Builder clearMaxBodySize() {
+ fieldSetFlags()[4] = false;
+ return this;
+ }
+
+ @Override
+ public AvroCoapConfig build() {
+ try {
+ AvroCoapConfig record = new AvroCoapConfig();
+ record.bindInterface = fieldSetFlags()[0] ? this.bindInterface : (java.lang.String) defaultValue(fields()[0]);
+ record.bindPort = fieldSetFlags()[1] ? this.bindPort : (java.lang.Integer) defaultValue(fields()[1]);
+ record.publicInterface = fieldSetFlags()[2] ? this.publicInterface : (java.lang.String) defaultValue(fields()[2]);
+ record.publicPort = fieldSetFlags()[3] ? this.publicPort : (java.lang.Integer) defaultValue(fields()[3]);
+ record.maxBodySize = fieldSetFlags()[4] ? this.maxBodySize : (java.lang.Integer) defaultValue(fields()[4]);
+ return record;
+ } catch (Exception e) {
+ throw new org.apache.avro.AvroRuntimeException(e);
+ }
+ }
+ }
+}
diff --git a/server/transports/coap/pom.xml b/server/transports/coap/pom.xml
new file mode 100644
index 0000000000..b69684181a
--- /dev/null
+++ b/server/transports/coap/pom.xml
@@ -0,0 +1,47 @@
+
+
+ 4.0.0
+
+
+ org.kaaproject.kaa.server
+ 0.11.0-SNAPSHOT
+ transports
+
+
+ org.kaaproject.kaa.server.transports
+ coap
+ 0.11.0-SNAPSHOT
+ pom
+
+
+ Kaa CoAP Transport
+ http://kaaproject.org
+
+
+ UTF-8
+ /kaa
+
+
+
+ config
+ transport
+
+
+
+
+
\ No newline at end of file
diff --git a/server/transports/coap/transport/pom.xml b/server/transports/coap/transport/pom.xml
new file mode 100644
index 0000000000..7db662cbcc
--- /dev/null
+++ b/server/transports/coap/transport/pom.xml
@@ -0,0 +1,102 @@
+
+
+
+ 4.0.0
+
+ org.kaaproject.kaa.server.transports
+ 0.11.0-SNAPSHOT
+ coap
+
+ org.kaaproject.kaa.server.transports.coap
+ transport
+ jar
+
+ Kaa CoAP Transports Implementation
+ http://kaaproject.org
+
+
+ UTF-8
+ /kaa
+
+
+
+ repo.eclipse.org
+ Californium Repository
+ https://repo.eclipse.org/content/repositories/californium/
+
+
+
+
+
+ org.kaaproject.kaa.server.common
+ transport-shared
+
+
+ org.kaaproject.kaa.server.common
+ netty-server
+
+
+ org.kaaproject.kaa.server.transports.coap
+ config
+ 0.11.0-SNAPSHOT
+ coap
+
+
+ commons-codec
+ commons-codec
+
+
+ junit
+ junit
+ test
+
+
+ org.mockito
+ mockito-all
+ test
+
+
+ org.springframework
+ spring-test
+
+
+
+ org.eclipse.californium
+ californium-core
+ 2.0.0-M2
+
+
+ org.eclipse.californium
+ element-connector
+ 2.0.0-M2
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+ coap
+
+
+
+
+
diff --git a/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java
new file mode 100644
index 0000000000..34cc737bbd
--- /dev/null
+++ b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapHandler.java
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.kaaproject.kaa.server.transports.coap.transport;
+
+import org.eclipse.californium.core.CoapResource;
+import org.eclipse.californium.core.CoapServer;
+import org.eclipse.californium.core.network.CoapEndpoint;
+import org.eclipse.californium.core.network.EndpointManager;
+import org.eclipse.californium.core.network.config.NetworkConfig;
+import org.eclipse.californium.core.server.resources.CoapExchange;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.SocketException;
+
+public class CoapHandler extends CoapServer {
+
+ private static int COAP_PORT = NetworkConfig.getStandard().getInt(NetworkConfig.Keys.COAP_PORT);
+ private static final Logger LOG = LoggerFactory.getLogger(CoapHandler.class);
+
+ /**
+ * Add individual endpoints listening on default CoAP port on all IPv4 addresses of all network interfaces.
+ */
+ private void addEndpoints() {
+ for (InetAddress addr : EndpointManager.getEndpointManager().getNetworkInterfaces()) {
+ // only binds to IPv4 addresses and localhost
+ if (addr instanceof Inet4Address || addr.isLoopbackAddress()) {
+ InetSocketAddress bindToAddress = new InetSocketAddress(addr, COAP_PORT);
+ addEndpoint(new CoapEndpoint(bindToAddress));
+ }
+ }
+ }
+
+ /**
+ * Handler add endpoints and resources.
+ * @param port listen port of CoAP server
+ * @throws SocketException socket exception
+ */
+ public CoapHandler(int port) throws SocketException {
+ // provide an instance of a Hello-World resource
+ add(new HelloWorldResource());
+ COAP_PORT = port;
+ addEndpoints();
+ LOG.info("New Resource and endpoints added.");
+ }
+
+ /*
+ * Definition of the Hello-World Resource
+ */
+ class HelloWorldResource extends CoapResource {
+
+ public HelloWorldResource() {
+
+ // set resource identifier
+ super("kaaCoAP");
+
+ // set display name
+ getAttributes().setTitle("Kaa-Coap Resource");
+ LOG.info("Resource identifier and display name is set.");
+
+
+ }
+
+
+ @Override
+ public void handleGET(CoapExchange exchange) {
+ //sample respond to the request is like this:
+
+ // exchange.respond("Hello World! This is a response from Kaa Coap Server!");
+ LOG.info("GET method handler.");
+
+ }
+
+
+ @Override
+ public void handlePOST(CoapExchange exchange) {
+
+ //sample respond to the request is like this:
+
+ // exchange.respond("Hello World! This is a response from Kaa Coap Server!");
+ LOG.info("POST method handler.");
+
+
+ }
+ }
+
+}
diff --git a/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java
new file mode 100644
index 0000000000..ce4c67a107
--- /dev/null
+++ b/server/transports/coap/transport/src/main/java/org/kaaproject/kaa/server/transports/coap/transport/CoapTransport.java
@@ -0,0 +1,138 @@
+/*
+ *
+ * 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.kaaproject.kaa.server.transports.coap.transport;
+
+import org.kaaproject.kaa.server.transport.AbstractKaaTransport;
+import org.kaaproject.kaa.server.transport.SpecificTransportContext;
+import org.kaaproject.kaa.server.transport.TransportLifecycleException;
+import org.kaaproject.kaa.server.transport.coap.config.gen.AvroCoapConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+
+public class CoapTransport extends AbstractKaaTransport {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CoapTransport.class);
+ private static final int SUPPORTED_VERSION = 1;
+
+ private CoapHandler server;
+
+ /**
+ * Initialize a transport instance with a particular configuration and
+ * common transport properties that are accessible via the context. The configuration is an Avro
+ * object. The serializaion/deserialization is done using the schema specified in
+ * {@link org.kaaproject.kaa.server.transport.KaaTransportConfig}.
+ * @param context the transport initialization context
+ * @throws TransportLifecycleException is socket exception.
+ */
+ @Override
+ protected void init(SpecificTransportContext context) throws TransportLifecycleException {
+
+ AvroCoapConfig configuration = context.getConfiguration();
+ configuration.setBindInterface(replaceProperty(configuration.getBindInterface(), BIND_INTERFACE_PROP_NAME, context
+ .getCommonProperties().getProperty(BIND_INTERFACE_PROP_NAME, LOCALHOST)));
+ configuration.setPublicInterface(replaceProperty(configuration.getPublicInterface(), PUBLIC_INTERFACE_PROP_NAME, context
+ .getCommonProperties().getProperty(PUBLIC_INTERFACE_PROP_NAME, LOCALHOST)));
+
+
+ try {
+ // create server
+ server = new CoapHandler(configuration.getBindPort());
+
+
+
+ } catch (SocketException exception) {
+ System.err.println("Failed to initialize server: " + exception.getMessage());
+ }
+
+ }
+
+ /**
+ * Starts a transport instance. This method should block its caller thread
+ * until the transport is started. This method should not block its caller
+ * thread after the startup sequence is successfully completed.
+ */
+ @Override
+ public void start() {
+
+ LOG.info("CoAP server is going to start");
+ server.start();
+ LOG.info("CoAP server is started!");
+
+ }
+
+ /**
+ * Stops the transport instance. This method should block its current thread
+ * until the transport is stopped. The transport may be started again after it is
+ * stopped.
+ */
+ @Override
+ public void stop() {
+
+
+ LOG.info("CoAP server is going to stop");
+ server.stop();
+
+ LOG.info("CoAP server is stopped");
+
+ }
+
+ /**
+ * Returns a min version of the transport protocol that is supported by this transport.
+ * Useful when a single transport instance needs to support multiple versions of the client protocol implementations.
+ */
+ @Override
+ protected int getMinSupportedVersion() {
+ return SUPPORTED_VERSION;
+ }
+
+ /**
+ * Returns a max version of the transport protocol that is supported by this transport.
+ * Useful when a single transport instance needs to support multiple versions of the client protocol implementations.
+ */
+ @Override
+ protected int getMaxSupportedVersion() {
+ return SUPPORTED_VERSION;
+ }
+
+ @Override
+ public Class getConfigurationClass() {
+ return AvroCoapConfig.class;
+ }
+
+ @Override
+ protected List getSerializedConnectionInfoList() {
+ byte[] interfaceData = toUtf8Bytes(context.getConfiguration().getPublicInterface());
+ byte[] publicKeyData = context.getServerKey().getEncoded();
+ ByteBuffer buf = ByteBuffer.wrap(
+ new byte[SIZE_OF_INT * 3 + interfaceData.length + publicKeyData.length]);
+ buf.putInt(publicKeyData.length);
+ buf.put(publicKeyData);
+ buf.putInt(interfaceData.length);
+ buf.put(interfaceData);
+ buf.putInt(context.getConfiguration().getPublicPort());
+ List connectionInfoList = new ArrayList<>();
+ connectionInfoList.add(buf.array());
+
+ return connectionInfoList;
+ }
+
+
+}
\ No newline at end of file
diff --git a/server/transports/pom.xml b/server/transports/pom.xml
index d12fc9c2bd..74d1f699d1 100644
--- a/server/transports/pom.xml
+++ b/server/transports/pom.xml
@@ -36,5 +36,6 @@
http
tcp
+ coap