Browse Source

Merge with master

pull/4680/head
Andrii Shvaika 5 years ago
parent
commit
02376ab157
  1. 99
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java
  2. 148
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java
  3. 11
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java
  4. 5
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java
  5. 8
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java
  6. 41
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java
  7. 4
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java
  8. 3
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java

99
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2MTransportMsgHandler.java

@ -196,8 +196,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
.setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build()) .setSubscribeToRPC(TransportProtos.SubscribeToRPCMsg.newBuilder().build())
.build(); .build();
transportService.process(msg, null); transportService.process(msg, null);
this.getInfoFirmwareUpdate(lwM2MClient); this.getInfoFirmwareUpdate(lwM2MClient, null);
this.getInfoSoftwareUpdate(lwM2MClient); this.getInfoSoftwareUpdate(lwM2MClient, null);
this.initLwM2mFromClientValue(registration, lwM2MClient); this.initLwM2mFromClientValue(registration, lwM2MClient);
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId()); this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client create after Registration", registration.getId());
} else { } else {
@ -285,7 +285,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
@Override @Override
public void setCancelObservationsAll(Registration registration) { public void setCancelObservationsAll(Registration registration) {
if (registration != null) { if (registration != null) {
lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL_ALL, this.lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL_ALL,
null, null, this.config.getTimeout(), null); null, null, this.config.getTimeout(), null);
} }
} }
@ -334,7 +334,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
READ, pathIdVer, value); READ, pathIdVer, value);
this.sendLogsToThingsboard(msg, registration.getId()); this.sendLogsToThingsboard(msg, registration.getId());
rpcRequest.setValueMsg(String.format("%s", value)); rpcRequest.setValueMsg(String.format("%s", value));
this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE); this.sentRpcResponse(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
} }
/** /**
@ -351,7 +351,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
@Override @Override
public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) { public void onAttributeUpdate(AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) {
LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo);
if (msg.getSharedUpdatedCount() > 0) { if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) {
log.warn ("2) OnAttributeUpdate, SharedUpdatedList() [{}]", msg.getSharedUpdatedList());
msg.getSharedUpdatedList().forEach(tsKvProto -> { msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey(); String pathName = tsKvProto.getKv().getKey();
String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName);
@ -360,12 +361,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
&& (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion()))) && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentVersion())))
|| (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName) || (OtaPackageUtil.getAttributeKey(OtaPackageType.FIRMWARE, OtaPackageKey.TITLE).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentTitle())))) { && (!valueNew.equals(lwM2MClient.getFwUpdate().getCurrentTitle())))) {
this.getInfoFirmwareUpdate(lwM2MClient); this.getInfoFirmwareUpdate(lwM2MClient, null);
} else if ((OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName) } else if ((OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.VERSION).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentVersion()))) && (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentVersion())))
|| (OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName) || (OtaPackageUtil.getAttributeKey(OtaPackageType.SOFTWARE, OtaPackageKey.TITLE).equals(pathName)
&& (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentTitle())))) { && (!valueNew.equals(lwM2MClient.getSwUpdate().getCurrentTitle())))) {
this.getInfoSoftwareUpdate(lwM2MClient); this.getInfoSoftwareUpdate(lwM2MClient, null);
} }
if (pathIdVer != null) { if (pathIdVer != null) {
ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.config ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.config
@ -386,7 +387,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
} }
}); });
} else if (msg.getSharedDeletedCount() > 0) { } else if (msg.getSharedDeletedCount() > 0 && lwM2MClient != null) {
msg.getSharedUpdatedList().forEach(tsKvProto -> { msg.getSharedUpdatedList().forEach(tsKvProto -> {
String pathName = tsKvProto.getKv().getKey(); String pathName = tsKvProto.getKv().getKey();
Object valueNew = getValueFromKvProto(tsKvProto.getKv()); Object valueNew = getValueFromKvProto(tsKvProto.getKv());
@ -396,6 +397,9 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
}); });
log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo); log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo);
} }
else if (lwM2MClient == null) {
log.error ("OnAttributeUpdate, lwM2MClient is null");
}
} }
/** /**
@ -442,6 +446,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) { public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) {
// #1 // #1
this.checkRpcRequestTimeout(); this.checkRpcRequestTimeout();
log.warn ("4) toDeviceRpcRequestMsg: [{}], sessionUUID: [{}]", toDeviceRpcRequestMsg, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null"; String bodyParams = StringUtils.trimToNull(toDeviceRpcRequestMsg.getParams()) != null ? toDeviceRpcRequestMsg.getParams() : "null";
LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName()); LwM2mTypeOper lwM2mTypeOper = setValidTypeOper(toDeviceRpcRequestMsg.getMethodName());
UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB()); UUID requestUUID = new UUID(toDeviceRpcRequestMsg.getRequestIdMSB(), toDeviceRpcRequestMsg.getRequestIdLSB());
@ -478,7 +483,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove); rpcSubscriptionsToRemove.forEach(rpcSubscriptions::remove);
} }
public void sentRpcRequest(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { public void sentRpcResponse(Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) {
rpcRequest.setResponseCode(requestCode); rpcRequest.setResponseCode(requestCode);
if (LOG_LW2M_ERROR.equals(typeMsg)) { if (LOG_LW2M_ERROR.equals(typeMsg)) {
rpcRequest.setInfoMsg(null); rpcRequest.setInfoMsg(null);
@ -501,6 +506,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
@Override @Override
public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) { public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) {
log.warn ("5) onToDeviceRpcResponse: [{}], sessionUUID: [{}]", toDeviceResponse, new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()));
transportService.process(sessionInfo, toDeviceResponse, null); transportService.process(sessionInfo, toDeviceResponse, null);
} }
@ -881,10 +887,16 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
*/ */
private Object getResourceValueFormatKv(LwM2mClient lwM2MClient, String pathIdVer) { private Object getResourceValueFormatKv(LwM2mClient lwM2MClient, String pathIdVer) {
LwM2mResource resourceValue = this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer); LwM2mResource resourceValue = this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer);
ResourceModel.Type currentType = resourceValue.getType(); if (resourceValue != null) {
ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer); ResourceModel.Type currentType = resourceValue.getType();
return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer);
new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))); return this.converter.convertValue(resourceValue.getValue(), currentType, expectedType,
new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)));
}
else {
return null;
}
} }
/** /**
@ -1245,22 +1257,28 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
*/ */
public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { public void updateAttributeFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) {
LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo); LwM2mClient lwM2MClient = clientContext.getClient(sessionInfo);
tsKvProtos.forEach(tsKvProto -> { if (lwM2MClient != null) {
String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); log.warn("1) UpdateAttributeFromThingsboard, tsKvProtos [{}]", tsKvProtos);
if (pathIdVer != null) { tsKvProtos.forEach(tsKvProto -> {
// #1.1 String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey());
if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { if (pathIdVer != null) {
lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto); // #1.1
} else if (!lwM2MClient.getDelayedRequests().containsKey(pathIdVer)) { if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) {
lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto); lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
} else if (!lwM2MClient.getDelayedRequests().containsKey(pathIdVer)) {
lwM2MClient.getDelayedRequests().put(pathIdVer, tsKvProto);
}
} }
} });
}); // #2.1
// #2.1 lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> {
lwM2MClient.getDelayedRequests().forEach((pathIdVer, tsKvProto) -> { this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer),
this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), getValueFromKvProto(tsKvProto.getKv()), pathIdVer);
getValueFromKvProto(tsKvProto.getKv()), pathIdVer); });
}); }
else {
log.error("UpdateAttributeFromThingsboard, lwM2MClient is null");
}
} }
/** /**
@ -1339,20 +1357,28 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
} }
} }
public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient) { public void getInfoFirmwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) {
if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) { if (lwM2MClient.getRegistration().getSupportedVersion(FW_ID) != null) {
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
if (sessionInfo != null) { if (sessionInfo != null) {
transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()), DefaultLwM2MTransportMsgHandler handler = this;
this.transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.FIRMWARE.name()),
new TransportServiceCallback<>() { new TransportServiceCallback<>() {
@Override @Override
public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) {
if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())
&& response.getType().equals(OtaPackageType.FIRMWARE.name())) { && response.getType().equals(OtaPackageType.FIRMWARE.name())) {
log.warn ("7) firmware start with ver: [{}]", response.getVersion());
lwM2MClient.getFwUpdate().setRpcRequest(rpcRequest);
lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion());
lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle()); lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle());
lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); lwM2MClient.getFwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId());
lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest); if (rpcRequest == null) {
lwM2MClient.getFwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
}
else {
lwM2MClient.getFwUpdate().writeFwSwWare(handler, lwM2mTransportRequest);
}
} else { } else {
log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); log.trace("OtaPackage [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
} }
@ -1367,21 +1393,28 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
} }
} }
public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient) { public void getInfoSoftwareUpdate(LwM2mClient lwM2MClient, Lwm2mClientRpcRequest rpcRequest) {
if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) { if (lwM2MClient.getRegistration().getSupportedVersion(SW_ID) != null) {
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient); SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(lwM2MClient);
if (sessionInfo != null) { if (sessionInfo != null) {
DefaultLwM2MTransportMsgHandler serviceImpl = this; DefaultLwM2MTransportMsgHandler handler = this;
transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()), transportService.process(sessionInfo, createOtaPackageRequestMsg(sessionInfo, OtaPackageType.SOFTWARE.name()),
new TransportServiceCallback<>() { new TransportServiceCallback<>() {
@Override @Override
public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) { public void onSuccess(TransportProtos.GetOtaPackageResponseMsg response) {
if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus()) if (TransportProtos.ResponseStatus.SUCCESS.equals(response.getResponseStatus())
&& response.getType().equals(OtaPackageType.SOFTWARE.name())) { && response.getType().equals(OtaPackageType.SOFTWARE.name())) {
lwM2MClient.getSwUpdate().setRpcRequest(rpcRequest);
lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion()); lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion());
lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle()); lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle());
lwM2MClient.getSwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId()); lwM2MClient.getSwUpdate().setCurrentId(new OtaPackageId(new UUID(response.getOtaPackageIdMSB(), response.getOtaPackageIdLSB())).getId());
lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest); lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
if (rpcRequest == null) {
lwM2MClient.getSwUpdate().sendReadObserveInfo(lwM2mTransportRequest);
}
else {
lwM2MClient.getSwUpdate().writeFwSwWare(handler, lwM2mTransportRequest);
}
} else { } else {
log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString()); log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
} }

148
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportRequest.java

@ -82,10 +82,8 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
@ -134,7 +132,7 @@ public class LwM2mTransportRequest {
ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT;
LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration); LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration);
LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null;
if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) { if (!OBSERVE_CANCEL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) {
if (lwM2MClient.isValidObjectVersion(targetIdVer)) { if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
DownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target, DownlinkRequest request = createRequest(registration, lwM2MClient, typeOper, contentFormat, target,
@ -153,47 +151,66 @@ public class LwM2mTransportRequest {
} else if (WRITE_UPDATE.name().equals(typeOper.name())) { } else if (WRITE_UPDATE.name().equals(typeOper.name())) {
if (lwm2mClientRpcRequest != null) { if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s params is not valid", targetIdVer); String errorMsg = String.format("Path %s params is not valid", targetIdVer);
handler.sentRpcRequest(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
} }
} else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) { } else if (WRITE_REPLACE.name().equals(typeOper.name()) || EXECUTE.name().equals(typeOper.name())) {
if (lwm2mClientRpcRequest != null) { if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s object model is absent", targetIdVer); String errorMsg = String.format("Path %s object model is absent", targetIdVer);
handler.sentRpcRequest(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); handler.sentRpcResponse(lwm2mClientRpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
} }
} else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) { } else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) {
log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer); log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer);
if (lwm2mClientRpcRequest != null) { if (lwm2mClientRpcRequest != null) {
ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()); ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null";
this.handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
} }
} }
} else if (lwm2mClientRpcRequest != null) { } else if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s not found in object version", targetIdVer); String errorMsg = String.format("Path %s not found in object version", targetIdVer);
this.handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); this.handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
} }
} else if (OBSERVE_READ_ALL.name().equals(typeOper.name()) || DISCOVER_ALL.name().equals(typeOper.name())) { } else {
Set<String> paths; switch (typeOper) {
if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { case OBSERVE_READ_ALL:
Set<Observation> observations = context.getServer().getObservationService().getObservations(registration); case DISCOVER_ALL:
paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); Set<String> paths;
} else { if (OBSERVE_READ_ALL.name().equals(typeOper.name())) {
assert registration != null; Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
Link[] objectLinks = registration.getSortedObjectLinks(); paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet());
paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet()); } else {
} assert registration != null;
String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO, Link[] objectLinks = registration.getSortedObjectLinks();
typeOper.name(), paths); paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet());
this.handler.sendLogsToThingsboard(msg, registration.getId()); }
if (lwm2mClientRpcRequest != null) { String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO,
String valueMsg = String.format("Paths - %s", paths); typeOper.name(), paths);
this.handler.sentRpcRequest(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); this.handler.sendLogsToThingsboard(msg, registration.getId());
if (lwm2mClientRpcRequest != null) {
String valueMsg = String.format("Paths - %s", paths);
this.handler.sentRpcResponse(lwm2mClientRpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE);
}
break;
case OBSERVE_CANCEL:
case OBSERVE_CANCEL_ALL:
int observeCancelCnt = 0;
String observeCancelMsg = null;
if (OBSERVE_CANCEL.name().equals(typeOper)) {
observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target);
observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO,
OBSERVE_CANCEL.name(), target, observeCancelCnt);
} else {
observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration);
observeCancelMsg = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO,
OBSERVE_CANCEL.name(), observeCancelCnt);
}
this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, lwm2mClientRpcRequest);
break;
// lwm2mClientRpcRequest != null
case FW_UPDATE:
this.handler.getInfoFirmwareUpdate(lwM2MClient, lwm2mClientRpcRequest);
break;
} }
} else if (OBSERVE_CANCEL_ALL.name().equals(typeOper.name())) {
int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration);
String observeCancelMsgAll = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO,
OBSERVE_CANCEL.name(), observeCancelCnt);
this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsgAll, lwm2mClientRpcRequest);
} }
} catch (Exception e) { } catch (Exception e) {
String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR,
@ -201,7 +218,7 @@ public class LwM2mTransportRequest {
handler.sendLogsToThingsboard(msg, registration.getId()); handler.sendLogsToThingsboard(msg, registration.getId());
if (lwm2mClientRpcRequest != null) { if (lwm2mClientRpcRequest != null) {
String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage()); String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage());
handler.sentRpcRequest(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); handler.sentRpcResponse(lwm2mClientRpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
} }
} }
} }
@ -234,17 +251,6 @@ public class LwM2mTransportRequest {
request = new ObserveRequest(contentFormat, resultIds.getObjectId()); request = new ObserveRequest(contentFormat, resultIds.getObjectId());
} }
break; break;
case OBSERVE_CANCEL:
/*
lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
At server side this will not remove the observation from the observation store, to do it you need to use
{@code ObservationService#cancelObservation()}
*/
int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target);
String observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO,
OBSERVE_CANCEL.name(), target, observeCancelCnt);
this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, rpcRequest);
break;
case EXECUTE: case EXECUTE:
ResourceModel resourceModelExecute = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()); ResourceModel resourceModelExecute = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
if (resourceModelExecute != null) { if (resourceModelExecute != null) {
@ -343,7 +349,7 @@ public class LwM2mTransportRequest {
} }
/** Not Found */ /** Not Found */
if (rpcRequest != null) { if (rpcRequest != null) {
handler.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
} }
/** Not Found /** Not Found
set setClient_fw_info... = empty set setClient_fw_info... = empty
@ -385,7 +391,7 @@ public class LwM2mTransportRequest {
handler.sendLogsToThingsboard(msg, registration.getId()); handler.sendLogsToThingsboard(msg, registration.getId());
log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString()); log.error("[{}] [{}] - [{}] error SendRequest", request.getClass().getName().toString(), request.getPath().toString(), e.toString());
if (rpcRequest != null) { if (rpcRequest != null) {
handler.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); handler.sentRpcResponse(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR);
} }
}); });
} }
@ -431,7 +437,7 @@ public class LwM2mTransportRequest {
log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString());
if (rpcRequest != null) { if (rpcRequest != null) {
String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value);
handler.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); handler.sentRpcResponse(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
} }
return null; return null;
} }
@ -462,44 +468,48 @@ public class LwM2mTransportRequest {
if (response instanceof ReadResponse) { if (response instanceof ReadResponse) {
handler.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); handler.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest);
} else if (response instanceof DeleteResponse) { } else if (response instanceof DeleteResponse) {
log.warn("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); log.warn("11) [{}] Path [{}] DeleteResponse", pathIdVer, response);
if (rpcRequest != null) {
rpcRequest.setInfoMsg(null);
handler.sentRpcResponse(rpcRequest, response.getCode().getName(), null, null);
}
} else if (response instanceof DiscoverResponse) { } else if (response instanceof DiscoverResponse) {
String discoverValue = Link.serialize(((DiscoverResponse)response).getObjectLinks()); String discoverValue = Link.serialize(((DiscoverResponse) response).getObjectLinks());
msgLog = String.format("%s: type operation: %s path: %s value: %s", msgLog = String.format("%s: type operation: %s path: %s value: %s",
LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue); LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue);
handler.sendLogsToThingsboard(msgLog, registration.getId()); handler.sendLogsToThingsboard(msgLog, registration.getId());
log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response); log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response);
if (rpcRequest != null) { if (rpcRequest != null) {
handler.sentRpcRequest(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE); handler.sentRpcResponse(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE);
} }
} else if (response instanceof ExecuteResponse) { } else if (response instanceof ExecuteResponse) {
log.warn("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); msgLog = String.format("%s: type operation: %s path: %s",
LOG_LW2M_INFO, EXECUTE.name(), request.getPath().toString());
log.warn("9) [{}] ", msgLog);
handler.sendLogsToThingsboard(msgLog, registration.getId());
if (rpcRequest != null) {
msgLog = String.format("Start %s path: %S. Preparation finished: %s", EXECUTE.name(), path, rpcRequest.getInfoMsg());
rpcRequest.setInfoMsg(msgLog);
handler.sentRpcResponse(rpcRequest, response.getCode().getName(), path, LOG_LW2M_INFO);
}
} else if (response instanceof WriteAttributesResponse) { } else if (response instanceof WriteAttributesResponse) {
msgLog = String.format("%s: type operation: %s path: %s value: %s", msgLog = String.format("%s: type operation: %s path: %s value: %s",
LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString()); LOG_LW2M_INFO, WRITE_ATTRIBUTES.name(), request.getPath().toString(), ((WriteAttributesRequest) request).getAttributes().toString());
handler.sendLogsToThingsboard(msgLog, registration.getId()); handler.sendLogsToThingsboard(msgLog, registration.getId());
log.warn("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response); log.warn("12) [{}] Path [{}] WriteAttributesResponse", pathIdVer, response);
if (rpcRequest != null) { if (rpcRequest != null) {
handler.sentRpcRequest(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE); handler.sentRpcResponse(rpcRequest, response.getCode().getName(), response.toString(), LOG_LW2M_VALUE);
} }
} else if (response instanceof WriteResponse) { } else if (response instanceof WriteResponse) {
log.warn("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response); msgLog = String.format("Type operation: Write path: %s", pathIdVer);
this.infoWriteResponse(registration, response, request); log.warn("10) [{}] response: [{}]", msgLog, response);
this.infoWriteResponse(registration, response, request, rpcRequest);
handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); handler.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request);
} }
if (rpcRequest != null) {
if (response instanceof ExecuteResponse
|| response instanceof WriteAttributesResponse
|| response instanceof DeleteResponse) {
rpcRequest.setInfoMsg(null);
handler.sentRpcRequest(rpcRequest, response.getCode().getName(), null, null);
} else if (response instanceof WriteResponse) {
handler.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO);
}
}
} }
private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request) { private void infoWriteResponse(Registration registration, LwM2mResponse response, DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
try { try {
LwM2mNode node = ((WriteRequest) request).getNode(); LwM2mNode node = ((WriteRequest) request).getNode();
String msg = null; String msg = null;
@ -517,12 +527,12 @@ public class LwM2mTransportRequest {
if (singleResource.getType() == ResourceModel.Type.STRING) { if (singleResource.getType() == ResourceModel.Type.STRING) {
valueLength = ((String) singleResource.getValue()).length(); valueLength = ((String) singleResource.getValue()).length();
value = ((String) singleResource.getValue()) value = ((String) singleResource.getValue())
.substring(Math.min(valueLength, config.getLogMaxLength())); .substring(Math.min(valueLength, config.getLogMaxLength())).trim();
} else { } else {
valueLength = ((byte[]) singleResource.getValue()).length; valueLength = ((byte[]) singleResource.getValue()).length;
value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()), value = new String(Arrays.copyOf(((byte[]) singleResource.getValue()),
Math.min(valueLength, config.getLogMaxLength()))); Math.min(valueLength, config.getLogMaxLength()))).trim();
} }
value = valueLength > config.getLogMaxLength() ? value + "..." : value; value = valueLength > config.getLogMaxLength() ? value + "..." : value;
msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s", msg = String.format("%s: Update finished successfully: Lwm2m code - %d Resource path: %s length: %s value: %s",
@ -538,6 +548,12 @@ public class LwM2mTransportRequest {
handler.sendLogsToThingsboard(msg, registration.getId()); handler.sendLogsToThingsboard(msg, registration.getId());
if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) { if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) {
this.afterWriteSuccessFwSwUpdate(registration, request); this.afterWriteSuccessFwSwUpdate(registration, request);
if (rpcRequest != null) {
rpcRequest.setInfoMsg(msg);
}
}
else if (rpcRequest != null) {
handler.sentRpcResponse(rpcRequest, response.getCode().getName(), msg, LOG_LW2M_INFO);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@ -558,7 +574,7 @@ public class LwM2mTransportRequest {
} }
if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) { if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) {
lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name()); lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name());
lwM2MClient.getSwUpdate().sendLogs(this.handler,WRITE_REPLACE.name(), LOG_LW2M_INFO, null); lwM2MClient.getSwUpdate().sendLogs(this.handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
} }
} }
@ -592,7 +608,7 @@ public class LwM2mTransportRequest {
log.warn("[{}]", observeCancelMsg); log.warn("[{}]", observeCancelMsg);
if (rpcRequest != null) { if (rpcRequest != null) {
rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt)); rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt));
handler.sentRpcRequest(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO); handler.sentRpcResponse(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO);
} }
} }
} }

11
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportServerHelper.java

@ -53,6 +53,8 @@ import java.io.ByteArrayInputStream;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V; import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V;
@ -63,7 +65,12 @@ import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.
public class LwM2mTransportServerHelper { public class LwM2mTransportServerHelper {
private final LwM2mTransportContext context; private final LwM2mTransportContext context;
private final LwM2MJsonAdaptor adaptor; private final AtomicInteger atomicTs = new AtomicInteger(0);
public long getTS() {
return TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) * 1000L + (atomicTs.getAndIncrement() % 1000);
}
/** /**
* send to Thingsboard Attribute || Telemetry * send to Thingsboard Attribute || Telemetry
@ -96,7 +103,7 @@ public class LwM2mTransportServerHelper {
public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) { public void sendParametersOnThingsboardTelemetry(List<TransportProtos.KeyValueProto> result, SessionInfoProto sessionInfo) {
PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder(); PostTelemetryMsg.Builder request = PostTelemetryMsg.newBuilder();
TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder(); TransportProtos.TsKvListProto.Builder builder = TransportProtos.TsKvListProto.newBuilder();
builder.setTs(System.currentTimeMillis()); builder.setTs(this.getTS());
builder.addAllKv(result); builder.addAllKv(result);
request.addTsKvList(builder.build()); request.addTsKvList(builder.build());
PostTelemetryMsg postTelemetryMsg = request.build(); PostTelemetryMsg postTelemetryMsg = request.build();

5
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mTransportUtil.java

@ -229,11 +229,12 @@ public class LwM2mTransportUtil {
*/ */
WRITE_UPDATE(9, "WriteUpdate"), WRITE_UPDATE(9, "WriteUpdate"),
WRITE_ATTRIBUTES(10, "WriteAttributes"), WRITE_ATTRIBUTES(10, "WriteAttributes"),
DELETE(11, "Delete"); DELETE(11, "Delete"),
// only for RPC // only for RPC
FW_UPDATE(12,"FirmwareUpdate");
// FW_READ_INFO(12, "FirmwareReadInfo"), // FW_READ_INFO(12, "FirmwareReadInfo"),
// FW_UPDATE(13, "FirmwareUpdate"),
// SW_READ_INFO(15, "SoftwareReadInfo"), // SW_READ_INFO(15, "SoftwareReadInfo"),
// SW_UPDATE(16, "SoftwareUpdate"), // SW_UPDATE(16, "SoftwareUpdate"),
// SW_UNINSTALL(18, "SoftwareUninstall"); // SW_UNINSTALL(18, "SoftwareUninstall");

8
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java

@ -83,11 +83,17 @@ public class LwM2mClientContextImpl implements LwM2mClientContext {
@Override @Override
public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) { public LwM2mClient getClient(TransportProtos.SessionInfoProto sessionInfo) {
return lwM2mClientsByEndpoint.values().stream().filter(c -> LwM2mClient lwM2mClient = lwM2mClientsByEndpoint.values().stream().filter(c ->
(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())) (new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()))
.equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB()))) .equals((new UUID(c.getSession().getSessionIdMSB(), c.getSession().getSessionIdLSB())))
).findAny().get(); ).findAny().get();
if (lwM2mClient == null) {
log.warn("Device TimeOut? lwM2mClient is null.");
log.warn("SessionInfo input [{}], lwM2mClientsByEndpoint size: [{}]", sessionInfo, lwM2mClientsByEndpoint.values().size());
log.error("", new RuntimeException());
}
return lwM2mClient;
} }
@Override @Override

41
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mFwSwUpdate.java

@ -37,6 +37,7 @@ import static org.thingsboard.server.common.data.ota.OtaPackageType.FIRMWARE;
import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE; import static org.thingsboard.server.common.data.ota.OtaPackageType.SOFTWARE;
import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING; import static org.thingsboard.server.common.data.ota.OtaPackageUpdateStatus.UPDATING;
import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey; import static org.thingsboard.server.common.data.ota.OtaPackageUtil.getAttributeKey;
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID;
@ -103,6 +104,9 @@ public class LwM2mFwSwUpdate {
@Getter @Getter
@Setter @Setter
private final List<String> pendingInfoRequestsStart; private final List<String> pendingInfoRequestsStart;
@Getter
@Setter
private volatile Lwm2mClientRpcRequest rpcRequest;
public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) { public LwM2mFwSwUpdate(LwM2mClient lwM2MClient, OtaPackageType type) {
this.lwM2MClient = lwM2MClient; this.lwM2MClient = lwM2MClient;
@ -153,16 +157,29 @@ public class LwM2mFwSwUpdate {
* Send FsSw to Lwm2mClient: * Send FsSw to Lwm2mClient:
* before operation Write: fw_state = DOWNLOADING * before operation Write: fw_state = DOWNLOADING
*/ */
private void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) { public void writeFwSwWare(DefaultLwM2MTransportMsgHandler handler, LwM2mTransportRequest request) {
this.stateUpdate = OtaPackageUpdateStatus.DOWNLOADING.name(); if (this.currentId != null) {
// this.observeStateUpdate(); this.stateUpdate = OtaPackageUpdateStatus.DOWNLOADING.name();
this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null); this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
int chunkSize = 0; int chunkSize = 0;
int chunk = 0; int chunk = 0;
byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk); byte[] firmwareChunk = handler.otaPackageDataCache.get(this.currentId.toString(), chunkSize, chunk);
String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration()); String targetIdVer = convertPathFromObjectIdToIdVer(this.pathPackageId, this.lwM2MClient.getRegistration());
request.sendAllRequest(lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(), String fwMsg = String.format("%s: Start type operation %s paths: %s", LOG_LW2M_INFO,
firmwareChunk, handler.config.getTimeout(), null); LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE.name(), FW_PACKAGE_ID);
handler.sendLogsToThingsboard(fwMsg, lwM2MClient.getRegistration().getId());
log.warn("8) Start firmware Update. Send save to: [{}] ver: [{}] path: [{}]", this.lwM2MClient.getDeviceName(), this.currentVersion, targetIdVer);
request.sendAllRequest(this.lwM2MClient.getRegistration(), targetIdVer, WRITE_REPLACE, ContentFormat.OPAQUE.getName(),
firmwareChunk, handler.config.getTimeout(), this.rpcRequest);
} else {
String msgError = "FirmWareId is null.";
log.warn("6) [{}]", msgError);
if (this.rpcRequest != null) {
handler.sentRpcResponse(this.rpcRequest, CONTENT.name(), msgError, LOG_LW2M_ERROR);
}
log.error (msgError);
this.sendLogs(handler, WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
}
} }
public void sendLogs(DefaultLwM2MTransportMsgHandler handler, String typeOper, String typeInfo, String msgError) { public void sendLogs(DefaultLwM2MTransportMsgHandler handler, String typeOper, String typeInfo, String msgError) {
@ -185,7 +202,7 @@ public class LwM2mFwSwUpdate {
this.setStateUpdate(UPDATING.name()); this.setStateUpdate(UPDATING.name());
this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null); this.sendLogs(handler, EXECUTE.name(), LOG_LW2M_INFO, null);
request.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(), request.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(),
null, 0, null); null, 0, this.rpcRequest);
} }
/** /**
@ -347,7 +364,7 @@ public class LwM2mFwSwUpdate {
this.pathResultId, this.lwM2MClient.getRegistration())); this.pathResultId, this.lwM2MClient.getRegistration()));
this.pendingInfoRequestsStart.forEach(pathIdVer -> { this.pendingInfoRequestsStart.forEach(pathIdVer -> {
request.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(), request.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(),
null, 0, null); null, 0, this.rpcRequest);
}); });
} }

4
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/Lwm2mClientRpcRequest.java

@ -39,6 +39,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.K
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.FW_UPDATE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES; import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_ATTRIBUTES;
@ -140,7 +141,8 @@ public class Lwm2mClientRpcRequest {
if (this.getTargetIdVer() == null if (this.getTargetIdVer() == null
&& !(OBSERVE_READ_ALL == this.getTypeOper() && !(OBSERVE_READ_ALL == this.getTypeOper()
|| DISCOVER_ALL == this.getTypeOper() || DISCOVER_ALL == this.getTypeOper()
|| OBSERVE_CANCEL == this.getTypeOper())) { || OBSERVE_CANCEL == this.getTypeOper()
|| FW_UPDATE == this.getTypeOper())) {
this.setErrorMsg(TARGET_ID_VER_KEY + " and " + this.setErrorMsg(TARGET_ID_VER_KEY + " and " +
KEY_NAME_KEY + " is null or bad format"); KEY_NAME_KEY + " is null or bad format");
} }

3
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java

@ -43,6 +43,9 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
@Override @Override
public Object convertValue(Object value, Type currentType, Type expectedType, LwM2mPath resourcePath) public Object convertValue(Object value, Type currentType, Type expectedType, LwM2mPath resourcePath)
throws CodecException { throws CodecException {
if (value == null) {
return null;
}
if (expectedType == null) { if (expectedType == null) {
/** unknown resource, trusted value */ /** unknown resource, trusted value */
return value; return value;

Loading…
Cancel
Save