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

Add transport command to leshan-client-demo #1522

Draft
wants to merge 2 commits 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-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