Browse Source

Refactoring of LwM2MTransport

pull/4542/head
Andrii Shvaika 5 years ago
parent
commit
dd5195e8d7
  1. 66
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerConfiguration.java
  2. 49
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerInitializer.java
  3. 54
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportContextBootstrap.java
  4. 23
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java
  5. 28
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java
  6. 4
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MInMemoryBootstrapConfigStore.java
  7. 1
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2mDefaultBootstrapSessionManager.java
  8. 5
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java
  9. 6
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java
  10. 41
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java
  11. 13
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java
  12. 23
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mRPkCredentials.java
  13. 8
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java
  14. 64
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java
  15. 21
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java
  16. 4
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java
  17. 24
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java
  18. 1
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java
  19. 50
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java
  20. 16
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java
  21. 33
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerInitializer.java
  22. 18
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java
  23. 9
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java
  24. 8
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java
  25. 8
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java
  26. 24
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java
  27. 1
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ModelObject.java
  28. 6
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java
  29. 1
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java

66
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerConfiguration.java

@ -15,15 +15,14 @@
*/
package org.thingsboard.server.transport.lwm2m.bootstrap;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.StringUtils;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore;
@ -31,8 +30,10 @@ import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBoot
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
@ -62,38 +63,45 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.g
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true')")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' && '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true')")
@RequiredArgsConstructor
public class LwM2MTransportBootstrapServerConfiguration {
private PublicKey publicKey;
private PrivateKey privateKey;
private boolean pskMode = false;
@Autowired
private LwM2MTransportServerConfig serverConfig;
private final LwM2MTransportServerConfig serverConfig;
private final LwM2MTransportBootstrapConfig bootstrapConfig;
private final LwM2MBootstrapSecurityStore lwM2MBootstrapSecurityStore;
private final LwM2MInMemoryBootstrapConfigStore lwM2MInMemoryBootstrapConfigStore;
@Autowired
private LwM2MTransportContextBootstrap contextBs;
@Autowired
private LwM2MBootstrapSecurityStore lwM2MBootstrapSecurityStore;
@Autowired
private LwM2MInMemoryBootstrapConfigStore lwM2MInMemoryBootstrapConfigStore;
private LeshanBootstrapServer server;
@PostConstruct
public void init() {
if (serverConfig.getEnableGenNewKeyPskRpk()) {
new LWM2MGenerationPSkRPkECC();
}
log.info("Starting LwM2M transport bootstrap server...");
this.server = getLhBootstrapServer();
this.server.start();
log.info("Started LwM2M transport bootstrap server.");
}
@Bean
public LeshanBootstrapServer getLeshanBootstrapServer() {
log.info("Prepare and start BootstrapServer... PostConstruct");
return this.getLhBootstrapServer(this.contextBs.getCtxBootStrap().getPort(), this.contextBs.getCtxBootStrap().getSecurePort());
@PreDestroy
public void shutdown() {
log.info("Stopping LwM2M transport bootstrap server!");
server.destroy();
log.info("LwM2M transport bootstrap server stopped!");
}
public LeshanBootstrapServer getLhBootstrapServer(Integer bootstrapPortNoSec, Integer bootstrapSecurePort) {
public LeshanBootstrapServer getLhBootstrapServer() {
LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder();
builder.setLocalAddress(this.contextBs.getCtxBootStrap().getHost(), bootstrapPortNoSec);
builder.setLocalSecureAddress(this.contextBs.getCtxBootStrap().getSecureHost(), bootstrapSecurePort);
builder.setLocalAddress(bootstrapConfig.getHost(), bootstrapConfig.getPort());
builder.setLocalSecureAddress(bootstrapConfig.getSecureHost(), bootstrapConfig.getSecurePort());
/** Create CoAP Config */
builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort));
builder.setCoapConfig(getCoapConfig(bootstrapConfig.getPort(), bootstrapConfig.getSecurePort()));
/** Define model provider (Create Models )*/
@ -169,8 +177,8 @@ public class LwM2MTransportBootstrapServerConfiguration {
* For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
*/
try {
X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getCertificateAlias());
PrivateKey privateKey = (PrivateKey) serverConfig.getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getCertificateAlias(), serverConfig.getKeyStorePassword() == null ? null : serverConfig.getKeyStorePassword().toCharArray());
X509Certificate serverCertificate = (X509Certificate) serverConfig.getKeyStoreValue().getCertificate(this.bootstrapConfig.getCertificateAlias());
PrivateKey privateKey = (PrivateKey) serverConfig.getKeyStoreValue().getKey(this.bootstrapConfig.getCertificateAlias(), serverConfig.getKeyStorePassword() == null ? null : serverConfig.getKeyStorePassword().toCharArray());
PublicKey publicKey = serverCertificate.getPublicKey();
if (privateKey != null && privateKey.getEncoded().length > 0 && publicKey != null && publicKey.getEncoded().length > 0) {
builder.setPublicKey(serverCertificate.getPublicKey());
@ -201,10 +209,10 @@ public class LwM2MTransportBootstrapServerConfiguration {
private void infoPramsUri(String mode) {
log.info("Bootstrap Server uses [{}]: serverNoSecureURI : [{}:{}], serverSecureURI : [{}:{}]",
mode,
this.contextBs.getCtxBootStrap().getHost(),
this.contextBs.getCtxBootStrap().getPort(),
this.contextBs.getCtxBootStrap().getSecureHost(),
this.contextBs.getCtxBootStrap().getSecurePort());
this.bootstrapConfig.getHost(),
this.bootstrapConfig.getPort(),
this.bootstrapConfig.getSecureHost(),
this.bootstrapConfig.getSecurePort());
}
@ -238,7 +246,7 @@ public class LwM2MTransportBootstrapServerConfiguration {
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
LwM2MTransportBootstrapConfig serverConfig = this.contextBs.getCtxBootStrap();
LwM2MTransportBootstrapConfig serverConfig = this.bootstrapConfig;
if (StringUtils.isNotEmpty(serverConfig.getPublicX()) && StringUtils.isNotEmpty(serverConfig.getPublicY())) {
/** Get point values */
byte[] publicX = Hex.decodeHex(serverConfig.getPublicX().toCharArray());

49
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerInitializer.java

@ -1,49 +0,0 @@
/**
* 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.bootstrap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Slf4j
@Service
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true')")
public class LwM2MTransportBootstrapServerInitializer {
@Autowired(required = false)
private LeshanBootstrapServer lhBServer;
@Autowired
private LwM2MTransportContextBootstrap contextBS;
@PostConstruct
public void init() {
this.lhBServer.start();
}
@PreDestroy
public void shutdown() throws InterruptedException {
log.info("Stopping LwM2M transport Bootstrap Server!");
lhBServer.destroy();
log.info("LwM2M transport Bootstrap Server stopped!");
}
}

54
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportContextBootstrap.java

@ -1,54 +0,0 @@
/**
* 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.bootstrap;
/**
* Copyright © 2016-2020 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.
*/
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportBootstrapConfig;
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith'")
public class LwM2MTransportContextBootstrap extends TransportContext {
private final LwM2MTransportBootstrapConfig lwM2MTransportBootstrapConfig;
public LwM2MTransportContextBootstrap(LwM2MTransportBootstrapConfig ctxBootStrap) {
this.lwM2MTransportBootstrapConfig = ctxBootStrap;
}
public LwM2MTransportBootstrapConfig getCtxBootStrap() {
return this.lwM2MTransportBootstrapConfig;
}
}

23
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java

@ -25,12 +25,12 @@ import java.nio.charset.StandardCharsets;
@Data
public class LwM2MBootstrapConfig {
/**
* interface BootstrapSecurityConfig
* servers: BootstrapServersSecurityConfig,
* bootstrapServer: ServerSecurityConfig,
* lwm2mServer: ServerSecurityConfig
* }
/*
interface BootstrapSecurityConfig
servers: BootstrapServersSecurityConfig,
bootstrapServer: ServerSecurityConfig,
lwm2mServer: ServerSecurityConfig
}
*/
/** -servers
* shortId: number,
@ -60,10 +60,10 @@ public class LwM2MBootstrapConfig {
public BootstrapConfig getLwM2MBootstrapConfig() {
BootstrapConfig configBs = new BootstrapConfig();
/** Delete old security objects */
/* Delete old security objects */
configBs.toDelete.add("/0");
configBs.toDelete.add("/1");
/** Server Configuration (object 1) as defined in LWM2M 1.0.x TS. */
/* Server Configuration (object 1) as defined in LWM2M 1.0.x TS. */
BootstrapConfig.ServerConfig server0 = new BootstrapConfig.ServerConfig();
server0.shortId = servers.getShortId();
server0.lifetime = servers.getLifetime();
@ -71,10 +71,10 @@ public class LwM2MBootstrapConfig {
server0.notifIfDisabled = servers.isNotifIfDisabled();
server0.binding = BindingMode.valueOf(servers.getBinding());
configBs.servers.put(0, server0);
/** Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */
/* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */
this.bootstrapServer.setBootstrapServerIs(true);
configBs.security.put(0, setServerSecuruty(this.bootstrapServer.getHost(), this.bootstrapServer.getPort(), this.bootstrapServer.isBootstrapServerIs(), this.bootstrapServer.getSecurityMode(), this.bootstrapServer.getClientPublicKeyOrId(), this.bootstrapServer.getServerPublicKey(), this.bootstrapServer.getClientSecretKey(), this.bootstrapServer.getServerId()));
/** Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */
/* Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */
configBs.security.put(1, setServerSecuruty(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.isBootstrapServerIs(), this.lwm2mServer.getSecurityMode(), this.lwm2mServer.getClientPublicKeyOrId(), this.lwm2mServer.getServerPublicKey(), this.lwm2mServer.getClientSecretKey(), this.lwm2mServer.getServerId()));
return configBs;
}
@ -92,9 +92,8 @@ public class LwM2MBootstrapConfig {
}
private byte[] setPublicKeyOrId(String publicKeyOrIdStr, String securityMode) {
byte[] publicKey = (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
return (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
SecurityMode.valueOf(securityMode).equals(SecurityMode.PSK) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
Hex.decodeHex(publicKeyOrIdStr.toCharArray());
return publicKey;
}
}

28
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java

@ -36,7 +36,7 @@ import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
@ -44,12 +44,12 @@ import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.BOOTSTRAP_SERVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LWM2M_SERVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.SERVERS;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.getBootstrapParametersFromThingsboard;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.BOOTSTRAP_SERVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_SERVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SERVERS;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getBootstrapParametersFromThingsboard;
@Slf4j
@Service("LwM2MBootstrapSecurityStore")
@ -72,9 +72,9 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
@Override
public List<SecurityInfo> getAllByEndpoint(String endPoint) {
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportHandlerUtil.LwM2mTypeServer.BOOTSTRAP);
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
/** add value to store from BootstrapJson */
/* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfigNew = store.getBootstrapConfig();
if (bsConfigNew != null) {
@ -96,9 +96,9 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
@Override
public SecurityInfo getByIdentity(String identity) {
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandlerUtil.LwM2mTypeServer.BOOTSTRAP);
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
/** add value to store from BootstrapJson */
/* add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfig = store.getBootstrapConfig();
if (bsConfig.security != null) {
@ -114,12 +114,12 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
}
private void setBootstrapConfigScurityInfo(ReadResultSecurityStore store) {
/** BootstrapConfig */
/* BootstrapConfig */
LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
if (lwM2MBootstrapConfig != null) {
/** Security info */
/* Security info */
switch (SecurityMode.valueOf(lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode())) {
/** Use RPK only */
/* Use RPK only */
case PSK:
store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndPoint(),
lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),

4
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MInMemoryBootstrapConfigStore.java

@ -21,6 +21,7 @@ import org.eclipse.leshan.server.bootstrap.InMemoryBootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
@ -58,8 +59,7 @@ public class LwM2MInMemoryBootstrapConfigStore extends InMemoryBootstrapConfigSt
public BootstrapConfig remove(String enpoint) {
writeLock.lock();
try {
BootstrapConfig res = super.remove(enpoint);
return res;
return super.remove(enpoint);
} finally {
writeLock.unlock();
}

1
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2mDefaultBootstrapSessionManager.java

@ -24,7 +24,6 @@ import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker;
import org.eclipse.leshan.server.security.SecurityInfo;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

5
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportBootstrapConfig.java

@ -16,15 +16,10 @@
package org.thingsboard.server.transport.lwm2m.config;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.gen.transport.TransportProtos;
import java.security.PublicKey;
import java.util.Map;
@Slf4j
@Component

6
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/config/LwM2MTransportServerConfig.java

@ -27,15 +27,9 @@ import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
@Slf4j
@Component

41
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java

@ -17,14 +17,15 @@ package org.thingsboard.server.transport.lwm2m.secure;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import java.security.SecureRandom;
import java.security.KeyPairGenerator;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.InvalidAlgorithmParameterException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.util.Arrays;
@ -48,33 +49,31 @@ public class LWM2MGenerationPSkRPkECC {
}
private void generationPSkKey() {
/** PSK */
/* PSK */
int lenPSkKey = 32;
/** Start PSK
* Clients and Servers MUST support PSK keys of up to 64 bytes in length, as required by [RFC7925]
* SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in [RFC4086]
* */
/* Start PSK
Clients and Servers MUST support PSK keys of up to 64 bytes in length, as required by [RFC7925]
SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in [RFC4086]
*/
SecureRandom randomPSK = new SecureRandom();
byte bytesPSK[] = new byte[lenPSkKey];
byte[] bytesPSK = new byte[lenPSkKey];
randomPSK.nextBytes(bytesPSK);
log.info("\nCreating new PSK: \n for the next start PSK -> security key: [{}]", Hex.encodeHexString(bytesPSK));
}
private void generationRPKECCKey() {
/** RPK */
/* RPK */
String algorithm = "EC";
String provider = "SunEC";
String nameParameterSpec = "secp256r1";
/** Start RPK
* Elliptic Curve parameters : [secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)]
* */
/* Start RPK
Elliptic Curve parameters : [secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)]
*/
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance(algorithm, provider);
} catch (NoSuchAlgorithmException e) {
log.error("", e);
} catch (NoSuchProviderException e) {
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
log.error("", e);
}
ECGenParameterSpec ecsp = new ECGenParameterSpec(nameParameterSpec);
@ -90,17 +89,17 @@ public class LWM2MGenerationPSkRPkECC {
if (pubKey instanceof ECPublicKey) {
ECPublicKey ecPublicKey = (ECPublicKey) pubKey;
/** Get x coordinate */
/* Get x coordinate */
byte[] x = ecPublicKey.getW().getAffineX().toByteArray();
if (x[0] == 0)
x = Arrays.copyOfRange(x, 1, x.length);
/** Get Y coordinate */
/* Get Y coordinate */
byte[] y = ecPublicKey.getW().getAffineY().toByteArray();
if (y[0] == 0)
y = Arrays.copyOfRange(y, 1, y.length);
/** Get Curves params */
/* Get Curves params */
String privHex = Hex.encodeHexString(privKey.getEncoded());
log.info("\nCreating new RPK for the next start... \n" +
" Public Key (Hex): [{}]\n" +

13
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mCredentialsSecurityInfoValidator.java

@ -29,8 +29,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
import java.io.IOException;
import java.security.GeneralSecurityException;
@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
* @param keyValue -
* @return ValidateDeviceCredentialsResponseMsg and SecurityInfo
*/
public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportHandlerUtil.LwM2mTypeServer keyValue) {
public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
CountDownLatch latch = new CountDownLatch(1);
final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1];
context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(),
@ -69,7 +68,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
String credentialsBody = msg.getCredentialsBody();
resultSecurityStore[0] = createSecurityInfo(endpoint, credentialsBody, keyValue);
resultSecurityStore[0].setMsg(msg);
Optional<DeviceProfile> deviceProfileOpt = LwM2mTransportHandlerUtil.decode(msg.getProfileBody().toByteArray());
Optional<DeviceProfile> deviceProfileOpt = LwM2mTransportUtil.decode(msg.getProfileBody().toByteArray());
deviceProfileOpt.ifPresent(profile -> resultSecurityStore[0].setDeviceProfile(profile));
latch.countDown();
}
@ -96,9 +95,9 @@ public class LwM2mCredentialsSecurityInfoValidator {
* @param keyValue -
* @return SecurityInfo
*/
private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportHandlerUtil.LwM2mTypeServer keyValue) {
private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
ReadResultSecurityStore result = new ReadResultSecurityStore();
JsonObject objectMsg = LwM2mTransportHandlerUtil.validateJson(jsonStr);
JsonObject objectMsg = LwM2mTransportUtil.validateJson(jsonStr);
if (objectMsg != null && !objectMsg.isJsonNull()) {
JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
/**
@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
&& objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk;
if (object != null && !object.isJsonNull()) {
if (keyValue.equals(LwM2mTransportHandlerUtil.LwM2mTypeServer.BOOTSTRAP)) {
if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
result.setBootstrapJsonCredential(object);
result.setEndPoint(endPoint);
result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code);

23
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mRPkCredentials.java

@ -18,20 +18,21 @@ package org.thingsboard.server.transport.lwm2m.secure;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPoint;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.KeySpec;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPoint;
import java.util.List;
@Slf4j
@ -54,7 +55,7 @@ public class LwM2mRPkCredentials {
private void generatePublicKeyRPK(String publX, String publY, String privS) {
try {
/**Get Elliptic Curve Parameter spec for secp256r1 */
/*Get Elliptic Curve Parameter spec for secp256r1 */
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
@ -62,18 +63,18 @@ public class LwM2mRPkCredentials {
// Get point values
byte[] publicX = Hex.decodeHex(publX.toCharArray());
byte[] publicY = Hex.decodeHex(publY.toCharArray());
/** Create key specs */
/* Create key specs */
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
parameterSpec);
/** Get keys */
/* Get keys */
this.serverPublicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
}
if (privS != null && !privS.isEmpty()) {
/** Get point values */
/* Get point values */
byte[] privateS = Hex.decodeHex(privS.toCharArray());
/** Create key specs */
/* Create key specs */
KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec);
/** Get keys */
/* Get keys */
this.serverPrivateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
}
} catch (GeneralSecurityException | IllegalArgumentException e) {

8
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java

@ -31,8 +31,8 @@ public class ReadResultSecurityStore {
private int securityMode = DEFAULT_MODE.code;
/** bootstrap */
DeviceProfile deviceProfile;
JsonObject bootstrapJsonCredential;
String endPoint;
BootstrapConfig bootstrapConfig;
private DeviceProfile deviceProfile;
private JsonObject bootstrapJsonCredential;
private String endPoint;
private BootstrapConfig bootstrapConfig;
}

64
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java

@ -33,7 +33,6 @@ import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.util.NamedThreadFactory;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
@ -55,6 +54,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
@ -85,30 +85,30 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST;
import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.CLIENT_NOT_AUTHORIZED;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.DEVICE_ATTRIBUTES_REQUEST;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.FR_OBJECT_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.FR_PATH_RESOURCE_VER_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LWM2M_STRATEGY_2;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.DISCOVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.OBSERVE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.READ;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_REPLACE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.WRITE_UPDATE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.SERVICE_CHANNEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertJsonArrayToSet;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.getAckCallback;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.validateObjectVerFromKey;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_OBJECT_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_PATH_RESOURCE_VER_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SERVICE_CHANNEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getAckCallback;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validateObjectVerFromKey;
@Slf4j
@Service
@ -125,6 +125,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
private final LwM2MTransportServerConfig config;
private final FirmwareDataCache firmwareDataCache;
private final LwM2mTransportServerHelper helper;
private final LwM2MJsonAdaptor adaptor;
private final LwM2mClientContext lwM2mClientContext;
private final LwM2mTransportRequest lwM2mTransportRequest;
@ -132,7 +133,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
LwM2mClientContext lwM2mClientContext,
@Lazy LwM2mTransportRequest lwM2mTransportRequest,
FirmwareDataCache firmwareDataCache,
LwM2mTransportContext context) {
LwM2mTransportContext context, LwM2MJsonAdaptor adaptor) {
this.transportService = transportService;
this.config = config;
this.helper = helper;
@ -140,6 +141,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
this.lwM2mTransportRequest = lwM2mTransportRequest;
this.firmwareDataCache = firmwareDataCache;
this.context = context;
this.adaptor = adaptor;
}
@PostConstruct
@ -334,7 +336,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey();
String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName);
Object valueNew = this.helper.getValueFromKvProto(tsKvProto.getKv());
Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv());
//TODO: react on change of the firmware name.
if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) {
this.getInfoFirmwareUpdate(lwM2MClient);
@ -361,7 +363,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
} else if (msg.getSharedDeletedCount() > 0) {
msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey();
Object valueNew = this.helper.getValueFromKvProto(tsKvProto.getKv());
Object valueNew = LwM2mTransportServerHelper.getValueFromKvProto(tsKvProto.getKv());
if (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) {
lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew);
}
@ -458,7 +460,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
lwm2mClientRpcRequest.setRequestId(toDeviceRequest.getRequestId());
lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
lwm2mClientRpcRequest.setValidTypeOper(toDeviceRequest.getMethodName());
JsonObject rpcRequest = LwM2mTransportHandlerUtil.validateJson(toDeviceRequest.getParams());
JsonObject rpcRequest = LwM2mTransportUtil.validateJson(toDeviceRequest.getParams());
if (rpcRequest != null) {
if (rpcRequest.has(lwm2mClientRpcRequest.keyNameKey)) {
String targetIdVer = this.getPresentPathIntoProfile(sessionInfo,
@ -639,7 +641,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
Set<String> clientObjects = lwM2mClientContext.getSupportedIdVerInClient(registration);
if (clientObjects != null && clientObjects.size() > 0) {
if (LWM2M_STRATEGY_2 == LwM2mTransportHandlerUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
if (LWM2M_STRATEGY_2 == LwM2mTransportUtil.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
// #2
lwM2MClient.getPendingReadRequests().addAll(clientObjects);
clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(),
@ -1361,7 +1363,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
if (keyNamesMap.values().size() > 0) {
try {
//#1.2
TransportProtos.GetAttributeRequestMsg getAttributeMsg = helper.getAdaptor().convertToGetAttributes(null, keyNamesMap.values());
TransportProtos.GetAttributeRequestMsg getAttributeMsg = adaptor.convertToGetAttributes(null, keyNamesMap.values());
transportService.process(sessionInfo, getAttributeMsg, getAckCallback(lwM2MClient, getAttributeMsg.getRequestId(), DEVICE_ATTRIBUTES_REQUEST));
} catch (AdaptorException e) {
log.warn("Failed to decode get attributes request", e);

21
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java

@ -17,8 +17,6 @@ package org.thingsboard.server.transport.lwm2m.server;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.eclipse.californium.core.network.stack.BlockwiseLayer;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder;
@ -91,40 +89,39 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
if (config.getEnableGenNewKeyPskRpk()) {
new LWM2MGenerationPSkRPkECC();
}
this.server = getLhServer(config.getPort(), config.getSecurePort());
this.server = getLhServer();
this.startLhServer();
this.context.setServer(server);
}
private void startLhServer() {
log.info("Starting LwM2M transport Server...");
log.info("Starting LwM2M transport server...");
this.server.start();
LwM2mServerListener lhServerCertListener = new LwM2mServerListener(handler);
this.server.getRegistrationService().addListener(lhServerCertListener.registrationListener);
this.server.getPresenceService().addListener(lhServerCertListener.presenceListener);
this.server.getObservationService().addListener(lhServerCertListener.observationListener);
log.info("Started LwM2M transport server.");
}
@PreDestroy
public void shutdown() {
log.info("Stopping LwM2M transport Server!");
log.info("Stopping LwM2M transport server!");
server.destroy();
log.info("LwM2M transport Server stopped!");
log.info("LwM2M transport server stopped!");
}
private LeshanServer getLhServer(Integer serverPortNoSec, Integer serverSecurePort) {
private LeshanServer getLhServer() {
LeshanServerBuilder builder = new LeshanServerBuilder();
builder.setLocalAddress(config.getHost(), serverPortNoSec);
builder.setLocalSecureAddress(config.getSecureHost(), serverSecurePort);
builder.setLocalAddress(config.getHost(), config.getPort());
builder.setLocalSecureAddress(config.getSecureHost(), config.getSecurePort());
builder.setDecoder(new DefaultLwM2mNodeDecoder());
/* Use a magic converter to support bad type send by the UI. */
builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance()));
/* Create CoAP Config */
NetworkConfig networkConfig = getCoapConfig(serverPortNoSec, serverSecurePort);
BlockwiseLayer blockwiseLayer = new BlockwiseLayer(networkConfig);
builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort));
builder.setCoapConfig(getCoapConfig(config.getPort(), config.getSecurePort()));
/* Define model provider (Create Models )*/
LwM2mModelProvider modelProvider = new LwM2mVersionedModelProvider(this.lwM2mClientContext, this.helper, this.context);

4
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java

@ -26,8 +26,8 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate;
import java.util.Collection;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
@Slf4j
public class LwM2mServerListener {

24
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mSessionMsgListener.java

@ -35,22 +35,22 @@ import java.util.Optional;
@Slf4j
public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? super Void>>, SessionMsgListener {
private DefaultLwM2MTransportMsgHandler service;
private DefaultLwM2MTransportMsgHandler handler;
private TransportProtos.SessionInfoProto sessionInfo;
public LwM2mSessionMsgListener(DefaultLwM2MTransportMsgHandler service, TransportProtos.SessionInfoProto sessionInfo) {
this.service = service;
public LwM2mSessionMsgListener(DefaultLwM2MTransportMsgHandler handler, TransportProtos.SessionInfoProto sessionInfo) {
this.handler = handler;
this.sessionInfo = sessionInfo;
}
@Override
public void onGetAttributesResponse(GetAttributeResponseMsg getAttributesResponse) {
this.service.onGetAttributesResponse(getAttributesResponse, this.sessionInfo);
this.handler.onGetAttributesResponse(getAttributesResponse, this.sessionInfo);
}
@Override
public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) {
this.service.onAttributeUpdate(attributeUpdateNotification, this.sessionInfo);
this.handler.onAttributeUpdate(attributeUpdateNotification, this.sessionInfo);
}
@Override
@ -60,27 +60,27 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s
@Override
public void onToTransportUpdateCredentials(ToTransportUpdateCredentialsProto updateCredentials) {
this.service.onToTransportUpdateCredentials(updateCredentials);
this.handler.onToTransportUpdateCredentials(updateCredentials);
}
@Override
public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
this.service.onDeviceProfileUpdate(sessionInfo, deviceProfile);
this.handler.onDeviceProfileUpdate(sessionInfo, deviceProfile);
}
@Override
public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
this.service.onDeviceUpdate(sessionInfo, device, deviceProfileOpt);
this.handler.onDeviceUpdate(sessionInfo, device, deviceProfileOpt);
}
@Override
public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) {
this.service.onToDeviceRpcRequest(toDeviceRequest,this.sessionInfo);
this.handler.onToDeviceRpcRequest(toDeviceRequest,this.sessionInfo);
}
@Override
public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) {
this.service.onToServerRpcResponse(toServerResponse);
this.handler.onToServerRpcResponse(toServerResponse);
}
@Override
@ -91,14 +91,14 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s
@Override
public void onResourceUpdate(@NotNull Optional<TransportProtos.ResourceUpdateMsg> resourceUpdateMsgOpt) {
if (ResourceType.LWM2M_MODEL.name().equals(resourceUpdateMsgOpt.get().getResourceType())) {
this.service.onResourceUpdate(resourceUpdateMsgOpt);
this.handler.onResourceUpdate(resourceUpdateMsgOpt);
}
}
@Override
public void onResourceDelete(@NotNull Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt) {
if (ResourceType.LWM2M_MODEL.name().equals(resourceDeleteMsgOpt.get().getResourceType())) {
this.service.onResourceDelete(resourceDeleteMsgOpt);
this.handler.onResourceDelete(resourceDeleteMsgOpt);
}
}
}

1
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportMsgHandler.java

@ -20,7 +20,6 @@ import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.server.registration.Registration;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.TbTransportService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;

50
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java

@ -46,10 +46,8 @@ import org.eclipse.leshan.core.response.WriteAttributesResponse;
import org.eclipse.leshan.core.response.WriteResponse;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.NamedThreadFactory;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
@ -68,18 +66,18 @@ import java.util.stream.Collectors;
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT;
import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST;
import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.DEFAULT_TIMEOUT;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.FR_PATH_RESOURCE_VER_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.RESPONSE_CHANNEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.createWriteAttributeRequest;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEFAULT_TIMEOUT;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FR_PATH_RESOURCE_VER_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_CHANNEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.createWriteAttributeRequest;
@Slf4j
@Service
@ -92,7 +90,6 @@ public class LwM2mTransportRequest {
private final LwM2mTransportContext context;
private final LwM2MTransportServerConfig config;
private final LwM2mTransportServerHelper lwM2MTransportServerHelper;
private final LwM2mClientContext lwM2mClientContext;
private final DefaultLwM2MTransportMsgHandler serviceImpl;
@ -120,8 +117,7 @@ public class LwM2mTransportRequest {
ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT;
LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(registration, null);
LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null;
if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 &&
lwM2MClient != null) {
if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) {
if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
ResourceModel resourceModel = null;
@ -142,10 +138,10 @@ public class LwM2mTransportRequest {
}
break;
case OBSERVE_CANCEL:
/**
* lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
* At server side this will not remove the observation from the observation store, to do it you need to use
* {@code ObservationService#cancelObservation()}
/*
lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
At server side this will not remove the observation from the observation store, to do it you need to use
{@code ObservationService#cancelObservation()}
*/
context.getServer().getObservationService().cancelObservations(registration, target);
break;
@ -266,9 +262,9 @@ public class LwM2mTransportRequest {
if (rpcRequest != null) {
serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
}
/** Not Found
* set setClient_fw_version = empty
**/
/* Not Found
set setClient_fw_version = empty
*/
if (FR_PATH_RESOURCE_VER_ID.equals(request.getPath().toString()) && lwM2MClient.isUpdateFw()) {
lwM2MClient.setUpdateFw(false);
lwM2MClient.getFrUpdate().setClientFwVersion("");
@ -277,9 +273,9 @@ public class LwM2mTransportRequest {
}
}
}, e -> {
/** version == null
* set setClient_fw_version = empty
**/
/* version == null
set setClient_fw_version = empty
*/
if (FR_PATH_RESOURCE_VER_ID.equals(request.getPath().toString()) && lwM2MClient.isUpdateFw()) {
lwM2MClient.setUpdateFw(false);
lwM2MClient.getFrUpdate().setClientFwVersion("");

16
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java

@ -30,7 +30,6 @@ package org.thingsboard.server.transport.lwm2m.server;
* limitations under the License.
*/
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.DDFFileParser;
@ -40,7 +39,6 @@ import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.codec.CodecException;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
@ -55,7 +53,7 @@ import java.util.ArrayList;
import java.util.List;
import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LOG_LW2M_TELEMETRY;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY;
@Slf4j
@Component
@ -64,10 +62,6 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle
public class LwM2mTransportServerHelper {
private final LwM2mTransportContext context;
private final TransportService transportService;
@Getter
private final LwM2MJsonAdaptor adaptor;
/**
@ -95,7 +89,7 @@ public class LwM2mTransportServerHelper {
request.addAllKv(result);
PostAttributeMsg postAttributeMsg = request.build();
TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postAttributeMsg);
transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call));
context.getTransportService().process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call));
}
public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) {
@ -106,7 +100,7 @@ public class LwM2mTransportServerHelper {
request.addTsKvList(builder.build());
PostTelemetryMsg postTelemetryMsg = request.build();
TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postTelemetryMsg);
transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call));
context.getTransportService().process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call));
}
/**
@ -191,7 +185,7 @@ public class LwM2mTransportServerHelper {
* @param resourcePath -
* @return
*/
public ResourceModel.Type getResourceModelTypeEqualsKvProtoValueType(ResourceModel.Type currentType, String resourcePath) {
public static ResourceModel.Type getResourceModelTypeEqualsKvProtoValueType(ResourceModel.Type currentType, String resourcePath) {
switch (currentType) {
case BOOLEAN:
return ResourceModel.Type.BOOLEAN;
@ -209,7 +203,7 @@ public class LwM2mTransportServerHelper {
throw new CodecException("Invalid ResourceModel_Type for resource %s, got %s", resourcePath, currentType);
}
public Object getValueFromKvProto(TransportProtos.KeyValueProto kv) {
public static Object getValueFromKvProto(TransportProtos.KeyValueProto kv) {
switch (kv.getType()) {
case BOOLEAN_V:
return kv.getBoolV();

33
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerInitializer.java

@ -1,33 +0,0 @@
/**
* Copyright © 2016-2021 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Slf4j
@Component("LwM2MTransportServerInitializer")
@TbLwM2mTransportComponent
public class LwM2mTransportServerInitializer {
}

18
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportHandlerUtil.java → common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java

@ -67,7 +67,7 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
@Slf4j
public class LwM2mTransportHandlerUtil {
public class LwM2mTransportUtil {
public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0";
public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings";
@ -150,8 +150,8 @@ public class LwM2mTransportHandlerUtil {
* if all resources are to be replaced
*/
WRITE_REPLACE(6, "WriteReplace"),
/**
* PUT
/*
PUT
*/
/**
* Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section
@ -178,7 +178,7 @@ public class LwM2mTransportHandlerUtil {
return to;
}
}
throw new IllegalArgumentException(String.format("Unsupported typeOper type : %d", type));
throw new IllegalArgumentException(String.format("Unsupported typeOper type : %s", type));
}
}
@ -198,7 +198,7 @@ public class LwM2mTransportHandlerUtil {
case OBJLNK:
return valueOld.equals(valueNew);
case OPAQUE:
return Hex.decodeHex(((String) valueOld).toCharArray()).equals(Hex.decodeHex(((String) valueNew).toCharArray()));
return Arrays.equals(Hex.decodeHex(((String) valueOld).toCharArray()), Hex.decodeHex(((String) valueNew).toCharArray()));
default:
throw new CodecException("Invalid value type for resource %s, type %s", resourcePath, type);
}
@ -256,7 +256,7 @@ public class LwM2mTransportHandlerUtil {
ObjectMapper mapper = new ObjectMapper();
String profileStr = mapper.writeValueAsString(profile);
JsonObject profileJson = (profileStr != null) ? validateJson(profileStr) : null;
return getValidateCredentialsBodyFromThingsboard(profileJson) ? LwM2mTransportHandlerUtil.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null;
return getValidateCredentialsBodyFromThingsboard(profileJson) ? LwM2mTransportUtil.getNewProfileParameters(profileJson, deviceProfile.getTenantId()) : null;
} catch (IOException e) {
log.error("", e);
}
@ -415,7 +415,7 @@ public class LwM2mTransportHandlerUtil {
}
public static String validPathIdVer(String pathIdVer, Registration registration) throws IllegalArgumentException {
if (pathIdVer.indexOf(LWM2M_SEPARATOR_PATH) < 0) {
if (!pathIdVer.contains(LWM2M_SEPARATOR_PATH)) {
throw new IllegalArgumentException(String.format("Error:"));
} else {
String[] keyArray = pathIdVer.split(LWM2M_SEPARATOR_PATH);
@ -488,7 +488,7 @@ public class LwM2mTransportHandlerUtil {
}
private static Attribute[] createWriteAttributes(Object params) {
List attributeLists = new ArrayList<Attribute>();
List<Attribute> attributeLists = new ArrayList<>();
ObjectMapper oMapper = new ObjectMapper();
Map<String, Object> map = oMapper.convertValue(params, ConcurrentHashMap.class);
map.forEach((k, v) -> {
@ -498,7 +498,7 @@ public class LwM2mTransportHandlerUtil {
((Double) v).longValue() : v));
}
});
return (Attribute[]) attributeLists.toArray(Attribute[]::new);
return attributeLists.toArray(Attribute[]::new);
}

9
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mVersionedModelProvider.java

@ -30,7 +30,6 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Optional;
@ -51,7 +50,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
private final LwM2mTransportServerHelper helper;
private final LwM2mTransportContext context;
private String getKeyIdVer(Integer objectId, String version) {
private String getKeyIdVer(Integer objectId, String version) {
return objectId != null ? objectId + LWM2M_SEPARATOR_KEY + ((version == null || version.isEmpty()) ? ObjectModel.DEFAULT_VERSION : version) : null;
}
@ -84,7 +83,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
return objectModel.resources.get(resourceId);
else
log.warn("TbResources (Object model) with id [{}/0/{}] not found on the server", objectId, resourceId);
return null;
return null;
} catch (Exception e) {
log.error("", e);
return null;
@ -104,9 +103,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
public Collection<ObjectModel> getObjectModels() {
Map<Integer, String> supportedObjects = this.registration.getSupportedObject();
Collection<ObjectModel> result = new ArrayList<>(supportedObjects.size());
Iterator<Map.Entry<Integer, String>> i$ = supportedObjects.entrySet().iterator();
while (i$.hasNext()) {
Map.Entry<Integer, String> supportedObject = i$.next();
for (Map.Entry<Integer, String> supportedObject : supportedObjects.entrySet()) {
ObjectModel objectModel = this.getObjectModelDynamic(supportedObject.getKey(), supportedObject.getValue());
if (objectModel != null) {
result.add(objectModel);

8
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java

@ -26,8 +26,8 @@ import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler;
import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import java.util.Collection;
@ -42,9 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.TRANSPORT_DEFAULT_LWM2M_VERSION;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.getVerFromPathIdVerOrId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.TRANSPORT_DEFAULT_LWM2M_VERSION;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getVerFromPathIdVerOrId;
@Slf4j
@Data

8
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java

@ -25,7 +25,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
import java.util.Arrays;
import java.util.Map;
@ -34,7 +34,7 @@ import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.convertPathFromObjectIdToIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
@Service
@TbLwM2mTransportComponent
@ -118,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
*/
@Override
public LwM2mClient addLwM2mClientToSession(String identity) {
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandlerUtil.LwM2mTypeServer.CLIENT);
ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
LwM2mClient client;
@ -165,7 +165,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
@Override
public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {
LwM2mClientProfile lwM2MClientProfile = LwM2mTransportHandlerUtil.getLwM2MClientProfileFromThingsboard(deviceProfile);
LwM2mClientProfile lwM2MClientProfile = LwM2mTransportUtil.getLwM2MClientProfileFromThingsboard(deviceProfile);
if (lwM2MClientProfile != null) {
profiles.put(deviceProfile.getUuidId(), lwM2MClientProfile);
return true;

24
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java

@ -21,11 +21,11 @@ import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.server.registration.Registration;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.LwM2mTypeOper;
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
import java.util.concurrent.ConcurrentHashMap;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandlerUtil.validPathIdVer;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validPathIdVer;
@Data
public class Lwm2mClientRpcRequest {
@ -43,7 +43,7 @@ public class Lwm2mClientRpcRequest {
private LwM2mTypeOper typeOper;
private String targetIdVer;
private String contentFormatName;
private String contentFormatName;
private long timeoutInMs;
private Object value;
private ConcurrentHashMap<String, Object> params;
@ -54,19 +54,19 @@ public class Lwm2mClientRpcRequest {
private String infoMsg;
private String responseCode;
public void setValidTypeOper (String typeOper){
public void setValidTypeOper(String typeOper) {
try {
this.typeOper = LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper);
} catch (Exception e) {
this.errorMsg = this.methodKey + " - " + typeOper + " is not valid.";
}
}
public void setValidContentFormatName (JsonObject rpcRequest){
public void setValidContentFormatName(JsonObject rpcRequest) {
try {
if (ContentFormat.fromName(rpcRequest.get(this.contentFormatNameKey).getAsString()) != null) {
this.contentFormatName = rpcRequest.get(this.contentFormatNameKey).getAsString();
}
else {
} else {
this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid.";
}
} catch (Exception e) {
@ -74,14 +74,14 @@ public class Lwm2mClientRpcRequest {
}
}
public void setValidTargetIdVerKey (JsonObject rpcRequest, Registration registration){
public void setValidTargetIdVerKey(JsonObject rpcRequest, Registration registration) {
if (rpcRequest.has(this.targetIdVerKey)) {
String targetIdVerStr = rpcRequest.get(targetIdVerKey).getAsString();
// targetIdVer without ver - ok
try {
// targetIdVer with/without ver - ok
this.targetIdVer = validPathIdVer(targetIdVerStr, registration);
if (this.targetIdVer != null){
if (this.targetIdVer != null) {
this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer);
}
} catch (Exception e) {
@ -97,11 +97,9 @@ public class Lwm2mClientRpcRequest {
payloadResp.addProperty(this.resultKey, this.responseCode);
if (this.errorMsg != null) {
payloadResp.addProperty(this.errorKey, this.errorMsg);
}
else if (this.valueMsg != null) {
} else if (this.valueMsg != null) {
payloadResp.addProperty(this.valueKey, this.valueMsg);
}
else if (this.infoMsg != null) {
} else if (this.infoMsg != null) {
payloadResp.addProperty(this.infoKey, this.infoMsg);
}
return TransportProtos.ToDeviceRpcResponseMsg.newBuilder()

1
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ModelObject.java

@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
import java.util.Map;
@Data

6
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisRegistrationStore.java

@ -18,12 +18,12 @@ package org.thingsboard.server.transport.lwm2m.server.store;
import org.eclipse.californium.core.coap.Token;
import org.eclipse.californium.core.observe.ObservationStoreException;
import org.eclipse.californium.elements.EndpointContext;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.util.NamedThreadFactory;
import org.eclipse.leshan.core.util.Validate;
import org.eclipse.leshan.core.Destroyable;
import org.eclipse.leshan.core.Startable;
import org.eclipse.leshan.core.Stoppable;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.util.NamedThreadFactory;
import org.eclipse.leshan.core.util.Validate;
import org.eclipse.leshan.server.californium.observation.ObserveUtil;
import org.eclipse.leshan.server.californium.registration.CaliforniumRegistrationStore;
import org.eclipse.leshan.server.redis.JedisLock;

1
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/store/TbLwM2mRedisSecurityStore.java

@ -21,7 +21,6 @@ import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.eclipse.leshan.server.security.SecurityStoreListener;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

Loading…
Cancel
Save