Commit 5f8a9e9f679f7f333a10bbabd51b22d519207144

Authored by nickAS21
Committed by GitHub
1 parent c350fb7a

Lwm2m rpc (#4473)

* Lwm2m: RPC_terminal

* Lwm2m: RPC_terminal del two file

* Lwm2m: RPC_terminal add test observe

* Lwm2m: RPC_terminal add test delete
Showing 13 changed files with 723 additions and 378 deletions
@@ -35,7 +35,7 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf @@ -35,7 +35,7 @@ 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.utils.TypeServer; 38 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
39 39
40 import java.io.IOException; 40 import java.io.IOException;
41 import java.security.GeneralSecurityException; 41 import java.security.GeneralSecurityException;
@@ -69,7 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @@ -69,7 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
69 69
70 @Override 70 @Override
71 public List<SecurityInfo> getAllByEndpoint(String endPoint) { 71 public List<SecurityInfo> getAllByEndpoint(String endPoint) {
72 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, TypeServer.BOOTSTRAP); 72 + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP);
73 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { 73 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
74 /** add value to store from BootstrapJson */ 74 /** add value to store from BootstrapJson */
75 this.setBootstrapConfigScurityInfo(store); 75 this.setBootstrapConfigScurityInfo(store);
@@ -93,7 +93,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { @@ -93,7 +93,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
93 93
94 @Override 94 @Override
95 public SecurityInfo getByIdentity(String identity) { 95 public SecurityInfo getByIdentity(String identity) {
96 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.BOOTSTRAP); 96 + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP);
97 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { 97 if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
98 /** add value to store from BootstrapJson */ 98 /** add value to store from BootstrapJson */
99 this.setBootstrapConfigScurityInfo(store); 99 this.setBootstrapConfigScurityInfo(store);
@@ -28,7 +28,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC @@ -28,7 +28,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC
28 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 28 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
29 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; 29 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer;
30 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; 30 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
31 -import org.thingsboard.server.transport.lwm2m.utils.TypeServer;  
32 31
33 import java.io.IOException; 32 import java.io.IOException;
34 import java.security.GeneralSecurityException; 33 import java.security.GeneralSecurityException;
@@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
59 * @param keyValue - 58 * @param keyValue -
60 * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo 59 * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo
61 */ 60 */
62 - public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, TypeServer keyValue) { 61 + public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportHandler.LwM2mTypeServer keyValue) {
63 CountDownLatch latch = new CountDownLatch(1); 62 CountDownLatch latch = new CountDownLatch(1);
64 final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; 63 final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1];
65 contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), 64 contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(),
@@ -96,7 +95,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -96,7 +95,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
96 * @param keyValue - 95 * @param keyValue -
97 * @return SecurityInfo 96 * @return SecurityInfo
98 */ 97 */
99 - private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, TypeServer keyValue) { 98 + private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportHandler.LwM2mTypeServer keyValue) {
100 ReadResultSecurityStore result = new ReadResultSecurityStore(); 99 ReadResultSecurityStore result = new ReadResultSecurityStore();
101 JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr); 100 JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr);
102 if (objectMsg != null && !objectMsg.isJsonNull()) { 101 if (objectMsg != null && !objectMsg.isJsonNull()) {
@@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator { @@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator {
109 && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; 108 && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
110 endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; 109 endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk;
111 if (object != null && !object.isJsonNull()) { 110 if (object != null && !object.isJsonNull()) {
112 - if (keyValue.equals(TypeServer.BOOTSTRAP)) { 111 + if (keyValue.equals(LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP)) {
113 result.setBootstrapJsonCredential(object); 112 result.setBootstrapJsonCredential(object);
114 result.setEndPoint(endPoint); 113 result.setEndPoint(endPoint);
115 result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); 114 result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code);
@@ -92,7 +92,8 @@ public class LwM2mServerListener { @@ -92,7 +92,8 @@ 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, convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), response); 95 + service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(),
  96 + registration), response, null);
96 } catch (Exception e) { 97 } catch (Exception e) {
97 log.error("[{}] onResponse", e.toString()); 98 log.error("[{}] onResponse", e.toString());
98 99
@@ -75,7 +75,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s @@ -75,7 +75,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s
75 75
76 @Override 76 @Override
77 public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { 77 public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) {
78 - this.service.onToDeviceRpcRequest(toDeviceRequest); 78 + this.service.onToDeviceRpcRequest(toDeviceRequest,this.sessionInfo);
79 } 79 }
80 80
81 @Override 81 @Override
@@ -16,9 +16,13 @@ @@ -16,9 +16,13 @@
16 package org.thingsboard.server.transport.lwm2m.server; 16 package org.thingsboard.server.transport.lwm2m.server;
17 17
18 import com.fasterxml.jackson.databind.ObjectMapper; 18 import com.fasterxml.jackson.databind.ObjectMapper;
  19 +import com.google.common.collect.Sets;
  20 +import com.google.gson.Gson;
  21 +import com.google.gson.JsonArray;
19 import com.google.gson.JsonObject; 22 import com.google.gson.JsonObject;
20 import com.google.gson.JsonParser; 23 import com.google.gson.JsonParser;
21 import com.google.gson.JsonSyntaxException; 24 import com.google.gson.JsonSyntaxException;
  25 +import com.google.gson.reflect.TypeToken;
22 import lombok.extern.slf4j.Slf4j; 26 import lombok.extern.slf4j.Slf4j;
23 import org.apache.commons.lang3.StringUtils; 27 import org.apache.commons.lang3.StringUtils;
24 import org.eclipse.californium.core.network.config.NetworkConfig; 28 import org.eclipse.californium.core.network.config.NetworkConfig;
@@ -26,7 +30,12 @@ import org.eclipse.leshan.core.attributes.Attribute; @@ -26,7 +30,12 @@ import org.eclipse.leshan.core.attributes.Attribute;
26 import org.eclipse.leshan.core.attributes.AttributeSet; 30 import org.eclipse.leshan.core.attributes.AttributeSet;
27 import org.eclipse.leshan.core.model.ObjectModel; 31 import org.eclipse.leshan.core.model.ObjectModel;
28 import org.eclipse.leshan.core.model.ResourceModel; 32 import org.eclipse.leshan.core.model.ResourceModel;
  33 +import org.eclipse.leshan.core.node.LwM2mMultipleResource;
  34 +import org.eclipse.leshan.core.node.LwM2mNode;
  35 +import org.eclipse.leshan.core.node.LwM2mObject;
  36 +import org.eclipse.leshan.core.node.LwM2mObjectInstance;
29 import org.eclipse.leshan.core.node.LwM2mPath; 37 import org.eclipse.leshan.core.node.LwM2mPath;
  38 +import org.eclipse.leshan.core.node.LwM2mSingleResource;
30 import org.eclipse.leshan.core.node.codec.CodecException; 39 import org.eclipse.leshan.core.node.codec.CodecException;
31 import org.eclipse.leshan.core.request.DownlinkRequest; 40 import org.eclipse.leshan.core.request.DownlinkRequest;
32 import org.eclipse.leshan.core.request.WriteAttributesRequest; 41 import org.eclipse.leshan.core.request.WriteAttributesRequest;
@@ -50,6 +59,7 @@ import java.util.LinkedList; @@ -50,6 +59,7 @@ import java.util.LinkedList;
50 import java.util.List; 59 import java.util.List;
51 import java.util.Map; 60 import java.util.Map;
52 import java.util.Optional; 61 import java.util.Optional;
  62 +import java.util.Set;
53 import java.util.concurrent.ConcurrentHashMap; 63 import java.util.concurrent.ConcurrentHashMap;
54 64
55 import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; 65 import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION;
@@ -62,8 +72,8 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA @@ -62,8 +72,8 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA
62 @Slf4j 72 @Slf4j
63 public class LwM2mTransportHandler { 73 public class LwM2mTransportHandler {
64 74
65 - public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me";  
66 - 75 + // public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me";
  76 + public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0";
67 public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; 77 public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings";
68 public static final String BOOTSTRAP = "bootstrap"; 78 public static final String BOOTSTRAP = "bootstrap";
69 public static final String SERVERS = "servers"; 79 public static final String SERVERS = "servers";
@@ -73,21 +83,21 @@ public class LwM2mTransportHandler { @@ -73,21 +83,21 @@ public class LwM2mTransportHandler {
73 public static final String ATTRIBUTE = "attribute"; 83 public static final String ATTRIBUTE = "attribute";
74 public static final String TELEMETRY = "telemetry"; 84 public static final String TELEMETRY = "telemetry";
75 public static final String KEY_NAME = "keyName"; 85 public static final String KEY_NAME = "keyName";
76 - public static final String OBSERVE = "observe"; 86 + public static final String OBSERVE_LWM2M = "observe";
77 public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; 87 public static final String ATTRIBUTE_LWM2M = "attributeLwm2m";
78 - public static final String RESOURCE_VALUE = "resValue";  
79 - public static final String RESOURCE_TYPE = "resType"; 88 +// public static final String RESOURCE_VALUE = "resValue";
  89 +// public static final String RESOURCE_TYPE = "resType";
80 90
81 private static final String REQUEST = "/request"; 91 private static final String REQUEST = "/request";
82 - private static final String RESPONSE = "/response"; 92 + // private static final String RESPONSE = "/response";
83 private static final String ATTRIBUTES = "/" + ATTRIBUTE; 93 private static final String ATTRIBUTES = "/" + ATTRIBUTE;
84 public static final String TELEMETRIES = "/" + TELEMETRY; 94 public static final String TELEMETRIES = "/" + TELEMETRY;
85 - public static final String ATTRIBUTES_RESPONSE = ATTRIBUTES + RESPONSE; 95 + // public static final String ATTRIBUTES_RESPONSE = ATTRIBUTES + RESPONSE;
86 public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST; 96 public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST;
87 - public static final String DEVICE_ATTRIBUTES_RESPONSE = ATTRIBUTES_RESPONSE + "/"; 97 + // public static final String DEVICE_ATTRIBUTES_RESPONSE = ATTRIBUTES_RESPONSE + "/";
88 public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/"; 98 public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/";
89 - public static final String DEVICE_ATTRIBUTES_TOPIC = BASE_DEVICE_API_TOPIC + ATTRIBUTES;  
90 - public static final String DEVICE_TELEMETRY_TOPIC = BASE_DEVICE_API_TOPIC + TELEMETRIES; 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;
91 101
92 public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms 102 public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms
93 103
@@ -95,30 +105,86 @@ public class LwM2mTransportHandler { @@ -95,30 +105,86 @@ public class LwM2mTransportHandler {
95 public static final String LOG_LW2M_INFO = "info"; 105 public static final String LOG_LW2M_INFO = "info";
96 public static final String LOG_LW2M_ERROR = "error"; 106 public static final String LOG_LW2M_ERROR = "error";
97 public static final String LOG_LW2M_WARN = "warn"; 107 public static final String LOG_LW2M_WARN = "warn";
  108 + public static final String LOG_LW2M_VALUE = "value";
98 109
99 public static final int LWM2M_STRATEGY_1 = 1; 110 public static final int LWM2M_STRATEGY_1 = 1;
100 public static final int LWM2M_STRATEGY_2 = 2; 111 public static final int LWM2M_STRATEGY_2 = 2;
101 112
102 public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; 113 public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized";
103 114
104 - public static final String GET_TYPE_OPER_READ = "read";  
105 - public static final String GET_TYPE_OPER_DISCOVER = "discover";  
106 - public static final String GET_TYPE_OPER_OBSERVE = "observe";  
107 - public static final String POST_TYPE_OPER_OBSERVE_CANCEL = "observeCancel";  
108 - public static final String POST_TYPE_OPER_EXECUTE = "execute";  
109 - /**  
110 - * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see  
111 - * section 5.3.3 of the LW M2M spec).  
112 - * if all resources are to be replaced  
113 - */  
114 - public static final String POST_TYPE_OPER_WRITE_REPLACE = "replace"; 115 + public enum LwM2mTypeServer {
  116 + BOOTSTRAP(0, "bootstrap"),
  117 + CLIENT(1, "client");
  118 +
  119 + public int code;
  120 + public String type;
  121 +
  122 + LwM2mTypeServer(int code, String type) {
  123 + this.code = code;
  124 + this.type = type;
  125 + }
  126 +
  127 + public static LwM2mTypeServer fromLwM2mTypeServer(String type) {
  128 + for (LwM2mTypeServer sm : LwM2mTypeServer.values()) {
  129 + if (sm.type.equals(type)) {
  130 + return sm;
  131 + }
  132 + }
  133 + throw new IllegalArgumentException(String.format("Unsupported typeServer type : %d", type));
  134 + }
  135 + }
  136 +
115 /** 137 /**
116 - * Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section  
117 - * 5.3.3 of the LW M2M spec).  
118 - * if this is a partial update request 138 + * Define the behavior of a write request.
119 */ 139 */
120 - public static final String PUT_TYPE_OPER_WRITE_UPDATE = "update";  
121 - public static final String PUT_TYPE_OPER_WRITE_ATTRIBUTES = "wright-attributes"; 140 + public enum LwM2mTypeOper {
  141 + /**
  142 + * GET
  143 + */
  144 + READ(0, "Read"),
  145 + DISCOVER(1, "Discover"),
  146 + OBSERVE_READ_ALL(2, "ObserveReadAll"),
  147 + /**
  148 + * POST
  149 + */
  150 + OBSERVE(3, "Observe"),
  151 + OBSERVE_CANCEL(4, "ObserveCancel"),
  152 + EXECUTE(5, "Execute"),
  153 + /**
  154 + * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see
  155 + * section 5.3.3 of the LW M2M spec).
  156 + * if all resources are to be replaced
  157 + */
  158 + WRITE_REPLACE(6, "WriteReplace"),
  159 + /**
  160 + * PUT
  161 + */
  162 + /**
  163 + * Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section
  164 + * 5.3.3 of the LW M2M spec).
  165 + * if this is a partial update request
  166 + */
  167 + WRITE_UPDATE(7, "WriteUpdate"),
  168 + WRITE_ATTRIBUTES(8, "WriteAttributes"),
  169 + DELETE(9, "Delete");
  170 +
  171 + public int code;
  172 + public String type;
  173 +
  174 + LwM2mTypeOper(int code, String type) {
  175 + this.code = code;
  176 + this.type = type;
  177 + }
  178 +
  179 + public static LwM2mTypeOper fromLwLwM2mTypeOper(String type) {
  180 + for (LwM2mTypeOper to : LwM2mTypeOper.values()) {
  181 + if (to.type.equals(type)) {
  182 + return to;
  183 + }
  184 + }
  185 + throw new IllegalArgumentException(String.format("Unsupported typeOper type : %d", type));
  186 + }
  187 + }
122 188
123 public static final String EVENT_AWAKE = "AWAKE"; 189 public static final String EVENT_AWAKE = "AWAKE";
124 public static final String SERVICE_CHANNEL = "SERVICE"; 190 public static final String SERVICE_CHANNEL = "SERVICE";
@@ -156,19 +222,20 @@ public class LwM2mTransportHandler { @@ -156,19 +222,20 @@ public class LwM2mTransportHandler {
156 throw new CodecException("Invalid value type for resource %s, type %s", resourcePath, type); 222 throw new CodecException("Invalid value type for resource %s, type %s", resourcePath, type);
157 } 223 }
158 } 224 }
159 -//  
160 -// public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) {  
161 -// if (content instanceof LwM2mObject) {  
162 -// return (LwM2mObject) content;  
163 -// } else if (content instanceof LwM2mObjectInstance) {  
164 -// return (LwM2mObjectInstance) content;  
165 -// } else if (content instanceof LwM2mSingleResource) {  
166 -// return (LwM2mSingleResource) content;  
167 -// } else if (content instanceof LwM2mMultipleResource) {  
168 -// return (LwM2mMultipleResource) content;  
169 -// }  
170 -// return null;  
171 -// } 225 +
  226 + public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) {
  227 + if (content instanceof LwM2mObject) {
  228 + return (LwM2mObject) content;
  229 + } else if (content instanceof LwM2mObjectInstance) {
  230 + return (LwM2mObjectInstance) content;
  231 + } else if (content instanceof LwM2mSingleResource) {
  232 + return (LwM2mSingleResource) content;
  233 + } else if (content instanceof LwM2mMultipleResource) {
  234 + return (LwM2mMultipleResource) content;
  235 + }
  236 + return null;
  237 + }
  238 +
172 239
173 public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) { 240 public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) {
174 LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile(); 241 LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile();
@@ -177,7 +244,7 @@ public class LwM2mTransportHandler { @@ -177,7 +244,7 @@ public class LwM2mTransportHandler {
177 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); 244 lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject());
178 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); 245 lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray());
179 lwM2MClientProfile.setPostTelemetryProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).getAsJsonArray()); 246 lwM2MClientProfile.setPostTelemetryProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).getAsJsonArray());
180 - lwM2MClientProfile.setPostObserveProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).getAsJsonArray()); 247 + lwM2MClientProfile.setPostObserveProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).getAsJsonArray());
181 lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject()); 248 lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject());
182 return lwM2MClientProfile; 249 return lwM2MClientProfile;
183 } 250 }
@@ -198,8 +265,8 @@ public class LwM2mTransportHandler { @@ -198,8 +265,8 @@ public class LwM2mTransportHandler {
198 * "telemetry":["/1/0/1","/2/0/1","/6/0/1"], 265 * "telemetry":["/1/0/1","/2/0/1","/6/0/1"],
199 * "observe":["/2/0","/2/0/0","/4/0/2"]} 266 * "observe":["/2/0","/2/0/0","/4/0/2"]}
200 * "attributeLwm2m": {"/3_1.0": {"ver": "currentTimeTest11"}, 267 * "attributeLwm2m": {"/3_1.0": {"ver": "currentTimeTest11"},
201 - * "/3_1.0/0": {"gt": 17},  
202 - * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}} 268 + * "/3_1.0/0": {"gt": 17},
  269 + * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}}
203 */ 270 */
204 public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { 271 public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) {
205 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { 272 if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) {
@@ -254,9 +321,9 @@ public class LwM2mTransportHandler { @@ -254,9 +321,9 @@ public class LwM2mTransportHandler {
254 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) && 321 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) &&
255 !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() && 322 !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() &&
256 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonArray() && 323 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonArray() &&
257 - objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(OBSERVE) &&  
258 - !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonNull() &&  
259 - objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonArray() && 324 + objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(OBSERVE_LWM2M) &&
  325 + !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).isJsonNull() &&
  326 + objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).isJsonArray() &&
260 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE_LWM2M) && 327 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE_LWM2M) &&
261 !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonNull() && 328 !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonNull() &&
262 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonObject()); 329 objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonObject());
@@ -341,8 +408,7 @@ public class LwM2mTransportHandler { @@ -341,8 +408,7 @@ public class LwM2mTransportHandler {
341 if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { 408 if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) {
342 keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; 409 keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0];
343 return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); 410 return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH);
344 - }  
345 - else { 411 + } else {
346 return pathIdVer; 412 return pathIdVer;
347 } 413 }
348 } catch (Exception e) { 414 } catch (Exception e) {
@@ -350,6 +416,37 @@ public class LwM2mTransportHandler { @@ -350,6 +416,37 @@ public class LwM2mTransportHandler {
350 } 416 }
351 } 417 }
352 418
  419 + /**
  420 + * @param path - pathId or pathIdVer
  421 + * @return
  422 + */
  423 + public static String getVerFromPathIdVerOrId(String path) {
  424 + try {
  425 + String[] keyArray = path.split(LWM2M_SEPARATOR_PATH);
  426 + if (keyArray.length > 1) {
  427 + String[] keyArrayVer = keyArray[1].split(LWM2M_SEPARATOR_KEY);
  428 + return keyArrayVer.length == 2 ? keyArrayVer[1] : null;
  429 + }
  430 + } catch (Exception e) {
  431 + return null;
  432 + }
  433 + return null;
  434 + }
  435 +
  436 + public static String validPathIdVer(String pathIdVer, Registration registration) throws IllegalArgumentException {
  437 + if (pathIdVer.indexOf(LWM2M_SEPARATOR_PATH) < 0) {
  438 + throw new IllegalArgumentException(String.format("Error:"));
  439 + } else {
  440 + String[] keyArray = pathIdVer.split(LWM2M_SEPARATOR_PATH);
  441 + if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) {
  442 + return pathIdVer;
  443 + } else {
  444 + LwM2mPath pathObjId = new LwM2mPath(pathIdVer);
  445 + return convertPathFromObjectIdToIdVer(pathIdVer, registration);
  446 + }
  447 + }
  448 + }
  449 +
353 public static String convertPathFromObjectIdToIdVer(String path, Registration registration) { 450 public static String convertPathFromObjectIdToIdVer(String path, Registration registration) {
354 String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); 451 String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId());
355 try { 452 try {
@@ -357,8 +454,7 @@ public class LwM2mTransportHandler { @@ -357,8 +454,7 @@ public class LwM2mTransportHandler {
357 if (keyArray.length > 1) { 454 if (keyArray.length > 1) {
358 keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; 455 keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver;
359 return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); 456 return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH);
360 - }  
361 - else { 457 + } else {
362 return path; 458 return path;
363 } 459 }
364 } catch (Exception e) { 460 } catch (Exception e) {
@@ -397,13 +493,13 @@ public class LwM2mTransportHandler { @@ -397,13 +493,13 @@ public class LwM2mTransportHandler {
397 * when: 493 * when:
398 * a.old value is 17 and new value is 24 due to lt condition 494 * a.old value is 17 and new value is 24 due to lt condition
399 * b.old value is 75 and new value is 90 due to both gt and step conditions 495 * b.old value is 75 and new value is 90 due to both gt and step conditions
400 - * String uriQueries = "pmin=10&pmax=60";  
401 - * AttributeSet attributes = AttributeSet.parse(uriQueries);  
402 - * WriteAttributesRequest request = new WriteAttributesRequest(target, attributes);  
403 - * Attribute gt = new Attribute(GREATER_THAN, Double.valueOf("45"));  
404 - * Attribute st = new Attribute(LESSER_THAN, Double.valueOf("10"));  
405 - * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60");  
406 - * Attribute [] attrs = {gt, st}; 496 + * String uriQueries = "pmin=10&pmax=60";
  497 + * AttributeSet attributes = AttributeSet.parse(uriQueries);
  498 + * WriteAttributesRequest request = new WriteAttributesRequest(target, attributes);
  499 + * Attribute gt = new Attribute(GREATER_THAN, Double.valueOf("45"));
  500 + * Attribute st = new Attribute(LESSER_THAN, Double.valueOf("10"));
  501 + * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60");
  502 + * Attribute [] attrs = {gt, st};
407 */ 503 */
408 public static DownlinkRequest createWriteAttributeRequest(String target, Object params) { 504 public static DownlinkRequest createWriteAttributeRequest(String target, Object params) {
409 AttributeSet attrSet = new AttributeSet(createWriteAttributes(params)); 505 AttributeSet attrSet = new AttributeSet(createWriteAttributes(params));
@@ -423,4 +519,12 @@ public class LwM2mTransportHandler { @@ -423,4 +519,12 @@ public class LwM2mTransportHandler {
423 }); 519 });
424 return (Attribute[]) attributeLists.toArray(Attribute[]::new); 520 return (Attribute[]) attributeLists.toArray(Attribute[]::new);
425 } 521 }
  522 +
  523 +
  524 + public static Set<String> convertJsonArrayToSet(JsonArray jsonArray) {
  525 + List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() {
  526 + }.getType());
  527 + return Sets.newConcurrentHashSet(attributeListOld);
  528 + }
  529 +
426 } 530 }
@@ -15,6 +15,7 @@ @@ -15,6 +15,7 @@
15 */ 15 */
16 package org.thingsboard.server.transport.lwm2m.server; 16 package org.thingsboard.server.transport.lwm2m.server;
17 17
  18 +import lombok.SneakyThrows;
18 import lombok.extern.slf4j.Slf4j; 19 import lombok.extern.slf4j.Slf4j;
19 import org.eclipse.californium.core.coap.CoAP; 20 import org.eclipse.californium.core.coap.CoAP;
20 import org.eclipse.californium.core.coap.Response; 21 import org.eclipse.californium.core.coap.Response;
@@ -24,8 +25,8 @@ import org.eclipse.leshan.core.node.LwM2mPath; @@ -24,8 +25,8 @@ import org.eclipse.leshan.core.node.LwM2mPath;
24 import org.eclipse.leshan.core.node.LwM2mSingleResource; 25 import org.eclipse.leshan.core.node.LwM2mSingleResource;
25 import org.eclipse.leshan.core.node.ObjectLink; 26 import org.eclipse.leshan.core.node.ObjectLink;
26 import org.eclipse.leshan.core.observation.Observation; 27 import org.eclipse.leshan.core.observation.Observation;
27 -import org.eclipse.leshan.core.request.CancelObservationRequest;  
28 import org.eclipse.leshan.core.request.ContentFormat; 28 import org.eclipse.leshan.core.request.ContentFormat;
  29 +import org.eclipse.leshan.core.request.DeleteRequest;
29 import org.eclipse.leshan.core.request.DiscoverRequest; 30 import org.eclipse.leshan.core.request.DiscoverRequest;
30 import org.eclipse.leshan.core.request.DownlinkRequest; 31 import org.eclipse.leshan.core.request.DownlinkRequest;
31 import org.eclipse.leshan.core.request.ExecuteRequest; 32 import org.eclipse.leshan.core.request.ExecuteRequest;
@@ -47,27 +48,31 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; @@ -47,27 +48,31 @@ import org.eclipse.leshan.core.util.NamedThreadFactory;
47 import org.eclipse.leshan.server.californium.LeshanServer; 48 import org.eclipse.leshan.server.californium.LeshanServer;
48 import org.eclipse.leshan.server.registration.Registration; 49 import org.eclipse.leshan.server.registration.Registration;
49 import org.springframework.stereotype.Service; 50 import org.springframework.stereotype.Service;
  51 +import org.thingsboard.server.common.transport.TransportService;
50 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; 52 import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
51 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 53 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
52 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; 54 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
  55 +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;
53 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 56 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
54 57
55 import javax.annotation.PostConstruct; 58 import javax.annotation.PostConstruct;
  59 +import java.util.Arrays;
56 import java.util.Date; 60 import java.util.Date;
  61 +import java.util.Set;
57 import java.util.concurrent.ExecutorService; 62 import java.util.concurrent.ExecutorService;
58 import java.util.concurrent.Executors; 63 import java.util.concurrent.Executors;
  64 +import java.util.stream.Collectors;
59 65
  66 +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT;
  67 +import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST;
  68 +import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND;
60 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT; 69 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT;
61 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER;  
62 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE;  
63 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ;  
64 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; 70 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
65 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; 71 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
66 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE;  
67 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_OBSERVE_CANCEL;  
68 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;  
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; 72 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE;
  73 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper;
  74 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_CANCEL;
  75 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_READ_ALL;
71 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; 76 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL;
72 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; 77 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId;
73 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; 78 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer;
@@ -79,7 +84,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle @@ -79,7 +84,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle
79 public class LwM2mTransportRequest { 84 public class LwM2mTransportRequest {
80 private ExecutorService executorResponse; 85 private ExecutorService executorResponse;
81 86
82 - private LwM2mValueConverterImpl converter; 87 + public LwM2mValueConverterImpl converter;
83 88
84 private final LwM2mTransportContextServer lwM2mTransportContextServer; 89 private final LwM2mTransportContextServer lwM2mTransportContextServer;
85 90
@@ -89,11 +94,16 @@ public class LwM2mTransportRequest { @@ -89,11 +94,16 @@ public class LwM2mTransportRequest {
89 94
90 private final LwM2mTransportServiceImpl serviceImpl; 95 private final LwM2mTransportServiceImpl serviceImpl;
91 96
92 - public LwM2mTransportRequest(LwM2mTransportContextServer lwM2mTransportContextServer, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, LwM2mTransportServiceImpl serviceImpl) { 97 + private final TransportService transportService;
  98 +
  99 + public LwM2mTransportRequest(LwM2mTransportContextServer lwM2mTransportContextServer,
  100 + LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer,
  101 + LwM2mTransportServiceImpl serviceImpl, TransportService transportService) {
93 this.lwM2mTransportContextServer = lwM2mTransportContextServer; 102 this.lwM2mTransportContextServer = lwM2mTransportContextServer;
94 this.lwM2mClientContext = lwM2mClientContext; 103 this.lwM2mClientContext = lwM2mClientContext;
95 this.leshanServer = leshanServer; 104 this.leshanServer = leshanServer;
96 this.serviceImpl = serviceImpl; 105 this.serviceImpl = serviceImpl;
  106 + this.transportService = transportService;
97 } 107 }
98 108
99 @PostConstruct 109 @PostConstruct
@@ -106,108 +116,155 @@ public class LwM2mTransportRequest { @@ -106,108 +116,155 @@ public class LwM2mTransportRequest {
106 /** 116 /**
107 * Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes 117 * Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes
108 * 118 *
109 - * @param registration -  
110 - * @param targetIdVer -  
111 - * @param typeOper -  
112 - * @param contentFormatParam -  
113 - * @param observation - 119 + * @param registration -
  120 + * @param targetIdVer -
  121 + * @param typeOper -
  122 + * @param contentFormatName -
114 */ 123 */
115 - public void sendAllRequest(Registration registration, String targetIdVer, String typeOper,  
116 - String contentFormatParam, Observation observation, Object params, long timeoutInMs) {  
117 - String target = convertPathFromIdVerToObjectId(targetIdVer);  
118 - LwM2mPath resultIds = new LwM2mPath(target);  
119 - if (registration != null && resultIds.getObjectId() >= 0) { 124 + @SneakyThrows
  125 + public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper,
  126 + String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) {
  127 + try {
  128 +
  129 + String target = convertPathFromIdVerToObjectId(targetIdVer);
120 DownlinkRequest request = null; 130 DownlinkRequest request = null;
121 - ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null;  
122 - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);  
123 - ResourceModel resource = null;  
124 - timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;  
125 - switch (typeOper) {  
126 - case GET_TYPE_OPER_READ:  
127 - request = new ReadRequest(contentFormat, target);  
128 - break;  
129 - case GET_TYPE_OPER_DISCOVER:  
130 - request = new DiscoverRequest(target);  
131 - break;  
132 - case GET_TYPE_OPER_OBSERVE:  
133 - if (resultIds.isResource()) {  
134 - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId());  
135 - } else if (resultIds.isObjectInstance()) {  
136 - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId());  
137 - } else if (resultIds.getObjectId() >= 0) {  
138 - request = new ObserveRequest(resultIds.getObjectId());  
139 - }  
140 - break;  
141 - case POST_TYPE_OPER_OBSERVE_CANCEL:  
142 - request = new CancelObservationRequest(observation);  
143 - break;  
144 - case POST_TYPE_OPER_EXECUTE:  
145 - resource = lwM2MClient.getResourceModel(targetIdVer);  
146 - if (params != null && resource != null && !resource.multiple) {  
147 - request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resource.type, ResourceModel.Type.STRING, resultIds));  
148 - } else {  
149 - request = new ExecuteRequest(target);  
150 - }  
151 - break;  
152 - case POST_TYPE_OPER_WRITE_REPLACE:  
153 - // Request to write a <b>String Single-Instance Resource</b> using the TLV content format.  
154 - resource = lwM2MClient.getResourceModel(targetIdVer);  
155 - if (resource != null && contentFormat != null) { 131 + ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT;
  132 + LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(registration, null);
  133 + LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null;
  134 + if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 &&
  135 + lwM2MClient != null) {
  136 + if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
  137 + timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
  138 + ResourceModel resourceModel = null;
  139 + switch (typeOper) {
  140 + case READ:
  141 + request = new ReadRequest(contentFormat, target);
  142 + break;
  143 + case DISCOVER:
  144 + request = new DiscoverRequest(target);
  145 + break;
  146 + case OBSERVE:
  147 + if (resultIds.isResource()) {
  148 + request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId());
  149 + } else if (resultIds.isObjectInstance()) {
  150 + request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId());
  151 + } else if (resultIds.getObjectId() >= 0) {
  152 + request = new ObserveRequest(resultIds.getObjectId());
  153 + }
  154 + break;
  155 + case OBSERVE_CANCEL:
  156 + /**
  157 + * lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
  158 + * At server side this will not remove the observation from the observation store, to do it you need to use
  159 + * {@code ObservationService#cancelObservation()}
  160 + */
  161 + leshanServer.getObservationService().cancelObservations(registration, target);
  162 + break;
  163 + case EXECUTE:
  164 + resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer()
  165 + .getModelProvider());
  166 + if (params != null && !resourceModel.multiple) {
  167 + request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModel.type, ResourceModel.Type.STRING, resultIds));
  168 + } else {
  169 + request = new ExecuteRequest(target);
  170 + }
  171 + break;
  172 + case WRITE_REPLACE:
  173 + // Request to write a <b>String Single-Instance Resource</b> using the TLV content format.
  174 +// resource = lwM2MClient.getResourceModel(targetIdVer);
156 // if (contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { 175 // if (contentFormat.equals(ContentFormat.TLV) && !resource.multiple) {
157 - if (contentFormat.equals(ContentFormat.TLV)) {  
158 - request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resource.type, registration);  
159 - }  
160 - // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON) 176 + resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer()
  177 + .getModelProvider());
  178 + if (contentFormat.equals(ContentFormat.TLV)) {
  179 + request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(),
  180 + resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type,
  181 + registration, rpcRequest);
  182 + }
  183 + // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON)
161 // else if (!contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { 184 // else if (!contentFormat.equals(ContentFormat.TLV) && !resource.multiple) {
162 - else if (!contentFormat.equals(ContentFormat.TLV)) {  
163 - request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resource.type, registration);  
164 - }  
165 - }  
166 - break;  
167 - case PUT_TYPE_OPER_WRITE_UPDATE:  
168 - if (resultIds.getResourceId() >= 0) {  
169 -// ResourceModel resourceModel = leshanServer.getModelProvider().getObjectModel(registration).getObjectModel(resultIds.getObjectId()).resources.get(resultIds.getResourceId());  
170 -// ResourceModel.Type typeRes = resourceModel.type;  
171 - LwM2mNode node = LwM2mSingleResource.newStringResource(resultIds.getResourceId(), (String) this.converter.convertValue(params, resource.type, ResourceModel.Type.STRING, resultIds));  
172 - request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, target, node); 185 + else if (!contentFormat.equals(ContentFormat.TLV)) {
  186 + request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(),
  187 + resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type,
  188 + registration, rpcRequest);
  189 + }
  190 + break;
  191 + case WRITE_UPDATE:
  192 +// LwM2mNode node = null;
  193 +// if (resultIds.isObjectInstance()) {
  194 +// node = new LwM2mObjectInstance(resultIds.getObjectInstanceId(), lwM2MClient.
  195 +// getNewResourcesForInstance(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider(),
  196 +// this.converter));
  197 +// request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, target, node);
  198 +// } else if (resultIds.getObjectId() >= 0) {
  199 +// request = new ObserveRequest(resultIds.getObjectId());
  200 +// }
  201 + break;
  202 + case WRITE_ATTRIBUTES:
  203 + request = createWriteAttributeRequest(target, params);
  204 + break;
  205 + case DELETE:
  206 + request = new DeleteRequest(target);
  207 + break;
173 } 208 }
174 - break;  
175 - case PUT_TYPE_OPER_WRITE_ATTRIBUTES:  
176 - request = createWriteAttributeRequest(target, params);  
177 - break;  
178 - }  
179 209
180 - if (request != null) {  
181 - try {  
182 - this.sendRequest(registration, lwM2MClient, request, timeoutInMs);  
183 - } catch (ClientSleepingException e) {  
184 - DownlinkRequest finalRequest = request;  
185 - long finalTimeoutInMs = timeoutInMs;  
186 - lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs));  
187 - } catch (Exception e) {  
188 - log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper, e); 210 + if (request != null) {
  211 + try {
  212 + this.sendRequest(registration, lwM2MClient, request, timeoutInMs, rpcRequest);
  213 + } catch (ClientSleepingException e) {
  214 + DownlinkRequest finalRequest = request;
  215 + long finalTimeoutInMs = timeoutInMs;
  216 + lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, rpcRequest));
  217 + } catch (Exception e) {
  218 + log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper, e);
  219 + }
  220 + } else if (OBSERVE_CANCEL == typeOper && rpcRequest != null) {
  221 + rpcRequest.setInfoMsg(null);
  222 + serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, null);
  223 + } else {
  224 + log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper, targetIdVer);
  225 + if (rpcRequest != 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);
  228 + }
  229 + }
  230 + } else if (rpcRequest != null) {
  231 + String errorMsg = String.format("Path %s not found in object version", targetIdVer);
  232 + serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
  233 + }
  234 + } else if (OBSERVE_READ_ALL.name().equals(typeOper.name())) {
  235 + Set<Observation> observations = leshanServer.getObservationService().getObservations(registration);
  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,
  238 + OBSERVE_READ_ALL.type, observationPaths);
  239 + serviceImpl.sendLogsToThingsboard(msg, registration);
  240 + log.info("[{}], [{}]", registration.getEndpoint(), msg);
  241 + if (rpcRequest != null) {
  242 + String valueMsg = String.format("Observation paths - %s", observationPaths);
  243 + serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE);
189 } 244 }
190 - } else {  
191 - log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper, targetIdVer);  
192 } 245 }
  246 + } catch (Exception e) {
  247 + String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR,
  248 + typeOper.name(), e.getMessage());
  249 + serviceImpl.sendLogsToThingsboard(msg, registration);
  250 + throw new Exception(e);
193 } 251 }
194 } 252 }
195 253
196 /** 254 /**
197 - *  
198 * @param registration - 255 * @param registration -
199 - * @param request -  
200 - * @param timeoutInMs - 256 + * @param request -
  257 + * @param timeoutInMs -
201 */ 258 */
202 259
203 @SuppressWarnings("unchecked") 260 @SuppressWarnings("unchecked")
204 - private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs) { 261 + private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) {
205 leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { 262 leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
206 if (!lwM2MClient.isInit()) { 263 if (!lwM2MClient.isInit()) {
207 lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); 264 lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration));
208 } 265 }
209 if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { 266 if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) {
210 - this.handleResponse(registration, request.getPath().toString(), response, request); 267 + this.handleResponse(registration, request.getPath().toString(), response, request, rpcRequest);
211 if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) { 268 if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) {
212 LwM2mNode node = ((WriteRequest) request).getNode(); 269 LwM2mNode node = ((WriteRequest) request).getNode();
213 Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), 270 Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(),
@@ -216,48 +273,64 @@ public class LwM2mTransportRequest { @@ -216,48 +273,64 @@ public class LwM2mTransportRequest {
216 LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), 273 LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(),
217 response.getCode().getName(), request.getPath().toString(), value); 274 response.getCode().getName(), request.getPath().toString(), value);
218 serviceImpl.sendLogsToThingsboard(msg, registration); 275 serviceImpl.sendLogsToThingsboard(msg, registration);
219 - log.debug("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), 276 + log.info("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(),
220 ((Response) response.getCoapResponse()).getCode(), response.getCode(), 277 ((Response) response.getCoapResponse()).getCode(), response.getCode(),
221 request.getPath().toString(), value); 278 request.getPath().toString(), value);
  279 + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO);
222 } 280 }
223 } else { 281 } else {
224 String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR, 282 String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR,
225 ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); 283 ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString());
226 serviceImpl.sendLogsToThingsboard(msg, registration); 284 serviceImpl.sendLogsToThingsboard(msg, registration);
227 log.error("[{}], [{}] - [{}] [{}] error SendRequest", registration.getEndpoint(), ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); 285 log.error("[{}], [{}] - [{}] [{}] error SendRequest", registration.getEndpoint(), ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString());
  286 + if (rpcRequest != null) {
  287 + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
  288 + }
228 } 289 }
229 }, e -> { 290 }, e -> {
230 if (!lwM2MClient.isInit()) { 291 if (!lwM2MClient.isInit()) {
231 lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); 292 lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration));
232 } 293 }
233 String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", 294 String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client",
234 - LOG_LW2M_ERROR, request.getPath().toString(), e.toString()); 295 + LOG_LW2M_ERROR, request.getPath().toString(), e.getMessage());
235 serviceImpl.sendLogsToThingsboard(msg, registration); 296 serviceImpl.sendLogsToThingsboard(msg, registration);
236 log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString()); 297 log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString());
  298 + if (rpcRequest != null) {
  299 + serviceImpl.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR);
  300 + }
237 }); 301 });
238 302
239 } 303 }
240 304
241 - private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, Integer resourceId, Object value, ResourceModel.Type type, Registration registration) { 305 + private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId,
  306 + Integer resourceId, Object value, ResourceModel.Type type,
  307 + Registration registration, Lwm2mClientRpcRequest rpcRequest) {
242 try { 308 try {
243 - switch (type) {  
244 - case STRING: // String  
245 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, value.toString()) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, value.toString());  
246 - case INTEGER: // Long  
247 - final long valueInt = Integer.toUnsignedLong(Integer.parseInt(value.toString()));  
248 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, valueInt) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueInt);  
249 - case OBJLNK: // ObjectLink  
250 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString()));  
251 - case BOOLEAN: // Boolean  
252 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString()));  
253 - case FLOAT: // Double  
254 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Double.parseDouble(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Double.parseDouble(value.toString()));  
255 - case TIME: // Date  
256 - Date date = new Date(Long.decode(value.toString()));  
257 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, date) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, date);  
258 - case OPAQUE: // byte[] value, base64  
259 - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray()));  
260 - default: 309 + if (type != null) {
  310 + switch (type) {
  311 + case STRING: // String
  312 + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, value.toString()) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, value.toString());
  313 + case INTEGER: // Long
  314 + final long valueInt = Integer.toUnsignedLong(Integer.parseInt(value.toString()));
  315 + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, valueInt) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueInt);
  316 + case OBJLNK: // ObjectLink
  317 + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString()));
  318 + case BOOLEAN: // Boolean
  319 + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString()));
  320 + case FLOAT: // Double
  321 + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Double.parseDouble(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Double.parseDouble(value.toString()));
  322 + case TIME: // Date
  323 + 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);
  325 + 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()));
  327 + default:
  328 + }
  329 + }
  330 + if (rpcRequest != null) {
  331 + String patn = "/" + objectId + "/" + instanceId + "/" + resourceId;
  332 + String errorMsg = String.format("Bad ResourceModel Operations (E): Resource path - %s ResourceModel type - %s", patn, type);
  333 + rpcRequest.setErrorMsg(errorMsg);
261 } 334 }
262 return null; 335 return null;
263 } catch (NumberFormatException e) { 336 } catch (NumberFormatException e) {
@@ -266,14 +339,19 @@ public class LwM2mTransportRequest { @@ -266,14 +339,19 @@ public class LwM2mTransportRequest {
266 patn, type, value, e.toString()); 339 patn, type, value, e.toString());
267 serviceImpl.sendLogsToThingsboard(msg, registration); 340 serviceImpl.sendLogsToThingsboard(msg, registration);
268 log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); 341 log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString());
  342 + if (rpcRequest != null) {
  343 + String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value);
  344 + serviceImpl.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
  345 + }
269 return null; 346 return null;
270 } 347 }
271 } 348 }
272 349
273 - private void handleResponse(Registration registration, final String path, LwM2mResponse response, DownlinkRequest request) { 350 + private void handleResponse(Registration registration, final String path, LwM2mResponse response,
  351 + DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
274 executorResponse.submit(() -> { 352 executorResponse.submit(() -> {
275 try { 353 try {
276 - sendResponse(registration, path, response, request); 354 + this.sendResponse(registration, path, response, request, rpcRequest);
277 } catch (Exception e) { 355 } catch (Exception e) {
278 log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", registration.getEndpoint(), path, e); 356 log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", registration.getEndpoint(), path, e);
279 } 357 }
@@ -282,20 +360,30 @@ public class LwM2mTransportRequest { @@ -282,20 +360,30 @@ public class LwM2mTransportRequest {
282 360
283 /** 361 /**
284 * processing a response from a client 362 * processing a response from a client
  363 + *
285 * @param registration - 364 * @param registration -
286 - * @param path -  
287 - * @param response - 365 + * @param path -
  366 + * @param response -
288 */ 367 */
289 - private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) { 368 + private void sendResponse(Registration registration, String path, LwM2mResponse response,
  369 + DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
290 String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); 370 String pathIdVer = convertPathFromObjectIdToIdVer(path, registration);
291 if (response instanceof ReadResponse) { 371 if (response instanceof ReadResponse) {
292 - serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); 372 + serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest);
293 } else if (response instanceof CancelObservationResponse) { 373 } else if (response instanceof CancelObservationResponse) {
294 log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); 374 log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response);
  375 +
295 } else if (response instanceof DeleteResponse) { 376 } else if (response instanceof DeleteResponse) {
296 log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); 377 log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response);
297 } else if (response instanceof DiscoverResponse) { 378 } else if (response instanceof DiscoverResponse) {
298 - log.info("[{}] Path [{}] DiscoverResponse 6_Send", pathIdVer, response); 379 + log.info("[{}] [{}] - [{}] [{}] Discovery value: [{}]", registration.getEndpoint(),
  380 + ((Response) response.getCoapResponse()).getCode(), response.getCode(),
  381 + request.getPath().toString(), ((DiscoverResponse) response).getObjectLinks());
  382 + if (rpcRequest != null) {
  383 + String discoveryMsg = String.format("%s",
  384 + Arrays.stream(((DiscoverResponse) response).getObjectLinks()).collect(Collectors.toSet()));
  385 + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), discoveryMsg, LOG_LW2M_VALUE);
  386 + }
299 } else if (response instanceof ExecuteResponse) { 387 } else if (response instanceof ExecuteResponse) {
300 log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); 388 log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response);
301 } else if (response instanceof WriteAttributesResponse) { 389 } else if (response instanceof WriteAttributesResponse) {
@@ -304,5 +392,11 @@ public class LwM2mTransportRequest { @@ -304,5 +392,11 @@ public class LwM2mTransportRequest {
304 log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); 392 log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response);
305 serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); 393 serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request);
306 } 394 }
  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);
  400 + }
307 } 401 }
308 } 402 }
@@ -21,6 +21,7 @@ import org.eclipse.leshan.server.registration.Registration; @@ -21,6 +21,7 @@ import org.eclipse.leshan.server.registration.Registration;
21 import org.thingsboard.server.common.data.Device; 21 import org.thingsboard.server.common.data.Device;
22 import org.thingsboard.server.common.data.DeviceProfile; 22 import org.thingsboard.server.common.data.DeviceProfile;
23 import org.thingsboard.server.gen.transport.TransportProtos; 23 import org.thingsboard.server.gen.transport.TransportProtos;
  24 +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;
24 25
25 import java.util.Collection; 26 import java.util.Collection;
26 import java.util.Optional; 27 import java.util.Optional;
@@ -37,9 +38,7 @@ public interface LwM2mTransportService { @@ -37,9 +38,7 @@ public interface LwM2mTransportService {
37 38
38 void setCancelObservations(Registration registration); 39 void setCancelObservations(Registration registration);
39 40
40 - void setCancelObservationRecourse(Registration registration, String path);  
41 -  
42 - void onObservationResponse(Registration registration, String path, ReadResponse response); 41 + void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest);
43 42
44 void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); 43 void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo);
45 44
@@ -51,7 +50,9 @@ public interface LwM2mTransportService { @@ -51,7 +50,9 @@ public interface LwM2mTransportService {
51 50
52 void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt); 51 void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt);
53 52
54 - void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest); 53 + void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, TransportProtos.SessionInfoProto sessionInfo);
  54 +
  55 + void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceRpcResponse, TransportProtos.SessionInfoProto sessionInfo);
55 56
56 void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); 57 void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse);
57 58
@@ -16,7 +16,6 @@ @@ -16,7 +16,6 @@
16 package org.thingsboard.server.transport.lwm2m.server; 16 package org.thingsboard.server.transport.lwm2m.server;
17 17
18 import com.fasterxml.jackson.core.type.TypeReference; 18 import com.fasterxml.jackson.core.type.TypeReference;
19 -import com.google.common.collect.Sets;  
20 import com.google.gson.Gson; 19 import com.google.gson.Gson;
21 import com.google.gson.GsonBuilder; 20 import com.google.gson.GsonBuilder;
22 import com.google.gson.JsonArray; 21 import com.google.gson.JsonArray;
@@ -52,6 +51,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; @@ -52,6 +51,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
52 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; 51 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
53 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; 52 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
54 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; 53 import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile;
  54 +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;
55 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; 55 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto;
56 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; 56 import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters;
57 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; 57 import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
@@ -74,21 +74,29 @@ import java.util.concurrent.Executors; @@ -74,21 +74,29 @@ import java.util.concurrent.Executors;
74 import java.util.concurrent.TimeUnit; 74 import java.util.concurrent.TimeUnit;
75 import java.util.stream.Collectors; 75 import java.util.stream.Collectors;
76 76
  77 +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST;
77 import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; 78 import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
78 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; 79 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
79 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; 80 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED;
80 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; 81 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST;
81 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER;  
82 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE;  
83 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ;  
84 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; 82 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR;
85 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; 83 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO;
  84 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE;
86 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; 85 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2;
87 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE;  
88 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;  
89 -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; 86 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper;
  87 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.DISCOVER;
  88 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.EXECUTE;
  89 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE;
  90 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_CANCEL;
  91 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_READ_ALL;
  92 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.READ;
  93 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_ATTRIBUTES;
  94 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_REPLACE;
  95 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_UPDATE;
90 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; 96 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL;
  97 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertJsonArrayToSet;
91 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; 98 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId;
  99 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer;
92 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; 100 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback;
93 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; 101 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey;
94 102
@@ -257,21 +265,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -257,21 +265,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
257 public void setCancelObservations(Registration registration) { 265 public void setCancelObservations(Registration registration) {
258 if (registration != null) { 266 if (registration != null) {
259 Set<Observation> observations = leshanServer.getObservationService().getObservations(registration); 267 Set<Observation> observations = leshanServer.getObservationService().getObservations(registration);
260 - observations.forEach(observation -> this.setCancelObservationRecourse(registration, observation.getPath().toString())); 268 + observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration,
  269 + convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL,
  270 + null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null));
261 } 271 }
262 } 272 }
263 273
264 /** 274 /**
265 - * lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());  
266 - * At server side this will not remove the observation from the observation store, to do it you need to use  
267 - * {@code ObservationService#cancelObservation()}  
268 - */  
269 - @Override  
270 - public void setCancelObservationRecourse(Registration registration, String path) {  
271 - leshanServer.getObservationService().cancelObservations(registration, path);  
272 - }  
273 -  
274 - /**  
275 * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource 275 * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource
276 * 276 *
277 * @param registration - Registration LwM2M Client 277 * @param registration - Registration LwM2M Client
@@ -279,7 +279,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -279,7 +279,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
279 * @param response - observe 279 * @param response - observe
280 */ 280 */
281 @Override 281 @Override
282 - public void onObservationResponse(Registration registration, String path, ReadResponse response) { 282 + public void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) {
283 if (response.getContent() != null) { 283 if (response.getContent() != null) {
284 if (response.getContent() instanceof LwM2mObject) { 284 if (response.getContent() instanceof LwM2mObject) {
285 LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); 285 LwM2mObject lwM2mObject = (LwM2mObject) response.getContent();
@@ -289,6 +289,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -289,6 +289,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
289 this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path); 289 this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path);
290 } else if (response.getContent() instanceof LwM2mResource) { 290 } else if (response.getContent() instanceof LwM2mResource) {
291 LwM2mResource lwM2mResource = (LwM2mResource) response.getContent(); 291 LwM2mResource lwM2mResource = (LwM2mResource) response.getContent();
  292 + if (rpcRequest != null) {
  293 + Object valueResp = lwM2mResource.isMultiInstances() ? lwM2mResource.getValues() : lwM2mResource.getValue();
  294 + Object value = this.converter.convertValue(valueResp, lwM2mResource.getType(), ResourceModel.Type.STRING,
  295 + new LwM2mPath(convertPathFromIdVerToObjectId(path)));
  296 + rpcRequest.setValueMsg(String.format("%s", value));
  297 + this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
  298 + }
292 this.updateResourcesValue(registration, lwM2mResource, path); 299 this.updateResourcesValue(registration, lwM2mResource, path);
293 } 300 }
294 } 301 }
@@ -307,11 +314,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -307,11 +314,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
307 if (msg.getSharedUpdatedCount() > 0) { 314 if (msg.getSharedUpdatedCount() > 0) {
308 msg.getSharedUpdatedList().forEach(tsKvProto -> { 315 msg.getSharedUpdatedList().forEach(tsKvProto -> {
309 String pathName = tsKvProto.getKv().getKey(); 316 String pathName = tsKvProto.getKv().getKey();
310 - String pathIdVer = this.validatePathIntoProfile(sessionInfo, pathName); 317 + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName);
311 Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); 318 Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv());
312 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); 319 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
313 if (pathIdVer != null) { 320 if (pathIdVer != null) {
314 - ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer); 321 + ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer()
  322 + .getModelProvider());
315 if (resourceModel != null && resourceModel.operations.isWritable()) { 323 if (resourceModel != null && resourceModel.operations.isWritable()) {
316 this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer); 324 this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer);
317 } else { 325 } else {
@@ -380,8 +388,124 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -380,8 +388,124 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
380 lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider())); 388 lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider()));
381 } 389 }
382 390
383 - public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest) {  
384 - log.info("[{}] toDeviceRpcRequest", toDeviceRequest); 391 + @Override
  392 + public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, SessionInfoProto sessionInfo) {
  393 + Lwm2mClientRpcRequest lwm2mClientRpcRequest = null;
  394 + try {
  395 + log.info("[{}] toDeviceRpcRequest", toDeviceRequest);
  396 + Registration registration = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration();
  397 + lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration);
  398 + if (lwm2mClientRpcRequest != null && lwm2mClientRpcRequest.getErrorMsg() != null) {
  399 + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
  400 + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
  401 + } else {
  402 + lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), lwm2mClientRpcRequest.getContentFormatName(),
  403 + lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(),
  404 + this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), lwm2mClientRpcRequest);
  405 + }
  406 + } catch (Exception e) {
  407 + if (lwm2mClientRpcRequest == null) {
  408 + lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
  409 + }
  410 + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
  411 + if (lwm2mClientRpcRequest.getErrorMsg() == null) {
  412 + lwm2mClientRpcRequest.setErrorMsg(e.getMessage());
  413 + }
  414 + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
  415 + }
  416 + }
  417 +
  418 + /**
  419 + * @param toDeviceRequest -
  420 + * @param sessionInfo -
  421 + * @param registration -
  422 + * @return
  423 + * @throws IllegalArgumentException
  424 + */
  425 + private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest,
  426 + SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException {
  427 + Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest();
  428 + try {
  429 + lwm2mClientRpcRequest.setRequestId(toDeviceRequest.getRequestId());
  430 + lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
  431 + lwm2mClientRpcRequest.setValidTypeOper(toDeviceRequest.getMethodName());
  432 + JsonObject rpcRequest = LwM2mTransportHandler.validateJson(toDeviceRequest.getParams());
  433 + if (rpcRequest != null) {
  434 + if (rpcRequest.has(lwm2mClientRpcRequest.keyNameKey)) {
  435 + String targetIdVer = this.getPresentPathIntoProfile(sessionInfo,
  436 + rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString());
  437 + if (targetIdVer != null) {
  438 + lwm2mClientRpcRequest.setTargetIdVer(targetIdVer);
  439 + lwm2mClientRpcRequest.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s",
  440 + rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString(), targetIdVer));
  441 + }
  442 + }
  443 + if (lwm2mClientRpcRequest.getTargetIdVer() == null) {
  444 + lwm2mClientRpcRequest.setValidTargetIdVerKey(rpcRequest, registration);
  445 + }
  446 + if (rpcRequest.has(lwm2mClientRpcRequest.contentFormatNameKey)) {
  447 + lwm2mClientRpcRequest.setValidContentFormatName(rpcRequest);
  448 + }
  449 + if (rpcRequest.has(lwm2mClientRpcRequest.timeoutInMsKey) && rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong() > 0) {
  450 + lwm2mClientRpcRequest.setTimeoutInMs(rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong());
  451 + }
  452 + if (rpcRequest.has(lwm2mClientRpcRequest.valueKey)) {
  453 + lwm2mClientRpcRequest.setValue(rpcRequest.get(lwm2mClientRpcRequest.valueKey).getAsString());
  454 + }
  455 + if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) {
  456 + lwm2mClientRpcRequest.setParams(new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey)
  457 + .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() {
  458 + }.getType()));
  459 + }
  460 + lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
  461 + if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) {
  462 + lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " +
  463 + lwm2mClientRpcRequest.keyNameKey + " is null or bad format");
  464 + }
  465 + else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper()
  466 + || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper())
  467 + && lwm2mClientRpcRequest.getTargetIdVer() !=null
  468 + && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource()
  469 + || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) {
  470 + lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey
  471 + + ". Only Resource or ResourceInstance can be this operation");
  472 + }
  473 + else if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()){
  474 + lwm2mClientRpcRequest.setErrorMsg("Procedures In Development...");
  475 + }
  476 + } else {
  477 + lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format.");
  478 + }
  479 + } catch (Exception e) {
  480 + throw new IllegalArgumentException(lwm2mClientRpcRequest.getErrorMsg());
  481 + }
  482 + return lwm2mClientRpcRequest;
  483 + }
  484 +
  485 + public void sentRpcRequest (Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) {
  486 + rpcRequest.setResponseCode(requestCode);
  487 + if (LOG_LW2M_ERROR.equals(typeMsg)) {
  488 + rpcRequest.setInfoMsg(null);
  489 + rpcRequest.setValueMsg(null);
  490 + if (rpcRequest.getErrorMsg() == null) {
  491 + msg = msg.isEmpty() ? null : msg;
  492 + rpcRequest.setErrorMsg(msg);
  493 + }
  494 + } else if (LOG_LW2M_INFO.equals(typeMsg)) {
  495 + if (rpcRequest.getInfoMsg() == null) {
  496 + rpcRequest.setInfoMsg(msg);
  497 + }
  498 + } else if (LOG_LW2M_VALUE.equals(typeMsg)) {
  499 + if (rpcRequest.getValueMsg() == null) {
  500 + rpcRequest.setValueMsg(msg);
  501 + }
  502 + }
  503 + this.onToDeviceRpcResponse(rpcRequest.getDeviceRpcResponseResultMsg(), rpcRequest.getSessionInfo());
  504 + }
  505 +
  506 + @Override
  507 + public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) {
  508 + transportService.process(sessionInfo, toDeviceResponse, null);
385 } 509 }
386 510
387 public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse) { 511 public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse) {
@@ -395,8 +519,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -395,8 +519,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
395 */ 519 */
396 @Override 520 @Override
397 public void doTrigger(Registration registration, String path) { 521 public void doTrigger(Registration registration, String path) {
398 - lwM2mTransportRequest.sendAllRequest(registration, path, POST_TYPE_OPER_EXECUTE,  
399 - ContentFormat.TLV.getName(), null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); 522 + lwM2mTransportRequest.sendAllRequest(registration, path, EXECUTE,
  523 + ContentFormat.TLV.getName(), null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
400 } 524 }
401 525
402 /** 526 /**
@@ -486,14 +610,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -486,14 +610,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
486 if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { 610 if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) {
487 // #2 611 // #2
488 lwM2MClient.getPendingRequests().addAll(clientObjects); 612 lwM2MClient.getPendingRequests().addAll(clientObjects);
489 - clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(),  
490 - null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout())); 613 + clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(),
  614 + null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null));
491 } 615 }
492 // #1 616 // #1
493 - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_READ, clientObjects);  
494 - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_OBSERVE, clientObjects);  
495 - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, PUT_TYPE_OPER_WRITE_ATTRIBUTES, clientObjects);  
496 - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_DISCOVER, clientObjects); 617 + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, READ, clientObjects);
  618 + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, OBSERVE, clientObjects);
  619 + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, WRITE_ATTRIBUTES, clientObjects);
  620 + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, DISCOVER, clientObjects);
497 } 621 }
498 } 622 }
499 623
@@ -534,7 +658,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -534,7 +658,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
534 */ 658 */
535 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { 659 private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) {
536 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); 660 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
537 - if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider())) { 661 + if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer()
  662 + .getModelProvider())) {
538 Set<String> paths = new HashSet<>(); 663 Set<String> paths = new HashSet<>();
539 paths.add(path); 664 paths.add(path);
540 this.updateAttrTelemetry(registration, paths); 665 this.updateAttrTelemetry(registration, paths);
@@ -570,64 +695,30 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -570,64 +695,30 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
570 } 695 }
571 696
572 /** 697 /**
573 - * @param clientProfile -  
574 - * @param path -  
575 - * @return true if path isPresent in postAttributeProfile  
576 - */  
577 - private boolean validatePathInAttrProfile(LwM2mClientProfile clientProfile, String path) {  
578 - try {  
579 - List<String> attributesSet = new Gson().fromJson(clientProfile.getPostAttributeProfile(),  
580 - new TypeToken<List<String>>() {  
581 - }.getType());  
582 - return attributesSet.stream().anyMatch(p -> p.equals(path));  
583 - } catch (Exception e) {  
584 - log.error("Fail Validate Path [{}] ClientProfile.Attribute", path, e);  
585 - return false;  
586 - }  
587 - }  
588 -  
589 - /**  
590 - * @param clientProfile -  
591 - * @param path -  
592 - * @return true if path isPresent in postAttributeProfile  
593 - */  
594 - private boolean validatePathInTelemetryProfile(LwM2mClientProfile clientProfile, String path) {  
595 - try {  
596 - List<String> telemetriesSet = new Gson().fromJson(clientProfile.getPostTelemetryProfile(), new TypeToken<List<String>>() {  
597 - }.getType());  
598 - return telemetriesSet.stream().anyMatch(p -> p.equals(path));  
599 - } catch (Exception e) {  
600 - log.error("Fail Validate Path [{}] ClientProfile.Telemetry", path, e);  
601 - return false;  
602 - }  
603 - }  
604 -  
605 - /**  
606 * Start observe/read: Attr/Telemetry 698 * Start observe/read: Attr/Telemetry
607 * #1 - Analyze: path in resource profile == client resource 699 * #1 - Analyze: path in resource profile == client resource
608 * 700 *
609 * @param registration - 701 * @param registration -
610 */ 702 */
611 private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, 703 private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient,
612 - String typeOper, Set<String> clientObjects) { 704 + LwM2mTypeOper typeOper, Set<String> clientObjects) {
613 LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); 705 LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration);
614 Set<String> result = null; 706 Set<String> result = null;
615 ConcurrentHashMap<String, Object> params = null; 707 ConcurrentHashMap<String, Object> params = null;
616 - if (GET_TYPE_OPER_READ.equals(typeOper)) { 708 + if (READ.equals(typeOper)) {
617 result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), 709 result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(),
618 new TypeReference<>() { 710 new TypeReference<>() {
619 }); 711 });
620 result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), 712 result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(),
621 new TypeReference<>() { 713 new TypeReference<>() {
622 })); 714 }));
623 - } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { 715 + } else if (OBSERVE.equals(typeOper)) {
624 result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), 716 result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(),
625 new TypeReference<>() { 717 new TypeReference<>() {
626 }); 718 });
627 - } else if (GET_TYPE_OPER_DISCOVER.equals(typeOper)) { 719 + } else if (DISCOVER.equals(typeOper)) {
628 result = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()).keySet(); 720 result = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()).keySet();
629 - ;  
630 - } else if (PUT_TYPE_OPER_WRITE_ATTRIBUTES.equals(typeOper)) { 721 + } else if (WRITE_ATTRIBUTES.equals(typeOper)) {
631 params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); 722 params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile());
632 result = params.keySet(); 723 result = params.keySet();
633 } 724 }
@@ -644,8 +735,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -644,8 +735,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
644 lwM2MClient.getPendingRequests().addAll(pathSend); 735 lwM2MClient.getPendingRequests().addAll(pathSend);
645 ConcurrentHashMap<String, Object> finalParams = params; 736 ConcurrentHashMap<String, Object> finalParams = params;
646 pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), 737 pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(),
647 - null, finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()));  
648 - if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { 738 + finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null));
  739 + if (OBSERVE.equals(typeOper)) {
649 lwM2MClient.initValue(this, null); 740 lwM2MClient.initValue(this, null);
650 } 741 }
651 } 742 }
@@ -718,11 +809,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -718,11 +809,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
718 return null; 809 return null;
719 } 810 }
720 811
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) { 812 private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) {
727 LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); 813 LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId());
728 JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); 814 JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile();
@@ -828,18 +914,18 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -828,18 +914,18 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
828 if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { 914 if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) {
829 // #1 915 // #1
830 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); 916 JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile();
831 - Set<String> attributeSetOld = this.convertJsonArrayToSet(attributeOld); 917 + Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld);
832 JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile(); 918 JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile();
833 - Set<String> telemetrySetOld = this.convertJsonArrayToSet(telemetryOld); 919 + Set<String> telemetrySetOld = convertJsonArrayToSet(telemetryOld);
834 JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile(); 920 JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile();
835 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); 921 JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile();
836 JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); 922 JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile();
837 923
838 LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); 924 LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId());
839 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); 925 JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile();
840 - Set<String> attributeSetNew = this.convertJsonArrayToSet(attributeNew); 926 + Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew);
841 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); 927 JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile();
842 - Set<String> telemetrySetNew = this.convertJsonArrayToSet(telemetryNew); 928 + Set<String> telemetrySetNew = convertJsonArrayToSet(telemetryNew);
843 JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile(); 929 JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile();
844 JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile(); 930 JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile();
845 JsonObject attributeLwm2mNew = lwM2MClientProfileNew.getPostAttributeLwm2mProfile(); 931 JsonObject attributeLwm2mNew = lwM2MClientProfileNew.getPostAttributeLwm2mProfile();
@@ -882,7 +968,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -882,7 +968,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
882 // update value in Resources 968 // update value in Resources
883 registrationIds.forEach(registrationId -> { 969 registrationIds.forEach(registrationId -> {
884 Registration registration = lwM2mClientContext.getRegistration(registrationId); 970 Registration registration = lwM2mClientContext.getRegistration(registrationId);
885 - this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ); 971 + this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ);
886 // send attr/telemetry to tingsboard for new path 972 // send attr/telemetry to tingsboard for new path
887 this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); 973 this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd());
888 }); 974 });
@@ -911,7 +997,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -911,7 +997,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
911 registrationIds.forEach(registrationId -> { 997 registrationIds.forEach(registrationId -> {
912 Registration registration = lwM2mClientContext.getRegistration(registrationId); 998 Registration registration = lwM2mClientContext.getRegistration(registrationId);
913 if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { 999 if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) {
914 - this.readResourceValueObserve(registration, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE); 1000 + this.readResourceValueObserve(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE);
915 } 1001 }
916 // 5.3 del 1002 // 5.3 del
917 // send Request cancel observe to Client 1003 // send Request cancel observe to Client
@@ -923,12 +1009,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -923,12 +1009,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
923 } 1009 }
924 } 1010 }
925 1011
926 - private Set<String> convertJsonArrayToSet(JsonArray jsonArray) {  
927 - List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() {  
928 - }.getType());  
929 - return Sets.newConcurrentHashSet(attributeListOld);  
930 - }  
931 -  
932 /** 1012 /**
933 * Compare old list with new list after change AttrTelemetryObserve in config Profile 1013 * Compare old list with new list after change AttrTelemetryObserve in config Profile
934 * 1014 *
@@ -962,16 +1042,16 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -962,16 +1042,16 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
962 * @param registration - Registration LwM2M Client 1042 * @param registration - Registration LwM2M Client
963 * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] 1043 * @param targets - path Resources == [ "/2/0/0", "/2/0/1"]
964 */ 1044 */
965 - private void readResourceValueObserve(Registration registration, Set<String> targets, String typeOper) { 1045 + private void readResourceValueObserve(Registration registration, Set<String> targets, LwM2mTypeOper typeOper) {
966 targets.forEach(target -> { 1046 targets.forEach(target -> {
967 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); 1047 LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target));
968 if (pathIds.isResource()) { 1048 if (pathIds.isResource()) {
969 - if (GET_TYPE_OPER_READ.equals(typeOper)) { 1049 + if (READ.equals(typeOper)) {
970 lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, 1050 lwM2mTransportRequest.sendAllRequest(registration, target, typeOper,
971 - ContentFormat.TLV.getName(), null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout());  
972 - } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { 1051 + ContentFormat.TLV.getName(), null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
  1052 + } else if (OBSERVE.equals(typeOper)) {
973 lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, 1053 lwM2mTransportRequest.sendAllRequest(registration, target, typeOper,
974 - null, null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); 1054 + null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
975 } 1055 }
976 } 1056 }
977 }); 1057 });
@@ -1026,8 +1106,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1026,8 +1106,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1026 .collect(Collectors.toUnmodifiableSet()); 1106 .collect(Collectors.toUnmodifiableSet());
1027 if (!pathSend.isEmpty()) { 1107 if (!pathSend.isEmpty()) {
1028 ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew; 1108 ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew;
1029 - pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, PUT_TYPE_OPER_WRITE_ATTRIBUTES, ContentFormat.TLV.getName(),  
1030 - null, finalParams.get(target), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout())); 1109 + pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(),
  1110 + finalParams.get(target), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null));
1031 } 1111 }
1032 }); 1112 });
1033 } 1113 }
@@ -1043,8 +1123,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1043,8 +1123,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1043 Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); 1123 Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target);
1044 params.clear(); 1124 params.clear();
1045 params.put(OBJECT_VERSION, ""); 1125 params.put(OBJECT_VERSION, "");
1046 - lwM2mTransportRequest.sendAllRequest(registration, target, PUT_TYPE_OPER_WRITE_ATTRIBUTES, ContentFormat.TLV.getName(),  
1047 - null, params, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); 1126 + lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(),
  1127 + params, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
1048 }); 1128 });
1049 } 1129 }
1050 }); 1130 });
@@ -1054,9 +1134,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1054,9 +1134,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1054 1134
1055 private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { 1135 private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) {
1056 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); 1136 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null);
1057 - paramAnallyzer.forEach(p -> {  
1058 - if (this.getResourceValueFromLwM2MClient(lwM2MClient, p) != null) {  
1059 - this.setCancelObservationRecourse(registration, convertPathFromIdVerToObjectId(p)); 1137 + paramAnallyzer.forEach(pathIdVer -> {
  1138 + if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) {
  1139 + lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null,
  1140 + null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
1060 } 1141 }
1061 } 1142 }
1062 ); 1143 );
@@ -1064,8 +1145,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1064,8 +1145,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1064 1145
1065 private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { 1146 private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) {
1066 if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { 1147 if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) {
1067 - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,  
1068 - ContentFormat.TLV.getName(), null, valueNew, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); 1148 + lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, WRITE_REPLACE,
  1149 + ContentFormat.TLV.getName(), valueNew,
  1150 + this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null);
1069 } else { 1151 } else {
1070 log.error("Failed update resource [{}] [{}]", path, valueNew); 1152 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", 1153 String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad",
@@ -1084,19 +1166,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1084,19 +1166,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1084 } 1166 }
1085 1167
1086 /** 1168 /**
1087 - * Get path to resource from profile equal keyName or from ModelObject equal name  
1088 - * Only for resource: isWritable && isPresent as attribute in profile -> LwM2MClientProfile (format: CamelCase)  
1089 - *  
1090 - * @param sessionInfo -  
1091 - * @param name -  
1092 - * @return path if path isPresent in postProfile  
1093 - */  
1094 - private String validatePathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) {  
1095 - String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, name);  
1096 - return !pathIdVer.isEmpty() ? pathIdVer : null;  
1097 - }  
1098 -  
1099 - /**  
1100 * Get path to resource from profile equal keyName 1169 * Get path to resource from profile equal keyName
1101 * 1170 *
1102 * @param sessionInfo - 1171 * @param sessionInfo -
@@ -1108,7 +1177,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1108,7 +1177,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1108 LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); 1177 LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo);
1109 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() 1178 return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
1110 .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) 1179 .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey)
1111 - .orElse(""); 1180 + .orElse(null);
1112 } 1181 }
1113 1182
1114 /** 1183 /**
@@ -1140,7 +1209,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1140,7 +1209,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1140 public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { 1209 public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) {
1141 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); 1210 LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo);
1142 tsKvProtos.forEach(tsKvProto -> { 1211 tsKvProtos.forEach(tsKvProto -> {
1143 - String pathIdVer = this.validatePathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); 1212 + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey());
1144 if (pathIdVer != null) { 1213 if (pathIdVer != null) {
1145 // #1.1 1214 // #1.1
1146 if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { 1215 if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) {
@@ -1276,7 +1345,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { @@ -1276,7 +1345,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService {
1276 } 1345 }
1277 1346
1278 private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { 1347 private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) {
1279 - ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer); 1348 + ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer()
  1349 + .getModelProvider());
1280 Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId(); 1350 Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId();
1281 String objectVer = validateObjectVerFromKey(pathIdVer); 1351 String objectVer = validateObjectVerFromKey(pathIdVer);
1282 return resourceModel != null && (isWritableNotOptional ? 1352 return resourceModel != null && (isWritableNotOptional ?
@@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j;
20 import org.eclipse.leshan.core.model.ResourceModel; 20 import org.eclipse.leshan.core.model.ResourceModel;
21 import org.eclipse.leshan.core.node.LwM2mPath; 21 import org.eclipse.leshan.core.node.LwM2mPath;
22 import org.eclipse.leshan.core.node.LwM2mResource; 22 import org.eclipse.leshan.core.node.LwM2mResource;
  23 +import org.eclipse.leshan.core.node.LwM2mSingleResource;
23 import org.eclipse.leshan.server.model.LwM2mModelProvider; 24 import org.eclipse.leshan.server.model.LwM2mModelProvider;
24 import org.eclipse.leshan.server.registration.Registration; 25 import org.eclipse.leshan.server.registration.Registration;
25 import org.eclipse.leshan.server.security.SecurityInfo; 26 import org.eclipse.leshan.server.security.SecurityInfo;
@@ -27,7 +28,9 @@ import org.thingsboard.server.gen.transport.TransportProtos; @@ -27,7 +28,9 @@ import org.thingsboard.server.gen.transport.TransportProtos;
27 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; 28 import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
28 import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; 29 import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest;
29 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServiceImpl; 30 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServiceImpl;
  31 +import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
30 32
  33 +import java.util.Collection;
31 import java.util.List; 34 import java.util.List;
32 import java.util.Map; 35 import java.util.Map;
33 import java.util.Queue; 36 import java.util.Queue;
@@ -39,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList; @@ -39,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList;
39 import java.util.stream.Collectors; 42 import java.util.stream.Collectors;
40 43
41 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; 44 import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
  45 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.TRANSPORT_DEFAULT_LWM2M_VERSION;
42 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; 46 import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId;
  47 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getVerFromPathIdVerOrId;
43 48
44 @Slf4j 49 @Slf4j
45 @Data 50 @Data
@@ -94,12 +99,33 @@ public class LwM2mClient implements Cloneable { @@ -94,12 +99,33 @@ public class LwM2mClient implements Cloneable {
94 } 99 }
95 } 100 }
96 101
97 - public ResourceModel getResourceModel(String pathRez) {  
98 - if (this.getResources().get(pathRez) != null) {  
99 - return this.getResources().get(pathRez).getResourceModel();  
100 - } else {  
101 - return null;  
102 - } 102 + public ResourceModel getResourceModel(String pathRez, LwM2mModelProvider modelProvider) {
  103 + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez));
  104 + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
  105 + String verRez = getVerFromPathIdVerOrId(pathRez);
  106 + return (verRez == null || verSupportedObject.equals(verRez)) ? modelProvider.getObjectModel(registration)
  107 + .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null;
  108 + }
  109 +
  110 + public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, LwM2mModelProvider modelProvider,
  111 + LwM2mValueConverterImpl converter) {
  112 + 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();
  116 + Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration)
  117 + .getObjectModel(pathIds.getObjectId()).resources;
  118 + resourceModels.forEach((k, resourceModel) -> {
  119 + resources.add(LwM2mSingleResource.newResource(k, converter.convertValue("0", ResourceModel.Type.STRING, resourceModel.type, pathIds), resourceModel.type));
  120 + });
  121 + return resources;
  122 + }
  123 +
  124 + public boolean isValidObjectVersion (String path) {
  125 + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(path));
  126 + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
  127 + String verRez = getVerFromPathIdVerOrId(path);
  128 + return verRez == null ? TRANSPORT_DEFAULT_LWM2M_VERSION.equals(verSupportedObject) : verRez.equals(verSupportedObject);
103 } 129 }
104 130
105 /** 131 /**
@@ -26,7 +26,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; @@ -26,7 +26,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
26 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; 26 import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator;
27 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; 27 import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
28 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; 28 import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler;
29 -import org.thingsboard.server.transport.lwm2m.utils.TypeServer;  
30 29
31 import java.util.Arrays; 30 import java.util.Arrays;
32 import java.util.Map; 31 import java.util.Map;
@@ -119,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { @@ -119,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
119 */ 118 */
120 @Override 119 @Override
121 public LwM2mClient addLwM2mClientToSession(String identity) { 120 public LwM2mClient addLwM2mClientToSession(String identity) {
122 - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT); 121 + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.CLIENT);
123 if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { 122 if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
124 UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; 123 UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
125 LwM2mClient client; 124 LwM2mClient client;
  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 com.google.gson.JsonObject;
  19 +import lombok.Data;
  20 +import org.eclipse.leshan.core.request.ContentFormat;
  21 +import org.eclipse.leshan.server.registration.Registration;
  22 +import org.thingsboard.server.gen.transport.TransportProtos;
  23 +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
  24 +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper;
  25 +
  26 +import java.util.concurrent.ConcurrentHashMap;
  27 +
  28 +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validPathIdVer;
  29 +
  30 +@Data
  31 +public class Lwm2mClientRpcRequest {
  32 + public final String targetIdVerKey = "targetIdVer";
  33 + public final String keyNameKey = "key";
  34 + public final String typeOperKey = "typeOper";
  35 + public final String contentFormatNameKey = "contentFormatName";
  36 + public final String valueKey = "value";
  37 + public final String infoKey = "info";
  38 + public final String paramsKey = "params";
  39 + public final String timeoutInMsKey = "timeOutInMs";
  40 + public final String resultKey = "result";
  41 + public final String errorKey = "error";
  42 + public final String methodKey = "methodName";
  43 +
  44 + private LwM2mTypeOper typeOper;
  45 + private String targetIdVer;
  46 + private String contentFormatName;
  47 + private long timeoutInMs;
  48 + private Object value;
  49 + private ConcurrentHashMap<String, Object> params;
  50 + private SessionInfoProto sessionInfo;
  51 + private int requestId;
  52 + private String errorMsg;
  53 + private String valueMsg;
  54 + private String infoMsg;
  55 + private String responseCode;
  56 +
  57 + public void setValidTypeOper (String typeOper){
  58 + try {
  59 + this.typeOper = LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper);
  60 + } catch (Exception e) {
  61 + this.errorMsg = this.methodKey + " - " + typeOper + " is not valid.";
  62 + }
  63 + }
  64 + public void setValidContentFormatName (JsonObject rpcRequest){
  65 + try {
  66 + if (ContentFormat.fromName(rpcRequest.get(this.contentFormatNameKey).getAsString()) != null) {
  67 + this.contentFormatName = rpcRequest.get(this.contentFormatNameKey).getAsString();
  68 + }
  69 + else {
  70 + this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid.";
  71 + }
  72 + } catch (Exception e) {
  73 + this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid.";
  74 + }
  75 + }
  76 +
  77 + public void setValidTargetIdVerKey (JsonObject rpcRequest, Registration registration){
  78 + if (rpcRequest.has(this.targetIdVerKey)) {
  79 + String targetIdVerStr = rpcRequest.get(targetIdVerKey).getAsString();
  80 + // targetIdVer without ver - ok
  81 + try {
  82 + // targetIdVer with/without ver - ok
  83 + this.targetIdVer = validPathIdVer(targetIdVerStr, registration);
  84 + if (this.targetIdVer != null){
  85 + this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer);
  86 + }
  87 + } catch (Exception e) {
  88 + if (this.targetIdVer == null) {
  89 + this.errorMsg = this.targetIdVerKey + " - " + targetIdVerStr + " is not valid.";
  90 + }
  91 + }
  92 + }
  93 + }
  94 +
  95 + public TransportProtos.ToDeviceRpcResponseMsg getDeviceRpcResponseResultMsg() {
  96 + JsonObject payloadResp = new JsonObject();
  97 + payloadResp.addProperty(this.resultKey, this.responseCode);
  98 + if (this.errorMsg != null) {
  99 + payloadResp.addProperty(this.errorKey, this.errorMsg);
  100 + }
  101 + else if (this.valueMsg != null) {
  102 + payloadResp.addProperty(this.valueKey, this.valueMsg);
  103 + }
  104 + else if (this.infoMsg != null) {
  105 + payloadResp.addProperty(this.infoKey, this.infoMsg);
  106 + }
  107 + return TransportProtos.ToDeviceRpcResponseMsg.newBuilder()
  108 + .setPayload(payloadResp.getAsJsonObject().toString())
  109 + .setRequestId(this.requestId)
  110 + .build();
  111 + }
  112 +}
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 -}  
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.utils;  
17 -  
18 -public enum TypeServer {  
19 - BOOTSTRAP(0, "bootstrap"),  
20 - CLIENT(1, "client");  
21 -  
22 - public int code;  
23 - public String type;  
24 -  
25 - TypeServer(int code, String type) {  
26 - this.code = code;  
27 - this.type = type;  
28 - }  
29 -}