lwm2m: fix bug WriteUpdate & updateAttributes after sleep

This commit is contained in:
nickAS21 2021-09-07 23:16:18 +03:00
parent be5ec4fce9
commit 4b74d2bde1
2 changed files with 56 additions and 39 deletions

View File

@ -57,7 +57,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_INFO;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LWM2M_WARN;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertMultiResourceValuesFromJson;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.fromVersionedIdToObjectId;
@ -212,7 +211,7 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService {
Object newValProto = getValueFromKvProto(tsKvProto.getKv());
Object oldResourceValue = this.getResourceValueFormatKv(lwM2MClient, pathIdVer);
if (!resourceModel.multiple || !(newValProto instanceof JsonElement)) {
this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue);
this.pushUpdateToClientIfNeeded(lwM2MClient, oldResourceValue, newValProto, pathIdVer, logFailedUpdateOfNonChangedValue, resourceModel.type);
} else {
pushUpdateMultiToClientIfNeeded(lwM2MClient, resourceModel, (JsonElement) newValProto,
(Map<Integer, LwM2mResourceInstance>) oldResourceValue, pathIdVer);
@ -221,22 +220,22 @@ public class DefaultLwM2MAttributesService implements LwM2MAttributesService {
}
private void pushUpdateToClientIfNeeded(LwM2mClient lwM2MClient, Object valueOld, Object newValue,
String versionedId, boolean logFailedUpdateOfNonChangedValue) {
String versionedId, boolean logFailedUpdateOfNonChangedValue, ResourceModel.Type type) {
if (newValue == null) {
String logMsg = String.format("%s: Failed update resource versionedId - %s value - %s. New value is bad",
LOG_LWM2M_ERROR, versionedId, "null");
logService.log(lwM2MClient, logMsg);
log.error("Failed update resource [{}] [{}]", versionedId, "null");
} else if (newValue.toString().equals(valueOld.toString())){
if (logFailedUpdateOfNonChangedValue) {
String logMsg = String.format("%s: Didn't update the versionedId resource - %s value - %s. Value is not changed",
LOG_LWM2M_WARN, versionedId, newValue);
logService.log(lwM2MClient, logMsg);
log.warn("Didn't update resource [{}] [{}]. Value is not changed", versionedId, newValue);
}
} else {
log.error("Failed update resource [{}] [{}]", versionedId, "null");
} else if ((valueOld == null) ||
((OPAQUE.equals(type) && !Arrays.equals((byte[]) newValue, (byte[]) valueOld)) ||
!newValue.equals(valueOld))) {
TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionedId).value(newValue).timeout(clientContext.getRequestTimeout(lwM2MClient)).build();
downlinkHandler.sendWriteReplaceRequest(lwM2MClient, request, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, lwM2MClient, versionedId));
} else if (logFailedUpdateOfNonChangedValue) {
String logMsg = String.format("%s: Didn't update the versionedId resource - %s value - %s. Value is not changed",
LOG_LWM2M_WARN, versionedId, newValue);
logService.log(lwM2MClient, logMsg);
log.warn("Didn't update resource [{}] [{}]. Value is not changed", versionedId, newValue);
}
}

View File

@ -345,39 +345,57 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
@Override
public void sendWriteUpdateRequest(LwM2mClient client, TbLwM2MWriteUpdateRequest request, DownlinkRequestCallback<WriteRequest, WriteResponse> callback) {
try {
validateVersionedId(client, request);
WriteRequest downlink = null;
LwM2mPath resultIds = new LwM2mPath(request.getObjectId());
ContentFormat contentFormat = getWriteRequestContentFormat(client, request, this.config.getModelProvider());
if (resultIds.isObjectInstance()) {
/*
* params = "{\"id\":0,\"value\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}"
* int rscId = resultIds.getObjectInstanceId();
* contentFormat Format of the payload (TLV or JSON).
*/
Collection<LwM2mResource> resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter);
if (resources.size() > 0) {
downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources);
} else {
callback.onValidationError(toString(request), "No resources to update!");
}
} else if (resultIds.isResource()) {
if (resultIds.isObjectInstance() || resultIds.isResource()) {
validateVersionedId(client, request);
ResourceModel resourceModelWrite = client.getResourceModel(request.getVersionedId(), this.config.getModelProvider());
if (resourceModelWrite.multiple) {
if (request.getValue() instanceof Map && ((Map) request.getValue()).size() > 0) {
Map value = convertMultiResourceValuesFromRpcBody((LinkedHashMap) request.getValue(), resourceModelWrite.type, request.getObjectId());
downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(),
value, resourceModelWrite.type);
if (resourceModelWrite != null) {
WriteRequest downlink = null;
ContentFormat contentFormat = getWriteRequestContentFormat(client, request, this.config.getModelProvider());
if (resultIds.isObjectInstance()) {
/*
* params = "{\"id\":0,\"value\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}"
* int rscId = resultIds.getObjectInstanceId();
* contentFormat Format of the payload (TLV or JSON).
*/
Collection<LwM2mResource> resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), this.config.getModelProvider(), this.converter);
if (resources.size() > 0) {
downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resources);
} else {
callback.onValidationError(toString(request), "No resources to update!");
}
} else if (resultIds.isResource()) {
if (resourceModelWrite.multiple) {
if (request.getValue() instanceof Map && ((Map) request.getValue()).size() > 0) {
Map value = convertMultiResourceValuesFromRpcBody((LinkedHashMap) request.getValue(), resourceModelWrite.type, request.getObjectId());
downlink = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(),
value, resourceModelWrite.type);
} else {
callback.onValidationError(toString(request), "Resource value is bad. Format: " + request.getValue().getClass().getSimpleName() + ". Value of Multi-Instance Resource must be in Json format!");
}
}
}
if (downlink != null) {
sendSimpleRequest(client, downlink, request.getTimeout(), callback);
} else {
callback.onValidationError(toString(request), "Resource value is bad. Format: " + request.getValue().getClass().getSimpleName() + ". Value of Multi-Instance Resource must be in Json format!");
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() + ". This operation can only be used for ObjectInstance or Multi-Instance Resource !");
}
}
else {
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() + " is not configured in the device profile!");
}
}
if (downlink != null) {
sendSimpleRequest(client, downlink, request.getTimeout(), callback);
} else {
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() + ". This operation can only be used for ObjectInstance or Multi-Instance Resource !");
else {
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() + ". This operation can only be used for ObjectInstance or Resource (multiple)");
}
} catch (Exception e) {
callback.onValidationError(toString(request), e.getMessage());
}
@ -585,7 +603,7 @@ public class DefaultLwM2mDownlinkMsgHandler extends LwM2MExecutorAwareService im
}
} else if (pathIds.isResource()) {
ResourceModel resourceModel = client.getResourceModel(versionedId, modelProvider);
if (!resourceModel.multiple) {
if (resourceModel!= null && !resourceModel.multiple) {
if (OBJLNK.equals(resourceModel.type)) {
return ContentFormat.LINK;
} else if (OPAQUE.equals(resourceModel.type)) {