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 Oct 13, 2022
1 parent c5aafc5 commit c8b7742
Show file tree
Hide file tree
Showing 10 changed files with 384 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,122 @@
/*******************************************************************************
* 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.InetSocketAddress;
import java.security.cert.Certificate;
import java.util.List;

import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.CoapEndpoint.Builder;
import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.californium.elements.Connector;
import org.eclipse.californium.elements.EndpointContextMatcher;
import org.eclipse.californium.elements.TcpEndpointContextMatcher;
import org.eclipse.californium.elements.UDPConnector;
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.Protocol;

public class CoapTcpClientEndpointFactory implements CaliforniumClientEndpointFactory {

private final String loggingTag = null;
protected EndpointContextMatcher unsecuredContextMatcher = new TcpEndpointContextMatcher();
protected InetSocketAddress addr = null;

public CoapTcpClientEndpointFactory(InetSocketAddress addr) {
this.addr = addr;
}

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

@Override
public Endpoint createEndpoint(Configuration defaultConfiguration, ServerInfo serverInfo,
boolean clientInitiatedOnly, List<Certificate> trustStore, ClientEndpointToolbox toolbox) {
return createUnsecuredEndpointBuilder(addr, serverInfo, defaultConfiguration).build();
}

/**
* This method is intended to be overridden.
*
* @param address the IP address and port, if null the connector is bound to an ephemeral port on the wildcard
* address.
* @param coapConfig the CoAP config used to create this endpoint.
* @return the {@link Builder} used for unsecured communication.
*/
protected CoapEndpoint.Builder createUnsecuredEndpointBuilder(InetSocketAddress address, ServerInfo serverInfo,
Configuration coapConfig) {
CoapEndpoint.Builder builder = new CoapEndpoint.Builder();
builder.setConnector(createUnsecuredConnector(address, coapConfig));
builder.setConfiguration(coapConfig);
if (loggingTag != null) {
builder.setLoggingTag("[" + loggingTag + "-coap://]");
} else {
builder.setLoggingTag("[coap://]");
}
if (unsecuredContextMatcher != null) {
builder.setEndpointContextMatcher(unsecuredContextMatcher);
}
return builder;
}

/**
* By default create an {@link UDPConnector}.
* <p>
* This method is intended to be overridden.
*
* @param address the IP address and port, if null the connector is bound to an ephemeral port on the wildcard
* address
* @param coapConfig the Configuration
* @return the {@link Connector} used for unsecured {@link CoapEndpoint}
*/
protected Connector createUnsecuredConnector(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 : maybe we need a more specific one
return new DefaultExceptionTranslator();
}

@Override
public CaliforniumConnectionController createConnectionController() {
return new CaliforniumConnectionController() {
@Override
public void forceReconnection(Endpoint endpoint, ServerIdentity identity, boolean resume) {
// no connection in coap, so nothing to do;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*******************************************************************************
* 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.InetSocketAddress;
import java.util.Arrays;
import java.util.List;

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.californium.elements.config.UdpConfig;
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);
}

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

@Override
public CaliforniumClientEndpointFactory createDefaultEndpointFactory(InetSocketAddress address) {
return new CoapTcpClientEndpointFactory(address);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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 createDtlsConfigBuilder(Configuration conf
};

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 @@ -305,7 +305,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 @@ -319,7 +319,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,123 @@
/*******************************************************************************
* 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.CoapEndpoint.Builder;
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.EndpointContextMatcher;
import org.eclipse.californium.elements.TcpEndpointContextMatcher;
import org.eclipse.californium.elements.UDPConnector;
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 {

private final String loggingTag = null;
protected EndpointContextMatcher unsecuredContextMatcher = new TcpEndpointContextMatcher();
protected URI endpointUri = null;

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

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

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

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

/**
* This method is intended to be overridden.
*
* @param address the IP address and port, if null the connector is bound to an ephemeral port on the wildcard
* address.
* @param coapConfig the CoAP config used to create this endpoint.
* @return the {@link Builder} used for unsecured communication.
*/
protected CoapEndpoint.Builder createUnsecuredEndpointBuilder(InetSocketAddress address, Configuration coapConfig,
LeshanServer server, LwM2mNotificationReceiver notificationReceiver) {
CoapEndpoint.Builder builder = new CoapEndpoint.Builder();
builder.setConnector(createUnsecuredConnector(address, coapConfig));
builder.setConfiguration(coapConfig);
if (loggingTag != null) {
builder.setLoggingTag("[" + loggingTag + "-coap://]");
} else {
builder.setLoggingTag("[coap://]");
}
if (unsecuredContextMatcher != null) {
builder.setEndpointContextMatcher(unsecuredContextMatcher);
}
builder.setObservationStore(new LwM2mObservationStore(server.getRegistrationStore(), notificationReceiver,
new ObservationSerDes(new TcpDataParser(), new TcpDataSerializer())));
return builder;
}

/**
* By default create an {@link UDPConnector}.
* <p>
* This method is intended to be overridden.
*
* @param address the IP address and port, if null the connector is bound to an ephemeral port on the wildcard
* address
* @param coapConfig the Configuration
* @return the {@link Connector} used for unsecured {@link CoapEndpoint}
*/
protected Connector createUnsecuredConnector(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();
}
}

0 comments on commit c8b7742

Please sign in to comment.