Merge pull request #12876 from thingsboard/fix_bug_lwm2m_fota
fix_bug_lwm2m_fota_3
This commit is contained in:
commit
85d070269b
@ -88,7 +88,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0];
|
TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0];
|
||||||
if (securityInfo.getSecurityMode() == null) {
|
if (securityInfo != null && securityInfo.getSecurityMode() == null) {
|
||||||
throw new LwM2MAuthException();
|
throw new LwM2MAuthException();
|
||||||
}
|
}
|
||||||
return securityInfo;
|
return securityInfo;
|
||||||
|
|||||||
@ -18,6 +18,9 @@ package org.thingsboard.server.transport.lwm2m.server;
|
|||||||
import jakarta.annotation.PreDestroy;
|
import jakarta.annotation.PreDestroy;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.eclipse.californium.core.CoapResource;
|
||||||
|
import org.eclipse.californium.core.CoapServer;
|
||||||
|
import org.eclipse.californium.core.config.CoapConfig;
|
||||||
import org.eclipse.californium.elements.config.Configuration;
|
import org.eclipse.californium.elements.config.Configuration;
|
||||||
import org.eclipse.californium.scandium.config.DtlsConfig;
|
import org.eclipse.californium.scandium.config.DtlsConfig;
|
||||||
import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
|
import org.eclipse.californium.scandium.dtls.cipher.CipherSuite;
|
||||||
@ -58,6 +61,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_W
|
|||||||
import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
|
import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
|
||||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig;
|
import static org.thingsboard.server.transport.lwm2m.server.LwM2MNetworkConfig.getCoapConfig;
|
||||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RESOURCE;
|
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RESOURCE;
|
||||||
|
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SOFTWARE_UPDATE_COAP_RESOURCE;
|
||||||
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength;
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.setDtlsConnectorConfigCidLength;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ -85,14 +89,6 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
|
|||||||
@AfterStartUp(order = AfterStartUp.AFTER_TRANSPORT_SERVICE)
|
@AfterStartUp(order = AfterStartUp.AFTER_TRANSPORT_SERVICE)
|
||||||
public void init() {
|
public void init() {
|
||||||
this.server = getLhServer();
|
this.server = getLhServer();
|
||||||
/*
|
|
||||||
* Add a resource to the server.
|
|
||||||
* CoapResource ->
|
|
||||||
* path = FW_PACKAGE or SW_PACKAGE
|
|
||||||
* nameFile = "BC68JAR01A09_TO_BC68JAR01A10.bin"
|
|
||||||
* "coap://host:port/{path}/{token}/{nameFile}"
|
|
||||||
*/
|
|
||||||
new LwM2mTransportCoapResource(otaPackageDataCache, FIRMWARE_UPDATE_COAP_RESOURCE);
|
|
||||||
this.context.setServer(server);
|
this.context.setServer(server);
|
||||||
this.startLhServer();
|
this.startLhServer();
|
||||||
}
|
}
|
||||||
@ -129,6 +125,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
|
|||||||
/* Set securityStore with new registrationStore */
|
/* Set securityStore with new registrationStore */
|
||||||
builder.setSecurityStore(securityStore);
|
builder.setSecurityStore(securityStore);
|
||||||
builder.setRegistrationStore(registrationStore);
|
builder.setRegistrationStore(registrationStore);
|
||||||
|
builder.setAuthorizer(authorizer);
|
||||||
|
|
||||||
|
|
||||||
// Create Californium Endpoints Provider:
|
// Create Californium Endpoints Provider:
|
||||||
@ -191,7 +188,18 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
|
|||||||
|
|
||||||
// Create LWM2M server
|
// Create LWM2M server
|
||||||
builder.setEndpointsProviders(endpointsBuilder.build());
|
builder.setEndpointsProviders(endpointsBuilder.build());
|
||||||
return builder.build();
|
LeshanServer leshanServer = builder.build();
|
||||||
|
CoapServer coapServer = ((CaliforniumServerEndpointsProvider) (leshanServer.getEndpointsProvider()).toArray()[0]).getCoapServer();
|
||||||
|
if (coapServer != null) {
|
||||||
|
CoapResource root = (CoapResource) coapServer.getRoot();
|
||||||
|
if (root == null) {
|
||||||
|
root = new CoapResource("");
|
||||||
|
coapServer.add(root);
|
||||||
|
}
|
||||||
|
root.add(new LwM2mTransportCoapResource(otaPackageDataCache, FIRMWARE_UPDATE_COAP_RESOURCE, serverCoapConfig.get(CoapConfig.PREFERRED_BLOCK_SIZE), serverCoapConfig.get(CoapConfig.MAX_RESOURCE_BODY_SIZE)));
|
||||||
|
root.add(new LwM2mTransportCoapResource(otaPackageDataCache, SOFTWARE_UPDATE_COAP_RESOURCE,serverCoapConfig.get(CoapConfig.PREFERRED_BLOCK_SIZE), serverCoapConfig.get(CoapConfig.MAX_RESOURCE_BODY_SIZE)));
|
||||||
|
}
|
||||||
|
return leshanServer;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setServerWithCredentials(LeshanServerBuilder builder) {
|
private void setServerWithCredentials(LeshanServerBuilder builder) {
|
||||||
|
|||||||
@ -34,16 +34,21 @@ import java.util.concurrent.atomic.AtomicInteger;
|
|||||||
|
|
||||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RESOURCE;
|
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RESOURCE;
|
||||||
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SOFTWARE_UPDATE_COAP_RESOURCE;
|
import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SOFTWARE_UPDATE_COAP_RESOURCE;
|
||||||
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.calculateSzx;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource {
|
public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource {
|
||||||
private final ConcurrentMap<String, ObserveRelation> tokenToObserveRelationMap = new ConcurrentHashMap<>();
|
private final ConcurrentMap<String, ObserveRelation> tokenToObserveRelationMap = new ConcurrentHashMap<>();
|
||||||
private final ConcurrentMap<String, AtomicInteger> tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>();
|
private final ConcurrentMap<String, AtomicInteger> tokenToObserveNotificationSeqMap = new ConcurrentHashMap<>();
|
||||||
private final OtaPackageDataCache otaPackageDataCache;
|
private final OtaPackageDataCache otaPackageDataCache;
|
||||||
|
private final int chunkSize;
|
||||||
|
private final int maxResourceBodySize;
|
||||||
|
|
||||||
public LwM2mTransportCoapResource(OtaPackageDataCache otaPackageDataCache, String name) {
|
public LwM2mTransportCoapResource(OtaPackageDataCache otaPackageDataCache, String name, int chunkSize, int maxResourceBodySize) {
|
||||||
super(name);
|
super(name);
|
||||||
this.otaPackageDataCache = otaPackageDataCache;
|
this.otaPackageDataCache = otaPackageDataCache;
|
||||||
|
this.chunkSize = chunkSize;
|
||||||
|
this.maxResourceBodySize = maxResourceBodySize;
|
||||||
this.setObservable(true); // enable observing
|
this.setObservable(true); // enable observing
|
||||||
this.addObserver(new CoapResourceObserver());
|
this.addObserver(new CoapResourceObserver());
|
||||||
}
|
}
|
||||||
@ -136,22 +141,29 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource {
|
|||||||
String idStr = exchange.getRequestOptions().getUriPath().get(exchange.getRequestOptions().getUriPath().size() - 1
|
String idStr = exchange.getRequestOptions().getUriPath().get(exchange.getRequestOptions().getUriPath().size() - 1
|
||||||
);
|
);
|
||||||
UUID currentId = UUID.fromString(idStr);
|
UUID currentId = UUID.fromString(idStr);
|
||||||
|
log.info("Start Read ota data (path): [{}]", exchange.getRequestOptions().getUriPath().toString());
|
||||||
Response response = new Response(CoAP.ResponseCode.CONTENT);
|
Response response = new Response(CoAP.ResponseCode.CONTENT);
|
||||||
byte[] otaData = this.getOtaData(currentId);
|
byte[] otaData = this.getOtaData(currentId);
|
||||||
if (otaData != null && otaData.length > 0) {
|
if (otaData != null && otaData.length > 0) {
|
||||||
log.debug("Read ota data (length): [{}]", otaData.length);
|
if (otaData.length <= this.maxResourceBodySize) {
|
||||||
|
log.info("Read ota data (length): [{}]", otaData.length);
|
||||||
response.setPayload(otaData);
|
response.setPayload(otaData);
|
||||||
if (exchange.getRequestOptions().getBlock2() != null) {
|
int chunkSize = calculateSzx(this.chunkSize);
|
||||||
int chunkSize = exchange.getRequestOptions().getBlock2().getSzx();
|
if (exchange.getRequestOptions().hasBlock2()) {
|
||||||
boolean lastFlag = otaData.length <= chunkSize;
|
chunkSize = exchange.getRequestOptions().getBlock2().getSzx();
|
||||||
response.getOptions().setBlock2(chunkSize, lastFlag, 0);
|
} else if (exchange.getRequestOptions().hasBlock1()) {
|
||||||
log.trace("With block2 Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), otaData.length, chunkSize, lastFlag);
|
chunkSize = exchange.getRequestOptions().getBlock1().getSzx();
|
||||||
} else {
|
|
||||||
log.trace("With block1 Send currentId: [{}], length: [{}], ", currentId.toString(), otaData.length);
|
|
||||||
}
|
}
|
||||||
|
log.info("With block2 Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), otaData.length, chunkSize, false);
|
||||||
|
boolean lastFlag = otaData.length <= this.chunkSize;
|
||||||
|
response.getOptions().setBlock2(chunkSize, lastFlag, 0);
|
||||||
|
response.setType(CoAP.Type.CON);
|
||||||
exchange.respond(response);
|
exchange.respond(response);
|
||||||
} else {
|
} else {
|
||||||
log.trace("Ota packaged currentId: [{}] is not found.", currentId.toString());
|
log.info("Ota package size: [{}] is larger than server's MAX_RESOURCE_BODY_SIZE [{}]", otaData.length, this.maxResourceBodySize);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.info("Ota packaged currentId: [{}] is not found.", currentId.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -141,7 +141,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
|
|||||||
}
|
}
|
||||||
oldSession = client.getSession();
|
oldSession = client.getSession();
|
||||||
TbLwM2MSecurityInfo securityInfo = securityStore.getTbLwM2MSecurityInfoByEndpoint(client.getEndpoint());
|
TbLwM2MSecurityInfo securityInfo = securityStore.getTbLwM2MSecurityInfoByEndpoint(client.getEndpoint());
|
||||||
if (securityInfo.getSecurityMode() != null) {
|
if (securityInfo != null && securityInfo.getSecurityMode() != null) {
|
||||||
if (SecurityMode.X509.equals(securityInfo.getSecurityMode())) {
|
if (SecurityMode.X509.equals(securityInfo.getSecurityMode())) {
|
||||||
securityStore.registerX509(registration.getEndpoint(), registration.getId());
|
securityStore.registerX509(registration.getEndpoint(), registration.getId());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -393,4 +393,11 @@ public class LwM2MTransportUtil {
|
|||||||
serverCoapConfig.set(DTLS_CONNECTION_ID_NODE_ID, null);
|
serverCoapConfig.set(DTLS_CONNECTION_ID_NODE_ID, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int calculateSzx(int size) {
|
||||||
|
if (size < 16 || size > 1024 || (size & (size - 1)) != 0) {
|
||||||
|
throw new IllegalArgumentException("Size must be a power of 2 between 16 and 1024.");
|
||||||
|
}
|
||||||
|
return (int) (Math.log(size / 16) / Math.log(2));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user