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 Sep 14, 2022
1 parent bbe8f75 commit 98da128
Show file tree
Hide file tree
Showing 10 changed files with 360 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.core.server.resources.CoapExchange;
import org.eclipse.californium.elements.Connector;
import org.eclipse.californium.elements.EndpointContext;
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.CaliforniumIdentityExtractor;
import org.eclipse.leshan.client.californium.enpoint.CaliforniumEndpointFactory;
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.endpoint.Protocol;
import org.eclipse.leshan.core.request.Identity;

public class CoapTcpEndpointFactory implements CaliforniumEndpointFactory {

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

public CoapTcpEndpointFactory(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 CaliforniumIdentityExtractor createIdentityExtractor() {
return new CaliforniumIdentityExtractor() {
@Override
public Identity getIdentity(CoapExchange exchange) {
EndpointContext context = getForeignPeerContext(exchange);
InetSocketAddress peerAddress = context.getPeerAddress();
return Identity.unsecure(peerAddress);
}
};
}

@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,57 @@
/*******************************************************************************
* 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.core.config.CoapConfig.TrackerMode;
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.enpoint.CaliforniumEndpointFactory;
import org.eclipse.leshan.client.californium.enpoint.CaliforniumProtocolProvider;
import org.eclipse.leshan.core.endpoint.Protocol;

public class CoapTcpProtocolProvider implements CaliforniumProtocolProvider {

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

@Override
public void applyDefaultValue(Configuration configuration) {
configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
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 CaliforniumEndpointFactory createDefaultEndpointFactory(InetSocketAddress address) {
return new CoapTcpEndpointFactory(address);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.eclipse.leshan.client.californium.endpoint.coap.CoapProtocolProvider;
import org.eclipse.leshan.client.californium.endpoint.coaps.CoapsEndpointFactory;
import org.eclipse.leshan.client.californium.endpoint.coaps.CoapsProtocolProvider;
import org.eclipse.leshan.client.californium.endpoint.coaptcp.CoapTcpProtocolProvider;
import org.eclipse.leshan.client.californium.enpoint.CaliforniumEndpointFactory;
import org.eclipse.leshan.client.californium.enpoint.CaliforniumEndpointsProvider;
import org.eclipse.leshan.client.demo.cli.LeshanClientDemoCLI;
Expand Down Expand Up @@ -254,7 +255,7 @@ protected DtlsConnectorConfig.Builder createDtlsConfigBuilder(Configuration conf
};

CaliforniumEndpointsProvider.Builder endpointsBuilder = new CaliforniumEndpointsProvider.Builder(
new CoapProtocolProvider(), customCoapsProtocolProvider);
new CoapProtocolProvider(), customCoapsProtocolProvider, new CoapTcpProtocolProvider());

// Create Californium Configuration
Configuration clientCoapConfig = endpointsBuilder.createDefaultCoapServerConfiguration();
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,99 @@
/*******************************************************************************
* 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 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.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.endpoint.Protocol;
import org.eclipse.leshan.server.californium.endpoint.CaliforniumEndpointFactory;
import org.eclipse.leshan.server.californium.observation.LwM2mObservationStore;
import org.eclipse.leshan.server.californium.observation.ObservationSerDes;
import org.eclipse.leshan.server.endpoint.LwM2mNotificationReceiver;
import org.eclipse.leshan.server.endpoint.LwM2mServer;
import org.eclipse.leshan.server.endpoint.ServerSecurityInfo;

public class CoapTcpEndpointFactory implements CaliforniumEndpointFactory {

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

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

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

@Override
public Endpoint createEndpoint(Configuration defaultConfiguration, ServerSecurityInfo serverSecurityInfo,
LwM2mServer server, LwM2mNotificationReceiver notificationReceiver) {
return createUnsecuredEndpointBuilder(addr, defaultConfiguration, 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,
LwM2mServer 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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*******************************************************************************
* 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.util.Arrays;
import java.util.List;

import org.eclipse.californium.core.config.CoapConfig;
import org.eclipse.californium.core.config.CoapConfig.TrackerMode;
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.core.endpoint.Protocol;
import org.eclipse.leshan.server.californium.endpoint.CaliforniumEndpointFactory;
import org.eclipse.leshan.server.californium.endpoint.CaliforniumProtocolProvider;

public class CoapTcpProtocolProvider implements CaliforniumProtocolProvider {

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

@Override
public void applyDefaultValue(Configuration configuration) {
configuration.set(CoapConfig.MID_TRACKER, TrackerMode.NULL);
}

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

@Override
public CaliforniumEndpointFactory createDefaultEndpointFactory(InetSocketAddress address) {
return new CoapTcpEndpointFactory(address);
}

@Override
public InetSocketAddress getDefaultSocketAddress(Configuration coapServerConfiguration) {
return new InetSocketAddress(coapServerConfiguration.get(CoapConfig.COAP_PORT));
}
}
Loading

0 comments on commit 98da128

Please sign in to comment.