Commit e33420d3a89264b3df099654eea8b3671ca0fbec
Committed by
GitHub
1 parent
9dcb7b9b
Lwm2m: firmwareUpdate (#4516)
* Lwm2m: firmwareUpdate * Lwm2m: firmwareUpdate with merge master * Lwm2m: firmwareUpdate cleaned * Lwm2m: delete Californium.properties * Lwm2m: merge with master
Showing
17 changed files
with
435 additions
and
208 deletions
@@ -185,7 +185,7 @@ public class DefaultTbResourceService implements TbResourceService { | @@ -185,7 +185,7 @@ public class DefaultTbResourceService implements TbResourceService { | ||
185 | instance.setId(0); | 185 | instance.setId(0); |
186 | List<LwM2mResourceObserve> resources = new ArrayList<>(); | 186 | List<LwM2mResourceObserve> resources = new ArrayList<>(); |
187 | obj.resources.forEach((k, v) -> { | 187 | obj.resources.forEach((k, v) -> { |
188 | - if (!v.operations.isExecutable()) { | 188 | + if (v.operations.isReadable()) { |
189 | LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false); | 189 | LwM2mResourceObserve lwM2MResourceObserve = new LwM2mResourceObserve(k, v.name, false, false, false); |
190 | resources.add(lwM2MResourceObserve); | 190 | resources.add(lwM2MResourceObserve); |
191 | } | 191 | } |
@@ -95,8 +95,8 @@ public class DataConstants { | @@ -95,8 +95,8 @@ public class DataConstants { | ||
95 | 95 | ||
96 | //firmware | 96 | //firmware |
97 | //telemetry | 97 | //telemetry |
98 | - public static final String CURRENT_FIRMWARE_TITLE = "cur_fw_title"; | ||
99 | - public static final String CURRENT_FIRMWARE_VERSION = "cur_fw_version"; | 98 | + public static final String CURRENT_FIRMWARE_TITLE = "current_fw_title"; |
99 | + public static final String CURRENT_FIRMWARE_VERSION = "current_fw_version"; | ||
100 | public static final String TARGET_FIRMWARE_TITLE = "target_fw_title"; | 100 | public static final String TARGET_FIRMWARE_TITLE = "target_fw_title"; |
101 | public static final String TARGET_FIRMWARE_VERSION = "target_fw_version"; | 101 | public static final String TARGET_FIRMWARE_VERSION = "target_fw_version"; |
102 | public static final String TARGET_FIRMWARE_TS = "target_fw_ts"; | 102 | public static final String TARGET_FIRMWARE_TS = "target_fw_ts"; |
@@ -55,7 +55,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE | @@ -55,7 +55,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE | ||
55 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; | 55 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; |
56 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; | 56 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; |
57 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; | 57 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; |
58 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig; | 58 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig; |
59 | 59 | ||
60 | @Slf4j | 60 | @Slf4j |
61 | @Component | 61 | @Component |
@@ -93,7 +93,6 @@ public class LwM2MTransportBootstrapServerConfiguration { | @@ -93,7 +93,6 @@ public class LwM2MTransportBootstrapServerConfiguration { | ||
93 | builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort)); | 93 | builder.setCoapConfig(getCoapConfig(bootstrapPortNoSec, bootstrapSecurePort)); |
94 | 94 | ||
95 | /** Define model provider (Create Models )*/ | 95 | /** Define model provider (Create Models )*/ |
96 | -// builder.setModel(new StaticModel(contextS.getLwM2MTransportConfigServer().getModelsValueCommon())); | ||
97 | 96 | ||
98 | /** Create credentials */ | 97 | /** Create credentials */ |
99 | this.setServerWithCredentials(builder); | 98 | this.setServerWithCredentials(builder); |
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; | ||
17 | + | ||
18 | +import org.eclipse.californium.core.network.config.NetworkConfig; | ||
19 | + | ||
20 | +public class LwM2mNetworkConfig { | ||
21 | + | ||
22 | + public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort) { | ||
23 | + NetworkConfig coapConfig = new NetworkConfig(); | ||
24 | + coapConfig.setInt(NetworkConfig.Keys.COAP_PORT,serverPortNoSec); | ||
25 | + coapConfig.setInt(NetworkConfig.Keys.COAP_SECURE_PORT,serverSecurePort); | ||
26 | + /** | ||
27 | + * Example:Property for large packet: | ||
28 | + * #NetworkConfig config = new NetworkConfig(); | ||
29 | + * #config.setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE,32); | ||
30 | + * #config.setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE,32); | ||
31 | + * #config.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE,2048); | ||
32 | + * #config.setInt(NetworkConfig.Keys.MAX_RETRANSMIT,3); | ||
33 | + * #config.setInt(NetworkConfig.Keys.MAX_TRANSMIT_WAIT,120000); | ||
34 | + */ | ||
35 | + | ||
36 | + /** | ||
37 | + * Property to indicate if the response should always include the Block2 option \ | ||
38 | + * when client request early blockwise negociation but the response can be sent on one packet. | ||
39 | + * - value of false indicate that the server will respond without block2 option if no further blocks are required. | ||
40 | + * - value of true indicate that the server will response with block2 option event if no further blocks are required. | ||
41 | + * CoAP client will try to use block mode | ||
42 | + * or adapt the block size when receiving a 4.13 Entity too large response code | ||
43 | + */ | ||
44 | + coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_STRICT_BLOCK2_OPTION, true); | ||
45 | + /*** | ||
46 | + * Property to indicate if the response should always include the Block2 option \ | ||
47 | + * when client request early blockwise negociation but the response can be sent on one packet. | ||
48 | + * - value of false indicate that the server will respond without block2 option if no further blocks are required. | ||
49 | + * - value of true indicate that the server will response with block2 option event if no further blocks are required. | ||
50 | + */ | ||
51 | + coapConfig.setBoolean(NetworkConfig.Keys.BLOCKWISE_ENTITY_TOO_LARGE_AUTO_FAILOVER, true); | ||
52 | + | ||
53 | + coapConfig.setInt(NetworkConfig.Keys.BLOCKWISE_STATUS_LIFETIME, 300000); | ||
54 | + /** | ||
55 | + * !!! REQUEST_ENTITY_TOO_LARGE CODE=4.13 | ||
56 | + * The maximum size of a resource body (in bytes) that will be accepted | ||
57 | + * as the payload of a POST/PUT or the response to a GET request in a | ||
58 | + * transparent> blockwise transfer. | ||
59 | + * This option serves as a safeguard against excessive memory | ||
60 | + * consumption when many resources contain large bodies that cannot be | ||
61 | + * transferred in a single CoAP message. This option has no impact on | ||
62 | + * *manually* managed blockwise transfers in which the blocks are handled individually. | ||
63 | + * Note that this option does not prevent local clients or resource | ||
64 | + * implementations from sending large bodies as part of a request or response to a peer. | ||
65 | + * The default value of this property is DEFAULT_MAX_RESOURCE_BODY_SIZE = 8192 | ||
66 | + * A value of {@code 0} turns off transparent handling of blockwise transfers altogether. | ||
67 | + */ | ||
68 | +// coapConfig.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE, 8192); | ||
69 | + coapConfig.setInt(NetworkConfig.Keys.MAX_RESOURCE_BODY_SIZE, 16384); | ||
70 | + /** | ||
71 | + * The default DTLS response matcher. | ||
72 | + * Supported values are STRICT, RELAXED, or PRINCIPAL. | ||
73 | + * The default value is STRICT. | ||
74 | + * Create new instance of udp endpoint context matcher. | ||
75 | + * Params: | ||
76 | + * checkAddress | ||
77 | + * – true with address check, (STRICT, UDP) | ||
78 | + * - false, without | ||
79 | + */ | ||
80 | + coapConfig.setString(NetworkConfig.Keys.RESPONSE_MATCHING, "STRICT"); | ||
81 | + /** | ||
82 | + * https://tools.ietf.org/html/rfc7959#section-2.9.3 | ||
83 | + * The block size (number of bytes) to use when doing a blockwise transfer. \ | ||
84 | + * This value serves as the upper limit for block size in blockwise transfers | ||
85 | + */ | ||
86 | + coapConfig.setInt(NetworkConfig.Keys.PREFERRED_BLOCK_SIZE, 512); | ||
87 | + /** | ||
88 | + * The maximum payload size (in bytes) that can be transferred in a | ||
89 | + * single message, i.e. without requiring a blockwise transfer. | ||
90 | + * NB: this value MUST be adapted to the maximum message size supported by the transport layer. | ||
91 | + * In particular, this value cannot exceed the network's MTU if UDP is used as the transport protocol | ||
92 | + * DEFAULT_VALUE = 1024 | ||
93 | + */ | ||
94 | + coapConfig.setInt(NetworkConfig.Keys.MAX_MESSAGE_SIZE, 512); | ||
95 | + | ||
96 | + coapConfig.setInt(NetworkConfig.Keys.MAX_RETRANSMIT, 4); | ||
97 | + | ||
98 | + return coapConfig; | ||
99 | + } | ||
100 | +} |
@@ -26,6 +26,7 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; | @@ -26,6 +26,7 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; | ||
26 | 26 | ||
27 | import java.util.Collection; | 27 | import java.util.Collection; |
28 | 28 | ||
29 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | ||
29 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; | 30 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; |
30 | 31 | ||
31 | @Slf4j | 32 | @Slf4j |
@@ -85,17 +86,19 @@ public class LwM2mServerListener { | @@ -85,17 +86,19 @@ public class LwM2mServerListener { | ||
85 | 86 | ||
86 | @Override | 87 | @Override |
87 | public void cancelled(Observation observation) { | 88 | public void cancelled(Observation observation) { |
88 | - log.info("Received notification cancelled from [{}] ", observation.getPath()); | 89 | + String msg = String.format("%s: Cancel Observation %s.", LOG_LW2M_INFO, observation.getPath()); |
90 | + service.sendLogsToThingsboard(msg, observation.getRegistrationId()); | ||
91 | + log.trace(msg); | ||
89 | } | 92 | } |
90 | 93 | ||
91 | @Override | 94 | @Override |
92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { | 95 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
93 | if (registration != null) { | 96 | if (registration != null) { |
94 | try { | 97 | try { |
95 | - service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), | 98 | + service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), |
96 | registration), response, null); | 99 | registration), response, null); |
97 | } catch (Exception e) { | 100 | } catch (Exception e) { |
98 | - log.error("[{}] onResponse", e.toString()); | 101 | + log.error("Observation/Read onResponse", e); |
99 | 102 | ||
100 | } | 103 | } |
101 | } | 104 | } |
@@ -108,7 +111,10 @@ public class LwM2mServerListener { | @@ -108,7 +111,10 @@ public class LwM2mServerListener { | ||
108 | 111 | ||
109 | @Override | 112 | @Override |
110 | public void newObservation(Observation observation, Registration registration) { | 113 | public void newObservation(Observation observation, Registration registration) { |
111 | - log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); | 114 | + String msg = String.format("%s: Successful start newObservation %s.", LOG_LW2M_INFO, |
115 | + observation.getPath()); | ||
116 | + service.sendLogsToThingsboard(msg, registration.getId()); | ||
117 | + log.trace(msg); | ||
112 | } | 118 | } |
113 | }; | 119 | }; |
114 | 120 |
@@ -25,7 +25,6 @@ import com.google.gson.JsonSyntaxException; | @@ -25,7 +25,6 @@ import com.google.gson.JsonSyntaxException; | ||
25 | import com.google.gson.reflect.TypeToken; | 25 | import com.google.gson.reflect.TypeToken; |
26 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
27 | import org.apache.commons.lang3.StringUtils; | 27 | import org.apache.commons.lang3.StringUtils; |
28 | -import org.eclipse.californium.core.network.config.NetworkConfig; | ||
29 | import org.eclipse.leshan.core.attributes.Attribute; | 28 | import org.eclipse.leshan.core.attributes.Attribute; |
30 | import org.eclipse.leshan.core.attributes.AttributeSet; | 29 | import org.eclipse.leshan.core.attributes.AttributeSet; |
31 | import org.eclipse.leshan.core.model.ObjectModel; | 30 | import org.eclipse.leshan.core.model.ObjectModel; |
@@ -40,7 +39,6 @@ import org.eclipse.leshan.core.node.codec.CodecException; | @@ -40,7 +39,6 @@ import org.eclipse.leshan.core.node.codec.CodecException; | ||
40 | import org.eclipse.leshan.core.request.DownlinkRequest; | 39 | import org.eclipse.leshan.core.request.DownlinkRequest; |
41 | import org.eclipse.leshan.core.request.WriteAttributesRequest; | 40 | import org.eclipse.leshan.core.request.WriteAttributesRequest; |
42 | import org.eclipse.leshan.core.util.Hex; | 41 | import org.eclipse.leshan.core.util.Hex; |
43 | -import org.eclipse.leshan.server.californium.LeshanServerBuilder; | ||
44 | import org.eclipse.leshan.server.registration.Registration; | 42 | import org.eclipse.leshan.server.registration.Registration; |
45 | import org.nustaq.serialization.FSTConfiguration; | 43 | import org.nustaq.serialization.FSTConfiguration; |
46 | import org.thingsboard.server.common.data.DeviceProfile; | 44 | import org.thingsboard.server.common.data.DeviceProfile; |
@@ -50,7 +48,6 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; | @@ -50,7 +48,6 @@ import org.thingsboard.server.common.transport.TransportServiceCallback; | ||
50 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 48 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
51 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; | 49 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
52 | 50 | ||
53 | -import java.io.File; | ||
54 | import java.io.IOException; | 51 | import java.io.IOException; |
55 | import java.util.ArrayList; | 52 | import java.util.ArrayList; |
56 | import java.util.Arrays; | 53 | import java.util.Arrays; |
@@ -72,7 +69,6 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | @@ -72,7 +69,6 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | ||
72 | @Slf4j | 69 | @Slf4j |
73 | public class LwM2mTransportHandler { | 70 | public class LwM2mTransportHandler { |
74 | 71 | ||
75 | - // public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me"; | ||
76 | public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0"; | 72 | public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0"; |
77 | public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; | 73 | public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; |
78 | public static final String BOOTSTRAP = "bootstrap"; | 74 | public static final String BOOTSTRAP = "bootstrap"; |
@@ -85,19 +81,12 @@ public class LwM2mTransportHandler { | @@ -85,19 +81,12 @@ public class LwM2mTransportHandler { | ||
85 | public static final String KEY_NAME = "keyName"; | 81 | public static final String KEY_NAME = "keyName"; |
86 | public static final String OBSERVE_LWM2M = "observe"; | 82 | public static final String OBSERVE_LWM2M = "observe"; |
87 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; | 83 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; |
88 | -// public static final String RESOURCE_VALUE = "resValue"; | ||
89 | -// public static final String RESOURCE_TYPE = "resType"; | ||
90 | 84 | ||
91 | private static final String REQUEST = "/request"; | 85 | private static final String REQUEST = "/request"; |
92 | - // private static final String RESPONSE = "/response"; | ||
93 | private static final String ATTRIBUTES = "/" + ATTRIBUTE; | 86 | private static final String ATTRIBUTES = "/" + ATTRIBUTE; |
94 | public static final String TELEMETRIES = "/" + TELEMETRY; | 87 | public static final String TELEMETRIES = "/" + TELEMETRY; |
95 | - // public static final String ATTRIBUTES_RESPONSE = ATTRIBUTES + RESPONSE; | ||
96 | public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST; | 88 | public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST; |
97 | - // public static final String DEVICE_ATTRIBUTES_RESPONSE = ATTRIBUTES_RESPONSE + "/"; | ||
98 | public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/"; | 89 | public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/"; |
99 | -// public static final String DEVICE_ATTRIBUTES_TOPIC = BASE_DEVICE_API_TOPIC + ATTRIBUTES; | ||
100 | -// public static final String DEVICE_TELEMETRY_TOPIC = BASE_DEVICE_API_TOPIC + TELEMETRIES; | ||
101 | 90 | ||
102 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms | 91 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms |
103 | 92 | ||
@@ -112,6 +101,11 @@ public class LwM2mTransportHandler { | @@ -112,6 +101,11 @@ public class LwM2mTransportHandler { | ||
112 | 101 | ||
113 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; | 102 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; |
114 | 103 | ||
104 | + public static final Integer FR_OBJECT_ID = 5; | ||
105 | + public static final Integer FR_RESOURCE_VER_ID = 7; | ||
106 | + public static final String FR_PATH_RESOURCE_VER_ID = LWM2M_SEPARATOR_PATH + FR_OBJECT_ID + LWM2M_SEPARATOR_PATH | ||
107 | + + "0" + LWM2M_SEPARATOR_PATH + FR_RESOURCE_VER_ID; | ||
108 | + | ||
115 | public enum LwM2mTypeServer { | 109 | public enum LwM2mTypeServer { |
116 | BOOTSTRAP(0, "bootstrap"), | 110 | BOOTSTRAP(0, "bootstrap"), |
117 | CLIENT(1, "client"); | 111 | CLIENT(1, "client"); |
@@ -168,6 +162,8 @@ public class LwM2mTransportHandler { | @@ -168,6 +162,8 @@ public class LwM2mTransportHandler { | ||
168 | WRITE_ATTRIBUTES(8, "WriteAttributes"), | 162 | WRITE_ATTRIBUTES(8, "WriteAttributes"), |
169 | DELETE(9, "Delete"); | 163 | DELETE(9, "Delete"); |
170 | 164 | ||
165 | +// READ_INFO_FW(10, "ReadInfoFirmware"); | ||
166 | + | ||
171 | public int code; | 167 | public int code; |
172 | public String type; | 168 | public String type; |
173 | 169 | ||
@@ -190,21 +186,6 @@ public class LwM2mTransportHandler { | @@ -190,21 +186,6 @@ public class LwM2mTransportHandler { | ||
190 | public static final String SERVICE_CHANNEL = "SERVICE"; | 186 | public static final String SERVICE_CHANNEL = "SERVICE"; |
191 | public static final String RESPONSE_CHANNEL = "RESP"; | 187 | public static final String RESPONSE_CHANNEL = "RESP"; |
192 | 188 | ||
193 | - public static NetworkConfig getCoapConfig(Integer serverPortNoSec, Integer serverSecurePort) { | ||
194 | - NetworkConfig coapConfig; | ||
195 | - File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME); | ||
196 | - if (configFile.isFile()) { | ||
197 | - coapConfig = new NetworkConfig(); | ||
198 | - coapConfig.load(configFile); | ||
199 | - } else { | ||
200 | - coapConfig = LeshanServerBuilder.createDefaultNetworkConfig(); | ||
201 | - coapConfig.store(configFile); | ||
202 | - } | ||
203 | - coapConfig.setString("COAP_PORT", Integer.toString(serverPortNoSec)); | ||
204 | - coapConfig.setString("COAP_SECURE_PORT", Integer.toString(serverSecurePort)); | ||
205 | - return coapConfig; | ||
206 | - } | ||
207 | - | ||
208 | public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException { | 189 | public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath resourcePath) throws CodecException { |
209 | switch (type) { | 190 | switch (type) { |
210 | case BOOLEAN: | 191 | case BOOLEAN: |
@@ -67,6 +67,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; | @@ -67,6 +67,7 @@ import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; | ||
67 | import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST; | 67 | import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST; |
68 | import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND; | 68 | import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND; |
69 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT; | 69 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT; |
70 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.FR_PATH_RESOURCE_VER_ID; | ||
70 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; | 71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | 72 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; |
72 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; | 73 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; |
@@ -125,7 +126,6 @@ public class LwM2mTransportRequest { | @@ -125,7 +126,6 @@ public class LwM2mTransportRequest { | ||
125 | public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, | 126 | public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, |
126 | String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { | 127 | String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { |
127 | try { | 128 | try { |
128 | - | ||
129 | String target = convertPathFromIdVerToObjectId(targetIdVer); | 129 | String target = convertPathFromIdVerToObjectId(targetIdVer); |
130 | DownlinkRequest request = null; | 130 | DownlinkRequest request = null; |
131 | ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; | 131 | ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; |
@@ -145,11 +145,11 @@ public class LwM2mTransportRequest { | @@ -145,11 +145,11 @@ public class LwM2mTransportRequest { | ||
145 | break; | 145 | break; |
146 | case OBSERVE: | 146 | case OBSERVE: |
147 | if (resultIds.isResource()) { | 147 | if (resultIds.isResource()) { |
148 | - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); | 148 | + request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); |
149 | } else if (resultIds.isObjectInstance()) { | 149 | } else if (resultIds.isObjectInstance()) { |
150 | - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId()); | 150 | + request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId()); |
151 | } else if (resultIds.getObjectId() >= 0) { | 151 | } else if (resultIds.getObjectId() >= 0) { |
152 | - request = new ObserveRequest(resultIds.getObjectId()); | 152 | + request = new ObserveRequest(contentFormat, resultIds.getObjectId()); |
153 | } | 153 | } |
154 | break; | 154 | break; |
155 | case OBSERVE_CANCEL: | 155 | case OBSERVE_CANCEL: |
@@ -171,8 +171,6 @@ public class LwM2mTransportRequest { | @@ -171,8 +171,6 @@ public class LwM2mTransportRequest { | ||
171 | break; | 171 | break; |
172 | case WRITE_REPLACE: | 172 | case WRITE_REPLACE: |
173 | // Request to write a <b>String Single-Instance Resource</b> using the TLV content format. | 173 | // Request to write a <b>String Single-Instance Resource</b> using the TLV content format. |
174 | -// resource = lwM2MClient.getResourceModel(targetIdVer); | ||
175 | -// if (contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { | ||
176 | resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() | 174 | resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
177 | .getModelProvider()); | 175 | .getModelProvider()); |
178 | if (contentFormat.equals(ContentFormat.TLV)) { | 176 | if (contentFormat.equals(ContentFormat.TLV)) { |
@@ -181,7 +179,6 @@ public class LwM2mTransportRequest { | @@ -181,7 +179,6 @@ public class LwM2mTransportRequest { | ||
181 | registration, rpcRequest); | 179 | registration, rpcRequest); |
182 | } | 180 | } |
183 | // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON) | 181 | // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON) |
184 | -// else if (!contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { | ||
185 | else if (!contentFormat.equals(ContentFormat.TLV)) { | 182 | else if (!contentFormat.equals(ContentFormat.TLV)) { |
186 | request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), | 183 | request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), |
187 | resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type, | 184 | resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type, |
@@ -215,13 +212,16 @@ public class LwM2mTransportRequest { | @@ -215,13 +212,16 @@ public class LwM2mTransportRequest { | ||
215 | long finalTimeoutInMs = timeoutInMs; | 212 | long finalTimeoutInMs = timeoutInMs; |
216 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, rpcRequest)); | 213 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, rpcRequest)); |
217 | } catch (Exception e) { | 214 | } catch (Exception e) { |
218 | - log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper, e); | 215 | + log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); |
216 | + } | ||
217 | + } else if (OBSERVE_CANCEL == typeOper) { | ||
218 | + log.trace("[{}], [{}] - [{}] SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); | ||
219 | + if (rpcRequest != null) { | ||
220 | + rpcRequest.setInfoMsg(null); | ||
221 | + serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, null); | ||
219 | } | 222 | } |
220 | - } else if (OBSERVE_CANCEL == typeOper && rpcRequest != null) { | ||
221 | - rpcRequest.setInfoMsg(null); | ||
222 | - serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, null); | ||
223 | } else { | 223 | } else { |
224 | - log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper, targetIdVer); | 224 | + log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); |
225 | if (rpcRequest != null) { | 225 | if (rpcRequest != null) { |
226 | String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; | 226 | String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; |
227 | serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | 227 | serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); |
@@ -236,8 +236,8 @@ public class LwM2mTransportRequest { | @@ -236,8 +236,8 @@ public class LwM2mTransportRequest { | ||
236 | Set<String> observationPaths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); | 236 | Set<String> observationPaths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); |
237 | String msg = String.format("%s: type operation %s observation paths - %s", LOG_LW2M_INFO, | 237 | String msg = String.format("%s: type operation %s observation paths - %s", LOG_LW2M_INFO, |
238 | OBSERVE_READ_ALL.type, observationPaths); | 238 | OBSERVE_READ_ALL.type, observationPaths); |
239 | - serviceImpl.sendLogsToThingsboard(msg, registration); | ||
240 | - log.info("[{}], [{}]", registration.getEndpoint(), msg); | 239 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); |
240 | + log.trace("[{}] [{}], [{}]", typeOper.name(), registration.getEndpoint(), msg); | ||
241 | if (rpcRequest != null) { | 241 | if (rpcRequest != null) { |
242 | String valueMsg = String.format("Observation paths - %s", observationPaths); | 242 | String valueMsg = String.format("Observation paths - %s", observationPaths); |
243 | serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); | 243 | serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); |
@@ -246,7 +246,7 @@ public class LwM2mTransportRequest { | @@ -246,7 +246,7 @@ public class LwM2mTransportRequest { | ||
246 | } catch (Exception e) { | 246 | } catch (Exception e) { |
247 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, | 247 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, |
248 | typeOper.name(), e.getMessage()); | 248 | typeOper.name(), e.getMessage()); |
249 | - serviceImpl.sendLogsToThingsboard(msg, registration); | 249 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); |
250 | throw new Exception(e); | 250 | throw new Exception(e); |
251 | } | 251 | } |
252 | } | 252 | } |
@@ -261,45 +261,53 @@ public class LwM2mTransportRequest { | @@ -261,45 +261,53 @@ public class LwM2mTransportRequest { | ||
261 | private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { | 261 | private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { |
262 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { | 262 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { |
263 | if (!lwM2MClient.isInit()) { | 263 | if (!lwM2MClient.isInit()) { |
264 | - lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | 264 | + lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
265 | } | 265 | } |
266 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { | 266 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { |
267 | this.handleResponse(registration, request.getPath().toString(), response, request, rpcRequest); | 267 | this.handleResponse(registration, request.getPath().toString(), response, request, rpcRequest); |
268 | - if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) { | ||
269 | - LwM2mNode node = ((WriteRequest) request).getNode(); | ||
270 | - Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), | ||
271 | - ((LwM2mSingleResource) node).getType(), ResourceModel.Type.STRING, request.getPath()); | ||
272 | - String msg = String.format("%s: sendRequest Replace: CoapCde - %s Lwm2m code - %d name - %s Resource path - %s value - %s SendRequest to Client", | ||
273 | - LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), | ||
274 | - response.getCode().getName(), request.getPath().toString(), value); | ||
275 | - serviceImpl.sendLogsToThingsboard(msg, registration); | ||
276 | - log.info("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), | ||
277 | - ((Response) response.getCoapResponse()).getCode(), response.getCode(), | ||
278 | - request.getPath().toString(), value); | ||
279 | - serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO); | ||
280 | - } | ||
281 | } else { | 268 | } else { |
282 | - String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR, | 269 | + String msg = String.format("%s: SendRequest %s: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s", LOG_LW2M_ERROR, request.getClass().getName().toString(), |
283 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); | 270 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); |
284 | - serviceImpl.sendLogsToThingsboard(msg, registration); | ||
285 | - log.error("[{}], [{}] - [{}] [{}] error SendRequest", registration.getEndpoint(), ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); | 271 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); |
272 | + log.error("[{}] [{}], [{}] - [{}] [{}] error SendRequest", request.getClass().getName().toString(), registration.getEndpoint(), | ||
273 | + ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); | ||
274 | + if (!lwM2MClient.isInit()) { | ||
275 | + lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | ||
276 | + } | ||
286 | if (rpcRequest != null) { | 277 | if (rpcRequest != null) { |
287 | serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); | 278 | serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); |
288 | } | 279 | } |
280 | + /** Not Found | ||
281 | + * set setClient_fw_version = empty | ||
282 | + **/ | ||
283 | + if (FR_PATH_RESOURCE_VER_ID.equals(request.getPath().toString()) && lwM2MClient.isUpdateFw()) { | ||
284 | + lwM2MClient.setUpdateFw(false); | ||
285 | + lwM2MClient.getFrUpdate().setClientFwVersion(""); | ||
286 | + log.warn("updateFirmwareClient1"); | ||
287 | + serviceImpl.updateFirmwareClient(lwM2MClient); | ||
288 | + } | ||
289 | } | 289 | } |
290 | }, e -> { | 290 | }, e -> { |
291 | + /** version == null | ||
292 | + * set setClient_fw_version = empty | ||
293 | + **/ | ||
294 | + if (FR_PATH_RESOURCE_VER_ID.equals(request.getPath().toString()) && lwM2MClient.isUpdateFw()) { | ||
295 | + lwM2MClient.setUpdateFw(false); | ||
296 | + lwM2MClient.getFrUpdate().setClientFwVersion(""); | ||
297 | + log.warn("updateFirmwareClient2"); | ||
298 | + serviceImpl.updateFirmwareClient(lwM2MClient); | ||
299 | + } | ||
291 | if (!lwM2MClient.isInit()) { | 300 | if (!lwM2MClient.isInit()) { |
292 | - lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | 301 | + lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
293 | } | 302 | } |
294 | - String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", | ||
295 | - LOG_LW2M_ERROR, request.getPath().toString(), e.getMessage()); | ||
296 | - serviceImpl.sendLogsToThingsboard(msg, registration); | ||
297 | - log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString()); | 303 | + String msg = String.format("%s: SendRequest %s: Resource path - %s msg error - %s", |
304 | + LOG_LW2M_ERROR, request.getClass().getName().toString(), request.getPath().toString(), e.getMessage()); | ||
305 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); | ||
306 | + log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); | ||
298 | if (rpcRequest != null) { | 307 | if (rpcRequest != null) { |
299 | serviceImpl.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); | 308 | serviceImpl.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); |
300 | } | 309 | } |
301 | }); | 310 | }); |
302 | - | ||
303 | } | 311 | } |
304 | 312 | ||
305 | private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, | 313 | private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, |
@@ -323,7 +331,9 @@ public class LwM2mTransportRequest { | @@ -323,7 +331,9 @@ public class LwM2mTransportRequest { | ||
323 | Date date = new Date(Long.decode(value.toString())); | 331 | Date date = new Date(Long.decode(value.toString())); |
324 | return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, date) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, date); | 332 | return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, date) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, date); |
325 | case OPAQUE: // byte[] value, base64 | 333 | case OPAQUE: // byte[] value, base64 |
326 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())); | 334 | + byte[] valueRequest = value instanceof byte[] ? (byte[]) value : Hex.decodeHex(value.toString().toCharArray()); |
335 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, valueRequest) : | ||
336 | + new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueRequest); | ||
327 | default: | 337 | default: |
328 | } | 338 | } |
329 | } | 339 | } |
@@ -337,7 +347,7 @@ public class LwM2mTransportRequest { | @@ -337,7 +347,7 @@ public class LwM2mTransportRequest { | ||
337 | String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; | 347 | String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; |
338 | String msg = String.format(LOG_LW2M_ERROR + ": NumberFormatException: Resource path - %s type - %s value - %s msg error - %s SendRequest to Client", | 348 | String msg = String.format(LOG_LW2M_ERROR + ": NumberFormatException: Resource path - %s type - %s value - %s msg error - %s SendRequest to Client", |
339 | patn, type, value, e.toString()); | 349 | patn, type, value, e.toString()); |
340 | - serviceImpl.sendLogsToThingsboard(msg, registration); | 350 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); |
341 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); | 351 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); |
342 | if (rpcRequest != null) { | 352 | if (rpcRequest != null) { |
343 | String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); | 353 | String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); |
@@ -369,7 +379,7 @@ public class LwM2mTransportRequest { | @@ -369,7 +379,7 @@ public class LwM2mTransportRequest { | ||
369 | DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | 379 | DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { |
370 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); | 380 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); |
371 | if (response instanceof ReadResponse) { | 381 | if (response instanceof ReadResponse) { |
372 | - serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); | 382 | + serviceImpl.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); |
373 | } else if (response instanceof CancelObservationResponse) { | 383 | } else if (response instanceof CancelObservationResponse) { |
374 | log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); | 384 | log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); |
375 | 385 | ||
@@ -389,14 +399,33 @@ public class LwM2mTransportRequest { | @@ -389,14 +399,33 @@ public class LwM2mTransportRequest { | ||
389 | } else if (response instanceof WriteAttributesResponse) { | 399 | } else if (response instanceof WriteAttributesResponse) { |
390 | log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); | 400 | log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); |
391 | } else if (response instanceof WriteResponse) { | 401 | } else if (response instanceof WriteResponse) { |
392 | - log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); | 402 | + log.info("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response); |
403 | + this.infoWriteResponse(registration, response, request); | ||
393 | serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); | 404 | serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); |
394 | } | 405 | } |
395 | - if (rpcRequest != null && (response instanceof ExecuteResponse | ||
396 | - || response instanceof WriteAttributesResponse | ||
397 | - || response instanceof DeleteResponse)) { | ||
398 | - rpcRequest.setInfoMsg(null); | ||
399 | - serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, null); | 406 | + if (rpcRequest != null) { |
407 | + if (response instanceof ExecuteResponse | ||
408 | + || response instanceof WriteAttributesResponse | ||
409 | + || response instanceof DeleteResponse) { | ||
410 | + rpcRequest.setInfoMsg(null); | ||
411 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, null); | ||
412 | + } else if (response instanceof WriteResponse) { | ||
413 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO); | ||
414 | + } | ||
400 | } | 415 | } |
401 | } | 416 | } |
417 | + | ||
418 | + private void infoWriteResponse(Registration registration, LwM2mResponse response, | ||
419 | + DownlinkRequest request) { | ||
420 | + LwM2mNode node = ((WriteRequest) request).getNode(); | ||
421 | + Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), | ||
422 | + ((LwM2mSingleResource) node).getType(), ResourceModel.Type.STRING, request.getPath()); | ||
423 | + String msg = String.format("%s: Update finished successfully: CoapCde - %s Lwm2m code - %d name - %s Resource path - %s value - %s", | ||
424 | + LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), | ||
425 | + response.getCode().getName(), request.getPath().toString(), value); | ||
426 | + serviceImpl.sendLogsToThingsboard(msg, registration.getId()); | ||
427 | + log.warn("[{}] [{}] [{}] - [{}] [{}] Update finished successfully: [{}]", request.getClass().getName().toString(), registration.getEndpoint(), | ||
428 | + ((Response) response.getCoapResponse()).getCode(), response.getCode(), | ||
429 | + request.getPath().toString(), value); | ||
430 | + } | ||
402 | } | 431 | } |
@@ -16,6 +16,8 @@ | @@ -16,6 +16,8 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m.server; | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | +import org.eclipse.californium.core.network.config.NetworkConfig; | ||
20 | +import org.eclipse.californium.core.network.stack.BlockwiseLayer; | ||
19 | import org.eclipse.californium.scandium.config.DtlsConnectorConfig; | 21 | import org.eclipse.californium.scandium.config.DtlsConnectorConfig; |
20 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; | 22 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder; |
21 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; | 23 | import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder; |
@@ -57,7 +59,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE | @@ -57,7 +59,7 @@ import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE | ||
57 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; | 59 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; |
58 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; | 60 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CBC_SHA256; |
59 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; | 61 | import static org.eclipse.californium.scandium.dtls.cipher.CipherSuite.TLS_PSK_WITH_AES_128_CCM_8; |
60 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getCoapConfig; | 62 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mNetworkConfig.getCoapConfig; |
61 | 63 | ||
62 | @Slf4j | 64 | @Slf4j |
63 | @Component | 65 | @Component |
@@ -92,7 +94,10 @@ public class LwM2mTransportServerConfiguration { | @@ -92,7 +94,10 @@ public class LwM2mTransportServerConfiguration { | ||
92 | /** Use a magic converter to support bad type send by the UI. */ | 94 | /** Use a magic converter to support bad type send by the UI. */ |
93 | builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance())); | 95 | builder.setEncoder(new DefaultLwM2mNodeEncoder(LwM2mValueConverterImpl.getInstance())); |
94 | 96 | ||
97 | + | ||
95 | /** Create CoAP Config */ | 98 | /** Create CoAP Config */ |
99 | + NetworkConfig networkConfig = getCoapConfig(serverPortNoSec, serverSecurePort); | ||
100 | + BlockwiseLayer blockwiseLayer = new BlockwiseLayer(networkConfig); | ||
96 | builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort)); | 101 | builder.setCoapConfig(getCoapConfig(serverPortNoSec, serverSecurePort)); |
97 | 102 | ||
98 | /** Define model provider (Create Models )*/ | 103 | /** Define model provider (Create Models )*/ |
@@ -110,6 +115,7 @@ public class LwM2mTransportServerConfiguration { | @@ -110,6 +115,7 @@ public class LwM2mTransportServerConfiguration { | ||
110 | 115 | ||
111 | /** Create DTLS Config */ | 116 | /** Create DTLS Config */ |
112 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); | 117 | DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder(); |
118 | + dtlsConfig.setServerOnly(true); | ||
113 | dtlsConfig.setRecommendedSupportedGroupsOnly(this.context.getLwM2MTransportConfigServer().isRecommendedSupportedGroups()); | 119 | dtlsConfig.setRecommendedSupportedGroupsOnly(this.context.getLwM2MTransportConfigServer().isRecommendedSupportedGroups()); |
114 | dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getLwM2MTransportConfigServer().isRecommendedCiphers()); | 120 | dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getLwM2MTransportConfigServer().isRecommendedCiphers()); |
115 | if (this.pskMode) { | 121 | if (this.pskMode) { |
@@ -39,7 +39,7 @@ public interface LwM2mTransportService extends TbTransportService { | @@ -39,7 +39,7 @@ public interface LwM2mTransportService extends TbTransportService { | ||
39 | 39 | ||
40 | void setCancelObservations(Registration registration); | 40 | void setCancelObservations(Registration registration); |
41 | 41 | ||
42 | - void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest); | 42 | + void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest); |
43 | 43 | ||
44 | void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); | 44 | void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); |
45 | 45 | ||
@@ -60,6 +60,4 @@ public interface LwM2mTransportService extends TbTransportService { | @@ -60,6 +60,4 @@ public interface LwM2mTransportService extends TbTransportService { | ||
60 | void doTrigger(Registration registration, String path); | 60 | void doTrigger(Registration registration, String path); |
61 | 61 | ||
62 | void doDisconnect(TransportProtos.SessionInfoProto sessionInfo); | 62 | void doDisconnect(TransportProtos.SessionInfoProto sessionInfo); |
63 | - | ||
64 | - | ||
65 | } | 63 | } |
@@ -38,10 +38,12 @@ import org.eclipse.leshan.server.registration.Registration; | @@ -38,10 +38,12 @@ import org.eclipse.leshan.server.registration.Registration; | ||
38 | import org.springframework.context.annotation.Lazy; | 38 | import org.springframework.context.annotation.Lazy; |
39 | import org.springframework.stereotype.Service; | 39 | import org.springframework.stereotype.Service; |
40 | import org.thingsboard.common.util.JacksonUtil; | 40 | import org.thingsboard.common.util.JacksonUtil; |
41 | +import org.thingsboard.server.cache.firmware.FirmwareDataCache; | ||
41 | import org.thingsboard.server.common.data.Device; | 42 | import org.thingsboard.server.common.data.Device; |
42 | import org.thingsboard.server.common.data.DeviceProfile; | 43 | import org.thingsboard.server.common.data.DeviceProfile; |
43 | -import org.thingsboard.server.common.data.DeviceTransportType; | 44 | +import org.thingsboard.server.common.data.id.FirmwareId; |
44 | import org.thingsboard.server.common.transport.TransportService; | 45 | import org.thingsboard.server.common.transport.TransportService; |
46 | +import org.thingsboard.server.common.transport.TransportServiceCallback; | ||
45 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 47 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
46 | import org.thingsboard.server.common.transport.service.DefaultTransportService; | 48 | import org.thingsboard.server.common.transport.service.DefaultTransportService; |
47 | import org.thingsboard.server.gen.transport.TransportProtos; | 49 | import org.thingsboard.server.gen.transport.TransportProtos; |
@@ -77,9 +79,12 @@ import java.util.stream.Collectors; | @@ -77,9 +79,12 @@ import java.util.stream.Collectors; | ||
77 | 79 | ||
78 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; | 80 | import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; |
79 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; | 81 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
82 | +import static org.thingsboard.server.common.data.DataConstants.FIRMWARE_VERSION; | ||
83 | +import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_KEY; | ||
80 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 84 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
81 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; | 85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; |
82 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; | 86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; |
87 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.FR_PATH_RESOURCE_VER_ID; | ||
83 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; | 88 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | 89 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; |
85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; | 90 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; |
@@ -110,6 +115,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -110,6 +115,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
110 | private ExecutorService executorUpdateRegistered; | 115 | private ExecutorService executorUpdateRegistered; |
111 | private ExecutorService executorUnRegistered; | 116 | private ExecutorService executorUnRegistered; |
112 | private LwM2mValueConverterImpl converter; | 117 | private LwM2mValueConverterImpl converter; |
118 | + private FirmwareDataCache firmwareDataCache; | ||
119 | + | ||
113 | 120 | ||
114 | private final TransportService transportService; | 121 | private final TransportService transportService; |
115 | 122 | ||
@@ -121,12 +128,15 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -121,12 +128,15 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
121 | 128 | ||
122 | private final LwM2mTransportRequest lwM2mTransportRequest; | 129 | private final LwM2mTransportRequest lwM2mTransportRequest; |
123 | 130 | ||
124 | - public LwM2mTransportServiceImpl(TransportService transportService, LwM2mTransportContextServer lwM2mTransportContextServer, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, @Lazy LwM2mTransportRequest lwM2mTransportRequest) { | 131 | + public LwM2mTransportServiceImpl(TransportService transportService, LwM2mTransportContextServer lwM2mTransportContextServer, |
132 | + LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, | ||
133 | + @Lazy LwM2mTransportRequest lwM2mTransportRequest, FirmwareDataCache firmwareDataCache) { | ||
125 | this.transportService = transportService; | 134 | this.transportService = transportService; |
126 | this.lwM2mTransportContextServer = lwM2mTransportContextServer; | 135 | this.lwM2mTransportContextServer = lwM2mTransportContextServer; |
127 | this.lwM2mClientContext = lwM2mClientContext; | 136 | this.lwM2mClientContext = lwM2mClientContext; |
128 | this.leshanServer = leshanServer; | 137 | this.leshanServer = leshanServer; |
129 | this.lwM2mTransportRequest = lwM2mTransportRequest; | 138 | this.lwM2mTransportRequest = lwM2mTransportRequest; |
139 | + this.firmwareDataCache = firmwareDataCache; | ||
130 | } | 140 | } |
131 | 141 | ||
132 | @PostConstruct | 142 | @PostConstruct |
@@ -168,8 +178,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -168,8 +178,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
168 | transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); | 178 | transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); |
169 | transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); | 179 | transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); |
170 | transportService.process(sessionInfo, TransportProtos.SubscribeToRPCMsg.newBuilder().build(), null); | 180 | transportService.process(sessionInfo, TransportProtos.SubscribeToRPCMsg.newBuilder().build(), null); |
181 | + this.getInfoFirmwareUpdate(lwM2MClient); | ||
171 | this.initLwM2mFromClientValue(registration, lwM2MClient); | 182 | this.initLwM2mFromClientValue(registration, lwM2MClient); |
172 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration); | 183 | + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); |
173 | } else { | 184 | } else { |
174 | log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); | 185 | log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null); |
175 | } | 186 | } |
@@ -224,7 +235,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -224,7 +235,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
224 | executorUnRegistered.submit(() -> { | 235 | executorUnRegistered.submit(() -> { |
225 | try { | 236 | try { |
226 | this.setCancelObservations(registration); | 237 | this.setCancelObservations(registration); |
227 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration); | 238 | + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); |
228 | this.closeClientSession(registration); | 239 | this.closeClientSession(registration); |
229 | } catch (Throwable t) { | 240 | } catch (Throwable t) { |
230 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); | 241 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); |
@@ -257,7 +268,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -257,7 +268,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
257 | @Override | 268 | @Override |
258 | public void onSleepingDev(Registration registration) { | 269 | public void onSleepingDev(Registration registration) { |
259 | log.info("[{}] [{}] Received endpoint Sleeping version event", registration.getId(), registration.getEndpoint()); | 270 | log.info("[{}] [{}] Received endpoint Sleeping version event", registration.getId(), registration.getEndpoint()); |
260 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is sleeping!", registration); | 271 | + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is sleeping!", registration.getId()); |
261 | 272 | ||
262 | //TODO: associate endpointId with device information. | 273 | //TODO: associate endpointId with device information. |
263 | } | 274 | } |
@@ -280,7 +291,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -280,7 +291,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
280 | * @param response - observe | 291 | * @param response - observe |
281 | */ | 292 | */ |
282 | @Override | 293 | @Override |
283 | - public void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { | 294 | + public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { |
284 | if (response.getContent() != null) { | 295 | if (response.getContent() != null) { |
285 | if (response.getContent() instanceof LwM2mObject) { | 296 | if (response.getContent() instanceof LwM2mObject) { |
286 | LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); | 297 | LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); |
@@ -304,20 +315,26 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -304,20 +315,26 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
304 | 315 | ||
305 | /** | 316 | /** |
306 | * Update - send request in change value resources in Client | 317 | * Update - send request in change value resources in Client |
307 | - * Path to resources from profile equal keyName or from ModelObject equal name | ||
308 | - * Only for resources: isWritable && isPresent as attribute in profile -> LwM2MClientProfile (format: CamelCase) | ||
309 | - * Delete - nothing * | 318 | + * 1. FirmwareUpdate: |
319 | + * - If msg.getSharedUpdatedList().forEach(tsKvProto -> {tsKvProto.getKv().getKey().indexOf(FIRMWARE_UPDATE_PREFIX, 0) == 0 | ||
320 | + * 2. Shared Other AttributeUpdate | ||
321 | + * -- Path to resources from profile equal keyName or from ModelObject equal name | ||
322 | + * -- Only for resources: isWritable && isPresent as attribute in profile -> LwM2MClientProfile (format: CamelCase) | ||
323 | + * 3. Delete - nothing | ||
310 | * | 324 | * |
311 | * @param msg - | 325 | * @param msg - |
312 | */ | 326 | */ |
313 | @Override | 327 | @Override |
314 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { | 328 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { |
329 | + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | ||
315 | if (msg.getSharedUpdatedCount() > 0) { | 330 | if (msg.getSharedUpdatedCount() > 0) { |
316 | msg.getSharedUpdatedList().forEach(tsKvProto -> { | 331 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
317 | String pathName = tsKvProto.getKv().getKey(); | 332 | String pathName = tsKvProto.getKv().getKey(); |
318 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); | 333 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
319 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | 334 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); |
320 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 335 | + if (FIRMWARE_VERSION.equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { |
336 | + this.getInfoFirmwareUpdate(lwM2MClient); | ||
337 | + } | ||
321 | if (pathIdVer != null) { | 338 | if (pathIdVer != null) { |
322 | ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() | 339 | ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
323 | .getModelProvider()); | 340 | .getModelProvider()); |
@@ -327,19 +344,26 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -327,19 +344,26 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
327 | log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, valueNew); | 344 | log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, valueNew); |
328 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", | 345 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", |
329 | LOG_LW2M_ERROR, pathIdVer, valueNew); | 346 | LOG_LW2M_ERROR, pathIdVer, valueNew); |
330 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | 347 | + this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); |
331 | } | 348 | } |
332 | } else { | 349 | } else { |
333 | log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew); | 350 | log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew); |
334 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", | 351 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", |
335 | LOG_LW2M_ERROR, pathName, valueNew); | 352 | LOG_LW2M_ERROR, pathName, valueNew); |
336 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | 353 | + this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); |
337 | } | 354 | } |
355 | + | ||
338 | }); | 356 | }); |
339 | } else if (msg.getSharedDeletedCount() > 0) { | 357 | } else if (msg.getSharedDeletedCount() > 0) { |
358 | + msg.getSharedUpdatedList().forEach(tsKvProto -> { | ||
359 | + String pathName = tsKvProto.getKv().getKey(); | ||
360 | + Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | ||
361 | + if (FIRMWARE_VERSION.equals(pathName) && !valueNew.equals(lwM2MClient.getFrUpdate().getCurrentFwVersion())) { | ||
362 | + lwM2MClient.getFrUpdate().setCurrentFwVersion((String) valueNew); | ||
363 | + } | ||
364 | + }); | ||
340 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); | 365 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); |
341 | } | 366 | } |
342 | - | ||
343 | } | 367 | } |
344 | 368 | ||
345 | /** | 369 | /** |
@@ -455,23 +479,21 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -455,23 +479,21 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
455 | } | 479 | } |
456 | if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) { | 480 | if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) { |
457 | lwm2mClientRpcRequest.setParams(new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey) | 481 | lwm2mClientRpcRequest.setParams(new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey) |
458 | - .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() { | ||
459 | - }.getType())); | 482 | + .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() { |
483 | + }.getType())); | ||
460 | } | 484 | } |
461 | lwm2mClientRpcRequest.setSessionInfo(sessionInfo); | 485 | lwm2mClientRpcRequest.setSessionInfo(sessionInfo); |
462 | if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) { | 486 | if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) { |
463 | lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " + | 487 | lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " + |
464 | lwm2mClientRpcRequest.keyNameKey + " is null or bad format"); | 488 | lwm2mClientRpcRequest.keyNameKey + " is null or bad format"); |
465 | - } | ||
466 | - else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper() | 489 | + } else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper() |
467 | || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper()) | 490 | || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper()) |
468 | - && lwm2mClientRpcRequest.getTargetIdVer() !=null | 491 | + && lwm2mClientRpcRequest.getTargetIdVer() != null |
469 | && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource() | 492 | && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource() |
470 | || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) { | 493 | || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) { |
471 | - lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey | 494 | + lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey |
472 | + ". Only Resource or ResourceInstance can be this operation"); | 495 | + ". Only Resource or ResourceInstance can be this operation"); |
473 | - } | ||
474 | - else if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()){ | 496 | + } else if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()) { |
475 | lwm2mClientRpcRequest.setErrorMsg("Procedures In Development..."); | 497 | lwm2mClientRpcRequest.setErrorMsg("Procedures In Development..."); |
476 | } | 498 | } |
477 | } else { | 499 | } else { |
@@ -483,23 +505,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -483,23 +505,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
483 | return lwm2mClientRpcRequest; | 505 | return lwm2mClientRpcRequest; |
484 | } | 506 | } |
485 | 507 | ||
486 | - public void sentRpcRequest (Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { | 508 | + public void sentRpcRequest(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { |
487 | rpcRequest.setResponseCode(requestCode); | 509 | rpcRequest.setResponseCode(requestCode); |
488 | - if (LOG_LW2M_ERROR.equals(typeMsg)) { | ||
489 | - rpcRequest.setInfoMsg(null); | ||
490 | - rpcRequest.setValueMsg(null); | ||
491 | - if (rpcRequest.getErrorMsg() == null) { | ||
492 | - msg = msg.isEmpty() ? null : msg; | ||
493 | - rpcRequest.setErrorMsg(msg); | ||
494 | - } | ||
495 | - } else if (LOG_LW2M_INFO.equals(typeMsg)) { | ||
496 | - if (rpcRequest.getInfoMsg() == null) { | ||
497 | - rpcRequest.setInfoMsg(msg); | ||
498 | - } | ||
499 | - } else if (LOG_LW2M_VALUE.equals(typeMsg)) { | ||
500 | - if (rpcRequest.getValueMsg() == null) { | ||
501 | - rpcRequest.setValueMsg(msg); | ||
502 | - } | 510 | + if (LOG_LW2M_ERROR.equals(typeMsg)) { |
511 | + rpcRequest.setInfoMsg(null); | ||
512 | + rpcRequest.setValueMsg(null); | ||
513 | + if (rpcRequest.getErrorMsg() == null) { | ||
514 | + msg = msg.isEmpty() ? null : msg; | ||
515 | + rpcRequest.setErrorMsg(msg); | ||
516 | + } | ||
517 | + } else if (LOG_LW2M_INFO.equals(typeMsg)) { | ||
518 | + if (rpcRequest.getInfoMsg() == null) { | ||
519 | + rpcRequest.setInfoMsg(msg); | ||
520 | + } | ||
521 | + } else if (LOG_LW2M_VALUE.equals(typeMsg)) { | ||
522 | + if (rpcRequest.getValueMsg() == null) { | ||
523 | + rpcRequest.setValueMsg(msg); | ||
524 | + } | ||
503 | } | 525 | } |
504 | this.onToDeviceRpcResponse(rpcRequest.getDeviceRpcResponseResultMsg(), rpcRequest.getSessionInfo()); | 526 | this.onToDeviceRpcResponse(rpcRequest.getDeviceRpcResponseResultMsg(), rpcRequest.getSessionInfo()); |
505 | } | 527 | } |
@@ -556,7 +578,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -556,7 +578,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
556 | */ | 578 | */ |
557 | protected void onAwakeDev(Registration registration) { | 579 | protected void onAwakeDev(Registration registration) { |
558 | log.info("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); | 580 | log.info("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint()); |
559 | - this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is awake!", registration); | 581 | + this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is awake!", registration.getId()); |
560 | //TODO: associate endpointId with device information. | 582 | //TODO: associate endpointId with device information. |
561 | } | 583 | } |
562 | 584 | ||
@@ -583,10 +605,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -583,10 +605,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
583 | 605 | ||
584 | /** | 606 | /** |
585 | * @param logMsg - text msg | 607 | * @param logMsg - text msg |
586 | - * @param registration - Id of Registration LwM2M Client | 608 | + * @param registrationId - Id of Registration LwM2M Client |
587 | */ | 609 | */ |
588 | - public void sendLogsToThingsboard(String logMsg, Registration registration) { | ||
589 | - SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | 610 | + public void sendLogsToThingsboard(String logMsg, String registrationId) { |
611 | + SessionInfoProto sessionInfo = this.getValidateSessionInfo(registrationId); | ||
590 | if (logMsg != null && sessionInfo != null) { | 612 | if (logMsg != null && sessionInfo != null) { |
591 | this.lwM2mTransportContextServer.sendParametersOnThingsboardTelemetry(this.lwM2mTransportContextServer.getKvLogyToThingsboard(logMsg), sessionInfo); | 613 | this.lwM2mTransportContextServer.sendParametersOnThingsboardTelemetry(this.lwM2mTransportContextServer.getKvLogyToThingsboard(logMsg), sessionInfo); |
592 | } | 614 | } |
@@ -610,7 +632,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -610,7 +632,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
610 | if (clientObjects != null && clientObjects.size() > 0) { | 632 | if (clientObjects != null && clientObjects.size() > 0) { |
611 | if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { | 633 | if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { |
612 | // #2 | 634 | // #2 |
613 | - lwM2MClient.getPendingRequests().addAll(clientObjects); | 635 | + lwM2MClient.getPendingReadRequests().addAll(clientObjects); |
614 | clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(), | 636 | clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(), |
615 | null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); | 637 | null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); |
616 | } | 638 | } |
@@ -652,6 +674,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -652,6 +674,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
652 | * Sending observe value of resources to thingsboard | 674 | * Sending observe value of resources to thingsboard |
653 | * #1 Return old Value Resource from LwM2MClient | 675 | * #1 Return old Value Resource from LwM2MClient |
654 | * #2 Update new Resources (replace old Resource Value on new Resource Value) | 676 | * #2 Update new Resources (replace old Resource Value on new Resource Value) |
677 | + * #3 If fr_update -> UpdateFirmware | ||
678 | + * #4 updateAttrTelemetry | ||
655 | * | 679 | * |
656 | * @param registration - Registration LwM2M Client | 680 | * @param registration - Registration LwM2M Client |
657 | * @param lwM2mResource - LwM2mSingleResource response.getContent() | 681 | * @param lwM2mResource - LwM2mSingleResource response.getContent() |
@@ -661,6 +685,19 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -661,6 +685,19 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
661 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 685 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); |
662 | if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() | 686 | if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
663 | .getModelProvider())) { | 687 | .getModelProvider())) { |
688 | + if (FR_PATH_RESOURCE_VER_ID.equals(convertPathFromIdVerToObjectId(path)) && | ||
689 | + lwM2MClient.getFrUpdate().getCurrentFwVersion() != null | ||
690 | + && !lwM2MClient.getFrUpdate().getCurrentFwVersion().equals(lwM2MClient.getFrUpdate().getClientFwVersion()) | ||
691 | + && lwM2MClient.isUpdateFw()) { | ||
692 | + | ||
693 | + /** version != null | ||
694 | + * set setClient_fw_version = value | ||
695 | + **/ | ||
696 | + lwM2MClient.setUpdateFw(false); | ||
697 | + lwM2MClient.getFrUpdate().setClientFwVersion(lwM2mResource.getValue().toString()); | ||
698 | + log.warn("updateFirmwareClient3"); | ||
699 | + this.updateFirmwareClient(lwM2MClient); | ||
700 | + } | ||
664 | Set<String> paths = new HashSet<>(); | 701 | Set<String> paths = new HashSet<>(); |
665 | paths.add(path); | 702 | paths.add(path); |
666 | this.updateAttrTelemetry(registration, paths); | 703 | this.updateAttrTelemetry(registration, paths); |
@@ -669,6 +706,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -669,6 +706,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
669 | } | 706 | } |
670 | } | 707 | } |
671 | 708 | ||
709 | + | ||
672 | /** | 710 | /** |
673 | * send Attribute and Telemetry to Thingsboard | 711 | * send Attribute and Telemetry to Thingsboard |
674 | * #1 - get AttrName/TelemetryName with value from LwM2MClient: | 712 | * #1 - get AttrName/TelemetryName with value from LwM2MClient: |
@@ -723,22 +761,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -723,22 +761,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
723 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); | 761 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); |
724 | result = params.keySet(); | 762 | result = params.keySet(); |
725 | } | 763 | } |
726 | - if (!result.isEmpty()) { | 764 | + if (result != null && !result.isEmpty()) { |
727 | // #1 | 765 | // #1 |
728 | Set<String> pathSend = result.stream().filter(target -> { | 766 | Set<String> pathSend = result.stream().filter(target -> { |
729 | return target.split(LWM2M_SEPARATOR_PATH).length < 3 ? | 767 | return target.split(LWM2M_SEPARATOR_PATH).length < 3 ? |
730 | clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1]) : | 768 | clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1]) : |
731 | clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1] + "/" + target.split(LWM2M_SEPARATOR_PATH)[2]); | 769 | clientObjects.contains("/" + target.split(LWM2M_SEPARATOR_PATH)[1] + "/" + target.split(LWM2M_SEPARATOR_PATH)[2]); |
732 | } | 770 | } |
733 | - ) | ||
734 | - .collect(Collectors.toUnmodifiableSet()); | 771 | + ).collect(Collectors.toUnmodifiableSet()); |
735 | if (!pathSend.isEmpty()) { | 772 | if (!pathSend.isEmpty()) { |
736 | - lwM2MClient.getPendingRequests().addAll(pathSend); | 773 | + lwM2MClient.getPendingReadRequests().addAll(pathSend); |
737 | ConcurrentHashMap<String, Object> finalParams = params; | 774 | ConcurrentHashMap<String, Object> finalParams = params; |
738 | - pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | ||
739 | - finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); | 775 | + pathSend.forEach(target -> { |
776 | + lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | ||
777 | + finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
778 | + }); | ||
740 | if (OBSERVE.equals(typeOper)) { | 779 | if (OBSERVE.equals(typeOper)) { |
741 | - lwM2MClient.initValue(this, null); | 780 | + lwM2MClient.initReadValue(this, null); |
742 | } | 781 | } |
743 | } | 782 | } |
744 | } | 783 | } |
@@ -969,7 +1008,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -969,7 +1008,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
969 | // update value in Resources | 1008 | // update value in Resources |
970 | registrationIds.forEach(registrationId -> { | 1009 | registrationIds.forEach(registrationId -> { |
971 | Registration registration = lwM2mClientContext.getRegistration(registrationId); | 1010 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
972 | - this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); | 1011 | + this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); |
973 | // send attr/telemetry to tingsboard for new path | 1012 | // send attr/telemetry to tingsboard for new path |
974 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); | 1013 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); |
975 | }); | 1014 | }); |
@@ -998,12 +1037,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -998,12 +1037,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
998 | registrationIds.forEach(registrationId -> { | 1037 | registrationIds.forEach(registrationId -> { |
999 | Registration registration = lwM2mClientContext.getRegistration(registrationId); | 1038 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
1000 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { | 1039 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { |
1001 | - this.readResourceValueObserve(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); | 1040 | + this.readObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); |
1002 | } | 1041 | } |
1003 | // 5.3 del | 1042 | // 5.3 del |
1004 | // send Request cancel observe to Client | 1043 | // send Request cancel observe to Client |
1005 | if (postObserveAnalyzer.getPathPostParametersDel().size() > 0) { | 1044 | if (postObserveAnalyzer.getPathPostParametersDel().size() > 0) { |
1006 | - this.cancelObserveIsValue(registration, postObserveAnalyzer.getPathPostParametersDel()); | 1045 | + this.cancelObserveFromProfile(registration, postObserveAnalyzer.getPathPostParametersDel()); |
1007 | } | 1046 | } |
1008 | }); | 1047 | }); |
1009 | } | 1048 | } |
@@ -1043,7 +1082,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1043,7 +1082,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1043 | * @param registration - Registration LwM2M Client | 1082 | * @param registration - Registration LwM2M Client |
1044 | * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] | 1083 | * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] |
1045 | */ | 1084 | */ |
1046 | - private void readResourceValueObserve(Registration registration, Set<String> targets, LwM2mTypeOper typeOper) { | 1085 | + private void readObserveFromProfile(Registration registration, Set<String> targets, LwM2mTypeOper typeOper) { |
1047 | targets.forEach(target -> { | 1086 | targets.forEach(target -> { |
1048 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); | 1087 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); |
1049 | if (pathIds.isResource()) { | 1088 | if (pathIds.isResource()) { |
@@ -1133,7 +1172,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1133,7 +1172,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1133 | 1172 | ||
1134 | } | 1173 | } |
1135 | 1174 | ||
1136 | - private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { | 1175 | + private void cancelObserveFromProfile(Registration registration, Set<String> paramAnallyzer) { |
1137 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 1176 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); |
1138 | paramAnallyzer.forEach(pathIdVer -> { | 1177 | paramAnallyzer.forEach(pathIdVer -> { |
1139 | if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { | 1178 | if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { |
@@ -1153,7 +1192,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1153,7 +1192,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1153 | log.error("Failed update resource [{}] [{}]", path, valueNew); | 1192 | log.error("Failed update resource [{}] [{}]", path, valueNew); |
1154 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", | 1193 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", |
1155 | LOG_LW2M_ERROR, path, valueNew); | 1194 | LOG_LW2M_ERROR, path, valueNew); |
1156 | - this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | 1195 | + this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId()); |
1157 | log.info("Failed update resource [{}] [{}]", path, valueNew); | 1196 | log.info("Failed update resource [{}] [{}]", path, valueNew); |
1158 | } | 1197 | } |
1159 | } | 1198 | } |
@@ -1182,8 +1221,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1182,8 +1221,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1182 | } | 1221 | } |
1183 | 1222 | ||
1184 | /** | 1223 | /** |
1185 | - * Update resource value on client: if there is a difference in values between the current resource values and the shared attribute values | ||
1186 | - * #1 Get path resource by result attributesResponse | 1224 | + * 1. FirmwareUpdate: |
1225 | + * - msg.getSharedUpdatedList().forEach(tsKvProto -> {tsKvProto.getKv().getKey().indexOf(FIRMWARE_UPDATE_PREFIX, 0) == 0 | ||
1226 | + * 2. Update resource value on client: if there is a difference in values between the current resource values and the shared attribute values | ||
1227 | + * - Get path resource by result attributesResponse | ||
1187 | * | 1228 | * |
1188 | * @param attributesResponse - | 1229 | * @param attributesResponse - |
1189 | * @param sessionInfo - | 1230 | * @param sessionInfo - |
@@ -1191,6 +1232,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1191,6 +1232,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1191 | public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { | 1232 | public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { |
1192 | try { | 1233 | try { |
1193 | List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList(); | 1234 | List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList(); |
1235 | + | ||
1194 | this.updateAttriuteFromThingsboard(tsKvProtos, sessionInfo); | 1236 | this.updateAttriuteFromThingsboard(tsKvProtos, sessionInfo); |
1195 | } catch (Exception e) { | 1237 | } catch (Exception e) { |
1196 | log.error(String.valueOf(e)); | 1238 | log.error(String.valueOf(e)); |
@@ -1274,7 +1316,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1274,7 +1316,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1274 | */ | 1316 | */ |
1275 | private SessionInfoProto getValidateSessionInfo(String registrationId) { | 1317 | private SessionInfoProto getValidateSessionInfo(String registrationId) { |
1276 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(null, registrationId); | 1318 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(null, registrationId); |
1277 | - return getNewSessionInfoProto(lwM2MClient); | 1319 | + return lwM2MClient != null ? this.getNewSessionInfoProto(lwM2MClient) : null; |
1278 | } | 1320 | } |
1279 | 1321 | ||
1280 | /** | 1322 | /** |
@@ -1293,28 +1335,88 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1293,28 +1335,88 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1293 | } | 1335 | } |
1294 | 1336 | ||
1295 | /** | 1337 | /** |
1296 | - * !!! sharedAttr === profileAttr !!! | ||
1297 | - * If there is a difference in values between the current resource values and the shared attribute values | ||
1298 | - * when the client connects to the server | ||
1299 | - * #1 get attributes name from profile include name resources in ModelObject if resource isWritable | ||
1300 | - * #2.1 #1 size > 0 => send Request getAttributes to thingsboard | 1338 | + * #1. !!! sharedAttr === profileAttr !!! |
1339 | + * - If there is a difference in values between the current resource values and the shared attribute values | ||
1340 | + * - when the client connects to the server | ||
1341 | + * #1.1 get attributes name from profile include name resources in ModelObject if resource isWritable | ||
1342 | + * #1.2 #1 size > 0 => send Request getAttributes to thingsboard | ||
1343 | + * #2. FirmwareAttribute subscribe: | ||
1301 | * | 1344 | * |
1302 | * @param lwM2MClient - LwM2M Client | 1345 | * @param lwM2MClient - LwM2M Client |
1303 | */ | 1346 | */ |
1304 | public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { | 1347 | public void putDelayedUpdateResourcesThingsboard(LwM2mClient lwM2MClient) { |
1305 | SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); | 1348 | SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); |
1306 | if (sessionInfo != null) { | 1349 | if (sessionInfo != null) { |
1307 | - //#1.1 + #1.2 | ||
1308 | - List<String> attrSharedNames = this.getNamesAttrFromProfileIsWritable(lwM2MClient); | ||
1309 | - if (attrSharedNames.size() > 0) { | ||
1310 | - //#2.1 | 1350 | + //#1.1 |
1351 | + ConcurrentMap<String, String> keyNamesMap = this.getNamesFromProfileForSharedAttributes(lwM2MClient); | ||
1352 | + if (keyNamesMap.values().size() > 0) { | ||
1311 | try { | 1353 | try { |
1312 | - TransportProtos.GetAttributeRequestMsg getAttributeMsg = lwM2mTransportContextServer.getAdaptor().convertToGetAttributes(null, attrSharedNames); | 1354 | + //#1.2 |
1355 | + TransportProtos.GetAttributeRequestMsg getAttributeMsg = lwM2mTransportContextServer.getAdaptor().convertToGetAttributes(null, keyNamesMap.values()); | ||
1313 | transportService.process(sessionInfo, getAttributeMsg, getAckCallback(lwM2MClient, getAttributeMsg.getRequestId(), DEVICE_ATTRIBUTES_REQUEST)); | 1356 | transportService.process(sessionInfo, getAttributeMsg, getAckCallback(lwM2MClient, getAttributeMsg.getRequestId(), DEVICE_ATTRIBUTES_REQUEST)); |
1314 | } catch (AdaptorException e) { | 1357 | } catch (AdaptorException e) { |
1315 | log.warn("Failed to decode get attributes request", e); | 1358 | log.warn("Failed to decode get attributes request", e); |
1316 | } | 1359 | } |
1317 | } | 1360 | } |
1361 | + | ||
1362 | + } | ||
1363 | + } | ||
1364 | + | ||
1365 | + public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) { | ||
1366 | + SessionInfoProto sessionInfo = this.getValidateSessionInfo(lwM2MClient.getRegistration()); | ||
1367 | + if (sessionInfo != null) { | ||
1368 | + TransportProtos.GetFirmwareRequestMsg getFirmwareRequestMsg = TransportProtos.GetFirmwareRequestMsg.newBuilder() | ||
1369 | + .setDeviceIdMSB(sessionInfo.getDeviceIdMSB()) | ||
1370 | + .setDeviceIdLSB(sessionInfo.getDeviceIdLSB()) | ||
1371 | + .setTenantIdMSB(sessionInfo.getTenantIdMSB()) | ||
1372 | + .setTenantIdLSB(sessionInfo.getTenantIdLSB()) | ||
1373 | + .build(); | ||
1374 | + transportService.process(sessionInfo, getFirmwareRequestMsg, | ||
1375 | + new TransportServiceCallback<>() { | ||
1376 | + @Override | ||
1377 | + public void onSuccess(TransportProtos.GetFirmwareResponseMsg response) { | ||
1378 | + if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())) { | ||
1379 | + lwM2MClient.getFrUpdate().setCurrentFwVersion(response.getVersion()); | ||
1380 | + lwM2MClient.getFrUpdate().setCurrentFwId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId()); | ||
1381 | + lwM2MClient.setUpdateFw(true); | ||
1382 | + readRequestToClientFirmwareVer(lwM2MClient.getRegistration()); | ||
1383 | + } else { | ||
1384 | + log.trace("Firmware [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); | ||
1385 | + } | ||
1386 | + } | ||
1387 | + | ||
1388 | + @Override | ||
1389 | + public void onError(Throwable e) { | ||
1390 | + log.trace("Failed to process credentials ", e); | ||
1391 | + } | ||
1392 | + }); | ||
1393 | + } | ||
1394 | + } | ||
1395 | + | ||
1396 | + /** | ||
1397 | + * @param registration | ||
1398 | + */ | ||
1399 | + public void readRequestToClientFirmwareVer(Registration registration) { | ||
1400 | + String pathIdVer = convertPathFromObjectIdToIdVer(FR_PATH_RESOURCE_VER_ID, registration); | ||
1401 | + lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, READ, ContentFormat.TLV.getName(), | ||
1402 | + null, lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
1403 | + } | ||
1404 | + | ||
1405 | + /** | ||
1406 | + * | ||
1407 | + * @param lwM2MClient - | ||
1408 | + */ | ||
1409 | + public void updateFirmwareClient(LwM2mClient lwM2MClient) { | ||
1410 | + if (!lwM2MClient.getFrUpdate().getCurrentFwVersion().equals(lwM2MClient.getFrUpdate().getClientFwVersion())) { | ||
1411 | + int chunkSize = 0; | ||
1412 | + int chunk = 0; | ||
1413 | + byte[] firmwareChunk = firmwareDataCache.get(lwM2MClient.getFrUpdate().getCurrentFwId().toString(), chunkSize, chunk); | ||
1414 | + Integer objectId = 5; | ||
1415 | + String verSupportedObject = lwM2MClient.getRegistration().getSupportedObject().get(objectId); | ||
1416 | + String targetIdVer = LWM2M_SEPARATOR_PATH + objectId + LWM2M_SEPARATOR_KEY + verSupportedObject + LWM2M_SEPARATOR_PATH + 0 + LWM2M_SEPARATOR_PATH + 0; | ||
1417 | + lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.TLV.getName(), | ||
1418 | + firmwareChunk, lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
1419 | + log.warn("updateFirmwareClient [{}] [{}]", lwM2MClient.getFrUpdate().getCurrentFwVersion(), lwM2MClient.getFrUpdate().getClientFwVersion()); | ||
1318 | } | 1420 | } |
1319 | } | 1421 | } |
1320 | 1422 | ||
@@ -1326,23 +1428,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1326,23 +1428,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1326 | * @param lwM2MClient - | 1428 | * @param lwM2MClient - |
1327 | * @return ArrayList keyNames from profile profileAttr && IsWritable | 1429 | * @return ArrayList keyNames from profile profileAttr && IsWritable |
1328 | */ | 1430 | */ |
1329 | - private List<String> getNamesAttrFromProfileIsWritable(LwM2mClient lwM2MClient) { | 1431 | + private ConcurrentMap<String, String> getNamesFromProfileForSharedAttributes(LwM2mClient lwM2MClient) { |
1432 | + | ||
1330 | LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId()); | 1433 | LwM2mClientProfile profile = lwM2mClientContext.getProfile(lwM2MClient.getProfileId()); |
1331 | - Set<String> attrSet = new Gson().fromJson(profile.getPostAttributeProfile(), | ||
1332 | - new TypeToken<HashSet<String>>() { | ||
1333 | - }.getType()); | ||
1334 | - ConcurrentMap<String, String> keyNamesMap = new Gson().fromJson(profile.getPostKeyNameProfile().toString(), | 1434 | + return new Gson().fromJson(profile.getPostKeyNameProfile().toString(), |
1335 | new TypeToken<ConcurrentHashMap<String, String>>() { | 1435 | new TypeToken<ConcurrentHashMap<String, String>>() { |
1336 | }.getType()); | 1436 | }.getType()); |
1337 | - | ||
1338 | - ConcurrentMap<String, String> keyNamesIsWritable = keyNamesMap.entrySet() | ||
1339 | - .stream() | ||
1340 | - .filter(e -> (attrSet.contains(e.getKey()) && validateResourceInModel(lwM2MClient, e.getKey(), true))) | ||
1341 | - .collect(Collectors.toConcurrentMap(Map.Entry::getKey, Map.Entry::getValue)); | ||
1342 | - | ||
1343 | - Set<String> namesIsWritable = ConcurrentHashMap.newKeySet(); | ||
1344 | - namesIsWritable.addAll(new HashSet<>(keyNamesIsWritable.values())); | ||
1345 | - return new ArrayList<>(namesIsWritable); | ||
1346 | } | 1437 | } |
1347 | 1438 | ||
1348 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { | 1439 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { |
@@ -24,11 +24,8 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | @@ -24,11 +24,8 @@ import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
24 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; | 24 | import org.thingsboard.server.common.transport.adaptor.JsonConverter; |
25 | import org.thingsboard.server.gen.transport.TransportProtos; | 25 | import org.thingsboard.server.gen.transport.TransportProtos; |
26 | 26 | ||
27 | -import java.util.Arrays; | ||
28 | -import java.util.HashSet; | ||
29 | -import java.util.List; | 27 | +import java.util.Collection; |
30 | import java.util.Random; | 28 | import java.util.Random; |
31 | -import java.util.Set; | ||
32 | 29 | ||
33 | @Slf4j | 30 | @Slf4j |
34 | @Component("LwM2MJsonAdaptor") | 31 | @Component("LwM2MJsonAdaptor") |
@@ -54,11 +51,7 @@ public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor { | @@ -54,11 +51,7 @@ public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor { | ||
54 | } | 51 | } |
55 | 52 | ||
56 | @Override | 53 | @Override |
57 | - public TransportProtos.GetAttributeRequestMsg convertToGetAttributes(List<String> clientKeys, List<String> sharedKeys) throws AdaptorException { | ||
58 | - return processGetAttributeRequestMsg(clientKeys, sharedKeys); | ||
59 | - } | ||
60 | - | ||
61 | - protected TransportProtos.GetAttributeRequestMsg processGetAttributeRequestMsg(List<String> clientKeys, List<String> sharedKeys) throws AdaptorException { | 54 | + public TransportProtos.GetAttributeRequestMsg convertToGetAttributes(Collection<String> clientKeys, Collection<String> sharedKeys) throws AdaptorException { |
62 | try { | 55 | try { |
63 | TransportProtos.GetAttributeRequestMsg.Builder result = TransportProtos.GetAttributeRequestMsg.newBuilder(); | 56 | TransportProtos.GetAttributeRequestMsg.Builder result = TransportProtos.GetAttributeRequestMsg.newBuilder(); |
64 | Random random = new Random(); | 57 | Random random = new Random(); |
@@ -75,14 +68,4 @@ public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor { | @@ -75,14 +68,4 @@ public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor { | ||
75 | throw new AdaptorException(e); | 68 | throw new AdaptorException(e); |
76 | } | 69 | } |
77 | } | 70 | } |
78 | - | ||
79 | - private Set<String> toStringSet(JsonElement requestBody, String name) { | ||
80 | - JsonElement element = requestBody.getAsJsonObject().get(name); | ||
81 | - if (element != null) { | ||
82 | - return new HashSet<>(Arrays.asList(element.getAsString().split(","))); | ||
83 | - } else { | ||
84 | - return null; | ||
85 | - } | ||
86 | - } | ||
87 | - | ||
88 | } | 71 | } |
@@ -19,7 +19,7 @@ import com.google.gson.JsonElement; | @@ -19,7 +19,7 @@ import com.google.gson.JsonElement; | ||
19 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 19 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
20 | import org.thingsboard.server.gen.transport.TransportProtos; | 20 | import org.thingsboard.server.gen.transport.TransportProtos; |
21 | 21 | ||
22 | -import java.util.List; | 22 | +import java.util.Collection; |
23 | 23 | ||
24 | public interface LwM2MTransportAdaptor { | 24 | public interface LwM2MTransportAdaptor { |
25 | 25 | ||
@@ -27,5 +27,5 @@ public interface LwM2MTransportAdaptor { | @@ -27,5 +27,5 @@ public interface LwM2MTransportAdaptor { | ||
27 | 27 | ||
28 | TransportProtos.PostAttributeMsg convertToPostAttributes(JsonElement jsonElement) throws AdaptorException; | 28 | TransportProtos.PostAttributeMsg convertToPostAttributes(JsonElement jsonElement) throws AdaptorException; |
29 | 29 | ||
30 | - TransportProtos.GetAttributeRequestMsg convertToGetAttributes(List<String> clientKeys, List<String> sharedKeys) throws AdaptorException; | 30 | + TransportProtos.GetAttributeRequestMsg convertToGetAttributes(Collection<String> clientKeys, Collection<String> sharedKeys) throws AdaptorException; |
31 | } | 31 | } |
@@ -57,13 +57,15 @@ public class LwM2mClient implements Cloneable { | @@ -57,13 +57,15 @@ public class LwM2mClient implements Cloneable { | ||
57 | private UUID deviceId; | 57 | private UUID deviceId; |
58 | private UUID sessionId; | 58 | private UUID sessionId; |
59 | private UUID profileId; | 59 | private UUID profileId; |
60 | + private volatile LwM2mFirmwareUpdate frUpdate; | ||
60 | private Registration registration; | 61 | private Registration registration; |
61 | private ValidateDeviceCredentialsResponseMsg credentialsResponse; | 62 | private ValidateDeviceCredentialsResponseMsg credentialsResponse; |
62 | private final Map<String, ResourceValue> resources; | 63 | private final Map<String, ResourceValue> resources; |
63 | private final Map<String, TransportProtos.TsKvProto> delayedRequests; | 64 | private final Map<String, TransportProtos.TsKvProto> delayedRequests; |
64 | - private final List<String> pendingRequests; | 65 | + private final List<String> pendingReadRequests; |
65 | private final Queue<LwM2mQueuedRequest> queuedRequests; | 66 | private final Queue<LwM2mQueuedRequest> queuedRequests; |
66 | private boolean init; | 67 | private boolean init; |
68 | + private volatile boolean updateFw; | ||
67 | 69 | ||
68 | public Object clone() throws CloneNotSupportedException { | 70 | public Object clone() throws CloneNotSupportedException { |
69 | return super.clone(); | 71 | return super.clone(); |
@@ -75,12 +77,14 @@ public class LwM2mClient implements Cloneable { | @@ -75,12 +77,14 @@ public class LwM2mClient implements Cloneable { | ||
75 | this.securityInfo = securityInfo; | 77 | this.securityInfo = securityInfo; |
76 | this.credentialsResponse = credentialsResponse; | 78 | this.credentialsResponse = credentialsResponse; |
77 | this.delayedRequests = new ConcurrentHashMap<>(); | 79 | this.delayedRequests = new ConcurrentHashMap<>(); |
78 | - this.pendingRequests = new CopyOnWriteArrayList<>(); | 80 | + this.pendingReadRequests = new CopyOnWriteArrayList<>(); |
79 | this.resources = new ConcurrentHashMap<>(); | 81 | this.resources = new ConcurrentHashMap<>(); |
80 | this.profileId = profileId; | 82 | this.profileId = profileId; |
81 | this.sessionId = sessionId; | 83 | this.sessionId = sessionId; |
82 | this.init = false; | 84 | this.init = false; |
85 | + this.updateFw = false; | ||
83 | this.queuedRequests = new ConcurrentLinkedQueue<>(); | 86 | this.queuedRequests = new ConcurrentLinkedQueue<>(); |
87 | + this.frUpdate = new LwM2mFirmwareUpdate(); | ||
84 | } | 88 | } |
85 | 89 | ||
86 | public boolean saveResourceValue(String pathRez, LwM2mResource rez, LwM2mModelProvider modelProvider) { | 90 | public boolean saveResourceValue(String pathRez, LwM2mResource rez, LwM2mModelProvider modelProvider) { |
@@ -103,15 +107,13 @@ public class LwM2mClient implements Cloneable { | @@ -103,15 +107,13 @@ public class LwM2mClient implements Cloneable { | ||
103 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); | 107 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); |
104 | String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); | 108 | String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); |
105 | String verRez = getVerFromPathIdVerOrId(pathRez); | 109 | String verRez = getVerFromPathIdVerOrId(pathRez); |
106 | - return (verRez == null || verSupportedObject.equals(verRez)) ? modelProvider.getObjectModel(registration) | 110 | + return verRez == null || verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration) |
107 | .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null; | 111 | .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null; |
108 | } | 112 | } |
109 | 113 | ||
110 | public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, LwM2mModelProvider modelProvider, | 114 | public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, LwM2mModelProvider modelProvider, |
111 | LwM2mValueConverterImpl converter) { | 115 | LwM2mValueConverterImpl converter) { |
112 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer)); | 116 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer)); |
113 | - String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); | ||
114 | - String verRez = getVerFromPathIdVerOrId(pathRezIdVer); | ||
115 | Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet(); | 117 | Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet(); |
116 | Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration) | 118 | Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration) |
117 | .getObjectModel(pathIds.getObjectId()).resources; | 119 | .getObjectModel(pathIds.getObjectId()).resources; |
@@ -170,11 +172,11 @@ public class LwM2mClient implements Cloneable { | @@ -170,11 +172,11 @@ public class LwM2mClient implements Cloneable { | ||
170 | .collect(Collectors.toSet()); | 172 | .collect(Collectors.toSet()); |
171 | } | 173 | } |
172 | 174 | ||
173 | - public void initValue(LwM2mTransportServiceImpl serviceImpl, String path) { | 175 | + public void initReadValue(LwM2mTransportServiceImpl serviceImpl, String path) { |
174 | if (path != null) { | 176 | if (path != null) { |
175 | - this.pendingRequests.remove(path); | 177 | + this.pendingReadRequests.remove(path); |
176 | } | 178 | } |
177 | - if (this.pendingRequests.size() == 0) { | 179 | + if (this.pendingReadRequests.size() == 0) { |
178 | this.init = true; | 180 | this.init = true; |
179 | serviceImpl.putDelayedUpdateResourcesThingsboard(this); | 181 | serviceImpl.putDelayedUpdateResourcesThingsboard(this); |
180 | } | 182 | } |
@@ -82,12 +82,12 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -82,12 +82,12 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
82 | 82 | ||
83 | @Override | 83 | @Override |
84 | public LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId) { | 84 | public LwM2mClient getLwM2mClientWithReg(Registration registration, String registrationId) { |
85 | - LwM2mClient client = registrationId != null ? | 85 | + LwM2mClient client = registrationId != null && this.lwM2mClients.containsKey(registrationId) ? |
86 | this.lwM2mClients.get(registrationId) : | 86 | this.lwM2mClients.get(registrationId) : |
87 | - this.lwM2mClients.containsKey(registration.getId()) ? | ||
88 | - this.lwM2mClients.get(registration.getId()) : | ||
89 | - this.lwM2mClients.get(registration.getEndpoint()); | ||
90 | - return client != null ? client : updateInSessionsLwM2MClient(registration); | 87 | + registration !=null && this.lwM2mClients.containsKey(registration.getId()) ? |
88 | + this.lwM2mClients.get(registration.getId()) : registration !=null && this.lwM2mClients.containsKey(registration) ? | ||
89 | + this.lwM2mClients.get(registration.getEndpoint()) : null; | ||
90 | + return client != null ? client : registration!= null ? updateInSessionsLwM2MClient(registration) : null; | ||
91 | } | 91 | } |
92 | 92 | ||
93 | @Override | 93 | @Override |
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.client; | ||
17 | + | ||
18 | +import lombok.Data; | ||
19 | + | ||
20 | +import java.util.UUID; | ||
21 | + | ||
22 | +@Data | ||
23 | +public class LwM2mFirmwareUpdate { | ||
24 | + private volatile String clientFwVersion; | ||
25 | + private volatile String currentFwVersion; | ||
26 | + private volatile UUID currentFwId; | ||
27 | +} |
@@ -24,6 +24,8 @@ import { | @@ -24,6 +24,8 @@ import { | ||
24 | NG_VALUE_ACCESSOR, | 24 | NG_VALUE_ACCESSOR, |
25 | Validators | 25 | Validators |
26 | } from '@angular/forms'; | 26 | } from '@angular/forms'; |
27 | +import { Store } from '@ngrx/store'; | ||
28 | +import { AppState } from '@core/core.state'; | ||
27 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; | 29 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
28 | import { | 30 | import { |
29 | ATTRIBUTE, | 31 | ATTRIBUTE, |
@@ -38,6 +40,7 @@ import { | @@ -38,6 +40,7 @@ import { | ||
38 | } from './lwm2m-profile-config.models'; | 40 | } from './lwm2m-profile-config.models'; |
39 | import { deepClone, isDefinedAndNotNull, isEqual, isUndefined } from '@core/utils'; | 41 | import { deepClone, isDefinedAndNotNull, isEqual, isUndefined } from '@core/utils'; |
40 | import { MatDialog } from '@angular/material/dialog'; | 42 | import { MatDialog } from '@angular/material/dialog'; |
43 | +import { TranslateService } from '@ngx-translate/core'; | ||
41 | import { | 44 | import { |
42 | Lwm2mObjectAddInstancesData, | 45 | Lwm2mObjectAddInstancesData, |
43 | Lwm2mObjectAddInstancesDialogComponent | 46 | Lwm2mObjectAddInstancesDialogComponent |
@@ -80,8 +83,10 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | @@ -80,8 +83,10 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | ||
80 | @Input() | 83 | @Input() |
81 | disabled: boolean; | 84 | disabled: boolean; |
82 | 85 | ||
83 | - constructor(private fb: FormBuilder, | ||
84 | - private dialog: MatDialog) { | 86 | + constructor(private store: Store<AppState>, |
87 | + private fb: FormBuilder, | ||
88 | + private dialog: MatDialog, | ||
89 | + public translate: TranslateService) { | ||
85 | this.observeAttrTelemetryFormGroup = this.fb.group({ | 90 | this.observeAttrTelemetryFormGroup = this.fb.group({ |
86 | [CLIENT_LWM2M]: this.fb.array([]) | 91 | [CLIENT_LWM2M]: this.fb.array([]) |
87 | }); | 92 | }); |
@@ -93,7 +98,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | @@ -93,7 +98,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | ||
93 | } | 98 | } |
94 | 99 | ||
95 | private propagateChange = (v: any) => { | 100 | private propagateChange = (v: any) => { |
96 | - } | 101 | + }; |
97 | 102 | ||
98 | registerOnChange(fn: any): void { | 103 | registerOnChange(fn: any): void { |
99 | this.propagateChange = fn; | 104 | this.propagateChange = fn; |
@@ -184,7 +189,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | @@ -184,7 +189,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | ||
184 | this.observeAttrTelemetryFormGroup.get(CLIENT_LWM2M).updateValueAndValidity(); | 189 | this.observeAttrTelemetryFormGroup.get(CLIENT_LWM2M).updateValueAndValidity(); |
185 | } | 190 | } |
186 | 191 | ||
187 | - trackByParams = (index: number): number => { | 192 | + trackByParams = (index: number, element: any): number => { |
188 | return index; | 193 | return index; |
189 | } | 194 | } |
190 | 195 | ||
@@ -312,7 +317,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | @@ -312,7 +317,7 @@ export class Lwm2mObserveAttrTelemetryComponent implements ControlValueAccessor | ||
312 | return objectName + ' <' + idVerObj + '>'; | 317 | return objectName + ' <' + idVerObj + '>'; |
313 | } | 318 | } |
314 | getNameInstanceLwm2m = (instance: Instance, idVerObj: string): string => { | 319 | getNameInstanceLwm2m = (instance: Instance, idVerObj: string): string => { |
315 | - return ` instance <${idVerObj}/${instance.id}>`; | 320 | + return ' instance <' + idVerObj + '/' + instance.id +'>'; |
316 | } | 321 | } |
317 | 322 | ||
318 | updateAttributeLwm2mObject = (event: Event, objectKeyId: number): void => { | 323 | updateAttributeLwm2mObject = (event: Event, objectKeyId: number): void => { |
@@ -1205,7 +1205,7 @@ | @@ -1205,7 +1205,7 @@ | ||
1205 | "telemetry-label": "Telemetry", | 1205 | "telemetry-label": "Telemetry", |
1206 | "key-name-label": "Key Name", | 1206 | "key-name-label": "Key Name", |
1207 | "attribute-lwm2m-label": "AttrLwm2m", | 1207 | "attribute-lwm2m-label": "AttrLwm2m", |
1208 | - "resource-tip": "ID & Original Name of the Resource", | 1208 | + "resource-tip": "ID & Original Name of the Resource (only Operations isReadable)", |
1209 | "is-observe-tip": "Is Observe", | 1209 | "is-observe-tip": "Is Observe", |
1210 | "not-observe-tip": "To observe select telemetry or attributes first", | 1210 | "not-observe-tip": "To observe select telemetry or attributes first", |
1211 | "is-attr-tip": "Is Attribute", | 1211 | "is-attr-tip": "Is Attribute", |