diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java index de0a22756d..3dad6231ad 100644 --- a/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/rpc/sql/RpcLwm2mIntegrationWriteTest.java @@ -121,7 +121,7 @@ public class RpcLwm2mIntegrationWriteTest extends AbstractRpcLwM2MIntegrationTes ObjectNode rpcActualResult = JacksonUtil.fromString(actualResult, ObjectNode.class); assertEquals(ResponseCode.BAD_REQUEST.getName(), rpcActualResult.get("result").asText()); String actualValues = rpcActualResult.get("error").asText(); - String expected = "is bad. Value of Multi-Instance Resource must be in Json format!"; + String expected = "Format value is bad. Value for this Multi-Instance Resource must be in Json format!"; assertTrue(actualValues.contains(expected)); } 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 a4a4fa58ed..e6fddf430b 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 @@ -44,7 +44,6 @@ import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandle import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.List; import java.util.Map; @@ -52,7 +51,6 @@ import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; -import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_TAG; import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_TITLE; @@ -67,6 +65,7 @@ import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LO import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.compareAttNameKeyOta; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromJson; import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId; +import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.valueEquals; @Slf4j @Service @@ -220,7 +219,7 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { Object newValProto = getValueFromKvProto(tsKvProto.getKv()); Object oldResourceValue = this.getResourceValueFormatKv(lwM2MClient, pathIdVer); if (!resourceModel.multiple || !(newValProto instanceof JsonElement)) { - this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue, resourceModel.type); + this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue); } else { try { pushUpdateMultiToClientIfNeeded(lwM2MClient, resourceModel, (JsonElement) newValProto, @@ -235,16 +234,14 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { }); } - private void pushUpdateToClientIfNeeded(LwM2mClient lwM2MClient, Object valueOld, Object newValue, - String versionedId, boolean logFailedUpdateOfNonChangedValue, ResourceModel.Type type) { + private void pushUpdateToClientIfNeeded(LwM2mClient lwM2MClient, Object oldValue, Object newValue, + String versionedId, boolean logFailedUpdateOfNonChangedValue) { if (newValue == null) { String logMsg = String.format("%s: Failed update resource versionedId - %s value - %s. New value is bad", LOG_LWM2M_ERROR, versionedId, "null"); logService.log(lwM2MClient, logMsg); log.error("Failed update resource [{}] [{}]", versionedId, "null"); - } else if ((valueOld == null) || - ((OPAQUE.equals(type) && !Arrays.equals((byte[]) newValue, (byte[]) valueOld)) || - !newValue.equals(valueOld))) { + } else if ((oldValue == null) || !valueEquals(newValue, oldValue)) { TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId).value(newValue).timeout(clientContext.getRequestTimeout(lwM2MClient)).build(); downlinkHandler.sendWriteReplaceRequest(lwM2MClient, request, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, lwM2MClient, versionedId)); } else if (logFailedUpdateOfNonChangedValue) { @@ -262,13 +259,7 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService { if (newValues.size() > 0 && valueOld != null && valueOld.size() > 0) { valueOld.values().stream().forEach((v) -> { if (newValues.containsKey(v.getId())) { - boolean isValueEquals; - if (OPAQUE.equals(v.getType())) { - isValueEquals = Arrays.equals((byte[]) newValues.get(v.getId()), (byte[]) v.getValue()); - } else { - isValueEquals = newValues.get(v.getId()).toString().equals(v.getValue().toString()); - } - if (isValueEquals) { + if (valueEquals(newValues.get(v.getId()), v.getValue())) { newValues.remove(v.getId()); } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java index 07acf224c8..3382c8a83b 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DefaultLwM2mDownlinkMsgHandler.java @@ -307,11 +307,16 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im value, resourceModelWrite.type); } catch (Exception e) { msgError = "Resource id=" + resultIds.toString() + ", value = " + request.getValue() + - ", class = " + request.getValue().getClass().getSimpleName() + "is bad. Value of Multi-Instance Resource must be in Json format!"; + ", class = " + request.getValue().getClass().getSimpleName() + ". Format value is bad. Value for this Multi-Instance Resource must be in Json format!"; } } else { - downlink = this.getWriteRequestSingleResource(resourceModelWrite.type, contentFormat, - resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), request.getValue()); + try { + downlink = this.getWriteRequestSingleResource(resourceModelWrite.type, contentFormat, + resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), request.getValue()); + } catch (Exception e) { + msgError = "Resource id=" + resultIds.toString() + ", value = " + request.getValue() + + ", class = " + request.getValue().getClass().getSimpleName() + ". Format value is bad. Value for this Single Resource must be " + resourceModelWrite.type + "!"; + } } if (downlink != null) { sendSimpleRequest(client, downlink, request.getTimeout(), callback); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java index 1a209fd7a3..1531f725c6 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2MTransportUtil.java @@ -525,4 +525,20 @@ public class LwM2MTransportUtil { } return false; } + + public static boolean valueEquals(Object newValue, Object oldValue) { + String newValueStr; + String oldValueStr; + if (oldValue instanceof byte[]) { + oldValueStr = Hex.encodeHexString((byte[]) oldValue); + } else { + oldValueStr = oldValue.toString(); + } + if (newValue instanceof byte[]) { + newValueStr = Hex.encodeHexString((byte[]) newValue); + } else { + newValueStr = newValue.toString(); + } + return newValueStr.equals(oldValueStr); + } }