Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Experiments some LWM2M over coap+tcp based on californium #1312

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -46,6 +46,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 @@ -260,7 +261,7 @@ protected DtlsConnectorConfig.Builder createRootDtlsConnectorConfigBuilder(

// Create client endpoints Provider
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 @@ -298,7 +298,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 @@ -312,7 +312,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