Commit 5f8a9e9f679f7f333a10bbabd51b22d519207144
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 | 35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
36 | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
37 | 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 | 40 | import java.io.IOException; |
41 | 41 | import java.security.GeneralSecurityException; |
... | ... | @@ -69,7 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
69 | 69 | |
70 | 70 | @Override |
71 | 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 | 73 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
74 | 74 | /** add value to store from BootstrapJson */ |
75 | 75 | this.setBootstrapConfigScurityInfo(store); |
... | ... | @@ -93,7 +93,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { |
93 | 93 | |
94 | 94 | @Override |
95 | 95 | public SecurityInfo getByIdentity(String identity) { |
96 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.BOOTSTRAP); | |
96 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP); | |
97 | 97 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
98 | 98 | /** add value to store from BootstrapJson */ |
99 | 99 | this.setBootstrapConfigScurityInfo(store); | ... | ... |
... | ... | @@ -28,7 +28,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC |
28 | 28 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
29 | 29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; |
30 | 30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
31 | -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | |
32 | 31 | |
33 | 32 | import java.io.IOException; |
34 | 33 | import java.security.GeneralSecurityException; |
... | ... | @@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator { |
59 | 58 | * @param keyValue - |
60 | 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 | 62 | CountDownLatch latch = new CountDownLatch(1); |
64 | 63 | final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; |
65 | 64 | contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), |
... | ... | @@ -96,7 +95,7 @@ public class LwM2mCredentialsSecurityInfoValidator { |
96 | 95 | * @param keyValue - |
97 | 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 | 99 | ReadResultSecurityStore result = new ReadResultSecurityStore(); |
101 | 100 | JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr); |
102 | 101 | if (objectMsg != null && !objectMsg.isJsonNull()) { |
... | ... | @@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator { |
109 | 108 | && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; |
110 | 109 | endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; |
111 | 110 | if (object != null && !object.isJsonNull()) { |
112 | - if (keyValue.equals(TypeServer.BOOTSTRAP)) { | |
111 | + if (keyValue.equals(LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP)) { | |
113 | 112 | result.setBootstrapJsonCredential(object); |
114 | 113 | result.setEndPoint(endPoint); |
115 | 114 | result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); | ... | ... |
... | ... | @@ -92,7 +92,8 @@ public class LwM2mServerListener { |
92 | 92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
93 | 93 | if (registration != null) { |
94 | 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 | 97 | } catch (Exception e) { |
97 | 98 | log.error("[{}] onResponse", e.toString()); |
98 | 99 | ... | ... |
... | ... | @@ -75,7 +75,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s |
75 | 75 | |
76 | 76 | @Override |
77 | 77 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
78 | - this.service.onToDeviceRpcRequest(toDeviceRequest); | |
78 | + this.service.onToDeviceRpcRequest(toDeviceRequest,this.sessionInfo); | |
79 | 79 | } |
80 | 80 | |
81 | 81 | @Override | ... | ... |
... | ... | @@ -16,9 +16,13 @@ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | |
18 | 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 | 22 | import com.google.gson.JsonObject; |
20 | 23 | import com.google.gson.JsonParser; |
21 | 24 | import com.google.gson.JsonSyntaxException; |
25 | +import com.google.gson.reflect.TypeToken; | |
22 | 26 | import lombok.extern.slf4j.Slf4j; |
23 | 27 | import org.apache.commons.lang3.StringUtils; |
24 | 28 | import org.eclipse.californium.core.network.config.NetworkConfig; |
... | ... | @@ -26,7 +30,12 @@ import org.eclipse.leshan.core.attributes.Attribute; |
26 | 30 | import org.eclipse.leshan.core.attributes.AttributeSet; |
27 | 31 | import org.eclipse.leshan.core.model.ObjectModel; |
28 | 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 | 37 | import org.eclipse.leshan.core.node.LwM2mPath; |
38 | +import org.eclipse.leshan.core.node.LwM2mSingleResource; | |
30 | 39 | import org.eclipse.leshan.core.node.codec.CodecException; |
31 | 40 | import org.eclipse.leshan.core.request.DownlinkRequest; |
32 | 41 | import org.eclipse.leshan.core.request.WriteAttributesRequest; |
... | ... | @@ -50,6 +59,7 @@ import java.util.LinkedList; |
50 | 59 | import java.util.List; |
51 | 60 | import java.util.Map; |
52 | 61 | import java.util.Optional; |
62 | +import java.util.Set; | |
53 | 63 | import java.util.concurrent.ConcurrentHashMap; |
54 | 64 | |
55 | 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 | 72 | @Slf4j |
63 | 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 | 77 | public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; |
68 | 78 | public static final String BOOTSTRAP = "bootstrap"; |
69 | 79 | public static final String SERVERS = "servers"; |
... | ... | @@ -73,21 +83,21 @@ public class LwM2mTransportHandler { |
73 | 83 | public static final String ATTRIBUTE = "attribute"; |
74 | 84 | public static final String TELEMETRY = "telemetry"; |
75 | 85 | public static final String KEY_NAME = "keyName"; |
76 | - public static final String OBSERVE = "observe"; | |
86 | + public static final String OBSERVE_LWM2M = "observe"; | |
77 | 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 | 91 | private static final String REQUEST = "/request"; |
82 | - private static final String RESPONSE = "/response"; | |
92 | + // private static final String RESPONSE = "/response"; | |
83 | 93 | private static final String ATTRIBUTES = "/" + ATTRIBUTE; |
84 | 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 | 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 | 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 | 102 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms |
93 | 103 | |
... | ... | @@ -95,30 +105,86 @@ public class LwM2mTransportHandler { |
95 | 105 | public static final String LOG_LW2M_INFO = "info"; |
96 | 106 | public static final String LOG_LW2M_ERROR = "error"; |
97 | 107 | public static final String LOG_LW2M_WARN = "warn"; |
108 | + public static final String LOG_LW2M_VALUE = "value"; | |
98 | 109 | |
99 | 110 | public static final int LWM2M_STRATEGY_1 = 1; |
100 | 111 | public static final int LWM2M_STRATEGY_2 = 2; |
101 | 112 | |
102 | 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 | 189 | public static final String EVENT_AWAKE = "AWAKE"; |
124 | 190 | public static final String SERVICE_CHANNEL = "SERVICE"; |
... | ... | @@ -156,19 +222,20 @@ public class LwM2mTransportHandler { |
156 | 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 | 240 | public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) { |
174 | 241 | LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile(); |
... | ... | @@ -177,7 +244,7 @@ public class LwM2mTransportHandler { |
177 | 244 | lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); |
178 | 245 | lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); |
179 | 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 | 248 | lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject()); |
182 | 249 | return lwM2MClientProfile; |
183 | 250 | } |
... | ... | @@ -198,8 +265,8 @@ public class LwM2mTransportHandler { |
198 | 265 | * "telemetry":["/1/0/1","/2/0/1","/6/0/1"], |
199 | 266 | * "observe":["/2/0","/2/0/0","/4/0/2"]} |
200 | 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 | 271 | public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { |
205 | 272 | if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { |
... | ... | @@ -254,9 +321,9 @@ public class LwM2mTransportHandler { |
254 | 321 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) && |
255 | 322 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() && |
256 | 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 | 327 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE_LWM2M) && |
261 | 328 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonNull() && |
262 | 329 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonObject()); |
... | ... | @@ -341,8 +408,7 @@ public class LwM2mTransportHandler { |
341 | 408 | if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { |
342 | 409 | keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; |
343 | 410 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
344 | - } | |
345 | - else { | |
411 | + } else { | |
346 | 412 | return pathIdVer; |
347 | 413 | } |
348 | 414 | } catch (Exception e) { |
... | ... | @@ -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 | 450 | public static String convertPathFromObjectIdToIdVer(String path, Registration registration) { |
354 | 451 | String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); |
355 | 452 | try { |
... | ... | @@ -357,8 +454,7 @@ public class LwM2mTransportHandler { |
357 | 454 | if (keyArray.length > 1) { |
358 | 455 | keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; |
359 | 456 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
360 | - } | |
361 | - else { | |
457 | + } else { | |
362 | 458 | return path; |
363 | 459 | } |
364 | 460 | } catch (Exception e) { |
... | ... | @@ -397,13 +493,13 @@ public class LwM2mTransportHandler { |
397 | 493 | * when: |
398 | 494 | * a.old value is 17 and new value is 24 due to lt condition |
399 | 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 | 504 | public static DownlinkRequest createWriteAttributeRequest(String target, Object params) { |
409 | 505 | AttributeSet attrSet = new AttributeSet(createWriteAttributes(params)); |
... | ... | @@ -423,4 +519,12 @@ public class LwM2mTransportHandler { |
423 | 519 | }); |
424 | 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 | 15 | */ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | |
18 | +import lombok.SneakyThrows; | |
18 | 19 | import lombok.extern.slf4j.Slf4j; |
19 | 20 | import org.eclipse.californium.core.coap.CoAP; |
20 | 21 | import org.eclipse.californium.core.coap.Response; |
... | ... | @@ -24,8 +25,8 @@ import org.eclipse.leshan.core.node.LwM2mPath; |
24 | 25 | import org.eclipse.leshan.core.node.LwM2mSingleResource; |
25 | 26 | import org.eclipse.leshan.core.node.ObjectLink; |
26 | 27 | import org.eclipse.leshan.core.observation.Observation; |
27 | -import org.eclipse.leshan.core.request.CancelObservationRequest; | |
28 | 28 | import org.eclipse.leshan.core.request.ContentFormat; |
29 | +import org.eclipse.leshan.core.request.DeleteRequest; | |
29 | 30 | import org.eclipse.leshan.core.request.DiscoverRequest; |
30 | 31 | import org.eclipse.leshan.core.request.DownlinkRequest; |
31 | 32 | import org.eclipse.leshan.core.request.ExecuteRequest; |
... | ... | @@ -47,27 +48,31 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; |
47 | 48 | import org.eclipse.leshan.server.californium.LeshanServer; |
48 | 49 | import org.eclipse.leshan.server.registration.Registration; |
49 | 50 | import org.springframework.stereotype.Service; |
51 | +import org.thingsboard.server.common.transport.TransportService; | |
50 | 52 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
51 | 53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
52 | 54 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
55 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | |
53 | 56 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
54 | 57 | |
55 | 58 | import javax.annotation.PostConstruct; |
59 | +import java.util.Arrays; | |
56 | 60 | import java.util.Date; |
61 | +import java.util.Set; | |
57 | 62 | import java.util.concurrent.ExecutorService; |
58 | 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 | 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 | 70 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
65 | 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 | 76 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; |
72 | 77 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
73 | 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 | 84 | public class LwM2mTransportRequest { |
80 | 85 | private ExecutorService executorResponse; |
81 | 86 | |
82 | - private LwM2mValueConverterImpl converter; | |
87 | + public LwM2mValueConverterImpl converter; | |
83 | 88 | |
84 | 89 | private final LwM2mTransportContextServer lwM2mTransportContextServer; |
85 | 90 | |
... | ... | @@ -89,11 +94,16 @@ public class LwM2mTransportRequest { |
89 | 94 | |
90 | 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 | 102 | this.lwM2mTransportContextServer = lwM2mTransportContextServer; |
94 | 103 | this.lwM2mClientContext = lwM2mClientContext; |
95 | 104 | this.leshanServer = leshanServer; |
96 | 105 | this.serviceImpl = serviceImpl; |
106 | + this.transportService = transportService; | |
97 | 107 | } |
98 | 108 | |
99 | 109 | @PostConstruct |
... | ... | @@ -106,108 +116,155 @@ public class LwM2mTransportRequest { |
106 | 116 | /** |
107 | 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 | 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 | 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 | 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 | 255 | * @param registration - |
199 | - * @param request - | |
200 | - * @param timeoutInMs - | |
256 | + * @param request - | |
257 | + * @param timeoutInMs - | |
201 | 258 | */ |
202 | 259 | |
203 | 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 | 262 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { |
206 | 263 | if (!lwM2MClient.isInit()) { |
207 | 264 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
208 | 265 | } |
209 | 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 | 268 | if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) { |
212 | 269 | LwM2mNode node = ((WriteRequest) request).getNode(); |
213 | 270 | Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), |
... | ... | @@ -216,48 +273,64 @@ public class LwM2mTransportRequest { |
216 | 273 | LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), |
217 | 274 | response.getCode().getName(), request.getPath().toString(), value); |
218 | 275 | serviceImpl.sendLogsToThingsboard(msg, registration); |
219 | - log.debug("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), | |
276 | + log.info("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), | |
220 | 277 | ((Response) response.getCoapResponse()).getCode(), response.getCode(), |
221 | 278 | request.getPath().toString(), value); |
279 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO); | |
222 | 280 | } |
223 | 281 | } else { |
224 | 282 | String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR, |
225 | 283 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); |
226 | 284 | serviceImpl.sendLogsToThingsboard(msg, registration); |
227 | 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 | 290 | }, e -> { |
230 | 291 | if (!lwM2MClient.isInit()) { |
231 | 292 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
232 | 293 | } |
233 | 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 | 296 | serviceImpl.sendLogsToThingsboard(msg, registration); |
236 | 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 | 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 | 335 | return null; |
263 | 336 | } catch (NumberFormatException e) { |
... | ... | @@ -266,14 +339,19 @@ public class LwM2mTransportRequest { |
266 | 339 | patn, type, value, e.toString()); |
267 | 340 | serviceImpl.sendLogsToThingsboard(msg, registration); |
268 | 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 | 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 | 352 | executorResponse.submit(() -> { |
275 | 353 | try { |
276 | - sendResponse(registration, path, response, request); | |
354 | + this.sendResponse(registration, path, response, request, rpcRequest); | |
277 | 355 | } catch (Exception e) { |
278 | 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 | 360 | |
283 | 361 | /** |
284 | 362 | * processing a response from a client |
363 | + * | |
285 | 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 | 370 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); |
291 | 371 | if (response instanceof ReadResponse) { |
292 | - serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); | |
372 | + serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); | |
293 | 373 | } else if (response instanceof CancelObservationResponse) { |
294 | 374 | log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); |
375 | + | |
295 | 376 | } else if (response instanceof DeleteResponse) { |
296 | 377 | log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); |
297 | 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 | 387 | } else if (response instanceof ExecuteResponse) { |
300 | 388 | log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); |
301 | 389 | } else if (response instanceof WriteAttributesResponse) { |
... | ... | @@ -304,5 +392,11 @@ public class LwM2mTransportRequest { |
304 | 392 | log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); |
305 | 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 | 21 | import org.thingsboard.server.common.data.Device; |
22 | 22 | import org.thingsboard.server.common.data.DeviceProfile; |
23 | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | |
24 | 25 | |
25 | 26 | import java.util.Collection; |
26 | 27 | import java.util.Optional; |
... | ... | @@ -37,9 +38,7 @@ public interface LwM2mTransportService { |
37 | 38 | |
38 | 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 | 43 | void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); |
45 | 44 | |
... | ... | @@ -51,7 +50,9 @@ public interface LwM2mTransportService { |
51 | 50 | |
52 | 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 | 57 | void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); |
57 | 58 | ... | ... |
... | ... | @@ -16,7 +16,6 @@ |
16 | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | -import com.google.common.collect.Sets; | |
20 | 19 | import com.google.gson.Gson; |
21 | 20 | import com.google.gson.GsonBuilder; |
22 | 21 | import com.google.gson.JsonArray; |
... | ... | @@ -52,6 +51,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
52 | 51 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
53 | 52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
54 | 53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
54 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | |
55 | 55 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; |
56 | 56 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; |
57 | 57 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
... | ... | @@ -74,21 +74,29 @@ import java.util.concurrent.Executors; |
74 | 74 | import java.util.concurrent.TimeUnit; |
75 | 75 | import java.util.stream.Collectors; |
76 | 76 | |
77 | +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; | |
77 | 78 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
78 | 79 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
79 | 80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; |
80 | 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 | 82 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
85 | 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 | 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 | 96 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; |
97 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertJsonArrayToSet; | |
91 | 98 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
99 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; | |
92 | 100 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; |
93 | 101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; |
94 | 102 | |
... | ... | @@ -257,21 +265,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
257 | 265 | public void setCancelObservations(Registration registration) { |
258 | 266 | if (registration != null) { |
259 | 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 | 275 | * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource |
276 | 276 | * |
277 | 277 | * @param registration - Registration LwM2M Client |
... | ... | @@ -279,7 +279,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
279 | 279 | * @param response - observe |
280 | 280 | */ |
281 | 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 | 283 | if (response.getContent() != null) { |
284 | 284 | if (response.getContent() instanceof LwM2mObject) { |
285 | 285 | LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); |
... | ... | @@ -289,6 +289,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
289 | 289 | this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path); |
290 | 290 | } else if (response.getContent() instanceof LwM2mResource) { |
291 | 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 | 299 | this.updateResourcesValue(registration, lwM2mResource, path); |
293 | 300 | } |
294 | 301 | } |
... | ... | @@ -307,11 +314,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
307 | 314 | if (msg.getSharedUpdatedCount() > 0) { |
308 | 315 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
309 | 316 | String pathName = tsKvProto.getKv().getKey(); |
310 | - String pathIdVer = this.validatePathIntoProfile(sessionInfo, pathName); | |
317 | + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); | |
311 | 318 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); |
312 | 319 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); |
313 | 320 | if (pathIdVer != null) { |
314 | - ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer); | |
321 | + ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() | |
322 | + .getModelProvider()); | |
315 | 323 | if (resourceModel != null && resourceModel.operations.isWritable()) { |
316 | 324 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer); |
317 | 325 | } else { |
... | ... | @@ -380,8 +388,124 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
380 | 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 | 511 | public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse) { |
... | ... | @@ -395,8 +519,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
395 | 519 | */ |
396 | 520 | @Override |
397 | 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 | 610 | if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { |
487 | 611 | // #2 |
488 | 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 | 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 | 658 | */ |
535 | 659 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { |
536 | 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 | 663 | Set<String> paths = new HashSet<>(); |
539 | 664 | paths.add(path); |
540 | 665 | this.updateAttrTelemetry(registration, paths); |
... | ... | @@ -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 | 698 | * Start observe/read: Attr/Telemetry |
607 | 699 | * #1 - Analyze: path in resource profile == client resource |
608 | 700 | * |
609 | 701 | * @param registration - |
610 | 702 | */ |
611 | 703 | private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, |
612 | - String typeOper, Set<String> clientObjects) { | |
704 | + LwM2mTypeOper typeOper, Set<String> clientObjects) { | |
613 | 705 | LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); |
614 | 706 | Set<String> result = null; |
615 | 707 | ConcurrentHashMap<String, Object> params = null; |
616 | - if (GET_TYPE_OPER_READ.equals(typeOper)) { | |
708 | + if (READ.equals(typeOper)) { | |
617 | 709 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), |
618 | 710 | new TypeReference<>() { |
619 | 711 | }); |
620 | 712 | result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), |
621 | 713 | new TypeReference<>() { |
622 | 714 | })); |
623 | - } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { | |
715 | + } else if (OBSERVE.equals(typeOper)) { | |
624 | 716 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), |
625 | 717 | new TypeReference<>() { |
626 | 718 | }); |
627 | - } else if (GET_TYPE_OPER_DISCOVER.equals(typeOper)) { | |
719 | + } else if (DISCOVER.equals(typeOper)) { | |
628 | 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 | 722 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); |
632 | 723 | result = params.keySet(); |
633 | 724 | } |
... | ... | @@ -644,8 +735,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
644 | 735 | lwM2MClient.getPendingRequests().addAll(pathSend); |
645 | 736 | ConcurrentHashMap<String, Object> finalParams = params; |
646 | 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 | 740 | lwM2MClient.initValue(this, null); |
650 | 741 | } |
651 | 742 | } |
... | ... | @@ -718,11 +809,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
718 | 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 | 812 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { |
727 | 813 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); |
728 | 814 | JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); |
... | ... | @@ -828,18 +914,18 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
828 | 914 | if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { |
829 | 915 | // #1 |
830 | 916 | JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); |
831 | - Set<String> attributeSetOld = this.convertJsonArrayToSet(attributeOld); | |
917 | + Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld); | |
832 | 918 | JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile(); |
833 | - Set<String> telemetrySetOld = this.convertJsonArrayToSet(telemetryOld); | |
919 | + Set<String> telemetrySetOld = convertJsonArrayToSet(telemetryOld); | |
834 | 920 | JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile(); |
835 | 921 | JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); |
836 | 922 | JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); |
837 | 923 | |
838 | 924 | LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); |
839 | 925 | JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); |
840 | - Set<String> attributeSetNew = this.convertJsonArrayToSet(attributeNew); | |
926 | + Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew); | |
841 | 927 | JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); |
842 | - Set<String> telemetrySetNew = this.convertJsonArrayToSet(telemetryNew); | |
928 | + Set<String> telemetrySetNew = convertJsonArrayToSet(telemetryNew); | |
843 | 929 | JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile(); |
844 | 930 | JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile(); |
845 | 931 | JsonObject attributeLwm2mNew = lwM2MClientProfileNew.getPostAttributeLwm2mProfile(); |
... | ... | @@ -882,7 +968,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
882 | 968 | // update value in Resources |
883 | 969 | registrationIds.forEach(registrationId -> { |
884 | 970 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
885 | - this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ); | |
971 | + this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); | |
886 | 972 | // send attr/telemetry to tingsboard for new path |
887 | 973 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); |
888 | 974 | }); |
... | ... | @@ -911,7 +997,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
911 | 997 | registrationIds.forEach(registrationId -> { |
912 | 998 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
913 | 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 | 1002 | // 5.3 del |
917 | 1003 | // send Request cancel observe to Client |
... | ... | @@ -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 | 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 | 1042 | * @param registration - Registration LwM2M Client |
963 | 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 | 1046 | targets.forEach(target -> { |
967 | 1047 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); |
968 | 1048 | if (pathIds.isResource()) { |
969 | - if (GET_TYPE_OPER_READ.equals(typeOper)) { | |
1049 | + if (READ.equals(typeOper)) { | |
970 | 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 | 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 | 1106 | .collect(Collectors.toUnmodifiableSet()); |
1027 | 1107 | if (!pathSend.isEmpty()) { |
1028 | 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 | 1123 | Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); |
1044 | 1124 | params.clear(); |
1045 | 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 | 1134 | |
1055 | 1135 | private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { |
1056 | 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 | 1145 | |
1065 | 1146 | private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { |
1066 | 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 | 1151 | } else { |
1070 | 1152 | log.error("Failed update resource [{}] [{}]", path, valueNew); |
1071 | 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 | 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 | 1169 | * Get path to resource from profile equal keyName |
1101 | 1170 | * |
1102 | 1171 | * @param sessionInfo - |
... | ... | @@ -1108,7 +1177,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
1108 | 1177 | LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); |
1109 | 1178 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
1110 | 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 | 1209 | public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { |
1141 | 1210 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); |
1142 | 1211 | tsKvProtos.forEach(tsKvProto -> { |
1143 | - String pathIdVer = this.validatePathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); | |
1212 | + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); | |
1144 | 1213 | if (pathIdVer != null) { |
1145 | 1214 | // #1.1 |
1146 | 1215 | if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { |
... | ... | @@ -1276,7 +1345,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { |
1276 | 1345 | } |
1277 | 1346 | |
1278 | 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 | 1350 | Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId(); |
1281 | 1351 | String objectVer = validateObjectVerFromKey(pathIdVer); |
1282 | 1352 | return resourceModel != null && (isWritableNotOptional ? | ... | ... |
... | ... | @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; |
20 | 20 | import org.eclipse.leshan.core.model.ResourceModel; |
21 | 21 | import org.eclipse.leshan.core.node.LwM2mPath; |
22 | 22 | import org.eclipse.leshan.core.node.LwM2mResource; |
23 | +import org.eclipse.leshan.core.node.LwM2mSingleResource; | |
23 | 24 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
24 | 25 | import org.eclipse.leshan.server.registration.Registration; |
25 | 26 | import org.eclipse.leshan.server.security.SecurityInfo; |
... | ... | @@ -27,7 +28,9 @@ import org.thingsboard.server.gen.transport.TransportProtos; |
27 | 28 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; |
28 | 29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; |
29 | 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 | 34 | import java.util.List; |
32 | 35 | import java.util.Map; |
33 | 36 | import java.util.Queue; |
... | ... | @@ -39,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList; |
39 | 42 | import java.util.stream.Collectors; |
40 | 43 | |
41 | 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 | 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 | 49 | @Slf4j |
45 | 50 | @Data |
... | ... | @@ -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 | 26 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
27 | 27 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
28 | 28 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
29 | -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | |
30 | 29 | |
31 | 30 | import java.util.Arrays; |
32 | 31 | import java.util.Map; |
... | ... | @@ -119,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { |
119 | 118 | */ |
120 | 119 | @Override |
121 | 120 | public LwM2mClient addLwM2mClientToSession(String identity) { |
122 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT); | |
121 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.CLIENT); | |
123 | 122 | if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
124 | 123 | UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; |
125 | 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 | +} | ... | ... |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResultsResourceValue.java
deleted
100644 → 0
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 | -} |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/TypeServer.java
deleted
100644 → 0
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 | -} |