Showing
9 changed files
with
490 additions
and
302 deletions
@@ -23,6 +23,7 @@ import com.google.gson.JsonElement; | @@ -23,6 +23,7 @@ import com.google.gson.JsonElement; | ||
23 | import com.google.gson.JsonObject; | 23 | import com.google.gson.JsonObject; |
24 | import com.google.gson.reflect.TypeToken; | 24 | import com.google.gson.reflect.TypeToken; |
25 | import lombok.extern.slf4j.Slf4j; | 25 | import lombok.extern.slf4j.Slf4j; |
26 | +import org.apache.commons.lang3.StringUtils; | ||
26 | import org.eclipse.leshan.core.model.ObjectModel; | 27 | import org.eclipse.leshan.core.model.ObjectModel; |
27 | import org.eclipse.leshan.core.model.ResourceModel; | 28 | import org.eclipse.leshan.core.model.ResourceModel; |
28 | import org.eclipse.leshan.core.node.LwM2mObject; | 29 | import org.eclipse.leshan.core.node.LwM2mObject; |
@@ -61,6 +62,7 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | @@ -61,6 +62,7 @@ import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | ||
61 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 62 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
62 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; | 63 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
63 | import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | 64 | import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; |
65 | +import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue; | ||
64 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; | 66 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; |
65 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; | 67 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; |
66 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; | 68 | import org.thingsboard.server.transport.lwm2m.server.store.TbLwM2MDtlsSessionStore; |
@@ -99,21 +101,20 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | @@ -99,21 +101,20 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | ||
99 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; | 101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; |
100 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2; | 102 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2; |
101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; | 103 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; |
102 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_All; | ||
103 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; | 104 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; |
104 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; | 105 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE; |
105 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; | 106 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; |
106 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; | 107 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL; |
107 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ; | 108 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ; |
108 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; | 109 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; |
109 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; | 110 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; |
110 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; | ||
111 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID; | 111 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID; |
112 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_RESULT_ID; | 112 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_RESULT_ID; |
113 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet; | 113 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet; |
114 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; | 114 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; |
115 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; | 115 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer; |
116 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getAckCallback; | 116 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getAckCallback; |
117 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.setValidTypeOper; | ||
117 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validateObjectVerFromKey; | 118 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validateObjectVerFromKey; |
118 | 119 | ||
119 | 120 | ||
@@ -125,7 +126,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -125,7 +126,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
125 | private ExecutorService registrationExecutor; | 126 | private ExecutorService registrationExecutor; |
126 | private ExecutorService updateRegistrationExecutor; | 127 | private ExecutorService updateRegistrationExecutor; |
127 | private ExecutorService unRegistrationExecutor; | 128 | private ExecutorService unRegistrationExecutor; |
128 | - private LwM2mValueConverterImpl converter; | 129 | + public LwM2mValueConverterImpl converter; |
129 | 130 | ||
130 | private final TransportService transportService; | 131 | private final TransportService transportService; |
131 | private final LwM2mTransportContext context; | 132 | private final LwM2mTransportContext context; |
@@ -133,10 +134,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -133,10 +134,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
133 | public final FirmwareDataCache firmwareDataCache; | 134 | public final FirmwareDataCache firmwareDataCache; |
134 | public final LwM2mTransportServerHelper helper; | 135 | public final LwM2mTransportServerHelper helper; |
135 | private final LwM2MJsonAdaptor adaptor; | 136 | private final LwM2MJsonAdaptor adaptor; |
136 | - private final LwM2mClientContext clientContext; | ||
137 | - private final LwM2mTransportRequest lwM2mTransportRequest; | ||
138 | private final TbLwM2MDtlsSessionStore sessionStore; | 137 | private final TbLwM2MDtlsSessionStore sessionStore; |
139 | - | 138 | + public final LwM2mClientContext clientContext; |
139 | + public final LwM2mTransportRequest lwM2mTransportRequest; | ||
140 | + private final Map<UUID, Long> rpcSubscriptions; | ||
140 | 141 | ||
141 | public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, | 142 | public DefaultLwM2MTransportMsgHandler(TransportService transportService, LwM2MTransportServerConfig config, LwM2mTransportServerHelper helper, |
142 | LwM2mClientContext clientContext, | 143 | LwM2mClientContext clientContext, |
@@ -151,6 +152,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -151,6 +152,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
151 | this.firmwareDataCache = firmwareDataCache; | 152 | this.firmwareDataCache = firmwareDataCache; |
152 | this.context = context; | 153 | this.context = context; |
153 | this.adaptor = adaptor; | 154 | this.adaptor = adaptor; |
155 | + this.rpcSubscriptions = new ConcurrentHashMap<>(); | ||
154 | this.sessionStore = sessionStore; | 156 | this.sessionStore = sessionStore; |
155 | } | 157 | } |
156 | 158 | ||
@@ -241,16 +243,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -241,16 +243,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
241 | 243 | ||
242 | /** | 244 | /** |
243 | * @param registration - Registration LwM2M Client | 245 | * @param registration - Registration LwM2M Client |
244 | - * @param observations - All paths observations before unReg | ||
245 | - * !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect | 246 | + * @param observations - !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect |
246 | */ | 247 | */ |
247 | public void unReg(Registration registration, Collection<Observation> observations) { | 248 | public void unReg(Registration registration, Collection<Observation> observations) { |
249 | + log.error("Client unRegistration -> test", new RuntimeException()); | ||
248 | unRegistrationExecutor.submit(() -> { | 250 | unRegistrationExecutor.submit(() -> { |
249 | try { | 251 | try { |
250 | - this.setCancelObservationsAll(registration); | ||
251 | this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); | 252 | this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId()); |
252 | this.closeClientSession(registration); | 253 | this.closeClientSession(registration); |
253 | - ; | ||
254 | } catch (Throwable t) { | 254 | } catch (Throwable t) { |
255 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); | 255 | log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t); |
256 | this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId()); | 256 | this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId()); |
@@ -285,12 +285,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -285,12 +285,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
285 | @Override | 285 | @Override |
286 | public void setCancelObservationsAll(Registration registration) { | 286 | public void setCancelObservationsAll(Registration registration) { |
287 | if (registration != null) { | 287 | if (registration != null) { |
288 | - lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL, | 288 | + lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL_ALL, |
289 | null, null, this.config.getTimeout(), null); | 289 | null, null, this.config.getTimeout(), null); |
290 | -// Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); | ||
291 | -// observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration, | ||
292 | -// convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL, | ||
293 | -// null, null, this.config.getTimeout(), null)); | ||
294 | } | 290 | } |
295 | } | 291 | } |
296 | 292 | ||
@@ -354,12 +350,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -354,12 +350,13 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
354 | */ | 350 | */ |
355 | @Override | 351 | @Override |
356 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { | 352 | public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { |
357 | - LwM2mClient lwM2MClient = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 353 | + LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); |
358 | if (msg.getSharedUpdatedCount() > 0) { | 354 | if (msg.getSharedUpdatedCount() > 0) { |
359 | msg.getSharedUpdatedList().forEach(tsKvProto -> { | 355 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
360 | String pathName = tsKvProto.getKv().getKey(); | 356 | String pathName = tsKvProto.getKv().getKey(); |
361 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); | 357 | String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
362 | Object valueNew = getValueFromKvProto(tsKvProto.getKv()); | 358 | Object valueNew = getValueFromKvProto(tsKvProto.getKv()); |
359 | + log.warn("12) Shared AttributeUpdate start pathName [{}], pathIdVer [{}], valueNew [{}]", pathName, pathIdVer, valueNew); | ||
363 | if ((FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) | 360 | if ((FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.VERSION).equals(pathName) |
364 | && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion()))) | 361 | && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion()))) |
365 | || (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.TITLE).equals(pathName) | 362 | || (FirmwareUtil.getAttributeKey(FirmwareType.FIRMWARE, FirmwareKey.TITLE).equals(pathName) |
@@ -438,121 +435,49 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -438,121 +435,49 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
438 | clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider())); | 435 | clientContext.getLwM2mClients().forEach(e -> e.deleteResources(pathIdVer, this.config.getModelProvider())); |
439 | } | 436 | } |
440 | 437 | ||
438 | + /** | ||
439 | + * #1 del from rpcSubscriptions by timeout | ||
440 | + * #2 if not present in rpcSubscriptions by requestId: create new Lwm2mClientRpcRequest, after success - add requestId, timeout | ||
441 | + */ | ||
441 | @Override | 442 | @Override |
442 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { | 443 | public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { |
443 | - log.warn("4) RPC-OK finish to [{}]", toDeviceRpcRequestMsg); | ||
444 | - Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; | ||
445 | - try { | ||
446 | - Registration registration = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration(); | ||
447 | - lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRpcRequestMsg, sessionInfo, registration); | ||
448 | - if (lwm2mClientRpcRequest.getErrorMsg() != null) { | ||
449 | - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | ||
450 | - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | ||
451 | - } else { | ||
452 | - lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), lwm2mClientRpcRequest.getContentFormatName(), | ||
453 | - lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), | ||
454 | - this.config.getTimeout(), lwm2mClientRpcRequest); | ||
455 | - } | ||
456 | - } catch (Exception e) { | ||
457 | - if (lwm2mClientRpcRequest == null) { | ||
458 | - lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); | ||
459 | - } | ||
460 | - lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | ||
461 | - if (lwm2mClientRpcRequest.getErrorMsg() == null) { | ||
462 | - lwm2mClientRpcRequest.setErrorMsg(e.getMessage()); | ||
463 | - } | ||
464 | - this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | ||
465 | - } | ||
466 | - } | ||
467 | - | ||
468 | - private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, | ||
469 | - SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException { | ||
470 | - Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); | ||
471 | - try { | ||
472 | - lwm2mClientRpcRequest.setRequestId(toDeviceRequest.getRequestId()); | ||
473 | - lwm2mClientRpcRequest.setSessionInfo(sessionInfo); | ||
474 | - lwm2mClientRpcRequest.setValidTypeOper(toDeviceRequest.getMethodName()); | ||
475 | - JsonObject rpcRequest = LwM2mTransportUtil.validateJson(toDeviceRequest.getParams()); | ||
476 | - if (rpcRequest != null) { | ||
477 | - if (rpcRequest.has(lwm2mClientRpcRequest.keyNameKey)) { | ||
478 | - String targetIdVer = this.getPresentPathIntoProfile(sessionInfo, | ||
479 | - rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString()); | ||
480 | - if (targetIdVer != null) { | ||
481 | - lwm2mClientRpcRequest.setTargetIdVer(targetIdVer); | ||
482 | - lwm2mClientRpcRequest.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s", | ||
483 | - rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString(), targetIdVer)); | ||
484 | - } | ||
485 | - } | ||
486 | - if (lwm2mClientRpcRequest.getTargetIdVer() == null) { | ||
487 | - lwm2mClientRpcRequest.setValidTargetIdVerKey(rpcRequest, registration); | ||
488 | - } | ||
489 | - if (rpcRequest.has(lwm2mClientRpcRequest.contentFormatNameKey)) { | ||
490 | - lwm2mClientRpcRequest.setValidContentFormatName(rpcRequest); | ||
491 | - } | ||
492 | - if (rpcRequest.has(lwm2mClientRpcRequest.timeoutInMsKey) && rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong() > 0) { | ||
493 | - lwm2mClientRpcRequest.setTimeoutInMs(rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong()); | ||
494 | - } | ||
495 | - if (rpcRequest.has(lwm2mClientRpcRequest.valueKey)) { | ||
496 | - lwm2mClientRpcRequest.setValue(rpcRequest.get(lwm2mClientRpcRequest.valueKey).getAsString()); | ||
497 | - } | ||
498 | - if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) { | ||
499 | - ConcurrentHashMap<String, Object> params = new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey) | ||
500 | - .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() { | ||
501 | - }.getType()); | ||
502 | - if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()) { | ||
503 | - ConcurrentHashMap<String, Object> paramsResourceId = convertParamsToResourceId(params, sessionInfo); | ||
504 | - if (paramsResourceId.size() > 0) { | ||
505 | - lwm2mClientRpcRequest.setParams(paramsResourceId); | ||
506 | - } | ||
507 | - } else { | ||
508 | - lwm2mClientRpcRequest.setParams(params); | ||
509 | - } | ||
510 | - } else if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonArray()) { | ||
511 | - new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey) | ||
512 | - .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() { | ||
513 | - }.getType()); | 444 | + // #1 |
445 | + this.checkRpcRequestTimeout(); | ||
446 | + String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; | ||
447 | + LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); | ||
448 | + UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); | ||
449 | + log.warn("4) RPC-OK finish to [{}], keys: [{}]", requestUUID, this.rpcSubscriptions.keySet()); | ||
450 | + if (!this.rpcSubscriptions.containsKey(requestUUID)) { | ||
451 | + this.rpcSubscriptions.put(requestUUID, toDeviceRpcRequestMsg.getExpirationTime()); | ||
452 | + Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; | ||
453 | + try { | ||
454 | + Registration registration = clientContext.getClient(sessionInfo).getRegistration(); | ||
455 | + lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(lwM2mTypeOper, bodyParams, toDeviceRpcRequestMsg.getRequestId(), sessionInfo, registration, this); | ||
456 | + if (lwm2mClientRpcRequest.getErrorMsg() != null) { | ||
457 | + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | ||
458 | + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | ||
459 | + } else { | ||
460 | + lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), | ||
461 | + null, | ||
462 | + lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), | ||
463 | + this.config.getTimeout(), lwm2mClientRpcRequest); | ||
514 | } | 464 | } |
515 | - lwm2mClientRpcRequest.setSessionInfo(sessionInfo); | ||
516 | - if (!(OBSERVE_READ_ALL == lwm2mClientRpcRequest.getTypeOper() | ||
517 | - || DISCOVER_All == lwm2mClientRpcRequest.getTypeOper() | ||
518 | - || OBSERVE_CANCEL == lwm2mClientRpcRequest.getTypeOper()) | ||
519 | - && lwm2mClientRpcRequest.getTargetIdVer() == null) { | ||
520 | - lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " + | ||
521 | - lwm2mClientRpcRequest.keyNameKey + " is null or bad format"); | 465 | + } catch (Exception e) { |
466 | + if (lwm2mClientRpcRequest == null) { | ||
467 | + lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); | ||
522 | } | 468 | } |
523 | - /** | ||
524 | - * EXECUTE && WRITE_REPLACE - only for Resource or ResourceInstance | ||
525 | - */ | ||
526 | - else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper() | ||
527 | - || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper()) | ||
528 | - && lwm2mClientRpcRequest.getTargetIdVer() != null | ||
529 | - && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource() | ||
530 | - || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) { | ||
531 | - lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey | ||
532 | - + ". Only Resource or ResourceInstance can be this operation"); | 469 | + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); |
470 | + if (lwm2mClientRpcRequest.getErrorMsg() == null) { | ||
471 | + lwm2mClientRpcRequest.setErrorMsg(e.getMessage()); | ||
533 | } | 472 | } |
534 | - } else { | ||
535 | - lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format."); | 473 | + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); |
536 | } | 474 | } |
537 | - } catch (Exception e) { | ||
538 | - throw new IllegalArgumentException(lwm2mClientRpcRequest.getErrorMsg()); | ||
539 | } | 475 | } |
540 | - return lwm2mClientRpcRequest; | ||
541 | } | 476 | } |
542 | 477 | ||
543 | - private ConcurrentHashMap<String, Object> convertParamsToResourceId(ConcurrentHashMap<String, Object> params, | ||
544 | - SessionInfoProto sessionInfo) { | ||
545 | - ConcurrentHashMap<String, Object> paramsIdVer = new ConcurrentHashMap<>(); | ||
546 | - params.forEach((k, v) -> { | ||
547 | - String targetIdVer = this.getPresentPathIntoProfile(sessionInfo, k); | ||
548 | - if (targetIdVer != null) { | ||
549 | - LwM2mPath targetId = new LwM2mPath(convertPathFromIdVerToObjectId(targetIdVer)); | ||
550 | - if (targetId.isResource()) { | ||
551 | - paramsIdVer.put(String.valueOf(targetId.getResourceId()), v); | ||
552 | - } | ||
553 | - } | ||
554 | - }); | ||
555 | - return paramsIdVer; | 478 | + private void checkRpcRequestTimeout() { |
479 | + Set<UUID> rpcSubscriptionsToRemove = rpcSubscriptions.entrySet().stream().filter(kv -> System.currentTimeMillis() > kv.getValue()).map(Map.Entry::getKey).collect(Collectors.toSet()); | ||
480 | + rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); | ||
556 | } | 481 | } |
557 | 482 | ||
558 | public void sentRpcRequest(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { | 483 | public void sentRpcRequest(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { |
@@ -722,10 +647,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -722,10 +647,10 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
722 | * set setClient_fw_info... = value | 647 | * set setClient_fw_info... = value |
723 | **/ | 648 | **/ |
724 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { | 649 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { |
725 | - lwM2MClient.getFwUpdate().initReadValue(this, lwM2mTransportRequest, path); | 650 | + lwM2MClient.getFwUpdate().initReadValue(this, this.lwM2mTransportRequest, path); |
726 | } | 651 | } |
727 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { | 652 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { |
728 | - lwM2MClient.getSwUpdate().initReadValue(this, lwM2mTransportRequest, path); | 653 | + lwM2MClient.getSwUpdate().initReadValue(this, this.lwM2mTransportRequest, path); |
729 | } | 654 | } |
730 | 655 | ||
731 | /** | 656 | /** |
@@ -742,7 +667,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -742,7 +667,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
742 | && (convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { | 667 | && (convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) { |
743 | if (DOWNLOADED.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) | 668 | if (DOWNLOADED.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) |
744 | && lwM2MClient.getFwUpdate().conditionalFwExecuteStart()) { | 669 | && lwM2MClient.getFwUpdate().conditionalFwExecuteStart()) { |
745 | - lwM2MClient.getFwUpdate().executeFwSwWare(this, lwM2mTransportRequest); | 670 | + lwM2MClient.getFwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest); |
746 | } else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) | 671 | } else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate()) |
747 | && lwM2MClient.getFwUpdate().conditionalFwExecuteAfterSuccess()) { | 672 | && lwM2MClient.getFwUpdate().conditionalFwExecuteAfterSuccess()) { |
748 | lwM2MClient.getFwUpdate().finishFwSwUpdate(this, true); | 673 | lwM2MClient.getFwUpdate().finishFwSwUpdate(this, true); |
@@ -767,7 +692,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -767,7 +692,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
767 | && (convertPathFromObjectIdToIdVer(SW_RESULT_ID, registration).equals(path))) { | 692 | && (convertPathFromObjectIdToIdVer(SW_RESULT_ID, registration).equals(path))) { |
768 | if (DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) | 693 | if (DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) |
769 | && lwM2MClient.getSwUpdate().conditionalSwUpdateExecute()) { | 694 | && lwM2MClient.getSwUpdate().conditionalSwUpdateExecute()) { |
770 | - lwM2MClient.getSwUpdate().executeFwSwWare(this, lwM2mTransportRequest); | 695 | + lwM2MClient.getSwUpdate().executeFwSwWare(this, this.lwM2mTransportRequest); |
771 | } else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) | 696 | } else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate()) |
772 | && lwM2MClient.getSwUpdate().conditionalSwExecuteAfterSuccess()) { | 697 | && lwM2MClient.getSwUpdate().conditionalSwExecuteAfterSuccess()) { |
773 | lwM2MClient.getSwUpdate().finishFwSwUpdate(this, true); | 698 | lwM2MClient.getSwUpdate().finishFwSwUpdate(this, true); |
@@ -970,11 +895,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -970,11 +895,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
970 | * @return - return value of Resource by idPath | 895 | * @return - return value of Resource by idPath |
971 | */ | 896 | */ |
972 | private LwM2mResource getResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) { | 897 | private LwM2mResource getResourceValueFromLwM2MClient(LwM2mClient lwM2MClient, String path) { |
973 | - LwM2mResource resourceValue = null; | ||
974 | - if (new LwM2mPath(convertPathFromIdVerToObjectId(path)).isResource()) { | ||
975 | - resourceValue = lwM2MClient.getResources().get(path).getLwM2mResource(); | 898 | + LwM2mResource lwm2mResourceValue = null; |
899 | + ResourceValue resourceValue = lwM2MClient.getResources().get(path); | ||
900 | + if (resourceValue != null) { | ||
901 | + if (new LwM2mPath(convertPathFromIdVerToObjectId(path)).isResource()) { | ||
902 | + lwm2mResourceValue = lwM2MClient.getResources().get(path).getLwM2mResource(); | ||
903 | + } | ||
976 | } | 904 | } |
977 | - return resourceValue; | 905 | + return lwm2mResourceValue; |
978 | } | 906 | } |
979 | 907 | ||
980 | /** | 908 | /** |
@@ -1281,7 +1209,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1281,7 +1209,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1281 | * @param name - | 1209 | * @param name - |
1282 | * @return - | 1210 | * @return - |
1283 | */ | 1211 | */ |
1284 | - private String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { | 1212 | + public String getPresentPathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { |
1285 | LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); | 1213 | LwM2mClientProfile profile = clientContext.getProfile(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB())); |
1286 | LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo); | 1214 | LwM2mClient lwM2mClient = clientContext.getClient(sessionInfo); |
1287 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() | 1215 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
@@ -1304,7 +1232,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1304,7 +1232,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1304 | 1232 | ||
1305 | this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo); | 1233 | this.updateAttributeFromThingsboard(tsKvProtos, sessionInfo); |
1306 | } catch (Exception e) { | 1234 | } catch (Exception e) { |
1307 | - log.error(String.valueOf(e)); | 1235 | + log.error("", e); |
1308 | } | 1236 | } |
1309 | } | 1237 | } |
1310 | 1238 | ||
@@ -1378,6 +1306,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1378,6 +1306,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1378 | private void reportActivityAndRegister(SessionInfoProto sessionInfo) { | 1306 | private void reportActivityAndRegister(SessionInfoProto sessionInfo) { |
1379 | if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) { | 1307 | if (sessionInfo != null && transportService.reportActivity(sessionInfo) == null) { |
1380 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); | 1308 | transportService.registerAsyncSession(sessionInfo, new LwM2mSessionMsgListener(this, sessionInfo)); |
1309 | + this.reportActivitySubscription(sessionInfo); | ||
1381 | } | 1310 | } |
1382 | } | 1311 | } |
1383 | 1312 | ||
@@ -1510,4 +1439,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | @@ -1510,4 +1439,11 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler | ||
1510 | return this.config; | 1439 | return this.config; |
1511 | } | 1440 | } |
1512 | 1441 | ||
1442 | + private void reportActivitySubscription(TransportProtos.SessionInfoProto sessionInfo) { | ||
1443 | + transportService.process(sessionInfo, TransportProtos.SubscriptionInfoProto.newBuilder() | ||
1444 | + .setAttributeSubscription(true) | ||
1445 | + .setRpcSubscription(true) | ||
1446 | + .setLastActivityTime(System.currentTimeMillis()) | ||
1447 | + .build(), TransportServiceCallback.EMPTY); | ||
1448 | + } | ||
1513 | } | 1449 | } |
@@ -94,12 +94,6 @@ public class LwM2mServerListener { | @@ -94,12 +94,6 @@ public class LwM2mServerListener { | ||
94 | @Override | 94 | @Override |
95 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { | 95 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
96 | if (registration != null) { | 96 | if (registration != null) { |
97 | -// if (observation.getPath().isResource() || observation.getPath().isResourceInstance()) { | ||
98 | -// String msg = String.format("%s: Successful Observation %s.", LOG_LW2M_INFO, | ||
99 | -// observation.getPath()); | ||
100 | -// log.warn(msg); | ||
101 | -// service.sendLogsToThingsboard(msg, registration.getId()); | ||
102 | -// } | ||
103 | service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), | 97 | service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), |
104 | registration), response, null); | 98 | registration), response, null); |
105 | } | 99 | } |
@@ -22,6 +22,8 @@ import org.eclipse.californium.core.coap.Response; | @@ -22,6 +22,8 @@ import org.eclipse.californium.core.coap.Response; | ||
22 | import org.eclipse.leshan.core.Link; | 22 | import org.eclipse.leshan.core.Link; |
23 | import org.eclipse.leshan.core.model.ResourceModel; | 23 | import org.eclipse.leshan.core.model.ResourceModel; |
24 | import org.eclipse.leshan.core.node.LwM2mNode; | 24 | import org.eclipse.leshan.core.node.LwM2mNode; |
25 | +import org.eclipse.leshan.core.node.LwM2mObject; | ||
26 | +import org.eclipse.leshan.core.node.LwM2mObjectInstance; | ||
25 | import org.eclipse.leshan.core.node.LwM2mPath; | 27 | import org.eclipse.leshan.core.node.LwM2mPath; |
26 | import org.eclipse.leshan.core.node.LwM2mResource; | 28 | import org.eclipse.leshan.core.node.LwM2mResource; |
27 | import org.eclipse.leshan.core.node.LwM2mSingleResource; | 29 | import org.eclipse.leshan.core.node.LwM2mSingleResource; |
@@ -34,6 +36,7 @@ import org.eclipse.leshan.core.request.DownlinkRequest; | @@ -34,6 +36,7 @@ import org.eclipse.leshan.core.request.DownlinkRequest; | ||
34 | import org.eclipse.leshan.core.request.ExecuteRequest; | 36 | import org.eclipse.leshan.core.request.ExecuteRequest; |
35 | import org.eclipse.leshan.core.request.ObserveRequest; | 37 | import org.eclipse.leshan.core.request.ObserveRequest; |
36 | import org.eclipse.leshan.core.request.ReadRequest; | 38 | import org.eclipse.leshan.core.request.ReadRequest; |
39 | +import org.eclipse.leshan.core.request.WriteAttributesRequest; | ||
37 | import org.eclipse.leshan.core.request.WriteRequest; | 40 | import org.eclipse.leshan.core.request.WriteRequest; |
38 | import org.eclipse.leshan.core.request.exception.ClientSleepingException; | 41 | import org.eclipse.leshan.core.request.exception.ClientSleepingException; |
39 | import org.eclipse.leshan.core.response.DeleteResponse; | 42 | import org.eclipse.leshan.core.response.DeleteResponse; |
@@ -79,10 +82,12 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | @@ -79,10 +82,12 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L | ||
79 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; | 82 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; |
80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; | 83 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; |
81 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; | 84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; |
82 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_All; | 85 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL; |
83 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; | 86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; |
84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; | 87 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; |
88 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL; | ||
85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; | 89 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; |
90 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; | ||
86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; | 91 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; |
87 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; | 92 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; |
88 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_REQUEST_CHANNEL; | 93 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_REQUEST_CHANNEL; |
@@ -123,7 +128,7 @@ public class LwM2mTransportRequest { | @@ -123,7 +128,7 @@ public class LwM2mTransportRequest { | ||
123 | */ | 128 | */ |
124 | 129 | ||
125 | public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, | 130 | public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, |
126 | - String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { | 131 | + String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest lwm2mClientRpcRequest) { |
127 | try { | 132 | try { |
128 | String target = convertPathFromIdVerToObjectId(targetIdVer); | 133 | String target = convertPathFromIdVerToObjectId(targetIdVer); |
129 | ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; | 134 | ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; |
@@ -132,45 +137,42 @@ public class LwM2mTransportRequest { | @@ -132,45 +137,42 @@ public class LwM2mTransportRequest { | ||
132 | if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { | 137 | if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { |
133 | if (lwM2MClient.isValidObjectVersion(targetIdVer)) { | 138 | if (lwM2MClient.isValidObjectVersion(targetIdVer)) { |
134 | timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; | 139 | timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; |
135 | - DownlinkRequest request = createRequest (registration, lwM2MClient, typeOper, contentFormat, target, | ||
136 | - targetIdVer, resultIds, params, rpcRequest); | 140 | + DownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target, |
141 | + targetIdVer, resultIds, params, lwm2mClientRpcRequest); | ||
137 | if (request != null) { | 142 | if (request != null) { |
138 | try { | 143 | try { |
139 | - this.sendRequest(registration, lwM2MClient, request, timeoutInMs, rpcRequest); | 144 | + this.sendRequest(registration, lwM2MClient, request, timeoutInMs, lwm2mClientRpcRequest); |
140 | } catch (ClientSleepingException e) { | 145 | } catch (ClientSleepingException e) { |
141 | DownlinkRequest finalRequest = request; | 146 | DownlinkRequest finalRequest = request; |
142 | long finalTimeoutInMs = timeoutInMs; | 147 | long finalTimeoutInMs = timeoutInMs; |
143 | - Lwm2mClientRpcRequest finalRpcRequest = rpcRequest; | 148 | + Lwm2mClientRpcRequest finalRpcRequest = lwm2mClientRpcRequest; |
144 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest)); | 149 | lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, finalRpcRequest)); |
145 | } catch (Exception e) { | 150 | } catch (Exception e) { |
146 | log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); | 151 | log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e); |
147 | } | 152 | } |
148 | - } | ||
149 | - else if (WRITE_UPDATE.name().equals(typeOper.name())) { | ||
150 | - if (rpcRequest != null) { | 153 | + } else if (WRITE_UPDATE.name().equals(typeOper.name())) { |
154 | + if (lwm2mClientRpcRequest != null) { | ||
151 | String errorMsg = String.format("Path %s params is not valid", targetIdVer); | 155 | String errorMsg = String.format("Path %s params is not valid", targetIdVer); |
152 | - handler.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); | 156 | + handler.sentRpcRequest(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); |
153 | } | 157 | } |
154 | - } | ||
155 | - else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name()) ) { | ||
156 | - if (rpcRequest != null) { | 158 | + } else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) { |
159 | + if (lwm2mClientRpcRequest != null) { | ||
157 | String errorMsg = String.format("Path %s object model is absent", targetIdVer); | 160 | String errorMsg = String.format("Path %s object model is absent", targetIdVer); |
158 | - handler.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); | 161 | + handler.sentRpcRequest(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); |
159 | } | 162 | } |
160 | - } | ||
161 | - else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) { | 163 | + } else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) { |
162 | log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); | 164 | log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); |
163 | - if (rpcRequest != null) { | 165 | + if (lwm2mClientRpcRequest != null) { |
164 | ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()); | 166 | ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()); |
165 | String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; | 167 | String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; |
166 | - handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | 168 | + this.handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); |
167 | } | 169 | } |
168 | } | 170 | } |
169 | - } else if (rpcRequest != null) { | 171 | + } else if (lwm2mClientRpcRequest != null) { |
170 | String errorMsg = String.format("Path %s not found in object version", targetIdVer); | 172 | String errorMsg = String.format("Path %s not found in object version", targetIdVer); |
171 | - handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | 173 | + this.handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); |
172 | } | 174 | } |
173 | - } else if (OBSERVE_READ_ALL.name().equals(typeOper.name()) || DISCOVER_All.name().equals(typeOper.name())) { | 175 | + } else if (OBSERVE_READ_ALL.name().equals(typeOper.name()) || DISCOVER_ALL.name().equals(typeOper.name())) { |
174 | Set<String> paths; | 176 | Set<String> paths; |
175 | if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { | 177 | if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { |
176 | Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); | 178 | Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); |
@@ -179,34 +181,34 @@ public class LwM2mTransportRequest { | @@ -179,34 +181,34 @@ public class LwM2mTransportRequest { | ||
179 | assert registration != null; | 181 | assert registration != null; |
180 | Link[] objectLinks = registration.getSortedObjectLinks(); | 182 | Link[] objectLinks = registration.getSortedObjectLinks(); |
181 | paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); | 183 | paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); |
182 | - String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, | ||
183 | - typeOper.name(), paths); | ||
184 | - handler.sendLogsToThingsboard(msg, registration.getId()); | ||
185 | } | 184 | } |
186 | - if (rpcRequest != null) { | 185 | + String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, |
186 | + typeOper.name(), paths); | ||
187 | + this.handler.sendLogsToThingsboard(msg, registration.getId()); | ||
188 | + if (lwm2mClientRpcRequest != null) { | ||
187 | String valueMsg = String.format("Paths - %s", paths); | 189 | String valueMsg = String.format("Paths - %s", paths); |
188 | - handler.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); | 190 | + this.handler.sentRpcRequest(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); |
189 | } | 191 | } |
190 | - } else if (OBSERVE_CANCEL.name().equals(typeOper.name())) { | 192 | + } else if (OBSERVE_CANCEL_ALL.name().equals(typeOper.name())) { |
191 | int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration); | 193 | int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration); |
192 | String observeCancelMsgAll = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, | 194 | String observeCancelMsgAll = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO, |
193 | OBSERVE_CANCEL.name(), observeCancelCnt); | 195 | OBSERVE_CANCEL.name(), observeCancelCnt); |
194 | - this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsgAll, rpcRequest); | 196 | + this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsgAll, lwm2mClientRpcRequest); |
195 | } | 197 | } |
196 | } catch (Exception e) { | 198 | } catch (Exception e) { |
197 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, | 199 | String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, |
198 | typeOper.name(), e.getMessage()); | 200 | typeOper.name(), e.getMessage()); |
199 | handler.sendLogsToThingsboard(msg, registration.getId()); | 201 | handler.sendLogsToThingsboard(msg, registration.getId()); |
200 | - if (rpcRequest != null) { | 202 | + if (lwm2mClientRpcRequest != null) { |
201 | String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); | 203 | String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); |
202 | - handler.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | 204 | + handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); |
203 | } | 205 | } |
204 | } | 206 | } |
205 | } | 207 | } |
206 | 208 | ||
207 | - private DownlinkRequest createRequest (Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, | ||
208 | - ContentFormat contentFormat, String target, String targetIdVer, | ||
209 | - LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) { | 209 | + private DownlinkRequest createRequest(Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper, |
210 | + ContentFormat contentFormat, String target, String targetIdVer, | ||
211 | + LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) { | ||
210 | DownlinkRequest request = null; | 212 | DownlinkRequest request = null; |
211 | switch (typeOper) { | 213 | switch (typeOper) { |
212 | case READ: | 214 | case READ: |
@@ -216,7 +218,7 @@ public class LwM2mTransportRequest { | @@ -216,7 +218,7 @@ public class LwM2mTransportRequest { | ||
216 | request = new DiscoverRequest(target); | 218 | request = new DiscoverRequest(target); |
217 | break; | 219 | break; |
218 | case OBSERVE: | 220 | case OBSERVE: |
219 | - String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer); | 221 | + String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer); |
220 | log.warn(msg); | 222 | log.warn(msg); |
221 | if (resultIds.isResource()) { | 223 | if (resultIds.isResource()) { |
222 | Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); | 224 | Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); |
@@ -305,7 +307,7 @@ public class LwM2mTransportRequest { | @@ -305,7 +307,7 @@ public class LwM2mTransportRequest { | ||
305 | } | 307 | } |
306 | break; | 308 | break; |
307 | case WRITE_ATTRIBUTES: | 309 | case WRITE_ATTRIBUTES: |
308 | - request = createWriteAttributeRequest(target, params); | 310 | + request = createWriteAttributeRequest(target, params, this.handler); |
309 | break; | 311 | break; |
310 | case DELETE: | 312 | case DELETE: |
311 | request = new DeleteRequest(target); | 313 | request = new DeleteRequest(target); |
@@ -347,10 +349,10 @@ public class LwM2mTransportRequest { | @@ -347,10 +349,10 @@ public class LwM2mTransportRequest { | ||
347 | set setClient_fw_info... = empty | 349 | set setClient_fw_info... = empty |
348 | **/ | 350 | **/ |
349 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { | 351 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { |
350 | - lwM2MClient.getFwUpdate().initReadValue(handler, request.getPath().toString()); | 352 | + lwM2MClient.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); |
351 | } | 353 | } |
352 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { | 354 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { |
353 | - lwM2MClient.getSwUpdate().initReadValue(handler, request.getPath().toString()); | 355 | + lwM2MClient.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); |
354 | } | 356 | } |
355 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { | 357 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { |
356 | this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage()); | 358 | this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage()); |
@@ -364,10 +366,10 @@ public class LwM2mTransportRequest { | @@ -364,10 +366,10 @@ public class LwM2mTransportRequest { | ||
364 | set setClient_fw_info... = empty | 366 | set setClient_fw_info... = empty |
365 | **/ | 367 | **/ |
366 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { | 368 | if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) { |
367 | - lwM2MClient.getFwUpdate().initReadValue(handler, request.getPath().toString()); | 369 | + lwM2MClient.getFwUpdate().initReadValue(handler, this, request.getPath().toString()); |
368 | } | 370 | } |
369 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { | 371 | if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) { |
370 | - lwM2MClient.getSwUpdate().initReadValue(handler, request.getPath().toString()); | 372 | + lwM2MClient.getSwUpdate().initReadValue(handler, this, request.getPath().toString()); |
371 | } | 373 | } |
372 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { | 374 | if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { |
373 | this.afterWriteFwSWUpdateError(registration, request, e.getMessage()); | 375 | this.afterWriteFwSWUpdateError(registration, request, e.getMessage()); |
@@ -473,7 +475,13 @@ public class LwM2mTransportRequest { | @@ -473,7 +475,13 @@ public class LwM2mTransportRequest { | ||
473 | } else if (response instanceof ExecuteResponse) { | 475 | } else if (response instanceof ExecuteResponse) { |
474 | log.warn("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); | 476 | log.warn("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); |
475 | } else if (response instanceof WriteAttributesResponse) { | 477 | } else if (response instanceof WriteAttributesResponse) { |
478 | + msgLog = String.format("%s: type operation: %s path: %s value: %s", | ||
479 | + LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); | ||
480 | + handler.sendLogsToThingsboard(msgLog, registration.getId()); | ||
476 | log.warn("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); | 481 | log.warn("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); |
482 | + if (rpcRequest != null) { | ||
483 | + handler.sentRpcRequest(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); | ||
484 | + } | ||
477 | } else if (response instanceof WriteResponse) { | 485 | } else if (response instanceof WriteResponse) { |
478 | log.warn("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response); | 486 | log.warn("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response); |
479 | this.infoWriteResponse(registration, response, request); | 487 | this.infoWriteResponse(registration, response, request); |
@@ -494,29 +502,37 @@ public class LwM2mTransportRequest { | @@ -494,29 +502,37 @@ public class LwM2mTransportRequest { | ||
494 | private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request) { | 502 | private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request) { |
495 | try { | 503 | try { |
496 | LwM2mNode node = ((WriteRequest) request).getNode(); | 504 | LwM2mNode node = ((WriteRequest) request).getNode(); |
497 | - String msg; | 505 | + String msg = null; |
498 | Object value; | 506 | Object value; |
499 | - LwM2mSingleResource singleResource = (LwM2mSingleResource) node; | ||
500 | - if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) { | ||
501 | - int valueLength; | ||
502 | - if (singleResource.getType() == ResourceModel.Type.STRING) { | ||
503 | - valueLength = ((String) singleResource.getValue()).length(); | ||
504 | - value = ((String) singleResource.getValue()) | ||
505 | - .substring(Math.min(valueLength, config.getLogMaxLength())); | 507 | + if (node instanceof LwM2mObject) { |
508 | + msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", | ||
509 | + LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObject) node).toString()); | ||
510 | + } else if (node instanceof LwM2mObjectInstance) { | ||
511 | + msg = String.format("%s: Update finished successfully: Lwm2m code - %d Source path: %s value: %s", | ||
512 | + LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), ((LwM2mObjectInstance) node).prettyPrint()); | ||
513 | + } else if (node instanceof LwM2mSingleResource) { | ||
514 | + LwM2mSingleResource singleResource = (LwM2mSingleResource) node; | ||
515 | + if (singleResource.getType() == ResourceModel.Type.STRING || singleResource.getType() == ResourceModel.Type.OPAQUE) { | ||
516 | + int valueLength; | ||
517 | + if (singleResource.getType() == ResourceModel.Type.STRING) { | ||
518 | + valueLength = ((String) singleResource.getValue()).length(); | ||
519 | + value = ((String) singleResource.getValue()) | ||
520 | + .substring(Math.min(valueLength, config.getLogMaxLength())); | ||
506 | 521 | ||
522 | + } else { | ||
523 | + valueLength = ((byte[]) singleResource.getValue()).length; | ||
524 | + value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()), | ||
525 | + Math.min(valueLength, config.getLogMaxLength()))); | ||
526 | + } | ||
527 | + value = valueLength > config.getLogMaxLength() ? value + "..." : value; | ||
528 | + msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s", | ||
529 | + LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value); | ||
507 | } else { | 530 | } else { |
508 | - valueLength = ((byte[]) singleResource.getValue()).length; | ||
509 | - value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()), | ||
510 | - Math.min(valueLength, config.getLogMaxLength()))); | 531 | + value = this.converter.convertValue(singleResource.getValue(), |
532 | + singleResource.getType(), ResourceModel.Type.STRING, request.getPath()); | ||
533 | + msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s", | ||
534 | + LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value); | ||
511 | } | 535 | } |
512 | - value = valueLength > config.getLogMaxLength() ? value + "..." : value; | ||
513 | - msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s", | ||
514 | - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), valueLength, value); | ||
515 | - } else { | ||
516 | - value = this.converter.convertValue(singleResource.getValue(), | ||
517 | - singleResource.getType(), ResourceModel.Type.STRING, request.getPath()); | ||
518 | - msg = String.format("%s: Update finished successfully. Lwm2m code: %d Resource path: %s value: %s", | ||
519 | - LOG_LW2M_INFO, response.getCode().getCode(), request.getPath().toString(), value); | ||
520 | } | 536 | } |
521 | if (msg != null) { | 537 | if (msg != null) { |
522 | handler.sendLogsToThingsboard(msg, registration.getId()); | 538 | handler.sendLogsToThingsboard(msg, registration.getId()); |
@@ -538,11 +554,11 @@ public class LwM2mTransportRequest { | @@ -538,11 +554,11 @@ public class LwM2mTransportRequest { | ||
538 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 554 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
539 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { | 555 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { |
540 | lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name()); | 556 | lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name()); |
541 | - lwM2MClient.getFwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_INFO, null); | 557 | + lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); |
542 | } | 558 | } |
543 | if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) { | 559 | if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) { |
544 | lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name()); | 560 | lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name()); |
545 | - lwM2MClient.getSwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_INFO, null); | 561 | + lwM2MClient.getSwUpdate().sendLogs(this.handler,WRITE_REPLACE.name(), LOG_LW2M_INFO, null); |
546 | } | 562 | } |
547 | } | 563 | } |
548 | 564 | ||
@@ -553,21 +569,21 @@ public class LwM2mTransportRequest { | @@ -553,21 +569,21 @@ public class LwM2mTransportRequest { | ||
553 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 569 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
554 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { | 570 | if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) { |
555 | lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name()); | 571 | lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name()); |
556 | - lwM2MClient.getFwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); | 572 | + lwM2MClient.getFwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); |
557 | } | 573 | } |
558 | if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) { | 574 | if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) { |
559 | lwM2MClient.getSwUpdate().setStateUpdate(FAILED.name()); | 575 | lwM2MClient.getSwUpdate().setStateUpdate(FAILED.name()); |
560 | - lwM2MClient.getSwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); | 576 | + lwM2MClient.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError); |
561 | } | 577 | } |
562 | } | 578 | } |
563 | 579 | ||
564 | private void afterExecuteFwSwUpdateError(Registration registration, DownlinkRequest request, String msgError) { | 580 | private void afterExecuteFwSwUpdateError(Registration registration, DownlinkRequest request, String msgError) { |
565 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); | 581 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId()); |
566 | if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) { | 582 | if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) { |
567 | - lwM2MClient.getFwUpdate().sendLogs(EXECUTE.name(), LOG_LW2M_ERROR, msgError); | 583 | + lwM2MClient.getFwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); |
568 | } | 584 | } |
569 | if (request.getPath().toString().equals(SW_INSTALL_ID) && lwM2MClient.getSwUpdate() != null) { | 585 | if (request.getPath().toString().equals(SW_INSTALL_ID) && lwM2MClient.getSwUpdate() != null) { |
570 | - lwM2MClient.getSwUpdate().sendLogs(EXECUTE.name(), LOG_LW2M_ERROR, msgError); | 586 | + lwM2MClient.getSwUpdate().sendLogs(this.handler, EXECUTE.name(), LOG_LW2M_ERROR, msgError); |
571 | } | 587 | } |
572 | } | 588 | } |
573 | 589 |
@@ -61,9 +61,12 @@ import java.util.Set; | @@ -61,9 +61,12 @@ import java.util.Set; | ||
61 | import java.util.concurrent.ConcurrentHashMap; | 61 | import java.util.concurrent.ConcurrentHashMap; |
62 | 62 | ||
63 | import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; | 63 | import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; |
64 | +import static org.eclipse.leshan.core.attributes.Attribute.GREATER_THAN; | ||
65 | +import static org.eclipse.leshan.core.attributes.Attribute.LESSER_THAN; | ||
64 | import static org.eclipse.leshan.core.attributes.Attribute.MAXIMUM_PERIOD; | 66 | import static org.eclipse.leshan.core.attributes.Attribute.MAXIMUM_PERIOD; |
65 | import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD; | 67 | import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD; |
66 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; | 68 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
69 | +import static org.eclipse.leshan.core.attributes.Attribute.STEP; | ||
67 | import static org.eclipse.leshan.core.model.ResourceModel.Type.BOOLEAN; | 70 | import static org.eclipse.leshan.core.model.ResourceModel.Type.BOOLEAN; |
68 | import static org.eclipse.leshan.core.model.ResourceModel.Type.FLOAT; | 71 | import static org.eclipse.leshan.core.model.ResourceModel.Type.FLOAT; |
69 | import static org.eclipse.leshan.core.model.ResourceModel.Type.INTEGER; | 72 | import static org.eclipse.leshan.core.model.ResourceModel.Type.INTEGER; |
@@ -104,8 +107,7 @@ public class LwM2mTransportUtil { | @@ -104,8 +107,7 @@ public class LwM2mTransportUtil { | ||
104 | 107 | ||
105 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms | 108 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms |
106 | 109 | ||
107 | - public static final String | ||
108 | - LOG_LW2M_TELEMETRY = "LwM2MLog"; | 110 | + public static final String LOG_LW2M_TELEMETRY = "logLwm2m"; |
109 | public static final String LOG_LW2M_INFO = "info"; | 111 | public static final String LOG_LW2M_INFO = "info"; |
110 | public static final String LOG_LW2M_ERROR = "error"; | 112 | public static final String LOG_LW2M_ERROR = "error"; |
111 | public static final String LOG_LW2M_WARN = "warn"; | 113 | public static final String LOG_LW2M_WARN = "warn"; |
@@ -117,6 +119,23 @@ public class LwM2mTransportUtil { | @@ -117,6 +119,23 @@ public class LwM2mTransportUtil { | ||
117 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; | 119 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; |
118 | public static final String LWM2M_VERSION_DEFAULT = "1.0"; | 120 | public static final String LWM2M_VERSION_DEFAULT = "1.0"; |
119 | 121 | ||
122 | + // RPC | ||
123 | + public static final String TYPE_OPER_KEY = "typeOper"; | ||
124 | + public static final String TARGET_ID_VER_KEY = "targetIdVer"; | ||
125 | + public static final String KEY_NAME_KEY = "key"; | ||
126 | + public static final String VALUE_KEY = "value"; | ||
127 | + public static final String PARAMS_KEY = "params"; | ||
128 | + public static final String SEPARATOR_KEY = ":"; | ||
129 | + public static final String FINISH_VALUE_KEY = ","; | ||
130 | + public static final String START_JSON_KEY = "{"; | ||
131 | + public static final String FINISH_JSON_KEY = "}"; | ||
132 | + // public static final String contentFormatNameKey = "contentFormatName"; | ||
133 | + public static final String INFO_KEY = "info"; | ||
134 | + // public static final String TIME_OUT_IN_MS = "timeOutInMs"; | ||
135 | + public static final String RESULT_KEY = "result"; | ||
136 | + public static final String ERROR_KEY = "error"; | ||
137 | + public static final String METHOD_KEY = "methodName"; | ||
138 | + | ||
120 | // FirmWare | 139 | // FirmWare |
121 | public static final String FW_UPDATE = "Firmware update"; | 140 | public static final String FW_UPDATE = "Firmware update"; |
122 | public static final Integer FW_ID = 5; | 141 | public static final Integer FW_ID = 5; |
@@ -182,20 +201,21 @@ public class LwM2mTransportUtil { | @@ -182,20 +201,21 @@ public class LwM2mTransportUtil { | ||
182 | */ | 201 | */ |
183 | READ(0, "Read"), | 202 | READ(0, "Read"), |
184 | DISCOVER(1, "Discover"), | 203 | DISCOVER(1, "Discover"), |
185 | - DISCOVER_All(2, "DiscoverAll"), | 204 | + DISCOVER_ALL(2, "DiscoverAll"), |
186 | OBSERVE_READ_ALL(3, "ObserveReadAll"), | 205 | OBSERVE_READ_ALL(3, "ObserveReadAll"), |
187 | /** | 206 | /** |
188 | * POST | 207 | * POST |
189 | */ | 208 | */ |
190 | OBSERVE(4, "Observe"), | 209 | OBSERVE(4, "Observe"), |
191 | OBSERVE_CANCEL(5, "ObserveCancel"), | 210 | OBSERVE_CANCEL(5, "ObserveCancel"), |
192 | - EXECUTE(6, "Execute"), | 211 | + OBSERVE_CANCEL_ALL(6, "ObserveCancelAll"), |
212 | + EXECUTE(7, "Execute"), | ||
193 | /** | 213 | /** |
194 | * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see | 214 | * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see |
195 | * section 5.3.3 of the LW M2M spec). | 215 | * section 5.3.3 of the LW M2M spec). |
196 | * if all resources are to be replaced | 216 | * if all resources are to be replaced |
197 | */ | 217 | */ |
198 | - WRITE_REPLACE(7, "WriteReplace"), | 218 | + WRITE_REPLACE(8, "WriteReplace"), |
199 | /* | 219 | /* |
200 | PUT | 220 | PUT |
201 | */ | 221 | */ |
@@ -204,18 +224,16 @@ public class LwM2mTransportUtil { | @@ -204,18 +224,16 @@ public class LwM2mTransportUtil { | ||
204 | * 5.3.3 of the LW M2M spec). | 224 | * 5.3.3 of the LW M2M spec). |
205 | * if this is a partial update request | 225 | * if this is a partial update request |
206 | */ | 226 | */ |
207 | - WRITE_UPDATE(8, "WriteUpdate"), | ||
208 | - WRITE_ATTRIBUTES(9, "WriteAttributes"), | ||
209 | - DELETE(10, "Delete"), | 227 | + WRITE_UPDATE(9, "WriteUpdate"), |
228 | + WRITE_ATTRIBUTES(10, "WriteAttributes"), | ||
229 | + DELETE(11, "Delete"); | ||
210 | 230 | ||
211 | // only for RPC | 231 | // only for RPC |
212 | - FW_READ_INFO(11, "FirmwareReadInfo"), | ||
213 | - FW_UPDATE(12, "FirmwareUpdate"), | ||
214 | - FW_UPDATE_URL(14, "FirmwareUpdateUrl"), | ||
215 | - SW_READ_INFO(15, "SoftwareReadInfo"), | ||
216 | - SW_UPDATE(16, "SoftwareUpdate"), | ||
217 | - SW_UPDATE_URL(17, "SoftwareUpdateUrl"), | ||
218 | - SW_UNINSTALL(18, "SoftwareUninstall"); | 232 | +// FW_READ_INFO(12, "FirmwareReadInfo"), |
233 | +// FW_UPDATE(13, "FirmwareUpdate"), | ||
234 | +// SW_READ_INFO(15, "SoftwareReadInfo"), | ||
235 | +// SW_UPDATE(16, "SoftwareUpdate"), | ||
236 | +// SW_UNINSTALL(18, "SoftwareUninstall"); | ||
219 | 237 | ||
220 | public int code; | 238 | public int code; |
221 | public String type; | 239 | public String type; |
@@ -817,26 +835,29 @@ public class LwM2mTransportUtil { | @@ -817,26 +835,29 @@ public class LwM2mTransportUtil { | ||
817 | * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); | 835 | * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); |
818 | * Attribute [] attrs = {gt, st}; | 836 | * Attribute [] attrs = {gt, st}; |
819 | */ | 837 | */ |
820 | - public static DownlinkRequest createWriteAttributeRequest(String target, Object params) { | ||
821 | - AttributeSet attrSet = new AttributeSet(createWriteAttributes(params)); | 838 | + public static DownlinkRequest createWriteAttributeRequest(String target, Object params, DefaultLwM2MTransportMsgHandler serviceImpl) { |
839 | + AttributeSet attrSet = new AttributeSet(createWriteAttributes(params, serviceImpl, target)); | ||
822 | return attrSet.getAttributes().size() > 0 ? new WriteAttributesRequest(target, attrSet) : null; | 840 | return attrSet.getAttributes().size() > 0 ? new WriteAttributesRequest(target, attrSet) : null; |
823 | } | 841 | } |
824 | 842 | ||
825 | - private static Attribute[] createWriteAttributes(Object params) { | 843 | + private static Attribute[] createWriteAttributes(Object params, DefaultLwM2MTransportMsgHandler serviceImpl, String target) { |
826 | List<Attribute> attributeLists = new ArrayList<>(); | 844 | List<Attribute> attributeLists = new ArrayList<>(); |
827 | ObjectMapper oMapper = new ObjectMapper(); | 845 | ObjectMapper oMapper = new ObjectMapper(); |
828 | Map<String, Object> map = oMapper.convertValue(params, ConcurrentHashMap.class); | 846 | Map<String, Object> map = oMapper.convertValue(params, ConcurrentHashMap.class); |
829 | map.forEach((k, v) -> { | 847 | map.forEach((k, v) -> { |
830 | - if (!v.toString().isEmpty() || (v.toString().isEmpty() && OBJECT_VERSION.equals(k))) { | ||
831 | - attributeLists.add(new Attribute(k, | ||
832 | - (DIMENSION.equals(k) || MINIMUM_PERIOD.equals(k) || MAXIMUM_PERIOD.equals(k)) ? | ||
833 | - ((Double) v).longValue() : v)); | 848 | + if (StringUtils.trimToNull(v.toString()) != null) { |
849 | + Object attrValue = convertWriteAttributes(k, v, serviceImpl, target); | ||
850 | + if (attrValue != null) { | ||
851 | + Attribute attribute = createAttribute(k, attrValue); | ||
852 | + if (attribute != null) { | ||
853 | + attributeLists.add(new Attribute(k, attrValue)); | ||
854 | + } | ||
855 | + } | ||
834 | } | 856 | } |
835 | }); | 857 | }); |
836 | return attributeLists.toArray(Attribute[]::new); | 858 | return attributeLists.toArray(Attribute[]::new); |
837 | } | 859 | } |
838 | 860 | ||
839 | - | ||
840 | public static Set<String> convertJsonArrayToSet(JsonArray jsonArray) { | 861 | public static Set<String> convertJsonArrayToSet(JsonArray jsonArray) { |
841 | List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() { | 862 | List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() { |
842 | }.getType()); | 863 | }.getType()); |
@@ -863,4 +884,47 @@ public class LwM2mTransportUtil { | @@ -863,4 +884,47 @@ public class LwM2mTransportUtil { | ||
863 | return null; | 884 | return null; |
864 | } | 885 | } |
865 | } | 886 | } |
887 | + | ||
888 | + public static LwM2mTypeOper setValidTypeOper(String typeOper) { | ||
889 | + try { | ||
890 | + return LwM2mTransportUtil.LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper); | ||
891 | + } catch (Exception e) { | ||
892 | + return null; | ||
893 | + } | ||
894 | + } | ||
895 | + | ||
896 | + public static Object convertWriteAttributes(String type, Object value, DefaultLwM2MTransportMsgHandler serviceImpl, String target) { | ||
897 | + switch (type) { | ||
898 | + /** Integer [0:255]; */ | ||
899 | + case DIMENSION: | ||
900 | + Long dim = (Long) serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), INTEGER, new LwM2mPath(target)); | ||
901 | + return dim >= 0 && dim <= 255 ? dim : null; | ||
902 | + /**String;*/ | ||
903 | + case OBJECT_VERSION: | ||
904 | + return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), STRING, new LwM2mPath(target)); | ||
905 | + /**INTEGER */ | ||
906 | + case MINIMUM_PERIOD: | ||
907 | + case MAXIMUM_PERIOD: | ||
908 | + return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), INTEGER, new LwM2mPath(target)); | ||
909 | + /**Float; */ | ||
910 | + case GREATER_THAN: | ||
911 | + case LESSER_THAN: | ||
912 | + case STEP: | ||
913 | + if (value.getClass().getSimpleName().equals("String") ) { | ||
914 | + value = Double.valueOf((String) value); | ||
915 | + } | ||
916 | + return serviceImpl.converter.convertValue(value, equalsResourceTypeGetSimpleName(value), FLOAT, new LwM2mPath(target)); | ||
917 | + default: | ||
918 | + return null; | ||
919 | + } | ||
920 | + } | ||
921 | + | ||
922 | + private static Attribute createAttribute(String key, Object attrValue) { | ||
923 | + try { | ||
924 | + return new Attribute(key, attrValue); | ||
925 | + } catch (Exception e) { | ||
926 | + log.error("CreateAttribute, not valid parameter key: [{}], attrValue: [{}], error: [{}]", key, attrValue, e.getMessage()); | ||
927 | + return null; | ||
928 | + } | ||
929 | + } | ||
866 | } | 930 | } |
@@ -31,8 +31,8 @@ import org.eclipse.leshan.server.registration.Registration; | @@ -31,8 +31,8 @@ import org.eclipse.leshan.server.registration.Registration; | ||
31 | import org.eclipse.leshan.server.security.SecurityInfo; | 31 | import org.eclipse.leshan.server.security.SecurityInfo; |
32 | import org.thingsboard.server.common.data.Device; | 32 | import org.thingsboard.server.common.data.Device; |
33 | import org.thingsboard.server.common.data.DeviceProfile; | 33 | import org.thingsboard.server.common.data.DeviceProfile; |
34 | -import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | ||
35 | import org.thingsboard.server.common.data.firmware.FirmwareType; | 34 | import org.thingsboard.server.common.data.firmware.FirmwareType; |
35 | +import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; | ||
36 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | 36 | import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
37 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; | 37 | import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto; |
38 | import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; | 38 | import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; |
@@ -117,7 +117,6 @@ public class LwM2mClient implements Cloneable { | @@ -117,7 +117,6 @@ public class LwM2mClient implements Cloneable { | ||
117 | this.pendingReadRequests = new CopyOnWriteArrayList<>(); | 117 | this.pendingReadRequests = new CopyOnWriteArrayList<>(); |
118 | this.resources = new ConcurrentHashMap<>(); | 118 | this.resources = new ConcurrentHashMap<>(); |
119 | this.profileId = profileId; | 119 | this.profileId = profileId; |
120 | - this.sessionId = sessionId; | ||
121 | this.init = false; | 120 | this.init = false; |
122 | this.queuedRequests = new ConcurrentLinkedQueue<>(); | 121 | this.queuedRequests = new ConcurrentLinkedQueue<>(); |
123 | 122 | ||
@@ -194,17 +193,31 @@ public class LwM2mClient implements Cloneable { | @@ -194,17 +193,31 @@ public class LwM2mClient implements Cloneable { | ||
194 | public Object getResourceValue(String pathRezIdVer, String pathRezId) { | 193 | public Object getResourceValue(String pathRezIdVer, String pathRezId) { |
195 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; | 194 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; |
196 | if (this.resources.get(pathRez) != null) { | 195 | if (this.resources.get(pathRez) != null) { |
197 | - return this.resources.get(pathRez).getLwM2mResource().isMultiInstances() ? | 196 | + return this.resources.get(pathRez).getLwM2mResource().isMultiInstances() ? |
198 | this.resources.get(pathRez).getLwM2mResource().getValues() : | 197 | this.resources.get(pathRez).getLwM2mResource().getValues() : |
199 | this.resources.get(pathRez).getLwM2mResource().getValue(); | 198 | this.resources.get(pathRez).getLwM2mResource().getValue(); |
200 | } | 199 | } |
201 | return null; | 200 | return null; |
202 | } | 201 | } |
203 | 202 | ||
204 | - public Object getResourceName (String pathRezIdVer, String pathRezId) { | 203 | + public Object getResourceNameByRezId(String pathRezIdVer, String pathRezId) { |
205 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; | 204 | String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer; |
206 | if (this.resources.get(pathRez) != null) { | 205 | if (this.resources.get(pathRez) != null) { |
207 | - return this.resources.get(pathRez).getResourceModel().name; | 206 | + return this.resources.get(pathRez).getResourceModel().name; |
207 | + } | ||
208 | + return null; | ||
209 | + } | ||
210 | + | ||
211 | + public String getRezIdByResourceNameAndObjectInstanceId(String resourceName, String pathObjectInstanceIdVer, LwM2mModelProvider modelProvider) { | ||
212 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathObjectInstanceIdVer)); | ||
213 | + if (pathIds.isObjectInstance()) { | ||
214 | + Set<Integer> rezIds = modelProvider.getObjectModel(registration) | ||
215 | + .getObjectModel(pathIds.getObjectId()).resources.entrySet() | ||
216 | + .stream() | ||
217 | + .filter(map -> resourceName.equals(map.getValue().name)) | ||
218 | + .map(map -> map.getKey()) | ||
219 | + .collect(Collectors.toSet()); | ||
220 | + return rezIds.size() > 0 ? String.valueOf(rezIds.stream().findFirst().get()) : null; | ||
208 | } | 221 | } |
209 | return null; | 222 | return null; |
210 | } | 223 | } |
@@ -225,11 +238,11 @@ public class LwM2mClient implements Cloneable { | @@ -225,11 +238,11 @@ public class LwM2mClient implements Cloneable { | ||
225 | .getObjectModel(pathIds.getObjectId()) : null; | 238 | .getObjectModel(pathIds.getObjectId()) : null; |
226 | } | 239 | } |
227 | 240 | ||
228 | - public String objectToString (LwM2mObject lwM2mObject, LwM2mValueConverterImpl converter, String pathIdVer) { | 241 | + public String objectToString(LwM2mObject lwM2mObject, LwM2mValueConverterImpl converter, String pathIdVer) { |
229 | StringBuilder builder = new StringBuilder(); | 242 | StringBuilder builder = new StringBuilder(); |
230 | builder.append("LwM2mObject [id=").append(lwM2mObject.getId()).append(", instances={"); | 243 | builder.append("LwM2mObject [id=").append(lwM2mObject.getId()).append(", instances={"); |
231 | lwM2mObject.getInstances().forEach((instId, inst) -> { | 244 | lwM2mObject.getInstances().forEach((instId, inst) -> { |
232 | - builder.append(instId).append("=").append(this.instanceToString(inst, converter, pathIdVer)).append(", "); | 245 | + builder.append(instId).append("=").append(this.instanceToString(inst, converter, pathIdVer)).append(", "); |
233 | }); | 246 | }); |
234 | int startInd = builder.lastIndexOf(", "); | 247 | int startInd = builder.lastIndexOf(", "); |
235 | if (startInd > 0) { | 248 | if (startInd > 0) { |
@@ -238,11 +251,12 @@ public class LwM2mClient implements Cloneable { | @@ -238,11 +251,12 @@ public class LwM2mClient implements Cloneable { | ||
238 | builder.append("}]"); | 251 | builder.append("}]"); |
239 | return builder.toString(); | 252 | return builder.toString(); |
240 | } | 253 | } |
241 | - public String instanceToString (LwM2mObjectInstance objectInstance, LwM2mValueConverterImpl converter, String pathIdVer) { | 254 | + |
255 | + public String instanceToString(LwM2mObjectInstance objectInstance, LwM2mValueConverterImpl converter, String pathIdVer) { | ||
242 | StringBuilder builder = new StringBuilder(); | 256 | StringBuilder builder = new StringBuilder(); |
243 | builder.append("LwM2mObjectInstance [id=").append(objectInstance.getId()).append(", resources={"); | 257 | builder.append("LwM2mObjectInstance [id=").append(objectInstance.getId()).append(", resources={"); |
244 | objectInstance.getResources().forEach((resId, res) -> { | 258 | objectInstance.getResources().forEach((resId, res) -> { |
245 | - builder.append(resId).append("=").append(this.resourceToString (res, converter, pathIdVer)).append(", "); | 259 | + builder.append(resId).append("=").append(this.resourceToString(res, converter, pathIdVer)).append(", "); |
246 | }); | 260 | }); |
247 | int startInd = builder.lastIndexOf(", "); | 261 | int startInd = builder.lastIndexOf(", "); |
248 | if (startInd > 0) { | 262 | if (startInd > 0) { |
@@ -252,12 +266,11 @@ public class LwM2mClient implements Cloneable { | @@ -252,12 +266,11 @@ public class LwM2mClient implements Cloneable { | ||
252 | return builder.toString(); | 266 | return builder.toString(); |
253 | } | 267 | } |
254 | 268 | ||
255 | - public String resourceToString (LwM2mResource lwM2mResource, LwM2mValueConverterImpl converter, String pathIdVer) { | 269 | + public String resourceToString(LwM2mResource lwM2mResource, LwM2mValueConverterImpl converter, String pathIdVer) { |
256 | if (!OPAQUE.equals(lwM2mResource.getType())) { | 270 | if (!OPAQUE.equals(lwM2mResource.getType())) { |
257 | return lwM2mResource.isMultiInstances() ? ((LwM2mMultipleResource) lwM2mResource).toString() : | 271 | return lwM2mResource.isMultiInstances() ? ((LwM2mMultipleResource) lwM2mResource).toString() : |
258 | ((LwM2mSingleResource) lwM2mResource).toString(); | 272 | ((LwM2mSingleResource) lwM2mResource).toString(); |
259 | - } | ||
260 | - else { | 273 | + } else { |
261 | return String.format("LwM2mSingleResource [id=%s, value=%s, type=%s]", lwM2mResource.getId(), | 274 | return String.format("LwM2mSingleResource [id=%s, value=%s, type=%s]", lwM2mResource.getId(), |
262 | converter.convertValue(lwM2mResource.getValue(), | 275 | converter.convertValue(lwM2mResource.getValue(), |
263 | OPAQUE, STRING, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))), lwM2mResource.getType().name()); | 276 | OPAQUE, STRING, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))), lwM2mResource.getType().name()); |
@@ -275,7 +288,8 @@ public class LwM2mClient implements Cloneable { | @@ -275,7 +288,8 @@ public class LwM2mClient implements Cloneable { | ||
275 | resources.add(LwM2mSingleResource.newResource(resId, converter.convertValue(params, | 288 | resources.add(LwM2mSingleResource.newResource(resId, converter.convertValue(params, |
276 | equalsResourceTypeGetSimpleName(params), resourceModel.type, pathIds), resourceModel.type)); | 289 | equalsResourceTypeGetSimpleName(params), resourceModel.type, pathIds), resourceModel.type)); |
277 | 290 | ||
278 | - }}); | 291 | + } |
292 | + }); | ||
279 | return resources; | 293 | return resources; |
280 | } | 294 | } |
281 | 295 | ||
@@ -291,7 +305,8 @@ public class LwM2mClient implements Cloneable { | @@ -291,7 +305,8 @@ public class LwM2mClient implements Cloneable { | ||
291 | resources.add(LwM2mSingleResource.newResource(resId, | 305 | resources.add(LwM2mSingleResource.newResource(resId, |
292 | converter.convertValue(value, equalsResourceTypeGetSimpleName(value), resourceModel.type, pathIds), resourceModel.type)); | 306 | converter.convertValue(value, equalsResourceTypeGetSimpleName(value), resourceModel.type, pathIds), resourceModel.type)); |
293 | 307 | ||
294 | - }}); | 308 | + } |
309 | + }); | ||
295 | return resources; | 310 | return resources; |
296 | } | 311 | } |
297 | 312 |
@@ -35,8 +35,6 @@ public interface LwM2mClientContext { | @@ -35,8 +35,6 @@ public interface LwM2mClientContext { | ||
35 | 35 | ||
36 | LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); | 36 | LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo); |
37 | 37 | ||
38 | - LwM2mClient getClient(UUID sessionId); | ||
39 | - | ||
40 | LwM2mClient getOrRegister(Registration registration); | 38 | LwM2mClient getOrRegister(Registration registration); |
41 | 39 | ||
42 | LwM2mClient registerOrUpdate(Registration registration); | 40 | LwM2mClient registerOrUpdate(Registration registration); |
@@ -83,13 +83,11 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -83,13 +83,11 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
83 | 83 | ||
84 | @Override | 84 | @Override |
85 | public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { | 85 | public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { |
86 | - return getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | ||
87 | - } | 86 | + return lwM2mClientsByEndpoint.values().stream().filter(c -> |
87 | + (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) | ||
88 | + .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) | ||
88 | 89 | ||
89 | - @Override | ||
90 | - public LwM2mClient getClient(UUID sessionId) { | ||
91 | - //TODO: refactor this to search by sessionId efficiently. | ||
92 | - return lwM2mClientsByEndpoint.values().stream().filter(c -> c.getSessionId().equals(sessionId)).findAny().get(); | 90 | + ).findAny().get(); |
93 | } | 91 | } |
94 | 92 | ||
95 | @Override | 93 | @Override |
@@ -286,7 +286,7 @@ public class LwM2mFwSwUpdate { | @@ -286,7 +286,7 @@ public class LwM2mFwSwUpdate { | ||
286 | Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); | 286 | Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId); |
287 | String value = FIRMWARE.equals(this.type) ? LwM2mTransportUtil.UpdateResultFw.fromUpdateResultFwByCode(updateResult.intValue()).type : | 287 | String value = FIRMWARE.equals(this.type) ? LwM2mTransportUtil.UpdateResultFw.fromUpdateResultFwByCode(updateResult.intValue()).type : |
288 | LwM2mTransportUtil.UpdateResultSw.fromUpdateResultSwByCode(updateResult.intValue()).type; | 288 | LwM2mTransportUtil.UpdateResultSw.fromUpdateResultSwByCode(updateResult.intValue()).type; |
289 | - String key = splitCamelCaseString((String) this.lwM2MClient.getResourceName(null, this.pathResultId)); | 289 | + String key = splitCamelCaseString((String) this.lwM2MClient.getResourceNameByRezId(null, this.pathResultId)); |
290 | if (success) { | 290 | if (success) { |
291 | this.stateUpdate = FirmwareUpdateStatus.UPDATED.name(); | 291 | this.stateUpdate = FirmwareUpdateStatus.UPDATED.name(); |
292 | this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); | 292 | this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); |
@@ -15,98 +15,265 @@ | @@ -15,98 +15,265 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.lwm2m.server.client; | 16 | package org.thingsboard.server.transport.lwm2m.server.client; |
17 | 17 | ||
18 | +import com.google.gson.Gson; | ||
18 | import com.google.gson.JsonObject; | 19 | import com.google.gson.JsonObject; |
20 | +import com.google.gson.reflect.TypeToken; | ||
19 | import lombok.Data; | 21 | import lombok.Data; |
20 | import lombok.extern.slf4j.Slf4j; | 22 | import lombok.extern.slf4j.Slf4j; |
21 | -import org.eclipse.leshan.core.request.ContentFormat; | 23 | +import org.apache.commons.lang3.StringUtils; |
24 | +import org.eclipse.leshan.core.node.LwM2mPath; | ||
22 | import org.eclipse.leshan.server.registration.Registration; | 25 | import org.eclipse.leshan.server.registration.Registration; |
23 | import org.thingsboard.server.gen.transport.TransportProtos; | 26 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | -import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | ||
25 | -import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; | 27 | +import org.thingsboard.server.transport.lwm2m.server.DefaultLwM2MTransportMsgHandler; |
26 | 28 | ||
29 | +import java.util.Map; | ||
30 | +import java.util.Objects; | ||
27 | import java.util.concurrent.ConcurrentHashMap; | 31 | import java.util.concurrent.ConcurrentHashMap; |
32 | +import java.util.concurrent.TimeoutException; | ||
28 | 33 | ||
34 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.ERROR_KEY; | ||
35 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FINISH_JSON_KEY; | ||
36 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FINISH_VALUE_KEY; | ||
37 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.INFO_KEY; | ||
38 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.KEY_NAME_KEY; | ||
39 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; | ||
40 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL; | ||
41 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; | ||
42 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; | ||
43 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; | ||
44 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; | ||
45 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; | ||
46 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE; | ||
47 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.METHOD_KEY; | ||
48 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.PARAMS_KEY; | ||
49 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESULT_KEY; | ||
50 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SEPARATOR_KEY; | ||
51 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.START_JSON_KEY; | ||
52 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.TARGET_ID_VER_KEY; | ||
53 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.VALUE_KEY; | ||
54 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId; | ||
29 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validPathIdVer; | 55 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.validPathIdVer; |
30 | 56 | ||
31 | @Slf4j | 57 | @Slf4j |
32 | @Data | 58 | @Data |
33 | public class Lwm2mClientRpcRequest { | 59 | public class Lwm2mClientRpcRequest { |
34 | - public final String targetIdVerKey = "targetIdVer"; | ||
35 | - public final String keyNameKey = "key"; | ||
36 | - public final String typeOperKey = "typeOper"; | ||
37 | - public final String contentFormatNameKey = "contentFormatName"; | ||
38 | - public final String valueKey = "value"; | ||
39 | - public final String infoKey = "info"; | ||
40 | - public final String paramsKey = "params"; | ||
41 | - public final String timeoutInMsKey = "timeOutInMs"; | ||
42 | - public final String resultKey = "result"; | ||
43 | - public final String errorKey = "error"; | ||
44 | - public final String methodKey = "methodName"; | 60 | + |
61 | + private Registration registration; | ||
62 | + private TransportProtos.SessionInfoProto sessionInfo; | ||
63 | + private String bodyParams; | ||
64 | + private int requestId; | ||
45 | 65 | ||
46 | private LwM2mTypeOper typeOper; | 66 | private LwM2mTypeOper typeOper; |
67 | + private String key; | ||
47 | private String targetIdVer; | 68 | private String targetIdVer; |
48 | - private String contentFormatName; | ||
49 | - private long timeoutInMs; | ||
50 | private Object value; | 69 | private Object value; |
51 | - private ConcurrentHashMap<String, Object> params; | ||
52 | - private SessionInfoProto sessionInfo; | ||
53 | - private int requestId; | 70 | + private Map<String, Object> params; |
71 | + | ||
54 | private String errorMsg; | 72 | private String errorMsg; |
55 | private String valueMsg; | 73 | private String valueMsg; |
56 | private String infoMsg; | 74 | private String infoMsg; |
57 | private String responseCode; | 75 | private String responseCode; |
58 | 76 | ||
59 | - public void setValidTypeOper(String typeOper) { | 77 | + public Lwm2mClientRpcRequest() { |
78 | + } | ||
79 | + | ||
80 | + public Lwm2mClientRpcRequest(LwM2mTypeOper lwM2mTypeOper, String bodyParams, int requestId, | ||
81 | + TransportProtos.SessionInfoProto sessionInfo, Registration registration, DefaultLwM2MTransportMsgHandler handler) { | ||
82 | + this.registration = registration; | ||
83 | + this.sessionInfo = sessionInfo; | ||
84 | + this.requestId = requestId; | ||
85 | + if (lwM2mTypeOper != null) { | ||
86 | + this.typeOper = lwM2mTypeOper; | ||
87 | + } else { | ||
88 | + this.errorMsg = METHOD_KEY + " - " + typeOper + " is not valid."; | ||
89 | + } | ||
90 | + if (this.errorMsg == null && !bodyParams.equals("null")) { | ||
91 | + this.bodyParams = bodyParams; | ||
92 | + this.init(handler); | ||
93 | + } | ||
94 | + } | ||
95 | + | ||
96 | + public TransportProtos.ToDeviceRpcResponseMsg getDeviceRpcResponseResultMsg() { | ||
97 | + JsonObject payloadResp = new JsonObject(); | ||
98 | + payloadResp.addProperty(RESULT_KEY, this.responseCode); | ||
99 | + if (this.errorMsg != null) { | ||
100 | + payloadResp.addProperty(ERROR_KEY, this.errorMsg); | ||
101 | + } else if (this.valueMsg != null) { | ||
102 | + payloadResp.addProperty(VALUE_KEY, this.valueMsg); | ||
103 | + } else if (this.infoMsg != null) { | ||
104 | + payloadResp.addProperty(INFO_KEY, this.infoMsg); | ||
105 | + } | ||
106 | + return TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
107 | + .setPayload(payloadResp.getAsJsonObject().toString()) | ||
108 | + .setRequestId(this.requestId) | ||
109 | + .build(); | ||
110 | + } | ||
111 | + | ||
112 | + private void init(DefaultLwM2MTransportMsgHandler handler) { | ||
60 | try { | 113 | try { |
61 | - this.typeOper = LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper); | 114 | + // #1 |
115 | + if (this.bodyParams.contains(KEY_NAME_KEY)) { | ||
116 | + String targetIdVerStr = this.getValueKeyFromBody(KEY_NAME_KEY); | ||
117 | + if (targetIdVerStr != null) { | ||
118 | + String targetIdVer = handler.getPresentPathIntoProfile(sessionInfo, targetIdVerStr); | ||
119 | + if (targetIdVer != null) { | ||
120 | + this.targetIdVer = targetIdVer; | ||
121 | + this.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s", | ||
122 | + targetIdVerStr, targetIdVer)); | ||
123 | + } | ||
124 | + } | ||
125 | + } | ||
126 | + if (this.getTargetIdVer() == null && this.bodyParams.contains(TARGET_ID_VER_KEY)) { | ||
127 | + this.setValidTargetIdVerKey(); | ||
128 | + } | ||
129 | + if (this.bodyParams.contains(VALUE_KEY)) { | ||
130 | + this.value = this.getValueKeyFromBody(VALUE_KEY); | ||
131 | + } | ||
132 | + try { | ||
133 | + if (this.bodyParams.contains(PARAMS_KEY)) { | ||
134 | + this.setValidParamsKey(handler); | ||
135 | + } | ||
136 | + } catch (Exception e) { | ||
137 | + this.setErrorMsg(String.format("Params of request is bad Json format. %s", e.getMessage())); | ||
138 | + } | ||
139 | + | ||
140 | + if (this.getTargetIdVer() == null | ||
141 | + && !(OBSERVE_READ_ALL == this.getTypeOper() | ||
142 | + || DISCOVER_ALL == this.getTypeOper() | ||
143 | + || OBSERVE_CANCEL == this.getTypeOper())) { | ||
144 | + this.setErrorMsg(TARGET_ID_VER_KEY + " and " + | ||
145 | + KEY_NAME_KEY + " is null or bad format"); | ||
146 | + } | ||
147 | + /** | ||
148 | + * EXECUTE && WRITE_REPLACE - only for Resource or ResourceInstance | ||
149 | + */ | ||
150 | + else if (this.getTargetIdVer() != null | ||
151 | + && (EXECUTE == this.getTypeOper() | ||
152 | + || WRITE_REPLACE == this.getTypeOper()) | ||
153 | + && !(new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.getTargetIdVer()))).isResource() | ||
154 | + || new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.getTargetIdVer()))).isResourceInstance())) { | ||
155 | + this.setErrorMsg("Invalid parameter " + TARGET_ID_VER_KEY | ||
156 | + + ". Only Resource or ResourceInstance can be this operation"); | ||
157 | + } | ||
62 | } catch (Exception e) { | 158 | } catch (Exception e) { |
63 | - this.errorMsg = this.methodKey + " - " + typeOper + " is not valid."; | 159 | + this.setErrorMsg(String.format("Bad format request. %s", e.getMessage())); |
64 | } | 160 | } |
161 | + | ||
65 | } | 162 | } |
66 | 163 | ||
67 | - public void setValidContentFormatName(JsonObject rpcRequest) { | 164 | + private void setValidTargetIdVerKey() { |
165 | + String targetIdVerStr = this.getValueKeyFromBody(TARGET_ID_VER_KEY); | ||
166 | + // targetIdVer without ver - ok | ||
68 | try { | 167 | try { |
69 | - if (ContentFormat.fromName(rpcRequest.get(this.contentFormatNameKey).getAsString()) != null) { | ||
70 | - this.contentFormatName = rpcRequest.get(this.contentFormatNameKey).getAsString(); | ||
71 | - } else { | ||
72 | - this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid."; | 168 | + // targetIdVer with/without ver - ok |
169 | + this.targetIdVer = validPathIdVer(targetIdVerStr, this.registration); | ||
170 | + if (this.targetIdVer != null) { | ||
171 | + this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer); | ||
73 | } | 172 | } |
74 | } catch (Exception e) { | 173 | } catch (Exception e) { |
75 | - this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid."; | 174 | + if (this.targetIdVer == null) { |
175 | + this.errorMsg = TARGET_ID_VER_KEY + " - " + targetIdVerStr + " is not valid."; | ||
176 | + } | ||
76 | } | 177 | } |
77 | } | 178 | } |
78 | 179 | ||
79 | - public void setValidTargetIdVerKey(JsonObject rpcRequest, Registration registration) { | ||
80 | - if (rpcRequest.has(this.targetIdVerKey)) { | ||
81 | - String targetIdVerStr = rpcRequest.get(targetIdVerKey).getAsString(); | ||
82 | - // targetIdVer without ver - ok | ||
83 | - try { | ||
84 | - // targetIdVer with/without ver - ok | ||
85 | - this.targetIdVer = validPathIdVer(targetIdVerStr, registration); | 180 | + private void setValidParamsKey(DefaultLwM2MTransportMsgHandler handler) { |
181 | + String paramsStr = this.getValueKeyFromBody(PARAMS_KEY); | ||
182 | + if (paramsStr != null) { | ||
183 | + String params2Json = | ||
184 | + START_JSON_KEY | ||
185 | + + "\"" | ||
186 | + + paramsStr | ||
187 | + .replaceAll(SEPARATOR_KEY, "\"" + SEPARATOR_KEY + "\"") | ||
188 | + .replaceAll(FINISH_VALUE_KEY, "\"" + FINISH_VALUE_KEY + "\"") | ||
189 | + + "\"" | ||
190 | + + FINISH_JSON_KEY; | ||
191 | + // jsonObject | ||
192 | + Map<String, Object> params = new Gson().fromJson(params2Json, new TypeToken<ConcurrentHashMap<String, Object>>() { | ||
193 | + }.getType()); | ||
194 | + if (WRITE_UPDATE == this.getTypeOper()) { | ||
86 | if (this.targetIdVer != null) { | 195 | if (this.targetIdVer != null) { |
87 | - this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer); | ||
88 | - } | ||
89 | - } catch (Exception e) { | ||
90 | - if (this.targetIdVer == null) { | ||
91 | - this.errorMsg = this.targetIdVerKey + " - " + targetIdVerStr + " is not valid."; | 196 | + Map<String, Object> paramsResourceId = this.convertParamsToResourceId((ConcurrentHashMap<String, Object>) params, handler); |
197 | + if (paramsResourceId.size() > 0) { | ||
198 | + this.setParams(paramsResourceId); | ||
199 | + } | ||
92 | } | 200 | } |
201 | + } else if (WRITE_ATTRIBUTES == this.getTypeOper()) { | ||
202 | + this.setParams(params); | ||
93 | } | 203 | } |
94 | } | 204 | } |
95 | } | 205 | } |
96 | 206 | ||
97 | - public TransportProtos.ToDeviceRpcResponseMsg getDeviceRpcResponseResultMsg() { | ||
98 | - JsonObject payloadResp = new JsonObject(); | ||
99 | - payloadResp.addProperty(this.resultKey, this.responseCode); | ||
100 | - if (this.errorMsg != null) { | ||
101 | - payloadResp.addProperty(this.errorKey, this.errorMsg); | ||
102 | - } else if (this.valueMsg != null) { | ||
103 | - payloadResp.addProperty(this.valueKey, this.valueMsg); | ||
104 | - } else if (this.infoMsg != null) { | ||
105 | - payloadResp.addProperty(this.infoKey, this.infoMsg); | 207 | + private String getValueKeyFromBody(String key) { |
208 | + String valueKey = null; | ||
209 | + int startInd = -1; | ||
210 | + int finishInd = -1; | ||
211 | + try { | ||
212 | + switch (key) { | ||
213 | + case KEY_NAME_KEY: | ||
214 | + case TARGET_ID_VER_KEY: | ||
215 | + case VALUE_KEY: | ||
216 | + startInd = this.bodyParams.indexOf(SEPARATOR_KEY, this.bodyParams.indexOf(key)); | ||
217 | + finishInd = this.bodyParams.indexOf(FINISH_VALUE_KEY, this.bodyParams.indexOf(key)); | ||
218 | + if (startInd >= 0 && finishInd < 0) { | ||
219 | + finishInd = this.bodyParams.indexOf(FINISH_JSON_KEY, this.bodyParams.indexOf(key)); | ||
220 | + } | ||
221 | + break; | ||
222 | + case PARAMS_KEY: | ||
223 | + startInd = this.bodyParams.indexOf(START_JSON_KEY, this.bodyParams.indexOf(key)); | ||
224 | + finishInd = this.bodyParams.indexOf(FINISH_JSON_KEY, this.bodyParams.indexOf(key)); | ||
225 | + } | ||
226 | + if (startInd >= 0 && finishInd > 0) { | ||
227 | + valueKey = this.bodyParams.substring(startInd + 1, finishInd); | ||
228 | + } | ||
229 | + } catch (Exception e) { | ||
230 | + log.error("", new TimeoutException()); | ||
106 | } | 231 | } |
107 | - return TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
108 | - .setPayload(payloadResp.getAsJsonObject().toString()) | ||
109 | - .setRequestId(this.requestId) | ||
110 | - .build(); | 232 | + /** |
233 | + * ReplaceAll "\"" | ||
234 | + */ | ||
235 | + if (StringUtils.trimToNull(valueKey) != null) { | ||
236 | + char[] chars = valueKey.toCharArray(); | ||
237 | + for (int i = 0; i < chars.length; i++) { | ||
238 | + if (chars[i] == 92 || chars[i] == 34) chars[i] = 32; | ||
239 | + } | ||
240 | + return key.equals(PARAMS_KEY) ? String.valueOf(chars) : String.valueOf(chars).replaceAll(" ", ""); | ||
241 | + } | ||
242 | + return null; | ||
243 | + } | ||
244 | + | ||
245 | + private ConcurrentHashMap<String, Object> convertParamsToResourceId(ConcurrentHashMap<String, Object> params, | ||
246 | + DefaultLwM2MTransportMsgHandler serviceImpl) { | ||
247 | + Map<String, Object> paramsIdVer = new ConcurrentHashMap<>(); | ||
248 | + LwM2mPath targetId = new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(this.targetIdVer))); | ||
249 | + if (targetId.isObjectInstance()) { | ||
250 | + params.forEach((k, v) -> { | ||
251 | + try { | ||
252 | + int id = Integer.parseInt(k); | ||
253 | + paramsIdVer.put(String.valueOf(id), v); | ||
254 | + } catch (NumberFormatException e) { | ||
255 | + String targetIdVer = serviceImpl.getPresentPathIntoProfile(sessionInfo, k); | ||
256 | + if (targetIdVer != null) { | ||
257 | + LwM2mPath lwM2mPath = new LwM2mPath(Objects.requireNonNull(convertPathFromIdVerToObjectId(targetIdVer))); | ||
258 | + paramsIdVer.put(String.valueOf(lwM2mPath.getResourceId()), v); | ||
259 | + } | ||
260 | + /** WRITE_UPDATE*/ | ||
261 | + else { | ||
262 | + String rezId = this.getRezIdByResourceNameAndObjectInstanceId(k, serviceImpl); | ||
263 | + if (rezId != null) { | ||
264 | + paramsIdVer.put(rezId, v); | ||
265 | + } | ||
266 | + } | ||
267 | + } | ||
268 | + }); | ||
269 | + } | ||
270 | + return (ConcurrentHashMap<String, Object>) paramsIdVer; | ||
271 | + } | ||
272 | + | ||
273 | + private String getRezIdByResourceNameAndObjectInstanceId(String resourceName, DefaultLwM2MTransportMsgHandler handler) { | ||
274 | + LwM2mClient lwM2mClient = handler.clientContext.getClient(this.sessionInfo); | ||
275 | + return lwM2mClient != null ? | ||
276 | + lwM2mClient.getRezIdByResourceNameAndObjectInstanceId(resourceName, this.targetIdVer, handler.config.getModelProvider()) : | ||
277 | + null; | ||
111 | } | 278 | } |
112 | } | 279 | } |