From f88cfee2b0f28737b9b0b8a271e7bcd01b980cd5 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Fri, 11 Jun 2021 12:29:41 +0300 Subject: [PATCH] Refactoring of the Downlink Part 2 --- .../server/DefaultLwM2MUplinkMsgHandler.java | 123 ++- .../DefaultLwM2mDownlinkMsgHandler.java | 970 ++++++++---------- .../lwm2m/server/LwM2mDownlinkMsgHandler.java | 50 +- .../lwm2m/server/LwM2mUplinkMsgHandler.java | 2 - .../lwm2m/server/client/LwM2mClient.java | 9 +- .../lwm2m/server/client/LwM2mFwSwUpdate.java | 46 +- .../AbstractTbLwM2MRequestCallback.java | 40 + ...bstractTbLwM2MTargetedDownlinkRequest.java | 32 + .../downlink/DownlinkRequestCallback.java | 27 +- .../server/downlink/HasContentFormat.java | 23 + .../lwm2m/server/downlink/HasVersionedId.java | 28 + ...bLwM2MCancelAllObserveRequestCallback.java | 36 + .../downlink/TbLwM2MCancelAllRequest.java | 38 + .../downlink/TbLwM2MCancelObserveRequest.java | 37 + .../TbLwM2MCancelObserveRequestCallback.java | 38 + .../server/downlink/TbLwM2MDeleteRequest.java | 37 + .../TbLwM2MDeleteRequestCallback.java | 37 + .../downlink/TbLwM2MDiscoverAllRequest.java | 40 + .../downlink/TbLwM2MDiscoverCallback.java | 37 + .../downlink/TbLwM2MDiscoverRequest.java | 37 + .../downlink/TbLwM2MDownlinkRequest.java | 26 + .../downlink/TbLwM2MExecuteRequest.java | 41 + .../TbLwM2MExecuteRequestCallback.java | 37 + .../downlink/TbLwM2MObserveAllRequest.java | 41 + .../downlink/TbLwM2MObserveRequest.java | 43 + .../TbLwM2MObserveRequestCallback.java | 37 + .../server/downlink/TbLwM2MReadRequest.java | 42 + .../downlink/TbLwM2MReadRequestCallback.java | 37 + .../TbLwM2MWriteAttributesCallback.java | 38 + .../TbLwM2MWriteAttributesRequest.java | 44 + .../downlink/TbLwM2MWriteReplaceCallback.java | 37 + .../downlink/TbLwM2MWriteReplaceRequest.java | 43 + .../downlink/TbLwM2MWriteUpdateRequest.java | 45 + 33 files changed, 1569 insertions(+), 629 deletions(-) create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MTargetedDownlinkRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasContentFormat.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasVersionedId.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllObserveRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverAllRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDownlinkRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveAllRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequestCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceCallback.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceRequest.java create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteUpdateRequest.java diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MUplinkMsgHandler.java index 45e07eaf4c..e6c14b0ba0 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MUplinkMsgHandler.java @@ -29,6 +29,7 @@ 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.observation.Observation; +import org.eclipse.leshan.core.request.CancelObservationRequest; import org.eclipse.leshan.core.request.WriteRequest; import org.eclipse.leshan.core.response.ReadResponse; import org.eclipse.leshan.server.registration.Registration; @@ -66,6 +67,22 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mFwSwUpdate; import org.thingsboard.server.transport.lwm2m.server.client.ParametersAnalyzeResult; import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; +import org.thingsboard.server.transport.lwm2m.server.downlink.DownlinkRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllObserveRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; @@ -99,11 +116,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_WARN; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertOtaUpdateValueToString; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; @@ -283,18 +296,18 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { //TODO: associate endpointId with device information. } - /** - * Cancel observation for All objects for this registration - */ - @Override - public void setCancelObservationsAll(Registration registration) { - if (registration != null) { - LwM2mClient client = clientContext.getClientByEndpoint(registration.getEndpoint()); - if (client != null && client.getRegistration() != null && client.getRegistration().getId().equals(registration.getId())) { - defaultLwM2MDownlinkMsgHandler.sendCancelAllRequest(client, this.config.getTimeout(), null); - } - } - } +// /** +// * Cancel observation for All objects for this registration +// */ +// @Override +// public void setCancelObservationsAll(Registration registration) { +// if (registration != null) { +// LwM2mClient client = clientContext.getClientByEndpoint(registration.getEndpoint()); +// if (client != null && client.getRegistration() != null && client.getRegistration().getId().equals(registration.getId())) { +// defaultLwM2MDownlinkMsgHandler.sendCancelAllRequest(client, TbLwM2MCancelAllRequest.builder().build(), new TbLwM2MCancelAllObserveRequestCallback(this, client)); +// } +// } +// } /** * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource @@ -321,6 +334,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { } } if (rpcRequest != null) { + //TODO: move this to separate callback. this.sendRpcRequestAfterReadResponse(registration, lwM2MClient, path, response, rpcRequest); } } @@ -466,10 +480,11 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); } else { - defaultLwM2MDownlinkMsgHandler.sendAllRequest(client, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), - null, - lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), - this.config.getTimeout(), lwm2mClientRpcRequest); + //TODO: use different methods and RPC callback wrapper. +// defaultLwM2MDownlinkMsgHandler.sendAllRequest(client, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), +// null, +// lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), +// this.config.getTimeout(), lwm2mClientRpcRequest); } } else { this.sendErrorRpcResponse(lwm2mClientRpcRequest, "registration == null", sessionInfo); @@ -594,7 +609,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { if (LwM2mTransportUtil.LwM2MClientStrategy.CLIENT_STRATEGY_2.code == profile.getClientLwM2mSettings().getClientOnlyObserveAfterConnect()) { // #2 lwM2MClient.getPendingReadRequests().addAll(supportedObjects); - supportedObjects.forEach(path -> defaultLwM2MDownlinkMsgHandler.sendReadRequest(lwM2MClient, path, this.config.getTimeout())); + supportedObjects.forEach(versionedId -> sendReadRequest(lwM2MClient, versionedId)); } // #1 this.sendReadRequests(lwM2MClient, profile, supportedObjects); @@ -610,7 +625,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { targetIds.addAll(profile.getObserveAttr().getTelemetry()); targetIds = targetIds.stream().filter(target -> isSupportedTargetId(supportedObjects, target)).collect(Collectors.toSet()); lwM2MClient.getPendingReadRequests().addAll(targetIds); - targetIds.forEach(targetId -> defaultLwM2MDownlinkMsgHandler.sendReadRequest(lwM2MClient, targetId, this.config.getTimeout())); + targetIds.forEach(versionedId -> sendReadRequest(lwM2MClient, versionedId)); } private void sendObserveRequests(LwM2mClient lwM2MClient, Lwm2mDeviceProfileTransportConfiguration profile, Set supportedObjects) { @@ -618,7 +633,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { targetIds = targetIds.stream().filter(target -> isSupportedTargetId(supportedObjects, target)).collect(Collectors.toSet()); // TODO: why do we need to put observe into pending read requests? // lwM2MClient.getPendingReadRequests().addAll(targetIds); - targetIds.forEach(targetId -> defaultLwM2MDownlinkMsgHandler.sendObserveRequest(lwM2MClient, targetId, this.config.getTimeout())); + targetIds.forEach(targetId -> sendObserveRequest(lwM2MClient, targetId)); } private void sendWriteAttributeRequests(LwM2mClient lwM2MClient, Lwm2mDeviceProfileTransportConfiguration profile, Set supportedObjects) { @@ -626,16 +641,40 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { attributesMap = attributesMap.entrySet().stream().filter(target -> isSupportedTargetId(supportedObjects, target.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); // TODO: why do we need to put observe into pending read requests? // lwM2MClient.getPendingReadRequests().addAll(targetIds); - attributesMap.forEach((targetId, params) -> defaultLwM2MDownlinkMsgHandler.sendWriteAttributesRequest(lwM2MClient, targetId, params, this.config.getTimeout())); + attributesMap.forEach((targetId, params) -> sendWriteAttributesRequest(lwM2MClient, targetId, params)); } - private void sendDiscoverRequests(LwM2mClient lwM2MClient, Lwm2mDeviceProfileTransportConfiguration profile, Set supportedObjects) { Set targetIds = profile.getObserveAttr().getAttributeLwm2m().keySet(); targetIds = targetIds.stream().filter(target -> isSupportedTargetId(supportedObjects, target)).collect(Collectors.toSet()); // TODO: why do we need to put observe into pending read requests? // lwM2MClient.getPendingReadRequests().addAll(targetIds); - targetIds.forEach(targetId -> defaultLwM2MDownlinkMsgHandler.sendDiscoverRequest(lwM2MClient, targetId, this.config.getTimeout())); + targetIds.forEach(targetId -> sendDiscoverRequest(lwM2MClient, targetId)); + } + + private void sendDiscoverRequest(LwM2mClient lwM2MClient, String targetId) { + TbLwM2MDiscoverRequest request = TbLwM2MDiscoverRequest.builder().versionedId(targetId).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendDiscoverRequest(lwM2MClient, request, new TbLwM2MDiscoverCallback(this, lwM2MClient, targetId)); + } + + private void sendReadRequest(LwM2mClient lwM2MClient, String versionedId) { + TbLwM2MReadRequest request = TbLwM2MReadRequest.builder().versionedId(versionedId).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendReadRequest(lwM2MClient, request, new TbLwM2MReadRequestCallback(this, lwM2MClient, versionedId)); + } + + private void sendObserveRequest(LwM2mClient lwM2MClient, String versionedId) { + TbLwM2MObserveRequest request = TbLwM2MObserveRequest.builder().versionedId(versionedId).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendObserveRequest(lwM2MClient, request, new TbLwM2MObserveRequestCallback(this, lwM2MClient, versionedId)); + } + + private void sendWriteAttributesRequest(LwM2mClient lwM2MClient, String targetId, ObjectAttributes params) { + TbLwM2MWriteAttributesRequest request = TbLwM2MWriteAttributesRequest.builder().versionedId(targetId).attributes(params).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendWriteAttributesRequest(lwM2MClient, request, new TbLwM2MWriteAttributesCallback(this, lwM2MClient, targetId)); + } + + private void sendCancelObserveRequest(String versionedId, LwM2mClient client) { + TbLwM2MCancelObserveRequest request = TbLwM2MCancelObserveRequest.builder().versionedId(versionedId).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendCancelObserveRequest(client, request, new TbLwM2MCancelObserveRequestCallback(this, client, versionedId)); } /** @@ -690,7 +729,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { if ((convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path)) || (convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { - LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(this, clientContext); log.warn("93) path: [{}] value: [{}]", path, lwM2mResource.getValue()); fwUpdate.updateStateOta(this, defaultLwM2MDownlinkMsgHandler, registration, path, ((Long) lwM2mResource.getValue()).intValue()); } @@ -935,27 +974,27 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { if (!newObjectsToRead.isEmpty()) { Set newObjectsToReadButNotNewInObserve = diffSets(observeToAdd, newObjectsToRead); // update value in Resources - for (String targetId : newObjectsToReadButNotNewInObserve) { - clients.forEach(client -> defaultLwM2MDownlinkMsgHandler.sendReadRequest(client, targetId, this.config.getTimeout())); + for (String versionedId : newObjectsToReadButNotNewInObserve) { + clients.forEach(client -> sendReadRequest(client, versionedId)); } } // Calculating difference between old and new flags. if (!observeToAdd.isEmpty()) { for (String targetId : observeToAdd) { - clients.forEach(client -> defaultLwM2MDownlinkMsgHandler.sendObserveRequest(client, targetId, this.config.getTimeout())); + clients.forEach(client -> sendObserveRequest(client, targetId)); } } if (!observeToRemove.isEmpty()) { for (String targetId : observeToRemove) { - clients.forEach(client -> defaultLwM2MDownlinkMsgHandler.sendCancelObserveRequest(client, targetId, this.config.getTimeout(), null)); + clients.forEach(client -> sendCancelObserveRequest(targetId, client)); } } } } /** - Returns new set with elements that are present in set B(new) but absent in set A(old). + * Returns new set with elements that are present in set B(new) but absent in set A(old). */ private static Set diffSets(Set a, Set b) { return b.stream().filter(p -> !a.contains(p)).collect(Collectors.toSet()); @@ -974,7 +1013,6 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { /** * #6.1 - send update WriteAttribute * #6.2 - send empty WriteAttribute - * */ private void compareAndSendWriteAttributes(List clients, Map lwm2mAttributesOld, Map lwm2mAttributesNew) { ParametersAnalyzeResult analyzerParameters = new ParametersAnalyzeResult(); @@ -997,7 +1035,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { Set pathSend = analyzerParameters.getPathPostParametersAdd().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) .collect(Collectors.toUnmodifiableSet()); if (!pathSend.isEmpty()) { - pathSend.forEach(target -> defaultLwM2MDownlinkMsgHandler.sendWriteAttributesRequest(client, target, lwm2mAttributesNew.get(target), this.config.getTimeout())); + pathSend.forEach(target -> sendWriteAttributesRequest(client, target, lwm2mAttributesNew.get(target))); } }); } @@ -1008,21 +1046,22 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { Set pathSend = analyzerParameters.getPathPostParametersDel().stream().filter(target -> clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1])) .collect(Collectors.toUnmodifiableSet()); if (!pathSend.isEmpty()) { - pathSend.forEach(target -> defaultLwM2MDownlinkMsgHandler.sendWriteAttributesRequest(client, target, new ObjectAttributes(), this.config.getTimeout())); + pathSend.forEach(target -> sendWriteAttributesRequest(client, target, new ObjectAttributes())); } }); } } - private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object newValue, String path) { + private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object newValue, String versionedId) { if (newValue != null && (valueOld == null || !newValue.toString().equals(valueOld.toString()))) { - defaultLwM2MDownlinkMsgHandler.sendWriteReplaceRequest(lwM2MClient, path, newValue, this.config.getTimeout(), null); + TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId).value(newValue).timeout(this.config.getTimeout()).build(); + defaultLwM2MDownlinkMsgHandler.sendWriteReplaceRequest(lwM2MClient, request, new TbLwM2MWriteReplaceCallback(this, lwM2MClient, versionedId)); } else { - log.error("Failed update resource [{}] [{}]", path, newValue); - String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", - LOG_LW2M_ERROR, path, newValue); + log.error("Failed update resource [{}] [{}]", versionedId, newValue); + String logMsg = String.format("%s: Failed update resource versionedId - %s value - %s. Value is not changed or bad", + LOG_LW2M_ERROR, versionedId, newValue); this.sendLogsToThingsboard(lwM2MClient, logMsg); - log.info("Failed update resource [{}] [{}]", path, newValue); + log.info("Failed update resource [{}] [{}]", versionedId, newValue); } } @@ -1176,7 +1215,7 @@ public class DefaultLwM2MUplinkMsgHandler implements LwM2mUplinkMsgHandler { public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) && response.getType().equals(OtaPackageType.FIRMWARE.name())) { - LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(clientContext); + LwM2mFwSwUpdate fwUpdate = lwM2MClient.getFwUpdate(DefaultLwM2MUplinkMsgHandler.this, clientContext); if (rpcRequest != null) { fwUpdate.setStateUpdate(INITIATED.name()); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mDownlinkMsgHandler.java index 3ba3de2b75..b1b52ec3ed 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mDownlinkMsgHandler.java @@ -17,18 +17,12 @@ package org.thingsboard.server.transport.lwm2m.server; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.eclipse.californium.core.coap.CoAP; -import org.eclipse.californium.core.coap.Response; import org.eclipse.leshan.core.Link; import org.eclipse.leshan.core.attributes.Attribute; import org.eclipse.leshan.core.attributes.AttributeSet; import org.eclipse.leshan.core.model.ResourceModel; -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.ObjectLink; import org.eclipse.leshan.core.node.codec.CodecException; import org.eclipse.leshan.core.observation.Observation; @@ -41,13 +35,12 @@ import org.eclipse.leshan.core.request.ReadRequest; import org.eclipse.leshan.core.request.SimpleDownlinkRequest; import org.eclipse.leshan.core.request.WriteAttributesRequest; import org.eclipse.leshan.core.request.WriteRequest; -import org.eclipse.leshan.core.request.exception.ClientSleepingException; import org.eclipse.leshan.core.response.DeleteResponse; import org.eclipse.leshan.core.response.DiscoverResponse; import org.eclipse.leshan.core.response.ExecuteResponse; import org.eclipse.leshan.core.response.LwM2mResponse; +import org.eclipse.leshan.core.response.ObserveResponse; import org.eclipse.leshan.core.response.ReadResponse; -import org.eclipse.leshan.core.response.ResponseCallback; import org.eclipse.leshan.core.response.WriteAttributesResponse; import org.eclipse.leshan.core.response.WriteResponse; import org.eclipse.leshan.core.util.Hex; @@ -61,6 +54,19 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientRpcRequest; import org.thingsboard.server.transport.lwm2m.server.downlink.DownlinkRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.HasContentFormat; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDeleteRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteUpdateRequest; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import javax.annotation.PostConstruct; @@ -70,43 +76,18 @@ import java.util.Date; import java.util.LinkedList; import java.util.List; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; -import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; -import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST; -import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND; import static org.eclipse.leshan.core.attributes.Attribute.GREATER_THAN; import static org.eclipse.leshan.core.attributes.Attribute.LESSER_THAN; import static org.eclipse.leshan.core.attributes.Attribute.MAXIMUM_PERIOD; import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD; import static org.eclipse.leshan.core.attributes.Attribute.STEP; -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED; -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEFAULT_TIMEOUT; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_5_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_REQUEST_CHANNEL; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_INSTALL_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_PACKAGE_ID; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.createWriteAttributeRequest; -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId; @Slf4j @Service @@ -120,7 +101,6 @@ public class DefaultLwM2mDownlinkMsgHandler implements LwM2mDownlinkMsgHandler { private final LwM2mTransportContext context; private final LwM2MTransportServerConfig config; private final LwM2mClientContext lwM2mClientContext; - private final DefaultLwM2MUplinkMsgHandler handler; @PostConstruct public void init() { @@ -130,100 +110,90 @@ public class DefaultLwM2mDownlinkMsgHandler implements LwM2mDownlinkMsgHandler { } @Override - public void sendReadRequest(LwM2mClient client, String targetId, Long timeout) { - sendReadRequest(client, targetId, client.getDefaultContentFormat(), timeout); - } - - @Override - public void sendReadRequest(LwM2mClient client, String targetId, ContentFormat contentFormat, Long timeout) { - String objectId = fromVersionedIdToObjectId(targetId); - if (objectId != null && client.isValidObjectVersion(targetId)) { - sendRequest(client, new ReadRequest(contentFormat, objectId), timeout); + public void sendReadRequest(LwM2mClient client, TbLwM2MReadRequest request, DownlinkRequestCallback callback) { + if (request.getObjectId() != null && client.isValidObjectVersion(request.getVersionedId())) { + ReadRequest downlink = new ReadRequest(getContentFormat(client, request), request.getObjectId()); + sendRequest(client, downlink, request.getTimeout(), callback); } } @Override - public void sendObserveRequest(LwM2mClient client, String targetId, Long timeout) { - sendObserveRequest(client, targetId, client.getDefaultContentFormat(), timeout); - } - - @Override - public void sendObserveRequest(LwM2mClient client, String targetId, ContentFormat contentFormat, Long timeout) { - String objectId = fromVersionedIdToObjectId(targetId); - if (objectId != null && client.isValidObjectVersion(targetId)) { - LwM2mPath resultIds = new LwM2mPath(objectId); + public void sendObserveRequest(LwM2mClient client, TbLwM2MObserveRequest request, DownlinkRequestCallback callback) { + if (request.getObjectId() != null && client.isValidObjectVersion(request.getVersionedId())) { + LwM2mPath resultIds = new LwM2mPath(request.getObjectId()); Set observations = context.getServer().getObservationService().getObservations(client.getRegistration()); if (observations.stream().noneMatch(observation -> observation.getPath().equals(resultIds))) { - ObserveRequest request; + ObserveRequest downlink; + ContentFormat contentFormat = getContentFormat(client, request); if (resultIds.isResource()) { - request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); + downlink = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); } else if (resultIds.isObjectInstance()) { - request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId()); + downlink = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId()); } else { - request = new ObserveRequest(contentFormat, resultIds.getObjectId()); + downlink = new ObserveRequest(contentFormat, resultIds.getObjectId()); } - log.info("[{}] Send observation: {}.", client.getEndpoint(), targetId); - sendRequest(client, request, timeout); + log.info("[{}] Send observation: {}.", client.getEndpoint(), request.getVersionedId()); + sendRequest(client, downlink, request.getTimeout(), callback); } } } @Override - public void sendExecuteRequest(LwM2mClient client, String targetId, Long timeout, DownlinkRequestCallback callback) { - sendExecuteRequest(client, targetId, null, timeout, callback); + public void sendObserveAllRequest(LwM2mClient client, TbLwM2MObserveAllRequest request, DownlinkRequestCallback> callback) { + Set observations = context.getServer().getObservationService().getObservations(client.getRegistration()); + Set paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); + callback.onSuccess(paths); } @Override - public void sendExecuteRequest(LwM2mClient client, String targetId, Object params, Long timeout, DownlinkRequestCallback callback) { - String target = fromVersionedIdToObjectId(targetId); - LwM2mPath resultIds = new LwM2mPath(target); - ResourceModel resourceModelExecute = client.getResourceModel(targetId, this.config.getModelProvider()); + public void sendDiscoverAllRequest(LwM2mClient client, TbLwM2MDiscoverAllRequest request, DownlinkRequestCallback> callback) { + Link[] objectLinks = client.getRegistration().getSortedObjectLinks(); + Set paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); + callback.onSuccess(paths); + } + + @Override + public void sendExecuteRequest(LwM2mClient client, TbLwM2MExecuteRequest request, DownlinkRequestCallback callback) { + ResourceModel resourceModelExecute = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider()); if (resourceModelExecute != null) { - ExecuteRequest request; - if (params != null && !resourceModelExecute.multiple) { - request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModelExecute.type, ResourceModel.Type.STRING, resultIds)); + ExecuteRequest downlink; + if (request.getParams() != null && !resourceModelExecute.multiple) { + downlink = new ExecuteRequest(request.getVersionedId(), (String) this.converter.convertValue(request.getParams(), resourceModelExecute.type, ResourceModel.Type.STRING, new LwM2mPath(request.getObjectId()))); } else { - request = new ExecuteRequest(target); + downlink = new ExecuteRequest(request.getVersionedId()); } - sendRequest(client, request, timeout); + sendRequest(client, downlink, request.getTimeout(), callback); } } - public void sendDeleteRequest(LwM2mClient client, String targetId, Long timeout, DownlinkRequestCallback callback) { - String target = fromVersionedIdToObjectId(targetId); - sendRequest(client, new DeleteRequest(target), timeout); + @Override + public void sendDeleteRequest(LwM2mClient client, TbLwM2MDeleteRequest request, DownlinkRequestCallback callback) { + sendRequest(client, new DeleteRequest(request.getObjectId()), request.getTimeout(), callback); } @Override - public void sendCancelObserveRequest(LwM2mClient client, String targetId, Long timeout, DownlinkRequestCallback callback) { - int observeCancelCnt = context.getServer().getObservationService().cancelObservations(client.getRegistration(), fromVersionedIdToObjectId(targetId)); - String observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO, OBSERVE_CANCEL.name(), targetId, observeCancelCnt); - if (callback != null) { - callback.onSuccess(client, observeCancelMsg); - } + public void sendCancelObserveRequest(LwM2mClient client, TbLwM2MCancelObserveRequest request, DownlinkRequestCallback callback) { + int observeCancelCnt = context.getServer().getObservationService().cancelObservations(client.getRegistration(), request.getObjectId()); + callback.onSuccess(observeCancelCnt); } @Override - public void sendCancelAllRequest(LwM2mClient client, Long timeout, DownlinkRequestCallback callback) { + public void sendCancelAllRequest(LwM2mClient client, TbLwM2MCancelAllRequest request, DownlinkRequestCallback callback) { int observeCancelCnt = context.getServer().getObservationService().cancelObservations(client.getRegistration()); - String observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, OBSERVE_CANCEL.name(), observeCancelCnt); - if (callback != null) { - callback.onSuccess(client, observeCancelMsg); - } + callback.onSuccess(observeCancelCnt); } @Override - public void sendDiscoverRequest(LwM2mClient client, String targetId, Long timeout) { - String objectId = fromVersionedIdToObjectId(targetId); - if (objectId != null && client.isValidObjectVersion(targetId)) { - sendRequest(client, new DiscoverRequest(objectId), timeout); + public void sendDiscoverRequest(LwM2mClient client, TbLwM2MDiscoverRequest request, DownlinkRequestCallback callback) { + if (request.getObjectId() != null && client.isValidObjectVersion(request.getVersionedId())) { + sendRequest(client, new DiscoverRequest(request.getObjectId()), request.getTimeout(), callback); } } @Override - public void sendWriteAttributesRequest(LwM2mClient client, String targetId, ObjectAttributes params, Long timeout) { - String objectId = fromVersionedIdToObjectId(targetId); - if (objectId != null && client.isValidObjectVersion(targetId) && params != null) { + public void sendWriteAttributesRequest(LwM2mClient client, TbLwM2MWriteAttributesRequest request, DownlinkRequestCallback callback) { + if (request.getObjectId() != null && client.isValidObjectVersion(request.getVersionedId()) && request.getAttributes() != null) { + ObjectAttributes params = request.getAttributes(); List attributes = new LinkedList<>(); // Dimension and Object version are read only attributes. // addAttribute(attributes, DIMENSION, params.getDim(), dim -> dim >= 0 && dim <= 255); @@ -234,366 +204,233 @@ public class DefaultLwM2mDownlinkMsgHandler implements LwM2mDownlinkMsgHandler { addAttribute(attributes, LESSER_THAN, params.getLt()); addAttribute(attributes, STEP, params.getSt()); AttributeSet attributeSet = new AttributeSet(attributes); - sendRequest(client, new WriteAttributesRequest(objectId, attributeSet), timeout); + sendRequest(client, new WriteAttributesRequest(request.getObjectId(), attributeSet), request.getTimeout(), callback); } } @Override - public void sendWriteReplaceRequest(LwM2mClient client, String targetIdVer, Object newValue, Long timeout, DownlinkRequestCallback callback) { - ResourceModel resourceModelWrite = client.getResourceModel(targetIdVer, this.config.getModelProvider()); + public void sendWriteReplaceRequest(LwM2mClient client, TbLwM2MWriteReplaceRequest request, DownlinkRequestCallback callback) { + ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider()); if (resourceModelWrite != null) { ContentFormat contentFormat = convertResourceModelTypeToContentFormat(client, resourceModelWrite.type); try { - LwM2mPath path = new LwM2mPath(fromVersionedIdToObjectId(targetIdVer)); - WriteRequest request = this.getWriteRequestSingleResource(resourceModelWrite.type, contentFormat, - path.getObjectId(), path.getObjectInstanceId(), path.getResourceId(), newValue); - sendRequest(client, request, timeout); + LwM2mPath path = new LwM2mPath(request.getObjectId()); + WriteRequest downlink = this.getWriteRequestSingleResource(resourceModelWrite.type, contentFormat, + path.getObjectId(), path.getObjectInstanceId(), path.getResourceId(), request.getValue()); + sendRequest(client, downlink, request.getTimeout(), callback); } catch (Exception e) { - callback.onError(client, e.getMessage(), e); + callback.onError(e); } + } else { + //TODO: log validation error using callback. } } @Override - public void sendWriteUpdateRequest(LwM2mClient client, String targetIdVer, Object newValue, ContentFormat contentFormat, Long timeout, DownlinkRequestCallback callback) { - LwM2mPath resultIds = new LwM2mPath(fromVersionedIdToObjectId(targetIdVer)); + public void sendWriteUpdateRequest(LwM2mClient client, TbLwM2MWriteUpdateRequest request, DownlinkRequestCallback callback) { + LwM2mPath resultIds = new LwM2mPath(request.getObjectId()); if (resultIds.isResource()) { /* * send request: path = '/3/0' node == wM2mObjectInstance * with params == "\"resources\": {15: resource:{id:15. value:'+01'...}} **/ - Collection resources = client.getNewResourceForInstance(targetIdVer, newValue, this.config.getModelProvider(), this.converter); - ResourceModel resourceModelWrite = client.getResourceModel(targetIdVer, this.config.getModelProvider()); - WriteRequest request = new WriteRequest(WriteRequest.Mode.UPDATE, convertResourceModelTypeToContentFormat(client, resourceModelWrite.type), resultIds.getObjectId(), + Collection resources = client.getNewResourceForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter); + ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider()); + WriteRequest downlink = new WriteRequest(WriteRequest.Mode.UPDATE, convertResourceModelTypeToContentFormat(client, resourceModelWrite.type), resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources); - sendRequest(client, request, timeout); + sendRequest(client, downlink, request.getTimeout(), callback); } else if (resultIds.isObjectInstance()) { /* * params = "{\"id\":0,\"resources\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}" * int rscId = resultIds.getObjectInstanceId(); * contentFormat – Format of the payload (TLV or JSON). */ - Collection resources = client.getNewResourcesForInstance(targetIdVer, newValue, this.config.getModelProvider(), this.converter); + Collection resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter); if (resources.size() > 0) { - contentFormat = contentFormat.equals(ContentFormat.JSON) ? contentFormat : client.getDefaultContentFormat(); - WriteRequest request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources); - sendRequest(client, request, timeout); + ContentFormat contentFormat = request.getObjectContentFormat() != null ? request.getObjectContentFormat() : client.getDefaultContentFormat(); + WriteRequest downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources); + sendRequest(client, downlink, request.getTimeout(), callback); } else { - callback.onError(client, "No resources to update!", new IllegalArgumentException()); + callback.onValidationError("No resources to update!"); } } else { - callback.onError(client, "Update of the root level object is not supported yet", new IllegalArgumentException()); - } - } - - private void addAttribute(List attributes, String attributeName, T value) { - addAttribute(attributes, attributeName, value, null, null); - } - - private void addAttribute(List attributes, String attributeName, T value, Function converter) { - addAttribute(attributes, attributeName, value, null, converter); - } - - private void addAttribute(List attributes, String attributeName, T value, Predicate filter, Function converter) { - if (value != null && ((filter == null) || filter.test(value))) { - attributes.add(new Attribute(attributeName, converter != null ? converter.apply(value) : value)); - } - } - - private static ContentFormat convertResourceModelTypeToContentFormat(LwM2mClient client, ResourceModel.Type type) { - switch (type) { - case BOOLEAN: - case STRING: - case TIME: - case INTEGER: - case FLOAT: - return client.getDefaultContentFormat(); - case OPAQUE: - return ContentFormat.OPAQUE; - case OBJLNK: - return ContentFormat.LINK; - default: + callback.onValidationError("Update of the root level object is not supported yet!"); } - throw new CodecException("Invalid ResourceModel_Type for %s ContentFormat.", type); - } - - public void sendAllRequest(LwM2mClient client, String targetIdVer, LwM2mTypeOper typeOper, Object params, long timeoutInMs, LwM2mClientRpcRequest lwm2mClientRpcRequest) { - sendAllRequest(client, targetIdVer, typeOper, client.getDefaultContentFormat(), params, timeoutInMs, lwm2mClientRpcRequest); - } - - public void sendAllRequest(LwM2mClient client, String targetIdVer, LwM2mTypeOper typeOper, - ContentFormat contentFormat, Object params, long timeoutInMs, LwM2mClientRpcRequest lwm2mClientRpcRequest) { - Registration registration = client.getRegistration(); - try { - String target = fromVersionedIdToObjectId(targetIdVer); - if (contentFormat == null) { - contentFormat = client.getDefaultContentFormat(); - } - LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; - if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0) { - if (client.isValidObjectVersion(targetIdVer)) { - timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; - SimpleDownlinkRequest request = createRequest(registration, client, typeOper, contentFormat, target, - targetIdVer, resultIds, params, lwm2mClientRpcRequest); - if (request != null) { - try { - this.sendRequest(client, request, timeoutInMs, lwm2mClientRpcRequest); - } catch (ClientSleepingException e) { - SimpleDownlinkRequest finalRequest = request; - long finalTimeoutInMs = timeoutInMs; - LwM2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; - client.getQueuedRequests().add(() -> sendRequest(client, finalRequest, finalTimeoutInMs, finalRpcRequest)); - } catch (Exception e) { - log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); - } - } else if (WRITE_UPDATE.name().equals(typeOper.name())) { - if (lwm2mClientRpcRequest != null) { - String errorMsg = String.format("Path %s params is not valid", targetIdVer); - handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); - } - } else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) { - if (lwm2mClientRpcRequest != null) { - String errorMsg = String.format("Path %s object model is absent", targetIdVer); - handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); - } - } else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) { - log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); - if (lwm2mClientRpcRequest != null) { - ResourceModel resourceModel = client.getResourceModel(targetIdVer, this.config.getModelProvider()); - String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; - handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); - } - } - } else if (lwm2mClientRpcRequest != null) { - String errorMsg = String.format("Path %s not found in object version", targetIdVer); - handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); - } - } else { - switch (typeOper) { - case OBSERVE_READ_ALL: - case DISCOVER_ALL: - Set paths; - if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { - Set observations = context.getServer().getObservationService().getObservations(registration); - paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); - } else { - assert registration != null; - Link[] objectLinks = registration.getSortedObjectLinks(); - paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); - } - String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, - typeOper.name(), paths); - this.handler.sendLogsToThingsboard(client, msg); - if (lwm2mClientRpcRequest != null) { - String valueMsg = String.format("Paths - %s", paths); - handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); - } - break; - case OBSERVE_CANCEL: - case OBSERVE_CANCEL_ALL: - int observeCancelCnt = 0; - String observeCancelMsg = null; - if (OBSERVE_CANCEL.name().equals(typeOper)) { - observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target); - observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO, - OBSERVE_CANCEL.name(), target, observeCancelCnt); - } else { - observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration); - observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, - OBSERVE_CANCEL.name(), observeCancelCnt); - } - this.afterObserveCancel(client, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest); - break; - // lwm2mClientRpcRequest != null - case FW_UPDATE: - handler.getInfoFirmwareUpdate(client, lwm2mClientRpcRequest); - break; - } - } - } catch (Exception e) { - String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, - typeOper.name(), e.getMessage()); - handler.sendLogsToThingsboard(client, msg); - if (lwm2mClientRpcRequest != null) { - String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); - handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); - } - } - } - - private SimpleDownlinkRequest createRequest(Registration registration, LwM2mClient client, LwM2mTypeOper typeOper, - ContentFormat contentFormat, String target, String targetIdVer, - LwM2mPath resultIds, Object params, LwM2mClientRpcRequest rpcRequest) { - SimpleDownlinkRequest request = null; - switch (typeOper) { - case READ: - request = new ReadRequest(contentFormat, target); - break; - case DISCOVER: - request = new DiscoverRequest(target); - break; - case OBSERVE: - String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer); - log.warn(msg); - if (resultIds.isResource()) { - Set observations = context.getServer().getObservationService().getObservations(registration); - Set paths = observations.stream().filter(observation -> observation.getPath().equals(resultIds)).collect(Collectors.toSet()); - if (paths.size() == 0) { - request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); - } else { - request = new ReadRequest(contentFormat, target); - } - } else if (resultIds.isObjectInstance()) { - request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId()); - } else if (resultIds.getObjectId() >= 0) { - request = new ObserveRequest(contentFormat, resultIds.getObjectId()); - } - break; - case EXECUTE: - ResourceModel resourceModelExecute = client.getResourceModel(targetIdVer, this.config.getModelProvider()); - if (resourceModelExecute != null) { - if (params != null && !resourceModelExecute.multiple) { - request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModelExecute.type, ResourceModel.Type.STRING, resultIds)); - } else { - request = new ExecuteRequest(target); - } - } - break; - case WRITE_REPLACE: - /** - * Request to write a String Single-Instance Resource using the TLV content format. - * Type from resourceModel -> STRING, INTEGER, FLOAT, BOOLEAN, OPAQUE, TIME, OBJLNK - * contentFormat -> TLV, TLV, TLV, TLV, OPAQUE, TLV, LINK - * JSON, TEXT; - **/ - ResourceModel resourceModelWrite = client.getResourceModel(targetIdVer, this.config.getModelProvider()); - if (resourceModelWrite != null) { -// contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat); -// request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), -// resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type, -// client, rpcRequest); - } - break; - case WRITE_UPDATE: - if (resultIds.isResource()) { - /** - * send request: path = '/3/0' node == wM2mObjectInstance - * with params == "\"resources\": {15: resource:{id:15. value:'+01'...}} - **/ - Collection resources = client.getNewResourceForInstance( - targetIdVer, params, - this.config.getModelProvider(), - this.converter); -// contentFormat = getContentFormatByResourceModelType(client.getResourceModel(targetIdVer, this.config.getModelProvider()), -// contentFormat); -// request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), -// resultIds.getObjectInstanceId(), resources); - } - /** - * params = "{\"id\":0,\"resources\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}" - * int rscId = resultIds.getObjectInstanceId(); - * contentFormat – Format of the payload (TLV or JSON). - */ - else if (resultIds.isObjectInstance()) { - if (((ConcurrentHashMap) params).size() > 0) { - Collection resources = client.getNewResourcesForInstance( - targetIdVer, params, - this.config.getModelProvider(), - this.converter); - if (resources.size() > 0) { - contentFormat = contentFormat.equals(ContentFormat.JSON) ? contentFormat : ContentFormat.TLV; - request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), - resultIds.getObjectInstanceId(), resources); - } - } - } else if (resultIds.getObjectId() >= 0) { - request = new ObserveRequest(resultIds.getObjectId()); - } - break; - case WRITE_ATTRIBUTES: - request = createWriteAttributeRequest(target, params, this.handler); - break; - case DELETE: - request = new DeleteRequest(target); - break; - } - return request; } - private void sendRequest(LwM2mClient client, SimpleDownlinkRequest request, long timeoutInMs) { - try { - sendRequest(client, request, timeoutInMs, null); - } catch (ClientSleepingException e) { - //TODO: this may cause infinite loop / memory leak. - client.getQueuedRequests().add(() -> sendRequest(client, request, timeoutInMs, null)); - } - } +// public void sendAllRequest(LwM2mClient client, String targetIdVer, LwM2mTypeOper typeOper, +// ContentFormat contentFormat, Object params, long timeoutInMs, LwM2mClientRpcRequest lwm2mClientRpcRequest) { +// Registration registration = client.getRegistration(); +// try { +// String target = fromVersionedIdToObjectId(targetIdVer); +// if (contentFormat == null) { +// contentFormat = client.getDefaultContentFormat(); +// } +// LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; +// if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0) { +// if (client.isValidObjectVersion(targetIdVer)) { +// timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; +// SimpleDownlinkRequest request = createRequest(registration, client, typeOper, contentFormat, target, +// targetIdVer, resultIds, params, lwm2mClientRpcRequest); +// if (request != null) { +// try { +// this.sendRequest(client, request, timeoutInMs, lwm2mClientRpcRequest); +// } catch (ClientSleepingException e) { +// SimpleDownlinkRequest finalRequest = request; +// long finalTimeoutInMs = timeoutInMs; +// LwM2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; +// client.getQueuedRequests().add(() -> sendRequest(client, finalRequest, finalTimeoutInMs, finalRpcRequest)); +// } catch (Exception e) { +// log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); +// } +// } else if (WRITE_UPDATE.name().equals(typeOper.name())) { +// if (lwm2mClientRpcRequest != null) { +// String errorMsg = String.format("Path %s params is not valid", targetIdVer); +// handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); +// } +// } else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) { +// if (lwm2mClientRpcRequest != null) { +// String errorMsg = String.format("Path %s object model is absent", targetIdVer); +// handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); +// } +// } else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) { +// log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); +// if (lwm2mClientRpcRequest != null) { +// ResourceModel resourceModel = client.getResourceModel(targetIdVer, this.config.getModelProvider()); +// String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; +// handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); +// } +// } +// } else if (lwm2mClientRpcRequest != null) { +// String errorMsg = String.format("Path %s not found in object version", targetIdVer); +// handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); +// } +// } else { +// switch (typeOper) { +// case OBSERVE_READ_ALL: +// case DISCOVER_ALL: +// Set paths; +// if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { +// Set observations = context.getServer().getObservationService().getObservations(registration); +// paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); +// } else { +// assert registration != null; +// Link[] objectLinks = registration.getSortedObjectLinks(); +// paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); +// } +// String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, +// typeOper.name(), paths); +// this.handler.sendLogsToThingsboard(client, msg); +// if (lwm2mClientRpcRequest != null) { +// String valueMsg = String.format("Paths - %s", paths); +// handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); +// } +// break; +// case OBSERVE_CANCEL: +// case OBSERVE_CANCEL_ALL: +// int observeCancelCnt = 0; +// String observeCancelMsg = null; +// if (OBSERVE_CANCEL.name().equals(typeOper)) { +// observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target); +// observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO, +// OBSERVE_CANCEL.name(), target, observeCancelCnt); +// } else { +// observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration); +// observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, +// OBSERVE_CANCEL.name(), observeCancelCnt); +// } +// this.afterObserveCancel(client, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest); +// break; +// // lwm2mClientRpcRequest != null +// case FW_UPDATE: +// handler.getInfoFirmwareUpdate(client, lwm2mClientRpcRequest); +// break; +// } +// } +// } catch (Exception e) { +// String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, +// typeOper.name(), e.getMessage()); +// handler.sendLogsToThingsboard(client, msg); +// if (lwm2mClientRpcRequest != null) { +// String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); +// handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); +// } +// } +// } - @SuppressWarnings({"error sendRequest"}) - private void sendRequest(LwM2mClient client, SimpleDownlinkRequest request, long timeoutInMs, LwM2mClientRpcRequest rpcRequest) { + private void sendRequest(LwM2mClient client, SimpleDownlinkRequest request, long timeoutInMs, DownlinkRequestCallback callback) { Registration registration = client.getRegistration(); - context.getServer().send(registration, request, timeoutInMs, (ResponseCallback) response -> { - - if (!client.isInit()) { - client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); - } - if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { - this.handleResponse(client, request.getPath().toString(), response, request, rpcRequest); - } else { - String msg = String.format("%s: SendRequest %s: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), - ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); - handler.sendLogsToThingsboard(client, msg); - log.error("[{}] [{}], [{}] - [{}] [{}] error SendRequest", request.getClass().getName().toString(), registration.getEndpoint(), - ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); - if (!client.isInit()) { - client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); - } - /** Not Found */ - if (rpcRequest != null) { - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); - } - /** Not Found - set setClient_fw_info... = empty - **/ - if (client.getFwUpdate() != null && client.getFwUpdate().isInfoFwSwUpdate()) { - client.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); - } - if (client.getSwUpdate() != null && client.getSwUpdate().isInfoFwSwUpdate()) { - client.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); - } - if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { - this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage()); - } - if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { - this.afterExecuteFwSwUpdateError(registration, request, response.getErrorMessage()); + context.getServer().send(registration, request, timeoutInMs, response -> { +// if (!client.isInit()) { +// client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); +// } + responseRequestExecutor.submit(() -> { + try { + callback.onSuccess(response); + } catch (Exception e) { + log.error("[{}] failed to process successful response [{}] ", registration.getEndpoint(), response, e); } - } + }); +// if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { +// this.handleResponse(client, request.getPath().toString(), response, request, rpcRequest); +// } else { +// String msg = String.format("%s: SendRequest %s: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), +// ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); +// handler.sendLogsToThingsboard(client, msg); +// log.error("[{}] [{}], [{}] - [{}] [{}] error SendRequest", request.getClass().getName().toString(), registration.getEndpoint(), +// ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); +// if (!client.isInit()) { +// client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); +// } +// /** Not Found */ +// if (rpcRequest != null) { +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); +// } +// /** Not Found +// set setClient_fw_info... = empty +// **/ +// if (client.getFwUpdate() != null && client.getFwUpdate().isInfoFwSwUpdate()) { +// client.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); +// } +// if (client.getSwUpdate() != null && client.getSwUpdate().isInfoFwSwUpdate()) { +// client.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); +// } +// if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { +// this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage()); +// } +// if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { +// this.afterExecuteFwSwUpdateError(registration, request, response.getErrorMessage()); +// } +// } }, e -> { - /** version == null - set setClient_fw_info... = empty - **/ - if (client.getFwUpdate() != null && client.getFwUpdate().isInfoFwSwUpdate()) { - client.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); - } - if (client.getSwUpdate() != null && client.getSwUpdate().isInfoFwSwUpdate()) { - client.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); - } - if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { - this.afterWriteFwSWUpdateError(registration, request, e.getMessage()); - } - if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { - this.afterExecuteFwSwUpdateError(registration, request, e.getMessage()); - } - if (!client.isInit()) { - client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); - } - String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", - LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); - handler.sendLogsToThingsboard(client, msg); - log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); - if (rpcRequest != null) { - handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); - } + responseRequestExecutor.submit(() -> { + callback.onError(e); + }); +// /** version == null +// set setClient_fw_info... = empty +// **/ +// if (client.getFwUpdate() != null && client.getFwUpdate().isInfoFwSwUpdate()) { +// client.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); +// } +// if (client.getSwUpdate() != null && client.getSwUpdate().isInfoFwSwUpdate()) { +// client.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); +// } +// if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { +// this.afterWriteFwSWUpdateError(registration, request, e.getMessage()); +// } +// if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) { +// this.afterExecuteFwSwUpdateError(registration, request, e.getMessage()); +// } +// if (!client.isInit()) { +// client.initReadValue(this.handler, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); +// } +// String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", +// LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); +// handler.sendLogsToThingsboard(client, msg); +// log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); +// if (rpcRequest != null) { +// handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); +// } }); } @@ -622,7 +459,9 @@ public class DefaultLwM2mDownlinkMsgHandler implements LwM2mDownlinkMsgHandler { } return new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueRequest); default: + throw new IllegalArgumentException("Not supported type:" + type.name()); } + // TODO: throw exception and execute callback. //// if (rpcRequest != null) { //// String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; @@ -663,158 +502,193 @@ public class DefaultLwM2mDownlinkMsgHandler implements LwM2mDownlinkMsgHandler { */ private void sendResponse(LwM2mClient lwM2mClient, String path, LwM2mResponse response, SimpleDownlinkRequest request, LwM2mClientRpcRequest rpcRequest) { - Registration registration = lwM2mClient.getRegistration(); - String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); - String msgLog = ""; - if (response instanceof ReadResponse) { - handler.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); - } else if (response instanceof DeleteResponse) { - log.warn("11) [{}] Path [{}] DeleteResponse", pathIdVer, response); - if (rpcRequest != null) { - rpcRequest.setInfoMsg(null); - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), null, null); - } - } else if (response instanceof DiscoverResponse) { - String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks()); - msgLog = String.format("%s: type operation: %s path: %s value: %s", - LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue); - handler.sendLogsToThingsboard(lwM2mClient, msgLog); - log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response); - if (rpcRequest != null) { - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE); - } - } else if (response instanceof ExecuteResponse) { - msgLog = String.format("%s: type operation: %s path: %s", - LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString()); - log.warn("9) [{}] ", msgLog); - handler.sendLogsToThingsboard(lwM2mClient, msgLog); - if (rpcRequest != null) { - msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg()); - rpcRequest.setInfoMsg(msgLog); - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), path, LOG_LW2M_INFO); - } - - } else if (response instanceof WriteAttributesResponse) { - msgLog = String.format("%s: type operation: %s path: %s value: %s", - LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); - handler.sendLogsToThingsboard(lwM2mClient, msgLog); - log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response); - if (rpcRequest != null) { - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); - } - } else if (response instanceof WriteResponse) { - msgLog = String.format("Type operation: Write path: %s", pathIdVer); - log.warn("10) [{}] response: [{}]", msgLog, response); - this.infoWriteResponse(lwM2mClient, response, request, rpcRequest); - handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); - } +// Registration registration = lwM2mClient.getRegistration(); +// String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); +// String msgLog = ""; +// if (response instanceof ReadResponse) { +// handler.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); +// } else if (response instanceof DeleteResponse) { +// log.warn("11) [{}] Path [{}] DeleteResponse", pathIdVer, response); +// if (rpcRequest != null) { +// rpcRequest.setInfoMsg(null); +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), null, null); +// } +// } else if (response instanceof DiscoverResponse) { +// String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks()); +// msgLog = String.format("%s: type operation: %s path: %s value: %s", +// LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue); +// handler.sendLogsToThingsboard(lwM2mClient, msgLog); +// log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response); +// if (rpcRequest != null) { +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE); +// } +// } else if (response instanceof ExecuteResponse) { +// msgLog = String.format("%s: type operation: %s path: %s", +// LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString()); +// log.warn("9) [{}] ", msgLog); +// handler.sendLogsToThingsboard(lwM2mClient, msgLog); +// if (rpcRequest != null) { +// msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg()); +// rpcRequest.setInfoMsg(msgLog); +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), path, LOG_LW2M_INFO); +// } +// +// } else if (response instanceof WriteAttributesResponse) { +// msgLog = String.format("%s: type operation: %s path: %s value: %s", +// LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); +// handler.sendLogsToThingsboard(lwM2mClient, msgLog); +// log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response); +// if (rpcRequest != null) { +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); +// } +// } else if (response instanceof WriteResponse) { +// msgLog = String.format("Type operation: Write path: %s", pathIdVer); +// log.warn("10) [{}] response: [{}]", msgLog, response); +// this.infoWriteResponse(lwM2mClient, response, request, rpcRequest); +// handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); +// } } - private void infoWriteResponse(LwM2mClient lwM2mClient, LwM2mResponse response, SimpleDownlinkRequest - request, LwM2mClientRpcRequest rpcRequest) { - try { - Registration registration = lwM2mClient.getRegistration(); - LwM2mNode node = ((WriteRequest) request).getNode(); - String msg = null; - Object value; - if (node instanceof LwM2mObject) { - msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObject) node).toString()); - } else if (node instanceof LwM2mObjectInstance) { - msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObjectInstance) node).prettyPrint()); - } else if (node instanceof LwM2mSingleResource) { - LwM2mSingleResource singleResource = (LwM2mSingleResource) node; - if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) { - int valueLength; - if (singleResource.getType() == ResourceModel.Type.STRING) { - valueLength = ((String) singleResource.getValue()).length(); - value = ((String) singleResource.getValue()) - .substring(Math.min(valueLength, config.getLogMaxLength())).trim(); - - } else { - valueLength = ((byte[]) singleResource.getValue()).length; - value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()), - Math.min(valueLength, config.getLogMaxLength()))).trim(); - } - value = valueLength > config.getLogMaxLength() ? value + "..." : value; - msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s", - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value); - } else { - value = this.converter.convertValue(singleResource.getValue(), - singleResource.getType(), ResourceModel.Type.STRING, request.getPath()); - msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s", - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value); - } - } - if (msg != null) { - handler.sendLogsToThingsboard(lwM2mClient, msg); - if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { - this.afterWriteSuccessFwSwUpdate(registration, request); - if (rpcRequest != null) { - rpcRequest.setInfoMsg(msg); - } - } else if (rpcRequest != null) { - handler.sentRpcResponse(rpcRequest, response.getCode().getName(), msg, LOG_LW2M_INFO); - } - } - } catch (Exception e) { - log.trace("Fail convert value from request to string. ", e); - } - } +// private void infoWriteResponse(LwM2mClient lwM2mClient, LwM2mResponse response, SimpleDownlinkRequest +// request, LwM2mClientRpcRequest rpcRequest) { +// try { +// Registration registration = lwM2mClient.getRegistration(); +// LwM2mNode node = ((WriteRequest) request).getNode(); +// String msg = null; +// Object value; +// if (node instanceof LwM2mObject) { +// msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", +// LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObject) node).toString()); +// } else if (node instanceof LwM2mObjectInstance) { +// msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", +// LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObjectInstance) node).prettyPrint()); +// } else if (node instanceof LwM2mSingleResource) { +// LwM2mSingleResource singleResource = (LwM2mSingleResource) node; +// if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) { +// int valueLength; +// if (singleResource.getType() == ResourceModel.Type.STRING) { +// valueLength = ((String) singleResource.getValue()).length(); +// value = ((String) singleResource.getValue()) +// .substring(Math.min(valueLength, config.getLogMaxLength())).trim(); +// +// } else { +// valueLength = ((byte[]) singleResource.getValue()).length; +// value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()), +// Math.min(valueLength, config.getLogMaxLength()))).trim(); +// } +// value = valueLength > config.getLogMaxLength() ? value + "..." : value; +// msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s", +// LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value); +// } else { +// value = this.converter.convertValue(singleResource.getValue(), +// singleResource.getType(), ResourceModel.Type.STRING, request.getPath()); +// msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s", +// LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value); +// } +// } +// if (msg != null) { +// handler.sendLogsToThingsboard(lwM2mClient, msg); +// if (request.getPath().toString().equals(FW_PACKAGE_5_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { +// this.afterWriteSuccessFwSwUpdate(registration, request); +// if (rpcRequest != null) { +// rpcRequest.setInfoMsg(msg); +// } +// } else if (rpcRequest != null) { +// handler.sentRpcResponse(rpcRequest, response.getCode().getName(), msg, LOG_LW2M_INFO); +// } +// } +// } catch (Exception e) { +// log.trace("Fail convert value from request to string. ", e); +// } +// } /** * After finish operation FwSwUpdate Write (success): * fw_state/sw_state = DOWNLOADED * send operation Execute */ - private void afterWriteSuccessFwSwUpdate(Registration registration, SimpleDownlinkRequest request) { - LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); - if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && client.getFwUpdate() != null) { - client.getFwUpdate().setStateUpdate(DOWNLOADED.name()); - client.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); - } - if (request.getPath().toString().equals(SW_PACKAGE_ID) && client.getSwUpdate() != null) { - client.getSwUpdate().setStateUpdate(DOWNLOADED.name()); - client.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); - } - } +// private void afterWriteSuccessFwSwUpdate(Registration registration, SimpleDownlinkRequest request) { +// LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); +// if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && client.getFwUpdate() != null) { +// client.getFwUpdate().setStateUpdate(DOWNLOADED.name()); +// client.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); +// } +// if (request.getPath().toString().equals(SW_PACKAGE_ID) && client.getSwUpdate() != null) { +// client.getSwUpdate().setStateUpdate(DOWNLOADED.name()); +// client.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); +// } +// } /** * After finish operation FwSwUpdate Write (error): fw_state = FAILED */ - private void afterWriteFwSWUpdateError(Registration registration, SimpleDownlinkRequest request, String - msgError) { - LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); - if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && client.getFwUpdate() != null) { - client.getFwUpdate().setStateUpdate(FAILED.name()); - client.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); - } - if (request.getPath().toString().equals(SW_PACKAGE_ID) && client.getSwUpdate() != null) { - client.getSwUpdate().setStateUpdate(FAILED.name()); - client.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); - } +// private void afterWriteFwSWUpdateError(Registration registration, SimpleDownlinkRequest request, String +// msgError) { +// LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); +// if (request.getPath().toString().equals(FW_PACKAGE_5_ID) && client.getFwUpdate() != null) { +// client.getFwUpdate().setStateUpdate(FAILED.name()); +// client.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); +// } +// if (request.getPath().toString().equals(SW_PACKAGE_ID) && client.getSwUpdate() != null) { +// client.getSwUpdate().setStateUpdate(FAILED.name()); +// client.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); +// } +// } + +// private void afterExecuteFwSwUpdateError(Registration registration, SimpleDownlinkRequest request, String +// msgError) { +// LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); +// if (request.getPath().toString().equals(FW_UPDATE_ID) && client.getFwUpdate() != null) { +// client.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); +// } +// if (request.getPath().toString().equals(SW_INSTALL_ID) && client.getSwUpdate() != null) { +// client.getSwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); +// } +// } + +// private void afterObserveCancel(LwM2mClient lwM2mClient, int observeCancelCnt, String +// observeCancelMsg, LwM2mClientRpcRequest rpcRequest) { +// handler.sendLogsToThingsboard(lwM2mClient, observeCancelMsg); +// log.warn("[{}]", observeCancelMsg); +// if (rpcRequest != null) { +// rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt)); +// handler.sentRpcResponse(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO); +// } +// } + + + private static void addAttribute(List attributes, String attributeName, T value) { + addAttribute(attributes, attributeName, value, null, null); } - private void afterExecuteFwSwUpdateError(Registration registration, SimpleDownlinkRequest request, String - msgError) { - LwM2mClient client = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); - if (request.getPath().toString().equals(FW_UPDATE_ID) && client.getFwUpdate() != null) { - client.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); - } - if (request.getPath().toString().equals(SW_INSTALL_ID) && client.getSwUpdate() != null) { - client.getSwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); + private static void addAttribute(List attributes, String attributeName, T value, Function converter) { + addAttribute(attributes, attributeName, value, null, converter); + } + + private static void addAttribute(List attributes, String attributeName, T value, Predicate filter, Function converter) { + if (value != null && ((filter == null) || filter.test(value))) { + attributes.add(new Attribute(attributeName, converter != null ? converter.apply(value) : value)); } } - private void afterObserveCancel(LwM2mClient lwM2mClient, int observeCancelCnt, String - observeCancelMsg, LwM2mClientRpcRequest rpcRequest) { - handler.sendLogsToThingsboard(lwM2mClient, observeCancelMsg); - log.warn("[{}]", observeCancelMsg); - if (rpcRequest != null) { - rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt)); - handler.sentRpcResponse(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO); + private static ContentFormat convertResourceModelTypeToContentFormat(LwM2mClient client, ResourceModel.Type type) { + switch (type) { + case BOOLEAN: + case STRING: + case TIME: + case INTEGER: + case FLOAT: + return client.getDefaultContentFormat(); + case OPAQUE: + return ContentFormat.OPAQUE; + case OBJLNK: + return ContentFormat.LINK; + default: } + throw new CodecException("Invalid ResourceModel_Type for %s ContentFormat.", type); } + private static ContentFormat getContentFormat(LwM2mClient client, HasContentFormat request) { + return request.getContentFormat() != null ? request.getContentFormat() : client.getDefaultContentFormat(); + } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mDownlinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mDownlinkMsgHandler.java index 40ad57e026..ed6226fc1d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mDownlinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mDownlinkMsgHandler.java @@ -15,34 +15,56 @@ */ package org.thingsboard.server.transport.lwm2m.server; -import org.eclipse.leshan.core.request.ContentFormat; -import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; +import org.eclipse.leshan.core.response.CancelObservationResponse; +import org.eclipse.leshan.core.response.DeleteResponse; +import org.eclipse.leshan.core.response.DiscoverResponse; +import org.eclipse.leshan.core.response.ExecuteResponse; +import org.eclipse.leshan.core.response.ObserveResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.eclipse.leshan.core.response.WriteAttributesResponse; +import org.eclipse.leshan.core.response.WriteResponse; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; import org.thingsboard.server.transport.lwm2m.server.downlink.DownlinkRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MCancelObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDeleteRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MDiscoverRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveAllRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MReadRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteUpdateRequest; + +import java.util.Set; public interface LwM2mDownlinkMsgHandler { - void sendReadRequest(LwM2mClient client, String targetId, Long timeout); + void sendReadRequest(LwM2mClient client, TbLwM2MReadRequest request, DownlinkRequestCallback callback); + + void sendObserveRequest(LwM2mClient client, TbLwM2MObserveRequest request, DownlinkRequestCallback callback); + + void sendObserveAllRequest(LwM2mClient client, TbLwM2MObserveAllRequest request, DownlinkRequestCallback> callback); - void sendReadRequest(LwM2mClient client, String targetId, ContentFormat contentFormat, Long timeout); + void sendExecuteRequest(LwM2mClient client, TbLwM2MExecuteRequest request, DownlinkRequestCallback callback); - void sendObserveRequest(LwM2mClient client, String targetId, Long timeout); + void sendDeleteRequest(LwM2mClient client, TbLwM2MDeleteRequest request, DownlinkRequestCallback callback); - void sendObserveRequest(LwM2mClient client, String targetId, ContentFormat contentFormat, Long timeout); + void sendCancelObserveRequest(LwM2mClient client, TbLwM2MCancelObserveRequest request, DownlinkRequestCallback callback); - void sendExecuteRequest(LwM2mClient client, String targetId, Long timeout, DownlinkRequestCallback callback); + void sendCancelAllRequest(LwM2mClient client, TbLwM2MCancelAllRequest request, DownlinkRequestCallback callback); - void sendExecuteRequest(LwM2mClient client, String targetId, Object params, Long timeout, DownlinkRequestCallback callback); + void sendDiscoverRequest(LwM2mClient client, TbLwM2MDiscoverRequest request, DownlinkRequestCallback callback); - void sendCancelObserveRequest(LwM2mClient client, String targetId, Long timeout, DownlinkRequestCallback callback); + void sendDiscoverAllRequest(LwM2mClient client, TbLwM2MDiscoverAllRequest request, DownlinkRequestCallback> callback); - void sendCancelAllRequest(LwM2mClient client, Long timeout, DownlinkRequestCallback callback); + void sendWriteAttributesRequest(LwM2mClient client, TbLwM2MWriteAttributesRequest request, DownlinkRequestCallback callback); - void sendDiscoverRequest(LwM2mClient client, String targetId, Long timeout); + void sendWriteReplaceRequest(LwM2mClient client, TbLwM2MWriteReplaceRequest request, DownlinkRequestCallback callback); - void sendWriteAttributesRequest(LwM2mClient client, String targetId, ObjectAttributes params, Long timeout); + void sendWriteUpdateRequest(LwM2mClient client, TbLwM2MWriteUpdateRequest request, DownlinkRequestCallback callback); - void sendWriteReplaceRequest(LwM2mClient client, String targetIdVer, Object newValue, Long timeout, DownlinkRequestCallback callback); - void sendWriteUpdateRequest(LwM2mClient client, String targetIdVer, Object newValue, ContentFormat contentFormat, Long timeout, DownlinkRequestCallback callback); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mUplinkMsgHandler.java index fcccf29f1d..132bd8689d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mUplinkMsgHandler.java @@ -38,8 +38,6 @@ public interface LwM2mUplinkMsgHandler { void onSleepingDev(Registration registration); - void setCancelObservationsAll(Registration registration); - void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, LwM2mClientRpcRequest rpcRequest); void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); 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 5c210d2af3..9148a44e93 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 @@ -39,6 +39,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; import java.util.Collection; @@ -394,18 +395,18 @@ public class LwM2mClient implements Cloneable { } } - public LwM2mFwSwUpdate getFwUpdate (LwM2mClientContext clientContext) { + public LwM2mFwSwUpdate getFwUpdate(LwM2mUplinkMsgHandler handler, LwM2mClientContext clientContext) { if (this.fwUpdate == null) { var profile = clientContext.getProfile(this.getProfileId()); - this.fwUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.FIRMWARE, profile.getClientLwM2mSettings().getFwUpdateStrategy()); + this.fwUpdate = new LwM2mFwSwUpdate(handler, this, OtaPackageType.FIRMWARE, profile.getClientLwM2mSettings().getFwUpdateStrategy()); } return this.fwUpdate; } - public LwM2mFwSwUpdate getSwUpdate (LwM2mClientContext clientContext) { + public LwM2mFwSwUpdate getSwUpdate (LwM2mUplinkMsgHandler handler,LwM2mClientContext clientContext) { if (this.swUpdate == null) { var profile = clientContext.getProfile(this.getProfileId()); - this.swUpdate = new LwM2mFwSwUpdate(this, OtaPackageType.SOFTWARE, profile.getClientLwM2mSettings().getSwUpdateStrategy()); + this.swUpdate = new LwM2mFwSwUpdate(handler, this, OtaPackageType.SOFTWARE, profile.getClientLwM2mSettings().getSwUpdateStrategy()); } return this.fwUpdate; } 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 efc5aa9657..0dda5d7269 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 @@ -27,6 +27,13 @@ import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MUplinkMsgHandler; import org.thingsboard.server.transport.lwm2m.server.LwM2mDownlinkMsgHandler; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequest; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MObserveRequestCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceCallback; +import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest; import java.util.ArrayList; import java.util.List; @@ -112,6 +119,9 @@ public class LwM2mFwSwUpdate { @Setter private volatile boolean infoFwSwUpdate = false; private final OtaPackageType type; + + private final LwM2mUplinkMsgHandler handler; + @Getter LwM2mClient lwM2MClient; @Getter @@ -124,7 +134,8 @@ public class LwM2mFwSwUpdate { @Setter private volatile int updateStrategy; - public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type, int updateStrategy) { + public LwM2mFwSwUpdate(LwM2mUplinkMsgHandler handler, LwM2mClient lwM2MClient, OtaPackageType type, int updateStrategy) { + this.handler = handler; this.lwM2MClient = lwM2MClient; this.pendingInfoRequestsStart = new CopyOnWriteArrayList<>(); this.type = type; @@ -189,7 +200,9 @@ public class LwM2mFwSwUpdate { int chunkSize = 0; int chunk = 0; byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk); - request.sendWriteReplaceRequest(this.lwM2MClient, targetIdVer, firmwareChunk, handler.config.getTimeout(), this.rpcRequest); + + TbLwM2MWriteReplaceRequest downlink = TbLwM2MWriteReplaceRequest.builder().versionedId(targetIdVer).value(firmwareChunk).timeout(handler.config.getTimeout()).build(); + request.sendWriteReplaceRequest(lwM2MClient, downlink, new TbLwM2MWriteReplaceCallback(handler, lwM2MClient, targetIdVer)); } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL.code == this.updateStrategy) { Registration registration = this.getLwM2MClient().getRegistration(); // String api = handler.config.getHostRequests(); @@ -197,7 +210,9 @@ public class LwM2mFwSwUpdate { int port = registration.getIdentity().isSecure() ? handler.config.getSecurePort() : handler.config.getPort(); String uri = "coap://" + api + ":" + Integer.valueOf(port) + "/" + FIRMWARE_UPDATE_COAP_RECOURSE + "/" + this.currentId.toString(); log.warn("89) coapUri: [{}]", uri); - request.sendWriteReplaceRequest(this.lwM2MClient, targetIdVer, uri, handler.config.getTimeout(), this.rpcRequest); + //TODO: user this.rpcRequest??? + TbLwM2MWriteReplaceRequest downlink = TbLwM2MWriteReplaceRequest.builder().versionedId(targetIdVer).value(uri).timeout(handler.config.getTimeout()).build(); + request.sendWriteReplaceRequest(lwM2MClient, downlink, new TbLwM2MWriteReplaceCallback(handler, lwM2MClient, targetIdVer)); } else if (LwM2mTransportUtil.LwM2MFirmwareUpdateStrategy.OBJ_19_BINARY.code == this.updateStrategy) { } @@ -230,7 +245,9 @@ public class LwM2mFwSwUpdate { */ public void executeFwSwWare(DefaultLwM2MUplinkMsgHandler handler, LwM2mDownlinkMsgHandler request) { this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); - request.sendExecuteRequest(this.lwM2MClient, this.pathInstallId, handler.config.getTimeout(), this.rpcRequest); + //TODO: user this.rpcRequest??? + TbLwM2MExecuteRequest downlink = TbLwM2MExecuteRequest.builder().versionedId(pathInstallId).timeout(handler.config.getTimeout()).build(); + request.sendExecuteRequest(lwM2MClient, downlink, new TbLwM2MExecuteRequestCallback(handler, lwM2MClient, pathInstallId)); } /** @@ -253,23 +270,21 @@ public class LwM2mFwSwUpdate { String ver3 = (String) this.lwM2MClient.getResourceValue(null, FW_3_VER_ID); // #1/#2 String fwMsg = null; - if ((this.currentVersion != null && ( + if ((this.currentVersion != null && ( ver5 != null && ver5.equals(this.currentVersion) || - ver3 != null && ver3.contains(this.currentVersion) - )) || - (this.currentTitle != null && pathName != null && this.currentTitle.equals(pathName))) { + ver3 != null && ver3.contains(this.currentVersion) + )) || + (this.currentTitle != null && pathName != null && this.currentTitle.equals(pathName))) { fwMsg = String.format("%s: The update was interrupted. The device has the same version: %s.", LOG_LW2M_ERROR, this.currentVersion); - } - else if (updateResultFw != null && updateResultFw > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { + } else if (updateResultFw != null && updateResultFw > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) { fwMsg = String.format("%s: The update was interrupted. The device has the status UpdateResult: error (%d).", LOG_LW2M_ERROR, updateResultFw); } if (fwMsg != null) { handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId()); return false; - } - else { + } else { return true; } } @@ -415,8 +430,9 @@ public class LwM2mFwSwUpdate { this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer( this.pathNameId, this.lwM2MClient.getRegistration())); } - this.pendingInfoRequestsStart.forEach(pathIdVer -> { - request.sendObserveRequest(this.lwM2MClient, pathIdVer, 0, this.rpcRequest); + this.pendingInfoRequestsStart.forEach(versionedId -> { + TbLwM2MObserveRequest downlink = TbLwM2MObserveRequest.builder().versionedId(versionedId).build(); + request.sendObserveRequest(this.lwM2MClient, downlink, new TbLwM2MObserveRequestCallback(handler, lwM2MClient, versionedId)); }); } @@ -449,7 +465,7 @@ public class LwM2mFwSwUpdate { } else if (OBJ_5_TEMP_URL.code == this.getUpdateStrategy()) { if (this.currentId != null && (convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path))) { String state = equalsFwSateToFirmwareUpdateStatus(LwM2mTransportUtil.StateFw.fromStateFwByCode(value)).name(); - if (StringUtils.isNotEmpty(state) && !FAILED.name().equals(this.stateUpdate) && !state.equals(this.stateUpdate)) { + if (StringUtils.isNotEmpty(state) && !FAILED.name().equals(this.stateUpdate) && !state.equals(this.stateUpdate)) { this.stateUpdate = state; this.sendSateOnThingsBoard(handler); } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MRequestCallback.java new file mode 100644 index 0000000000..16723aaadf --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MRequestCallback.java @@ -0,0 +1,40 @@ +/** + * 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.downlink; + +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public abstract class AbstractTbLwM2MRequestCallback implements DownlinkRequestCallback { + + protected final LwM2mUplinkMsgHandler handler; + protected final LwM2mClient client; + + protected AbstractTbLwM2MRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client) { + this.handler = handler; + this.client = client; + } + + @Override + public void onValidationError(String msg) { + + } + + @Override + public void onError(Exception e) { + + } +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MTargetedDownlinkRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MTargetedDownlinkRequest.java new file mode 100644 index 0000000000..7d81308df1 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/AbstractTbLwM2MTargetedDownlinkRequest.java @@ -0,0 +1,32 @@ +/** + * 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.downlink; + +import lombok.Getter; + +public abstract class AbstractTbLwM2MTargetedDownlinkRequest implements TbLwM2MDownlinkRequest, HasVersionedId { + + @Getter + private final String versionedId; + @Getter + private final long timeout; + + public AbstractTbLwM2MTargetedDownlinkRequest(String versionedId, long timeout) { + this.versionedId = versionedId; + this.timeout = timeout; + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DownlinkRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DownlinkRequestCallback.java index 84f1854e1d..342abf39f4 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DownlinkRequestCallback.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/DownlinkRequestCallback.java @@ -15,11 +15,30 @@ */ package org.thingsboard.server.transport.lwm2m.server.downlink; -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; +public interface DownlinkRequestCallback { -public interface DownlinkRequestCallback { + void onSuccess(T response); - void onSuccess(LwM2mClient client, String msg); + void onValidationError(String msg); - void onError(LwM2mClient client, String msg, Exception e); + void onError(Exception e); + + static DownlinkRequestCallback doNothing() { + return new DownlinkRequestCallback() { + @Override + public void onSuccess(T response) { + + } + + @Override + public void onValidationError(String msg) { + + } + + @Override + public void onError(Exception e) { + + } + }; + } } diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasContentFormat.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasContentFormat.java new file mode 100644 index 0000000000..6d2ecc98ed --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasContentFormat.java @@ -0,0 +1,23 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.request.ContentFormat; + +public interface HasContentFormat { + + ContentFormat getContentFormat(); +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasVersionedId.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasVersionedId.java new file mode 100644 index 0000000000..fcbb195935 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/HasVersionedId.java @@ -0,0 +1,28 @@ +/** + * 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.downlink; + +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public interface HasVersionedId { + + String getVersionedId(); + + default String getObjectId(){ + return LwM2mTransportUtil.fromVersionedIdToObjectId(getVersionedId()); + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllObserveRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllObserveRequestCallback.java new file mode 100644 index 0000000000..a76f317085 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllObserveRequestCallback.java @@ -0,0 +1,36 @@ +/** + * 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.downlink; + +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL; + +public class TbLwM2MCancelAllObserveRequestCallback extends AbstractTbLwM2MRequestCallback { + + public TbLwM2MCancelAllObserveRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client) { + super(handler, client); + } + + @Override + public void onSuccess(Integer canceledSubscriptionsCount) { + String observeCancelMsg = String.format("%s: type operation %s paths: count: %d", LOG_LW2M_INFO, OBSERVE_CANCEL_ALL.name(), canceledSubscriptionsCount); + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllRequest.java new file mode 100644 index 0000000000..b6f796aefd --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelAllRequest.java @@ -0,0 +1,38 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.response.CancelObservationResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MCancelAllRequest implements TbLwM2MDownlinkRequest { + + @Getter + private final long timeout; + + @Builder + private TbLwM2MCancelAllRequest(long timeout) { + this.timeout = timeout; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL; + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequest.java new file mode 100644 index 0000000000..51b016f80d --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequest.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import lombok.Builder; +import org.eclipse.leshan.core.response.CancelObservationResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MCancelObserveRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Builder + private TbLwM2MCancelObserveRequest(String versionedId, long timeout) { + super(versionedId, timeout); + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequestCallback.java new file mode 100644 index 0000000000..48d7519006 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MCancelObserveRequestCallback.java @@ -0,0 +1,38 @@ +/** + * 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.downlink; + +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO; +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; + +public class TbLwM2MCancelObserveRequestCallback extends AbstractTbLwM2MRequestCallback { + + private final String versionedId; + + public TbLwM2MCancelObserveRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String versionedId) { + super(handler, client); + this.versionedId = versionedId; + } + + @Override + public void onSuccess(Integer canceledSubscriptionsCount) { + String observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO, OBSERVE_CANCEL.name(), versionedId, canceledSubscriptionsCount); + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequest.java new file mode 100644 index 0000000000..63a360b822 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequest.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MDeleteRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Builder + private TbLwM2MDeleteRequest(String versionedId, long timeout) { + super(versionedId, timeout); + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.DELETE; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequestCallback.java new file mode 100644 index 0000000000..106f34a14d --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDeleteRequestCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.DeleteResponse; +import org.eclipse.leshan.core.response.ExecuteResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MDeleteRequestCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MDeleteRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(DeleteResponse response) { + //TODO: separate callback wrapper for the RPC calls. + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverAllRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverAllRequest.java new file mode 100644 index 0000000000..16f32a9ecc --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverAllRequest.java @@ -0,0 +1,40 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.response.DiscoverResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MDiscoverAllRequest implements TbLwM2MDownlinkRequest { + + @Getter + private final long timeout; + + @Builder + private TbLwM2MDiscoverAllRequest(long timeout) { + this.timeout = timeout; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverCallback.java new file mode 100644 index 0000000000..fa0e3cf761 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.DeleteResponse; +import org.eclipse.leshan.core.response.DiscoverResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MDiscoverCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MDiscoverCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(DiscoverResponse response) { + //TODO: separate callback wrapper for the RPC calls. + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverRequest.java new file mode 100644 index 0000000000..6b0dcc4994 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDiscoverRequest.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import lombok.Builder; +import org.eclipse.leshan.core.response.DiscoverResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MDiscoverRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Builder + private TbLwM2MDiscoverRequest(String versionedId, long timeout) { + super(versionedId, timeout); + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDownlinkRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDownlinkRequest.java new file mode 100644 index 0000000000..a069bb4ddc --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MDownlinkRequest.java @@ -0,0 +1,26 @@ +/** + * 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.downlink; + +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public interface TbLwM2MDownlinkRequest { + + LwM2mTransportUtil.LwM2mTypeOper getType(); + + long getTimeout(); + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequest.java new file mode 100644 index 0000000000..32d1be665c --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequest.java @@ -0,0 +1,41 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MExecuteRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Getter + private final Object params; + + @Builder + private TbLwM2MExecuteRequest(String versionedId, long timeout, Object params) { + super(versionedId, timeout); + this.params = params; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequestCallback.java new file mode 100644 index 0000000000..4a2ca7f1fb --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MExecuteRequestCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.ExecuteResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MExecuteRequestCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MExecuteRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(ExecuteResponse response) { + //TODO: separate callback wrapper for the RPC calls. + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveAllRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveAllRequest.java new file mode 100644 index 0000000000..b12b4469d6 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveAllRequest.java @@ -0,0 +1,41 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +import java.util.Set; + +public class TbLwM2MObserveAllRequest implements TbLwM2MDownlinkRequest> { + + @Getter + private final long timeout; + + @Builder + private TbLwM2MObserveAllRequest(long timeout) { + this.timeout = timeout; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequest.java new file mode 100644 index 0000000000..1239725be2 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequest.java @@ -0,0 +1,43 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.request.ContentFormat; +import org.eclipse.leshan.core.response.ObserveResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MObserveRequest extends AbstractTbLwM2MTargetedDownlinkRequest implements HasContentFormat { + + @Getter + private final ContentFormat contentFormat; + + @Builder + private TbLwM2MObserveRequest(String versionedId, long timeout, ContentFormat contentFormat) { + super(versionedId, timeout); + this.contentFormat = contentFormat; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequestCallback.java new file mode 100644 index 0000000000..65f04cd920 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MObserveRequestCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.ObserveResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MObserveRequestCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MObserveRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(ObserveResponse response) { + //TODO: handle the response (at least log to telemetry) + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequest.java new file mode 100644 index 0000000000..5d88a20ae4 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequest.java @@ -0,0 +1,42 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.request.ContentFormat; +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MReadRequest extends AbstractTbLwM2MTargetedDownlinkRequest implements HasContentFormat { + + @Getter + private final ContentFormat contentFormat; + + @Builder + private TbLwM2MReadRequest(String versionedId, long timeout, ContentFormat contentFormat) { + super(versionedId, timeout); + this.contentFormat = contentFormat; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.READ; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequestCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequestCallback.java new file mode 100644 index 0000000000..345c585b1f --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MReadRequestCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.ReadResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MReadRequestCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MReadRequestCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(ReadResponse response) { + //TODO: separate callback wrapper for the RPC calls. + handler.onUpdateValueAfterReadResponse(client.getRegistration(), targetId, response, null); + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesCallback.java new file mode 100644 index 0000000000..4bda629256 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesCallback.java @@ -0,0 +1,38 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.ReadResponse; +import org.eclipse.leshan.core.response.WriteAttributesResponse; +import org.eclipse.leshan.core.response.WriteResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MWriteAttributesCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MWriteAttributesCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(WriteAttributesResponse response) { + //TODO: separate callback wrapper for the RPC calls. + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesRequest.java new file mode 100644 index 0000000000..dd1f9311d9 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteAttributesRequest.java @@ -0,0 +1,44 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.request.ContentFormat; +import org.eclipse.leshan.core.response.ObserveResponse; +import org.eclipse.leshan.core.response.WriteAttributesResponse; +import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MWriteAttributesRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Getter + private final ObjectAttributes attributes; + + @Builder + private TbLwM2MWriteAttributesRequest(String versionedId, long timeout, ObjectAttributes attributes) { + super(versionedId, timeout); + this.attributes = attributes; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceCallback.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceCallback.java new file mode 100644 index 0000000000..b15632da19 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceCallback.java @@ -0,0 +1,37 @@ +/** + * 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.downlink; + +import org.eclipse.leshan.core.response.WriteAttributesResponse; +import org.eclipse.leshan.core.response.WriteResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mUplinkMsgHandler; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; + +public class TbLwM2MWriteReplaceCallback extends AbstractTbLwM2MRequestCallback { + + private final String targetId; + + public TbLwM2MWriteReplaceCallback(LwM2mUplinkMsgHandler handler, LwM2mClient client, String targetId) { + super(handler, client); + this.targetId = targetId; + } + + @Override + public void onSuccess(WriteResponse response) { + //TODO: separate callback wrapper for the RPC calls. + } + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceRequest.java new file mode 100644 index 0000000000..71c1080655 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteReplaceRequest.java @@ -0,0 +1,43 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.response.WriteAttributesResponse; +import org.eclipse.leshan.core.response.WriteResponse; +import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MWriteReplaceRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Getter + private final Object value; + + @Builder + private TbLwM2MWriteReplaceRequest(String versionedId, long timeout, Object value) { + super(versionedId, timeout); + this.value = value; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; + } + + + +} diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteUpdateRequest.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteUpdateRequest.java new file mode 100644 index 0000000000..071d9fc889 --- /dev/null +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/downlink/TbLwM2MWriteUpdateRequest.java @@ -0,0 +1,45 @@ +/** + * 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.downlink; + +import lombok.Builder; +import lombok.Getter; +import org.eclipse.leshan.core.request.ContentFormat; +import org.eclipse.leshan.core.response.WriteResponse; +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil; + +public class TbLwM2MWriteUpdateRequest extends AbstractTbLwM2MTargetedDownlinkRequest { + + @Getter + private final Object value; + @Getter + private final ContentFormat objectContentFormat; + + @Builder + private TbLwM2MWriteUpdateRequest(String versionedId, long timeout, Object value, ContentFormat objectContentFormat) { + super(versionedId, timeout); + this.value = value; + this.objectContentFormat = objectContentFormat; + } + + @Override + public LwM2mTransportUtil.LwM2mTypeOper getType() { + return LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; + } + + + +}