From 4ec25beeb3a109277260018163832eaa320a27b9 Mon Sep 17 00:00:00 2001 From: Andrii Shvaika Date: Thu, 6 May 2021 17:11:24 +0300 Subject: [PATCH] LwM2M Integration test --- .../server/controller/AbstractWebTest.java | 3 +- .../transport/TransportSqlTestSuite.java | 3 +- .../lwm2m/AbstractLwM2MIntegrationTest.java | 95 ++++ .../lwm2m/NoSecLwM2MIntegrationTest.java | 156 +++++++ .../lwm2m/client/LwM2MTestClient.java | 262 +++++++++++ .../lwm2m/client/SimpleLwM2MDevice.java | 199 +++++++++ application/src/test/resources/logback.xml | 6 +- application/src/test/resources/lwm2m/0.xml | 405 ++++++++++++++++++ application/src/test/resources/lwm2m/1.xml | 360 ++++++++++++++++ application/src/test/resources/lwm2m/2.xml | 123 ++++++ application/src/test/resources/lwm2m/3.xml | 331 ++++++++++++++ .../lwm2m/secure/credentials/HasKey.java | 15 + .../LwM2MClientCredentialsConfig.java | 15 + .../secure/credentials/LwM2MCredentials.java | 15 + .../NoSecClientCredentialsConfig.java | 15 + .../PSKClientCredentialsConfig.java | 15 + .../RPKClientCredentialsConfig.java | 15 + .../X509ClientCredentialsConfig.java | 15 + .../DefaultLwM2MTransportMsgHandler.java | 3 +- 19 files changed, 2045 insertions(+), 6 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/lwm2m/NoSecLwM2MIntegrationTest.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java create mode 100644 application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java create mode 100644 application/src/test/resources/lwm2m/0.xml create mode 100644 application/src/test/resources/lwm2m/1.xml create mode 100644 application/src/test/resources/lwm2m/2.xml create mode 100644 application/src/test/resources/lwm2m/3.xml diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index 2329e8086c..937244fc93 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -22,6 +22,7 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.Header; import io.jsonwebtoken.Jwt; import io.jsonwebtoken.Jwts; +import lombok.Getter; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.lang3.StringUtils; @@ -120,7 +121,7 @@ public abstract class AbstractWebTest { protected String refreshToken; protected String username; - private TenantId tenantId; + protected TenantId tenantId; @SuppressWarnings("rawtypes") private HttpMessageConverter mappingJackson2HttpMessageConverter; diff --git a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java index d16bbc3885..25df3bee00 100644 --- a/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java +++ b/application/src/test/java/org/thingsboard/server/transport/TransportSqlTestSuite.java @@ -32,7 +32,8 @@ import java.util.Arrays; "org.thingsboard.server.transport.*.attributes.updates.sql.*Test", "org.thingsboard.server.transport.*.attributes.request.sql.*Test", "org.thingsboard.server.transport.*.claim.sql.*Test", - "org.thingsboard.server.transport.*.provision.sql.*Test" + "org.thingsboard.server.transport.*.provision.sql.*Test", + "org.thingsboard.server.transport.lwm2m.*Test" }) public class TransportSqlTestSuite { diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java new file mode 100644 index 0000000000..97f7bfbc3c --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/AbstractLwM2MIntegrationTest.java @@ -0,0 +1,95 @@ +/** + * 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; + +import com.fasterxml.jackson.core.type.TypeReference; +import org.apache.commons.io.IOUtils; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.DeviceProfileProvisionType; +import org.thingsboard.server.common.data.DeviceProfileType; +import org.thingsboard.server.common.data.DeviceTransportType; +import org.thingsboard.server.common.data.ResourceType; +import org.thingsboard.server.common.data.TbResource; +import org.thingsboard.server.common.data.device.profile.DefaultDeviceProfileConfiguration; +import org.thingsboard.server.common.data.device.profile.DeviceProfileData; +import org.thingsboard.server.common.data.device.profile.DisabledDeviceProfileProvisionConfiguration; +import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; +import org.thingsboard.server.controller.AbstractWebsocketTest; +import org.thingsboard.server.controller.TbTestWebSocketClient; +import org.thingsboard.server.dao.service.DaoSqlTest; + +import java.util.Base64; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; + +@DaoSqlTest +public class AbstractLwM2MIntegrationTest extends AbstractWebsocketTest { + + protected DeviceProfile deviceProfile; + protected ScheduledExecutorService executor; + protected TbTestWebSocketClient wsClient; + + @Before + public void beforeTest() throws Exception { + executor = Executors.newScheduledThreadPool(10); + loginTenantAdmin(); + + String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml"}; + for (String resourceName : resources) { + TbResource lwModel = new TbResource(); + lwModel.setResourceType(ResourceType.LWM2M_MODEL); + lwModel.setTitle(resourceName); + lwModel.setFileName(resourceName); + lwModel.setTenantId(tenantId); + byte[] bytes = IOUtils.toByteArray(AbstractLwM2MIntegrationTest.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName)); + lwModel.setData(Base64.getEncoder().encodeToString(bytes)); + lwModel = doPostWithTypedResponse("/api/resource", lwModel, new TypeReference<>(){}); + Assert.assertNotNull(lwModel); + } + wsClient = buildAndConnectWebSocketClient(); + } + + protected void createDeviceProfile(String transportConfiguration) throws Exception { + deviceProfile = new DeviceProfile(); + + deviceProfile.setName("LwM2M No Security"); + deviceProfile.setType(DeviceProfileType.DEFAULT); + deviceProfile.setTenantId(tenantId); + deviceProfile.setTransportType(DeviceTransportType.LWM2M); + deviceProfile.setProvisionType(DeviceProfileProvisionType.DISABLED); + deviceProfile.setDescription(deviceProfile.getName()); + + DeviceProfileData deviceProfileData = new DeviceProfileData(); + deviceProfileData.setConfiguration(new DefaultDeviceProfileConfiguration()); + deviceProfileData.setProvisionConfiguration(new DisabledDeviceProfileProvisionConfiguration(null)); + deviceProfileData.setTransportConfiguration(JacksonUtil.fromString(transportConfiguration, Lwm2mDeviceProfileTransportConfiguration.class)); + deviceProfile.setProfileData(deviceProfileData); + + deviceProfile = doPost("/api/deviceProfile", deviceProfile, DeviceProfile.class); + Assert.assertNotNull(deviceProfile); + } + + @After + public void after() { + executor.shutdownNow(); + wsClient.close(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/NoSecLwM2MIntegrationTest.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/NoSecLwM2MIntegrationTest.java new file mode 100644 index 0000000000..809f1f609b --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/NoSecLwM2MIntegrationTest.java @@ -0,0 +1,156 @@ +/** + * 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; + +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; +import org.junit.Test; +import org.thingsboard.common.util.JacksonUtil; +import org.thingsboard.server.common.data.Device; +import org.thingsboard.server.common.data.query.EntityData; +import org.thingsboard.server.common.data.query.EntityDataPageLink; +import org.thingsboard.server.common.data.query.EntityDataQuery; +import org.thingsboard.server.common.data.query.EntityKey; +import org.thingsboard.server.common.data.query.EntityKeyType; +import org.thingsboard.server.common.data.query.SingleEntityFilter; +import org.thingsboard.server.common.data.security.DeviceCredentials; +import org.thingsboard.server.common.data.security.DeviceCredentialsType; +import org.thingsboard.server.service.telemetry.cmd.TelemetryPluginCmdsWrapper; +import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataCmd; +import org.thingsboard.server.service.telemetry.cmd.v2.EntityDataUpdate; +import org.thingsboard.server.service.telemetry.cmd.v2.LatestValueCmd; +import org.thingsboard.server.transport.lwm2m.client.LwM2MTestClient; +import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials; +import org.thingsboard.server.transport.lwm2m.secure.credentials.NoSecClientCredentialsConfig; + +import java.util.Collections; +import java.util.List; + +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +public class NoSecLwM2MIntegrationTest extends AbstractLwM2MIntegrationTest { + + protected final String TRANSPORT_CONFIGURATION = "{\n" + + " \"type\": \"LWM2M\",\n" + + " \"observeAttr\": {\n" + + " \"keyName\": {\n" + + " \"/3_1.0/0/9\": \"batteryLevel\"\n" + + " },\n" + + " \"observe\": [],\n" + + " \"attribute\": [\n" + + " ],\n" + + " \"telemetry\": [\n" + + " \"/3_1.0/0/9\"\n" + + " ],\n" + + " \"attributeLwm2m\": {}\n" + + " },\n" + + " \"bootstrap\": {\n" + + " \"servers\": {\n" + + " \"binding\": \"UQ\",\n" + + " \"shortId\": 123,\n" + + " \"lifetime\": 300,\n" + + " \"notifIfDisabled\": true,\n" + + " \"defaultMinPeriod\": 1\n" + + " },\n" + + " \"lwm2mServer\": {\n" + + " \"host\": \"localhost\",\n" + + " \"port\": 5685,\n" + + " \"serverId\": 123,\n" + + " \"securityMode\": \"NO_SEC\",\n" + + " \"serverPublicKey\": \"\",\n" + + " \"bootstrapServerIs\": false,\n" + + " \"clientHoldOffTime\": 1,\n" + + " \"bootstrapServerAccountTimeout\": 0\n" + + " },\n" + + " \"bootstrapServer\": {\n" + + " \"host\": \"localhost\",\n" + + " \"port\": 5687,\n" + + " \"serverId\": 111,\n" + + " \"securityMode\": \"NO_SEC\",\n" + + " \"serverPublicKey\": \"\",\n" + + " \"bootstrapServerIs\": true,\n" + + " \"clientHoldOffTime\": 1,\n" + + " \"bootstrapServerAccountTimeout\": 0\n" + + " }\n" + + " },\n" + + " \"clientLwM2mSettings\": {\n" + + " \"clientOnlyObserveAfterConnect\": 1\n" + + " }\n" + + "}"; + + @NotNull + private Device createDevice(String deviceAEndpoint) throws Exception { + Device device = new Device(); + device.setName("Device A"); + device.setDeviceProfileId(deviceProfile.getId()); + device.setTenantId(tenantId); + device = doPost("/api/device", device, Device.class); + Assert.assertNotNull(device); + + DeviceCredentials deviceCredentials = + doGet("/api/device/" + device.getId().getId().toString() + "/credentials", DeviceCredentials.class); + Assert.assertEquals(device.getId(), deviceCredentials.getDeviceId()); + deviceCredentials.setCredentialsType(DeviceCredentialsType.LWM2M_CREDENTIALS); + + deviceCredentials.setCredentialsId(deviceAEndpoint); + + LwM2MCredentials noSecCredentials = new LwM2MCredentials(); + noSecCredentials.setClient(new NoSecClientCredentialsConfig()); + deviceCredentials.setCredentialsValue(JacksonUtil.toString(noSecCredentials)); + doPost("/api/device/credentials", deviceCredentials).andExpect(status().isOk()); + return device; + } + + @Test + public void testConnectAndObserveTelemetry() throws Exception { + createDeviceProfile(TRANSPORT_CONFIGURATION); + + String deviceAEndpoint = "deviceAEndpoint"; + + Device device = createDevice(deviceAEndpoint); + + SingleEntityFilter sef = new SingleEntityFilter(); + sef.setSingleEntity(device.getId()); + LatestValueCmd latestCmd = new LatestValueCmd(); + latestCmd.setKeys(Collections.singletonList(new EntityKey(EntityKeyType.TIME_SERIES, "batteryLevel"))); + EntityDataQuery edq = new EntityDataQuery(sef, new EntityDataPageLink(1, 0, null, null), + Collections.emptyList(), Collections.emptyList(), Collections.emptyList()); + + EntityDataCmd cmd = new EntityDataCmd(1, edq, null, latestCmd, null); + TelemetryPluginCmdsWrapper wrapper = new TelemetryPluginCmdsWrapper(); + wrapper.setEntityDataCmds(Collections.singletonList(cmd)); + + wsClient.send(mapper.writeValueAsString(wrapper)); + wsClient.waitForReply(); + + wsClient.registerWaitForUpdate(); + LwM2MTestClient client = new LwM2MTestClient(executor, deviceAEndpoint); + client.init(); + String msg = wsClient.waitForUpdate(); + + EntityDataUpdate update = mapper.readValue(msg, EntityDataUpdate.class); + Assert.assertEquals(1, update.getCmdId()); + List eData = update.getUpdate(); + Assert.assertNotNull(eData); + Assert.assertEquals(1, eData.size()); + Assert.assertEquals(device.getId(), eData.get(0).getEntityId()); + Assert.assertNotNull(eData.get(0).getLatest().get(EntityKeyType.TIME_SERIES)); + var tsValue = eData.get(0).getLatest().get(EntityKeyType.TIME_SERIES).get("batteryLevel"); + Assert.assertEquals(42, Long.parseLong(tsValue.getValue())); + client.destroy(); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java new file mode 100644 index 0000000000..6061813bcf --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/LwM2MTestClient.java @@ -0,0 +1,262 @@ +/** + * 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.client; + +import lombok.Data; +import lombok.extern.slf4j.Slf4j; +import org.eclipse.californium.core.network.config.NetworkConfig; +import org.eclipse.californium.elements.Connector; +import org.eclipse.californium.scandium.DTLSConnector; +import org.eclipse.californium.scandium.config.DtlsConnectorConfig; +import org.eclipse.californium.scandium.dtls.ClientHandshaker; +import org.eclipse.californium.scandium.dtls.DTLSSession; +import org.eclipse.californium.scandium.dtls.HandshakeException; +import org.eclipse.californium.scandium.dtls.Handshaker; +import org.eclipse.californium.scandium.dtls.ResumingClientHandshaker; +import org.eclipse.californium.scandium.dtls.ResumingServerHandshaker; +import org.eclipse.californium.scandium.dtls.ServerHandshaker; +import org.eclipse.californium.scandium.dtls.SessionAdapter; +import org.eclipse.leshan.client.californium.LeshanClient; +import org.eclipse.leshan.client.californium.LeshanClientBuilder; +import org.eclipse.leshan.client.engine.DefaultRegistrationEngineFactory; +import org.eclipse.leshan.client.object.Server; +import org.eclipse.leshan.client.observer.LwM2mClientObserver; +import org.eclipse.leshan.client.resource.ObjectsInitializer; +import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.ResponseCode; +import org.eclipse.leshan.core.californium.DefaultEndpointFactory; +import org.eclipse.leshan.core.model.LwM2mModel; +import org.eclipse.leshan.core.model.ObjectLoader; +import org.eclipse.leshan.core.model.ObjectModel; +import org.eclipse.leshan.core.model.StaticModel; +import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; +import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; +import org.eclipse.leshan.core.request.BindingMode; +import org.eclipse.leshan.core.request.BootstrapRequest; +import org.eclipse.leshan.core.request.DeregisterRequest; +import org.eclipse.leshan.core.request.RegisterRequest; +import org.eclipse.leshan.core.request.UpdateRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ScheduledExecutorService; + +import static org.eclipse.leshan.client.object.Security.noSec; +import static org.eclipse.leshan.core.LwM2mId.DEVICE; +import static org.eclipse.leshan.core.LwM2mId.SECURITY; +import static org.eclipse.leshan.core.LwM2mId.SERVER; + +@Slf4j +@Data +public class LwM2MTestClient { + + private final ScheduledExecutorService executor; + private final String endpoint; + private LeshanClient client; + + public void init() { + String[] resources = new String[]{"0.xml", "1.xml", "2.xml", "3.xml"}; + List models = new ArrayList<>(); + for (String resourceName : resources) { + models.addAll(ObjectLoader.loadDdfFile(LwM2MTestClient.class.getClassLoader().getResourceAsStream("lwm2m/" + resourceName), resourceName)); + } + LwM2mModel model = new StaticModel(models); + ObjectsInitializer initializer = new ObjectsInitializer(model); + initializer.setInstancesForObject(SECURITY, noSec("coap://localhost:5685", 123)); + initializer.setInstancesForObject(SERVER, new Server(123, 300, BindingMode.U, false)); + initializer.setInstancesForObject(DEVICE, new SimpleLwM2MDevice()); + + NetworkConfig coapConfig = new NetworkConfig(); + coapConfig.setString("COAP_PORT", Integer.toString(5685)); + + DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); + dtlsConfig.setRecommendedCipherSuitesOnly(true); + + DefaultRegistrationEngineFactory engineFactory = new DefaultRegistrationEngineFactory(); + engineFactory.setReconnectOnUpdate(false); + engineFactory.setResumeOnConnect(true); + + DefaultEndpointFactory endpointFactory = new DefaultEndpointFactory(endpoint) { + @Override + protected Connector createSecuredConnector(DtlsConnectorConfig dtlsConfig) { + + return new DTLSConnector(dtlsConfig) { + @Override + protected void onInitializeHandshaker(Handshaker handshaker) { + handshaker.addSessionListener(new SessionAdapter() { + + @Override + public void handshakeStarted(Handshaker handshaker) throws HandshakeException { + if (handshaker instanceof ServerHandshaker) { + log.info("DTLS Full Handshake initiated by server : STARTED ..."); + } else if (handshaker instanceof ResumingServerHandshaker) { + log.info("DTLS abbreviated Handshake initiated by server : STARTED ..."); + } else if (handshaker instanceof ClientHandshaker) { + log.info("DTLS Full Handshake initiated by client : STARTED ..."); + } else if (handshaker instanceof ResumingClientHandshaker) { + log.info("DTLS abbreviated Handshake initiated by client : STARTED ..."); + } + } + + @Override + public void sessionEstablished(Handshaker handshaker, DTLSSession establishedSession) + throws HandshakeException { + if (handshaker instanceof ServerHandshaker) { + log.info("DTLS Full Handshake initiated by server : SUCCEED, handshaker {}", handshaker); + } else if (handshaker instanceof ResumingServerHandshaker) { + log.info("DTLS abbreviated Handshake initiated by server : SUCCEED, handshaker {}", handshaker); + } else if (handshaker instanceof ClientHandshaker) { + log.info("DTLS Full Handshake initiated by client : SUCCEED, handshaker {}", handshaker); + } else if (handshaker instanceof ResumingClientHandshaker) { + log.info("DTLS abbreviated Handshake initiated by client : SUCCEED, handshaker {}", handshaker); + } + } + + @Override + public void handshakeFailed(Handshaker handshaker, Throwable error) { + /** get cause */ + String cause; + if (error != null) { + if (error.getMessage() != null) { + cause = error.getMessage(); + } else { + cause = error.getClass().getName(); + } + } else { + cause = "unknown cause"; + } + + if (handshaker instanceof ServerHandshaker) { + log.info("DTLS Full Handshake initiated by server : FAILED [{}]", cause); + } else if (handshaker instanceof ResumingServerHandshaker) { + log.info("DTLS abbreviated Handshake initiated by server : FAILED [{}]", cause); + } else if (handshaker instanceof ClientHandshaker) { + log.info("DTLS Full Handshake initiated by client : FAILED [{}]", cause); + } else if (handshaker instanceof ResumingClientHandshaker) { + log.info("DTLS abbreviated Handshake initiated by client : FAILED [{}]", cause); + } + } + }); + } + }; + } + }; + + LeshanClientBuilder builder = new LeshanClientBuilder(endpoint); + builder.setLocalAddress("0.0.0.0", 11000); + builder.setObjects(initializer.createAll()); + builder.setCoapConfig(coapConfig); + builder.setDtlsConfig(dtlsConfig); + builder.setRegistrationEngineFactory(engineFactory); + builder.setEndpointFactory(endpointFactory); + builder.setSharedExecutor(executor); + builder.setDecoder(new DefaultLwM2mNodeDecoder(true)); + builder.setEncoder(new DefaultLwM2mNodeEncoder(true)); + client = builder.build(); + + LwM2mClientObserver observer = new LwM2mClientObserver() { + @Override + public void onBootstrapStarted(ServerIdentity bsserver, BootstrapRequest request) { + log.info("ClientObserver -> onBootstrapStarted..."); + } + + @Override + public void onBootstrapSuccess(ServerIdentity bsserver, BootstrapRequest request) { + log.info("ClientObserver -> onBootstrapSuccess..."); + } + + @Override + public void onBootstrapFailure(ServerIdentity bsserver, BootstrapRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { + log.info("ClientObserver -> onBootstrapFailure..."); + } + + @Override + public void onBootstrapTimeout(ServerIdentity bsserver, BootstrapRequest request) { + log.info("ClientObserver -> onBootstrapTimeout..."); + } + + @Override + public void onRegistrationStarted(ServerIdentity server, RegisterRequest request) { +// log.info("ClientObserver -> onRegistrationStarted... EndpointName [{}]", request.getEndpointName()); + } + + @Override + public void onRegistrationSuccess(ServerIdentity server, RegisterRequest request, String registrationID) { + log.info("ClientObserver -> onRegistrationSuccess... EndpointName [{}] [{}]", request.getEndpointName(), registrationID); + } + + @Override + public void onRegistrationFailure(ServerIdentity server, RegisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { + log.info("ClientObserver -> onRegistrationFailure... ServerIdentity [{}]", server); + } + + @Override + public void onRegistrationTimeout(ServerIdentity server, RegisterRequest request) { + log.info("ClientObserver -> onRegistrationTimeout... RegisterRequest [{}]", request); + } + + @Override + public void onUpdateStarted(ServerIdentity server, UpdateRequest request) { +// log.info("ClientObserver -> onUpdateStarted... UpdateRequest [{}]", request); + } + + @Override + public void onUpdateSuccess(ServerIdentity server, UpdateRequest request) { +// log.info("ClientObserver -> onUpdateSuccess... UpdateRequest [{}]", request); + } + + @Override + public void onUpdateFailure(ServerIdentity server, UpdateRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { + + } + + @Override + public void onUpdateTimeout(ServerIdentity server, UpdateRequest request) { + + } + + @Override + public void onDeregistrationStarted(ServerIdentity server, DeregisterRequest request) { + log.info("ClientObserver ->onDeregistrationStarted... DeregisterRequest [{}]", request.getRegistrationId()); + + } + + @Override + public void onDeregistrationSuccess(ServerIdentity server, DeregisterRequest request) { + log.info("ClientObserver ->onDeregistrationSuccess... DeregisterRequest [{}]", request.getRegistrationId()); + + } + + @Override + public void onDeregistrationFailure(ServerIdentity server, DeregisterRequest request, ResponseCode responseCode, String errorMessage, Exception cause) { + log.info("ClientObserver ->onDeregistrationFailure... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); + } + + @Override + public void onDeregistrationTimeout(ServerIdentity server, DeregisterRequest request) { + log.info("ClientObserver ->onDeregistrationTimeout... DeregisterRequest [{}] [{}]", request.getRegistrationId(), request.getRegistrationId()); + } + }; + this.client.addObserver(observer); + + client.start(); + } + + public void destroy() { + client.stop(false); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java new file mode 100644 index 0000000000..4512a94a27 --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/transport/lwm2m/client/SimpleLwM2MDevice.java @@ -0,0 +1,199 @@ +/** + * 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.client; + +import lombok.extern.slf4j.Slf4j; +import org.eclipse.leshan.client.resource.BaseInstanceEnabler; +import org.eclipse.leshan.client.servers.ServerIdentity; +import org.eclipse.leshan.core.model.ObjectModel; +import org.eclipse.leshan.core.model.ResourceModel; +import org.eclipse.leshan.core.node.LwM2mResource; +import org.eclipse.leshan.core.response.ExecuteResponse; +import org.eclipse.leshan.core.response.ReadResponse; +import org.eclipse.leshan.core.response.WriteResponse; + +import javax.security.auth.Destroyable; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.TimeZone; + +@Slf4j +public class SimpleLwM2MDevice extends BaseInstanceEnabler implements Destroyable { + + + private static final Random RANDOM = new Random(); + private static final List supportedResources = Arrays.asList(0, 1, 2, 3 +// , 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 20, 21 + ); + + @Override + public ReadResponse read(ServerIdentity identity, int resourceid) { + if (!identity.isSystem()) + log.info("Read on Device resource /{}/{}/{}", getModel().id, getId(), resourceid); + switch (resourceid) { + case 0: + return ReadResponse.success(resourceid, getManufacturer()); + case 1: + return ReadResponse.success(resourceid, getModelNumber()); + case 2: + return ReadResponse.success(resourceid, getSerialNumber()); + case 3: + return ReadResponse.success(resourceid, getFirmwareVersion()); + case 9: + return ReadResponse.success(resourceid, getBatteryLevel()); + case 10: + return ReadResponse.success(resourceid, getMemoryFree()); + case 11: + Map errorCodes = new HashMap<>(); + errorCodes.put(0, getErrorCode()); + return ReadResponse.success(resourceid, errorCodes, ResourceModel.Type.INTEGER); + case 14: + return ReadResponse.success(resourceid, getUtcOffset()); + case 15: + return ReadResponse.success(resourceid, getTimezone()); + case 16: + return ReadResponse.success(resourceid, getSupportedBinding()); + case 17: + return ReadResponse.success(resourceid, getDeviceType()); + case 18: + return ReadResponse.success(resourceid, getHardwareVersion()); + case 19: + return ReadResponse.success(resourceid, getSoftwareVersion()); + case 20: + return ReadResponse.success(resourceid, getBatteryStatus()); + case 21: + return ReadResponse.success(resourceid, getMemoryTotal()); + default: + return super.read(identity, resourceid); + } + } + + @Override + public ExecuteResponse execute(ServerIdentity identity, int resourceid, String params) { + String withParams = null; + if (params != null && params.length() != 0) { + withParams = " with params " + params; + } + log.info("Execute on Device resource /{}/{}/{} {}", getModel().id, getId(), resourceid, withParams != null ? withParams : ""); + return ExecuteResponse.success(); + } + + @Override + public WriteResponse write(ServerIdentity identity, int resourceid, LwM2mResource value) { + log.info("Write on Device resource /{}/{}/{}", getModel().id, getId(), resourceid); + + switch (resourceid) { + case 13: + return WriteResponse.notFound(); + case 14: + setUtcOffset((String) value.getValue()); + fireResourcesChange(resourceid); + return WriteResponse.success(); + case 15: + setTimezone((String) value.getValue()); + fireResourcesChange(resourceid); + return WriteResponse.success(); + default: + return super.write(identity, resourceid, value); + } + } + + private String getManufacturer() { + return "Leshan Demo Device"; + } + + private String getModelNumber() { + return "Model 500"; + } + + private String getSerialNumber() { + return "LT-500-000-0001"; + } + + private String getFirmwareVersion() { + return "1.0.0"; + } + + private long getErrorCode() { + return 0; + } + + private int getBatteryLevel() { + return 42; + } + + private long getMemoryFree() { + return Runtime.getRuntime().freeMemory() / 1024; + } + + private String utcOffset = new SimpleDateFormat("X").format(Calendar.getInstance().getTime()); + + private String getUtcOffset() { + return utcOffset; + } + + private void setUtcOffset(String t) { + utcOffset = t; + } + + private String timeZone = TimeZone.getDefault().getID(); + + private String getTimezone() { + return timeZone; + } + + private void setTimezone(String t) { + timeZone = t; + } + + private String getSupportedBinding() { + return "U"; + } + + private String getDeviceType() { + return "Demo"; + } + + private String getHardwareVersion() { + return "1.0.1"; + } + + private String getSoftwareVersion() { + return "1.0.2"; + } + + private int getBatteryStatus() { + return RANDOM.nextInt(7); + } + + private long getMemoryTotal() { + return Runtime.getRuntime().totalMemory() / 1024; + } + + @Override + public List getAvailableResourceIds(ObjectModel model) { + return supportedResources; + } + + @Override + public void destroy() { + } +} diff --git a/application/src/test/resources/logback.xml b/application/src/test/resources/logback.xml index f991a40078..81d213b42d 100644 --- a/application/src/test/resources/logback.xml +++ b/application/src/test/resources/logback.xml @@ -9,13 +9,15 @@ - + + - + + diff --git a/application/src/test/resources/lwm2m/0.xml b/application/src/test/resources/lwm2m/0.xml new file mode 100644 index 0000000000..81e8523880 --- /dev/null +++ b/application/src/test/resources/lwm2m/0.xml @@ -0,0 +1,405 @@ + + + + + + + LWM2M Security + + 0 + urn:oma:lwm2m:oma:0:1.2 + 1.1 + 1.2 + Multiple + Mandatory + + + LWM2M Server URI + + Single + Mandatory + String + 0..255 + + + + + Bootstrap-Server + + Single + Mandatory + Boolean + + + + + + Security Mode + + Single + Mandatory + Integer + 0..4 + + + + + Public Key or Identity + + Single + Mandatory + Opaque + + + + + + Server Public Key + + Single + Mandatory + Opaque + + + + + + Secret Key + + Single + Mandatory + Opaque + + + + + + SMS Security Mode + + Single + Optional + Integer + 0..255 + + + + + SMS Binding Key Parameters + + Single + Optional + Opaque + 6 + + + + + SMS Binding Secret Key(s) + + Single + Optional + Opaque + 16,32,48 + + + + + LwM2M Server SMS Number + + Single + Optional + String + + + + + + Short Server ID + + Single + Optional + Integer + 1..65534 + + + + + Client Hold Off Time + + Single + Optional + Integer + + s + + + + Bootstrap-Server Account Timeout + + Single + Optional + Integer + + s + + + + Matching Type + + Single + Optional + Integer + 0..3 + + + + + SNI + + Single + Optional + String + + + + + + Certificate Usage + + Single + Optional + Integer + 0..3 + + + + + DTLS/TLS Ciphersuite + + Multiple + Optional + Integer + + + + + OSCORE Security Mode + + Single + Optional + Objlnk + + + + + + Groups To Use by Client + + Multiple + Optional + Integer + 0..65535 + + + + + Signature Algorithms Supported by Server + + Multiple + Optional + Integer + 0..65535 + + + + Signature Algorithms To Use by Client + + Multiple + Optional + Integer + 0..65535 + + + + + Signature Algorithm Certs Supported by Server + + Multiple + Optional + Integer + 0..65535 + + + + + TLS 1.3 Features To Use by Client + + Single + Optional + Integer + 0..65535 + + + + + TLS Extensions Supported by Server + + Single + Optional + Integer + 0..65535 + + + + + TLS Extensions To Use by Client + + Single + Optional + Integer + 0..65535 + + + + + Secondary LwM2M Server URI + + Multiple + Optional + String + 0..255 + + + + MQTT Server + + Single + Optional + Objlnk + + + + + LwM2M COSE Security + + Multiple + Optional + Objlnk + + + + + RDS Destination Port + + Single + Optional + Integer + 0..15 + + + + RDS Source Port + + Single + Optional + Integer + 0..15 + + + + RDS Application ID + + Single + Optional + String + + + + + + + + diff --git a/application/src/test/resources/lwm2m/1.xml b/application/src/test/resources/lwm2m/1.xml new file mode 100644 index 0000000000..f31e839c96 --- /dev/null +++ b/application/src/test/resources/lwm2m/1.xml @@ -0,0 +1,360 @@ + + + + + + + LwM2M Server + + 1 + urn:oma:lwm2m:oma:1:1.2 + 1.2 + 1.2 + Multiple + Mandatory + + + Short Server ID + R + Single + Mandatory + Integer + 1..65534 + + + + + Lifetime + RW + Single + Mandatory + Integer + + s + + + + Default Minimum Period + RW + Single + Optional + Integer + + s + + + + Default Maximum Period + RW + Single + Optional + Integer + + s + + + + Disable + E + Single + Optional + + + + + + + Disable Timeout + RW + Single + Optional + Integer + + s + + + + Notification Storing When Disabled or Offline + RW + Single + Mandatory + Boolean + + + + + + Binding + RW + Single + Mandatory + String + + + + + + Registration Update Trigger + E + Single + Mandatory + + + + + + + Bootstrap-Request Trigger + E + Single + Optional + + + + + + + APN Link + RW + Single + Optional + Objlnk + + + + + + TLS-DTLS Alert Code + R + Single + Optional + Integer + 0..255 + + + + + Last Bootstrapped + R + Single + Optional + Time + + + + + + Registration Priority Order + R + Single + Optional + Integer + + + + + + Initial Registration Delay Timer + RW + Single + Optional + Integer + + s + + + + Registration Failure Block + R + Single + Optional + Boolean + + + + + + Bootstrap on Registration Failure + R + Single + Optional + Boolean + + + + + + Communication Retry Count + RW + Single + Optional + Integer + + + + + + Communication Retry Timer + RW + Single + Optional + Integer + + s + + + + Communication Sequence Delay Timer + RW + Single + Optional + Integer + + s + + + + Communication Sequence Retry Count + RW + Single + Optional + Integer + + + + + + Trigger + RW + Single + Optional + Boolean + + + + + + Preferred Transport + RW + Single + Optional + String + The possible values are those listed in the LwM2M Core Specification + + + + Mute Send + RW + Single + Optional + Boolean + + + + + + Alternate APN Links + RW + Multiple + Optional + Objlnk + + + + + + Supported Server Versions + RW + Multiple + Optional + String + + + + + + Default Notification Mode + RW + Single + Optional + Integer + 0..1 + + + + + Profile ID Hash Algorithm + RW + Single + Optional + Integer + 0..255 + + + + + + + diff --git a/application/src/test/resources/lwm2m/2.xml b/application/src/test/resources/lwm2m/2.xml new file mode 100644 index 0000000000..4ea5805b36 --- /dev/null +++ b/application/src/test/resources/lwm2m/2.xml @@ -0,0 +1,123 @@ + + + + + + + LwM2M Access Control + + 2 + urn:oma:lwm2m:oma:2:1.1 + 1.0 + 1.1 + Multiple + Optional + + + Object ID + R + Single + Mandatory + Integer + 1..65534 + + + + + Object Instance ID + R + Single + Mandatory + Integer + 0..65535 + + + + + ACL + RW + Multiple + Optional + Integer + 0..31 + + + + + Access Control Owner + RW + Single + Mandatory + Integer + 0..65535 + + + + + + + diff --git a/application/src/test/resources/lwm2m/3.xml b/application/src/test/resources/lwm2m/3.xml new file mode 100644 index 0000000000..724fc4cb33 --- /dev/null +++ b/application/src/test/resources/lwm2m/3.xml @@ -0,0 +1,331 @@ + + + + + + + Device + + 3 + urn:oma:lwm2m:oma:3:1.0 + 1.1 + 1.0 + Single + Mandatory + + + Manufacturer + R + Single + Optional + String + + + + + + Model Number + R + Single + Optional + String + + + + + + Serial Number + R + Single + Optional + String + + + + + + Firmware Version + R + Single + Optional + String + + + + + + Reboot + E + Single + Mandatory + + + + + + + Factory Reset + E + Single + Optional + + + + + + + Available Power Sources + R + Multiple + Optional + Integer + 0..7 + + + + + Power Source Voltage + R + Multiple + Optional + Integer + + + + + + Power Source Current + R + Multiple + Optional + Integer + + + + + + Battery Level + R + Single + Optional + Integer + 0..100 + /100 + + + + Memory Free + R + Single + Optional + Integer + + + + + + Error Code + R + Multiple + Mandatory + Integer + 0..32 + + + + + Reset Error Code + E + Single + Optional + + + + + + + Current Time + RW + Single + Optional + Time + + + + + + UTC Offset + RW + Single + Optional + String + + + + + + Timezone + RW + Single + Optional + String + + + + + + Supported Binding and Modes + R + Single + Mandatory + String + + + + + Device Type + R + Single + Optional + String + + + + + Hardware Version + R + Single + Optional + String + + + + + Software Version + R + Single + Optional + String + + + + + Battery Status + R + Single + Optional + Integer + 0..6 + + + + Memory Total + R + Single + Optional + Integer + + + + + ExtDevInfo + R + Multiple + Optional + Objlnk + + + + + + + diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java index 7c75589c4c..65be16bfd6 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/HasKey.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import org.eclipse.leshan.core.util.Hex; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java index 33a297c91a..65f027a849 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MClientCredentialsConfig.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import com.fasterxml.jackson.annotation.JsonIgnore; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java index ebb1fc138b..09c27f0e42 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/LwM2MCredentials.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import lombok.Data; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java index bcac7174aa..03933972c3 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/NoSecClientCredentialsConfig.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import org.eclipse.leshan.core.SecurityMode; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java index d79083647f..8de85ce72d 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/PSKClientCredentialsConfig.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import lombok.Data; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java index 280e8492f8..025c8b3b10 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/RPKClientCredentialsConfig.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import org.eclipse.leshan.core.SecurityMode; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java index 0aff74d189..0a2df6852e 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/credentials/X509ClientCredentialsConfig.java @@ -1,3 +1,18 @@ +/** + * 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.secure.credentials; import lombok.Data; diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java index b9de7bcea2..e93984e87c 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java @@ -646,8 +646,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler */ private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { LwM2mClient lwM2MClient = clientContext.getOrRegister(registration); - if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config - .getModelProvider())) { + if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.config.getModelProvider())) { if (FR_PATH_RESOURCE_VER_ID.equals(convertPathFromIdVerToObjectId(path)) && lwM2MClient.getFrUpdate().getCurrentFwVersion() != null && !lwM2MClient.getFrUpdate().getCurrentFwVersion().equals(lwM2MClient.getFrUpdate().getClientFwVersion())