From 9fd2d34e7c466c9465037cf33c78deae511f03e9 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Mon, 7 Jun 2021 21:15:12 +0300 Subject: [PATCH] LWM2M: add update Firmware from terminal --- .../DefaultLwM2MTransportMsgHandler.java | 81 ++++++++++++------- .../server/client/LwM2mClientContext.java | 2 + .../server/client/LwM2mClientContextImpl.java | 42 +++++----- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 1 + 4 files changed, 73 insertions(+), 53 deletions(-) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index 10f2dfeff5..9304a36e60 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -90,6 +90,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.INITIATED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST; @@ -139,7 +140,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler public final LwM2mClientContext clientContext; public final LwM2mTransportRequest lwM2mTransportRequest; private final Map rpcSubscriptions; - private final Map getCoapResource; + public final Map firmwareUpdateState; public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, LwM2mClientContext clientContext, @@ -155,7 +156,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.context = context; this.adaptor = adaptor; this.rpcSubscriptions = new ConcurrentHashMap<>(); - this.getCoapResource = new ConcurrentHashMap<>(); + this.firmwareUpdateState = new ConcurrentHashMap<>(); this.sessionStore = sessionStore; } @@ -187,7 +188,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler try { String msgReg = previousObservations != null ? String.format("%s %s Client: create after Registration", registration.getEndpoint(), registration.getId()) : String.format("%s %s Client: create after UpdateRegistration", registration.getEndpoint(), registration.getId()); - log.warn(msgReg); + log.warn(msgReg); LwM2mClient lwM2MClient = this.clientContext.registerOrUpdate(registration); if (lwM2MClient != null) { SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); @@ -202,7 +203,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder() .setSessionType(TransportProtos.SessionType.ASYNC).build()) .build(), null); - this.getInfoFirmwareUpdate(lwM2MClient, null); + if (!(this.firmwareUpdateState.containsKey(lwM2MClient.getEndpoint()) && this.firmwareUpdateState.get(lwM2MClient.getEndpoint()) == 3)) { + this.getInfoFirmwareUpdate(lwM2MClient, null); + } this.getInfoSoftwareUpdate(lwM2MClient, null); this.initLwM2mFromClientValue(registration, lwM2MClient); this.sendLogsToThingsboard(LOG_LW2M_INFO + ": " + msgReg, registration.getId()); @@ -243,8 +246,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId()); } }); - } - else { + } else { this.onRegistered(registration, null); } } catch (Throwable t) { @@ -458,35 +460,43 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler // #1 this.checkRpcRequestTimeout(); UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); - log.warn("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); + log.warn("4) toDeviceRpcRequestMsg: [{}], requestUUID: [{}]", toDeviceRpcRequestMsg, requestUUID); String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); -// if (!this.rpcSubscriptions.containsKey(requestUUID)) { + if (!this.rpcSubscriptions.containsKey(requestUUID)) { this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); LwM2mClientRpcRequest lwm2mClientRpcRequest = null; try { - Registration registration = clientContext.getClient(sessionInfo).getRegistration(); - lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); - if (lwm2mClientRpcRequest.getErrorMsg() != null) { - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + Registration registration = clientContext.getRegistration(sessionInfo); + if (registration != null) { + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); + if (lwm2mClientRpcRequest.getErrorMsg() != null) { + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + } else { + lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), + null, + lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), + this.config.getBlockwiseLifetime(), lwm2mClientRpcRequest); + } } else { - lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), - null, - lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), - this.config.getTimeout(), lwm2mClientRpcRequest); + this.sentErrorRpcResponse(lwm2mClientRpcRequest, "registration == null", sessionInfo); } } catch (Exception e) { - if (lwm2mClientRpcRequest == null) { - lwm2mClientRpcRequest = new LwM2mClientRpcRequest(); - } - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); - if (lwm2mClientRpcRequest.getErrorMsg() == null) { - lwm2mClientRpcRequest.setErrorMsg(e.getMessage()); - } - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); + this.sentErrorRpcResponse(lwm2mClientRpcRequest, e.getMessage(), sessionInfo); } -// } + } + } + + private void sentErrorRpcResponse(LwM2mClientRpcRequest lwm2mClientRpcRequest, String msgError, SessionInfoProto sessionInfo) { + if (lwm2mClientRpcRequest == null) { + lwm2mClientRpcRequest = new LwM2mClientRpcRequest(); + } + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); + if (lwm2mClientRpcRequest.getErrorMsg() == null) { + lwm2mClientRpcRequest.setErrorMsg(msgError); + } + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); } private void checkRpcRequestTimeout() { @@ -846,7 +856,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler valueKvProto = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); } - LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString (pathIdVer, valueKvProto, currentType); + LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString(pathIdVer, valueKvProto, currentType); valueKvProto = lwM2mOtaConvert.getValue(); currentType = lwM2mOtaConvert.getCurrentType(); return valueKvProto != null ? this.helper.getKvAttrTelemetryToThingsboard(currentType, resourceName, valueKvProto, resourceValue.isMultiInstances()) : null; @@ -1355,6 +1365,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + if (rpcRequest != null) { + fwUpdate.setStateUpdate(INITIATED.name()); + } if (!FAILED.name().equals(fwUpdate.getStateUpdate())) { log.warn("7) firmware start with ver: [{}]", response.getVersion()); fwUpdate.setRpcRequest(rpcRequest); @@ -1366,12 +1379,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler } else { fwUpdate.writeFwSwWare(handler, lwM2mTransportRequest); } - } - else { - log.warn("7_1) OtaPackage [{}] [{}] [{}]", lwM2MClient.getDeviceName(), response.getVersion(), fwUpdate.getStateUpdate()); + } else { + String msgError = String.format("OtaPackage device: %s, version: %s, stateUpdate: %s", + lwM2MClient.getDeviceName(), response.getVersion(), fwUpdate.getStateUpdate()); + log.warn("7_1 [{}]", msgError); } } else { - log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); + String msgError = String.format("OtaPackage device: %s, responseStatus: %s", + lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); + log.trace(msgError); + if (rpcRequest != null) { + sentErrorRpcResponse(rpcRequest, msgError, sessionInfo); + } } } 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 bb3e97b7e4..2773c4c989 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 @@ -35,6 +35,8 @@ public interface LwM2mClientContext { LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); + Registration getRegistration(TransportProtos.SessionInfoProto sessionInfo); + LwM2mClient getOrRegister(Registration registration); LwM2mClient registerOrUpdate(Registration registration); 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 da59528fc1..50a1cf5c17 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 @@ -73,7 +73,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { if (registration == null) { return client; } - if (lwM2mClientsByRegistrationId.size()>0) { + if (lwM2mClientsByRegistrationId.size() > 0) { client = this.lwM2mClientsByRegistrationId.get(registration.getId()); } if (client == null) { @@ -91,32 +91,31 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { Predicate isClientFilter = c -> (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))); -// if (this.lwM2mClientsByEndpoint.size()>0) { -// lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(c -> -// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) -// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) -// ).findAny().get(); -// } - if (this.lwM2mClientsByEndpoint.size()>0) { - lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(isClientFilter).findAny().get(); + if (this.lwM2mClientsByEndpoint.size() > 0) { + lwM2mClient = this.lwM2mClientsByEndpoint.values().stream().filter(isClientFilter).findAny().orElse(null); } -// if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { -// lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(c -> -// (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) -// .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) -// ).findAny().get(); -// } if (lwM2mClient == null && this.lwM2mClientsByRegistrationId.size() > 0) { - lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(isClientFilter).findAny().get(); + lwM2mClient = this.lwM2mClientsByRegistrationId.values().stream().filter(isClientFilter).findAny().orElse(null); } - if (lwM2mClient == null){ + if (lwM2mClient == null) { log.warn("Device TimeOut? lwM2mClient is null."); - log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); + log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}] lwM2mClientsByRegistrationId: [{}]", sessionInfo, lwM2mClientsByEndpoint.values(), lwM2mClientsByRegistrationId.values()); log.error("", new RuntimeException()); } return lwM2mClient; } + @Override + public Registration getRegistration(TransportProtos.SessionInfoProto sessionInfo) { + Registration registration = this.getClient(sessionInfo).getRegistration(); + if (registration == null) { + log.warn("Device TimeOut? registration is null."); + log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size()); + log.error("", new RuntimeException()); + } + return registration; + } + @Override public LwM2mClient registerOrUpdate(Registration registration) { LwM2mClient lwM2MClient = lwM2mClientsByEndpoint.get(registration.getEndpoint()); @@ -139,10 +138,10 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { EndpointSecurityInfo securityInfo = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfo(endpoint, LwM2mTransportUtil.LwM2mTypeServer.CLIENT); if (securityInfo.getSecurityMode() != null) { if (securityInfo.getDeviceProfile() != null) { - UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile())!= null ? + UUID profileUuid = profileUpdate(securityInfo.getDeviceProfile()) != null ? securityInfo.getDeviceProfile().getUuidId() : null; // TODO: for tests bug. - if (profileUuid== null) { + if (profileUuid == null) { log.trace("input parameters toClientProfile if the result is null: [{}]", securityInfo.getDeviceProfile()); } LwM2mClient client; @@ -207,8 +206,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { if (lwM2MClientProfile != null) { profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile); return lwM2MClientProfile; - } - else { + } else { return null; } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java index 410d5a2e9a..a4efc35cf4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java @@ -458,6 +458,7 @@ public class LwM2mFwSwUpdate { if (value == LwM2mTransportUtil.StateFw.DOWNLOADED.code) { this.executeFwSwWare(handler, request); } + handler.firmwareUpdateState.put(lwM2MClient.getEndpoint(), value); } if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { if (this.currentId != null && value == LwM2mTransportUtil.UpdateResultFw.INITIAL.code) {