Skip to content

Commit

Permalink
Experiments some LwM2mEndpoint abstraction at Client Side.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Sep 16, 2022
1 parent bda6e73 commit 6694e2b
Show file tree
Hide file tree
Showing 69 changed files with 2,944 additions and 1,353 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*******************************************************************************
* 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;

import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.leshan.client.servers.ServerIdentity;

public interface CaliforniumConnectionController {
void forceReconnection(Endpoint endpoint, ServerIdentity identity, boolean resume);
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*******************************************************************************
* 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;

import org.eclipse.californium.core.network.Exchange.Origin;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.elements.EndpointContext;
import org.eclipse.leshan.core.request.Identity;

public abstract class CaliforniumIdentityExtractor {

protected EndpointContext getForeignPeerContext(CoapExchange exchange) {
return exchange.advanced().getOrigin() == Origin.REMOTE ? exchange.advanced().getRequest().getSourceContext()
: exchange.advanced().getRequest().getDestinationContext();
}

public abstract Identity getIdentity(CoapExchange exchange);

}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP.ResponseCode;
import org.eclipse.californium.core.network.Exchange;
import org.eclipse.californium.core.network.Exchange.Origin;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.leshan.client.engine.RegistrationEngine;
import org.eclipse.leshan.client.californium.enpoint.ServerIdentityExtractor;
import org.eclipse.leshan.client.servers.ServerIdentity;
import org.eclipse.leshan.core.californium.LwM2mCoapResource;

Expand All @@ -29,27 +28,11 @@
*/
public class LwM2mClientCoapResource extends LwM2mCoapResource {

protected final CaliforniumEndpointsManager endpointsManager;
protected final RegistrationEngine registrationEngine;
protected final ServerIdentityExtractor identityExtractor;

public LwM2mClientCoapResource(String name, RegistrationEngine registrationEngine,
CaliforniumEndpointsManager endpointsManager) {
public LwM2mClientCoapResource(String name, ServerIdentityExtractor identityExtractor) {
super(name);
this.registrationEngine = registrationEngine;
this.endpointsManager = endpointsManager;
}

/**
* @return the server identity of a registered or bootstrap server, return null if this identity does match to any
* server for which we are in communication.
*/
protected ServerIdentity getServer(CoapExchange exchange) {
ServerIdentity serverIdentity = extractIdentity(exchange);
if (registrationEngine.isAllowedToCommunicate(serverIdentity)) {
return serverIdentity;
} else {
return null;
}
this.identityExtractor = identityExtractor;
}

/**
Expand All @@ -58,7 +41,7 @@ protected ServerIdentity getServer(CoapExchange exchange) {
*/
protected ServerIdentity getServerOrRejectRequest(CoapExchange exchange) {
// search if we are in communication with this server.
ServerIdentity server = getServer(exchange);
ServerIdentity server = extractIdentity(exchange);
if (server != null)
return server;

Expand All @@ -74,8 +57,6 @@ protected ServerIdentity getServerOrRejectRequest(CoapExchange exchange) {
* @throws IllegalStateException if we are not able to extract {@link ServerIdentity}.
*/
protected ServerIdentity extractIdentity(CoapExchange exchange) {
return endpointsManager.getServerIdentity(exchange.advanced().getEndpoint(), exchange.getSourceSocketAddress(),
exchange.advanced().getOrigin() == Origin.REMOTE ? exchange.advanced().getRequest().getSourceContext()
: exchange.advanced().getRequest().getDestinationContext());
return identityExtractor.extractIdentity(exchange);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
/**
* An {@link ObserveRelationFilter} which select {@link ObserveRelation} based on one of resource URIs.
*/
class ObserveCompositeRelationFilter implements ObserveRelationFilter {
public class ObserveCompositeRelationFilter implements ObserveRelationFilter {

private final List<LwM2mPath> paths;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,17 +30,13 @@
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.leshan.client.bootstrap.BootstrapHandler;
import org.eclipse.leshan.client.engine.RegistrationEngine;
import org.eclipse.leshan.client.resource.LwM2mRootEnabler;
import org.eclipse.leshan.client.resource.listener.ObjectsListenerAdapter;
import org.eclipse.leshan.client.californium.enpoint.ServerIdentityExtractor;
import org.eclipse.leshan.client.endpoint.ClientEndpointToolbox;
import org.eclipse.leshan.client.endpoint.LwM2mRequestReceiver;
import org.eclipse.leshan.client.servers.ServerIdentity;
import org.eclipse.leshan.core.californium.ObserveUtil;
import org.eclipse.leshan.core.link.LinkSerializer;
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.node.codec.LwM2mDecoder;
import org.eclipse.leshan.core.node.codec.LwM2mEncoder;
import org.eclipse.leshan.core.request.BootstrapDeleteRequest;
import org.eclipse.leshan.core.request.BootstrapDiscoverRequest;
import org.eclipse.leshan.core.request.ContentFormat;
Expand All @@ -59,27 +55,19 @@
*/
public class RootResource extends LwM2mClientCoapResource {

protected CoapServer coapServer;
protected BootstrapHandler bootstrapHandler;
protected LwM2mRootEnabler rootEnabler;
protected LwM2mEncoder encoder;
protected LwM2mDecoder decoder;
protected LinkSerializer linkSerializer;

public RootResource(RegistrationEngine registrationEngine, CaliforniumEndpointsManager endpointsManager,
BootstrapHandler bootstrapHandler, CoapServer coapServer, LwM2mRootEnabler rootEnabler,
LwM2mEncoder encoder, LwM2mDecoder decoder, LinkSerializer linkSerializer) {
super("", registrationEngine, endpointsManager);
this.bootstrapHandler = bootstrapHandler;
protected LwM2mRequestReceiver requestReceiver;
protected ClientEndpointToolbox toolbox;

public RootResource(ServerIdentityExtractor identityExtractor, CoapServer coapServer,
LwM2mRequestReceiver requestReceiver, ClientEndpointToolbox toolbox) {
super("", identityExtractor);
setVisible(false);
setObservable(true);
this.coapServer = coapServer;
this.rootEnabler = rootEnabler;
this.encoder = encoder;
this.decoder = decoder;
this.linkSerializer = linkSerializer;
this.requestReceiver = requestReceiver;
this.toolbox = toolbox;

addListeners();
// TODO TL
// addListeners();
}

@Override
Expand All @@ -92,13 +80,13 @@ public void handleGET(CoapExchange exchange) {

// Manage Bootstrap Discover Request
Request coapRequest = exchange.advanced().getRequest();
BootstrapDiscoverResponse response = bootstrapHandler.discover(identity,
new BootstrapDiscoverRequest(URI, coapRequest));
BootstrapDiscoverResponse response = requestReceiver
.requestReceived(identity, new BootstrapDiscoverRequest(URI, coapRequest)).getResponse();
if (response.getCode().isError()) {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
} else {
exchange.respond(toCoapResponseCode(response.getCode()),
linkSerializer.serializeCoreLinkFormat(response.getObjectLinks()),
toolbox.getLinkSerializer().serializeCoreLinkFormat(response.getObjectLinks()),
MediaTypeRegistry.APPLICATION_LINK_FORMAT);
}
return;
Expand All @@ -117,7 +105,7 @@ public void handleFETCH(CoapExchange exchange) {
if (exchange.getRequestOptions().hasAccept()) {
// If an request ask for a specific content format, use it (if we support it)
responseContentFormat = ContentFormat.fromCode(exchange.getRequestOptions().getAccept());
if (!encoder.isSupported(responseContentFormat)) {
if (!toolbox.getEncoder().isSupported(responseContentFormat)) {
exchange.respond(ResponseCode.NOT_ACCEPTABLE);
return;
}
Expand All @@ -129,36 +117,38 @@ public void handleFETCH(CoapExchange exchange) {
return;
}
ContentFormat requestContentFormat = ContentFormat.fromCode(exchange.getRequestOptions().getContentFormat());
List<LwM2mPath> paths = decoder.decodePaths(coapRequest.getPayload(), requestContentFormat);
List<LwM2mPath> paths = toolbox.getDecoder().decodePaths(coapRequest.getPayload(), requestContentFormat);

if (exchange.getRequestOptions().hasObserve()) {
// Manage Observe Composite request
ObserveCompositeRequest observeRequest = new ObserveCompositeRequest(requestContentFormat,
responseContentFormat, paths, coapRequest);
ObserveCompositeResponse response = rootEnabler.observe(identity, observeRequest);
ObserveCompositeResponse response = requestReceiver.requestReceived(identity, observeRequest).getResponse();

updateUserContextWithPaths(coapRequest, paths);

if (response.getCode().isError()) {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
return;
} else {
exchange.respond(toCoapResponseCode(response.getCode()),
encoder.encodeNodes(response.getContent(), responseContentFormat, rootEnabler.getModel()),
exchange.respond(toCoapResponseCode(response.getCode()), toolbox.getEncoder()
.encodeNodes(response.getContent(), responseContentFormat, toolbox.getModel()),
responseContentFormat.getCode());
return;
}
} else {
// Manage Read Composite request
ReadCompositeResponse response = rootEnabler.read(identity,
new ReadCompositeRequest(paths, requestContentFormat, responseContentFormat, coapRequest));
ReadCompositeResponse response = requestReceiver
.requestReceived(identity,
new ReadCompositeRequest(paths, requestContentFormat, responseContentFormat, coapRequest))
.getResponse();
if (response.getCode().isError()) {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
} else {
// TODO we could maybe face some race condition if an objectEnabler is removed from LwM2mObjectTree
// between rootEnabler.read() and rootEnabler.getModel()
exchange.respond(toCoapResponseCode(response.getCode()),
encoder.encodeNodes(response.getContent(), responseContentFormat, rootEnabler.getModel()),
exchange.respond(toCoapResponseCode(response.getCode()), toolbox.getEncoder()
.encodeNodes(response.getContent(), responseContentFormat, toolbox.getModel()),
responseContentFormat.getCode());
}
return;
Expand All @@ -185,16 +175,16 @@ public void handleIPATCH(CoapExchange exchange) {

// Handle content format
ContentFormat contentFormat = ContentFormat.fromCode(exchange.getRequestOptions().getContentFormat());
if (!decoder.isSupported(contentFormat)) {
if (!toolbox.getDecoder().isSupported(contentFormat)) {
exchange.respond(ResponseCode.UNSUPPORTED_CONTENT_FORMAT);
return;
}

Map<LwM2mPath, LwM2mNode> nodes = decoder.decodeNodes(coapRequest.getPayload(), contentFormat, null,
rootEnabler.getModel());
Map<LwM2mPath, LwM2mNode> nodes = toolbox.getDecoder().decodeNodes(coapRequest.getPayload(), contentFormat,
null, toolbox.getModel());

WriteCompositeResponse response = rootEnabler.write(identity,
new WriteCompositeRequest(contentFormat, nodes, coapRequest));
WriteCompositeResponse response = requestReceiver
.requestReceived(identity, new WriteCompositeRequest(contentFormat, nodes, coapRequest)).getResponse();
if (response.getCode().isError()) {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
} else {
Expand All @@ -216,18 +206,19 @@ public void handleDELETE(CoapExchange exchange) {
return;

Request coapRequest = exchange.advanced().getRequest();
BootstrapDeleteResponse response = bootstrapHandler.delete(identity,
new BootstrapDeleteRequest(URI, coapRequest));
BootstrapDeleteResponse response = requestReceiver
.requestReceived(identity, new BootstrapDeleteRequest(URI, coapRequest)).getResponse();
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
}

private void addListeners() {
rootEnabler.addListener(new ObjectsListenerAdapter() {

@Override
public void resourceChanged(LwM2mPath... paths) {
changed(new ObserveCompositeRelationFilter(paths));
}
});
}
// TODO TL : handle object modification
// private void addListeners() {
// rootEnabler.addListener(new ObjectsListenerAdapter() {
//
// @Override
// public void resourceChanged(LwM2mPath... paths) {
// changed(new ObserveCompositeRelationFilter(paths));
// }
// });
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@
import org.eclipse.californium.core.coap.Response;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.core.server.resources.Resource;
import org.eclipse.leshan.client.bootstrap.BootstrapHandler;
import org.eclipse.leshan.client.californium.CaliforniumEndpointsManager;
import org.eclipse.leshan.client.californium.LwM2mClientCoapResource;
import org.eclipse.leshan.client.engine.RegistrationEngine;
import org.eclipse.leshan.client.californium.enpoint.ServerIdentityExtractor;
import org.eclipse.leshan.client.endpoint.LwM2mRequestReceiver;
import org.eclipse.leshan.client.servers.ServerIdentity;
import org.eclipse.leshan.core.request.BootstrapFinishRequest;
import org.eclipse.leshan.core.response.BootstrapFinishResponse;
Expand All @@ -38,12 +37,11 @@
*/
public class BootstrapResource extends LwM2mClientCoapResource {

protected BootstrapHandler bootstrapHandler;
protected LwM2mRequestReceiver requestReceiver;

public BootstrapResource(RegistrationEngine registrationEngine, CaliforniumEndpointsManager endpointsManager,
BootstrapHandler bootstrapHandler) {
super("bs", registrationEngine, endpointsManager);
this.bootstrapHandler = bootstrapHandler;
public BootstrapResource(ServerIdentityExtractor identityExtractor, LwM2mRequestReceiver requestReceiver) {
super("bs", identityExtractor);
this.requestReceiver = requestReceiver;
this.setVisible(false);
}

Expand All @@ -57,7 +55,7 @@ public void handlePOST(CoapExchange exchange) {
// Acknowledge bootstrap finished request
exchange.accept();
Request coapRequest = exchange.advanced().getRequest();
final SendableResponse<BootstrapFinishResponse> sendableResponse = bootstrapHandler.finished(identity,
final SendableResponse<BootstrapFinishResponse> sendableResponse = requestReceiver.requestReceived(identity,
new BootstrapFinishRequest(coapRequest));

// Create CoAP response
Expand Down

0 comments on commit 6694e2b

Please sign in to comment.