Skip to content

Commit

Permalink
Add "transport" command to leshan-client-demo.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Oct 19, 2023
1 parent a15a513 commit eb8badc
Show file tree
Hide file tree
Showing 16 changed files with 717 additions and 78 deletions.
4 changes: 4 additions & 0 deletions leshan-client-demo/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Contributors:
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-core-demo</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-tl-javacoap-client</artifactId>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,15 @@
import static org.eclipse.leshan.core.LwM2mId.SECURITY;
import static org.eclipse.leshan.core.LwM2mId.SERVER;

import java.io.File;
import java.io.PrintWriter;
import java.util.List;

import org.eclipse.californium.elements.config.Configuration;
import org.eclipse.californium.scandium.config.DtlsConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig.Builder;
import org.eclipse.leshan.client.LeshanClient;
import org.eclipse.leshan.client.LeshanClientBuilder;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpointFactory;
import org.eclipse.leshan.client.californium.endpoint.CaliforniumClientEndpointsProvider;
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.demo.cli.LeshanClientDemoCLI;
import org.eclipse.leshan.client.demo.cli.interactive.InteractiveCommands;
import org.eclipse.leshan.client.demo.cli.transport.TransportCommand;
import org.eclipse.leshan.client.endpoint.LwM2mClientEndpointsProvider;
import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory;
import org.eclipse.leshan.client.object.LwM2mTestObject;
import org.eclipse.leshan.client.object.Oscore;
Expand All @@ -56,8 +48,8 @@
import org.eclipse.leshan.client.resource.ObjectsInitializer;
import org.eclipse.leshan.client.resource.listener.ObjectsListenerAdapter;
import org.eclipse.leshan.client.send.ManualDataSender;
import org.eclipse.leshan.core.californium.PrincipalMdcConnectionListener;
import org.eclipse.leshan.core.demo.LwM2mDemoConstant;
import org.eclipse.leshan.core.demo.cli.PicocliUtil;
import org.eclipse.leshan.core.demo.cli.ShortErrorMessageHandler;
import org.eclipse.leshan.core.demo.cli.interactive.InteractiveCLI;
import org.eclipse.leshan.core.model.LwM2mModelRepository;
Expand All @@ -69,6 +61,7 @@
import org.slf4j.LoggerFactory;

import picocli.CommandLine;
import picocli.CommandLine.RunAll;

public class LeshanClientDemo {

Expand All @@ -83,26 +76,27 @@ public class LeshanClientDemo {
private static final Logger LOG = LoggerFactory.getLogger(LeshanClientDemo.class);
private static final int OBJECT_ID_TEMPERATURE_SENSOR = 3303;
private static final int OBJECT_ID_LWM2M_TEST_OBJECT = 3442;
private static final String CF_CONFIGURATION_FILENAME = "Californium3.client.properties";
private static final String CF_CONFIGURATION_HEADER = "Leshan Client Demo - " + Configuration.DEFAULT_HEADER;

public static void main(String[] args) {

// Parse command line
LeshanClientDemoCLI cli = new LeshanClientDemoCLI();
CommandLine command = new CommandLine(cli).setParameterExceptionHandler(new ShortErrorMessageHandler());
CommandLine command = new CommandLine(cli) //
.setExecutionStrategy(new RunAll()).setParameterExceptionHandler(new ShortErrorMessageHandler());

// Handle exit code error
int exitCode = command.execute(args);
if (exitCode != 0)
System.exit(exitCode);
// Handle help or version command
if (command.isUsageHelpRequested() || command.isVersionHelpRequested())
if (command.isUsageHelpRequested() || command.isVersionHelpRequested() || PicocliUtil.isHelpRequested(command))
System.exit(0);

try {
// Create Client
LwM2mModelRepository repository = createModel(cli);
final LeshanClient client = createClient(cli, repository);
List<LwM2mClientEndpointsProvider> endpointProviders = createEndpointsProviders(cli, command);
final LeshanClient client = createClient(cli, repository, endpointProviders);

// Print commands help
InteractiveCLI console = new InteractiveCLI(new InteractiveCommands(client, repository));
Expand Down Expand Up @@ -145,7 +139,18 @@ private static LwM2mModelRepository createModel(LeshanClientDemoCLI cli) throws
return new LwM2mModelRepository(models);
}

public static LeshanClient createClient(LeshanClientDemoCLI cli, LwM2mModelRepository repository) throws Exception {
private static List<LwM2mClientEndpointsProvider> createEndpointsProviders(LeshanClientDemoCLI cli,
CommandLine commandLine) {
// Get transport command
CommandLine transportCommand = commandLine.getSubcommands().get("transport");
List<LwM2mClientEndpointsProvider> providers = ((TransportCommand) transportCommand.getCommandSpec()
.userObject()).createEndpointsProviders(cli, transportCommand);

return providers;
}

public static LeshanClient createClient(LeshanClientDemoCLI cli, LwM2mModelRepository repository,
List<LwM2mClientEndpointsProvider> endpointProviders) throws Exception {
// create Leshan client from command line option
final MyLocation locationInstance = new MyLocation(cli.location.position.latitude,
cli.location.position.longitude, cli.location.scaleFactor);
Expand Down Expand Up @@ -233,65 +238,10 @@ public static LeshanClient createClient(LeshanClientDemoCLI cli, LwM2mModelRepos
engineFactory.setResumeOnConnect(!cli.dtls.forceFullhandshake);
engineFactory.setQueueMode(cli.main.queueMode);

// Create Californium Endpoints Provider:
// --------------------------------------
// Define Custom CoAPS protocol provider
CoapsClientProtocolProvider customCoapsProtocolProvider = new CoapsClientProtocolProvider() {
@Override
public CaliforniumClientEndpointFactory createDefaultEndpointFactory() {
return new CoapsClientEndpointFactory() {

@Override
protected DtlsConnectorConfig.Builder createRootDtlsConnectorConfigBuilder(
Configuration configuration) {
Builder builder = super.createRootDtlsConnectorConfigBuilder(configuration);

// Add DTLS Session lifecycle logger
builder.setSessionListener(new DtlsSessionLogger());

// Add MDC for connection logs
if (cli.helpsOptions.getVerboseLevel() > 0)
builder.setConnectionListener(new PrincipalMdcConnectionListener());
return builder;
};
};
}
};

// Create client endpoints Provider
CaliforniumClientEndpointsProvider.Builder endpointsBuilder = new CaliforniumClientEndpointsProvider.Builder(
new CoapOscoreProtocolProvider(), customCoapsProtocolProvider);

// Create Californium Configuration
Configuration clientCoapConfig = endpointsBuilder.createDefaultConfiguration();

// Set some DTLS stuff
// These configuration values are always overwritten by CLI therefore set them to transient.
clientCoapConfig.setTransient(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY);
clientCoapConfig.setTransient(DtlsConfig.DTLS_CONNECTION_ID_LENGTH);
clientCoapConfig.set(DtlsConfig.DTLS_RECOMMENDED_CIPHER_SUITES_ONLY, !cli.dtls.supportDeprecatedCiphers);
clientCoapConfig.set(DtlsConfig.DTLS_CONNECTION_ID_LENGTH, cli.dtls.cid);
if (cli.dtls.ciphers != null) {
clientCoapConfig.set(DtlsConfig.DTLS_CIPHER_SUITES, cli.dtls.ciphers);
}

// Persist configuration
File configFile = new File(CF_CONFIGURATION_FILENAME);
if (configFile.isFile()) {
clientCoapConfig.load(configFile);
} else {
clientCoapConfig.store(configFile, CF_CONFIGURATION_HEADER);
}

// Set Californium Configuration
endpointsBuilder.setConfiguration(clientCoapConfig);

endpointsBuilder.setClientAddress(cli.main.localAddress);

// Create client
LeshanClientBuilder builder = new LeshanClientBuilder(cli.main.endpoint);
builder.setObjects(enablers);
builder.setEndpointsProviders(endpointsBuilder.build());
builder.setEndpointsProviders(endpointProviders);
builder.setDataSenders(new ManualDataSender());
if (cli.identity.isx509())
builder.setTrustStore(cli.identity.getX509().trustStore);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
import org.eclipse.leshan.client.demo.cli.transport.TransportCommand;
import org.eclipse.leshan.client.demo.cli.transport.californium.CaliforniumCommand;
import org.eclipse.leshan.core.CertificateUsage;
import org.eclipse.leshan.core.demo.cli.MultiParameterException;
import org.eclipse.leshan.core.demo.cli.StandardHelpOptions;
Expand All @@ -34,6 +36,7 @@

import picocli.CommandLine.ArgGroup;
import picocli.CommandLine.Command;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.ITypeConverter;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Model.CommandSpec;
Expand All @@ -49,11 +52,16 @@
+ "@|italic " //
+ "This is a LWM2M client demo implemented with Leshan library.%n" //
+ "You can launch it without any option and it will try to register to a LWM2M server at " + "coap://"
+ LeshanClientDemoCLI.DEFAULT_COAP_URL + ".%n" //
+ LeshanClientDemoCLI.DEFAULT_COAP_URL + ".|@%n" //
+ "%n" //
+ "Californium is used as CoAP library and some CoAP parameters can be tweaked in 'Californium.properties' file." //
+ "|@%n%n",
versionProvider = VersionProvider.class)
+ CaliforniumCommand.DEFAULT_DESCRIPTION //
+ "%n" //
+ "You can use @|bold transport|@ command to use different transport layer.%n"
+ "Launch @|bold transport -h|@ for more details.%n" //
+ "%n",
versionProvider = VersionProvider.class,
subcommands = { HelpCommand.class, TransportCommand.class })

public class LeshanClientDemoCLI implements Runnable {

public static final String DEFAULT_COAP_URL = "localhost:" + CoAP.DEFAULT_COAP_PORT;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2023 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.demo.cli.transport;

import org.eclipse.leshan.client.demo.cli.LeshanClientDemoCLI;
import org.eclipse.leshan.client.endpoint.LwM2mClientEndpointsProvider;

import picocli.CommandLine;

public interface DefaultEndpointProviderFactory {
LwM2mClientEndpointsProvider createDefault(LeshanClientDemoCLI cli, CommandLine commandLine);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2023 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.demo.cli.transport;

import org.eclipse.leshan.client.demo.cli.LeshanClientDemoCLI;
import org.eclipse.leshan.client.endpoint.LwM2mClientEndpointsProvider;

import picocli.CommandLine.ParseResult;

public interface EndpointProviderFactory {

LwM2mClientEndpointsProvider create(LeshanClientDemoCLI cli, ParseResult result);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2023 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.demo.cli.transport;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.leshan.client.demo.cli.LeshanClientDemoCLI;
import org.eclipse.leshan.client.demo.cli.transport.californium.CaliforniumCommand;
import org.eclipse.leshan.client.demo.cli.transport.javacoap.JavaCoapCommand;
import org.eclipse.leshan.client.endpoint.LwM2mClientEndpointsProvider;
import org.eclipse.leshan.core.demo.cli.PicocliUtil;

import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;

@Command(name = "transport",
description = {
"Configure Leshan transport layer. Can be used to add, remove or use different implementation of supported LWM2M transport.", //
"%n"//
+ CaliforniumCommand.DEFAULT_DESCRIPTION //
+ CaliforniumCommand.DEFAULT_COMMAND_DESCRIPTION //
+ "%n" //
+ "@|italic More examples :|@%n" //
+ CaliforniumCommand.COMMON_USAGE //
+ "%n" //
+ JavaCoapCommand.COMMON_USAGE //
+ "%n" //
+ "coaps support based on Californium library and coap support based java-coap library: %n" //
+ "@|bold transport californium coaps java-coap coap|@%n"//
+ "%n" //
+ "Launch @|bold transport [californium|java-coap] -h|@ for more details.%n" //
},
subcommandsRepeatable = true,
subcommands = { CaliforniumCommand.class, JavaCoapCommand.class })
public class TransportCommand implements Runnable {

@Option(names = { "-h", "--help" }, description = "Display help information.", usageHelp = true)
private boolean help;

@Override
public void run() {
}

public List<LwM2mClientEndpointsProvider> createEndpointsProviders(LeshanClientDemoCLI cli,
CommandLine commandLine) {

// if transport sub-command is called
if (commandLine.getParseResult() != null && commandLine.getParseResult().hasSubcommand()) {
List<LwM2mClientEndpointsProvider> providers = new ArrayList<>();

// add provider from call sub-commands
PicocliUtil.applyTo(commandLine.getParseResult(), EndpointProviderFactory.class, //
(parseResult, endpointProviderFactory) -> {
providers.add(endpointProviderFactory.create(cli, parseResult));
});
return providers;
}
// else create default providers
else {
List<LwM2mClientEndpointsProvider> providers = new ArrayList<>();
PicocliUtil.applyTo(commandLine, DefaultEndpointProviderFactory.class, //
(cmd, endpointProviderFactory) -> {
providers.add(endpointProviderFactory.createDefault(cli, cmd));
});
return providers;
}
}
}
Loading

0 comments on commit eb8badc

Please sign in to comment.