Skip to content

Commit

Permalink
Experimental add coap over tcp support
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Nov 15, 2022
1 parent a325a69 commit fcea497
Show file tree
Hide file tree
Showing 10 changed files with 353 additions and 4 deletions.
4 changes: 4 additions & 0 deletions leshan-client-cf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Contributors:
<groupId>org.eclipse.californium</groupId>
<artifactId>scandium</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector-tcp-netty</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>cf-oscore</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2022 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.client.californium.endpoint.coaptcp;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.security.cert.Certificate;
import java.util.List;

import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.californium.elements.Connector;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.elements.tcp.netty.TcpClientConnector;
import org.eclipse.leshan.client.californium.CaliforniumConnectionController;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpointFactory;
import org.eclipse.leshan.client.endpoint.ClientEndpointToolbox;
import org.eclipse.leshan.client.servers.ServerIdentity;
import org.eclipse.leshan.client.servers.ServerInfo;
import org.eclipse.leshan.core.californium.DefaultExceptionTranslator;
import org.eclipse.leshan.core.californium.ExceptionTranslator;
import org.eclipse.leshan.core.californium.identity.DefaultCoapIdentityHandler;
import org.eclipse.leshan.core.californium.identity.IdentityHandler;
import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
import org.eclipse.leshan.core.endpoint.Protocol;

public class CoapTcpClientEndpointFactory implements CaliforniumClientEndpointFactory {

protected final String loggingTagPrefix;

public CoapTcpClientEndpointFactory() {
this("LWM2M Client");
}

public CoapTcpClientEndpointFactory(String loggingTagPrefix) {
this.loggingTagPrefix = loggingTagPrefix;
}

@Override
public Protocol getProtocol() {
return Protocol.COAP_TCP;
}

protected String getLoggingTag(URI uri) {
if (loggingTagPrefix != null) {
return String.format("[%s-%s]", loggingTagPrefix, uri);
} else {
return String.format("[%s-%s]", uri);
}
}

@Override
public Endpoint createCoapEndpoint(InetAddress clientAddress, Configuration defaultConfiguration,
ServerInfo serverInfo, boolean clientInitiatedOnly, List<Certificate> trustStore,
ClientEndpointToolbox toolbox) {
return createEndpointBuilder(new InetSocketAddress(clientAddress, 0), serverInfo, defaultConfiguration).build();
}

protected CoapEndpoint.Builder createEndpointBuilder(InetSocketAddress address, ServerInfo serverInfo,
Configuration coapConfig) {
CoapEndpoint.Builder builder = new CoapEndpoint.Builder();
builder.setConnector(createConnector(address, coapConfig));
builder.setConfiguration(coapConfig);
builder.setLoggingTag(getLoggingTag(EndpointUriUtil.createUri(getProtocol().getUriScheme(), address)));
return builder;
}

protected Connector createConnector(InetSocketAddress address, Configuration coapConfig) {
return new TcpClientConnector(coapConfig);
}

@Override
public IdentityHandler createIdentityHandler() {
// TODO TCP : maybe we need a more specific one
return new DefaultCoapIdentityHandler();
}

@Override
public ExceptionTranslator createExceptionTranslator() {
// TODO TCP : don't know if there is TCP specific error to handle
return new DefaultExceptionTranslator();
}

@Override
public CaliforniumConnectionController createConnectionController() {
return new CaliforniumConnectionController() {
@Override
public void forceReconnection(Endpoint endpoint, ServerIdentity identity, boolean resume) {
// TODO TCP : don't know if you need to implement this for TCP
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*******************************************************************************
* Copyright (c) 2022 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.client.californium.endpoint.coaptcp;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.eclipse.californium.core.config.CoapConfig;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
import org.eclipse.californium.elements.config.SystemConfig;
import org.eclipse.californium.elements.config.TcpConfig;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpointFactory;
import org.eclipse.leshan.client.californium.endpoint.ClientProtocolProvider;
import org.eclipse.leshan.core.endpoint.Protocol;

public class CoapTcpClientProtocolProvider implements ClientProtocolProvider {

@Override
public Protocol getProtocol() {
return Protocol.COAP_TCP;
}

@Override
public void applyDefaultValue(Configuration configuration) {
configuration.set(CoapConfig.MAX_ACTIVE_PEERS, 10);
configuration.set(CoapConfig.PROTOCOL_STAGE_THREAD_COUNT, 1);
configuration.set(TcpConfig.TCP_CONNECTION_IDLE_TIMEOUT, 0, TimeUnit.SECONDS);
}

@Override
public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, TcpConfig.DEFINITIONS);
}

@Override
public CaliforniumClientEndpointFactory createDefaultEndpointFactory() {
return new CoapTcpClientEndpointFactory();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import org.eclipse.leshan.client.californium.endpoint.coap.CoapOscoreProtocolProvider;
import org.eclipse.leshan.client.californium.endpoint.coaps.CoapsClientEndpointFactory;
import org.eclipse.leshan.client.californium.endpoint.coaps.CoapsClientProtocolProvider;
import org.eclipse.leshan.client.californium.endpoint.coaptcp.CoapTcpClientProtocolProvider;
import org.eclipse.leshan.client.demo.cli.LeshanClientDemoCLI;
import org.eclipse.leshan.client.demo.cli.interactive.InteractiveCommands;
import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory;
Expand Down Expand Up @@ -254,7 +255,7 @@ protected DtlsConnectorConfig.Builder createDtlsConnectorConfigBuilder(
};

CaliforniumClientEndpointsProvider.Builder endpointsBuilder = new CaliforniumClientEndpointsProvider.Builder(
new CoapOscoreProtocolProvider(), customCoapsProtocolProvider);
new CoapOscoreProtocolProvider(), customCoapsProtocolProvider, new CoapTcpClientProtocolProvider());

// Create Californium Configuration
Configuration clientCoapConfig = endpointsBuilder.createDefaultConfiguration();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ public void run() {
int indexOf = main.url.indexOf("://");
String scheme = main.url.substring(0, indexOf);
// we support only coap and coaps
if (!"coap".equals(scheme) && !"coaps".equals(scheme)) {
if (!"coap".equals(scheme) && !"coaps".equals(scheme) && !"coap+tcp".equals(scheme)) {
throw new MultiParameterException(spec.commandLine(),
String.format("Invalid URL %s : unknown scheme '%s', we support only 'coap' or 'coaps' for now",
main.url, scheme),
Expand All @@ -310,7 +310,7 @@ public void run() {
main.url, scheme), "-u");
}
} else {
if (!scheme.equals("coap")) {
if (!scheme.equals("coap") && !scheme.equals("coap+tcp")) {
throw new MultiParameterException(spec.commandLine(), String.format(
"Invalid URL %s : '%s' scheme must be used with PSK, RPK or x509 option. Do you mean 'coap' ? ",
main.url, scheme), "-u");
Expand Down
4 changes: 4 additions & 0 deletions leshan-server-cf/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Contributors:
<groupId>org.eclipse.californium</groupId>
<artifactId>scandium</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector-tcp-netty</artifactId>
</dependency>

<!-- test dependencies -->
<dependency>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*******************************************************************************
* Copyright (c) 2022 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.server.californium.endpoint.coaptcp;

import java.net.InetSocketAddress;
import java.net.URI;

import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.serialization.TcpDataParser;
import org.eclipse.californium.core.network.serialization.TcpDataSerializer;
import org.eclipse.californium.elements.Connector;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.elements.tcp.netty.TcpServerConnector;
import org.eclipse.leshan.core.californium.DefaultExceptionTranslator;
import org.eclipse.leshan.core.californium.ExceptionTranslator;
import org.eclipse.leshan.core.californium.identity.DefaultCoapIdentityHandler;
import org.eclipse.leshan.core.californium.identity.IdentityHandler;
import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.server.LeshanServer;
import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointFactory;
import org.eclipse.leshan.server.californium.observation.LwM2mObservationStore;
import org.eclipse.leshan.server.californium.observation.ObservationSerDes;
import org.eclipse.leshan.server.observation.LwM2mNotificationReceiver;
import org.eclipse.leshan.server.security.ServerSecurityInfo;

public class CoapTcpServerEndpointFactory implements CaliforniumServerEndpointFactory {

protected final String loggingTagPrefix;
protected URI endpointUri = null;

public CoapTcpServerEndpointFactory(URI uri) {
this(uri, "LWM2M Server");
}

public CoapTcpServerEndpointFactory(URI uri, String loggingTagPrefix) {
this.endpointUri = uri;
this.loggingTagPrefix = loggingTagPrefix;
}

@Override
public Protocol getProtocol() {
return Protocol.COAP_TCP;
}

@Override
public URI getUri() {
return endpointUri;
}

protected String getLoggingTag() {
if (loggingTagPrefix != null) {
return String.format("[%s-%s]", loggingTagPrefix, getUri().toString());
} else {
return String.format("[%s-%s]", getUri().toString());
}
}

@Override
public CoapEndpoint createCoapEndpoint(Configuration defaultCaliforniumConfiguration,
ServerSecurityInfo serverSecurityInfo, LwM2mNotificationReceiver notificationReceiver,
LeshanServer server) {
return createEndpointBuilder(EndpointUriUtil.getSocketAddr(endpointUri), defaultCaliforniumConfiguration,
notificationReceiver, server).build();
}

protected CoapEndpoint.Builder createEndpointBuilder(InetSocketAddress address, Configuration coapConfig,
LwM2mNotificationReceiver notificationReceiver, LeshanServer server) {
CoapEndpoint.Builder builder = new CoapEndpoint.Builder();
builder.setConnector(createConnector(address, coapConfig));
builder.setConfiguration(coapConfig);
builder.setLoggingTag(getLoggingTag());

builder.setObservationStore(new LwM2mObservationStore(server.getRegistrationStore(), notificationReceiver,
new ObservationSerDes(new TcpDataParser(), new TcpDataSerializer())));
return builder;
}

protected Connector createConnector(InetSocketAddress address, Configuration coapConfig) {
return new TcpServerConnector(address, coapConfig);
}

@Override
public IdentityHandler createIdentityHandler() {
// TODO TCP : maybe we need a more specific one
return new DefaultCoapIdentityHandler();
}

@Override
public ExceptionTranslator createExceptionTranslator() {
// TODO TCP : maybe we need a more specific one
return new DefaultExceptionTranslator();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*******************************************************************************
* Copyright (c) 2022 Sierra Wireless and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* and Eclipse Distribution License v1.0 which accompany this distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.html.
*
* Contributors:
* Sierra Wireless - initial API and implementation
*******************************************************************************/
package org.eclipse.leshan.server.californium.endpoint.coaptcp;

import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

import org.eclipse.californium.core.config.CoapConfig;
import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.elements.config.Configuration.ModuleDefinitionsProvider;
import org.eclipse.californium.elements.config.SystemConfig;
import org.eclipse.californium.elements.config.TcpConfig;
import org.eclipse.leshan.core.endpoint.EndpointUriUtil;
import org.eclipse.leshan.core.endpoint.Protocol;
import org.eclipse.leshan.server.californium.endpoint.CaliforniumServerEndpointFactory;
import org.eclipse.leshan.server.californium.endpoint.ServerProtocolProvider;

public class CoapTcpServerProtocolProvider implements ServerProtocolProvider {

@Override
public Protocol getProtocol() {
return Protocol.COAP_TCP;
}

@Override
public void applyDefaultValue(Configuration configuration) {
configuration.set(TcpConfig.TCP_CONNECTION_IDLE_TIMEOUT, 0, TimeUnit.SECONDS);
}

@Override
public List<ModuleDefinitionsProvider> getModuleDefinitionsProviders() {
return Arrays.asList(SystemConfig.DEFINITIONS, CoapConfig.DEFINITIONS, TcpConfig.DEFINITIONS);
}

@Override
public CaliforniumServerEndpointFactory createDefaultEndpointFactory(URI uri) {
return new CoapTcpServerEndpointFactory(uri);
}

@Override
public URI getDefaultUri(Configuration configuration) {
return EndpointUriUtil.createUri(getProtocol().getUriScheme(),
new InetSocketAddress(configuration.get(CoapConfig.COAP_PORT)));
}
}
Loading

0 comments on commit fcea497

Please sign in to comment.