Commit 51b0d50542ff0da65c7abd722e3c0f6332c8a5ee
Committed by
GitHub
1 parent
cb945010
Lwm2m discovery (#4438)
* Lwm2m: fix bug delete zero updateAttribute * Lwm2m: front add select binding * Lwm2m: discovery only for test * Lwm2m: remove type_cast_enabled from the main branch. * Lwm2m: remove type_cast_enabled from the main branch. * Lwm2m: remove type_cast_enabled from the main branch. * Lwm2m: remove double code.
Showing
15 changed files
with
420 additions
and
208 deletions
@@ -35,7 +35,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | @@ -35,7 +35,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | ||
35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | 35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; | 37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; |
38 | -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; | ||
39 | import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | 38 | import org.thingsboard.server.transport.lwm2m.utils.TypeServer; |
40 | 39 | ||
41 | import java.io.IOException; | 40 | import java.io.IOException; |
@@ -165,13 +164,13 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -165,13 +164,13 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
165 | lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap); | 164 | lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap); |
166 | lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer); | 165 | lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer); |
167 | String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint()); | 166 | String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint()); |
168 | - context.sendParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); | 167 | + context.sendParametersOnThingsboardTelemetry(context.getKvLogyToThingsboard(logMsg), sessionInfo); |
169 | return lwM2MBootstrapConfig; | 168 | return lwM2MBootstrapConfig; |
170 | } else { | 169 | } else { |
171 | log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint()); | 170 | log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint()); |
172 | log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); | 171 | log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); |
173 | String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); | 172 | String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint()); |
174 | - context.sendParametersOnThingsboard(context.getTelemetryMsgObject(logMsg), LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC, sessionInfo); | 173 | + context.sendParametersOnThingsboardTelemetry(context.getKvLogyToThingsboard(logMsg), sessionInfo); |
175 | return null; | 174 | return null; |
176 | } | 175 | } |
177 | } | 176 | } |
@@ -26,7 +26,7 @@ import org.eclipse.leshan.server.registration.RegistrationUpdate; | @@ -26,7 +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.convertToIdVerFromObjectId; | 29 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; |
30 | 30 | ||
31 | @Slf4j | 31 | @Slf4j |
32 | public class LwM2mServerListener { | 32 | public class LwM2mServerListener { |
@@ -92,7 +92,7 @@ public class LwM2mServerListener { | @@ -92,7 +92,7 @@ public class LwM2mServerListener { | ||
92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { | 92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
93 | if (registration != null) { | 93 | if (registration != null) { |
94 | try { | 94 | try { |
95 | - service.onObservationResponse(registration, convertToIdVerFromObjectId(observation.getPath().toString(), registration), response); | 95 | + service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), response); |
96 | } catch (Exception e) { | 96 | } catch (Exception e) { |
97 | log.error("[{}] onResponse", e.toString()); | 97 | log.error("[{}] onResponse", e.toString()); |
98 | 98 | ||
@@ -107,7 +107,7 @@ public class LwM2mServerListener { | @@ -107,7 +107,7 @@ public class LwM2mServerListener { | ||
107 | 107 | ||
108 | @Override | 108 | @Override |
109 | public void newObservation(Observation observation, Registration registration) { | 109 | public void newObservation(Observation observation, Registration registration) { |
110 | -// log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); | 110 | + log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint()); |
111 | } | 111 | } |
112 | }; | 112 | }; |
113 | 113 |
@@ -30,31 +30,33 @@ package org.thingsboard.server.transport.lwm2m.server; | @@ -30,31 +30,33 @@ package org.thingsboard.server.transport.lwm2m.server; | ||
30 | * limitations under the License. | 30 | * limitations under the License. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | -import com.google.gson.JsonElement; | ||
34 | -import com.google.gson.JsonObject; | ||
35 | import lombok.Getter; | 33 | import lombok.Getter; |
36 | import lombok.extern.slf4j.Slf4j; | 34 | import lombok.extern.slf4j.Slf4j; |
37 | import org.eclipse.leshan.core.model.DDFFileParser; | 35 | import org.eclipse.leshan.core.model.DDFFileParser; |
38 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; | 36 | import org.eclipse.leshan.core.model.DefaultDDFFileValidator; |
39 | import org.eclipse.leshan.core.model.InvalidDDFFileException; | 37 | import org.eclipse.leshan.core.model.InvalidDDFFileException; |
40 | import org.eclipse.leshan.core.model.ObjectModel; | 38 | import org.eclipse.leshan.core.model.ObjectModel; |
39 | +import org.eclipse.leshan.core.model.ResourceModel; | ||
40 | +import org.eclipse.leshan.core.node.codec.CodecException; | ||
41 | import org.springframework.stereotype.Component; | 41 | import org.springframework.stereotype.Component; |
42 | import org.thingsboard.server.common.transport.TransportContext; | 42 | import org.thingsboard.server.common.transport.TransportContext; |
43 | import org.thingsboard.server.common.transport.TransportResourceCache; | 43 | import org.thingsboard.server.common.transport.TransportResourceCache; |
44 | import org.thingsboard.server.common.transport.TransportService; | 44 | import org.thingsboard.server.common.transport.TransportService; |
45 | import org.thingsboard.server.common.transport.TransportServiceCallback; | 45 | import org.thingsboard.server.common.transport.TransportServiceCallback; |
46 | -import org.thingsboard.server.common.transport.adaptor.AdaptorException; | ||
47 | import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; | 46 | import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer; |
47 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
48 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; | 48 | import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg; |
49 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; | 49 | import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg; |
50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | 50 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
51 | -import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; | ||
52 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 51 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
53 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; | 52 | import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor; |
54 | 53 | ||
55 | import java.io.ByteArrayInputStream; | 54 | import java.io.ByteArrayInputStream; |
56 | import java.io.IOException; | 55 | import java.io.IOException; |
56 | +import java.util.ArrayList; | ||
57 | +import java.util.List; | ||
57 | 58 | ||
59 | +import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V; | ||
58 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; | 60 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; |
59 | 61 | ||
60 | @Slf4j | 62 | @Slf4j |
@@ -91,7 +93,7 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -91,7 +93,7 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
91 | /** | 93 | /** |
92 | * send to Thingsboard Attribute || Telemetry | 94 | * send to Thingsboard Attribute || Telemetry |
93 | * | 95 | * |
94 | - * @param msg - JsonObject: [{name: value}] | 96 | + * @param msg - JsonObject: [{name: value}] |
95 | * @return - dummy | 97 | * @return - dummy |
96 | */ | 98 | */ |
97 | private <T> TransportServiceCallback<Void> getPubAckCallbackSendAttrTelemetry(final T msg) { | 99 | private <T> TransportServiceCallback<Void> getPubAckCallbackSendAttrTelemetry(final T msg) { |
@@ -108,33 +110,29 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -108,33 +110,29 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
108 | }; | 110 | }; |
109 | } | 111 | } |
110 | 112 | ||
111 | - public void sendParametersOnThingsboard(JsonElement msg, String topicName, SessionInfoProto sessionInfo) { | ||
112 | - try { | ||
113 | - if (topicName.equals(LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) { | ||
114 | - PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg); | ||
115 | - TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postAttributeMsg); | ||
116 | - transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
117 | - } else if (topicName.equals(LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC)) { | ||
118 | - PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg); | ||
119 | - TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postTelemetryMsg); | ||
120 | - transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
121 | - } | ||
122 | - } catch (AdaptorException e) { | ||
123 | - log.error("[{}] Failed to process publish msg [{}]", topicName, e); | ||
124 | - log.info("[{}] Closing current session due to invalid publish", topicName); | ||
125 | - } | 113 | + public void sendParametersOnThingsboardAttribute(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { |
114 | + PostAttributeMsg.Builder request = PostAttributeMsg.newBuilder(); | ||
115 | + request.addAllKv(result); | ||
116 | + PostAttributeMsg postAttributeMsg = request.build(); | ||
117 | + TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postAttributeMsg); | ||
118 | + transportService.process(sessionInfo, postAttributeMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
126 | } | 119 | } |
127 | 120 | ||
128 | - public JsonObject getTelemetryMsgObject(String logMsg) { | ||
129 | - JsonObject telemetries = new JsonObject(); | ||
130 | - telemetries.addProperty(LOG_LW2M_TELEMETRY, logMsg); | ||
131 | - return telemetries; | 121 | + public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { |
122 | + PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder(); | ||
123 | + TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder(); | ||
124 | + builder.setTs(System.currentTimeMillis()); | ||
125 | + builder.addAllKv(result); | ||
126 | + request.addTsKvList(builder.build()); | ||
127 | + PostTelemetryMsg postTelemetryMsg = request.build(); | ||
128 | + TransportServiceCallback call = this.getPubAckCallbackSendAttrTelemetry(postTelemetryMsg); | ||
129 | + transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSendAttrTelemetry(call)); | ||
132 | } | 130 | } |
133 | 131 | ||
134 | /** | 132 | /** |
135 | * @return - sessionInfo after access connect client | 133 | * @return - sessionInfo after access connect client |
136 | */ | 134 | */ |
137 | - public SessionInfoProto getValidateSessionInfo(ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) { | 135 | + public SessionInfoProto getValidateSessionInfo(TransportProtos.ValidateDeviceCredentialsResponseMsg msg, long mostSignificantBits, long leastSignificantBits) { |
138 | return SessionInfoProto.newBuilder() | 136 | return SessionInfoProto.newBuilder() |
139 | .setNodeId(this.getNodeId()) | 137 | .setNodeId(this.getNodeId()) |
140 | .setSessionIdMSB(mostSignificantBits) | 138 | .setSessionIdMSB(mostSignificantBits) |
@@ -159,4 +157,90 @@ public class LwM2mTransportContextServer extends TransportContext { | @@ -159,4 +157,90 @@ public class LwM2mTransportContextServer extends TransportContext { | ||
159 | return null; | 157 | return null; |
160 | } | 158 | } |
161 | } | 159 | } |
160 | + | ||
161 | + /** | ||
162 | + * | ||
163 | + * @param logMsg - info about Logs | ||
164 | + * @return- KeyValueProto for telemetry (Logs) | ||
165 | + */ | ||
166 | + public List <TransportProtos.KeyValueProto> getKvLogyToThingsboard(String logMsg) { | ||
167 | + List <TransportProtos.KeyValueProto> result = new ArrayList<>(); | ||
168 | + result.add(TransportProtos.KeyValueProto.newBuilder() | ||
169 | + .setKey(LOG_LW2M_TELEMETRY) | ||
170 | + .setType(TransportProtos.KeyValueType.STRING_V) | ||
171 | + .setStringV(logMsg).build()); | ||
172 | + return result; | ||
173 | + } | ||
174 | + | ||
175 | + /** | ||
176 | + * @return - KeyValueProto for attribute/telemetry (change value) | ||
177 | + * @throws CodecException - | ||
178 | + */ | ||
179 | + | ||
180 | + public TransportProtos.KeyValueProto getKvAttrTelemetryToThingsboard(ResourceModel.Type resourceType, String resourceName, Object value, boolean isMultiInstances) { | ||
181 | + TransportProtos.KeyValueProto.Builder kvProto = TransportProtos.KeyValueProto.newBuilder().setKey(resourceName); | ||
182 | + if (isMultiInstances) { | ||
183 | + kvProto.setType(TransportProtos.KeyValueType.JSON_V) | ||
184 | + .setJsonV((String) value); | ||
185 | + } | ||
186 | + else { | ||
187 | + switch (resourceType) { | ||
188 | + case BOOLEAN: | ||
189 | + kvProto.setType(BOOLEAN_V).setBoolV((Boolean) value).build(); | ||
190 | + break; | ||
191 | + case STRING: | ||
192 | + case TIME: | ||
193 | + case OPAQUE: | ||
194 | + case OBJLNK: | ||
195 | + kvProto.setType(TransportProtos.KeyValueType.STRING_V).setStringV((String) value); | ||
196 | + break; | ||
197 | + case INTEGER: | ||
198 | + kvProto.setType(TransportProtos.KeyValueType.LONG_V).setLongV((Long) value); | ||
199 | + break; | ||
200 | + case FLOAT: | ||
201 | + kvProto.setType(TransportProtos.KeyValueType.DOUBLE_V).setDoubleV((Double) value); | ||
202 | + } | ||
203 | + } | ||
204 | + return kvProto.build(); | ||
205 | + } | ||
206 | + | ||
207 | + /** | ||
208 | + * | ||
209 | + * @param currentType - | ||
210 | + * @param resourcePath - | ||
211 | + * @return | ||
212 | + */ | ||
213 | + public ResourceModel.Type getResourceModelTypeEqualsKvProtoValueType(ResourceModel.Type currentType, String resourcePath) { | ||
214 | + switch (currentType) { | ||
215 | + case BOOLEAN: | ||
216 | + return ResourceModel.Type.BOOLEAN; | ||
217 | + case STRING: | ||
218 | + case TIME: | ||
219 | + case OPAQUE: | ||
220 | + case OBJLNK: | ||
221 | + return ResourceModel.Type.STRING; | ||
222 | + case INTEGER: | ||
223 | + return ResourceModel.Type.INTEGER; | ||
224 | + case FLOAT: | ||
225 | + return ResourceModel.Type.FLOAT; | ||
226 | + default: | ||
227 | + } | ||
228 | + throw new CodecException("Invalid ResourceModel_Type for resource %s, got %s", resourcePath, currentType); | ||
229 | + } | ||
230 | + | ||
231 | + public Object getValueFromKvProto (TransportProtos.KeyValueProto kv) { | ||
232 | + switch (kv.getType()) { | ||
233 | + case BOOLEAN_V: | ||
234 | + return kv.getBoolV(); | ||
235 | + case LONG_V: | ||
236 | + return kv.getLongV(); | ||
237 | + case DOUBLE_V: | ||
238 | + return kv.getDoubleV(); | ||
239 | + case STRING_V: | ||
240 | + return kv.getStringV(); | ||
241 | + case JSON_V: | ||
242 | + return kv.getJsonV(); | ||
243 | + } | ||
244 | + return null; | ||
245 | + } | ||
162 | } | 246 | } |
@@ -75,6 +75,8 @@ public class LwM2mTransportHandler { | @@ -75,6 +75,8 @@ public class LwM2mTransportHandler { | ||
75 | public static final String KEY_NAME = "keyName"; | 75 | public static final String KEY_NAME = "keyName"; |
76 | public static final String OBSERVE = "observe"; | 76 | public static final String OBSERVE = "observe"; |
77 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; | 77 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; |
78 | + public static final String RESOURCE_VALUE = "resValue"; | ||
79 | + public static final String RESOURCE_TYPE = "resType"; | ||
78 | 80 | ||
79 | private static final String REQUEST = "/request"; | 81 | private static final String REQUEST = "/request"; |
80 | private static final String RESPONSE = "/response"; | 82 | private static final String RESPONSE = "/response"; |
@@ -333,28 +335,30 @@ public class LwM2mTransportHandler { | @@ -333,28 +335,30 @@ public class LwM2mTransportHandler { | ||
333 | }; | 335 | }; |
334 | } | 336 | } |
335 | 337 | ||
336 | - public static String convertToObjectIdFromIdVer(String key) { | 338 | + public static String convertPathFromIdVerToObjectId(String pathIdVer) { |
337 | try { | 339 | try { |
338 | - String[] keyArray = key.split(LWM2M_SEPARATOR_PATH); | 340 | + String[] keyArray = pathIdVer.split(LWM2M_SEPARATOR_PATH); |
339 | if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { | 341 | if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { |
340 | keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; | 342 | keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; |
341 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); | 343 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
342 | - } else { | ||
343 | - return key; | 344 | + } |
345 | + else { | ||
346 | + return pathIdVer; | ||
344 | } | 347 | } |
345 | } catch (Exception e) { | 348 | } catch (Exception e) { |
346 | return null; | 349 | return null; |
347 | } | 350 | } |
348 | } | 351 | } |
349 | 352 | ||
350 | - public static String convertToIdVerFromObjectId(String path, Registration registration) { | 353 | + public static String convertPathFromObjectIdToIdVer(String path, Registration registration) { |
351 | String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); | 354 | String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); |
352 | try { | 355 | try { |
353 | String[] keyArray = path.split(LWM2M_SEPARATOR_PATH); | 356 | String[] keyArray = path.split(LWM2M_SEPARATOR_PATH); |
354 | if (keyArray.length > 1) { | 357 | if (keyArray.length > 1) { |
355 | keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; | 358 | keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; |
356 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); | 359 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
357 | - } else { | 360 | + } |
361 | + else { | ||
358 | return path; | 362 | return path; |
359 | } | 363 | } |
360 | } catch (Exception e) { | 364 | } catch (Exception e) { |
@@ -69,8 +69,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle | @@ -69,8 +69,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle | ||
69 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; | 69 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; |
70 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE; | 70 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE; |
71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; | 71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; |
72 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; | ||
73 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer; | 72 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
73 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; | ||
74 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.createWriteAttributeRequest; | 74 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.createWriteAttributeRequest; |
75 | 75 | ||
76 | @Slf4j | 76 | @Slf4j |
@@ -114,7 +114,7 @@ public class LwM2mTransportRequest { | @@ -114,7 +114,7 @@ public class LwM2mTransportRequest { | ||
114 | */ | 114 | */ |
115 | public void sendAllRequest(Registration registration, String targetIdVer, String typeOper, | 115 | public void sendAllRequest(Registration registration, String targetIdVer, String typeOper, |
116 | String contentFormatParam, Observation observation, Object params, long timeoutInMs) { | 116 | String contentFormatParam, Observation observation, Object params, long timeoutInMs) { |
117 | - String target = convertToObjectIdFromIdVer(targetIdVer); | 117 | + String target = convertPathFromIdVerToObjectId(targetIdVer); |
118 | LwM2mPath resultIds = new LwM2mPath(target); | 118 | LwM2mPath resultIds = new LwM2mPath(target); |
119 | if (registration != null && resultIds.getObjectId() >= 0) { | 119 | if (registration != null && resultIds.getObjectId() >= 0) { |
120 | DownlinkRequest request = null; | 120 | DownlinkRequest request = null; |
@@ -204,7 +204,7 @@ public class LwM2mTransportRequest { | @@ -204,7 +204,7 @@ public class LwM2mTransportRequest { | ||
204 | private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs) { | 204 | private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs) { |
205 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { | 205 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { |
206 | if (!lwM2MClient.isInit()) { | 206 | if (!lwM2MClient.isInit()) { |
207 | - lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration)); | 207 | + lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
208 | } | 208 | } |
209 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { | 209 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { |
210 | this.handleResponse(registration, request.getPath().toString(), response, request); | 210 | this.handleResponse(registration, request.getPath().toString(), response, request); |
@@ -228,7 +228,7 @@ public class LwM2mTransportRequest { | @@ -228,7 +228,7 @@ public class LwM2mTransportRequest { | ||
228 | } | 228 | } |
229 | }, e -> { | 229 | }, e -> { |
230 | if (!lwM2MClient.isInit()) { | 230 | if (!lwM2MClient.isInit()) { |
231 | - lwM2MClient.initValue(this.serviceImpl, convertToIdVerFromObjectId(request.getPath().toString(), registration)); | 231 | + lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
232 | } | 232 | } |
233 | String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", | 233 | String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", |
234 | LOG_LW2M_ERROR, request.getPath().toString(), e.toString()); | 234 | LOG_LW2M_ERROR, request.getPath().toString(), e.toString()); |
@@ -287,7 +287,7 @@ public class LwM2mTransportRequest { | @@ -287,7 +287,7 @@ public class LwM2mTransportRequest { | ||
287 | * @param response - | 287 | * @param response - |
288 | */ | 288 | */ |
289 | private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) { | 289 | private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) { |
290 | - String pathIdVer = convertToIdVerFromObjectId(path, registration); | 290 | + String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); |
291 | if (response instanceof ReadResponse) { | 291 | if (response instanceof ReadResponse) { |
292 | serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); | 292 | serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); |
293 | } else if (response instanceof CancelObservationResponse) { | 293 | } else if (response instanceof CancelObservationResponse) { |
@@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server; | @@ -18,6 +18,7 @@ package org.thingsboard.server.transport.lwm2m.server; | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | import com.google.common.collect.Sets; | 19 | import com.google.common.collect.Sets; |
20 | import com.google.gson.Gson; | 20 | import com.google.gson.Gson; |
21 | +import com.google.gson.GsonBuilder; | ||
21 | import com.google.gson.JsonArray; | 22 | import com.google.gson.JsonArray; |
22 | import com.google.gson.JsonElement; | 23 | import com.google.gson.JsonElement; |
23 | import com.google.gson.JsonObject; | 24 | import com.google.gson.JsonObject; |
@@ -42,7 +43,6 @@ import org.thingsboard.server.common.data.Device; | @@ -42,7 +43,6 @@ 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.transport.TransportService; | 44 | import org.thingsboard.server.common.transport.TransportService; |
44 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; | 45 | import org.thingsboard.server.common.transport.adaptor.AdaptorException; |
45 | -import org.thingsboard.server.common.transport.adaptor.JsonConverter; | ||
46 | import org.thingsboard.server.common.transport.service.DefaultTransportService; | 46 | import org.thingsboard.server.common.transport.service.DefaultTransportService; |
47 | import org.thingsboard.server.gen.transport.TransportProtos; | 47 | import org.thingsboard.server.gen.transport.TransportProtos; |
48 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; | 48 | import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg; |
@@ -52,12 +52,12 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | @@ -52,12 +52,12 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | ||
52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
54 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; | 54 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
55 | +import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; | ||
55 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; | 56 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; |
56 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | 57 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
57 | 58 | ||
58 | import javax.annotation.PostConstruct; | 59 | import javax.annotation.PostConstruct; |
59 | import java.util.ArrayList; | 60 | import java.util.ArrayList; |
60 | -import java.util.Arrays; | ||
61 | import java.util.Collection; | 61 | import java.util.Collection; |
62 | import java.util.HashSet; | 62 | import java.util.HashSet; |
63 | import java.util.LinkedHashSet; | 63 | import java.util.LinkedHashSet; |
@@ -76,24 +76,19 @@ import java.util.stream.Collectors; | @@ -76,24 +76,19 @@ import java.util.stream.Collectors; | ||
76 | 76 | ||
77 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; | 77 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
78 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 78 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
79 | -import static org.thingsboard.server.common.transport.util.JsonUtils.getJsonObject; | ||
80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; | 79 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; |
81 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; | 80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; |
82 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_TOPIC; | ||
83 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_TELEMETRY_TOPIC; | ||
84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER; | 81 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER; |
85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE; | 82 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE; |
86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ; | 83 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ; |
87 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; | 84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
88 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | 85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; |
89 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_TELEMETRY; | ||
90 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; | 86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; |
91 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE; | 87 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE; |
92 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE; | 88 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE; |
93 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; | 89 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; |
94 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; | 90 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; |
95 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; | ||
96 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer; | 91 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
97 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; | 92 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; |
98 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; | 93 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; |
99 | 94 | ||
@@ -163,6 +158,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -163,6 +158,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
163 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); | 158 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); |
164 | transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); | 159 | transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null); |
165 | transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); | 160 | transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null); |
161 | + transportService.process(sessionInfo, TransportProtos.SubscribeToRPCMsg.newBuilder().build(), null); | ||
166 | this.initLwM2mFromClientValue(registration, lwM2MClient); | 162 | this.initLwM2mFromClientValue(registration, lwM2MClient); |
167 | this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration); | 163 | this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration); |
168 | } else { | 164 | } else { |
@@ -309,33 +305,32 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -309,33 +305,32 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
309 | @Override | 305 | @Override |
310 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { | 306 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { |
311 | if (msg.getSharedUpdatedCount() > 0) { | 307 | if (msg.getSharedUpdatedCount() > 0) { |
312 | - JsonElement el = JsonConverter.toJson(msg); | ||
313 | - el.getAsJsonObject().entrySet().forEach(de -> { | ||
314 | - String pathIdVer = this.getPathAttributeUpdate(sessionInfo, de.getKey()); | ||
315 | - String value = de.getValue().getAsString(); | 308 | + msg.getSharedUpdatedList().forEach(tsKvProto -> { |
309 | + String pathName = tsKvProto.getKv().getKey(); | ||
310 | + String pathIdVer = this.validatePathIntoProfile(sessionInfo, pathName); | ||
311 | + Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | ||
316 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 312 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); |
317 | - LwM2mClientProfile clientProfile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | ||
318 | - if (pathIdVer != null && !pathIdVer.isEmpty() && (this.validatePathInAttrProfile(clientProfile, pathIdVer) || this.validatePathInTelemetryProfile(clientProfile, pathIdVer))) { | 313 | + if (pathIdVer != null) { |
319 | ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer); | 314 | ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer); |
320 | if (resourceModel != null && resourceModel.operations.isWritable()) { | 315 | if (resourceModel != null && resourceModel.operations.isWritable()) { |
321 | - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), pathIdVer, POST_TYPE_OPER_WRITE_REPLACE, | ||
322 | - ContentFormat.TLV.getName(), null, value, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 316 | + this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer); |
323 | } else { | 317 | } else { |
324 | - log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, value); | 318 | + log.error("Resource path - [{}] value - [{}] is not Writable and cannot be updated", pathIdVer, valueNew); |
325 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", | 319 | String logMsg = String.format("%s: attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", |
326 | - LOG_LW2M_ERROR, pathIdVer, value); | 320 | + LOG_LW2M_ERROR, pathIdVer, valueNew); |
327 | this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | 321 | this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); |
328 | } | 322 | } |
329 | } else { | 323 | } else { |
330 | - log.error("Attribute name - [{}] value - [{}] is not present as attribute in profile and cannot be updated", de.getKey(), value); | 324 | + log.error("Resource name name - [{}] value - [{}] is not present as attribute/telemetry in profile and cannot be updated", pathName, valueNew); |
331 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", | 325 | String logMsg = String.format("%s: attributeUpdate: attribute name - %s value - %s is not present as attribute in profile and cannot be updated", |
332 | - LOG_LW2M_ERROR, de.getKey(), value); | 326 | + LOG_LW2M_ERROR, pathName, valueNew); |
333 | this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | 327 | this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); |
334 | } | 328 | } |
335 | }); | 329 | }); |
336 | } else if (msg.getSharedDeletedCount() > 0) { | 330 | } else if (msg.getSharedDeletedCount() > 0) { |
337 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); | 331 | log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); |
338 | } | 332 | } |
333 | + | ||
339 | } | 334 | } |
340 | 335 | ||
341 | /** | 336 | /** |
@@ -462,32 +457,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -462,32 +457,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
462 | } | 457 | } |
463 | 458 | ||
464 | /** | 459 | /** |
465 | - * @param msg - text msg | 460 | + * @param logMsg - text msg |
466 | * @param registration - Id of Registration LwM2M Client | 461 | * @param registration - Id of Registration LwM2M Client |
467 | */ | 462 | */ |
468 | - public void sendLogsToThingsboard(String msg, Registration registration) { | ||
469 | - if (msg != null) { | ||
470 | - JsonObject telemetries = new JsonObject(); | ||
471 | - telemetries.addProperty(LOG_LW2M_TELEMETRY, msg); | ||
472 | - this.updateParametersOnThingsboard(telemetries, DEVICE_TELEMETRY_TOPIC, registration); | ||
473 | - } | ||
474 | - } | ||
475 | - | ||
476 | - | ||
477 | - /** | ||
478 | - * // !!! Ok | ||
479 | - * Prepare send to Thigsboard callback - Attribute or Telemetry | ||
480 | - * | ||
481 | - * @param msg - JsonArray: [{name: value}] | ||
482 | - * @param topicName - Api Attribute or Telemetry | ||
483 | - * @param registration - Id of Registration LwM2M Client | ||
484 | - */ | ||
485 | - public void updateParametersOnThingsboard(JsonElement msg, String topicName, Registration registration) { | 463 | + public void sendLogsToThingsboard(String logMsg, Registration registration) { |
486 | SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | 464 | SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); |
487 | - if (sessionInfo != null) { | ||
488 | - lwM2mTransportContextServer.sendParametersOnThingsboard(msg, topicName, sessionInfo); | ||
489 | - } else { | ||
490 | - log.error("Client: [{}] updateParametersOnThingsboard [{}] sessionInfo ", registration, null); | 465 | + if (logMsg != null && sessionInfo != null) { |
466 | + this.lwM2mTransportContextServer.sendParametersOnThingsboardTelemetry(this.lwM2mTransportContextServer.getKvLogyToThingsboard(logMsg), sessionInfo); | ||
491 | } | 467 | } |
492 | } | 468 | } |
493 | 469 | ||
@@ -517,7 +493,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -517,7 +493,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
517 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_READ, clientObjects); | 493 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_READ, clientObjects); |
518 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_OBSERVE, clientObjects); | 494 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_OBSERVE, clientObjects); |
519 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, PUT_TYPE_OPER_WRITE_ATTRIBUTES, clientObjects); | 495 | this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, PUT_TYPE_OPER_WRITE_ATTRIBUTES, clientObjects); |
520 | -// this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_DISCOVER, clientObjects); | 496 | + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_DISCOVER, clientObjects); |
521 | } | 497 | } |
522 | } | 498 | } |
523 | 499 | ||
@@ -577,17 +553,20 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -577,17 +553,20 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
577 | * @param registration - Registration LwM2M Client | 553 | * @param registration - Registration LwM2M Client |
578 | */ | 554 | */ |
579 | private void updateAttrTelemetry(Registration registration, Set<String> paths) { | 555 | private void updateAttrTelemetry(Registration registration, Set<String> paths) { |
580 | - JsonObject attributes = new JsonObject(); | ||
581 | - JsonObject telemetries = new JsonObject(); | ||
582 | try { | 556 | try { |
583 | - this.getParametersFromProfile(attributes, telemetries, registration, paths); | 557 | + ResultsAddKeyValueProto results = getParametersFromProfile(registration, paths); |
558 | + SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration); | ||
559 | + if (results != null && sessionInfo != null) { | ||
560 | + if (results.getResultAttributes().size() > 0) { | ||
561 | + this.lwM2mTransportContextServer.sendParametersOnThingsboardAttribute(results.getResultAttributes(), sessionInfo); | ||
562 | + } | ||
563 | + if (results.getResultTelemetries().size() > 0) { | ||
564 | + this.lwM2mTransportContextServer.sendParametersOnThingsboardTelemetry(results.getResultTelemetries(), sessionInfo); | ||
565 | + } | ||
566 | + } | ||
584 | } catch (Exception e) { | 567 | } catch (Exception e) { |
585 | log.error("UpdateAttrTelemetry", e); | 568 | log.error("UpdateAttrTelemetry", e); |
586 | } | 569 | } |
587 | - if (attributes.getAsJsonObject().entrySet().size() > 0) | ||
588 | - this.updateParametersOnThingsboard(attributes, DEVICE_ATTRIBUTES_TOPIC, registration); | ||
589 | - if (telemetries.getAsJsonObject().entrySet().size() > 0) | ||
590 | - this.updateParametersOnThingsboard(telemetries, DEVICE_TELEMETRY_TOPIC, registration); | ||
591 | } | 570 | } |
592 | 571 | ||
593 | /** | 572 | /** |
@@ -700,73 +679,99 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -700,73 +679,99 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
700 | } | 679 | } |
701 | 680 | ||
702 | /** | 681 | /** |
703 | - * @param registration - | ||
704 | - * @return all instances in client | ||
705 | - */ | ||
706 | - private Set<String> getAllInstancesInClient(Registration registration) { | ||
707 | - Set<String> clientInstances = ConcurrentHashMap.newKeySet(); | ||
708 | - Arrays.stream(registration.getObjectLinks()).forEach(url -> { | ||
709 | - LwM2mPath pathIds = new LwM2mPath(url.getUrl()); | ||
710 | - if (pathIds.isObjectInstance()) { | ||
711 | - clientInstances.add(convertToIdVerFromObjectId(url.getUrl(), registration)); | ||
712 | - } | ||
713 | - }); | ||
714 | - return (clientInstances.size() > 0) ? clientInstances : null; | ||
715 | - } | ||
716 | - | ||
717 | - /** | ||
718 | - * @param attributes - new JsonObject | ||
719 | - * @param telemetry - new JsonObject | 682 | + * // * @param attributes - new JsonObject |
683 | + * // * @param telemetry - new JsonObject | ||
684 | + * | ||
720 | * @param registration - Registration LwM2M Client | 685 | * @param registration - Registration LwM2M Client |
721 | * @param path - | 686 | * @param path - |
722 | */ | 687 | */ |
723 | - private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set<String> path) { | 688 | + private ResultsAddKeyValueProto getParametersFromProfile(Registration registration, Set<String> path) { |
724 | if (path != null && path.size() > 0) { | 689 | if (path != null && path.size() > 0) { |
690 | + ResultsAddKeyValueProto results = new ResultsAddKeyValueProto(); | ||
725 | LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); | 691 | LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); |
726 | - lwM2MClientProfile.getPostAttributeProfile().forEach(idVer -> { | ||
727 | - if (path.contains(idVer.getAsString())) { | ||
728 | - this.addParameters(idVer.getAsString(), attributes, registration); | 692 | + List<TransportProtos.KeyValueProto> resultAttributes = new ArrayList<>(); |
693 | + lwM2MClientProfile.getPostAttributeProfile().forEach(pathIdVer -> { | ||
694 | + if (path.contains(pathIdVer.getAsString())) { | ||
695 | + TransportProtos.KeyValueProto kvAttr = this.getKvToThingsboard(pathIdVer.getAsString(), registration); | ||
696 | + if (kvAttr != null) { | ||
697 | + resultAttributes.add(kvAttr); | ||
698 | + } | ||
729 | } | 699 | } |
730 | }); | 700 | }); |
731 | - lwM2MClientProfile.getPostTelemetryProfile().forEach(idVer -> { | ||
732 | - if (path.contains(idVer.getAsString())) { | ||
733 | - this.addParameters(idVer.getAsString(), telemetry, registration); | 701 | + List<TransportProtos.KeyValueProto> resultTelemetries = new ArrayList<>(); |
702 | + lwM2MClientProfile.getPostTelemetryProfile().forEach(pathIdVer -> { | ||
703 | + if (path.contains(pathIdVer.getAsString())) { | ||
704 | + TransportProtos.KeyValueProto kvAttr = this.getKvToThingsboard(pathIdVer.getAsString(), registration); | ||
705 | + if (kvAttr != null) { | ||
706 | + resultTelemetries.add(kvAttr); | ||
707 | + } | ||
734 | } | 708 | } |
735 | }); | 709 | }); |
710 | + if (resultAttributes.size() > 0) { | ||
711 | + results.setResultAttributes(resultAttributes); | ||
712 | + } | ||
713 | + if (resultTelemetries.size() > 0) { | ||
714 | + results.setResultTelemetries(resultTelemetries); | ||
715 | + } | ||
716 | + return results; | ||
736 | } | 717 | } |
718 | + return null; | ||
737 | } | 719 | } |
738 | 720 | ||
739 | - /** | ||
740 | - * @param parameters - JsonObject attributes/telemetry | ||
741 | - * @param registration - Registration LwM2M Client | ||
742 | - */ | ||
743 | - private void addParameters(String path, JsonObject parameters, Registration registration) { | ||
744 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 721 | +// public TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { |
722 | +// ResultsResourceValue resultsResourceValue = getResultsResourceValue(pathIdVer, registration); | ||
723 | +// return resultsResourceValue != null ? this.lwM2mTransportContextServer.getKvAttrTelemetryToThingsboard(resultsResourceValue) : null; | ||
724 | +// } | ||
725 | + | ||
726 | + private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { | ||
727 | + LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); | ||
745 | JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); | 728 | JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); |
746 | - if (names != null && names.has(path)) { | ||
747 | - String resName = names.get(path).getAsString(); | ||
748 | - if (resName != null && !resName.isEmpty()) { | 729 | + if (names != null && names.has(pathIdVer)) { |
730 | + String resourceName = names.get(pathIdVer).getAsString(); | ||
731 | + if (resourceName != null && !resourceName.isEmpty()) { | ||
749 | try { | 732 | try { |
750 | - String resValue = this.getResourceValueToString(lwM2MClient, path); | ||
751 | - parameters.addProperty(resName, resValue); | 733 | + LwM2mResource resourceValue = lwM2MClient != null ? getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) : null; |
734 | + if (resourceValue != null) { | ||
735 | + ResourceModel.Type currentType = resourceValue.getType(); | ||
736 | + ResourceModel.Type expectedType = this.lwM2mTransportContextServer.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); | ||
737 | + Object valueKvProto = null; | ||
738 | + if (resourceValue.isMultiInstances()) { | ||
739 | + valueKvProto = new JsonObject(); | ||
740 | + Object finalvalueKvProto = valueKvProto; | ||
741 | + Gson gson = new GsonBuilder().create(); | ||
742 | + resourceValue.getValues().forEach((k, v) -> { | ||
743 | + Object val = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, | ||
744 | + new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); | ||
745 | + JsonElement element = gson.toJsonTree(val, val.getClass()); | ||
746 | + ((JsonObject) finalvalueKvProto).add(String.valueOf(k), element); | ||
747 | + }); | ||
748 | + valueKvProto = gson.toJson(valueKvProto); | ||
749 | + } else { | ||
750 | + valueKvProto = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, | ||
751 | + new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); | ||
752 | + } | ||
753 | + return valueKvProto != null ? this.lwM2mTransportContextServer.getKvAttrTelemetryToThingsboard(currentType, resourceName, valueKvProto, resourceValue.isMultiInstances()) : null; | ||
754 | + } | ||
752 | } catch (Exception e) { | 755 | } catch (Exception e) { |
753 | log.error("Failed to add parameters.", e); | 756 | log.error("Failed to add parameters.", e); |
754 | } | 757 | } |
755 | } | 758 | } |
756 | } else { | 759 | } else { |
757 | - log.error("Failed to add parameters. path: [{}], names: [{}]", path, names); | 760 | + log.error("Failed to add parameters. path: [{}], names: [{}]", pathIdVer, names); |
758 | } | 761 | } |
762 | + return null; | ||
759 | } | 763 | } |
760 | 764 | ||
761 | /** | 765 | /** |
762 | - * @param path - path resource | ||
763 | - * @return - value of Resource or null | 766 | + * @param pathIdVer - path resource |
767 | + * @return - value of Resource into format KvProto or null | ||
764 | */ | 768 | */ |
765 | - private String getResourceValueToString(LwM2mClient lwM2MClient, String path) { | ||
766 | - LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(path)); | ||
767 | - LwM2mResource resourceValue = this.returnResourceValueFromLwM2MClient(lwM2MClient, path); | ||
768 | - return resourceValue == null ? null : | ||
769 | - this.converter.convertValue(resourceValue.isMultiInstances() ? resourceValue.getValues() : resourceValue.getValue(), resourceValue.getType(), ResourceModel.Type.STRING, pathIds).toString(); | 769 | + private Object getResourceValueFormatKv(LwM2mClient lwM2MClient, String pathIdVer) { |
770 | + LwM2mResource resourceValue = this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer); | ||
771 | + ResourceModel.Type currentType = resourceValue.getType(); | ||
772 | + ResourceModel.Type expectedType = this.lwM2mTransportContextServer.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); | ||
773 | + return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, | ||
774 | + new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); | ||
770 | } | 775 | } |
771 | 776 | ||
772 | /** | 777 | /** |
@@ -774,9 +779,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -774,9 +779,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
774 | * @param path - | 779 | * @param path - |
775 | * @return - return value of Resource by idPath | 780 | * @return - return value of Resource by idPath |
776 | */ | 781 | */ |
777 | - private LwM2mResource returnResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) { | 782 | + private LwM2mResource getResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) { |
778 | LwM2mResource resourceValue = null; | 783 | LwM2mResource resourceValue = null; |
779 | - if (new LwM2mPath(convertToObjectIdFromIdVer(path)).isResource()) { | 784 | + if (new LwM2mPath(convertPathFromIdVerToObjectId(path)).isResource()) { |
780 | resourceValue = lwM2MClient.getResources().get(path).getLwM2mResource(); | 785 | resourceValue = lwM2MClient.getResources().get(path).getLwM2mResource(); |
781 | } | 786 | } |
782 | return resourceValue; | 787 | return resourceValue; |
@@ -959,7 +964,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -959,7 +964,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
959 | */ | 964 | */ |
960 | private void readResourceValueObserve(Registration registration, Set<String> targets, String typeOper) { | 965 | private void readResourceValueObserve(Registration registration, Set<String> targets, String typeOper) { |
961 | targets.forEach(target -> { | 966 | targets.forEach(target -> { |
962 | - LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(target)); | 967 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); |
963 | if (pathIds.isResource()) { | 968 | if (pathIds.isResource()) { |
964 | if (GET_TYPE_OPER_READ.equals(typeOper)) { | 969 | if (GET_TYPE_OPER_READ.equals(typeOper)) { |
965 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, | 970 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, |
@@ -1050,19 +1055,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1050,19 +1055,23 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1050 | private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { | 1055 | private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { |
1051 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 1056 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); |
1052 | paramAnallyzer.forEach(p -> { | 1057 | paramAnallyzer.forEach(p -> { |
1053 | - if (this.returnResourceValueFromLwM2MClient(lwM2MClient, p) != null) { | ||
1054 | - this.setCancelObservationRecourse(registration, convertToObjectIdFromIdVer(p)); | 1058 | + if (this.getResourceValueFromLwM2MClient(lwM2MClient, p) != null) { |
1059 | + this.setCancelObservationRecourse(registration, convertPathFromIdVerToObjectId(p)); | ||
1055 | } | 1060 | } |
1056 | } | 1061 | } |
1057 | ); | 1062 | ); |
1058 | } | 1063 | } |
1059 | 1064 | ||
1060 | - private void putDelayedUpdateResourcesClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { | 1065 | + private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { |
1061 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { | 1066 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { |
1062 | lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE, | 1067 | lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE, |
1063 | ContentFormat.TLV.getName(), null, valueNew, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 1068 | ContentFormat.TLV.getName(), null, valueNew, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); |
1064 | } else { | 1069 | } else { |
1065 | - log.error("05 delayError"); | 1070 | + log.error("Failed update resource [{}] [{}]", path, valueNew); |
1071 | + String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", | ||
1072 | + LOG_LW2M_ERROR, path, valueNew); | ||
1073 | + this.sendLogsToThingsboard(logMsg, lwM2MClient.getRegistration()); | ||
1074 | + log.info("Failed update resource [{}] [{}]", path, valueNew); | ||
1066 | } | 1075 | } |
1067 | } | 1076 | } |
1068 | 1077 | ||
@@ -1082,9 +1091,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1082,9 +1091,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1082 | * @param name - | 1091 | * @param name - |
1083 | * @return path if path isPresent in postProfile | 1092 | * @return path if path isPresent in postProfile |
1084 | */ | 1093 | */ |
1085 | - private String getPathAttributeUpdate(TransportProtos.SessionInfoProto sessionInfo, String name) { | ||
1086 | - String profilePath = this.getPathAttributeUpdateProfile(sessionInfo, name); | ||
1087 | - return !profilePath.isEmpty() ? profilePath : null; | 1094 | + private String validatePathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { |
1095 | + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, name); | ||
1096 | + return !pathIdVer.isEmpty() ? pathIdVer : null; | ||
1088 | } | 1097 | } |
1089 | 1098 | ||
1090 | /** | 1099 | /** |
@@ -1094,7 +1103,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1094,7 +1103,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1094 | * @param name - | 1103 | * @param name - |
1095 | * @return - | 1104 | * @return - |
1096 | */ | 1105 | */ |
1097 | - private String getPathAttributeUpdateProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { | 1106 | + private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { |
1098 | LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | 1107 | LwM2mClientProfile profile = lwM2mClientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); |
1099 | LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | 1108 | LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); |
1100 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() | 1109 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
@@ -1105,41 +1114,50 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1105,41 +1114,50 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1105 | /** | 1114 | /** |
1106 | * Update resource value on client: if there is a difference in values between the current resource values and the shared attribute values | 1115 | * Update resource value on client: if there is a difference in values between the current resource values and the shared attribute values |
1107 | * #1 Get path resource by result attributesResponse | 1116 | * #1 Get path resource by result attributesResponse |
1108 | - * #1.1 If two names have equal path => last time attribute | ||
1109 | - * #2.1 if there is a difference in values between the current resource values and the shared attribute values | ||
1110 | - * => send to client Request Update of value (new value from shared attribute) | ||
1111 | - * and LwM2MClient.delayedRequests.add(path) | ||
1112 | - * #2.1 if there is not a difference in values between the current resource values and the shared attribute values | ||
1113 | * | 1117 | * |
1114 | * @param attributesResponse - | 1118 | * @param attributesResponse - |
1115 | * @param sessionInfo - | 1119 | * @param sessionInfo - |
1116 | */ | 1120 | */ |
1117 | public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { | 1121 | public void onGetAttributesResponse(TransportProtos.GetAttributeResponseMsg attributesResponse, TransportProtos.SessionInfoProto sessionInfo) { |
1118 | try { | 1122 | try { |
1119 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | ||
1120 | - attributesResponse.getSharedAttributeListList().forEach(attr -> { | ||
1121 | - String path = this.getPathAttributeUpdate(sessionInfo, attr.getKv().getKey()); | ||
1122 | - if (path != null) { | ||
1123 | - // #1.1 | ||
1124 | - if (lwM2MClient.getDelayedRequests().containsKey(path) && attr.getTs() > lwM2MClient.getDelayedRequests().get(path).getTs()) { | ||
1125 | - lwM2MClient.getDelayedRequests().put(path, attr); | ||
1126 | - } else { | ||
1127 | - lwM2MClient.getDelayedRequests().put(path, attr); | ||
1128 | - } | ||
1129 | - } | ||
1130 | - }); | ||
1131 | - // #2.1 | ||
1132 | - lwM2MClient.getDelayedRequests().forEach((k, v) -> { | ||
1133 | - ArrayList<TransportProtos.KeyValueProto> listV = new ArrayList<>(); | ||
1134 | - listV.add(v.getKv()); | ||
1135 | - this.putDelayedUpdateResourcesClient(lwM2MClient, this.getResourceValueToString(lwM2MClient, k), getJsonObject(listV).get(v.getKv().getKey()), k); | ||
1136 | - }); | 1123 | + List<TransportProtos.TsKvProto> tsKvProtos = attributesResponse.getSharedAttributeListList(); |
1124 | + this.updateAttriuteFromThingsboard(tsKvProtos, sessionInfo); | ||
1137 | } catch (Exception e) { | 1125 | } catch (Exception e) { |
1138 | log.error(String.valueOf(e)); | 1126 | log.error(String.valueOf(e)); |
1139 | } | 1127 | } |
1140 | } | 1128 | } |
1141 | 1129 | ||
1142 | /** | 1130 | /** |
1131 | + * #1.1 If two names have equal path => last time attribute | ||
1132 | + * #2.1 if there is a difference in values between the current resource values and the shared attribute values | ||
1133 | + * => send to client Request Update of value (new value from shared attribute) | ||
1134 | + * and LwM2MClient.delayedRequests.add(path) | ||
1135 | + * #2.1 if there is not a difference in values between the current resource values and the shared attribute values | ||
1136 | + * | ||
1137 | + * @param tsKvProtos | ||
1138 | + * @param sessionInfo | ||
1139 | + */ | ||
1140 | + public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { | ||
1141 | + LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | ||
1142 | + tsKvProtos.forEach(tsKvProto -> { | ||
1143 | + String pathIdVer = this.validatePathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); | ||
1144 | + if (pathIdVer != null) { | ||
1145 | + // #1.1 | ||
1146 | + if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { | ||
1147 | + lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto); | ||
1148 | + } else if (!lwM2MClient.getDelayedRequests().containsKey(pathIdVer)) { | ||
1149 | + lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto); | ||
1150 | + } | ||
1151 | + } | ||
1152 | + }); | ||
1153 | + // #2.1 | ||
1154 | + lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> { | ||
1155 | + this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), | ||
1156 | + this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()), pathIdVer); | ||
1157 | + }); | ||
1158 | + } | ||
1159 | + | ||
1160 | + /** | ||
1143 | * @param lwM2MClient - | 1161 | * @param lwM2MClient - |
1144 | * @return SessionInfoProto - | 1162 | * @return SessionInfoProto - |
1145 | */ | 1163 | */ |
@@ -1257,7 +1275,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1257,7 +1275,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1257 | 1275 | ||
1258 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { | 1276 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { |
1259 | ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer); | 1277 | ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer); |
1260 | - Integer objectId = new LwM2mPath(convertToObjectIdFromIdVer(pathIdVer)).getObjectId(); | 1278 | + Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId(); |
1261 | String objectVer = validateObjectVerFromKey(pathIdVer); | 1279 | String objectVer = validateObjectVerFromKey(pathIdVer); |
1262 | return resourceModel != null && (isWritableNotOptional ? | 1280 | return resourceModel != null && (isWritableNotOptional ? |
1263 | objectId != null && objectVer != null && objectVer.equals(lwM2mClient.getRegistration().getSupportedVersion(objectId)) && resourceModel.operations.isWritable() : | 1281 | objectId != null && objectVer != null && objectVer.equals(lwM2mClient.getRegistration().getSupportedVersion(objectId)) && resourceModel.operations.isWritable() : |
@@ -39,7 +39,7 @@ import java.util.concurrent.CopyOnWriteArrayList; | @@ -39,7 +39,7 @@ import java.util.concurrent.CopyOnWriteArrayList; | ||
39 | import java.util.stream.Collectors; | 39 | import java.util.stream.Collectors; |
40 | 40 | ||
41 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 41 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
42 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToObjectIdFromIdVer; | 42 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
43 | 43 | ||
44 | @Slf4j | 44 | @Slf4j |
45 | @Data | 45 | @Data |
@@ -83,7 +83,7 @@ public class LwM2mClient implements Cloneable { | @@ -83,7 +83,7 @@ public class LwM2mClient implements Cloneable { | ||
83 | this.resources.get(pathRez).setLwM2mResource(rez); | 83 | this.resources.get(pathRez).setLwM2mResource(rez); |
84 | return true; | 84 | return true; |
85 | } else { | 85 | } else { |
86 | - LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(pathRez)); | 86 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); |
87 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); | 87 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); |
88 | if (resourceModel != null) { | 88 | if (resourceModel != null) { |
89 | this.resources.put(pathRez, new ResourceValue(rez, resourceModel)); | 89 | this.resources.put(pathRez, new ResourceValue(rez, resourceModel)); |
@@ -110,7 +110,7 @@ public class LwM2mClient implements Cloneable { | @@ -110,7 +110,7 @@ public class LwM2mClient implements Cloneable { | ||
110 | public void deleteResources(String pathIdVer, LwM2mModelProvider modelProvider) { | 110 | public void deleteResources(String pathIdVer, LwM2mModelProvider modelProvider) { |
111 | Set<String> key = getKeysEqualsIdVer(pathIdVer); | 111 | Set<String> key = getKeysEqualsIdVer(pathIdVer); |
112 | key.forEach(pathRez -> { | 112 | key.forEach(pathRez -> { |
113 | - LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(pathRez)); | 113 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); |
114 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); | 114 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); |
115 | if (resourceModel != null) { | 115 | if (resourceModel != null) { |
116 | this.resources.get(pathRez).setResourceModel(resourceModel); | 116 | this.resources.get(pathRez).setResourceModel(resourceModel); |
@@ -132,7 +132,7 @@ public class LwM2mClient implements Cloneable { | @@ -132,7 +132,7 @@ public class LwM2mClient implements Cloneable { | ||
132 | } | 132 | } |
133 | 133 | ||
134 | private void saveResourceModel(String pathRez, LwM2mModelProvider modelProvider) { | 134 | private void saveResourceModel(String pathRez, LwM2mModelProvider modelProvider) { |
135 | - LwM2mPath pathIds = new LwM2mPath(convertToObjectIdFromIdVer(pathRez)); | 135 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); |
136 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); | 136 | ResourceModel resourceModel = modelProvider.getObjectModel(registration).getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()); |
137 | this.resources.get(pathRez).setResourceModel(resourceModel); | 137 | this.resources.get(pathRez).setResourceModel(resourceModel); |
138 | } | 138 | } |
@@ -35,7 +35,7 @@ import java.util.UUID; | @@ -35,7 +35,7 @@ import java.util.UUID; | ||
35 | import java.util.concurrent.ConcurrentHashMap; | 35 | import java.util.concurrent.ConcurrentHashMap; |
36 | 36 | ||
37 | import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; | 37 | import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC; |
38 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertToIdVerFromObjectId; | 38 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; |
39 | 39 | ||
40 | @Service | 40 | @Service |
41 | @TbLwM2mTransportComponent | 41 | @TbLwM2mTransportComponent |
@@ -185,7 +185,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -185,7 +185,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
185 | Arrays.stream(registration.getObjectLinks()).forEach(url -> { | 185 | Arrays.stream(registration.getObjectLinks()).forEach(url -> { |
186 | LwM2mPath pathIds = new LwM2mPath(url.getUrl()); | 186 | LwM2mPath pathIds = new LwM2mPath(url.getUrl()); |
187 | if (!pathIds.isRoot()) { | 187 | if (!pathIds.isRoot()) { |
188 | - clientObjects.add(convertToIdVerFromObjectId(url.getUrl(), registration)); | 188 | + clientObjects.add(convertPathFromObjectIdToIdVer(url.getUrl(), registration)); |
189 | } | 189 | } |
190 | }); | 190 | }); |
191 | return (clientObjects.size() > 0) ? clientObjects : null; | 191 | return (clientObjects.size() > 0) ? clientObjects : null; |
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 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
20 | + | ||
21 | +import java.util.ArrayList; | ||
22 | +import java.util.List; | ||
23 | + | ||
24 | +@Data | ||
25 | +public class ResultsAddKeyValueProto { | ||
26 | + List<TransportProtos.KeyValueProto> resultAttributes; | ||
27 | + List<TransportProtos.KeyValueProto> resultTelemetries; | ||
28 | + | ||
29 | + public ResultsAddKeyValueProto() { | ||
30 | + this.resultAttributes = new ArrayList<>(); | ||
31 | + this.resultTelemetries = new ArrayList<>(); | ||
32 | + } | ||
33 | + | ||
34 | +} |
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 | +import org.thingsboard.server.common.data.kv.DataType; | ||
20 | + | ||
21 | +@Data | ||
22 | +public class ResultsResourceValue { | ||
23 | + DataType dataType; | ||
24 | + Object value; | ||
25 | + String resourceName; | ||
26 | + | ||
27 | + public ResultsResourceValue (DataType dataType, Object value, String resourceName) { | ||
28 | + this.dataType = dataType; | ||
29 | + this.value = value; | ||
30 | + this.resourceName = resourceName; | ||
31 | + } | ||
32 | +} |
@@ -18,14 +18,12 @@ package org.thingsboard.server.transport.lwm2m.utils; | @@ -18,14 +18,12 @@ package org.thingsboard.server.transport.lwm2m.utils; | ||
18 | import lombok.extern.slf4j.Slf4j; | 18 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.leshan.core.model.ResourceModel.Type; | 19 | import org.eclipse.leshan.core.model.ResourceModel.Type; |
20 | import org.eclipse.leshan.core.node.LwM2mPath; | 20 | import org.eclipse.leshan.core.node.LwM2mPath; |
21 | +import org.eclipse.leshan.core.node.ObjectLink; | ||
21 | import org.eclipse.leshan.core.node.codec.CodecException; | 22 | import org.eclipse.leshan.core.node.codec.CodecException; |
22 | import org.eclipse.leshan.core.node.codec.LwM2mValueConverter; | 23 | import org.eclipse.leshan.core.node.codec.LwM2mValueConverter; |
23 | import org.eclipse.leshan.core.util.Hex; | 24 | import org.eclipse.leshan.core.util.Hex; |
24 | import org.eclipse.leshan.core.util.StringUtils; | 25 | import org.eclipse.leshan.core.util.StringUtils; |
25 | 26 | ||
26 | -import javax.xml.datatype.DatatypeConfigurationException; | ||
27 | -import javax.xml.datatype.DatatypeFactory; | ||
28 | -import javax.xml.datatype.XMLGregorianCalendar; | ||
29 | import java.math.BigInteger; | 27 | import java.math.BigInteger; |
30 | import java.text.DateFormat; | 28 | import java.text.DateFormat; |
31 | import java.text.SimpleDateFormat; | 29 | import java.text.SimpleDateFormat; |
@@ -111,15 +109,16 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | @@ -111,15 +109,16 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | ||
111 | case INTEGER: | 109 | case INTEGER: |
112 | log.debug("Trying to convert long value {} to date", value); | 110 | log.debug("Trying to convert long value {} to date", value); |
113 | /** let's assume we received the millisecond since 1970/1/1 */ | 111 | /** let's assume we received the millisecond since 1970/1/1 */ |
114 | - return new Date((Long) value); | 112 | + return new Date(((Number) value).longValue() * 1000L); |
115 | case STRING: | 113 | case STRING: |
116 | log.debug("Trying to convert string value {} to date", value); | 114 | log.debug("Trying to convert string value {} to date", value); |
117 | /** let's assume we received an ISO 8601 format date */ | 115 | /** let's assume we received an ISO 8601 format date */ |
118 | try { | 116 | try { |
119 | - DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); | ||
120 | - XMLGregorianCalendar cal = datatypeFactory.newXMLGregorianCalendar((String) value); | ||
121 | - return cal.toGregorianCalendar().getTime(); | ||
122 | - } catch (DatatypeConfigurationException | IllegalArgumentException e) { | 117 | + return new Date(Long.decode(value.toString())); |
118 | +// DatatypeFactory datatypeFactory = DatatypeFactory.newInstance(); | ||
119 | +// XMLGregorianCalendar cal = datatypeFactory.newXMLGregorianCalendar((String) value); | ||
120 | +// return cal.toGregorianCalendar().getTime(); | ||
121 | + } catch (IllegalArgumentException e) { | ||
123 | log.debug("Unable to convert string to date", e); | 122 | log.debug("Unable to convert string to date", e); |
124 | throw new CodecException("Unable to convert string (%s) to date for resource %s", value, | 123 | throw new CodecException("Unable to convert string (%s) to date for resource %s", value, |
125 | resourcePath); | 124 | resourcePath); |
@@ -147,6 +146,8 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | @@ -147,6 +146,8 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | ||
147 | return formatter.format(new Date(timeValue)); | 146 | return formatter.format(new Date(timeValue)); |
148 | case OPAQUE: | 147 | case OPAQUE: |
149 | return Hex.encodeHexString((byte[])value); | 148 | return Hex.encodeHexString((byte[])value); |
149 | + case OBJLNK: | ||
150 | + return ObjectLink.decodeFromString((String) value); | ||
150 | default: | 151 | default: |
151 | break; | 152 | break; |
152 | } | 153 | } |
@@ -164,10 +165,14 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | @@ -164,10 +165,14 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter { | ||
164 | } | 165 | } |
165 | } | 166 | } |
166 | break; | 167 | break; |
168 | + case OBJLNK: | ||
169 | + if (currentType == Type.STRING) { | ||
170 | + return ObjectLink.fromPath(value.toString()); | ||
171 | + } | ||
167 | default: | 172 | default: |
168 | } | 173 | } |
169 | 174 | ||
170 | throw new CodecException("Invalid value type for resource %s, expected %s, got %s", resourcePath, expectedType, | 175 | throw new CodecException("Invalid value type for resource %s, expected %s, got %s", resourcePath, expectedType, |
171 | currentType); | 176 | currentType); |
172 | } | 177 | } |
173 | -} | 178 | + } |
@@ -119,6 +119,18 @@ redis: | @@ -119,6 +119,18 @@ redis: | ||
119 | 119 | ||
120 | # LWM2M server parameters | 120 | # LWM2M server parameters |
121 | transport: | 121 | transport: |
122 | + sessions: | ||
123 | + inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" | ||
124 | + report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" | ||
125 | + json: | ||
126 | + # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON | ||
127 | + type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:false}" | ||
128 | + # Maximum allowed string value length when processing Telemetry/Attributes JSON (0 value disables string value length check) | ||
129 | + max_string_value_length: "${JSON_MAX_STRING_VALUE_LENGTH:0}" | ||
130 | + client_side_rpc: | ||
131 | + timeout: "${CLIENT_SIDE_RPC_TIMEOUT:60000}" | ||
132 | + # Enable/disable http/mqtt/coap transport protocols (has higher priority than certain protocol's 'enabled' property) | ||
133 | + api_enabled: "${TB_TRANSPORT_API_ENABLED:true}" | ||
122 | # Local LwM2M transport parameters | 134 | # Local LwM2M transport parameters |
123 | lwm2m: | 135 | lwm2m: |
124 | # Enable/disable lvm2m transport protocol. | 136 | # Enable/disable lvm2m transport protocol. |
@@ -180,15 +192,6 @@ transport: | @@ -180,15 +192,6 @@ transport: | ||
180 | # Use redis for Security and Registration stores | 192 | # Use redis for Security and Registration stores |
181 | redis.enabled: "${LWM2M_REDIS_ENABLED:false}" | 193 | redis.enabled: "${LWM2M_REDIS_ENABLED:false}" |
182 | 194 | ||
183 | - sessions: | ||
184 | - inactivity_timeout: "${TB_TRANSPORT_SESSIONS_INACTIVITY_TIMEOUT:300000}" | ||
185 | - report_timeout: "${TB_TRANSPORT_SESSIONS_REPORT_TIMEOUT:30000}" | ||
186 | - json: | ||
187 | - # Cast String data types to Numeric if possible when processing Telemetry/Attributes JSON | ||
188 | - type_cast_enabled: "${JSON_TYPE_CAST_ENABLED:true}" | ||
189 | - # Maximum allowed string value length when processing Telemetry/Attributes JSON (0 value disables string value length check) | ||
190 | - max_string_value_length: "${JSON_MAX_STRING_VALUE_LENGTH:0}" | ||
191 | - | ||
192 | queue: | 195 | queue: |
193 | type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) | 196 | type: "${TB_QUEUE_TYPE:kafka}" # kafka (Apache Kafka) or aws-sqs (AWS SQS) or pubsub (PubSub) or service-bus (Azure Service Bus) or rabbitmq (RabbitMQ) |
194 | kafka: | 197 | kafka: |
@@ -82,8 +82,6 @@ | @@ -82,8 +82,6 @@ | ||
82 | <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | 82 | <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> |
83 | </mat-error> | 83 | </mat-error> |
84 | </mat-form-field> | 84 | </mat-form-field> |
85 | - </div> | ||
86 | - <div fxLayout="row" fxLayoutGap="8px"> | ||
87 | <mat-form-field fxFlex> | 85 | <mat-form-field fxFlex> |
88 | <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label> | 86 | <mat-label>{{ 'device-profile.lwm2m.default-min-period' | translate }}</mat-label> |
89 | <input matInput type="number" formControlName="defaultMinPeriod" required> | 87 | <input matInput type="number" formControlName="defaultMinPeriod" required> |
@@ -93,13 +91,16 @@ | @@ -93,13 +91,16 @@ | ||
93 | <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | 91 | <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> |
94 | </mat-error> | 92 | </mat-error> |
95 | </mat-form-field> | 93 | </mat-form-field> |
96 | - <mat-form-field fxFlex> | 94 | + </div> |
95 | + <div fxLayout="row" fxLayoutGap="8px"> | ||
96 | + <mat-form-field class="mat-block" fxFlex="100"> | ||
97 | <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label> | 97 | <mat-label>{{ 'device-profile.lwm2m.binding' | translate }}</mat-label> |
98 | - <input matInput type="text" formControlName="binding" required> | ||
99 | - <mat-error *ngIf="lwm2mDeviceProfileFormGroup.get('binding').hasError('required')"> | ||
100 | - {{ 'device-profile.lwm2m.binding' | translate }} | ||
101 | - <strong>{{ 'device-profile.lwm2m.required' | translate }}</strong> | ||
102 | - </mat-error> | 98 | + <mat-select formControlName="binding"> |
99 | + <mat-option *ngFor="let bindingMode of bindingModeTypes" | ||
100 | + [value]="bindingMode"> | ||
101 | + {{ bindingModeTypeNamesMap.get(bindingModeType[bindingMode]) }} | ||
102 | + </mat-option> | ||
103 | + </mat-select> | ||
103 | </mat-form-field> | 104 | </mat-form-field> |
104 | </div> | 105 | </div> |
105 | <div> | 106 | <div> |
@@ -22,7 +22,8 @@ import { AppState } from '@app/core/core.state'; | @@ -22,7 +22,8 @@ import { AppState } from '@app/core/core.state'; | ||
22 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; | 22 | import { coerceBooleanProperty } from '@angular/cdk/coercion'; |
23 | import { | 23 | import { |
24 | ATTRIBUTE, | 24 | ATTRIBUTE, |
25 | - DEFAULT_BINDING, | 25 | + BINDING_MODE, |
26 | + BINDING_MODE_NAMES, | ||
26 | getDefaultProfileConfig, | 27 | getDefaultProfileConfig, |
27 | INSTANCES, | 28 | INSTANCES, |
28 | KEY_NAME, | 29 | KEY_NAME, |
@@ -55,6 +56,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro | @@ -55,6 +56,9 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro | ||
55 | private requiredValue: boolean; | 56 | private requiredValue: boolean; |
56 | private disabled = false; | 57 | private disabled = false; |
57 | 58 | ||
59 | + bindingModeType = BINDING_MODE; | ||
60 | + bindingModeTypes = Object.keys(BINDING_MODE); | ||
61 | + bindingModeTypeNamesMap = BINDING_MODE_NAMES; | ||
58 | lwm2mDeviceProfileFormGroup: FormGroup; | 62 | lwm2mDeviceProfileFormGroup: FormGroup; |
59 | lwm2mDeviceConfigFormGroup: FormGroup; | 63 | lwm2mDeviceConfigFormGroup: FormGroup; |
60 | bootstrapServers: string; | 64 | bootstrapServers: string; |
@@ -86,7 +90,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro | @@ -86,7 +90,7 @@ export class Lwm2mDeviceProfileTransportConfigurationComponent implements Contro | ||
86 | lifetime: [null, Validators.required], | 90 | lifetime: [null, Validators.required], |
87 | defaultMinPeriod: [null, Validators.required], | 91 | defaultMinPeriod: [null, Validators.required], |
88 | notifIfDisabled: [true, []], | 92 | notifIfDisabled: [true, []], |
89 | - binding: [DEFAULT_BINDING, Validators.required], | 93 | + binding:[], |
90 | bootstrapServer: [null, Validators.required], | 94 | bootstrapServer: [null, Validators.required], |
91 | lwm2mServer: [null, Validators.required], | 95 | lwm2mServer: [null, Validators.required], |
92 | }); | 96 | }); |
@@ -44,6 +44,35 @@ export const KEY_REGEXP_NUMBER = /^(\-?|\+?)\d*$/; | @@ -44,6 +44,35 @@ export const KEY_REGEXP_NUMBER = /^(\-?|\+?)\d*$/; | ||
44 | export const INSTANCES_ID_VALUE_MIN = 0; | 44 | export const INSTANCES_ID_VALUE_MIN = 0; |
45 | export const INSTANCES_ID_VALUE_MAX = 65535; | 45 | export const INSTANCES_ID_VALUE_MAX = 65535; |
46 | 46 | ||
47 | + | ||
48 | +export enum BINDING_MODE { | ||
49 | + U = 'U', | ||
50 | + UQ = 'UQ', | ||
51 | + T = 'T', | ||
52 | + TQ = 'TQ', | ||
53 | + S = 'S', | ||
54 | + SQ = 'SQ', | ||
55 | + US = 'US', | ||
56 | + TS = 'TS', | ||
57 | + UQS = 'UQS', | ||
58 | + TQS = 'TQS' | ||
59 | +} | ||
60 | + | ||
61 | +export const BINDING_MODE_NAMES = new Map<BINDING_MODE, string>( | ||
62 | + [ | ||
63 | + [BINDING_MODE.U, 'U: UDP connection in standard mode'], | ||
64 | + [BINDING_MODE.UQ, 'UQ: UDP connection in queue mode'], | ||
65 | + [BINDING_MODE.US, 'US: both UDP and SMS connections active, both in standard mode'], | ||
66 | + [BINDING_MODE.UQS, 'UQS: both UDP and SMS connections active; UDP in queue mode, SMS in standard mode'], | ||
67 | + [BINDING_MODE.T,'T: TCP connection in standard mode'], | ||
68 | + [BINDING_MODE.TQ, 'TQ: TCP connection in queue mode'], | ||
69 | + [BINDING_MODE.TS, 'TS: both TCP and SMS connections active, both in standard mode'], | ||
70 | + [BINDING_MODE.TQS, 'TQS: both TCP and SMS connections active; TCP in queue mode, SMS in standard mode'], | ||
71 | + [BINDING_MODE.S, 'S: SMS connection in standard mode'], | ||
72 | + [BINDING_MODE.SQ, 'SQ: SMS connection in queue mode'] | ||
73 | + ] | ||
74 | +); | ||
75 | + | ||
47 | export enum ATTRIBUTE_LWM2M_ENUM { | 76 | export enum ATTRIBUTE_LWM2M_ENUM { |
48 | dim = 'dim', | 77 | dim = 'dim', |
49 | ver = 'ver', | 78 | ver = 'ver', |
@@ -62,8 +91,7 @@ export const ATTRIBUTE_LWM2M_LABEL = new Map<ATTRIBUTE_LWM2M_ENUM, string>( | @@ -62,8 +91,7 @@ export const ATTRIBUTE_LWM2M_LABEL = new Map<ATTRIBUTE_LWM2M_ENUM, string>( | ||
62 | [ATTRIBUTE_LWM2M_ENUM.pmax, 'pmax='], | 91 | [ATTRIBUTE_LWM2M_ENUM.pmax, 'pmax='], |
63 | [ATTRIBUTE_LWM2M_ENUM.gt, '>'], | 92 | [ATTRIBUTE_LWM2M_ENUM.gt, '>'], |
64 | [ATTRIBUTE_LWM2M_ENUM.lt, '<'], | 93 | [ATTRIBUTE_LWM2M_ENUM.lt, '<'], |
65 | - [ATTRIBUTE_LWM2M_ENUM.st, 'st='], | ||
66 | - | 94 | + [ATTRIBUTE_LWM2M_ENUM.st, 'st='] |
67 | ] | 95 | ] |
68 | ); | 96 | ); |
69 | 97 |