|
|
|
@ -25,6 +25,7 @@ import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.DeviceProfile; |
|
|
|
import org.thingsboard.server.common.data.FirmwareInfo; |
|
|
|
import org.thingsboard.server.common.data.firmware.FirmwareKeyUtil; |
|
|
|
import org.thingsboard.server.common.data.firmware.FirmwareType; |
|
|
|
import org.thingsboard.server.common.data.id.DeviceId; |
|
|
|
import org.thingsboard.server.common.data.id.FirmwareId; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
@ -56,6 +57,7 @@ import java.util.List; |
|
|
|
import java.util.Set; |
|
|
|
import java.util.UUID; |
|
|
|
import java.util.function.Consumer; |
|
|
|
import java.util.function.Function; |
|
|
|
|
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareKey.CHECKSUM_ALGORITHM; |
|
|
|
@ -67,6 +69,8 @@ import static org.thingsboard.server.common.data.firmware.FirmwareKey.VERSION; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getAttributeKey; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getTargetTelemetryKey; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareKeyUtil.getTelemetryKey; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE; |
|
|
|
import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE; |
|
|
|
|
|
|
|
@Slf4j |
|
|
|
@Service |
|
|
|
@ -95,6 +99,11 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
|
|
|
|
@Override |
|
|
|
public void update(Device device, Device oldDevice) { |
|
|
|
updateFirmware(device, oldDevice); |
|
|
|
updateSoftware(device, oldDevice); |
|
|
|
} |
|
|
|
|
|
|
|
private void updateFirmware(Device device, Device oldDevice) { |
|
|
|
FirmwareId newFirmwareId = device.getFirmwareId(); |
|
|
|
if (newFirmwareId == null) { |
|
|
|
DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); |
|
|
|
@ -109,35 +118,84 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
} |
|
|
|
if (!newFirmwareId.equals(oldFirmwareId)) { |
|
|
|
// Device was updated and new firmware is different from previous firmware.
|
|
|
|
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis()); |
|
|
|
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis(), FIRMWARE); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Device was updated and new firmware is not set.
|
|
|
|
remove(device); |
|
|
|
remove(device, FIRMWARE); |
|
|
|
} |
|
|
|
} else if (newFirmwareId != null) { |
|
|
|
// Device was created and firmware is defined.
|
|
|
|
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis()); |
|
|
|
send(device.getTenantId(), device.getId(), newFirmwareId, System.currentTimeMillis(), FIRMWARE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void updateSoftware(Device device, Device oldDevice) { |
|
|
|
FirmwareId newSoftwareId = device.getSoftwareId(); |
|
|
|
if (newSoftwareId == null) { |
|
|
|
DeviceProfile newDeviceProfile = deviceProfileService.findDeviceProfileById(device.getTenantId(), device.getDeviceProfileId()); |
|
|
|
newSoftwareId = newDeviceProfile.getSoftwareId(); |
|
|
|
} |
|
|
|
if (oldDevice != null) { |
|
|
|
if (newSoftwareId != null) { |
|
|
|
FirmwareId oldSoftwareId = oldDevice.getSoftwareId(); |
|
|
|
if (oldSoftwareId == null) { |
|
|
|
DeviceProfile oldDeviceProfile = deviceProfileService.findDeviceProfileById(oldDevice.getTenantId(), oldDevice.getDeviceProfileId()); |
|
|
|
oldSoftwareId = oldDeviceProfile.getSoftwareId(); |
|
|
|
} |
|
|
|
if (!newSoftwareId.equals(oldSoftwareId)) { |
|
|
|
// Device was updated and new firmware is different from previous firmware.
|
|
|
|
send(device.getTenantId(), device.getId(), newSoftwareId, System.currentTimeMillis(), SOFTWARE); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// Device was updated and new firmware is not set.
|
|
|
|
remove(device, SOFTWARE); |
|
|
|
} |
|
|
|
} else if (newSoftwareId != null) { |
|
|
|
// Device was created and firmware is defined.
|
|
|
|
send(device.getTenantId(), device.getId(), newSoftwareId, System.currentTimeMillis(), SOFTWARE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void update(DeviceProfile deviceProfile) { |
|
|
|
public void update(DeviceProfile deviceProfile, boolean isFirmwareChanged, boolean isSoftwareChanged) { |
|
|
|
TenantId tenantId = deviceProfile.getTenantId(); |
|
|
|
|
|
|
|
if (isFirmwareChanged) { |
|
|
|
update(tenantId, deviceProfile, FIRMWARE); |
|
|
|
} |
|
|
|
if (isSoftwareChanged) { |
|
|
|
update(tenantId, deviceProfile, SOFTWARE); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private void update(TenantId tenantId, DeviceProfile deviceProfile, FirmwareType firmwareType) { |
|
|
|
Function<PageLink, PageData<Device>> getDevicesFunction; |
|
|
|
Consumer<Device> updateConsumer; |
|
|
|
|
|
|
|
switch (firmwareType) { |
|
|
|
case FIRMWARE: |
|
|
|
getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pl); |
|
|
|
break; |
|
|
|
case SOFTWARE: |
|
|
|
getDevicesFunction = pl -> deviceService.findDevicesByTenantIdAndTypeAndEmptySoftware(tenantId, deviceProfile.getName(), pl); |
|
|
|
break; |
|
|
|
default: |
|
|
|
log.warn("Unsupported firmware type: [{}]", firmwareType); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
if (deviceProfile.getFirmwareId() != null) { |
|
|
|
long ts = System.currentTimeMillis(); |
|
|
|
updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts); |
|
|
|
updateConsumer = d -> send(d.getTenantId(), d.getId(), deviceProfile.getFirmwareId(), ts, firmwareType); |
|
|
|
} else { |
|
|
|
updateConsumer = this::remove; |
|
|
|
updateConsumer = d -> remove(d, firmwareType); |
|
|
|
} |
|
|
|
|
|
|
|
PageLink pageLink = new PageLink(100); |
|
|
|
PageData<Device> pageData; |
|
|
|
do { |
|
|
|
pageData = deviceService.findDevicesByTenantIdAndTypeAndEmptyFirmware(tenantId, deviceProfile.getName(), pageLink); |
|
|
|
|
|
|
|
pageData = getDevicesFunction.apply(pageLink); |
|
|
|
pageData.getData().forEach(updateConsumer); |
|
|
|
|
|
|
|
if (pageData.hasNext()) { |
|
|
|
@ -152,16 +210,37 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
FirmwareId targetFirmwareId = new FirmwareId(new UUID(msg.getFirmwareIdMSB(), msg.getFirmwareIdLSB())); |
|
|
|
DeviceId deviceId = new DeviceId(new UUID(msg.getDeviceIdMSB(), msg.getDeviceIdLSB())); |
|
|
|
TenantId tenantId = new TenantId(new UUID(msg.getTenantIdMSB(), msg.getTenantIdLSB())); |
|
|
|
FirmwareType firmwareType = FirmwareType.valueOf(msg.getType()); |
|
|
|
long ts = msg.getTs(); |
|
|
|
|
|
|
|
Device device = deviceService.findDeviceById(tenantId, deviceId); |
|
|
|
if (device == null) { |
|
|
|
log.warn("[{}] [{}] Device was removed during firmware update msg was queued!", tenantId, deviceId); |
|
|
|
} else { |
|
|
|
FirmwareId currentFirmwareId = device.getFirmwareId(); |
|
|
|
FirmwareId currentFirmwareId; |
|
|
|
|
|
|
|
switch (firmwareType) { |
|
|
|
case FIRMWARE: |
|
|
|
currentFirmwareId = device.getFirmwareId(); |
|
|
|
break; |
|
|
|
case SOFTWARE: |
|
|
|
currentFirmwareId = device.getSoftwareId(); |
|
|
|
break; |
|
|
|
default: |
|
|
|
log.warn("Unsupported firmware type: [{}]", firmwareType); |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
if (currentFirmwareId == null) { |
|
|
|
currentFirmwareId = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()).getFirmwareId(); |
|
|
|
DeviceProfile deviceProfile = deviceProfileService.findDeviceProfileById(tenantId, device.getDeviceProfileId()); |
|
|
|
switch (firmwareType) { |
|
|
|
case FIRMWARE: |
|
|
|
currentFirmwareId = deviceProfile.getFirmwareId(); |
|
|
|
break; |
|
|
|
case SOFTWARE: |
|
|
|
currentFirmwareId = deviceProfile.getSoftwareId(); |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (targetFirmwareId.equals(currentFirmwareId)) { |
|
|
|
@ -174,7 +253,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
return isSuccess; |
|
|
|
} |
|
|
|
|
|
|
|
private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts) { |
|
|
|
private void send(TenantId tenantId, DeviceId deviceId, FirmwareId firmwareId, long ts, FirmwareType firmwareType) { |
|
|
|
ToFirmwareStateServiceMsg msg = ToFirmwareStateServiceMsg.newBuilder() |
|
|
|
.setTenantIdMSB(tenantId.getId().getMostSignificantBits()) |
|
|
|
.setTenantIdLSB(tenantId.getId().getLeastSignificantBits()) |
|
|
|
@ -182,6 +261,7 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
.setDeviceIdLSB(deviceId.getId().getLeastSignificantBits()) |
|
|
|
.setFirmwareIdMSB(firmwareId.getId().getMostSignificantBits()) |
|
|
|
.setFirmwareIdLSB(firmwareId.getId().getLeastSignificantBits()) |
|
|
|
.setType(firmwareType.name()) |
|
|
|
.setTs(ts) |
|
|
|
.build(); |
|
|
|
|
|
|
|
@ -252,14 +332,14 @@ public class DefaultFirmwareStateService implements FirmwareStateService { |
|
|
|
}); |
|
|
|
} |
|
|
|
|
|
|
|
private void remove(Device device) { |
|
|
|
telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareKeyUtil.ALL_ATTRIBUTE_KEYS, |
|
|
|
private void remove(Device device, FirmwareType firmwareType) { |
|
|
|
telemetryService.deleteAndNotify(device.getTenantId(), device.getId(), DataConstants.SHARED_SCOPE, FirmwareKeyUtil.getAttributeKeys(firmwareType), |
|
|
|
new FutureCallback<>() { |
|
|
|
@Override |
|
|
|
public void onSuccess(@Nullable Void tmp) { |
|
|
|
log.trace("[{}] Success remove target firmware attributes!", device.getId()); |
|
|
|
Set<AttributeKey> keysToNotify = new HashSet<>(); |
|
|
|
FirmwareKeyUtil.ALL_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); |
|
|
|
FirmwareKeyUtil.ALL_FW_ATTRIBUTE_KEYS.forEach(key -> keysToNotify.add(new AttributeKey(DataConstants.SHARED_SCOPE, key))); |
|
|
|
tbClusterService.pushMsgToCore(DeviceAttributesEventNotificationMsg.onDelete(device.getTenantId(), device.getId(), keysToNotify), null); |
|
|
|
} |
|
|
|
|
|
|
|
|