From a665b2cbe631dc87ed128b2182cfbc25ddff03c7 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Thu, 24 Jun 2021 10:53:35 +0300 Subject: [PATCH] added power mode to lwm2m-device-profile-transport-configuration --- .../transport/DefaultTransportApiService.java | 10 +++ .../Lwm2mDeviceTransportConfiguration.java | 5 +- common/queue/src/main/proto/queue.proto | 1 + .../transport/coap/CoapTransportResource.java | 19 +---- .../transport/http/DeviceApiController.java | 16 +--- ...LwM2mCredentialsSecurityInfoValidator.java | 10 ++- .../lwm2m/secure/TbLwM2MAuthorizer.java | 11 ++- .../lwm2m/server/LwM2mSessionMsgListener.java | 19 +---- .../server/client/LwM2MAuthException.java | 22 ++++++ .../lwm2m/server/client/LwM2mClient.java | 7 ++ .../uplink/DefaultLwM2MUplinkMsgHandler.java | 77 ++++++++++--------- .../transport/mqtt/MqttTransportHandler.java | 24 +----- .../mqtt/session/GatewayDeviceSessionCtx.java | 23 +----- .../snmp/session/DeviceSessionContext.java | 19 +---- .../common/transport/TransportService.java | 7 +- .../transport/auth/TransportDeviceInfo.java | 2 + .../service/DefaultTransportService.java | 34 ++++++-- ...ile-transport-configuration.component.html | 7 +- ...ofile-transport-configuration.component.ts | 9 +-- .../lwm2m/lwm2m-profile-config.models.ts | 14 ++-- ...ice-transport-configuration.component.html | 4 +- ...ice-transport-configuration.component.html | 14 ++-- ...evice-transport-configuration.component.ts | 9 ++- ui-ngx/src/app/shared/models/device.models.ts | 2 +- .../assets/locale/locale.constant-en_US.json | 7 ++ 25 files changed, 186 insertions(+), 186 deletions(-) create mode 100644 common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MAuthException.java diff --git a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java index c09d81bd45..de3615ae08 100644 --- a/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java +++ b/application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java @@ -41,6 +41,8 @@ import org.thingsboard.server.common.data.TbResource; import org.thingsboard.server.common.data.TenantProfile; import org.thingsboard.server.common.data.device.credentials.BasicMqttCredentials; import org.thingsboard.server.common.data.device.credentials.ProvisionDeviceCredentialsData; +import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; +import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.profile.ProvisionDeviceProfileCredentials; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; @@ -459,6 +461,13 @@ public class DefaultTransportApiService implements TransportApiService { } private DeviceInfoProto getDeviceInfoProto(Device device) throws JsonProcessingException { + PowerMode powerMode = null; + switch (device.getDeviceData().getTransportConfiguration().getType()) { + case LWM2M: + powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode(); + break; + } + return DeviceInfoProto.newBuilder() .setTenantIdMSB(device.getTenantId().getId().getMostSignificantBits()) .setTenantIdLSB(device.getTenantId().getId().getLeastSignificantBits()) @@ -471,6 +480,7 @@ public class DefaultTransportApiService implements TransportApiService { .setDeviceProfileIdMSB(device.getDeviceProfileId().getId().getMostSignificantBits()) .setDeviceProfileIdLSB(device.getDeviceProfileId().getId().getLeastSignificantBits()) .setAdditionalInfo(mapper.writeValueAsString(device.getAdditionalInfo())) + .setPowerMode(powerMode != null ? powerMode.name() : null) .build(); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java index 510bfeda7f..085e60212a 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/data/Lwm2mDeviceTransportConfiguration.java @@ -20,9 +20,6 @@ import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.Data; import org.thingsboard.server.common.data.DeviceTransportType; -import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration; -import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; -import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; import java.util.HashMap; import java.util.Map; @@ -30,6 +27,8 @@ import java.util.Map; @Data public class Lwm2mDeviceTransportConfiguration implements DeviceTransportConfiguration { + private PowerMode powerMode; + @JsonIgnore private Map properties = new HashMap<>(); diff --git a/common/queue/src/main/proto/queue.proto b/common/queue/src/main/proto/queue.proto index 049b6934e7..1225e6d824 100644 --- a/common/queue/src/main/proto/queue.proto +++ b/common/queue/src/main/proto/queue.proto @@ -115,6 +115,7 @@ message DeviceInfoProto { int64 deviceProfileIdLSB = 9; int64 customerIdMSB = 10; int64 customerIdLSB = 11; + string powerMode = 12; } /** diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java index 85b0f5e03d..8fff78ae86 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java @@ -44,7 +44,6 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportC import org.thingsboard.server.common.data.device.profile.JsonTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.ProtoTransportPayloadConfiguration; import org.thingsboard.server.common.data.device.profile.TransportPayloadTypeConfiguration; -import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.data.security.DeviceTokenCredentials; import org.thingsboard.server.common.msg.session.FeatureType; import org.thingsboard.server.common.msg.session.SessionMsgType; @@ -515,23 +514,7 @@ public class CoapTransportResource extends AbstractCoapTransportResource { exchange.respond(CoAP.ResponseCode.INTERNAL_SERVER_ERROR); successful = false; } - if (msg.getPersisted()) { - RpcStatus status; - if (!successful) { - status = RpcStatus.FAILED; - } else if (msg.getOneway()) { - status = RpcStatus.SUCCESSFUL; - } else { - status = RpcStatus.DELIVERED; - } - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() - .setRequestId(msg.getRequestId()) - .setRequestIdLSB(msg.getRequestIdLSB()) - .setRequestIdMSB(msg.getRequestIdMSB()) - .setStatus(status.name()) - .build(); - coapTransportResource.transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY); - } + coapTransportResource.transportService.process(sessionInfo, msg, !successful, TransportServiceCallback.EMPTY); } @Override diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index cfb25e9d78..2871f474bd 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -406,21 +406,7 @@ public class DeviceApiController implements TbTransportService { @Override public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg msg) { responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg, true).toString(), HttpStatus.OK)); - if (msg.getPersisted()) { - RpcStatus status; - if (msg.getOneway()) { - status = RpcStatus.SUCCESSFUL; - } else { - status = RpcStatus.DELIVERED; - } - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() - .setRequestId(msg.getRequestId()) - .setRequestIdLSB(msg.getRequestIdLSB()) - .setRequestIdMSB(msg.getRequestIdMSB()) - .setStatus(status.name()) - .build(); - transportService.process(sessionInfo, responseMsg, TransportServiceCallback.EMPTY); - } + transportService.process(sessionInfo, msg, false, TransportServiceCallback.EMPTY); } @Override diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java index d11f39c7f2..2a2af5f099 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java @@ -33,6 +33,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig; import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer; import java.io.IOException; @@ -84,7 +85,14 @@ public class LwM2mCredentialsSecurityInfoValidator { } catch (InterruptedException e) { log.error("Failed to await credentials!", e); } - return resultSecurityStore[0]; + + TbLwM2MSecurityInfo securityInfo = resultSecurityStore[0]; + + if (securityInfo.getSecurityMode() == null) { + throw new LwM2MAuthException(); + } + + return securityInfo; } /** diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java index cd7f1f3072..5a94a7e3ed 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/TbLwM2MAuthorizer.java @@ -16,6 +16,7 @@ package org.thingsboard.server.transport.lwm2m.secure; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.eclipse.leshan.core.request.Identity; import org.eclipse.leshan.core.request.UplinkRequest; import org.eclipse.leshan.server.registration.Registration; @@ -24,14 +25,15 @@ import org.eclipse.leshan.server.security.SecurityChecker; import org.eclipse.leshan.server.security.SecurityInfo; import org.springframework.stereotype.Component; import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; +import org.thingsboard.server.transport.lwm2m.server.client.LwM2MAuthException; import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; -import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2mSecurityStore; import org.thingsboard.server.transport.lwm2m.server.store.TbSecurityStore; @Component @RequiredArgsConstructor @TbLwM2mTransportComponent +@Slf4j public class TbLwM2MAuthorizer implements Authorizer { private final TbLwM2MDtlsSessionStore sessionStorage; @@ -57,7 +59,12 @@ public class TbLwM2MAuthorizer implements Authorizer { } SecurityInfo expectedSecurityInfo = null; if (securityStore != null) { - expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); + try { + expectedSecurityInfo = securityStore.getByEndpoint(registration.getEndpoint()); + } catch (LwM2MAuthException e) { + log.warn("Registration failed: FORBIDDEN, endpointId: [{}]", registration.getEndpoint()); + return null; + } } if (securityChecker.checkSecurityInfo(registration.getEndpoint(), senderIdentity, expectedSecurityInfo)) { return registration; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java index bcc23dd778..36fff8e3d1 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java @@ -23,7 +23,6 @@ import org.jetbrains.annotations.NotNull; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.ResourceType; -import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; @@ -58,7 +57,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener updateSession(deviceProfile, builder)); this.session = builder.build(); + this.powerMode = ((Lwm2mDeviceTransportConfiguration) device.getDeviceData().getTransportConfiguration()).getPowerMode(); } public void onDeviceProfileUpdate(DeviceProfile deviceProfile) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java index 2517bb2bfb..d0f2047f97 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/uplink/DefaultLwM2MUplinkMsgHandler.java @@ -37,10 +37,10 @@ import org.eclipse.leshan.server.registration.Registration; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import org.thingsboard.common.util.DonAsynchron; -import org.thingsboard.server.cache.ota.OtaPackageDataCache; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.StringUtils; +import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.device.data.lwm2m.ObjectAttributes; import org.thingsboard.server.common.data.device.data.lwm2m.OtherConfiguration; import org.thingsboard.server.common.data.device.data.lwm2m.TelemetryMappingConfiguration; @@ -83,8 +83,6 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttrib import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest; import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService; -import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy; -import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy; import org.thingsboard.server.transport.lwm2m.server.rpc.LwM2MRpcRequestHandler; import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; @@ -203,30 +201,25 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl executor.submit(() -> { LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); try { - log.warn("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); - if (lwM2MClient != null) { - Optional oldSessionInfo = this.clientContext.register(lwM2MClient, registration); - if (oldSessionInfo.isPresent()) { - log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB())); - closeSession(oldSessionInfo.get()); - } - logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId()); - SessionInfoProto sessionInfo = lwM2MClient.getSession(); - transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService)); - log.warn("40) sessionId [{}] Registering rpc subscription after Registration client", new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); - TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() - .setSessionInfo(sessionInfo) - .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) - .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) - .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) - .build(); - transportService.process(msg, null); - this.initClientTelemetry(lwM2MClient); - this.initAttributes(lwM2MClient); - otaService.init(lwM2MClient); - } else { - log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), null); + log.debug("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId()); + Optional oldSessionInfo = this.clientContext.register(lwM2MClient, registration); + if (oldSessionInfo.isPresent()) { + log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB())); + closeSession(oldSessionInfo.get()); } + logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId()); + SessionInfoProto sessionInfo = lwM2MClient.getSession(); + transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, attributesService, rpcHandler, sessionInfo, transportService)); + TransportProtos.TransportToDeviceActorMsg msg = TransportProtos.TransportToDeviceActorMsg.newBuilder() + .setSessionInfo(sessionInfo) + .setSessionEvent(DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN)) + .setSubscribeToAttributes(TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) + .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().setSessionType(TransportProtos.SessionType.ASYNC).build()) + .build(); + transportService.process(msg, null); + this.initClientTelemetry(lwM2MClient); + this.initAttributes(lwM2MClient); + otaService.init(lwM2MClient); } catch (LwM2MClientStateException stateException) { if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) { log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState()); @@ -410,6 +403,27 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); logService.log(clientContext.getClientByEndpoint(registration.getEndpoint()), LOG_LWM2M_INFO + ": Client is awake!"); //TODO: associate endpointId with device information. + + LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint()); + + if (LwM2MClientState.REGISTERED.equals(lwM2MClient.getState())) { + Lwm2mDeviceProfileTransportConfiguration deviceProfile = clientContext.getProfile(lwM2MClient.getProfileId()); + + PowerMode powerMode = lwM2MClient.getPowerMode(); + if (powerMode == null) { + powerMode = deviceProfile.getClientLwM2mSettings().getPowerMode(); + } + + if (powerMode.equals(PowerMode.PSM) || powerMode.equals(PowerMode.E_DRX)) { + initAttributes(lwM2MClient); + TransportProtos.TransportToDeviceActorMsg toDeviceActorMsg = TransportProtos.TransportToDeviceActorMsg + .newBuilder() + .setSessionInfo(lwM2MClient.getSession()) + .setSendPendingRPC(TransportProtos.SendPendingRPCMsg.newBuilder().build()) + .build(); + transportService.process(toDeviceActorMsg, TransportServiceCallback.EMPTY); + } + } } /** @@ -709,7 +723,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl this.updateResourcesValue(client, resource, path + "/" + resId); }); } - } //TODO: review and optimize the logic to minimize number of the requests to device. @@ -920,16 +933,6 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl } } - private TransportProtos.GetOtaPackageRequestMsg createOtaPackageRequestMsg(SessionInfoProto sessionInfo, String nameFwSW) { - return TransportProtos.GetOtaPackageRequestMsg.newBuilder() - .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) - .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) - .setTenantIdMSB(sessionInfo.getTenantIdMSB()) - .setTenantIdLSB(sessionInfo.getTenantIdLSB()) - .setType(nameFwSW) - .build(); - } - private Map getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { Lwm2mDeviceProfileTransportConfiguration profile = clientContext.getProfile(lwM2MClient.getProfileId()); return profile.getObserveAttr().getKeyName(); diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index c2faa3d808..58ccd5f8a0 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -50,7 +50,6 @@ import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.MqttTopics; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.ota.OtaPackageType; -import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.EncryptionUtil; import org.thingsboard.server.common.msg.tools.TbRateLimitsException; import org.thingsboard.server.common.transport.SessionMsgListener; @@ -819,25 +818,10 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement .ifPresent(payload -> { ChannelFuture channelFuture = deviceSessionCtx.getChannel().writeAndFlush(payload); if (rpcRequest.getPersisted()) { - channelFuture.addListener(future -> { - RpcStatus status; - Throwable t = future.cause(); - if (t != null) { - log.error("Failed delivering RPC command to device!", t); - status = RpcStatus.FAILED; - } else if (rpcRequest.getOneway()) { - status = RpcStatus.SUCCESSFUL; - } else { - status = RpcStatus.DELIVERED; - } - TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() - .setRequestId(rpcRequest.getRequestId()) - .setRequestIdLSB(rpcRequest.getRequestIdLSB()) - .setRequestIdMSB(rpcRequest.getRequestIdMSB()) - .setStatus(status.name()) - .build(); - transportService.process(deviceSessionCtx.getSessionInfo(), msg, TransportServiceCallback.EMPTY); - }); + channelFuture.addListener(future -> + transportService.process(deviceSessionCtx.getSessionInfo(), rpcRequest, + future.cause() != null, TransportServiceCallback.EMPTY) + ); } }); } catch (Exception e) { diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java index 9e3633cb4b..55d36e0060 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java @@ -18,7 +18,6 @@ package org.thingsboard.server.transport.mqtt.session; import io.netty.channel.ChannelFuture; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.DeviceProfile; -import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportService; import org.thingsboard.server.common.transport.TransportServiceCallback; @@ -100,25 +99,9 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple payload -> { ChannelFuture channelFuture = parent.writeAndFlush(payload); if (request.getPersisted()) { - channelFuture.addListener(future -> { - RpcStatus status; - Throwable t = future.cause(); - if (t != null) { - log.error("Failed delivering RPC command to device!", t); - status = RpcStatus.FAILED; - } else if (request.getOneway()) { - status = RpcStatus.SUCCESSFUL; - } else { - status = RpcStatus.DELIVERED; - } - TransportProtos.ToDevicePersistedRpcResponseMsg msg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() - .setRequestId(request.getRequestId()) - .setRequestIdLSB(request.getRequestIdLSB()) - .setRequestIdMSB(request.getRequestIdMSB()) - .setStatus(status.name()) - .build(); - transportService.process(getSessionInfo(), msg, TransportServiceCallback.EMPTY); - }); + channelFuture.addListener(future -> + transportService.process(getSessionInfo(), request, future.cause() != null, TransportServiceCallback.EMPTY) + ); } } ); diff --git a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java index da459214c0..65759f2eab 100644 --- a/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java +++ b/common/transport/snmp/src/main/java/org/thingsboard/server/transport/snmp/session/DeviceSessionContext.java @@ -26,7 +26,6 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.device.data.SnmpDeviceTransportConfiguration; import org.thingsboard.server.common.data.device.profile.SnmpDeviceProfileTransportConfiguration; import org.thingsboard.server.common.data.id.DeviceId; -import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportServiceCallback; import org.thingsboard.server.common.transport.session.DeviceAwareSessionContext; @@ -140,22 +139,8 @@ public class DeviceSessionContext extends DeviceAwareSessionContext implements S @Override public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { - snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest); - if (toDeviceRequest.getPersisted()) { - RpcStatus status; - if (toDeviceRequest.getOneway()) { - status = RpcStatus.SUCCESSFUL; - } else { - status = RpcStatus.DELIVERED; - } - TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() - .setRequestId(toDeviceRequest.getRequestId()) - .setRequestIdLSB(toDeviceRequest.getRequestIdLSB()) - .setRequestIdMSB(toDeviceRequest.getRequestIdMSB()) - .setStatus(status.name()) - .build(); - snmpTransportContext.getTransportService().process(getSessionInfo(), responseMsg, TransportServiceCallback.EMPTY); - } + snmpTransportContext.getSnmpTransportService().onToDeviceRpcRequest(this, toDeviceRequest); + snmpTransportContext.getTransportService().process(getSessionInfo(), toDeviceRequest, false, TransportServiceCallback.EMPTY); } @Override diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java index e692d3b002..243787fed7 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java @@ -21,7 +21,6 @@ import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGateway import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; import org.thingsboard.server.common.transport.service.SessionMetaData; import org.thingsboard.server.gen.transport.TransportProtos; -import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceCredentialsRequestMsg; @@ -30,9 +29,9 @@ import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetDeviceResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetEntityProfileResponseMsg; +import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetOtaPackageResponseMsg; -import org.thingsboard.server.gen.transport.TransportProtos.GetOrCreateDeviceFromGatewayRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetResourceResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.GetSnmpDevicesRequestMsg; @@ -50,8 +49,8 @@ import org.thingsboard.server.gen.transport.TransportProtos.SubscribeToRPCMsg; import org.thingsboard.server.gen.transport.TransportProtos.SubscriptionInfoProto; import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcRequestMsg; +import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateBasicMqttCredRequestMsg; -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg; import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg; @@ -110,7 +109,7 @@ public interface TransportService { void process(SessionInfoProto sessionInfo, ToServerRpcRequestMsg msg, TransportServiceCallback callback); - void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback callback); + void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback callback); void process(SessionInfoProto sessionInfo, SubscriptionInfoProto msg, TransportServiceCallback callback); diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/TransportDeviceInfo.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/TransportDeviceInfo.java index 27d42d867f..a436028714 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/TransportDeviceInfo.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/auth/TransportDeviceInfo.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.transport.auth; import lombok.Data; +import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -30,6 +31,7 @@ public class TransportDeviceInfo { private DeviceId deviceId; private String deviceName; private String deviceType; + private PowerMode powerMode; private String additionalInfo; } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index b4e536a49b..0ec2888c3e 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -35,6 +35,7 @@ import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.EntityType; import org.thingsboard.server.common.data.ResourceType; import org.thingsboard.server.common.data.Tenant; +import org.thingsboard.server.common.data.device.data.PowerMode; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -42,6 +43,7 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.RuleChainId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.TenantProfileId; +import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.common.msg.TbMsgMetaData; import org.thingsboard.server.common.msg.queue.ServiceQueue; @@ -439,6 +441,9 @@ public class DefaultTransportService implements TransportService { tdi.setAdditionalInfo(di.getAdditionalInfo()); tdi.setDeviceName(di.getDeviceName()); tdi.setDeviceType(di.getDeviceType()); + if (di.getPowerMode() != null) { + tdi.setPowerMode(PowerMode.valueOf(di.getPowerMode())); + } return tdi; } @@ -558,11 +563,30 @@ public class DefaultTransportService implements TransportService { } @Override - public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDevicePersistedRpcResponseMsg msg, TransportServiceCallback callback) { - if (checkLimits(sessionInfo, msg, callback)) { - reportActivityInternal(sessionInfo); - sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(msg).build(), - new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, callback)); + public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.ToDeviceRpcRequestMsg msg, boolean isFailedRpc, TransportServiceCallback callback) { + if (msg.getPersisted()) { + RpcStatus status; + + if (isFailedRpc) { + status = RpcStatus.FAILED; + } else if (msg.getOneway()) { + status = RpcStatus.SUCCESSFUL; + } else { + status = RpcStatus.DELIVERED; + } + + TransportProtos.ToDevicePersistedRpcResponseMsg responseMsg = TransportProtos.ToDevicePersistedRpcResponseMsg.newBuilder() + .setRequestId(msg.getRequestId()) + .setRequestIdLSB(msg.getRequestIdLSB()) + .setRequestIdMSB(msg.getRequestIdMSB()) + .setStatus(status.name()) + .build(); + + if (checkLimits(sessionInfo, responseMsg, callback)) { + reportActivityInternal(sessionInfo); + sendToDeviceActor(sessionInfo, TransportToDeviceActorMsg.newBuilder().setSessionInfo(sessionInfo).setPersistedRpcResponseMsg(responseMsg).build(), + new ApiStatsProxyCallback<>(getTenantId(sessionInfo), getCustomerId(sessionInfo), 1, TransportServiceCallback.EMPTY)); + } } } diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html index 75878c7078..aa6bfeb019 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.html @@ -151,13 +151,12 @@
- device-profile.lwm2m.power-mode + device-profile.power-saving-mode - - {{ powerModeLwM2MNamesMap.get(powerModeLwM2MType[powerMode]) }} + + {{ powerModeTranslationMap.get(powerMod) | translate}} diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts index 389a214d22..a51ae50928 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-device-profile-transport-configuration.component.ts @@ -32,7 +32,7 @@ import { ModelValue, ObjectLwM2M, OBSERVE, - OBSERVE_ATTR_TELEMETRY, powerMode, powerModeNames, + OBSERVE_ATTR_TELEMETRY, PowerMode, PowerModeTranslationMap, RESOURCES, TELEMETRY } from './lwm2m-profile-config.models'; @@ -72,9 +72,8 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro sortFunction: (key: string, value: object) => object; isFwUpdateStrategy: boolean; isSwUpdateStrategy: boolean; - powerModeLwM2MType = powerMode; - powerModeLwM2MTypes = Object.keys(powerMode); - powerModeLwM2MNamesMap = powerModeNames; + powerMods = Object.values(PowerMode); + powerModeTranslationMap = PowerModeTranslationMap; get required(): boolean { return this.requiredValue; @@ -208,7 +207,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro private updateWriteValue = (value: ModelValue): void => { const fwResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? this.configurationValue.clientLwM2mSettings.fwUpdateResource : ''; - const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.fwUpdateResource) ? + const swResource = isDefinedAndNotNull(this.configurationValue.clientLwM2mSettings.swUpdateResource) ? this.configurationValue.clientLwM2mSettings.swUpdateResource : ''; this.lwm2mDeviceProfileFormGroup.patchValue({ objectIds: value, diff --git a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts index 51b6e3f351..b870622592 100644 --- a/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts +++ b/ui-ngx/src/app/modules/home/components/profile/device/lwm2m/lwm2m-profile-config.models.ts @@ -128,17 +128,17 @@ export const securityConfigModeNames = new Map( ] ); -export enum powerMode { +export enum PowerMode { PSM = 'PSM', DRX = 'DRX', E_DRX = 'E_DRX' } -export const powerModeNames = new Map( +export const PowerModeTranslationMap = new Map( [ - [powerMode.PSM, 'Power Saving Mode (PSM)'], - [powerMode.DRX, 'Discontinuous Reception (DRX)'], - [powerMode.E_DRX, 'Extended Discontinuous Reception (eDRX)'] + [PowerMode.PSM, 'device-profile.power-saving-mode-type.psm'], + [PowerMode.DRX, 'device-profile.power-saving-mode-type.drx'], + [PowerMode.E_DRX, 'device-profile.power-saving-mode-type.edrx'] ] ); @@ -187,7 +187,7 @@ export interface ClientLwM2mSettings { swUpdateStrategy: number; fwUpdateResource: string; swUpdateResource: string; - powerMode: powerMode; + powerMode: PowerMode; } export interface ObservableAttributes { @@ -260,7 +260,7 @@ function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings { swUpdateStrategy: 1, fwUpdateResource: DEFAULT_FW_UPDATE_RESOURCE, swUpdateResource: DEFAULT_SW_UPDATE_RESOURCE, - powerMode: powerMode.DRX + powerMode: PowerMode.DRX }; } diff --git a/ui-ngx/src/app/modules/home/pages/device/data/device-transport-configuration.component.html b/ui-ngx/src/app/modules/home/pages/device/data/device-transport-configuration.component.html index dfe34de697..d6d871e4a5 100644 --- a/ui-ngx/src/app/modules/home/pages/device/data/device-transport-configuration.component.html +++ b/ui-ngx/src/app/modules/home/pages/device/data/device-transport-configuration.component.html @@ -29,12 +29,12 @@ formControlName="configuration"> - +
- + + device-profile.power-saving-mode + + {{ "device-profile.power-saving-mode-type.default" | translate }} + + {{ powerModeTranslationMap.get(powerMod) | translate }} + + +
diff --git a/ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts b/ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts index 72ba719873..f74029c2ff 100644 --- a/ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts +++ b/ui-ngx/src/app/modules/home/pages/device/data/lwm2m-device-transport-configuration.component.ts @@ -23,6 +23,7 @@ import { DeviceTransportConfiguration, DeviceTransportType, Lwm2mDeviceTransportConfiguration } from '@shared/models/device.models'; +import {PowerMode, PowerModeTranslationMap} from "@home/components/profile/device/lwm2m/lwm2m-profile-config.models"; @Component({ selector: 'tb-lwm2m-device-transport-configuration', @@ -37,6 +38,8 @@ import { export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueAccessor, OnInit { lwm2mDeviceTransportConfigurationFormGroup: FormGroup; + powerMods = Object.values(PowerMode); + powerModeTranslationMap = PowerModeTranslationMap; private requiredValue: boolean; get required(): boolean { @@ -65,7 +68,7 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA ngOnInit() { this.lwm2mDeviceTransportConfigurationFormGroup = this.fb.group({ - configuration: [null, Validators.required] + powerMode: [null] }); this.lwm2mDeviceTransportConfigurationFormGroup.valueChanges.subscribe(() => { this.updateModel(); @@ -82,13 +85,13 @@ export class Lwm2mDeviceTransportConfigurationComponent implements ControlValueA } writeValue(value: Lwm2mDeviceTransportConfiguration | null): void { - this.lwm2mDeviceTransportConfigurationFormGroup.patchValue({configuration: value}, {emitEvent: false}); + this.lwm2mDeviceTransportConfigurationFormGroup.patchValue(value, {emitEvent: false}); } private updateModel() { let configuration: DeviceTransportConfiguration = null; if (this.lwm2mDeviceTransportConfigurationFormGroup.valid) { - configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue().configuration; + configuration = this.lwm2mDeviceTransportConfigurationFormGroup.getRawValue(); // configuration.type = DeviceTransportType.LWM2M; } this.propagateChange(configuration); diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts index a766c3a6c3..2c09d64113 100644 --- a/ui-ngx/src/app/shared/models/device.models.ts +++ b/ui-ngx/src/app/shared/models/device.models.ts @@ -200,7 +200,7 @@ export const deviceTransportTypeConfigurationInfoMap = new Map