lwm2m: refactoring SW with unInstall (argument is 1) -> "ForUpdate"

This commit is contained in:
nickAS21 2025-04-15 15:04:17 +03:00
parent 94be11b458
commit fea2d7e4a3
4 changed files with 60 additions and 39 deletions

View File

@ -114,15 +114,6 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
public static final String FW_RESULT_ID = "/5/0/5"; public static final String FW_RESULT_ID = "/5/0/5";
public static final String FW_NAME_ID = "/5/0/6"; public static final String FW_NAME_ID = "/5/0/6";
public static final String FW_VER_ID = "/5/0/7"; public static final String FW_VER_ID = "/5/0/7";
public static final int FW_INSTANCE_ID = 65533;
public static final String FW_INFO_19_INSTANCE_ID = "/19/" + FW_INSTANCE_ID;
public static final int SW_INSTANCE_ID = 65534;
public static final String SW_INFO_19_INSTANCE_ID = "/19/" + SW_INSTANCE_ID;
public static final String OTA_INFO_19_TITLE = "title";
public static final String OTA_INFO_19_VERSION = "version";
public static final String OTA_INFO_19_FILE_CHECKSUM256 = "checksum";
public static final String OTA_INFO_19_FILE_SIZE = "dataSize";
public static final String OTA_INFO_19_FILE_NAME = "fileName";
public static final String FW_3_VER_ID = "/3/0/3"; public static final String FW_3_VER_ID = "/3/0/3";
public static final String FW_DELIVERY_METHOD = "/5/0/9"; public static final String FW_DELIVERY_METHOD = "/5/0/9";
@ -138,6 +129,16 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
public static final String SW_RESULT_ID = "/9/0/9"; public static final String SW_RESULT_ID = "/9/0/9";
public static final String SW_UN_INSTALL_ID = "/9/0/6"; public static final String SW_UN_INSTALL_ID = "/9/0/6";
public static final int FW_INSTANCE_ID = 65533;
public static final String FW_INFO_19_INSTANCE_ID = "/19/" + FW_INSTANCE_ID;
public static final int SW_INSTANCE_ID = 65534;
public static final String SW_INFO_19_INSTANCE_ID = "/19/" + SW_INSTANCE_ID;
public static final String OTA_INFO_19_TITLE = "title";
public static final String OTA_INFO_19_VERSION = "version";
public static final String OTA_INFO_19_FILE_CHECKSUM256 = "checksum";
public static final String OTA_INFO_19_FILE_SIZE = "dataSize";
public static final String OTA_INFO_19_FILE_NAME = "fileName";
private final Map<String, LwM2MClientFwOtaInfo> fwStates = new ConcurrentHashMap<>(); private final Map<String, LwM2MClientFwOtaInfo> fwStates = new ConcurrentHashMap<>();
private final Map<String, LwM2MClientSwOtaInfo> swStates = new ConcurrentHashMap<>(); private final Map<String, LwM2MClientSwOtaInfo> swStates = new ConcurrentHashMap<>();
@ -529,7 +530,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
} }
Boolean useObject19ForOta = clientContext.getProfile(client.getProfileId()).getClientLwM2mSettings().getUseObject19ForOta(); Boolean useObject19ForOta = clientContext.getProfile(client.getProfileId()).getClientLwM2mSettings().getUseObject19ForOta();
if (useObject19ForOta != null && useObject19ForOta){ if (useObject19ForOta != null && useObject19ForOta){
sendInfoFwToObject19ForOta(client, convertObjectIdToVersionedId(FW_INFO_19_INSTANCE_ID, client), response, otaPackageId); sendInfoToObject19ForOta(client, FW_INFO_19_INSTANCE_ID, response, otaPackageId);
} }
switch (strategy) { switch (strategy) {
case OBJ_5_BINARY: case OBJ_5_BINARY:
@ -555,7 +556,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
LwM2MSoftwareUpdateStrategy strategy = info.getStrategy(); LwM2MSoftwareUpdateStrategy strategy = info.getStrategy();
Boolean useObject19ForOta = clientContext.getProfile(client.getProfileId()).getClientLwM2mSettings().getUseObject19ForOta(); Boolean useObject19ForOta = clientContext.getProfile(client.getProfileId()).getClientLwM2mSettings().getUseObject19ForOta();
if (useObject19ForOta != null && useObject19ForOta){ if (useObject19ForOta != null && useObject19ForOta){
sendInfoFwToObject19ForOta(client, convertObjectIdToVersionedId(SW_INFO_19_INSTANCE_ID, client), response, otaPackageId); sendInfoToObject19ForOta(client, SW_INFO_19_INSTANCE_ID, response, otaPackageId);
} }
switch (strategy) { switch (strategy) {
case BINARY: case BINARY:
@ -591,21 +592,24 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
} }
private void executeFwUpdate(LwM2mClient client) { private void executeFwUpdate(LwM2mClient client) {
log.trace("[{}] Execute SW [{}]", client.getEndpoint(), FW_EXECUTE_ID);
String fwExecuteVerId = convertObjectIdToVersionedId(FW_EXECUTE_ID, client); String fwExecuteVerId = convertObjectIdToVersionedId(FW_EXECUTE_ID, client);
TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(fwExecuteVerId).timeout(clientContext.getRequestTimeout(client)).build(); TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(fwExecuteVerId).timeout(clientContext.getRequestTimeout(client)).build();
downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, fwExecuteVerId)); downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, fwExecuteVerId));
} }
private void executeSwInstall(LwM2mClient client) { private void executeSwInstall(LwM2mClient client) {
log.trace("[{}] Execute SW (install) [{}]", client.getEndpoint(), SW_INSTALL_ID);
String swInstallVerId = convertObjectIdToVersionedId(SW_INSTALL_ID, client); String swInstallVerId = convertObjectIdToVersionedId(SW_INSTALL_ID, client);
TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(swInstallVerId).timeout(clientContext.getRequestTimeout(client)).build(); TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(swInstallVerId).timeout(clientContext.getRequestTimeout(client)).build();
downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, swInstallVerId)); downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, swInstallVerId));
} }
private void executeSwUninstallForUpdate(LwM2mClient client) { private void executeSwUninstallForUpdate(LwM2mClient client) {
String swInInstallVerId = convertObjectIdToVersionedId(SW_UN_INSTALL_ID, client); log.trace("[{}] Execute SW (uninstall with params(\"1\") ) [{}]", client.getEndpoint(), SW_UN_INSTALL_ID);
TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(swInInstallVerId).params("1").timeout(clientContext.getRequestTimeout(client)).build(); String swUnInstallVerId = convertObjectIdToVersionedId(SW_UN_INSTALL_ID, client);
downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, swInInstallVerId)); TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest.builder().versionedId(swUnInstallVerId).params("1").timeout(clientContext.getRequestTimeout(client)).build();
downlinkHandler.sendExecuteRequest(client, request, new TbLwM2MExecuteCallback(logService, client, swUnInstallVerId));
} }
private Optional<String> getAttributeValue(List<TransportProtos.TsKvProto> attrs, String keyName) { private Optional<String> getAttributeValue(List<TransportProtos.TsKvProto> attrs, String keyName) {
@ -675,36 +679,37 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
* "fileSize":59832. * "fileSize":59832.
* "fileName" : "BC68JAR01A10_TO_BC68JAR01A09_09.bin" } * "fileName" : "BC68JAR01A10_TO_BC68JAR01A09_09.bin" }
* @param client * @param client
* @param targetIdVer * @param targetId
* @param response * @param response
* @param otaPackageId * @param otaPackageId
*/ */
private void sendInfoFwToObject19ForOta(LwM2mClient client, String targetIdVer, TransportProtos.GetOtaPackageResponseMsg response, UUID otaPackageId) { private void sendInfoToObject19ForOta(LwM2mClient client, String targetId, TransportProtos.GetOtaPackageResponseMsg response, UUID otaPackageId) {
log.trace("[{}] Current info fw toObject19ForOta", client.getEndpoint()); log.trace("[{}] Current info ota toObject19ForOta [{}]", client.getEndpoint(), targetId);
String targetIdVer = convertObjectIdToVersionedId(targetId, client);
ObjectModel objectModel = client.getObjectModel(targetIdVer, modelProvider); ObjectModel objectModel = client.getObjectModel(targetIdVer, modelProvider);
if (objectModel != null) { if (objectModel != null) {
try { try {
if (client.getRegistration().getSupportedObject().get(19) != null) { if (client.getRegistration().getSupportedObject().get(19) != null) {
ObjectNode objectNodeInfoFw = JacksonUtil.newObjectNode(); ObjectNode objectNodeInfoOta = JacksonUtil.newObjectNode();
byte[] firmwareChunk = otaPackageDataCache.get(otaPackageId.toString(), 0, 0); byte[] firmwareChunk = otaPackageDataCache.get(otaPackageId.toString(), 0, 0);
String fileChecksumSHA256 = Hashing.sha256().hashBytes(firmwareChunk).toString(); String fileChecksumSHA256 = Hashing.sha256().hashBytes(firmwareChunk).toString();
objectNodeInfoFw.put(OTA_INFO_19_TITLE, response.getTitle()); objectNodeInfoOta.put(OTA_INFO_19_TITLE, response.getTitle());
objectNodeInfoFw.put(OTA_INFO_19_VERSION, response.getVersion()); objectNodeInfoOta.put(OTA_INFO_19_VERSION, response.getVersion());
objectNodeInfoFw.put(OTA_INFO_19_FILE_CHECKSUM256, fileChecksumSHA256); objectNodeInfoOta.put(OTA_INFO_19_FILE_CHECKSUM256, fileChecksumSHA256);
objectNodeInfoFw.put(OTA_INFO_19_FILE_SIZE, firmwareChunk.length); objectNodeInfoOta.put(OTA_INFO_19_FILE_SIZE, firmwareChunk.length);
objectNodeInfoFw.put(OTA_INFO_19_FILE_NAME, response.getFileName()); objectNodeInfoOta.put(OTA_INFO_19_FILE_NAME, response.getFileName());
String objectNodeInfoFwStr = JacksonUtil.toString(objectNodeInfoFw); String objectNodeInfoOtaStr = JacksonUtil.toString(objectNodeInfoOta);
assert objectNodeInfoFwStr != null; assert objectNodeInfoOtaStr != null;
String objectNodeInfoFwBase64 = Base64.getEncoder().encodeToString(objectNodeInfoFwStr.getBytes()); String objectNodeInfoOtaBase64 = Base64.getEncoder().encodeToString(objectNodeInfoOtaStr.getBytes());
LwM2mPath pathFwInstance = new LwM2mPath(FW_INFO_19_INSTANCE_ID); LwM2mPath pathOtaInstance = new LwM2mPath(targetId);
if (client.getRegistration().getAvailableInstances().contains(pathFwInstance)) { if (client.getRegistration().getAvailableInstances().contains(pathOtaInstance)) {
String versionId = targetIdVer + "/0/0"; String versionId = targetIdVer + "/0/0";
TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionId).value(objectNodeInfoFwBase64).timeout(clientContext.getRequestTimeout(client)).build(); TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest.builder().versionedId(versionId).value(objectNodeInfoOtaBase64).timeout(clientContext.getRequestTimeout(client)).build();
downlinkHandler.sendWriteReplaceRequest(client, request, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, client, versionId)); downlinkHandler.sendWriteReplaceRequest(client, request, new TbLwM2MWriteResponseCallback(uplinkHandler, logService, client, versionId));
} else { } else {
String valueResourcesStr = "{\"" + 0 + "\":{\"0\":\"" + objectNodeInfoFwBase64 + "\"}}"; String valueResourcesStr = "{\"" + 0 + "\":{\"0\":\"" + objectNodeInfoOtaBase64 + "\"}}";
String valueStr = "{\"id\":\"" + targetIdVer + "\",\"value\":" + valueResourcesStr + "}"; String valueStr = "{\"id\":\"" + targetIdVer + "\",\"value\":" + valueResourcesStr + "}";
RpcCreateRequest requestBody = JacksonUtil.fromString(valueStr, RpcCreateRequest.class); RpcCreateRequest requestBody = JacksonUtil.fromString(valueStr, RpcCreateRequest.class);
assert requestBody != null; assert requestBody != null;
@ -713,8 +718,8 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
downlinkHandler.sendCreateRequest(client, builder.build(), new TbLwM2MCreateResponseCallback(uplinkHandler, logService, client, targetIdVer)); downlinkHandler.sendCreateRequest(client, builder.build(), new TbLwM2MCreateResponseCallback(uplinkHandler, logService, client, targetIdVer));
} }
} else { } else {
String errorMsg = "Failed to send Info Fw to object 19. The client does not have object 19."; String errorMsg = String.format("[%s], Failed to send Info Ota to objectInstance [%s]. The client does not have object 19.", client.getEndpoint(), targetId);
log.trace("[{}] {}", client.getEndpoint(), errorMsg); log.trace(errorMsg);
logService.log(client, errorMsg); logService.log(client, errorMsg);
} }
} catch (Exception e){ } catch (Exception e){

View File

@ -23,6 +23,9 @@ import lombok.ToString;
import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo;
import static org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateResult.UPDATE_SUCCESSFULLY;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@NoArgsConstructor @NoArgsConstructor
@ -43,6 +46,11 @@ public class LwM2MClientFwOtaInfo extends LwM2MClientOtaInfo<LwM2MFirmwareUpdate
public void update(FirmwareUpdateResult result) { public void update(FirmwareUpdateResult result) {
this.result = result; this.result = result;
if (result.getCode() > UPDATE_SUCCESSFULLY.getCode()) {
failedPackageId = getPackageId(targetName, targetVersion);
}
switch (result) { switch (result) {
case INITIAL: case INITIAL:
break; break;
@ -50,7 +58,6 @@ public class LwM2MClientFwOtaInfo extends LwM2MClientOtaInfo<LwM2MFirmwareUpdate
retryAttempts = 0; retryAttempts = 0;
break; break;
default: default:
failedPackageId = getPackageId(targetName, targetVersion);
break; break;
} }
} }

View File

@ -23,6 +23,8 @@ import lombok.ToString;
import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.ota.OtaPackageType;
import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo; import org.thingsboard.server.transport.lwm2m.server.ota.LwM2MClientOtaInfo;
import static org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdateResult.NOT_ENOUGH_STORAGE;
@Data @Data
@EqualsAndHashCode(callSuper = true) @EqualsAndHashCode(callSuper = true)
@NoArgsConstructor @NoArgsConstructor
@ -42,12 +44,17 @@ public class LwM2MClientSwOtaInfo extends LwM2MClientOtaInfo<LwM2MSoftwareUpdate
public void update(SoftwareUpdateResult result) { public void update(SoftwareUpdateResult result) {
this.result = result; this.result = result;
if (result.getCode() >= NOT_ENOUGH_STORAGE.getCode()) {
failedPackageId = getPackageId(targetName, targetVersion);
}
switch (result) { switch (result) {
case INITIAL: case INITIAL:
break; break;
//TODO: implement case SUCCESSFULLY_INSTALLED:
retryAttempts = 0;
break;
default: default:
failedPackageId = getPackageId(targetName, targetVersion);
break; break;
} }
} }

View File

@ -31,6 +31,7 @@ import java.text.SimpleDateFormat;
import java.util.Base64; import java.util.Base64;
import java.util.Date; import java.util.Date;
import static org.eclipse.leshan.core.model.ResourceModel.Type.NONE;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE; import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
@Slf4j @Slf4j
@ -53,14 +54,15 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
return value; return value;
} }
if (currentType == expectedType) {
/** expected type */
return value;
}
if (currentType == null) { if (currentType == null) {
currentType = OPAQUE; currentType = OPAQUE;
} }
if (currentType == expectedType || currentType == NONE) {
/** expected type */
return value;
}
switch (expectedType) { switch (expectedType) {
case INTEGER: case INTEGER:
switch (currentType) { switch (currentType) {