Skip to content

Commit

Permalink
Add BootstrapReadRequest support.
Browse files Browse the repository at this point in the history
  • Loading branch information
sbernard31 committed Jun 30, 2021
1 parent f281c3a commit ecf961a
Show file tree
Hide file tree
Showing 13 changed files with 465 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
import org.eclipse.leshan.core.node.codec.LwM2mNodeEncoder;
import org.eclipse.leshan.core.request.BootstrapDeleteRequest;
import org.eclipse.leshan.core.request.BootstrapDiscoverRequest;
import org.eclipse.leshan.core.request.BootstrapReadRequest;
import org.eclipse.leshan.core.request.BootstrapWriteRequest;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.CreateRequest;
Expand All @@ -62,6 +63,7 @@
import org.eclipse.leshan.core.request.WriteRequest.Mode;
import org.eclipse.leshan.core.response.BootstrapDeleteResponse;
import org.eclipse.leshan.core.response.BootstrapDiscoverResponse;
import org.eclipse.leshan.core.response.BootstrapReadResponse;
import org.eclipse.leshan.core.response.BootstrapWriteResponse;
import org.eclipse.leshan.core.response.CreateResponse;
import org.eclipse.leshan.core.response.DeleteResponse;
Expand Down Expand Up @@ -152,21 +154,41 @@ public void handleGET(CoapExchange exchange) {
return;
}
}
// Manage Read Request

else {
ReadRequest readRequest = new ReadRequest(requestedContentFormat, URI, coapRequest);
ReadResponse response = nodeEnabler.read(identity, readRequest);
if (response.getCode() == org.eclipse.leshan.core.ResponseCode.CONTENT) {
LwM2mPath path = new LwM2mPath(URI);
LwM2mNode content = response.getContent();
LwM2mModel model = new StaticModel(nodeEnabler.getObjectModel());
ContentFormat format = getContentFormat(readRequest, requestedContentFormat);
exchange.respond(ResponseCode.CONTENT, encoder.encode(content, format, path, model),
format.getCode());
return;
if (identity.isLwm2mBootstrapServer()) {
// Manage Bootstrap Read Request
BootstrapReadRequest readRequest = new BootstrapReadRequest(requestedContentFormat, URI,
coapRequest);
BootstrapReadResponse response = nodeEnabler.read(identity, readRequest);
if (response.getCode() == org.eclipse.leshan.core.ResponseCode.CONTENT) {
LwM2mPath path = new LwM2mPath(URI);
LwM2mNode content = response.getContent();
LwM2mModel model = new StaticModel(nodeEnabler.getObjectModel());
ContentFormat format = getContentFormat(readRequest, requestedContentFormat);
exchange.respond(ResponseCode.CONTENT, encoder.encode(content, format, path, model),
format.getCode());
return;
} else {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
return;
}
} else {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
return;
// Manage Read Request
ReadRequest readRequest = new ReadRequest(requestedContentFormat, URI, coapRequest);
ReadResponse response = nodeEnabler.read(identity, readRequest);
if (response.getCode() == org.eclipse.leshan.core.ResponseCode.CONTENT) {
LwM2mPath path = new LwM2mPath(URI);
LwM2mNode content = response.getContent();
LwM2mModel model = new StaticModel(nodeEnabler.getObjectModel());
ContentFormat format = getContentFormat(readRequest, requestedContentFormat);
exchange.respond(ResponseCode.CONTENT, encoder.encode(content, format, path, model),
format.getCode());
return;
} else {
exchange.respond(toCoapResponseCode(response.getCode()), response.getErrorMessage());
return;
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import org.eclipse.leshan.core.node.LwM2mResource;
import org.eclipse.leshan.core.request.BootstrapDeleteRequest;
import org.eclipse.leshan.core.request.BootstrapDiscoverRequest;
import org.eclipse.leshan.core.request.BootstrapReadRequest;
import org.eclipse.leshan.core.request.BootstrapWriteRequest;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.CreateRequest;
Expand All @@ -53,6 +54,7 @@
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.response.BootstrapDeleteResponse;
import org.eclipse.leshan.core.response.BootstrapDiscoverResponse;
import org.eclipse.leshan.core.response.BootstrapReadResponse;
import org.eclipse.leshan.core.response.BootstrapWriteResponse;
import org.eclipse.leshan.core.response.CreateResponse;
import org.eclipse.leshan.core.response.DeleteResponse;
Expand Down Expand Up @@ -180,6 +182,29 @@ protected ReadResponse doRead(ServerIdentity identity, ReadRequest request) {
return ReadResponse.internalServerError("not implemented");
}

@Override
public BootstrapReadResponse read(ServerIdentity identity, BootstrapReadRequest request) {
// read is not supported for bootstrap
if (identity.isLwm2mServer()) {
return BootstrapReadResponse.methodNotAllowed();
}

if (!identity.isSystem()) {
LwM2mPath path = request.getPath();

// BootstrapRead can only target object 1 and 2
if (path.getObjectId() != 1 && path.getObjectId() != 2) {
return BootstrapReadResponse.badRequest("bootstrap read can only target Object 1 (Server) or 2 (ACL)");
}
}
return doRead(identity, request);
}

protected BootstrapReadResponse doRead(ServerIdentity identity, BootstrapReadRequest request) {
// This should be a not implemented error, but this is not defined in the spec.
return BootstrapReadResponse.internalServerError("not implemented");
}

@Override
public synchronized WriteResponse write(ServerIdentity identity, WriteRequest request) {
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.request.BootstrapDeleteRequest;
import org.eclipse.leshan.core.request.BootstrapDiscoverRequest;
import org.eclipse.leshan.core.request.BootstrapReadRequest;
import org.eclipse.leshan.core.request.BootstrapWriteRequest;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.CreateRequest;
Expand All @@ -40,6 +41,7 @@
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.response.BootstrapDeleteResponse;
import org.eclipse.leshan.core.response.BootstrapDiscoverResponse;
import org.eclipse.leshan.core.response.BootstrapReadResponse;
import org.eclipse.leshan.core.response.BootstrapWriteResponse;
import org.eclipse.leshan.core.response.CreateResponse;
import org.eclipse.leshan.core.response.DeleteResponse;
Expand Down Expand Up @@ -79,6 +81,8 @@ public interface LwM2mObjectEnabler {

ReadResponse read(ServerIdentity identity, ReadRequest request);

BootstrapReadResponse read(ServerIdentity identity, BootstrapReadRequest request);

WriteResponse write(ServerIdentity identity, WriteRequest request);

BootstrapWriteResponse write(ServerIdentity identity, BootstrapWriteRequest request);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.eclipse.leshan.core.node.LwM2mResource;
import org.eclipse.leshan.core.node.LwM2mResourceInstance;
import org.eclipse.leshan.core.request.BootstrapDeleteRequest;
import org.eclipse.leshan.core.request.BootstrapReadRequest;
import org.eclipse.leshan.core.request.BootstrapWriteRequest;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.CreateRequest;
Expand All @@ -50,6 +51,7 @@
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.request.WriteRequest.Mode;
import org.eclipse.leshan.core.response.BootstrapDeleteResponse;
import org.eclipse.leshan.core.response.BootstrapReadResponse;
import org.eclipse.leshan.core.response.BootstrapWriteResponse;
import org.eclipse.leshan.core.response.CreateResponse;
import org.eclipse.leshan.core.response.DeleteResponse;
Expand Down Expand Up @@ -224,6 +226,14 @@ protected ReadResponse doRead(ServerIdentity identity, ReadRequest request) {
return instance.read(identity, path.getResourceId(), path.getResourceInstanceId());
}

@Override
protected BootstrapReadResponse doRead(ServerIdentity identity, BootstrapReadRequest request) {
// Basic implementation we delegate to classic Read Request
ReadResponse response = doRead(identity,
new ReadRequest(request.getContentFormat(), request.getPath(), request.getCoapRequest()));
return new BootstrapReadResponse(response.getCode(), response.getContent(), response.getErrorMessage());
}

@Override
protected ObserveResponse doObserve(final ServerIdentity identity, final ObserveRequest request) {
final LwM2mPath path = request.getPath();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/*******************************************************************************
* Copyright (c) 2013-2015 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.core.request;

import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.request.exception.InvalidRequestException;
import org.eclipse.leshan.core.response.BootstrapReadResponse;

/**
* A Lightweight M2M request for retrieving the values of resources from a LWM2M Client.
*
* The "Bootstrap-Read" operation in the Bootstrap Interface is a restricted form of the "Read" operation found in the
* Device Management and Service Enablement interface, and MUST be limited to target Objects that are strictly necessary
* to setup a proper configuration in a LwM2M Client.
*/
public class BootstrapReadRequest extends AbstractSimpleDownlinkRequest<BootstrapReadResponse>
implements BootstrapDownlinkRequest<BootstrapReadResponse> {

private final ContentFormat format;

/**
* Creates a request for reading all instances of a particular object from a client.
*
* @param objectId the object ID of the resource
*/
public BootstrapReadRequest(int objectId) {
this(null, new LwM2mPath(objectId), null);
}

/**
* Creates a request for reading all instances of a particular object from a client.
*
* @param format the desired format for the response
* @param objectId the object ID of the resource
*/
public BootstrapReadRequest(ContentFormat format, int objectId) {
this(format, new LwM2mPath(objectId), null);
}

/**
* Creates a request for reading a particular object instance from a client.
*
* @param objectId the object ID of the resource
* @param objectInstanceId the object instance ID
*/
public BootstrapReadRequest(int objectId, int objectInstanceId) {
this(null, new LwM2mPath(objectId, objectInstanceId), null);
}

/**
* Creates a request for reading a particular object instance from a client.
*
* @param format the desired format for the response
* @param objectId the object ID of the resource
* @param objectInstanceId the object instance ID
*/
public BootstrapReadRequest(ContentFormat format, int objectId, int objectInstanceId) {
this(format, new LwM2mPath(objectId, objectInstanceId), null);
}

/**
* Create a request for reading an object/instance targeted by a specific path.
*
* @param path the path to the LWM2M node to read
* @throws IllegalArgumentException if the target path is not valid
*/
public BootstrapReadRequest(String path) {
this(null, new LwM2mPath(path), null);
}

/**
* Create a request for reading an object/instance targeted by a specific path.
*
* @param format the desired format for the response
* @param path the path to the LWM2M node to read
* @throws IllegalArgumentException if the target path is not valid
*/
public BootstrapReadRequest(ContentFormat format, String path) {
this(format, new LwM2mPath(path), null);
}

/**
* Create a request for reading an object/instance targeted by a specific path.
*
* @param format the desired format for the response
* @param path the path to the LWM2M node to read
* @param coapRequest the underlying request
*
* @throws IllegalArgumentException if the target path is not valid
*/
public BootstrapReadRequest(ContentFormat format, String path, Object coapRequest) {
this(format, new LwM2mPath(path), coapRequest);
}

/**
* Create a request for reading an object/instance targeted by a specific path.
* <p>
* This constructor is mainly for internal purpose.
*
* @param format the desired format for the response
* @param target the path to the LWM2M node to read
* @param coapRequest the underlying request
*
* @throws IllegalArgumentException if the target path is not valid
*/
public BootstrapReadRequest(ContentFormat format, LwM2mPath target, Object coapRequest) {
super(target, coapRequest);
if (!target.isObject() && !target.isObjectInstance())
throw new InvalidRequestException("Bootstrap Read request cannot only target Object and Object instance");
this.format = format;
}

/**
* @return the desired format of the resource to read
*/
public ContentFormat getContentFormat() {
return format;
}

@Override
public final String toString() {
return String.format("BootstrapReadRequest [path=%s format=%s]", getPath(), format);
}

@Override
public void accept(DownlinkRequestVisitor visitor) {
visitor.visit(this);

}

@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((format == null) ? 0 : format.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
BootstrapReadRequest other = (BootstrapReadRequest) obj;
if (format != other.format)
return false;
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ public void visit(BootstrapDiscoverRequest request) {
public void visit(BootstrapWriteRequest request) {
}

@Override
public void visit(BootstrapReadRequest request) {
}

@Override
public void visit(BootstrapDeleteRequest request) {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public interface DownlinkRequestVisitor {

void visit(BootstrapWriteRequest request);

void visit(BootstrapReadRequest request);

void visit(BootstrapDeleteRequest request);

void visit(BootstrapFinishRequest request);
Expand Down
Loading

0 comments on commit ecf961a

Please sign in to comment.