diff --git a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java index 2d5f107d61..4d41b258f3 100644 --- a/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java +++ b/application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java @@ -269,7 +269,9 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor { ToDeviceRpcRequestMetadata requestMd = toDeviceRpcPendingMap.remove(msg.getId()); if (requestMd != null) { log.debug("[{}] RPC request [{}] timeout detected!", deviceId, msg.getId()); - systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), RpcStatus.TIMEOUT, null); + if (requestMd.getMsg().getMsg().isPersisted()) { + systemContext.getTbRpcService().save(tenantId, new RpcId(requestMd.getMsg().getMsg().getId()), RpcStatus.TIMEOUT, null); + } systemContext.getTbCoreDeviceRpcService().processRpcResponseFromDeviceActor(new FromDeviceRpcResponse(requestMd.getMsg().getMsg().getId(), null, requestMd.isSent() ? RpcError.TIMEOUT : RpcError.NO_ACTIVE_CONNECTION)); } diff --git a/application/src/main/resources/logback.xml b/application/src/main/resources/logback.xml index 5f2a47f7ba..caf78e1537 100644 --- a/application/src/main/resources/logback.xml +++ b/application/src/main/resources/logback.xml @@ -26,7 +26,6 @@ - diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java index 81d9d56a8c..c940cd5e85 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/lwm2m/OtherConfiguration.java @@ -27,6 +27,6 @@ public class OtherConfiguration { private PowerMode powerMode; private String fwUpdateResource; private String swUpdateResource; - private boolean composite; + private boolean compositeOperationsSupport; } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java index 5a94a7e3ed..04c6a2b160 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java @@ -62,7 +62,7 @@ public class TbLwM2MAuthorizer implements Authorizer { try { expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); } catch (LwM2MAuthException e) { - log.warn("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint()); + log.info("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint()); return null; } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java index c8443415cc..bbeda58270 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportCoapResource.java @@ -26,6 +26,7 @@ import org.eclipse.californium.core.server.resources.Resource; import org.eclipse.californium.core.server.resources.ResourceObserver; import org.thingsboard.server.cache.ota.OtaPackageDataCache; +import java.util.List; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; @@ -69,17 +70,18 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { @Override protected void processHandleGet(CoapExchange exchange) { - log.warn("90) processHandleGet [{}]", exchange); - if (exchange.getRequestOptions().getUriPath().size() >= 2 && - (FIRMWARE_UPDATE_COAP_RESOURCE.equals(exchange.getRequestOptions().getUriPath().get(exchange.getRequestOptions().getUriPath().size() - 2)) || - SOFTWARE_UPDATE_COAP_RESOURCE.equals(exchange.getRequestOptions().getUriPath().get(exchange.getRequestOptions().getUriPath().size() - 2)))) { + log.debug("processHandleGet [{}]", exchange); + List uriPath = exchange.getRequestOptions().getUriPath(); + if (uriPath.size() >= 2 && + (FIRMWARE_UPDATE_COAP_RESOURCE.equals(uriPath.get(uriPath.size() - 2)) || + SOFTWARE_UPDATE_COAP_RESOURCE.equals(uriPath.get(uriPath.size() - 2)))) { this.sendOtaData(exchange); } } @Override protected void processHandlePost(CoapExchange exchange) { - log.warn("2) processHandleGet [{}]", exchange); + log.debug("processHandlePost [{}]", exchange); } /** @@ -136,16 +138,16 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource { UUID currentId = UUID.fromString(idStr); Response response = new Response(CoAP.ResponseCode.CONTENT); byte[] fwData = this.getOtaData(currentId); - log.warn("91) read softWare data (length): [{}]", fwData.length); + log.debug("Read softWare data (length): [{}]", fwData.length); if (fwData != null && fwData.length > 0) { response.setPayload(fwData); if (exchange.getRequestOptions().getBlock2() != null) { int chunkSize = exchange.getRequestOptions().getBlock2().getSzx(); boolean lastFlag = fwData.length <= chunkSize; response.getOptions().setBlock2(chunkSize, lastFlag, 0); - log.warn("92) with blokc2 Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, lastFlag); + log.trace("With block2 Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, lastFlag); } else { - log.warn("92) with block1 Send currentId: [{}], length: [{}], ", currentId.toString(), fwData.length); + log.trace("With block1 Send currentId: [{}], length: [{}], ", currentId.toString(), fwData.length); } exchange.respond(response); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java index 923c9d7bad..5930825894 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java @@ -16,34 +16,24 @@ package org.thingsboard.server.transport.lwm2m.server; import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.gson.JsonObject; -import com.google.gson.JsonParser; -import com.google.gson.JsonSyntaxException; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.eclipse.leshan.core.attributes.Attribute; import org.eclipse.leshan.core.attributes.AttributeSet; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ResourceModel; -import org.eclipse.leshan.core.node.LwM2mMultipleResource; -import org.eclipse.leshan.core.node.LwM2mNode; -import org.eclipse.leshan.core.node.LwM2mObject; -import org.eclipse.leshan.core.node.LwM2mObjectInstance; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.core.node.LwM2mResource; -import org.eclipse.leshan.core.node.LwM2mSingleResource; import org.eclipse.leshan.core.node.codec.CodecException; import org.eclipse.leshan.core.request.SimpleDownlinkRequest; import org.eclipse.leshan.core.request.WriteAttributesRequest; import org.eclipse.leshan.core.util.Hex; import org.eclipse.leshan.server.registration.Registration; -import org.nustaq.serialization.FSTConfiguration; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration; import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; -import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.transport.lwm2m.config.LwM2mVersion; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; @@ -56,10 +46,8 @@ import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2MUplinkMs import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; @@ -81,7 +69,7 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_RESULT_ID; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_STATE_ID; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_RESULT_ID; -import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_UPDATE_STATE_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_STATE_ID; @Slf4j public class LwM2mTransportUtil { @@ -155,7 +143,7 @@ public class LwM2mTransportUtil { lwM2mOtaConvert.setCurrentType(STRING); lwM2mOtaConvert.setValue(FirmwareUpdateResult.fromUpdateResultFwByCode(((Long) value).intValue()).getType()); return lwM2mOtaConvert; - } else if (SW_UPDATE_STATE_ID.equals(path)) { + } else if (SW_STATE_ID.equals(path)) { lwM2mOtaConvert.setCurrentType(STRING); lwM2mOtaConvert.setValue(SoftwareUpdateState.fromUpdateStateSwByCode(((Long) value).intValue()).type); return lwM2mOtaConvert; @@ -175,7 +163,7 @@ public class LwM2mTransportUtil { if (transportConfiguration.getType().equals(DeviceTransportType.LWM2M)) { return (Lwm2mDeviceProfileTransportConfiguration) transportConfiguration; } else { - log.warn("[{}] Received profile with invalid transport configuration: {}", deviceProfile.getId(), deviceProfile.getProfileData().getTransportConfiguration()); + log.info("[{}] Received profile with invalid transport configuration: {}", deviceProfile.getId(), deviceProfile.getProfileData().getTransportConfiguration()); throw new IllegalArgumentException("Received profile with invalid transport configuration: " + transportConfiguration.getType()); } } @@ -197,7 +185,7 @@ public class LwM2mTransportUtil { return pathIdVer; } } catch (Exception e) { - log.warn("Issue converting path with version [{}] to path without version: ", pathIdVer, e); + log.debug("Issue converting path with version [{}] to path without version: ", pathIdVer, e); throw new RuntimeException(e); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/attributes/DefaultLwM2MAttributesService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/attributes/DefaultLwM2MAttributesService.java index 0f0d95610b..353188c8ff 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/attributes/DefaultLwM2MAttributesService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/attributes/DefaultLwM2MAttributesService.java @@ -23,9 +23,6 @@ import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.core.node.LwM2mResource; import org.springframework.stereotype.Service; -import org.thingsboard.server.common.data.ota.OtaPackageKey; -import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.data.ota.OtaPackageUtil; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.gen.transport.TransportProtos; @@ -126,6 +123,7 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { String newFirmwareUrl = null; String newSoftwareTitle = null; String newSoftwareVersion = null; + String newSoftwareUrl = null; List otherAttributes = new ArrayList<>(); for (TransportProtos.TsKvProto tsKvProto : msg.getSharedUpdatedList()) { String attrName = tsKvProto.getKv().getKey(); @@ -139,7 +137,9 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { newSoftwareTitle = getStrValue(tsKvProto); } else if (DefaultLwM2MOtaUpdateService.SOFTWARE_VERSION.equals(attrName)) { newSoftwareVersion = getStrValue(tsKvProto); - } else { + } else if (DefaultLwM2MOtaUpdateService.SOFTWARE_URL.equals(attrName)) { + newSoftwareUrl = getStrValue(tsKvProto); + }else { otherAttributes.add(tsKvProto); } } @@ -147,7 +147,7 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { otaUpdateService.onTargetFirmwareUpdate(lwM2MClient, newFirmwareTitle, newFirmwareVersion, Optional.ofNullable(newFirmwareUrl)); } if (newSoftwareTitle != null || newSoftwareVersion != null) { - otaUpdateService.onTargetSoftwareUpdate(lwM2MClient, newSoftwareTitle, newSoftwareVersion); + otaUpdateService.onTargetSoftwareUpdate(lwM2MClient, newSoftwareTitle, newSoftwareVersion, Optional.ofNullable(newSoftwareUrl)); } if (!otherAttributes.isEmpty()) { onAttributesUpdate(lwM2MClient, otherAttributes); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index 588c8e77f4..1028e1927d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.transport.lwm2m.server.client; +import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; @@ -62,6 +63,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.f import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getVerFromPathIdVerOrId; @Slf4j +@EqualsAndHashCode(of = {"endpoint"}) public class LwM2mClient implements Serializable { private static final long serialVersionUID = 8793482946289222623L; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java index 8b8186f3db..a7305177e1 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContext.java @@ -58,4 +58,6 @@ public interface LwM2mClientContext { void update(LwM2mClient lwM2MClient); void removeCredentials(TransportProtos.SessionInfoProto sessionInfo); + + void sendMsgsAfterSleeping(LwM2mClient lwM2MClient); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index 178602a16b..04c4cc6bcd 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -21,21 +21,28 @@ import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.server.registration.Registration; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.transport.TransportDeviceProfileCache; +import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.gen.transport.TransportProtos; +import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; +import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService; import org.thingsboard.server.transport.lwm2m.server.session.LwM2MSessionManager; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MClientStore; import org.thingsboard.server.transport.lwm2m.server.store.TbMainSecurityStore; +import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2MUplinkMsgHandler; import java.util.Arrays; import java.util.Collection; @@ -63,10 +70,29 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { private final TbLwM2MClientStore clientStore; private final LwM2MSessionManager sessionManager; private final TransportDeviceProfileCache deviceProfileCache; + + @Autowired + @Lazy + private DefaultLwM2MUplinkMsgHandler defaultLwM2MUplinkMsgHandler; + @Autowired + @Lazy + private LwM2MOtaUpdateService otaUpdateService; + private final Map lwM2mClientsByEndpoint = new ConcurrentHashMap<>(); private final Map lwM2mClientsByRegistrationId = new ConcurrentHashMap<>(); private final Map profiles = new ConcurrentHashMap<>(); + @AfterStartUp + public void init() { + String nodeId = context.getNodeId(); + Set fetchedClients = clientStore.getAll(); + log.debug("Fetched clients from store: {}", fetchedClients); + fetchedClients.forEach(client -> { + lwM2mClientsByEndpoint.put(client.getEndpoint(), client); + updateFetchedClient(nodeId, client); + }); + } + @Override public LwM2mClient getClientByEndpoint(String endpoint) { return lwM2mClientsByEndpoint.computeIfAbsent(endpoint, ep -> { @@ -77,23 +103,27 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { client = new LwM2mClient(nodeId, ep); } else { log.debug("[{}] fetched client from store: {}", endpoint, client); - boolean updated = false; - if (client.getRegistration() != null) { - lwM2mClientsByRegistrationId.put(client.getRegistration().getId(), client); - } - if (client.getSession() != null) { - client.refreshSessionId(nodeId); - sessionManager.register(client.getSession()); - updated = true; - } - if (updated) { - clientStore.put(client); - } + updateFetchedClient(nodeId, client); } return client; }); } + private void updateFetchedClient(String nodeId, LwM2mClient client) { + boolean updated = false; + if (client.getRegistration() != null) { + lwM2mClientsByRegistrationId.put(client.getRegistration().getId(), client); + } + if (client.getSession() != null) { + client.refreshSessionId(nodeId); + sessionManager.register(client.getSession()); + updated = true; + } + if (updated) { + clientStore.put(client); + } + } + @Override public Optional register(LwM2mClient client, Registration registration) throws LwM2MClientStateException { TransportProtos.SessionInfoProto oldSession = null; @@ -142,6 +172,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { } client.setRegistration(registration); clientStore.put(client); + sendMsgsAfterSleeping(client); } finally { client.unlock(); } @@ -232,6 +263,28 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { //TODO: implement } + @Override + public void sendMsgsAfterSleeping(LwM2mClient lwM2MClient) { + if (LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { + PowerMode powerMode = lwM2MClient.getPowerMode(); + if (powerMode == null) { + Lwm2mDeviceProfileTransportConfiguration deviceProfile = getProfile(lwM2MClient.getProfileId()); + powerMode = deviceProfile.getClientLwM2mSettings().getPowerMode(); + } + + if (PowerMode.PSM.equals(powerMode) || PowerMode.E_DRX.equals(powerMode)) { + defaultLwM2MUplinkMsgHandler.initAttributes(lwM2MClient); + TransportProtos.TransportToDeviceActorMsg persistentRpcRequestMsg = TransportProtos.TransportToDeviceActorMsg + .newBuilder() + .setSessionInfo(lwM2MClient.getSession()) + .setSendPendingRPC(TransportProtos.SendPendingRPCMsg.newBuilder().build()) + .build(); + context.getTransportService().process(persistentRpcRequestMsg, TransportServiceCallback.EMPTY); + otaUpdateService.init(lwM2MClient); + } + } + } + @Override public Collection getLwM2mClients() { return lwM2mClientsByEndpoint.values(); @@ -245,22 +298,23 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @Override public Lwm2mDeviceProfileTransportConfiguration getProfile(Registration registration) { UUID profileId = getClientByEndpoint(registration.getEndpoint()).getProfileId(); - Lwm2mDeviceProfileTransportConfiguration result = doGetAndCache(profileId); + return doGetAndCache(profileId); + } + + private Lwm2mDeviceProfileTransportConfiguration doGetAndCache(UUID profileId) { + Lwm2mDeviceProfileTransportConfiguration result = profiles.get(profileId); if (result == null) { - log.debug("[{}] Fetching profile [{}]", registration.getEndpoint(), profileId); + log.debug("Fetching profile [{}]", profileId); DeviceProfile deviceProfile = deviceProfileCache.get(new DeviceProfileId(profileId)); if (deviceProfile != null) { - profileUpdate(deviceProfile); - result = doGetAndCache(profileId); + result = profileUpdate(deviceProfile); + } else { + log.info("Device profile was not found! Most probably device profile [{}] has been removed from the database.", profileId); } } return result; } - private Lwm2mDeviceProfileTransportConfiguration doGetAndCache(UUID profileId) { - return profiles.get(profileId); - } - @Override public Lwm2mDeviceProfileTransportConfiguration profileUpdate(DeviceProfile deviceProfile) { Lwm2mDeviceProfileTransportConfiguration clientProfile = LwM2mTransportUtil.toLwM2MClientProfile(deviceProfile); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java index c6c2f4ea63..fd0fbf4a71 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/DefaultLwM2MOtaUpdateService.java @@ -45,10 +45,12 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest; import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteResponseCallback; import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MClientFwOtaInfo; import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy; import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareDeliveryMethod; import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateResult; import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateState; +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MClientSwOtaInfo; import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy; import org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdateResult; import org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdateState; @@ -91,12 +93,13 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl public static final String FIRMWARE_UPDATE_COAP_RESOURCE = "tbfw"; public static final String SOFTWARE_UPDATE_COAP_RESOURCE = "tbsw"; private static final String FW_PACKAGE_5_ID = "/5/0/0"; + private static final String FW_PACKAGE_19_ID = "/19/0/0"; private static final String FW_URL_ID = "/5/0/1"; private static final String FW_EXECUTE_ID = "/5/0/2"; public static final String FW_STATE_ID = "/5/0/3"; public static final String FW_RESULT_ID = "/5/0/5"; public static final String FW_NAME_ID = "/5/0/6"; - public static final String FW_5_VER_ID = "/5/0/7"; + public static final String FW_VER_ID = "/5/0/7"; /** * Quectel@Hi15RM1-HLB_V1.0@BC68JAR01A10,V150R100C20B300SP7,V150R100C20B300SP7@8 * Revision:BC68JAR01A10 @@ -104,17 +107,19 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl public static final String FW_3_VER_ID = "/3/0/3"; public static final String FW_DELIVERY_METHOD = "/5/0/9"; - private static final String SW_NAME_ID = "/9/0/0"; - private static final String SW_VER_ID = "/9/0/1"; + public static final String SW_3_VER_ID = "/3/0/19"; + + public static final String SW_NAME_ID = "/9/0/0"; + public static final String SW_VER_ID = "/9/0/1"; public static final String SW_PACKAGE_ID = "/9/0/2"; public static final String SW_PACKAGE_URI_ID = "/9/0/3"; public static final String SW_INSTALL_ID = "/9/0/4"; - public static final String SW_UPDATE_STATE_ID = "/9/0/7"; + public static final String SW_STATE_ID = "/9/0/7"; public static final String SW_RESULT_ID = "/9/0/9"; public static final String SW_UN_INSTALL_ID = "/9/0/6"; - private final Map fwStates = new ConcurrentHashMap<>(); - private final Map swStates = new ConcurrentHashMap<>(); + private final Map fwStates = new ConcurrentHashMap<>(); + private final Map swStates = new ConcurrentHashMap<>(); private final TransportService transportService; private final LwM2mClientContext clientContext; @@ -155,27 +160,41 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl //TODO: add locks by client fwInfo. //TODO: check that the client supports FW and SW by checking the supported objects in the model. List attributesToFetch = new ArrayList<>(); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); if (fwInfo.isSupported()) { attributesToFetch.add(FIRMWARE_TITLE); attributesToFetch.add(FIRMWARE_VERSION); attributesToFetch.add(FIRMWARE_URL); } + LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo(client); + if (swInfo.isSupported()) { + attributesToFetch.add(SOFTWARE_TITLE); + attributesToFetch.add(SOFTWARE_VERSION); + attributesToFetch.add(SOFTWARE_URL); + } + if (!attributesToFetch.isEmpty()) { var future = attributesService.getSharedAttributes(client, attributesToFetch); DonAsynchron.withCallback(future, attrs -> { if (fwInfo.isSupported()) { - Optional newFirmwareTitle = getAttributeValue(attrs, FIRMWARE_TITLE); - Optional newFirmwareVersion = getAttributeValue(attrs, FIRMWARE_VERSION); - Optional newFirmwareUrl = getAttributeValue(attrs, FIRMWARE_URL); - if (newFirmwareTitle.isPresent() && newFirmwareVersion.isPresent()) { - onTargetFirmwareUpdate(client, newFirmwareTitle.get(), newFirmwareVersion.get(), newFirmwareUrl); + Optional newFwTitle = getAttributeValue(attrs, FIRMWARE_TITLE); + Optional newFwVersion = getAttributeValue(attrs, FIRMWARE_VERSION); + Optional newFwUrl = getAttributeValue(attrs, FIRMWARE_URL); + if (newFwTitle.isPresent() && newFwVersion.isPresent()) { + onTargetFirmwareUpdate(client, newFwTitle.get(), newFwVersion.get(), newFwUrl); + } + } + if (swInfo.isSupported()) { + Optional newSwTitle = getAttributeValue(attrs, SOFTWARE_TITLE); + Optional newSwVersion = getAttributeValue(attrs, SOFTWARE_VERSION); + Optional newSwUrl = getAttributeValue(attrs, SOFTWARE_URL); + if (newSwTitle.isPresent() && newSwVersion.isPresent()) { + onTargetSoftwareUpdate(client, newSwTitle.get(), newSwVersion.get(), newSwUrl); } } }, throwable -> { if (fwInfo.isSupported()) { - fwInfo.setTargetFetchFailure(true); update(fwInfo); } }, executor); @@ -184,7 +203,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void forceFirmwareUpdate(LwM2mClient client) { - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); fwInfo.setRetryAttempts(0); fwInfo.setFailedPackageId(null); startFirmwareUpdateIfNeeded(client, fwInfo); @@ -192,7 +211,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void onTargetFirmwareUpdate(LwM2mClient client, String newFirmwareTitle, String newFirmwareVersion, Optional newFirmwareUrl) { - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); fwInfo.updateTarget(newFirmwareTitle, newFirmwareVersion, newFirmwareUrl); update(fwInfo); startFirmwareUpdateIfNeeded(client, fwInfo); @@ -201,15 +220,20 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void onCurrentFirmwareNameUpdate(LwM2mClient client, String name) { log.debug("[{}] Current fw name: {}", client.getEndpoint(), name); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); - fwInfo.setCurrentName(name); + getOrInitFwInfo(client).setCurrentName(name); + } + + @Override + public void onCurrentSoftwareNameUpdate(LwM2mClient client, String name) { + log.debug("[{}] Current sw name: {}", client.getEndpoint(), name); + getOrInitSwInfo(client).setCurrentName(name); } @Override public void onFirmwareStrategyUpdate(LwM2mClient client, OtherConfiguration configuration) { log.debug("[{}] Current fw strategy: {}", client.getEndpoint(), configuration.getFwUpdateStrategy()); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); - fwInfo.setFwStrategy(LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(configuration.getFwUpdateStrategy())); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); + fwInfo.setStrategy(LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(configuration.getFwUpdateStrategy())); fwInfo.setBaseUrl(configuration.getFwUpdateResource()); startFirmwareUpdateIfNeeded(client, fwInfo); } @@ -217,30 +241,30 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void onCurrentSoftwareStrategyUpdate(LwM2mClient client, OtherConfiguration configuration) { log.debug("[{}] Current sw strategy: {}", client.getEndpoint(), configuration.getSwUpdateStrategy()); - LwM2MClientOtaInfo swInfo = getOrInitSwInfo(client); - swInfo.setSwStrategy(LwM2MSoftwareUpdateStrategy.fromStrategySwByCode(configuration.getSwUpdateStrategy())); + LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo(client); + swInfo.setStrategy(LwM2MSoftwareUpdateStrategy.fromStrategySwByCode(configuration.getSwUpdateStrategy())); swInfo.setBaseUrl(configuration.getSwUpdateResource()); startSoftwareUpdateIfNeeded(client, swInfo); } @Override public void onCurrentFirmwareVersion3Update(LwM2mClient client, String version) { - log.debug("[{}] Current fw version: {}", client.getEndpoint(), version); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + log.debug("[{}] Current fw version(3): {}", client.getEndpoint(), version); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); fwInfo.setCurrentVersion3(version); } @Override - public void onCurrentFirmwareVersion5Update(LwM2mClient client, String version) { - log.debug("[{}] Current fw version: {}", client.getEndpoint(), version); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); - fwInfo.setCurrentVersion5(version); + public void onCurrentFirmwareVersionUpdate(LwM2mClient client, String version) { + log.debug("[{}] Current fw version(5): {}", client.getEndpoint(), version); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); + fwInfo.setCurrentVersion(version); } @Override public void onCurrentFirmwareStateUpdate(LwM2mClient client, Long stateCode) { log.debug("[{}] Current fw state: {}", client.getEndpoint(), stateCode); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); FirmwareUpdateState state = FirmwareUpdateState.fromStateFwByCode(stateCode.intValue()); if (FirmwareUpdateState.DOWNLOADED.equals(state)) { executeFwUpdate(client); @@ -255,7 +279,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void onCurrentFirmwareResultUpdate(LwM2mClient client, Long code) { log.debug("[{}] Current fw result: {}", client.getEndpoint(), code); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); FirmwareUpdateResult result = FirmwareUpdateResult.fromUpdateResultFwByCode(code.intValue()); Optional status = toOtaPackageUpdateStatus(result); status.ifPresent(otaStatus -> sendStateUpdateToTelemetry(client, fwInfo, @@ -272,16 +296,66 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl @Override public void onCurrentFirmwareDeliveryMethodUpdate(LwM2mClient client, Long value) { log.debug("[{}] Current fw delivery method: {}", client.getEndpoint(), value); - LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client); + LwM2MClientFwOtaInfo fwInfo = getOrInitFwInfo(client); fwInfo.setDeliveryMethod(value.intValue()); } @Override - public void onTargetSoftwareUpdate(LwM2mClient client, String newSoftwareTitle, String newSoftwareVersion) { + public void onCurrentSoftwareVersion3Update(LwM2mClient client, String version) { + log.debug("[{}] Current sw version(3): {}", client.getEndpoint(), version); + getOrInitSwInfo(client).setCurrentVersion3(version); + } + + @Override + public void onCurrentSoftwareVersionUpdate(LwM2mClient client, String version) { + log.debug("[{}] Current sw version(9): {}", client.getEndpoint(), version); + getOrInitSwInfo(client).setCurrentVersion(version); + } + @Override + public void onCurrentSoftwareStateUpdate(LwM2mClient client, Long stateCode) { + log.debug("[{}] Current sw state: {}", client.getEndpoint(), stateCode); + LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo(client); + SoftwareUpdateState state = SoftwareUpdateState.fromUpdateStateSwByCode(stateCode.intValue()); + if (SoftwareUpdateState.INITIAL.equals(state)) { + startSoftwareUpdateIfNeeded(client, swInfo); + } else if (SoftwareUpdateState.DELIVERED.equals(state)) { + executeSwInstall(client); + } + swInfo.setUpdateState(state); + Optional status = toOtaPackageUpdateStatus(state); + status.ifPresent(otaStatus -> sendStateUpdateToTelemetry(client, swInfo, + otaStatus, "Firmware Update State: " + state.name())); + update(swInfo); } - private void startFirmwareUpdateIfNeeded(LwM2mClient client, LwM2MClientOtaInfo fwInfo) { + + @Override + public void onCurrentSoftwareResultUpdate(LwM2mClient client, Long code) { + log.debug("[{}] Current sw result: {}", client.getEndpoint(), code); + LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo(client); + SoftwareUpdateResult result = SoftwareUpdateResult.fromUpdateResultSwByCode(code.intValue()); + Optional status = toOtaPackageUpdateStatus(result); + status.ifPresent(otaStatus -> sendStateUpdateToTelemetry(client, swInfo, + otaStatus, "Firmware Update Result: " + result.name())); + if (result.isAgain() && swInfo.getRetryAttempts() <= 2) { + swInfo.setRetryAttempts(swInfo.getRetryAttempts() + 1); + startSoftwareUpdateIfNeeded(client, swInfo); + } else { + swInfo.update(result); + } + update(swInfo); + } + + @Override + public void onTargetSoftwareUpdate(LwM2mClient client, String newSoftwareTitle, String newSoftwareVersion, Optional newFirmwareUrl) { + LwM2MClientSwOtaInfo fwInfo = getOrInitSwInfo(client); + fwInfo.updateTarget(newSoftwareTitle, newSoftwareVersion, newFirmwareUrl); + update(fwInfo); + startSoftwareUpdateIfNeeded(client, fwInfo); + } + + private void startFirmwareUpdateIfNeeded(LwM2mClient client, LwM2MClientFwOtaInfo fwInfo) { try { if (!fwInfo.isSupported()) { log.debug("[{}] Fw update is not supported: {}", client.getEndpoint(), fwInfo); @@ -289,35 +363,70 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl } else if (fwInfo.isUpdateRequired()) { if (StringUtils.isNotEmpty(fwInfo.getTargetUrl())) { log.debug("[{}] Starting update to [{}{}] using URL: {}", client.getEndpoint(), fwInfo.getTargetName(), fwInfo.getTargetVersion(), fwInfo.getTargetUrl()); - startFirmwareUpdateUsingUrl(client, fwInfo.getTargetUrl()); + startUpdateUsingUrl(client, FW_URL_ID, fwInfo.getTargetUrl()); } else { log.debug("[{}] Starting update to [{}{}] using binary", client.getEndpoint(), fwInfo.getTargetName(), fwInfo.getTargetVersion()); - startFirmwareUpdateUsingBinary(client, fwInfo); + startUpdateUsingBinary(client, fwInfo); } } } catch (Exception e) { - log.warn("[{}] failed to update client: {}", client.getEndpoint(), fwInfo, e); + log.info("[{}] failed to update client: {}", client.getEndpoint(), fwInfo, e); sendStateUpdateToTelemetry(client, fwInfo, OtaPackageUpdateStatus.FAILED, "Internal server error: " + e.getMessage()); } } - private void startSoftwareUpdateIfNeeded(LwM2mClient client, LwM2MClientOtaInfo swInfo) { + private void startSoftwareUpdateIfNeeded(LwM2mClient client, LwM2MClientSwOtaInfo swInfo) { + try { + if (!swInfo.isSupported()) { + log.debug("[{}] Sw update is not supported: {}", client.getEndpoint(), swInfo); + sendStateUpdateToTelemetry(client, swInfo, OtaPackageUpdateStatus.FAILED, "Client does not support software update or profile misconfiguration!"); + } else if (swInfo.isUpdateRequired()) { + if (SoftwareUpdateState.INSTALLED.equals(swInfo.getUpdateState())) { + log.debug("[{}] Attempt to restore the update state: {}", client.getEndpoint(), swInfo.getUpdateState()); + executeSwUninstallForUpdate(client); + } else { + if (StringUtils.isNotEmpty(swInfo.getTargetUrl())) { + log.debug("[{}] Starting update to [{}{}] using URL: {}", client.getEndpoint(), swInfo.getTargetName(), swInfo.getTargetVersion(), swInfo.getTargetUrl()); + startUpdateUsingUrl(client, SW_PACKAGE_URI_ID, swInfo.getTargetUrl()); + } else { + log.debug("[{}] Starting update to [{}{}] using binary", client.getEndpoint(), swInfo.getTargetName(), swInfo.getTargetVersion()); + startUpdateUsingBinary(client, swInfo); + } + } + } + } catch (Exception e) { + log.info("[{}] failed to update client: {}", client.getEndpoint(), swInfo, e); + sendStateUpdateToTelemetry(client, swInfo, OtaPackageUpdateStatus.FAILED, "Internal server error: " + e.getMessage()); + } + } + + public void startUpdateUsingBinary(LwM2mClient client, LwM2MClientSwOtaInfo swInfo) { + this.transportService.process(client.getSession(), createOtaPackageRequestMsg(client.getSession(), swInfo.getType().name()), + new TransportServiceCallback<>() { + @Override + public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { + executor.submit(() -> doUpdateSoftwareUsingBinary(response, swInfo, client)); + } + @Override + public void onError(Throwable e) { + logService.log(client, "Failed to process software update: " + e.getMessage()); + } + }); } - private void startFirmwareUpdateUsingUrl(LwM2mClient client, String url) { - String targetIdVer = convertObjectIdToVersionedId(FW_URL_ID, client.getRegistration()); + private void startUpdateUsingUrl(LwM2mClient client, String id, String url) { + String targetIdVer = convertObjectIdToVersionedId(id, client.getRegistration()); TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(targetIdVer).value(url).timeout(config.getTimeout()).build(); downlinkHandler.sendWriteReplaceRequest(client, request, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, client, targetIdVer)); } - public void startFirmwareUpdateUsingBinary(LwM2mClient client, LwM2MClientOtaInfo fwInfo) { - String versionedId = convertObjectIdToVersionedId(FW_PACKAGE_5_ID, client.getRegistration()); - this.transportService.process(client.getSession(), createOtaPackageRequestMsg(client.getSession(), OtaPackageType.FIRMWARE.name()), + public void startUpdateUsingBinary(LwM2mClient client, LwM2MClientFwOtaInfo fwInfo) { + this.transportService.process(client.getSession(), createOtaPackageRequestMsg(client.getSession(), fwInfo.getType().name()), new TransportServiceCallback<>() { @Override public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { - executor.submit(() -> doUpdateFirmwareUsingBinary(response, fwInfo, versionedId, client)); + executor.submit(() -> doUpdateFirmwareUsingBinary(response, fwInfo, client)); } @Override @@ -327,34 +436,60 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl }); } - private void doUpdateFirmwareUsingBinary(TransportProtos.GetOtaPackageResponseMsg response, LwM2MClientOtaInfo fwInfo, String versionedId, LwM2mClient client) { + private void doUpdateFirmwareUsingBinary(TransportProtos.GetOtaPackageResponseMsg response, LwM2MClientFwOtaInfo info, LwM2mClient client) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { UUID otaPackageId = new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()); LwM2MFirmwareUpdateStrategy strategy; - if (fwInfo.getDeliveryMethod() == null || fwInfo.getDeliveryMethod() == FirmwareDeliveryMethod.BOTH.code) { - strategy = fwInfo.getFwStrategy(); + if (info.getDeliveryMethod() == null || info.getDeliveryMethod() == FirmwareDeliveryMethod.BOTH.code) { + strategy = info.getStrategy(); } else { - strategy = fwInfo.getDeliveryMethod() == FirmwareDeliveryMethod.PULL.code ? LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY; + strategy = info.getDeliveryMethod() == FirmwareDeliveryMethod.PULL.code ? LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY; } switch (strategy) { case OBJ_5_BINARY: - byte[] firmwareChunk = otaPackageDataCache.get(otaPackageId.toString(), 0, 0); - TbLwM2MWriteReplaceRequest writeRequest = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId) - .value(firmwareChunk).contentFormat(ContentFormat.OPAQUE) - .timeout(config.getTimeout()).build(); - downlinkHandler.sendWriteReplaceRequest(client, writeRequest, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, client, versionedId)); + startUpdateUsingBinary(client, convertObjectIdToVersionedId(FW_PACKAGE_5_ID, client.getRegistration()), otaPackageId); + break; + case OBJ_19_BINARY: + startUpdateUsingBinary(client, convertObjectIdToVersionedId(FW_PACKAGE_19_ID, client.getRegistration()), otaPackageId); break; case OBJ_5_TEMP_URL: - startFirmwareUpdateUsingUrl(client, fwInfo.getBaseUrl() + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId.toString()); + startUpdateUsingUrl(client, FW_URL_ID, info.getBaseUrl() + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId.toString()); + break; + default: + sendStateUpdateToTelemetry(client, info, OtaPackageUpdateStatus.FAILED, "Unsupported strategy: " + strategy.name()); + } + } else { + sendStateUpdateToTelemetry(client, info, OtaPackageUpdateStatus.FAILED, "Failed to fetch OTA package: " + response.getResponseStatus()); + } + } + + private void doUpdateSoftwareUsingBinary(TransportProtos.GetOtaPackageResponseMsg response, LwM2MClientSwOtaInfo info, LwM2mClient client) { + if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { + UUID otaPackageId = new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB()); + LwM2MSoftwareUpdateStrategy strategy = info.getStrategy(); + switch (strategy) { + case BINARY: + startUpdateUsingBinary(client, convertObjectIdToVersionedId(SW_PACKAGE_ID, client.getRegistration()), otaPackageId); + break; + case TEMP_URL: + startUpdateUsingUrl(client, SW_PACKAGE_URI_ID, info.getBaseUrl() + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId.toString()); break; default: - sendStateUpdateToTelemetry(client, fwInfo, OtaPackageUpdateStatus.FAILED, "Unsupported strategy: " + strategy.name()); + sendStateUpdateToTelemetry(client, info, OtaPackageUpdateStatus.FAILED, "Unsupported strategy: " + strategy.name()); } } else { - sendStateUpdateToTelemetry(client, fwInfo, OtaPackageUpdateStatus.FAILED, "Failed to fetch OTA package: " + response.getResponseStatus()); + sendStateUpdateToTelemetry(client, info, OtaPackageUpdateStatus.FAILED, "Failed to fetch OTA package: " + response.getResponseStatus()); } } + private void startUpdateUsingBinary(LwM2mClient client, String versionedId, UUID otaPackageId) { + byte[] firmwareChunk = otaPackageDataCache.get(otaPackageId.toString(), 0, 0); + TbLwM2MWriteReplaceRequest writeRequest = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId) + .value(firmwareChunk).contentFormat(ContentFormat.OPAQUE) + .timeout(config.getTimeout()).build(); + downlinkHandler.sendWriteReplaceRequest(client, writeRequest, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, client, versionedId)); + } + private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(TransportProtos.SessionInfoProto sessionInfo, String nameFwSW) { return TransportProtos.GetOtaPackageRequestMsg.newBuilder() .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) @@ -370,6 +505,16 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, FW_EXECUTE_ID)); } + private void executeSwInstall(LwM2mClient client) { + TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(SW_INSTALL_ID).timeout(config.getTimeout()).build(); + downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, SW_INSTALL_ID)); + } + + private void executeSwUninstallForUpdate(LwM2mClient client) { + TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(SW_UN_INSTALL_ID).params("1").timeout(config.getTimeout()).build(); + downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, SW_INSTALL_ID)); + } + private Optional getAttributeValue(List attrs, String keyName) { for (TransportProtos.TsKvProto attr : attrs) { if (keyName.equals(attr.getKv().getKey())) { @@ -383,40 +528,41 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl return Optional.empty(); } - public LwM2MClientOtaInfo getOrInitFwInfo(LwM2mClient client) { + private LwM2MClientFwOtaInfo getOrInitFwInfo(LwM2mClient client) { return this.fwStates.computeIfAbsent(client.getEndpoint(), endpoint -> { - LwM2MClientOtaInfo info = otaInfoStore.get(OtaPackageType.FIRMWARE, endpoint); + LwM2MClientFwOtaInfo info = otaInfoStore.getFw(endpoint); if (info == null) { var profile = clientContext.getProfile(client.getProfileId()); - info = new LwM2MClientOtaInfo(endpoint, OtaPackageType.FIRMWARE, - LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(profile.getClientLwM2mSettings().getFwUpdateStrategy()), - profile.getClientLwM2mSettings().getFwUpdateResource()); + info = new LwM2MClientFwOtaInfo(endpoint, profile.getClientLwM2mSettings().getFwUpdateResource(), + LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(profile.getClientLwM2mSettings().getFwUpdateStrategy())); update(info); } return info; }); } - private LwM2MClientOtaInfo getOrInitSwInfo(LwM2mClient client) { - return this.fwStates.computeIfAbsent(client.getEndpoint(), endpoint -> { - LwM2MClientOtaInfo info = otaInfoStore.get(OtaPackageType.SOFTWARE, endpoint); + private LwM2MClientSwOtaInfo getOrInitSwInfo(LwM2mClient client) { + return this.swStates.computeIfAbsent(client.getEndpoint(), endpoint -> { + LwM2MClientSwOtaInfo info = otaInfoStore.getSw(endpoint); if (info == null) { var profile = clientContext.getProfile(client.getProfileId()); - info = new LwM2MClientOtaInfo(endpoint, OtaPackageType.SOFTWARE, - LwM2MSoftwareUpdateStrategy.fromStrategySwByCode(profile.getClientLwM2mSettings().getFwUpdateStrategy()), - profile.getClientLwM2mSettings().getSwUpdateResource()); + info = new LwM2MClientSwOtaInfo(endpoint, profile.getClientLwM2mSettings().getSwUpdateResource(), + LwM2MSoftwareUpdateStrategy.fromStrategySwByCode(profile.getClientLwM2mSettings().getFwUpdateStrategy())); update(info); } return info; }); + } + private void update(LwM2MClientFwOtaInfo info) { + otaInfoStore.putFw(info); } - private void update(LwM2MClientOtaInfo info) { - otaInfoStore.put(info); + private void update(LwM2MClientSwOtaInfo info) { + otaInfoStore.putSw(info); } - private void sendStateUpdateToTelemetry(LwM2mClient client, LwM2MClientOtaInfo fwInfo, OtaPackageUpdateStatus status, String log) { + private void sendStateUpdateToTelemetry(LwM2mClient client, LwM2MClientOtaInfo fwInfo, OtaPackageUpdateStatus status, String log) { List result = new ArrayList<>(); TransportProtos.KeyValueProto.Builder kvProto = TransportProtos.KeyValueProto.newBuilder().setKey(getAttributeKey(fwInfo.getType(), STATE)); kvProto.setType(TransportProtos.KeyValueType.STRING_V).setStringV(status.name()); @@ -462,22 +608,31 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl } } + private static Optional toOtaPackageUpdateStatus(SoftwareUpdateState swUpdateState) { + switch (swUpdateState) { + case INITIAL: + return Optional.empty(); + case DOWNLOAD_STARTED: + return Optional.of(DOWNLOADING); + case DOWNLOADED: + return Optional.of(DOWNLOADING); + case DELIVERED: + return Optional.of(DOWNLOADED); + case INSTALLED: + return Optional.empty(); + default: + throw new CodecException("Invalid value stateSw %d for SoftwareUpdateState.", swUpdateState); + } + } + /** * FirmwareUpdateStatus { * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED */ - public static Optional toSwSateResultUpdateStatus(SoftwareUpdateState softwareUpdateState, SoftwareUpdateResult softwareUpdateResult) { + public static Optional toOtaPackageUpdateStatus(SoftwareUpdateResult softwareUpdateResult) { switch (softwareUpdateResult) { case INITIAL: - switch (softwareUpdateState) { - case INITIAL: - case DOWNLOAD_STARTED: - return Optional.of(DOWNLOADING); - case DOWNLOADED: - return Optional.of(DOWNLOADED); - case DELIVERED: - return Optional.of(VERIFIED); - } + return Optional.empty(); case DOWNLOADING: return Optional.of(DOWNLOADING); case SUCCESSFULLY_INSTALLED: @@ -495,7 +650,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl case UN_INSTALL_FAILURE: return Optional.of(FAILED); default: - throw new CodecException("Invalid value stateFw %s %s for FirmwareUpdateStatus.", softwareUpdateState.name(), softwareUpdateResult.name()); + throw new CodecException("Invalid value stateFw %s for FirmwareUpdateStatus.", softwareUpdateResult.name()); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MClientOtaInfo.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MClientOtaInfo.java index 260c266906..48936862f3 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MClientOtaInfo.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MClientOtaInfo.java @@ -20,60 +20,42 @@ import lombok.Data; import lombok.NoArgsConstructor; import org.thingsboard.server.common.data.StringUtils; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy; -import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateResult; -import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateState; -import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy; import java.util.Optional; @Data @NoArgsConstructor -public class LwM2MClientOtaInfo { +public abstract class LwM2MClientOtaInfo { private String endpoint; - private OtaPackageType type; - private String baseUrl; - private boolean targetFetchFailure; - private String targetName; - private String targetVersion; - private String targetUrl; - - private boolean currentFetchFailure; - private String currentName; - private String currentVersion3; - private String currentVersion5; - private Integer deliveryMethod; + protected String targetName; + protected String targetVersion; + protected String targetUrl; //TODO: use value from device if applicable; - private LwM2MFirmwareUpdateStrategy fwStrategy; - private LwM2MSoftwareUpdateStrategy swStrategy; - private FirmwareUpdateState updateState; - private FirmwareUpdateResult updateResult; + protected Strategy strategy; + protected State updateState; + protected Result result; - private String failedPackageId; - private int retryAttempts; + protected String failedPackageId; + protected int retryAttempts; - public LwM2MClientOtaInfo(String endpoint, OtaPackageType type, LwM2MFirmwareUpdateStrategy fwStrategy, String baseUrl) { - this.endpoint = endpoint; - this.type = type; - this.fwStrategy = fwStrategy; - this.baseUrl = baseUrl; - } + protected String currentName; + protected String currentVersion3; + protected String currentVersion; - public LwM2MClientOtaInfo(String endpoint, OtaPackageType type, LwM2MSoftwareUpdateStrategy swStrategy, String baseUrl) { + public LwM2MClientOtaInfo(String endpoint, String baseUrl, Strategy strategy) { this.endpoint = endpoint; - this.type = type; - this.swStrategy = swStrategy; this.baseUrl = baseUrl; + this.strategy = strategy; } - public void updateTarget(String targetName, String targetVersion, Optional newFirmwareUrl) { + public void updateTarget(String targetName, String targetVersion, Optional newTargetUrl) { this.targetName = targetName; this.targetVersion = targetVersion; - this.targetUrl = newFirmwareUrl.orElse(null); + this.targetUrl = newTargetUrl.orElse(null); } @JsonIgnore @@ -82,7 +64,7 @@ public class LwM2MClientOtaInfo { return false; } else { String targetPackageId = getPackageId(targetName, targetVersion); - String currentPackageIdUsingObject5 = getPackageId(currentName, currentVersion5); + String currentPackageIdUsingObject5 = getPackageId(currentName, currentVersion); if (StringUtils.isNotEmpty(failedPackageId) && failedPackageId.equals(targetPackageId)) { return false; } else { @@ -99,25 +81,15 @@ public class LwM2MClientOtaInfo { @JsonIgnore public boolean isSupported() { - return StringUtils.isNotEmpty(currentName) || StringUtils.isNotEmpty(currentVersion5) || StringUtils.isNotEmpty(currentVersion3); + return StringUtils.isNotEmpty(currentName) || StringUtils.isNotEmpty(currentVersion) || StringUtils.isNotEmpty(currentVersion3); } - public void update(FirmwareUpdateResult updateResult) { - this.updateResult = updateResult; - switch (updateResult) { - case INITIAL: - break; - case UPDATE_SUCCESSFULLY: - retryAttempts = 0; - break; - default: - failedPackageId = getPackageId(targetName, targetVersion); - break; - } - } + public abstract void update(Result result); - private static String getPackageId(String name, String version) { + protected static String getPackageId(String name, String version) { return (StringUtils.isNotEmpty(name) ? name : "") + (StringUtils.isNotEmpty(version) ? version : ""); } + public abstract OtaPackageType getType(); + } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MOtaUpdateService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MOtaUpdateService.java index 2aa7f39872..df9505f887 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MOtaUpdateService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/LwM2MOtaUpdateService.java @@ -26,9 +26,9 @@ public interface LwM2MOtaUpdateService { void forceFirmwareUpdate(LwM2mClient client); - void onTargetFirmwareUpdate(LwM2mClient client, String newFirmwareTitle, String newFirmwareVersion, Optional newFirmwareUrl); + void onTargetFirmwareUpdate(LwM2mClient client, String newFwTitle, String newFwVersion, Optional newFwUrl); - void onTargetSoftwareUpdate(LwM2mClient client, String newSoftwareTitle, String newSoftwareVersion); + void onTargetSoftwareUpdate(LwM2mClient client, String newSwTitle, String newSwVersion, Optional newSwUrl); void onCurrentFirmwareNameUpdate(LwM2mClient client, String name); @@ -38,11 +38,21 @@ public interface LwM2MOtaUpdateService { void onCurrentFirmwareVersion3Update(LwM2mClient client, String version); - void onCurrentFirmwareVersion5Update(LwM2mClient client, String version); + void onCurrentFirmwareVersionUpdate(LwM2mClient client, String version); void onCurrentFirmwareStateUpdate(LwM2mClient client, Long state); void onCurrentFirmwareResultUpdate(LwM2mClient client, Long result); void onCurrentFirmwareDeliveryMethodUpdate(LwM2mClient lwM2MClient, Long value); + + void onCurrentSoftwareNameUpdate(LwM2mClient lwM2MClient, String name); + + void onCurrentSoftwareVersion3Update(LwM2mClient lwM2MClient, String version); + + void onCurrentSoftwareVersionUpdate(LwM2mClient client, String version); + + void onCurrentSoftwareStateUpdate(LwM2mClient lwM2MClient, Long value); + + void onCurrentSoftwareResultUpdate(LwM2mClient client, Long result); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/LwM2MClientFwOtaInfo.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/LwM2MClientFwOtaInfo.java new file mode 100644 index 0000000000..49faa2760d --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/LwM2MClientFwOtaInfo.java @@ -0,0 +1,56 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.server.ota.firmware; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class LwM2MClientFwOtaInfo extends LwM2MClientOtaInfo { + + private Integer deliveryMethod; + + public LwM2MClientFwOtaInfo(String endpoint, String baseUrl, LwM2MFirmwareUpdateStrategy strategy) { + super(endpoint, baseUrl, strategy); + } + + @JsonIgnore + @Override + public OtaPackageType getType() { + return OtaPackageType.FIRMWARE; + } + + public void update(FirmwareUpdateResult result) { + this.result = result; + switch (result) { + case INITIAL: + break; + case UPDATE_SUCCESSFULLY: + retryAttempts = 0; + break; + default: + failedPackageId = getPackageId(targetName, targetVersion); + break; + } + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/LwM2MClientSwOtaInfo.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/LwM2MClientSwOtaInfo.java new file mode 100644 index 0000000000..76795d922f --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/LwM2MClientSwOtaInfo.java @@ -0,0 +1,57 @@ +/** + * Copyright © 2016-2021 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.transport.lwm2m.server.ota.software; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import lombok.Data; +import lombok.EqualsAndHashCode; +import lombok.NoArgsConstructor; +import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.ota.OtaPackageType; +import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateResult; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateState; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy; + +@Data +@EqualsAndHashCode(callSuper = true) +@NoArgsConstructor +public class LwM2MClientSwOtaInfo extends LwM2MClientOtaInfo { + + public LwM2MClientSwOtaInfo(String endpoint, String baseUrl, LwM2MSoftwareUpdateStrategy strategy) { + super(endpoint, baseUrl, strategy); + } + + @JsonIgnore + @Override + public OtaPackageType getType() { + return OtaPackageType.SOFTWARE; + } + + + public void update(SoftwareUpdateResult result) { + this.result = result; + switch (result) { + case INITIAL: + break; + //TODO: implement + default: + failedPackageId = getPackageId(targetName, targetVersion); + break; + } + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/SoftwareUpdateResult.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/SoftwareUpdateResult.java index e99d4e4aca..7bf5473a1b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/SoftwareUpdateResult.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/SoftwareUpdateResult.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.transport.lwm2m.server.ota.software; +import lombok.Getter; + /** * SW Update Result * Contains the result of downloading or installing/uninstalling the software @@ -56,6 +58,7 @@ public enum SoftwareUpdateResult { public int code; public String type; + @Getter public boolean isAgain; SoftwareUpdateResult(int code, String type, boolean isAgain) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java index dd263b33e0..ee195dbbe3 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/DefaultLwM2MRpcRequestHandler.java @@ -82,7 +82,7 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg rpcRequst, TransportProtos.SessionInfoProto sessionInfo) { this.cleanupOldSessions(); UUID requestUUID = new UUID(rpcRequst.getRequestIdMSB(), rpcRequst.getRequestIdLSB()); - log.warn("Received params: {}", rpcRequst.getParams()); + log.debug("Received params: {}", rpcRequst.getParams()); // We use this map to protect from browser issue that the same command is sent twice. // TODO: This is probably not the best place and should be moved to DeviceActor if (!this.rpcSubscriptions.containsKey(requestUUID)) { @@ -324,20 +324,19 @@ public class DefaultLwM2MRpcRequestHandler implements LwM2MRpcRequestHandler { } private void cleanupOldSessions() { - log.warn("4.1) before rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); + log.debug("Before rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); if (rpcSubscriptions.size() > 0) { long currentTime = System.currentTimeMillis(); Set rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> currentTime > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); - log.warn("4.2) System.currentTimeMillis(): [{}]", System.currentTimeMillis()); - log.warn("4.3) rpcSubscriptionsToRemove: [{}]", rpcSubscriptionsToRemove); + log.debug("RpcSubscriptionsToRemove: [{}]", rpcSubscriptionsToRemove); rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); } - log.warn("4.4) after rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); + log.debug("After rpcSubscriptions.size(): [{}]", rpcSubscriptions.size()); } @Override public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, TransportProtos.SessionInfoProto sessionInfo) { - log.warn("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); + log.debug("OnToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); transportService.process(sessionInfo, toDeviceResponse, null); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientOtaInfoStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientOtaInfoStore.java index ee46adcdf8..14b5ce476a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientOtaInfoStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientOtaInfoStore.java @@ -15,18 +15,28 @@ */ package org.thingsboard.server.transport.lwm2m.server.store; -import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MClientFwOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MClientSwOtaInfo; public class TbDummyLwM2MClientOtaInfoStore implements TbLwM2MClientOtaInfoStore { @Override - public LwM2MClientOtaInfo get(OtaPackageType type, String endpoint) { + public LwM2MClientFwOtaInfo getFw(String endpoint) { return null; } @Override - public void put(LwM2MClientOtaInfo info) { + public LwM2MClientSwOtaInfo getSw(String endpoint) { + return null; + } + + @Override + public void putFw(LwM2MClientFwOtaInfo info) { + + } + + @Override + public void putSw(LwM2MClientSwOtaInfo info) { } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientStore.java index 3708bf4b0e..767ab43493 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbDummyLwM2MClientStore.java @@ -17,12 +17,20 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; +import java.util.Collections; +import java.util.Set; + public class TbDummyLwM2MClientStore implements TbLwM2MClientStore { @Override public LwM2mClient get(String endpoint) { return null; } + @Override + public Set getAll() { + return Collections.emptySet(); + } + @Override public void put(LwM2mClient client) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientOtaInfoStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientOtaInfoStore.java index b80321ccfb..fb7bff4337 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientOtaInfoStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientOtaInfoStore.java @@ -17,10 +17,16 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MClientFwOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MClientSwOtaInfo; public interface TbLwM2MClientOtaInfoStore { - LwM2MClientOtaInfo get(OtaPackageType type, String endpoint); + LwM2MClientFwOtaInfo getFw(String endpoint); - void put(LwM2MClientOtaInfo info); + LwM2MClientSwOtaInfo getSw(String endpoint); + + void putFw(LwM2MClientFwOtaInfo info); + + void putSw(LwM2MClientSwOtaInfo info); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientStore.java index 16e4e9e90a..55b0423b05 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2MClientStore.java @@ -17,10 +17,14 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; +import java.util.Set; + public interface TbLwM2MClientStore { LwM2mClient get(String endpoint); + Set getAll(); + void put(LwM2mClient client); void remove(String endpoint); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java index 36283ef3ff..fcc588473a 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisClientOtaInfoStore.java @@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException; import org.eclipse.leshan.server.security.SecurityInfo; +import org.jetbrains.annotations.Nullable; import org.nustaq.serialization.FSTConfiguration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.integration.redis.util.RedisLockRegistry; @@ -24,6 +25,8 @@ import org.thingsboard.common.util.JacksonUtil; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MClientFwOtaInfo; +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MClientSwOtaInfo; import java.util.concurrent.locks.Lock; @@ -36,19 +39,36 @@ public class TbLwM2mRedisClientOtaInfoStore implements TbLwM2MClientOtaInfoStore this.connectionFactory = connectionFactory; } - @Override - public LwM2MClientOtaInfo get(OtaPackageType type, String endpoint) { + private void put(OtaPackageType type, LwM2MClientOtaInfo info) { try (var connection = connectionFactory.getConnection()) { - byte[] data = connection.get((OTA_EP + type + endpoint).getBytes()); - return JacksonUtil.fromBytes(data, LwM2MClientOtaInfo.class); + connection.set((OTA_EP + type + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); } } @Override - public void put(LwM2MClientOtaInfo info) { + public LwM2MClientFwOtaInfo getFw(String endpoint) { + return getLwM2MClientOtaInfo(OtaPackageType.FIRMWARE, endpoint, LwM2MClientFwOtaInfo.class); + } + + @Override + public void putFw(LwM2MClientFwOtaInfo info) { + put(OtaPackageType.FIRMWARE, info); + } + + @Override + public LwM2MClientSwOtaInfo getSw(String endpoint) { + return getLwM2MClientOtaInfo(OtaPackageType.SOFTWARE, endpoint, LwM2MClientSwOtaInfo.class); + } + + @Override + public void putSw(LwM2MClientSwOtaInfo info) { + put(OtaPackageType.SOFTWARE, info); + } + + private > T getLwM2MClientOtaInfo(OtaPackageType type, String endpoint, Class clazz) { try (var connection = connectionFactory.getConnection()) { - connection.set((OTA_EP + info.getType() + info.getEndpoint()).getBytes(), JacksonUtil.toString(info).getBytes()); + byte[] data = connection.get((OTA_EP + type + endpoint).getBytes()); + return JacksonUtil.fromBytes(data, clazz); } } - } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java index bf1f275f32..ac0d3d0e68 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mSecurityStore.java @@ -23,12 +23,9 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo; import java.util.HashSet; -import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.CLIENT; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java index a408cc22c4..d735eed26e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbRedisLwM2MClientStore.java @@ -16,9 +16,17 @@ package org.thingsboard.server.transport.lwm2m.server.store; import org.nustaq.serialization.FSTConfiguration; +import org.springframework.data.redis.connection.RedisClusterConnection; import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.Cursor; +import org.springframework.data.redis.core.ScanOptions; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { private static final String CLIENT_EP = "CLIENT#EP#"; @@ -42,6 +50,30 @@ public class TbRedisLwM2MClientStore implements TbLwM2MClientStore { } } + @Override + public Set getAll() { + try (var connection = connectionFactory.getConnection()) { + Set clients = new HashSet<>(); + ScanOptions scanOptions = ScanOptions.scanOptions().count(100).match(CLIENT_EP + "*").build(); + List> scans = new ArrayList<>(); + if (connection instanceof RedisClusterConnection) { + ((RedisClusterConnection) connection).clusterGetNodes().forEach(node -> { + scans.add(((RedisClusterConnection) connection).scan(node, scanOptions)); + }); + } else { + scans.add(connection.scan(scanOptions)); + } + + scans.forEach(scan -> { + scan.forEachRemaining(key -> { + byte[] element = connection.get(key); + clients.add((LwM2mClient) serializer.asObject(element)); + }); + }); + return clients; + } + } + @Override public void put(LwM2mClient client) { byte[] clientSerialized = serializer.asByteArray(client); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java index ed2a1802ff..8f8e4f307e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java @@ -42,7 +42,6 @@ import org.thingsboard.common.util.DonAsynchron; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.StringUtils; -import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; @@ -111,11 +110,16 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertOtaUpdateValueToString; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_3_VER_ID; -import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_5_VER_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_VER_ID; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_DELIVERY_METHOD; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_RESULT_ID; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_STATE_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_3_VER_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_NAME_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_RESULT_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_STATE_ID; +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_VER_ID; @Slf4j @@ -238,7 +242,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl executor.submit(() -> { LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); try { - log.warn("[{}] [{{}] Client: update after Registration", registration.getEndpoint(), registration.getId()); + log.info("[{}] [{{}] Client: update after Registration", registration.getEndpoint(), registration.getId()); logService.log(lwM2MClient, String.format("[%s][%s] Updated registration.", registration.getId(), registration.getSocketAddress())); clientContext.updateRegistration(lwM2MClient, registration); this.reportActivityAndRegister(lwM2MClient.getSession()); @@ -318,7 +322,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl } public void onUpdateValueAfterReadCompositeResponse(Registration registration, ReadCompositeResponse response) { - log.warn("201) ReadCompositeResponse: [{}]", response); + log.trace("ReadCompositeResponse: [{}]", response); if (response.getContent() != null) { LwM2mClient lwM2MClient = clientContext.getClientByEndpoint(registration.getEndpoint()); response.getContent().forEach((k, v) -> { @@ -387,26 +391,9 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl @Override public void onAwakeDev(Registration registration) { log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); - LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); - logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client is awake!"); - - if (LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { - PowerMode powerMode = lwM2MClient.getPowerMode(); - if (powerMode == null) { - Lwm2mDeviceProfileTransportConfiguration deviceProfile = clientContext.getProfile(lwM2MClient.getProfileId()); - powerMode = deviceProfile.getClientLwM2mSettings().getPowerMode(); - } - - if (PowerMode.PSM.equals(powerMode) || PowerMode.E_DRX.equals(powerMode)) { - initAttributes(lwM2MClient); - TransportProtos.TransportToDeviceActorMsg persistentRpcRequestMsg = TransportProtos.TransportToDeviceActorMsg - .newBuilder() - .setSessionInfo(lwM2MClient.getSession()) - .setSendPendingRPC(TransportProtos.SendPendingRPCMsg.newBuilder().build()) - .build(); - transportService.process(persistentRpcRequestMsg, TransportServiceCallback.EMPTY); - } - } + LwM2mClient client = this.clientContext.getClientByEndpoint(registration.getEndpoint()); + logService.log(client, LOG_LWM2M_INFO + ": Client is awake!"); + clientContext.sendMsgsAfterSleeping(client); } /** @@ -424,7 +411,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); Set supportedObjects = clientContext.getSupportedIdVerInClient(lwM2MClient); if (supportedObjects != null && supportedObjects.size() > 0) { - // #1 this.sendReadRequests(lwM2MClient, profile, supportedObjects); this.sendObserveRequests(lwM2MClient, profile, supportedObjects); this.sendWriteAttributeRequests(lwM2MClient, profile, supportedObjects); @@ -537,14 +523,24 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl otaService.onCurrentFirmwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); } else if (path.equals(convertObjectIdToVersionedId(FW_3_VER_ID, registration))) { otaService.onCurrentFirmwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); - } else if (path.equals(convertObjectIdToVersionedId(FW_5_VER_ID, registration))) { - otaService.onCurrentFirmwareVersion5Update(lwM2MClient, (String) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(FW_VER_ID, registration))) { + otaService.onCurrentFirmwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); } else if (path.equals(convertObjectIdToVersionedId(FW_STATE_ID, registration))) { otaService.onCurrentFirmwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); } else if (path.equals(convertObjectIdToVersionedId(FW_RESULT_ID, registration))) { otaService.onCurrentFirmwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); } else if (path.equals(convertObjectIdToVersionedId(FW_DELIVERY_METHOD, registration))) { otaService.onCurrentFirmwareDeliveryMethodUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(SW_NAME_ID, registration))) { + otaService.onCurrentSoftwareNameUpdate(lwM2MClient, (String) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(SW_VER_ID, registration))) { + otaService.onCurrentSoftwareVersionUpdate(lwM2MClient, (String) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(SW_3_VER_ID, registration))) { + otaService.onCurrentSoftwareVersion3Update(lwM2MClient, (String) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(SW_STATE_ID, registration))) { + otaService.onCurrentSoftwareStateUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); + } else if (path.equals(convertObjectIdToVersionedId(SW_RESULT_ID, registration))) { + otaService.onCurrentSoftwareResultUpdate(lwM2MClient, (Long) lwM2mResource.getValue()); } this.updateAttrTelemetry(registration, Collections.singleton(path)); } else { @@ -704,7 +700,7 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl @Override public void onWriteCompositeResponseOk(LwM2mClient client, WriteCompositeRequest request) { - log.warn("202) ReadCompositeResponse: [{}]", request.getNodes()); + log.trace("ReadCompositeResponse: [{}]", request.getNodes()); request.getNodes().forEach((k, v) -> { this.updateResourcesValue(client, (LwM2mResource) v, k.toString()); }); diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java index 64efb5f036..2a0419b43d 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttSslHandlerProvider.java @@ -55,7 +55,6 @@ import java.util.concurrent.TimeUnit; */ @Slf4j @Component("MqttSslHandlerProvider") -@ConditionalOnExpression("'${transport.mqtt.enabled}'=='true'") @ConditionalOnProperty(prefix = "transport.mqtt.ssl", value = "enabled", havingValue = "true", matchIfMissing = false) public class MqttSslHandlerProvider { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java index 30f263cba4..f160936c7c 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportContext.java @@ -52,7 +52,7 @@ public class MqttTransportContext extends TransportContext { private Integer maxPayloadSize; @Getter - @Value("${transport.mqtt.netty.skip_validity_check_for_client_cert:false}") + @Value("${transport.mqtt.ssl.skip_validity_check_for_client_cert:false}") private boolean skipValidityCheckForClientCert; @Getter diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html index a54a33733d..571820acb2 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html @@ -168,6 +168,8 @@ + {{ 'device-profile.lwm2m.composite-operations-support' | translate }} diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.scss b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.scss index 25532ec165..c096e5462a 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.scss +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.scss @@ -24,4 +24,8 @@ color: rgba(0, 0, 0, .7); } } + + .mat-slider { + margin: 8px 0 8px 10px; + } } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index 90f68bb92c..777431ea3a 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -117,7 +117,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro swUpdateStrategy: [1, []], fwUpdateResource: [{value: '', disabled: true}, []], swUpdateResource: [{value: '', disabled: true}, []], - powerMode: [null, Validators.required] + powerMode: [PowerMode.DRX, Validators.required], + compositeOperationsSupport: [false] }) }); this.lwm2mDeviceConfigFormGroup = this.fb.group({ @@ -258,7 +259,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy || 1, fwUpdateResource: fwResource, swUpdateResource: swResource, - powerMode: this.configurationValue.clientLwM2mSettings.powerMode + powerMode: this.configurationValue.clientLwM2mSettings.powerMode || PowerMode.DRX, + compositeOperationsSupport: this.configurationValue.clientLwM2mSettings.compositeOperationsSupport || false } }, {emitEvent: false}); diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts index bc48182e9d..b550e4f5ae 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts @@ -175,6 +175,7 @@ export interface ClientLwM2mSettings { fwUpdateResource: string; swUpdateResource: string; powerMode: PowerMode; + compositeOperationsSupport: boolean; } export interface ObservableAttributes { @@ -231,7 +232,8 @@ export function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSetting swUpdateStrategy: 1, fwUpdateResource: DEFAULT_FW_UPDATE_RESOURCE, swUpdateResource: DEFAULT_SW_UPDATE_RESOURCE, - powerMode: PowerMode.DRX + powerMode: PowerMode.DRX, + compositeOperationsSupport: false }; } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 89c31a70c2..bf6b576952 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -1328,7 +1328,8 @@ "step": "Step", "min-evaluation-period": "Minimum evaluation period", "max-evaluation-period": "Maximum evaluation period" - } + }, + "composite-operations-support": "Supports composite Read/Write/Observe operations" }, "snmp": { "add-communication-config": "Add communication config",