Commit 3a82c2275d7a3646535f35d103204869c1ca4a66

Authored by Andrii Shvaika
2 parents 1f9b4c09 a34ffe8a

Merge remote-tracking branch 'origin/lwm2m_coap_url_in_out'

Showing 25 changed files with 497 additions and 404 deletions
... ... @@ -18,11 +18,12 @@ package org.thingsboard.server.transport.coap;
18 18 import lombok.extern.slf4j.Slf4j;
19 19 import org.eclipse.californium.core.CoapResource;
20 20 import org.eclipse.californium.core.CoapServer;
  21 +import org.eclipse.californium.core.network.config.NetworkConfig;
21 22 import org.springframework.beans.factory.annotation.Autowired;
22 23 import org.springframework.stereotype.Service;
23   -import org.thingsboard.server.common.data.TbTransportService;
24 24 import org.thingsboard.server.coapserver.CoapServerService;
25 25 import org.thingsboard.server.coapserver.TbCoapServerComponent;
  26 +import org.thingsboard.server.common.data.TbTransportService;
26 27 import org.thingsboard.server.common.data.ota.OtaPackageType;
27 28 import org.thingsboard.server.transport.coap.efento.CoapEfentoTransportResource;
28 29
... ... @@ -30,6 +31,8 @@ import javax.annotation.PostConstruct;
30 31 import javax.annotation.PreDestroy;
31 32 import java.net.UnknownHostException;
32 33
  34 +import static org.eclipse.californium.core.network.config.NetworkConfigDefaults.DEFAULT_BLOCKWISE_STATUS_LIFETIME;
  35 +
33 36 @Service("CoapTransportService")
34 37 @TbCoapServerComponent
35 38 @Slf4j
... ... @@ -52,6 +55,14 @@ public class CoapTransportService implements TbTransportService {
52 55 public void init() throws UnknownHostException {
53 56 log.info("Starting CoAP transport...");
54 57 coapServer = coapServerService.getCoapServer();
  58 + coapServer.getConfig().setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, true);
  59 + coapServer.getConfig().setBoolean(NetworkConfig.Keys.BLOCKWISE_ENTITY_TOO_LARGE_AUTO_FAILOVER, true);
  60 + coapServer.getConfig().setLong(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, DEFAULT_BLOCKWISE_STATUS_LIFETIME);
  61 + coapServer.getConfig().setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE, 256 * 1024 * 1024);
  62 + coapServer.getConfig().setString(NetworkConfig.Keys.RESPONSE_MATCHING, "RELAXED");
  63 + coapServer.getConfig().setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE, 1024);
  64 + coapServer.getConfig().setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE, 1024);
  65 + coapServer.getConfig().setInt(NetworkConfig.Keys.MAX_RETRANSMIT, 10);
55 66 CoapResource api = new CoapResource(API);
56 67 api.add(new CoapTransportResource(coapTransportContext, coapServerService, V1));
57 68
... ...
... ... @@ -24,6 +24,7 @@ import org.eclipse.californium.core.observe.ObserveRelation;
24 24 import org.eclipse.californium.core.server.resources.CoapExchange;
25 25 import org.eclipse.californium.core.server.resources.Resource;
26 26 import org.eclipse.californium.core.server.resources.ResourceObserver;
  27 +import org.thingsboard.common.util.ThingsBoardExecutors;
27 28 import org.thingsboard.server.common.data.DeviceTransportType;
28 29 import org.thingsboard.server.common.data.StringUtils;
29 30 import org.thingsboard.server.common.data.ota.OtaPackageType;
... ... @@ -34,18 +35,21 @@ import org.thingsboard.server.gen.transport.TransportProtos;
34 35 import java.util.List;
35 36 import java.util.Optional;
36 37 import java.util.UUID;
  38 +import java.util.concurrent.ExecutorService;
37 39
38 40 @Slf4j
39 41 public class OtaPackageTransportResource extends AbstractCoapTransportResource {
40 42 private static final int ACCESS_TOKEN_POSITION = 2;
41 43
42 44 private final OtaPackageType otaPackageType;
  45 + private final ExecutorService sendOtaDataOutUriLarge;
43 46
44 47 public OtaPackageTransportResource(CoapTransportContext ctx, OtaPackageType otaPackageType) {
45 48 super(ctx, otaPackageType.getKeyPrefix());
46   - this.setObservable(true);
47   - this.addObserver(new OtaPackageTransportResource.CoapResourceObserver());
48 49 this.otaPackageType = otaPackageType;
  50 +
  51 + this.setObservable(true);
  52 + this.sendOtaDataOutUriLarge = ThingsBoardExecutors.newWorkStealingPool(10, "LwM2M sendOtaDataOutUriLarge");
49 53 }
50 54
51 55 @Override
... ... @@ -136,12 +140,13 @@ public class OtaPackageTransportResource extends AbstractCoapTransportResource {
136 140 Response response = new Response(CoAP.ResponseCode.CONTENT);
137 141 if (data != null && data.length > 0) {
138 142 response.setPayload(data);
  143 +// response.getOptions().setAccept(MediaTypeRegistry.APPLICATION_OCTET_STREAM);
139 144 if (exchange.getRequestOptions().getBlock2() != null) {
140 145 int chunkSize = exchange.getRequestOptions().getBlock2().getSzx();
141   - boolean lastFlag = data.length > chunkSize;
142   - response.getOptions().setUriPath(exchange.getRequestOptions().getUriPathString());
143   - response.getOptions().setBlock2(chunkSize, lastFlag, 0);
144   - }
  146 + boolean lastFlag = data.length <= chunkSize;
  147 + this.sendOtaDataOutUriLarge.submit(() -> {
  148 + response.getOptions().setBlock2(chunkSize, lastFlag, 0);
  149 + }); }
145 150 exchange.respond(response);
146 151 }
147 152 }
... ...
... ... @@ -29,12 +29,11 @@ import org.springframework.stereotype.Service;
29 29 import org.thingsboard.common.util.JacksonUtil;
30 30 import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration;
31 31 import org.thingsboard.server.gen.transport.TransportProtos;
32   -import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
33 32 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
  33 +import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
34 34 import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener;
35 35 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
36 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
37   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
38 37
39 38 import java.io.IOException;
40 39 import java.security.GeneralSecurityException;
... ... @@ -46,6 +45,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L
46 45 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_INFO;
47 46 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_TELEMETRY;
48 47 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getBootstrapParametersFromThingsboard;
  48 +import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.BOOTSTRAP;
49 49
50 50 @Slf4j
51 51 @Service("LwM2MBootstrapSecurityStore")
... ... @@ -68,7 +68,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
68 68
69 69 @Override
70 70 public Iterator<SecurityInfo> getAllByEndpoint(String endPoint) {
71   - TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(endPoint, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
  71 + TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(endPoint, BOOTSTRAP);
72 72 if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
73 73 /* add value to store from BootstrapJson */
74 74 this.setBootstrapConfigScurityInfo(store);
... ... @@ -92,7 +92,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
92 92
93 93 @Override
94 94 public SecurityInfo getByIdentity(String identity) {
95   - TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(identity, LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP);
  95 + TbLwM2MSecurityInfo store = lwM2MCredentialsSecurityInfoValidator.getEndpointSecurityInfoByCredentialsId(identity, BOOTSTRAP);
96 96 if (store.getBootstrapCredentialConfig() != null && store.getSecurityMode() != null) {
97 97 /* add value to store from BootstrapJson */
98 98 this.setBootstrapConfigScurityInfo(store);
... ...
... ... @@ -33,7 +33,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
33 33 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
34 34 import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials;
35 35 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext;
36   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
  36 +import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer;
37 37
38 38 import java.io.IOException;
39 39 import java.security.GeneralSecurityException;
... ... @@ -45,6 +45,7 @@ import static org.eclipse.leshan.core.SecurityMode.NO_SEC;
45 45 import static org.eclipse.leshan.core.SecurityMode.PSK;
46 46 import static org.eclipse.leshan.core.SecurityMode.RPK;
47 47 import static org.eclipse.leshan.core.SecurityMode.X509;
  48 +import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.BOOTSTRAP;
48 49
49 50 @Slf4j
50 51 @Component
... ... @@ -55,13 +56,15 @@ public class LwM2mCredentialsSecurityInfoValidator {
55 56 private final LwM2mTransportContext context;
56 57 private final LwM2MTransportServerConfig config;
57 58
58   - public TbLwM2MSecurityInfo getEndpointSecurityInfoByCredentialsId(String credentialsId, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
  59 + public TbLwM2MSecurityInfo getEndpointSecurityInfoByCredentialsId(String credentialsId, LwM2mTypeServer keyValue) {
59 60 CountDownLatch latch = new CountDownLatch(1);
60 61 final TbLwM2MSecurityInfo[] resultSecurityStore = new TbLwM2MSecurityInfo[1];
  62 + log.warn("001) [{}]", credentialsId);
61 63 context.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(credentialsId).build(),
62 64 new TransportServiceCallback<>() {
63 65 @Override
64 66 public void onSuccess(ValidateDeviceCredentialsResponse msg) {
  67 + log.warn("002) [{}] [{}]", credentialsId, msg);
65 68 String credentialsBody = msg.getCredentials();
66 69 resultSecurityStore[0] = createSecurityInfo(credentialsId, credentialsBody, keyValue);
67 70 resultSecurityStore[0].setMsg(msg);
... ... @@ -71,6 +74,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
71 74
72 75 @Override
73 76 public void onError(Throwable e) {
  77 + log.warn("003) [{}] [{}] Failed to process credentials ", credentialsId, e);
74 78 log.trace("[{}] [{}] Failed to process credentials ", credentialsId, e);
75 79 resultSecurityStore[0] = createSecurityInfo(credentialsId, null, null);
76 80 latch.countDown();
... ... @@ -91,11 +95,11 @@ public class LwM2mCredentialsSecurityInfoValidator {
91 95 * @param keyValue -
92 96 * @return SecurityInfo
93 97 */
94   - private TbLwM2MSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTransportUtil.LwM2mTypeServer keyValue) {
  98 + private TbLwM2MSecurityInfo createSecurityInfo(String endpoint, String jsonStr, LwM2mTypeServer keyValue) {
95 99 TbLwM2MSecurityInfo result = new TbLwM2MSecurityInfo();
96 100 LwM2MCredentials credentials = JacksonUtil.fromString(jsonStr, LwM2MCredentials.class);
97 101 if (credentials != null) {
98   - if (keyValue.equals(LwM2mTransportUtil.LwM2mTypeServer.BOOTSTRAP)) {
  102 + if (keyValue.equals(BOOTSTRAP)) {
99 103 result.setBootstrapCredentialConfig(credentials.getBootstrap());
100 104 if (LwM2MSecurityMode.PSK.equals(credentials.getClient().getSecurityConfigClientMode())) {
101 105 PSKClientCredentials pskClientConfig = (PSKClientCredentials) credentials.getClient();
... ...
... ... @@ -42,7 +42,6 @@ import org.thingsboard.server.common.transport.util.SslUtil;
42 42 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
43 43 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
44 44 import org.thingsboard.server.transport.lwm2m.secure.credentials.LwM2MCredentials;
45   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
46 45 import org.thingsboard.server.transport.lwm2m.server.store.TbEditableSecurityStore;
47 46 import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
48 47
... ... @@ -57,6 +56,8 @@ import java.security.cert.X509Certificate;
57 56 import java.util.Arrays;
58 57 import java.util.List;
59 58
  59 +import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.CLIENT;
  60 +
60 61 @Slf4j
61 62 @Component
62 63 @TbLwM2mTransportComponent
... ... @@ -117,7 +118,7 @@ public class TbLwM2MDtlsCertificateVerifier implements NewAdvancedCertificateVer
117 118
118 119 String strCert = SslUtil.getCertificateString(cert);
119 120 String sha3Hash = EncryptionUtil.getSha3Hash(strCert);
120   - TbLwM2MSecurityInfo securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
  121 + TbLwM2MSecurityInfo securityInfo = securityInfoValidator.getEndpointSecurityInfoByCredentialsId(sha3Hash, CLIENT);
121 122 ValidateDeviceCredentialsResponse msg = securityInfo != null ? securityInfo.getMsg() : null;
122 123 if (msg != null && org.thingsboard.server.common.data.StringUtils.isNotEmpty(msg.getCredentials())) {
123 124 LwM2MCredentials credentials = JacksonUtil.fromString(msg.getCredentials(), LwM2MCredentials.class);
... ...
... ... @@ -65,7 +65,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE
65 65 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256;
66 66 import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8;
67 67 import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig;
68   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE;
  68 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RECOURSE;
69 69
70 70 @Slf4j
71 71 @Component
... ...
... ... @@ -25,16 +25,14 @@ import org.eclipse.californium.core.server.resources.CoapExchange;
25 25 import org.eclipse.californium.core.server.resources.Resource;
26 26 import org.eclipse.californium.core.server.resources.ResourceObserver;
27 27 import org.thingsboard.server.cache.ota.OtaPackageDataCache;
28   -import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2MUplinkMsgHandler;
29   -import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler;
30 28
31 29 import java.util.UUID;
32 30 import java.util.concurrent.ConcurrentHashMap;
33 31 import java.util.concurrent.ConcurrentMap;
34 32 import java.util.concurrent.atomic.AtomicInteger;
35 33
36   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE;
37   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SOFTWARE_UPDATE_COAP_RECOURSE;
  34 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FIRMWARE_UPDATE_COAP_RECOURSE;
  35 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SOFTWARE_UPDATE_COAP_RECOURSE;
38 36
39 37 @Slf4j
40 38 public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource {
... ... @@ -143,7 +141,7 @@ public class LwM2mTransportCoapResource extends AbstractLwM2mTransportResource {
143 141 response.setPayload(fwData);
144 142 if (exchange.getRequestOptions().getBlock2() != null) {
145 143 int chunkSize = exchange.getRequestOptions().getBlock2().getSzx();
146   - boolean lastFlag = fwData.length > chunkSize;
  144 + boolean lastFlag = fwData.length <= chunkSize;
147 145 response.getOptions().setBlock2(chunkSize, lastFlag, 0);
148 146 log.warn("92) with blokc2 Send currentId: [{}], length: [{}], chunkSize [{}], moreFlag [{}]", currentId.toString(), fwData.length, chunkSize, lastFlag);
149 147 }
... ...
... ... @@ -43,13 +43,13 @@ import org.thingsboard.server.common.data.DeviceTransportType;
43 43 import org.thingsboard.server.common.data.device.data.lwm2m.BootstrapConfiguration;
44 44 import org.thingsboard.server.common.data.device.profile.DeviceProfileTransportConfiguration;
45 45 import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
46   -import org.thingsboard.server.common.data.ota.OtaPackageKey;
47   -import org.thingsboard.server.common.data.ota.OtaPackageType;
48   -import org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus;
49   -import org.thingsboard.server.common.data.ota.OtaPackageUtil;
50 46 import org.thingsboard.server.common.transport.TransportServiceCallback;
51 47 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
52 48 import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue;
  49 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateResultFw;
  50 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateStateFw;
  51 +import org.thingsboard.server.transport.lwm2m.server.ota.software.UpdateResultSw;
  52 +import org.thingsboard.server.transport.lwm2m.server.ota.software.UpdateStateSw;
53 53 import org.thingsboard.server.transport.lwm2m.server.uplink.DefaultLwM2MUplinkMsgHandler;
54 54
55 55 import java.util.ArrayList;
... ... @@ -77,277 +77,20 @@ import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING;
77 77 import static org.eclipse.leshan.core.model.ResourceModel.Type.TIME;
78 78 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY;
79 79 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
80   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
81   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING;
82   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED;
83   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED;
84   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
85   -import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED;
  80 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_RESULT_ID;
  81 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_STATE_ID;
  82 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_RESULT_ID;
  83 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.SW_UPDATE_STATE_ID;
86 84
87 85 @Slf4j
88 86 public class LwM2mTransportUtil {
89 87
90   - public static final String EVENT_AWAKE = "AWAKE";
91   - public static final String RESPONSE_REQUEST_CHANNEL = "RESP_REQ";
92   - public static final String RESPONSE_CHANNEL = "RESP";
93   - public static final String OBSERVE_CHANNEL = "OBSERVE";
94   -
95   - public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0";
96   - public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings";
97   - public static final String BOOTSTRAP = "bootstrap";
98   - public static final String SERVERS = "servers";
99   - public static final String LWM2M_SERVER = "lwm2mServer";
100   - public static final String BOOTSTRAP_SERVER = "bootstrapServer";
101   - public static final String OBSERVE_ATTRIBUTE_TELEMETRY = "observeAttr";
102   - public static final String ATTRIBUTE = "attribute";
103   - public static final String TELEMETRY = "telemetry";
104   - public static final String KEY_NAME = "keyName";
105   - public static final String OBSERVE_LWM2M = "observe";
106   - public static final String ATTRIBUTE_LWM2M = "attributeLwm2m";
107   -
108   - private static final String REQUEST = "/request";
109   - private static final String ATTRIBUTES = "/" + ATTRIBUTE;
110   - public static final String TELEMETRIES = "/" + TELEMETRY;
111   - public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST;
112   - public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/";
113   -
114   - public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms
  88 + public static final String LWM2M_VERSION_DEFAULT = "1.0";
115 89
116 90 public static final String LOG_LWM2M_TELEMETRY = "logLwm2m";
117 91 public static final String LOG_LWM2M_INFO = "info";
118 92 public static final String LOG_LWM2M_ERROR = "error";
119 93 public static final String LOG_LWM2M_WARN = "warn";
120   - public static final String LOG_LWM2M_VALUE = "value";
121   -
122   - public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized";
123   - public static final String LWM2M_VERSION_DEFAULT = "1.0";
124   -
125   - // Firmware
126   - public static final String FIRMWARE_UPDATE_COAP_RECOURSE = "tbfw";
127   - public static final String FW_UPDATE = "Firmware update";
128   - public static final Integer FW_5_ID = 5;
129   - public static final Integer FW_19_ID = 19;
130   -
131   - // Package W
132   - public static final String FW_PACKAGE_5_ID = "/5/0/0";
133   - public static final String FW_PACKAGE_19_ID = "/19/0/0";
134   - // Package URI
135   - public static final String FW_PACKAGE_URI_ID = "/5/0/1";
136   - // State R
137   - public static final String FW_STATE_ID = "/5/0/3";
138   - // Update Result R
139   - public static final String FW_RESULT_ID = "/5/0/5";
140   -
141   - public static final String FW_DELIVERY_METHOD = "/5/0/9";
142   -
143   - // PkgName R
144   - public static final String FW_NAME_ID = "/5/0/6";
145   - // PkgVersion R
146   - public static final String FW_5_VER_ID = "/5/0/7";
147   -
148   - /**
149   - * Quectel@Hi15RM1-HLB_V1.0@BC68JAR01A10,V150R100C20B300SP7,V150R100C20B300SP7@8
150   - * BC68JAR01A10
151   - * # Request prodct type number
152   - * ATI
153   - * Quectel
154   - * BC68
155   - * Revision:BC68JAR01A10
156   - */
157   - public static final String FW_3_VER_ID = "/3/0/3";
158   - // Update E
159   - public static final String FW_UPDATE_ID = "/5/0/2";
160   -
161   - // Software
162   - public static final String SOFTWARE_UPDATE_COAP_RECOURSE = "softwareUpdateCoapRecourse";
163   - public static final String SW_UPDATE = "Software update";
164   - public static final Integer SW_ID = 9;
165   - // Package W
166   - public static final String SW_PACKAGE_ID = "/9/0/2";
167   - // Package URI
168   - public static final String SW_PACKAGE_URI_ID = "/9/0/3";
169   - // Update State R
170   - public static final String SW_UPDATE_STATE_ID = "/9/0/7";
171   - // Update Result R
172   - public static final String SW_RESULT_ID = "/9/0/9";
173   - // PkgName R
174   - public static final String SW_NAME_ID = "/9/0/0";
175   - // PkgVersion R
176   - public static final String SW_VER_ID = "/9/0/1";
177   - // Install E
178   - public static final String SW_INSTALL_ID = "/9/0/4";
179   - // Uninstall E
180   - public static final String SW_UN_INSTALL_ID = "/9/0/6";
181   -
182   - public enum LwM2mTypeServer {
183   - BOOTSTRAP(0, "bootstrap"),
184   - CLIENT(1, "client");
185   -
186   - public int code;
187   - public String type;
188   -
189   - LwM2mTypeServer(int code, String type) {
190   - this.code = code;
191   - this.type = type;
192   - }
193   -
194   - public static LwM2mTypeServer fromLwM2mTypeServer(String type) {
195   - for (LwM2mTypeServer sm : LwM2mTypeServer.values()) {
196   - if (sm.type.equals(type)) {
197   - return sm;
198   - }
199   - }
200   - throw new IllegalArgumentException(String.format("Unsupported typeServer type : %d", type));
201   - }
202   - }
203   -
204   - public static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(UpdateResultFw updateResultFw) {
205   - switch (updateResultFw) {
206   - case INITIAL:
207   - return Optional.empty();
208   - case UPDATE_SUCCESSFULLY:
209   - return Optional.of(UPDATED);
210   - case NOT_ENOUGH:
211   - case OUT_OFF_MEMORY:
212   - case CONNECTION_LOST:
213   - case INTEGRITY_CHECK_FAILURE:
214   - case UNSUPPORTED_TYPE:
215   - case INVALID_URI:
216   - case UPDATE_FAILED:
217   - case UNSUPPORTED_PROTOCOL:
218   - return Optional.of(FAILED);
219   - default:
220   - throw new CodecException("Invalid value stateFw %s for FirmwareUpdateStatus.", updateResultFw.name());
221   - }
222   - }
223   -
224   - public static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(UpdateStateFw updateStateFw) {
225   - switch (updateStateFw) {
226   - case IDLE:
227   - return Optional.empty();
228   - case DOWNLOADING:
229   - return Optional.of(DOWNLOADING);
230   - case DOWNLOADED:
231   - return Optional.of(DOWNLOADED);
232   - case UPDATING:
233   - return Optional.of(UPDATING);
234   - default:
235   - throw new CodecException("Invalid value stateFw %d for FirmwareUpdateStatus.", updateStateFw);
236   - }
237   - }
238   -
239   - /**
240   - * SW Update State R
241   - * 0: INITIAL Before downloading. (see 5.1.2.1)
242   - * 1: DOWNLOAD STARTED The downloading process has started and is on-going. (see 5.1.2.2)
243   - * 2: DOWNLOADED The package has been completely downloaded (see 5.1.2.3)
244   - * 3: DELIVERED In that state, the package has been correctly downloaded and is ready to be installed. (see 5.1.2.4)
245   - * If executing the Install Resource failed, the state remains at DELIVERED.
246   - * If executing the Install Resource was successful, the state changes from DELIVERED to INSTALLED.
247   - * After executing the UnInstall Resource, the state changes to INITIAL.
248   - * 4: INSTALLED
249   - */
250   - public enum UpdateStateSw {
251   - INITIAL(0, "Initial"),
252   - DOWNLOAD_STARTED(1, "DownloadStarted"),
253   - DOWNLOADED(2, "Downloaded"),
254   - DELIVERED(3, "Delivered"),
255   - INSTALLED(4, "Installed");
256   -
257   - public int code;
258   - public String type;
259   -
260   - UpdateStateSw(int code, String type) {
261   - this.code = code;
262   - this.type = type;
263   - }
264   -
265   - public static UpdateStateSw fromUpdateStateSwByType(String type) {
266   - for (UpdateStateSw to : UpdateStateSw.values()) {
267   - if (to.type.equals(type)) {
268   - return to;
269   - }
270   - }
271   - throw new IllegalArgumentException(String.format("Unsupported SW State type : %s", type));
272   - }
273   -
274   - public static UpdateStateSw fromUpdateStateSwByCode(int code) {
275   - for (UpdateStateSw to : UpdateStateSw.values()) {
276   - if (to.code == code) {
277   - return to;
278   - }
279   - }
280   - throw new IllegalArgumentException(String.format("Unsupported SW State type : %s", code));
281   - }
282   - }
283   -
284   - /**
285   - * SW Update Result
286   - * Contains the result of downloading or installing/uninstalling the software
287   - * 0: Initial value.
288   - * - Prior to download any new package in the Device, Update Result MUST be reset to this initial value.
289   - * - One side effect of executing the Uninstall resource is to reset Update Result to this initial value "0".
290   - * 1: Downloading.
291   - * - The package downloading process is on-going.
292   - * 2: Software successfully installed.
293   - * 3: Successfully Downloaded and package integrity verified
294   - * (( 4-49, for expansion, of other scenarios))
295   - * ** Failed
296   - * 50: Not enough storage for the new software package.
297   - * 51: Out of memory during downloading process.
298   - * 52: Connection lost during downloading process.
299   - * 53: Package integrity check failure.
300   - * 54: Unsupported package type.
301   - * 56: Invalid URI
302   - * 57: Device defined update error
303   - * 58: Software installation failure
304   - * 59: Uninstallation Failure during forUpdate(arg=0)
305   - * 60-200 : (for expansion, selection to be in blocks depending on new introduction of features)
306   - * This Resource MAY be reported by sending Observe operation.
307   - */
308   - public enum UpdateResultSw {
309   - INITIAL(0, "Initial value", false),
310   - DOWNLOADING(1, "Downloading", false),
311   - SUCCESSFULLY_INSTALLED(2, "Software successfully installed", false),
312   - SUCCESSFULLY_DOWNLOADED_VERIFIED(3, "Successfully Downloaded and package integrity verified", false),
313   - NOT_ENOUGH_STORAGE(50, "Not enough storage for the new software package", true),
314   - OUT_OFF_MEMORY(51, "Out of memory during downloading process", true),
315   - CONNECTION_LOST(52, "Connection lost during downloading process", false),
316   - PACKAGE_CHECK_FAILURE(53, "Package integrity check failure.", false),
317   - UNSUPPORTED_PACKAGE_TYPE(54, "Unsupported package type", false),
318   - INVALID_URI(56, "Invalid URI", true),
319   - UPDATE_ERROR(57, "Device defined update error", true),
320   - INSTALL_FAILURE(58, "Software installation failure", true),
321   - UN_INSTALL_FAILURE(59, "Uninstallation Failure during forUpdate(arg=0)", true);
322   -
323   - public int code;
324   - public String type;
325   - public boolean isAgain;
326   -
327   - UpdateResultSw(int code, String type, boolean isAgain) {
328   - this.code = code;
329   - this.type = type;
330   - this.isAgain = isAgain;
331   - }
332   -
333   - public static UpdateResultSw fromUpdateResultSwByType(String type) {
334   - for (UpdateResultSw to : UpdateResultSw.values()) {
335   - if (to.type.equals(type)) {
336   - return to;
337   - }
338   - }
339   - throw new IllegalArgumentException(String.format("Unsupported SW Update Result type : %s", type));
340   - }
341   -
342   - public static UpdateResultSw fromUpdateResultSwByCode(int code) {
343   - for (UpdateResultSw to : UpdateResultSw.values()) {
344   - if (to.code == code) {
345   - return to;
346   - }
347   - }
348   - throw new IllegalArgumentException(String.format("Unsupported SW Update Result code : %s", code));
349   - }
350   - }
351 94
352 95 public enum LwM2MClientStrategy {
353 96 CLIENT_STRATEGY_1(1, "Read only resources marked as observation"),
... ... @@ -380,45 +123,7 @@ public class LwM2mTransportUtil {
380 123 }
381 124 }
382 125
383   - /**
384   - * FirmwareUpdateStatus {
385   - * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
386   - */
387   - public static OtaPackageUpdateStatus EqualsSwSateToFirmwareUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) {
388   - switch (updateResultSw) {
389   - case INITIAL:
390   - switch (updateStateSw) {
391   - case INITIAL:
392   - case DOWNLOAD_STARTED:
393   - return DOWNLOADING;
394   - case DOWNLOADED:
395   - return DOWNLOADED;
396   - case DELIVERED:
397   - return VERIFIED;
398   - }
399   - case DOWNLOADING:
400   - return DOWNLOADING;
401   - case SUCCESSFULLY_INSTALLED:
402   - return UPDATED;
403   - case SUCCESSFULLY_DOWNLOADED_VERIFIED:
404   - return VERIFIED;
405   - case NOT_ENOUGH_STORAGE:
406   - case OUT_OFF_MEMORY:
407   - case CONNECTION_LOST:
408   - case PACKAGE_CHECK_FAILURE:
409   - case UNSUPPORTED_PACKAGE_TYPE:
410   - case INVALID_URI:
411   - case UPDATE_ERROR:
412   - case INSTALL_FAILURE:
413   - case UN_INSTALL_FAILURE:
414   - return FAILED;
415   - default:
416   - throw new CodecException("Invalid value stateFw %s %s for FirmwareUpdateStatus.", updateStateSw.name(), updateResultSw.name());
417   - }
418   - }
419   -
420   -
421   - public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath
  126 + public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath
422 127 resourcePath) throws CodecException {
423 128 switch (type) {
424 129 case BOOLEAN:
... ... @@ -477,18 +182,6 @@ public class LwM2mTransportUtil {
477 182 return null;
478 183 }
479 184
480   -// public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) {
481   -// LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile();
482   -// lwM2MClientProfile.setTenantId(tenantId);
483   -// lwM2MClientProfile.setPostClientLwM2mSettings(profilesConfigData.get(CLIENT_LWM2M_SETTINGS).getAsJsonObject());
484   -// lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject());
485   -// lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray());
486   -// lwM2MClientProfile.setPostTelemetryProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).getAsJsonArray());
487   -// lwM2MClientProfile.setPostObserveProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).getAsJsonArray());
488   -// lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject());
489   -// return lwM2MClientProfile;
490   -// }
491   -
492 185 public static Lwm2mDeviceProfileTransportConfiguration toLwM2MClientProfile(DeviceProfile deviceProfile) {
493 186 DeviceProfileTransportConfiguration transportConfiguration = deviceProfile.getProfileData().getTransportConfiguration();
494 187 if (transportConfiguration.getType().equals(DeviceTransportType.LWM2M)) {
... ... @@ -603,7 +296,6 @@ public class LwM2mTransportUtil {
603 296 if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) {
604 297 return pathIdVer;
605 298 } else {
606   - LwM2mPath pathObjId = new LwM2mPath(pathIdVer);
607 299 return convertObjectIdToVersionedId(pathIdVer, registration);
608 300 }
609 301 }
... ... @@ -743,18 +435,18 @@ public class LwM2mTransportUtil {
743 435 }
744 436 }
745 437
746   - public static boolean isFwSwWords(String pathName) {
747   - return OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName)
748   - || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName)
749   - || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM).equals(pathName)
750   - || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
751   - || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.SIZE).equals(pathName)
752   - || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName)
753   - || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName)
754   - || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM).equals(pathName)
755   - || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
756   - || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.SIZE).equals(pathName);
757   - }
  438 +// public static boolean isFwSwWords(String pathName) {
  439 +// return OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.VERSION).equals(pathName)
  440 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName)
  441 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM).equals(pathName)
  442 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
  443 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.SIZE).equals(pathName)
  444 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName)
  445 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName)
  446 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM).equals(pathName)
  447 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.CHECKSUM_ALGORITHM).equals(pathName)
  448 +// || OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.SIZE).equals(pathName);
  449 +// }
758 450
759 451 /**
760 452 * @param lwM2MClient -
... ...
... ... @@ -33,12 +33,10 @@ import org.eclipse.leshan.server.security.SecurityInfo;
33 33 import org.thingsboard.server.common.data.Device;
34 34 import org.thingsboard.server.common.data.DeviceProfile;
35 35 import org.thingsboard.server.common.data.id.TenantId;
36   -import org.thingsboard.server.common.data.ota.OtaPackageType;
37 36 import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
38 37 import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
39 38 import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
40 39 import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
41   -import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler;
42 40
43 41 import java.util.Collection;
44 42 import java.util.Map;
... ... @@ -53,7 +51,7 @@ import java.util.concurrent.locks.ReentrantLock;
53 51 import java.util.stream.Collectors;
54 52
55 53 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
56   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.TRANSPORT_DEFAULT_LWM2M_VERSION;
  54 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_VERSION_DEFAULT;
57 55 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertObjectIdToVersionedId;
58 56 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.equalsResourceTypeGetSimpleName;
59 57 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId;
... ... @@ -307,7 +305,7 @@ public class LwM2mClient implements Cloneable {
307 305 LwM2mPath pathIds = new LwM2mPath(fromVersionedIdToObjectId(path));
308 306 String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
309 307 String verRez = getVerFromPathIdVerOrId(path);
310   - return verRez == null ? TRANSPORT_DEFAULT_LWM2M_VERSION.equals(verSupportedObject) : verRez.equals(verSupportedObject);
  308 + return verRez == null ? LWM2M_VERSION_DEFAULT.equals(verSupportedObject) : verRez.equals(verSupportedObject);
311 309 }
312 310
313 311 /**
... ...
... ... @@ -17,6 +17,7 @@ package org.thingsboard.server.transport.lwm2m.server.ota;
17 17
18 18 import lombok.RequiredArgsConstructor;
19 19 import lombok.extern.slf4j.Slf4j;
  20 +import org.eclipse.leshan.core.node.codec.CodecException;
20 21 import org.eclipse.leshan.core.request.ContentFormat;
21 22 import org.springframework.beans.factory.annotation.Autowired;
22 23 import org.springframework.context.annotation.Lazy;
... ... @@ -32,11 +33,7 @@ import org.thingsboard.server.common.transport.TransportServiceCallback;
32 33 import org.thingsboard.server.gen.transport.TransportProtos;
33 34 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
34 35 import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
35   -import org.thingsboard.server.transport.lwm2m.server.LwM2MFirmwareUpdateStrategy;
36 36 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper;
37   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
38   -import org.thingsboard.server.transport.lwm2m.server.UpdateResultFw;
39   -import org.thingsboard.server.transport.lwm2m.server.UpdateStateFw;
40 37 import org.thingsboard.server.transport.lwm2m.server.attributes.LwM2MAttributesService;
41 38 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
42 39 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
... ... @@ -47,6 +44,13 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequ
47 44 import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest;
48 45 import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteResponseCallback;
49 46 import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService;
  47 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy;
  48 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateDeliveryFw;
  49 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateResultFw;
  50 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateStateFw;
  51 +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy;
  52 +import org.thingsboard.server.transport.lwm2m.server.ota.software.UpdateResultSw;
  53 +import org.thingsboard.server.transport.lwm2m.server.ota.software.UpdateStateSw;
50 54 import org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mUplinkMsgHandler;
51 55
52 56 import javax.annotation.PostConstruct;
... ... @@ -59,8 +63,13 @@ import java.util.UUID;
59 63 import java.util.concurrent.ConcurrentHashMap;
60 64
61 65 import static org.thingsboard.server.common.data.ota.OtaPackageKey.STATE;
  66 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADED;
  67 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.DOWNLOADING;
  68 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.FAILED;
  69 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATED;
  70 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
  71 +import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.VERIFIED;
62 72 import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey;
63   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FIRMWARE_UPDATE_COAP_RECOURSE;
64 73 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_TELEMETRY;
65 74 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertObjectIdToVersionedId;
66 75
... ... @@ -77,13 +86,30 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
77 86 public static final String SOFTWARE_TITLE = getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE);
78 87 public static final String SOFTWARE_URL = getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.URL);
79 88
  89 + public static final String FIRMWARE_UPDATE_COAP_RECOURSE = "tbfw";
  90 + public static final String SOFTWARE_UPDATE_COAP_RECOURSE = "tbsw";
80 91 private static final String FW_PACKAGE_5_ID = "/5/0/0";
81 92 private static final String FW_URL_ID = "/5/0/1";
82 93 private static final String FW_EXECUTE_ID = "/5/0/2";
83   - private static final String FW_NAME_ID = "/5/0/6";
84   - private static final String FW_VER_ID = "/5/0/7";
  94 + public static final String FW_STATE_ID = "/5/0/3";
  95 + public static final String FW_RESULT_ID = "/5/0/5";
  96 + public static final String FW_NAME_ID = "/5/0/6";
  97 + public static final String FW_5_VER_ID = "/5/0/7";
  98 + /**
  99 + * Quectel@Hi15RM1-HLB_V1.0@BC68JAR01A10,V150R100C20B300SP7,V150R100C20B300SP7@8
  100 + * Revision:BC68JAR01A10
  101 + */
  102 + public static final String FW_3_VER_ID = "/3/0/3";
  103 + public static final String FW_DELIVERY_METHOD = "/5/0/9";
  104 +
85 105 private static final String SW_NAME_ID = "/9/0/0";
86 106 private static final String SW_VER_ID = "/9/0/1";
  107 + public static final String SW_PACKAGE_ID = "/9/0/2";
  108 + public static final String SW_PACKAGE_URI_ID = "/9/0/3";
  109 + public static final String SW_INSTALL_ID = "/9/0/4";
  110 + public static final String SW_UPDATE_STATE_ID = "/9/0/7";
  111 + public static final String SW_RESULT_ID = "/9/0/9";
  112 + public static final String SW_UN_INSTALL_ID = "/9/0/6";
87 113
88 114 private final Map<String, LwM2MClientOtaInfo> fwStates = new ConcurrentHashMap<>();
89 115 private final Map<String, LwM2MClientOtaInfo> swStates = new ConcurrentHashMap<>();
... ... @@ -175,6 +201,24 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
175 201 }
176 202
177 203 @Override
  204 + public void onCurrentFirmwareStrategyUpdate(LwM2mClient client, Integer newStrategy, String newBaseUrl) {
  205 + log.debug("[{}] Current fw strategy: {}", client.getEndpoint(), newStrategy);
  206 + LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client);
  207 + fwInfo.setFwStrategy(LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(newStrategy));
  208 + fwInfo.setBaseUrl(newBaseUrl);
  209 + startFirmwareUpdateIfNeeded(client, fwInfo);
  210 + }
  211 +
  212 + @Override
  213 + public void onCurrentSoftwareStrategyUpdate(LwM2mClient client, Integer newStrategy, String newBaseUrl) {
  214 + log.debug("[{}] Current sw strategy: {}", client.getEndpoint(), newStrategy);
  215 + LwM2MClientOtaInfo swInfo = getOrInitSwInfo(client);
  216 + swInfo.setSwStrategy(LwM2MSoftwareUpdateStrategy.fromStrategySwByCode(newStrategy));
  217 + swInfo.setBaseUrl(newBaseUrl);
  218 + startSoftwareUpdateIfNeeded(client, swInfo);
  219 + }
  220 +
  221 + @Override
178 222 public void onCurrentFirmwareVersion3Update(LwM2mClient client, String version) {
179 223 log.debug("[{}] Current fw version: {}", client.getEndpoint(), version);
180 224 LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client);
... ... @@ -197,7 +241,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
197 241 executeFwUpdate(client);
198 242 }
199 243 fwInfo.setUpdateState(state);
200   - Optional<OtaPackageUpdateStatus> status = LwM2mTransportUtil.toOtaPackageUpdateStatus(state);
  244 + Optional<OtaPackageUpdateStatus> status = this.toOtaPackageUpdateStatus(state);
201 245 status.ifPresent(otaStatus -> sendStateUpdateToTelemetry(client, fwInfo,
202 246 otaStatus, "Firmware Update State: " + state.name()));
203 247 }
... ... @@ -207,7 +251,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
207 251 log.debug("[{}] Current fw result: {}", client.getEndpoint(), code);
208 252 LwM2MClientOtaInfo fwInfo = getOrInitFwInfo(client);
209 253 UpdateResultFw result = UpdateResultFw.fromUpdateResultFwByCode(code.intValue());
210   - Optional<OtaPackageUpdateStatus> status = LwM2mTransportUtil.toOtaPackageUpdateStatus(result);
  254 + Optional<OtaPackageUpdateStatus> status = this.toOtaPackageUpdateStatus(result);
211 255 status.ifPresent(otaStatus -> sendStateUpdateToTelemetry(client, fwInfo,
212 256 otaStatus, "Firmware Update Result: " + result.name()));
213 257 if (result.isAgain() && fwInfo.getRetryAttempts() <= 2) {
... ... @@ -250,6 +294,10 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
250 294 }
251 295 }
252 296
  297 + private void startSoftwareUpdateIfNeeded(LwM2mClient client, LwM2MClientOtaInfo swInfo) {
  298 +
  299 + }
  300 +
253 301 private void startFirmwareUpdateUsingUrl(LwM2mClient client, String url) {
254 302 String targetIdVer = convertObjectIdToVersionedId(FW_URL_ID, client.getRegistration());
255 303 TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(targetIdVer).value(url).timeout(config.getTimeout()).build();
... ... @@ -276,10 +324,10 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
276 324 if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) {
277 325 UUID otaPackageId = new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB());
278 326 LwM2MFirmwareUpdateStrategy strategy;
279   - if (fwInfo.getDeliveryMethod() == null || fwInfo.getDeliveryMethod() == 2) {
280   - strategy = fwInfo.getStrategy();
  327 + if (fwInfo.getDeliveryMethod() == null || fwInfo.getDeliveryMethod() == UpdateDeliveryFw.BOTH.code) {
  328 + strategy = fwInfo.getFwStrategy();
281 329 } else {
282   - strategy = fwInfo.getDeliveryMethod() == 0 ? LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY;
  330 + strategy = fwInfo.getDeliveryMethod() == UpdateDeliveryFw.PULL.code ? LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy.OBJ_5_BINARY;
283 331 }
284 332 switch (strategy) {
285 333 case OBJ_5_BINARY:
... ... @@ -328,9 +376,9 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
328 376 return Optional.empty();
329 377 }
330 378
331   - private LwM2MClientOtaInfo getOrInitFwInfo(LwM2mClient client) {
  379 + public LwM2MClientOtaInfo getOrInitFwInfo(LwM2mClient client) {
332 380 //TODO: fetch state from the cache or DB.
333   - return fwStates.computeIfAbsent(client.getEndpoint(), endpoint -> {
  381 + return this.fwStates.computeIfAbsent(client.getEndpoint(), endpoint -> {
334 382 var profile = clientContext.getProfile(client.getProfileId());
335 383 return new LwM2MClientOtaInfo(endpoint, OtaPackageType.FIRMWARE, profile.getClientLwM2mSettings().getFwUpdateStrategy(),
336 384 profile.getClientLwM2mSettings().getFwUpdateRecourse());
... ... @@ -357,4 +405,78 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
357 405 helper.sendParametersOnThingsboardTelemetry(result, client.getSession());
358 406 }
359 407
  408 + private static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(UpdateResultFw updateResultFw) {
  409 + switch (updateResultFw) {
  410 + case INITIAL:
  411 + return Optional.empty();
  412 + case UPDATE_SUCCESSFULLY:
  413 + return Optional.of(UPDATED);
  414 + case NOT_ENOUGH:
  415 + case OUT_OFF_MEMORY:
  416 + case CONNECTION_LOST:
  417 + case INTEGRITY_CHECK_FAILURE:
  418 + case UNSUPPORTED_TYPE:
  419 + case INVALID_URI:
  420 + case UPDATE_FAILED:
  421 + case UNSUPPORTED_PROTOCOL:
  422 + return Optional.of(FAILED);
  423 + default:
  424 + throw new CodecException("Invalid value stateFw %s for FirmwareUpdateStatus.", updateResultFw.name());
  425 + }
  426 + }
  427 +
  428 + private static Optional<OtaPackageUpdateStatus> toOtaPackageUpdateStatus(UpdateStateFw updateStateFw) {
  429 + switch (updateStateFw) {
  430 + case IDLE:
  431 + return Optional.empty();
  432 + case DOWNLOADING:
  433 + return Optional.of(DOWNLOADING);
  434 + case DOWNLOADED:
  435 + return Optional.of(DOWNLOADED);
  436 + case UPDATING:
  437 + return Optional.of(UPDATING);
  438 + default:
  439 + throw new CodecException("Invalid value stateFw %d for FirmwareUpdateStatus.", updateStateFw);
  440 + }
  441 + }
  442 +
  443 + /**
  444 + * FirmwareUpdateStatus {
  445 + * DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED
  446 + */
  447 + public static Optional<OtaPackageUpdateStatus> toSwSateResultUpdateStatus(UpdateStateSw updateStateSw, UpdateResultSw updateResultSw) {
  448 + switch (updateResultSw) {
  449 + case INITIAL:
  450 + switch (updateStateSw) {
  451 + case INITIAL:
  452 + case DOWNLOAD_STARTED:
  453 + return Optional.of(DOWNLOADING);
  454 + case DOWNLOADED:
  455 + return Optional.of(DOWNLOADED);
  456 + case DELIVERED:
  457 + return Optional.of(VERIFIED);
  458 + }
  459 + case DOWNLOADING:
  460 + return Optional.of(DOWNLOADING);
  461 + case SUCCESSFULLY_INSTALLED:
  462 + return Optional.of(UPDATED);
  463 + case SUCCESSFULLY_DOWNLOADED_VERIFIED:
  464 + return Optional.of(VERIFIED);
  465 + case NOT_ENOUGH_STORAGE:
  466 + case OUT_OFF_MEMORY:
  467 + case CONNECTION_LOST:
  468 + case PACKAGE_CHECK_FAILURE:
  469 + case UNSUPPORTED_PACKAGE_TYPE:
  470 + case INVALID_URI:
  471 + case UPDATE_ERROR:
  472 + case INSTALL_FAILURE:
  473 + case UN_INSTALL_FAILURE:
  474 + return Optional.of(FAILED);
  475 + default:
  476 + throw new CodecException("Invalid value stateFw %s %s for FirmwareUpdateStatus.", updateStateSw.name(), updateResultSw.name());
  477 + }
  478 + }
  479 +
  480 +
  481 +
360 482 }
... ...
... ... @@ -18,9 +18,10 @@ package org.thingsboard.server.transport.lwm2m.server.ota;
18 18 import lombok.Data;
19 19 import org.thingsboard.server.common.data.StringUtils;
20 20 import org.thingsboard.server.common.data.ota.OtaPackageType;
21   -import org.thingsboard.server.transport.lwm2m.server.LwM2MFirmwareUpdateStrategy;
22   -import org.thingsboard.server.transport.lwm2m.server.UpdateStateFw;
23   -import org.thingsboard.server.transport.lwm2m.server.UpdateResultFw;
  21 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy;
  22 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateResultFw;
  23 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.UpdateStateFw;
  24 +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy;
24 25
25 26 import java.util.Optional;
26 27
... ... @@ -44,7 +45,8 @@ public class LwM2MClientOtaInfo {
44 45 private Integer deliveryMethod;
45 46
46 47 //TODO: use value from device if applicable;
47   - private LwM2MFirmwareUpdateStrategy strategy;
  48 + private LwM2MFirmwareUpdateStrategy fwStrategy;
  49 + private LwM2MSoftwareUpdateStrategy swStrategy;
48 50 private UpdateStateFw updateState;
49 51 private UpdateResultFw updateResult;
50 52
... ... @@ -54,7 +56,7 @@ public class LwM2MClientOtaInfo {
54 56 public LwM2MClientOtaInfo(String endpoint, OtaPackageType type, Integer strategyCode, String baseUrl) {
55 57 this.endpoint = endpoint;
56 58 this.type = type;
57   - this.strategy = LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(strategyCode);
  59 + this.fwStrategy = LwM2MFirmwareUpdateStrategy.fromStrategyFwByCode(strategyCode);
58 60 this.baseUrl = baseUrl;
59 61 }
60 62
... ...
... ... @@ -31,6 +31,10 @@ public interface LwM2MOtaUpdateService {
31 31
32 32 void onCurrentFirmwareNameUpdate(LwM2mClient client, String name);
33 33
  34 + void onCurrentFirmwareStrategyUpdate(LwM2mClient client, Integer newStrategy, String newBaseUrl);
  35 +
  36 + void onCurrentSoftwareStrategyUpdate(LwM2mClient client, Integer newStrategy, String newBaseUrl);
  37 +
34 38 void onCurrentFirmwareVersion3Update(LwM2mClient client, String version);
35 39
36 40 void onCurrentFirmwareVersion5Update(LwM2mClient client, String version);
... ...
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/LwM2MFirmwareUpdateStrategy.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MFirmwareUpdateStrategy.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.transport.lwm2m.server;
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.firmware;
17 17
18 18 public enum LwM2MFirmwareUpdateStrategy {
19 19 OBJ_5_BINARY(1, "ObjectId 5, Binary"),
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.firmware;
  17 +
  18 +/**
  19 + * /** Delivery Method R
  20 + * 0: Pull only
  21 + * 1: Push only
  22 + * 2: Both:
  23 + * - In this case the LwM2M Server MAY choose the preferred mechanism for conveying the firmware image to the LwM2M Client.
  24 + */
  25 +public enum UpdateDeliveryFw {
  26 + PULL(0, "Pull only"),
  27 + PUSH(1, "Push only"),
  28 + BOTH(2, "Push or Push");
  29 +
  30 + public int code;
  31 + public String type;
  32 +
  33 + UpdateDeliveryFw(int code, String type) {
  34 + this.code = code;
  35 + this.type = type;
  36 + }
  37 +
  38 + public static UpdateDeliveryFw fromStateFwByType(String type) {
  39 + for (UpdateDeliveryFw to : UpdateDeliveryFw.values()) {
  40 + if (to.type.equals(type)) {
  41 + return to;
  42 + }
  43 + }
  44 + throw new IllegalArgumentException(String.format("Unsupported FW delivery type : %s", type));
  45 + }
  46 +
  47 + public static UpdateDeliveryFw fromStateFwByCode(int code) {
  48 + for (UpdateDeliveryFw to : UpdateDeliveryFw.values()) {
  49 + if (to.code == code) {
  50 + return to;
  51 + }
  52 + }
  53 + throw new IllegalArgumentException(String.format("Unsupported FW delivery code : %s", code));
  54 + }
  55 +}
... ...
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/UpdateResultFw.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/UpdateResultFw.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.transport.lwm2m.server;
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.firmware;
17 17
18 18 import lombok.Getter;
19 19
... ...
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/firmware/UpdateStateFw.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/UpdateStateFw.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.transport.lwm2m.server;
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.firmware;
17 17
18 18 /**
19 19 * /** State R
... ...
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ota/software/LwM2MSoftwareUpdateStrategy.java renamed from common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MSoftwareUpdateStrategy.java
... ... @@ -13,7 +13,7 @@
13 13 * See the License for the specific language governing permissions and
14 14 * limitations under the License.
15 15 */
16   -package org.thingsboard.server.transport.lwm2m.server;
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.software;
17 17
18 18 public enum LwM2MSoftwareUpdateStrategy {
19 19 BINARY(1, "ObjectId 9, Binary"),
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.software;
  17 +
  18 +/**
  19 + * SW Update Result
  20 + * Contains the result of downloading or installing/uninstalling the software
  21 + * 0: Initial value.
  22 + * - Prior to download any new package in the Device, Update Result MUST be reset to this initial value.
  23 + * - One side effect of executing the Uninstall resource is to reset Update Result to this initial value "0".
  24 + * 1: Downloading.
  25 + * - The package downloading process is on-going.
  26 + * 2: Software successfully installed.
  27 + * 3: Successfully Downloaded and package integrity verified
  28 + * (( 4-49, for expansion, of other scenarios))
  29 + * ** Failed
  30 + * 50: Not enough storage for the new software package.
  31 + * 51: Out of memory during downloading process.
  32 + * 52: Connection lost during downloading process.
  33 + * 53: Package integrity check failure.
  34 + * 54: Unsupported package type.
  35 + * 56: Invalid URI
  36 + * 57: Device defined update error
  37 + * 58: Software installation failure
  38 + * 59: Uninstallation Failure during forUpdate(arg=0)
  39 + * 60-200 : (for expansion, selection to be in blocks depending on new introduction of features)
  40 + * This Resource MAY be reported by sending Observe operation.
  41 + */
  42 +public enum UpdateResultSw {
  43 + INITIAL(0, "Initial value", false),
  44 + DOWNLOADING(1, "Downloading", false),
  45 + SUCCESSFULLY_INSTALLED(2, "Software successfully installed", false),
  46 + SUCCESSFULLY_DOWNLOADED_VERIFIED(3, "Successfully Downloaded and package integrity verified", false),
  47 + NOT_ENOUGH_STORAGE(50, "Not enough storage for the new software package", true),
  48 + OUT_OFF_MEMORY(51, "Out of memory during downloading process", true),
  49 + CONNECTION_LOST(52, "Connection lost during downloading process", false),
  50 + PACKAGE_CHECK_FAILURE(53, "Package integrity check failure.", false),
  51 + UNSUPPORTED_PACKAGE_TYPE(54, "Unsupported package type", false),
  52 + INVALID_URI(56, "Invalid URI", true),
  53 + UPDATE_ERROR(57, "Device defined update error", true),
  54 + INSTALL_FAILURE(58, "Software installation failure", true),
  55 + UN_INSTALL_FAILURE(59, "Uninstallation Failure during forUpdate(arg=0)", true);
  56 +
  57 + public int code;
  58 + public String type;
  59 + public boolean isAgain;
  60 +
  61 + UpdateResultSw(int code, String type, boolean isAgain) {
  62 + this.code = code;
  63 + this.type = type;
  64 + this.isAgain = isAgain;
  65 + }
  66 +
  67 + public static UpdateResultSw fromUpdateResultSwByType(String type) {
  68 + for (UpdateResultSw to : UpdateResultSw.values()) {
  69 + if (to.type.equals(type)) {
  70 + return to;
  71 + }
  72 + }
  73 + throw new IllegalArgumentException(String.format("Unsupported SW Update Result type : %s", type));
  74 + }
  75 +
  76 + public static UpdateResultSw fromUpdateResultSwByCode(int code) {
  77 + for (UpdateResultSw to : UpdateResultSw.values()) {
  78 + if (to.code == code) {
  79 + return to;
  80 + }
  81 + }
  82 + throw new IllegalArgumentException(String.format("Unsupported SW Update Result code : %s", code));
  83 + }
  84 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.ota.software;
  17 +
  18 +/**
  19 + * SW Update State R
  20 + * 0: INITIAL Before downloading. (see 5.1.2.1)
  21 + * 1: DOWNLOAD STARTED The downloading process has started and is on-going. (see 5.1.2.2)
  22 + * 2: DOWNLOADED The package has been completely downloaded (see 5.1.2.3)
  23 + * 3: DELIVERED In that state, the package has been correctly downloaded and is ready to be installed. (see 5.1.2.4)
  24 + * If executing the Install Resource failed, the state remains at DELIVERED.
  25 + * If executing the Install Resource was successful, the state changes from DELIVERED to INSTALLED.
  26 + * After executing the UnInstall Resource, the state changes to INITIAL.
  27 + * 4: INSTALLED
  28 + */
  29 +public enum UpdateStateSw {
  30 + INITIAL(0, "Initial"),
  31 + DOWNLOAD_STARTED(1, "DownloadStarted"),
  32 + DOWNLOADED(2, "Downloaded"),
  33 + DELIVERED(3, "Delivered"),
  34 + INSTALLED(4, "Installed");
  35 +
  36 + public int code;
  37 + public String type;
  38 +
  39 + UpdateStateSw(int code, String type) {
  40 + this.code = code;
  41 + this.type = type;
  42 + }
  43 +
  44 + public static UpdateStateSw fromUpdateStateSwByType(String type) {
  45 + for (UpdateStateSw to : UpdateStateSw.values()) {
  46 + if (to.type.equals(type)) {
  47 + return to;
  48 + }
  49 + }
  50 + throw new IllegalArgumentException(String.format("Unsupported SW State type : %s", type));
  51 + }
  52 +
  53 + public static UpdateStateSw fromUpdateStateSwByCode(int code) {
  54 + for (UpdateStateSw to : UpdateStateSw.values()) {
  55 + if (to.code == code) {
  56 + return to;
  57 + }
  58 + }
  59 + throw new IllegalArgumentException(String.format("Unsupported SW State type : %s", code));
  60 + }
  61 +}
  62 +
... ...
... ... @@ -16,20 +16,13 @@
16 16 package org.thingsboard.server.transport.lwm2m.server.store;
17 17
18 18 import lombok.extern.slf4j.Slf4j;
19   -import org.eclipse.leshan.server.security.EditableSecurityStore;
20 19 import org.eclipse.leshan.server.security.NonUniqueSecurityInfoException;
21 20 import org.eclipse.leshan.server.security.SecurityInfo;
22   -import org.eclipse.leshan.server.security.SecurityStore;
23   -import org.eclipse.leshan.server.security.SecurityStoreListener;
24 21 import org.jetbrains.annotations.Nullable;
25   -import org.springframework.stereotype.Component;
26   -import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
27 22 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
28 23 import org.thingsboard.server.transport.lwm2m.secure.TbLwM2MSecurityInfo;
29   -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil;
30   -import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
31 24
32   -import java.util.Collection;
  25 +import static org.thingsboard.server.transport.lwm2m.server.uplink.LwM2mTypeServer.CLIENT;
33 26
34 27 @Slf4j
35 28 public class TbLwM2mSecurityStore implements TbEditableSecurityStore {
... ... @@ -67,7 +60,7 @@ public class TbLwM2mSecurityStore implements TbEditableSecurityStore {
67 60
68 61 @Nullable
69 62 public SecurityInfo fetchAndPutSecurityInfo(String credentialsId) {
70   - TbLwM2MSecurityInfo securityInfo = validator.getEndpointSecurityInfoByCredentialsId(credentialsId, LwM2mTransportUtil.LwM2mTypeServer.CLIENT);
  63 + TbLwM2MSecurityInfo securityInfo = validator.getEndpointSecurityInfoByCredentialsId(credentialsId, CLIENT);
71 64 try {
72 65 if (securityInfo != null) {
73 66 securityStore.put(securityInfo);
... ...
... ... @@ -37,7 +37,6 @@ import org.eclipse.leshan.server.registration.Registration;
37 37 import org.springframework.context.annotation.Lazy;
38 38 import org.springframework.stereotype.Service;
39 39 import org.thingsboard.common.util.DonAsynchron;
40   -import org.thingsboard.common.util.ThingsBoardExecutors;
41 40 import org.thingsboard.server.cache.ota.OtaPackageDataCache;
42 41 import org.thingsboard.server.common.data.Device;
43 42 import org.thingsboard.server.common.data.DeviceProfile;
... ... @@ -82,6 +81,8 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttrib
82 81 import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteAttributesRequest;
83 82 import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService;
84 83 import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MOtaUpdateService;
  84 +import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy;
  85 +import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy;
85 86 import org.thingsboard.server.transport.lwm2m.server.rpc.LwM2MRpcRequestHandler;
86 87 import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore;
87 88 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
... ... @@ -100,23 +101,22 @@ import java.util.Set;
100 101 import java.util.UUID;
101 102 import java.util.concurrent.ConcurrentHashMap;
102 103 import java.util.concurrent.CountDownLatch;
103   -import java.util.concurrent.ExecutorService;
104 104 import java.util.concurrent.TimeUnit;
105 105 import java.util.stream.Collectors;
106 106
107 107 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
108   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_3_VER_ID;
109   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_5_VER_ID;
110   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_DELIVERY_METHOD;
111   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID;
112   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID;
113   -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_STATE_ID;
114 108 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_ERROR;
115 109 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_INFO;
116 110 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_WARN;
117 111 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertObjectIdToVersionedId;
118 112 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertOtaUpdateValueToString;
119 113 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId;
  114 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_3_VER_ID;
  115 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_5_VER_ID;
  116 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_DELIVERY_METHOD;
  117 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_NAME_ID;
  118 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_RESULT_ID;
  119 +import static org.thingsboard.server.transport.lwm2m.server.ota.DefaultLwM2MOtaUpdateService.FW_STATE_ID;
120 120
121 121
122 122 @Slf4j
... ... @@ -780,6 +780,29 @@ public class DefaultLwM2MUplinkMsgHandler extends LwM2MExecutorAwareService impl
780 780 clients.forEach(client -> sendCancelObserveRequest(targetId, client));
781 781 }
782 782 }
  783 +
  784 + // # 7.1
  785 + // update value in fwInfo
  786 + if (!newProfile.getClientLwM2mSettings().getFwUpdateStrategy().equals(oldProfile.getClientLwM2mSettings().getFwUpdateStrategy())
  787 + || (LwM2MFirmwareUpdateStrategy.OBJ_5_TEMP_URL.code == newProfile.getClientLwM2mSettings().getFwUpdateStrategy() &&
  788 + !newProfile.getClientLwM2mSettings().getFwUpdateRecourse().equals(oldProfile.getClientLwM2mSettings().getFwUpdateRecourse()))) {
  789 + clients.forEach(lwM2MClient -> {
  790 + otaService.onCurrentFirmwareStrategyUpdate(lwM2MClient,
  791 + newProfile.getClientLwM2mSettings().getFwUpdateStrategy(),
  792 + newProfile.getClientLwM2mSettings().getFwUpdateRecourse());
  793 + });
  794 + }
  795 +
  796 + //# 7.2 // update value in swInfo
  797 + if (!newProfile.getClientLwM2mSettings().getSwUpdateStrategy().equals(oldProfile.getClientLwM2mSettings().getSwUpdateStrategy())
  798 + || (LwM2MSoftwareUpdateStrategy.TEMP_URL.code == newProfile.getClientLwM2mSettings().getSwUpdateStrategy() &&
  799 + !newProfile.getClientLwM2mSettings().getSwUpdateRecourse().equals(oldProfile.getClientLwM2mSettings().getSwUpdateRecourse()))) {
  800 + clients.forEach(lwM2MClient -> {
  801 + otaService.onCurrentSoftwareStrategyUpdate(lwM2MClient,
  802 + newProfile.getClientLwM2mSettings().getFwUpdateStrategy(),
  803 + newProfile.getClientLwM2mSettings().getFwUpdateRecourse());
  804 + });
  805 + }
783 806 }
784 807 }
785 808
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.transport.lwm2m.server.uplink;
  17 +
  18 +public enum LwM2mTypeServer {
  19 + BOOTSTRAP(0, "bootstrap"),
  20 + CLIENT(1, "client");
  21 +
  22 + public int code;
  23 + public String type;
  24 +
  25 + LwM2mTypeServer(int code, String type) {
  26 + this.code = code;
  27 + this.type = type;
  28 + }
  29 +
  30 + public static LwM2mTypeServer fromLwM2mTypeServer(String type) {
  31 + for (LwM2mTypeServer sm : LwM2mTypeServer.values()) {
  32 + if (sm.type.equals(type)) {
  33 + return sm;
  34 + }
  35 + }
  36 + throw new IllegalArgumentException(String.format("Unsupported typeServer type : %d", type));
  37 + }
  38 +}
  39 +
... ...
... ... @@ -160,9 +160,9 @@
160 160 <!-- <div fxLayout="column">-->
161 161 <!-- <mat-form-field class="mat-block">-->
162 162 <!-- <mat-label>{{ 'device-profile.lwm2m.client-strategy-label' | translate }}</mat-label>-->
163   -<!-- <mat-select formControlName="clientStrategy"-->
  163 +<!-- <mat-select formControlName="clientOnlyObserveAfterConnect"-->
164 164 <!-- matTooltip="{{ 'device-profile.lwm2m.client-strategy-tip' | translate:-->
165   -<!-- { count: +lwm2mDeviceProfileFormGroup.get('clientStrategy').value } }}"-->
  165 +<!-- { count: +lwm2mDeviceProfileFormGroup.get('clientOnlyObserveAfterConnect').value } }}"-->
166 166 <!-- matTooltipPosition="above">-->
167 167 <!-- <mat-option value=1>{{ 'device-profile.lwm2m.client-strategy-connect' | translate:-->
168 168 <!-- {count: 1} }}</mat-option>-->
... ...
... ... @@ -97,7 +97,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
97 97 binding: [],
98 98 bootstrapServer: [null, Validators.required],
99 99 lwm2mServer: [null, Validators.required],
100   - clientStrategy: [1, []],
  100 + clientOnlyObserveAfterConnect: [1, []],
101 101 fwUpdateStrategy: [1, []],
102 102 swUpdateStrategy: [1, []],
103 103 fwUpdateRecourse: [{value: '', disabled: true}, []],
... ... @@ -216,7 +216,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
216 216 binding: this.configurationValue.bootstrap.servers.binding,
217 217 bootstrapServer: this.configurationValue.bootstrap.bootstrapServer,
218 218 lwm2mServer: this.configurationValue.bootstrap.lwm2mServer,
219   - clientStrategy: this.configurationValue.clientLwM2mSettings.clientStrategy,
  219 + clientOnlyObserveAfterConnect: this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect,
220 220 fwUpdateStrategy: this.configurationValue.clientLwM2mSettings.fwUpdateStrategy || 1,
221 221 swUpdateStrategy: this.configurationValue.clientLwM2mSettings.swUpdateStrategy || 1,
222 222 fwUpdateRecourse: fwResource,
... ... @@ -257,7 +257,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro
257 257 bootstrapServers.defaultMinPeriod = config.defaultMinPeriod;
258 258 bootstrapServers.notifIfDisabled = config.notifIfDisabled;
259 259 bootstrapServers.binding = config.binding;
260   - this.configurationValue.clientLwM2mSettings.clientStrategy = config.clientStrategy;
  260 + this.configurationValue.clientLwM2mSettings.clientOnlyObserveAfterConnect = config.clientOnlyObserveAfterConnect;
261 261 this.configurationValue.clientLwM2mSettings.fwUpdateStrategy = config.fwUpdateStrategy;
262 262 this.configurationValue.clientLwM2mSettings.swUpdateStrategy = config.swUpdateStrategy;
263 263 this.configurationValue.clientLwM2mSettings.fwUpdateRecourse = config.fwUpdateRecourse;
... ...
... ... @@ -168,7 +168,7 @@ export interface Lwm2mProfileConfigModels {
168 168 }
169 169
170 170 export interface ClientLwM2mSettings {
171   - clientStrategy: string;
  171 + clientOnlyObserveAfterConnect: number;
172 172 fwUpdateStrategy: number;
173 173 swUpdateStrategy: number;
174 174 fwUpdateRecourse: string;
... ... @@ -240,7 +240,7 @@ export function getDefaultProfileConfig(hostname?: any): Lwm2mProfileConfigModel
240 240
241 241 function getDefaultProfileClientLwM2mSettingsConfig(): ClientLwM2mSettings {
242 242 return {
243   - clientStrategy: '1',
  243 + clientOnlyObserveAfterConnect: 1,
244 244 fwUpdateStrategy: 1,
245 245 swUpdateStrategy: 1,
246 246 fwUpdateRecourse: DEFAULT_FW_UPDATE_RESOURCE,
... ...