@ -45,10 +45,12 @@ import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MExecuteRequ
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteReplaceRequest ;
import org.thingsboard.server.transport.lwm2m.server.downlink.TbLwM2MWriteResponseCallback ;
import org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService ;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MClientFwOtaInfo ;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.LwM2MFirmwareUpdateStrategy ;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareDeliveryMethod ;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateResult ;
import org.thingsboard.server.transport.lwm2m.server.ota.firmware.FirmwareUpdateState ;
import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MClientSwOtaInfo ;
import org.thingsboard.server.transport.lwm2m.server.ota.software.LwM2MSoftwareUpdateStrategy ;
import org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdateResult ;
import org.thingsboard.server.transport.lwm2m.server.ota.software.SoftwareUpdateState ;
@ -91,12 +93,13 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
public static final String FIRMWARE_UPDATE_COAP_RESOURCE = "tbfw" ;
public static final String SOFTWARE_UPDATE_COAP_RESOURCE = "tbsw" ;
private static final String FW_PACKAGE_5_ID = "/5/0/0" ;
private static final String FW_PACKAGE_19_ID = "/19/0/0" ;
private static final String FW_URL_ID = "/5/0/1" ;
private static final String FW_EXECUTE_ID = "/5/0/2" ;
public static final String FW_STATE_ID = "/5/0/3" ;
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_5_ VER_ID = "/5/0/7" ;
public static final String FW_VER_ID = "/5/0/7" ;
/ * *
* Quectel @Hi15RM1 - HLB_V1 . 0 @BC68JAR01A10 , V150R100C20B300SP7 , V150R100C20B300SP7 @8
* Revision : BC68JAR01A10
@ -104,17 +107,19 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
public static final String FW_3_VER_ID = "/3/0/3" ;
public static final String FW_DELIVERY_METHOD = "/5/0/9" ;
private static final String SW_NAME_ID = "/9/0/0" ;
private static final String SW_VER_ID = "/9/0/1" ;
public static final String SW_3_VER_ID = "/3/0/19" ;
public static final String SW_NAME_ID = "/9/0/0" ;
public static final String SW_VER_ID = "/9/0/1" ;
public static final String SW_PACKAGE_ID = "/9/0/2" ;
public static final String SW_PACKAGE_URI_ID = "/9/0/3" ;
public static final String SW_INSTALL_ID = "/9/0/4" ;
public static final String SW_UPDATE_ STATE_ID = "/9/0/7" ;
public static final String SW_STATE_ID = "/9/0/7" ;
public static final String SW_RESULT_ID = "/9/0/9" ;
public static final String SW_UN_INSTALL_ID = "/9/0/6" ;
private final Map < String , LwM2MClientOtaInfo > fwStates = new ConcurrentHashMap < > ( ) ;
private final Map < String , LwM2MClientOtaInfo > swStates = new ConcurrentHashMap < > ( ) ;
private final Map < String , LwM2MClientFw OtaInfo > fwStates = new ConcurrentHashMap < > ( ) ;
private final Map < String , LwM2MClientSw OtaInfo > swStates = new ConcurrentHashMap < > ( ) ;
private final TransportService transportService ;
private final LwM2mClientContext clientContext ;
@ -155,27 +160,41 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
//TODO: add locks by client fwInfo.
//TODO: check that the client supports FW and SW by checking the supported objects in the model.
List < String > attributesToFetch = new ArrayList < > ( ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
if ( fwInfo . isSupported ( ) ) {
attributesToFetch . add ( FIRMWARE_TITLE ) ;
attributesToFetch . add ( FIRMWARE_VERSION ) ;
attributesToFetch . add ( FIRMWARE_URL ) ;
}
LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo ( client ) ;
if ( swInfo . isSupported ( ) ) {
attributesToFetch . add ( SOFTWARE_TITLE ) ;
attributesToFetch . add ( SOFTWARE_VERSION ) ;
attributesToFetch . add ( SOFTWARE_URL ) ;
}
if ( ! attributesToFetch . isEmpty ( ) ) {
var future = attributesService . getSharedAttributes ( client , attributesToFetch ) ;
DonAsynchron . withCallback ( future , attrs - > {
if ( fwInfo . isSupported ( ) ) {
Optional < String > newFirmwareTitle = getAttributeValue ( attrs , FIRMWARE_TITLE ) ;
Optional < String > newFirmwareVersion = getAttributeValue ( attrs , FIRMWARE_VERSION ) ;
Optional < String > newFirmwareUrl = getAttributeValue ( attrs , FIRMWARE_URL ) ;
if ( newFirmwareTitle . isPresent ( ) & & newFirmwareVersion . isPresent ( ) ) {
onTargetFirmwareUpdate ( client , newFirmwareTitle . get ( ) , newFirmwareVersion . get ( ) , newFirmwareUrl ) ;
Optional < String > newFwTitle = getAttributeValue ( attrs , FIRMWARE_TITLE ) ;
Optional < String > newFwVersion = getAttributeValue ( attrs , FIRMWARE_VERSION ) ;
Optional < String > newFwUrl = getAttributeValue ( attrs , FIRMWARE_URL ) ;
if ( newFwTitle . isPresent ( ) & & newFwVersion . isPresent ( ) ) {
onTargetFirmwareUpdate ( client , newFwTitle . get ( ) , newFwVersion . get ( ) , newFwUrl ) ;
}
}
if ( swInfo . isSupported ( ) ) {
Optional < String > newSwTitle = getAttributeValue ( attrs , SOFTWARE_TITLE ) ;
Optional < String > newSwVersion = getAttributeValue ( attrs , SOFTWARE_VERSION ) ;
Optional < String > newSwUrl = getAttributeValue ( attrs , SOFTWARE_URL ) ;
if ( newSwTitle . isPresent ( ) & & newSwVersion . isPresent ( ) ) {
onTargetSoftwareUpdate ( client , newSwTitle . get ( ) , newSwVersion . get ( ) , newSwUrl ) ;
}
}
} , throwable - > {
if ( fwInfo . isSupported ( ) ) {
fwInfo . setTargetFetchFailure ( true ) ;
update ( fwInfo ) ;
}
} , executor ) ;
@ -184,7 +203,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void forceFirmwareUpdate ( LwM2mClient client ) {
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setRetryAttempts ( 0 ) ;
fwInfo . setFailedPackageId ( null ) ;
startFirmwareUpdateIfNeeded ( client , fwInfo ) ;
@ -192,7 +211,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void onTargetFirmwareUpdate ( LwM2mClient client , String newFirmwareTitle , String newFirmwareVersion , Optional < String > newFirmwareUrl ) {
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . updateTarget ( newFirmwareTitle , newFirmwareVersion , newFirmwareUrl ) ;
update ( fwInfo ) ;
startFirmwareUpdateIfNeeded ( client , fwInfo ) ;
@ -201,15 +220,20 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void onCurrentFirmwareNameUpdate ( LwM2mClient client , String name ) {
log . debug ( "[{}] Current fw name: {}" , client . getEndpoint ( ) , name ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setCurrentName ( name ) ;
getOrInitFwInfo ( client ) . setCurrentName ( name ) ;
}
@Override
public void onCurrentSoftwareNameUpdate ( LwM2mClient client , String name ) {
log . debug ( "[{}] Current sw name: {}" , client . getEndpoint ( ) , name ) ;
getOrInitSwInfo ( client ) . setCurrentName ( name ) ;
}
@Override
public void onFirmwareStrategyUpdate ( LwM2mClient client , OtherConfiguration configuration ) {
log . debug ( "[{}] Current fw strategy: {}" , client . getEndpoint ( ) , configuration . getFwUpdateStrategy ( ) ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setFw Strategy ( LwM2MFirmwareUpdateStrategy . fromStrategyFwByCode ( configuration . getFwUpdateStrategy ( ) ) ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setStrategy ( LwM2MFirmwareUpdateStrategy . fromStrategyFwByCode ( configuration . getFwUpdateStrategy ( ) ) ) ;
fwInfo . setBaseUrl ( configuration . getFwUpdateResource ( ) ) ;
startFirmwareUpdateIfNeeded ( client , fwInfo ) ;
}
@ -217,30 +241,30 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void onCurrentSoftwareStrategyUpdate ( LwM2mClient client , OtherConfiguration configuration ) {
log . debug ( "[{}] Current sw strategy: {}" , client . getEndpoint ( ) , configuration . getSwUpdateStrategy ( ) ) ;
LwM2MClientOtaInfo swInfo = getOrInitSwInfo ( client ) ;
swInfo . setSwS trategy ( LwM2MSoftwareUpdateStrategy . fromStrategySwByCode ( configuration . getSwUpdateStrategy ( ) ) ) ;
LwM2MClientSw OtaInfo swInfo = getOrInitSwInfo ( client ) ;
swInfo . setStrategy ( LwM2MSoftwareUpdateStrategy . fromStrategySwByCode ( configuration . getSwUpdateStrategy ( ) ) ) ;
swInfo . setBaseUrl ( configuration . getSwUpdateResource ( ) ) ;
startSoftwareUpdateIfNeeded ( client , swInfo ) ;
}
@Override
public void onCurrentFirmwareVersion3Update ( LwM2mClient client , String version ) {
log . debug ( "[{}] Current fw version: {}" , client . getEndpoint ( ) , version ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
log . debug ( "[{}] Current fw version(3) : {}" , client . getEndpoint ( ) , version ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setCurrentVersion3 ( version ) ;
}
@Override
public void onCurrentFirmwareVersion5 Update ( LwM2mClient client , String version ) {
log . debug ( "[{}] Current fw version: {}" , client . getEndpoint ( ) , version ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setCurrentVersion5 ( version ) ;
public void onCurrentFirmwareVersionUpdate ( LwM2mClient client , String version ) {
log . debug ( "[{}] Current fw version(5) : {}" , client . getEndpoint ( ) , version ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setCurrentVersion ( version ) ;
}
@Override
public void onCurrentFirmwareStateUpdate ( LwM2mClient client , Long stateCode ) {
log . debug ( "[{}] Current fw state: {}" , client . getEndpoint ( ) , stateCode ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
FirmwareUpdateState state = FirmwareUpdateState . fromStateFwByCode ( stateCode . intValue ( ) ) ;
if ( FirmwareUpdateState . DOWNLOADED . equals ( state ) ) {
executeFwUpdate ( client ) ;
@ -255,7 +279,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void onCurrentFirmwareResultUpdate ( LwM2mClient client , Long code ) {
log . debug ( "[{}] Current fw result: {}" , client . getEndpoint ( ) , code ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
FirmwareUpdateResult result = FirmwareUpdateResult . fromUpdateResultFwByCode ( code . intValue ( ) ) ;
Optional < OtaPackageUpdateStatus > status = toOtaPackageUpdateStatus ( result ) ;
status . ifPresent ( otaStatus - > sendStateUpdateToTelemetry ( client , fwInfo ,
@ -272,16 +296,66 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
@Override
public void onCurrentFirmwareDeliveryMethodUpdate ( LwM2mClient client , Long value ) {
log . debug ( "[{}] Current fw delivery method: {}" , client . getEndpoint ( ) , value ) ;
LwM2MClientOtaInfo fwInfo = getOrInitFwInfo ( client ) ;
LwM2MClientFw OtaInfo fwInfo = getOrInitFwInfo ( client ) ;
fwInfo . setDeliveryMethod ( value . intValue ( ) ) ;
}
@Override
public void onTargetSoftwareUpdate ( LwM2mClient client , String newSoftwareTitle , String newSoftwareVersion ) {
public void onCurrentSoftwareVersion3Update ( LwM2mClient client , String version ) {
log . debug ( "[{}] Current sw version(3): {}" , client . getEndpoint ( ) , version ) ;
getOrInitSwInfo ( client ) . setCurrentVersion3 ( version ) ;
}
@Override
public void onCurrentSoftwareVersionUpdate ( LwM2mClient client , String version ) {
log . debug ( "[{}] Current sw version(9): {}" , client . getEndpoint ( ) , version ) ;
getOrInitSwInfo ( client ) . setCurrentVersion ( version ) ;
}
@Override
public void onCurrentSoftwareStateUpdate ( LwM2mClient client , Long stateCode ) {
log . debug ( "[{}] Current sw state: {}" , client . getEndpoint ( ) , stateCode ) ;
LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo ( client ) ;
SoftwareUpdateState state = SoftwareUpdateState . fromUpdateStateSwByCode ( stateCode . intValue ( ) ) ;
if ( SoftwareUpdateState . INITIAL . equals ( state ) ) {
startSoftwareUpdateIfNeeded ( client , swInfo ) ;
} else if ( SoftwareUpdateState . DELIVERED . equals ( state ) ) {
executeSwInstall ( client ) ;
}
swInfo . setUpdateState ( state ) ;
Optional < OtaPackageUpdateStatus > status = toOtaPackageUpdateStatus ( state ) ;
status . ifPresent ( otaStatus - > sendStateUpdateToTelemetry ( client , swInfo ,
otaStatus , "Firmware Update State: " + state . name ( ) ) ) ;
update ( swInfo ) ;
}
private void startFirmwareUpdateIfNeeded ( LwM2mClient client , LwM2MClientOtaInfo fwInfo ) {
@Override
public void onCurrentSoftwareResultUpdate ( LwM2mClient client , Long code ) {
log . debug ( "[{}] Current sw result: {}" , client . getEndpoint ( ) , code ) ;
LwM2MClientSwOtaInfo swInfo = getOrInitSwInfo ( client ) ;
SoftwareUpdateResult result = SoftwareUpdateResult . fromUpdateResultSwByCode ( code . intValue ( ) ) ;
Optional < OtaPackageUpdateStatus > status = toOtaPackageUpdateStatus ( result ) ;
status . ifPresent ( otaStatus - > sendStateUpdateToTelemetry ( client , swInfo ,
otaStatus , "Firmware Update Result: " + result . name ( ) ) ) ;
if ( result . isAgain ( ) & & swInfo . getRetryAttempts ( ) < = 2 ) {
swInfo . setRetryAttempts ( swInfo . getRetryAttempts ( ) + 1 ) ;
startSoftwareUpdateIfNeeded ( client , swInfo ) ;
} else {
swInfo . update ( result ) ;
}
update ( swInfo ) ;
}
@Override
public void onTargetSoftwareUpdate ( LwM2mClient client , String newSoftwareTitle , String newSoftwareVersion , Optional < String > newFirmwareUrl ) {
LwM2MClientSwOtaInfo fwInfo = getOrInitSwInfo ( client ) ;
fwInfo . updateTarget ( newSoftwareTitle , newSoftwareVersion , newFirmwareUrl ) ;
update ( fwInfo ) ;
startSoftwareUpdateIfNeeded ( client , fwInfo ) ;
}
private void startFirmwareUpdateIfNeeded ( LwM2mClient client , LwM2MClientFwOtaInfo fwInfo ) {
try {
if ( ! fwInfo . isSupported ( ) ) {
log . debug ( "[{}] Fw update is not supported: {}" , client . getEndpoint ( ) , fwInfo ) ;
@ -289,35 +363,70 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
} else if ( fwInfo . isUpdateRequired ( ) ) {
if ( StringUtils . isNotEmpty ( fwInfo . getTargetUrl ( ) ) ) {
log . debug ( "[{}] Starting update to [{}{}] using URL: {}" , client . getEndpoint ( ) , fwInfo . getTargetName ( ) , fwInfo . getTargetVersion ( ) , fwInfo . getTargetUrl ( ) ) ;
startFirmware UpdateUsingUrl ( client , fwInfo . getTargetUrl ( ) ) ;
startUpdateUsingUrl ( client , FW_URL_ID , fwInfo . getTargetUrl ( ) ) ;
} else {
log . debug ( "[{}] Starting update to [{}{}] using binary" , client . getEndpoint ( ) , fwInfo . getTargetName ( ) , fwInfo . getTargetVersion ( ) ) ;
startFirmware UpdateUsingBinary ( client , fwInfo ) ;
startUpdateUsingBinary ( client , fwInfo ) ;
}
}
} catch ( Exception e ) {
log . warn ( "[{}] failed to update client: {}" , client . getEndpoint ( ) , fwInfo , e ) ;
log . info ( "[{}] failed to update client: {}" , client . getEndpoint ( ) , fwInfo , e ) ;
sendStateUpdateToTelemetry ( client , fwInfo , OtaPackageUpdateStatus . FAILED , "Internal server error: " + e . getMessage ( ) ) ;
}
}
private void startSoftwareUpdateIfNeeded ( LwM2mClient client , LwM2MClientOtaInfo swInfo ) {
private void startSoftwareUpdateIfNeeded ( LwM2mClient client , LwM2MClientSwOtaInfo swInfo ) {
try {
if ( ! swInfo . isSupported ( ) ) {
log . debug ( "[{}] Sw update is not supported: {}" , client . getEndpoint ( ) , swInfo ) ;
sendStateUpdateToTelemetry ( client , swInfo , OtaPackageUpdateStatus . FAILED , "Client does not support software update or profile misconfiguration!" ) ;
} else if ( swInfo . isUpdateRequired ( ) ) {
if ( SoftwareUpdateState . INSTALLED . equals ( swInfo . getUpdateState ( ) ) ) {
log . debug ( "[{}] Attempt to restore the update state: {}" , client . getEndpoint ( ) , swInfo . getUpdateState ( ) ) ;
executeSwUninstallForUpdate ( client ) ;
} else {
if ( StringUtils . isNotEmpty ( swInfo . getTargetUrl ( ) ) ) {
log . debug ( "[{}] Starting update to [{}{}] using URL: {}" , client . getEndpoint ( ) , swInfo . getTargetName ( ) , swInfo . getTargetVersion ( ) , swInfo . getTargetUrl ( ) ) ;
startUpdateUsingUrl ( client , SW_PACKAGE_URI_ID , swInfo . getTargetUrl ( ) ) ;
} else {
log . debug ( "[{}] Starting update to [{}{}] using binary" , client . getEndpoint ( ) , swInfo . getTargetName ( ) , swInfo . getTargetVersion ( ) ) ;
startUpdateUsingBinary ( client , swInfo ) ;
}
}
}
} catch ( Exception e ) {
log . info ( "[{}] failed to update client: {}" , client . getEndpoint ( ) , swInfo , e ) ;
sendStateUpdateToTelemetry ( client , swInfo , OtaPackageUpdateStatus . FAILED , "Internal server error: " + e . getMessage ( ) ) ;
}
}
public void startUpdateUsingBinary ( LwM2mClient client , LwM2MClientSwOtaInfo swInfo ) {
this . transportService . process ( client . getSession ( ) , createOtaPackageRequestMsg ( client . getSession ( ) , swInfo . getType ( ) . name ( ) ) ,
new TransportServiceCallback < > ( ) {
@Override
public void onSuccess ( TransportProtos . GetOtaPackageResponseMsg response ) {
executor . submit ( ( ) - > doUpdateSoftwareUsingBinary ( response , swInfo , client ) ) ;
}
@Override
public void onError ( Throwable e ) {
logService . log ( client , "Failed to process software update: " + e . getMessage ( ) ) ;
}
} ) ;
}
private void startFirmwareUpdateUsingUrl ( LwM2mClient client , String url ) {
String targetIdVer = convertObjectIdToVersionedId ( FW_URL_ID , client . getRegistration ( ) ) ;
private void startUpdateUsingUrl ( LwM2mClient client , String id , String url ) {
String targetIdVer = convertObjectIdToVersionedId ( id , client . getRegistration ( ) ) ;
TbLwM2MWriteReplaceRequest request = TbLwM2MWriteReplaceRequest . builder ( ) . versionedId ( targetIdVer ) . value ( url ) . timeout ( config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendWriteReplaceRequest ( client , request , new TbLwM2MWriteResponseCallback ( uplinkHandler , logService , client , targetIdVer ) ) ;
}
public void startFirmwareUpdateUsingBinary ( LwM2mClient client , LwM2MClientOtaInfo fwInfo ) {
String versionedId = convertObjectIdToVersionedId ( FW_PACKAGE_5_ID , client . getRegistration ( ) ) ;
this . transportService . process ( client . getSession ( ) , createOtaPackageRequestMsg ( client . getSession ( ) , OtaPackageType . FIRMWARE . name ( ) ) ,
public void startUpdateUsingBinary ( LwM2mClient client , LwM2MClientFwOtaInfo fwInfo ) {
this . transportService . process ( client . getSession ( ) , createOtaPackageRequestMsg ( client . getSession ( ) , fwInfo . getType ( ) . name ( ) ) ,
new TransportServiceCallback < > ( ) {
@Override
public void onSuccess ( TransportProtos . GetOtaPackageResponseMsg response ) {
executor . submit ( ( ) - > doUpdateFirmwareUsingBinary ( response , fwInfo , versionedId , client ) ) ;
executor . submit ( ( ) - > doUpdateFirmwareUsingBinary ( response , fwInfo , client ) ) ;
}
@Override
@ -327,34 +436,60 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
} ) ;
}
private void doUpdateFirmwareUsingBinary ( TransportProtos . GetOtaPackageResponseMsg response , LwM2MClientOtaInfo fwInfo , String versionedId , LwM2mClient client ) {
private void doUpdateFirmwareUsingBinary ( TransportProtos . GetOtaPackageResponseMsg response , LwM2MClientFwOtaInfo info , LwM2mClient client ) {
if ( TransportProtos . ResponseStatus . SUCCESS . equals ( response . getResponseStatus ( ) ) ) {
UUID otaPackageId = new UUID ( response . getOtaPackageIdMSB ( ) , response . getOtaPackageIdLSB ( ) ) ;
LwM2MFirmwareUpdateStrategy strategy ;
if ( fwI nfo. getDeliveryMethod ( ) = = null | | fwI nfo. getDeliveryMethod ( ) = = FirmwareDeliveryMethod . BOTH . code ) {
strategy = fwI nfo. getFw Strategy ( ) ;
if ( i nfo. getDeliveryMethod ( ) = = null | | i nfo. getDeliveryMethod ( ) = = FirmwareDeliveryMethod . BOTH . code ) {
strategy = i nfo. getStrategy ( ) ;
} else {
strategy = fwI nfo. getDeliveryMethod ( ) = = FirmwareDeliveryMethod . PULL . code ? LwM2MFirmwareUpdateStrategy . OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy . OBJ_5_BINARY ;
strategy = i nfo. getDeliveryMethod ( ) = = FirmwareDeliveryMethod . PULL . code ? LwM2MFirmwareUpdateStrategy . OBJ_5_TEMP_URL : LwM2MFirmwareUpdateStrategy . OBJ_5_BINARY ;
}
switch ( strategy ) {
case OBJ_5_BINARY :
byte [ ] firmwareChunk = otaPackageDataCache . get ( otaPackageId . toString ( ) , 0 , 0 ) ;
TbLwM2MWriteReplaceRequest writeRequest = TbLwM2MWriteReplaceRequest . builder ( ) . versionedId ( versionedId )
. value ( firmwareChunk ) . contentFormat ( ContentFormat . OPAQUE )
. timeout ( config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendWriteReplaceRequest ( client , writeRequest , new TbLwM2MWriteResponseCallback ( uplinkHandler , logService , client , versionedId ) ) ;
startUpdateUsingBinary ( client , convertObjectIdToVersionedId ( FW_PACKAGE_5_ID , client . getRegistration ( ) ) , otaPackageId ) ;
break ;
case OBJ_19_BINARY :
startUpdateUsingBinary ( client , convertObjectIdToVersionedId ( FW_PACKAGE_19_ID , client . getRegistration ( ) ) , otaPackageId ) ;
break ;
case OBJ_5_TEMP_URL :
startFirmwareUpdateUsingUrl ( client , fwInfo . getBaseUrl ( ) + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId . toString ( ) ) ;
startUpdateUsingUrl ( client , FW_URL_ID , info . getBaseUrl ( ) + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId . toString ( ) ) ;
break ;
default :
sendStateUpdateToTelemetry ( client , info , OtaPackageUpdateStatus . FAILED , "Unsupported strategy: " + strategy . name ( ) ) ;
}
} else {
sendStateUpdateToTelemetry ( client , info , OtaPackageUpdateStatus . FAILED , "Failed to fetch OTA package: " + response . getResponseStatus ( ) ) ;
}
}
private void doUpdateSoftwareUsingBinary ( TransportProtos . GetOtaPackageResponseMsg response , LwM2MClientSwOtaInfo info , LwM2mClient client ) {
if ( TransportProtos . ResponseStatus . SUCCESS . equals ( response . getResponseStatus ( ) ) ) {
UUID otaPackageId = new UUID ( response . getOtaPackageIdMSB ( ) , response . getOtaPackageIdLSB ( ) ) ;
LwM2MSoftwareUpdateStrategy strategy = info . getStrategy ( ) ;
switch ( strategy ) {
case BINARY :
startUpdateUsingBinary ( client , convertObjectIdToVersionedId ( SW_PACKAGE_ID , client . getRegistration ( ) ) , otaPackageId ) ;
break ;
case TEMP_URL :
startUpdateUsingUrl ( client , SW_PACKAGE_URI_ID , info . getBaseUrl ( ) + "/" + FIRMWARE_UPDATE_COAP_RESOURCE + "/" + otaPackageId . toString ( ) ) ;
break ;
default :
sendStateUpdateToTelemetry ( client , fwInfo , OtaPackageUpdateStatus . FAILED , "Unsupported strategy: " + strategy . name ( ) ) ;
sendStateUpdateToTelemetry ( client , i nfo, OtaPackageUpdateStatus . FAILED , "Unsupported strategy: " + strategy . name ( ) ) ;
}
} else {
sendStateUpdateToTelemetry ( client , fwInfo , OtaPackageUpdateStatus . FAILED , "Failed to fetch OTA package: " + response . getResponseStatus ( ) ) ;
sendStateUpdateToTelemetry ( client , i nfo, OtaPackageUpdateStatus . FAILED , "Failed to fetch OTA package: " + response . getResponseStatus ( ) ) ;
}
}
private void startUpdateUsingBinary ( LwM2mClient client , String versionedId , UUID otaPackageId ) {
byte [ ] firmwareChunk = otaPackageDataCache . get ( otaPackageId . toString ( ) , 0 , 0 ) ;
TbLwM2MWriteReplaceRequest writeRequest = TbLwM2MWriteReplaceRequest . builder ( ) . versionedId ( versionedId )
. value ( firmwareChunk ) . contentFormat ( ContentFormat . OPAQUE )
. timeout ( config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendWriteReplaceRequest ( client , writeRequest , new TbLwM2MWriteResponseCallback ( uplinkHandler , logService , client , versionedId ) ) ;
}
private TransportProtos . GetOtaPackageRequestMsg createOtaPackageRequestMsg ( TransportProtos . SessionInfoProto sessionInfo , String nameFwSW ) {
return TransportProtos . GetOtaPackageRequestMsg . newBuilder ( )
. setDeviceIdMSB ( sessionInfo . getDeviceIdMSB ( ) )
@ -370,6 +505,16 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
downlinkHandler . sendExecuteRequest ( client , request , new TbLwM2MExecuteCallback ( logService , client , FW_EXECUTE_ID ) ) ;
}
private void executeSwInstall ( LwM2mClient client ) {
TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest . builder ( ) . versionedId ( SW_INSTALL_ID ) . timeout ( config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendExecuteRequest ( client , request , new TbLwM2MExecuteCallback ( logService , client , SW_INSTALL_ID ) ) ;
}
private void executeSwUninstallForUpdate ( LwM2mClient client ) {
TbLwM2MExecuteRequest request = TbLwM2MExecuteRequest . builder ( ) . versionedId ( SW_UN_INSTALL_ID ) . params ( "1" ) . timeout ( config . getTimeout ( ) ) . build ( ) ;
downlinkHandler . sendExecuteRequest ( client , request , new TbLwM2MExecuteCallback ( logService , client , SW_INSTALL_ID ) ) ;
}
private Optional < String > getAttributeValue ( List < TransportProtos . TsKvProto > attrs , String keyName ) {
for ( TransportProtos . TsKvProto attr : attrs ) {
if ( keyName . equals ( attr . getKv ( ) . getKey ( ) ) ) {
@ -383,40 +528,41 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
return Optional . empty ( ) ;
}
public LwM2MClient OtaInfo getOrInitFwInfo ( LwM2mClient client ) {
private LwM2MClientFw OtaInfo getOrInitFwInfo ( LwM2mClient client ) {
return this . fwStates . computeIfAbsent ( client . getEndpoint ( ) , endpoint - > {
LwM2MClientOtaInfo info = otaInfoStore . get ( OtaPackageType . FIRMWARE , endpoint ) ;
LwM2MClientFw OtaInfo info = otaInfoStore . getFw ( endpoint ) ;
if ( info = = null ) {
var profile = clientContext . getProfile ( client . getProfileId ( ) ) ;
info = new LwM2MClientOtaInfo ( endpoint , OtaPackageType . FIRMWARE ,
LwM2MFirmwareUpdateStrategy . fromStrategyFwByCode ( profile . getClientLwM2mSettings ( ) . getFwUpdateStrategy ( ) ) ,
profile . getClientLwM2mSettings ( ) . getFwUpdateResource ( ) ) ;
info = new LwM2MClientFwOtaInfo ( endpoint , profile . getClientLwM2mSettings ( ) . getFwUpdateResource ( ) ,
LwM2MFirmwareUpdateStrategy . fromStrategyFwByCode ( profile . getClientLwM2mSettings ( ) . getFwUpdateStrategy ( ) ) ) ;
update ( info ) ;
}
return info ;
} ) ;
}
private LwM2MClientOtaInfo getOrInitSwInfo ( LwM2mClient client ) {
return this . f wStates. computeIfAbsent ( client . getEndpoint ( ) , endpoint - > {
LwM2MClientOtaInfo info = otaInfoStore . get ( OtaPackageType . SOFTWARE , endpoint ) ;
private LwM2MClientSw OtaInfo getOrInitSwInfo ( LwM2mClient client ) {
return this . s wStates. computeIfAbsent ( client . getEndpoint ( ) , endpoint - > {
LwM2MClientSw OtaInfo info = otaInfoStore . getSw ( endpoint ) ;
if ( info = = null ) {
var profile = clientContext . getProfile ( client . getProfileId ( ) ) ;
info = new LwM2MClientOtaInfo ( endpoint , OtaPackageType . SOFTWARE ,
LwM2MSoftwareUpdateStrategy . fromStrategySwByCode ( profile . getClientLwM2mSettings ( ) . getFwUpdateStrategy ( ) ) ,
profile . getClientLwM2mSettings ( ) . getSwUpdateResource ( ) ) ;
info = new LwM2MClientSwOtaInfo ( endpoint , profile . getClientLwM2mSettings ( ) . getSwUpdateResource ( ) ,
LwM2MSoftwareUpdateStrategy . fromStrategySwByCode ( profile . getClientLwM2mSettings ( ) . getFwUpdateStrategy ( ) ) ) ;
update ( info ) ;
}
return info ;
} ) ;
}
private void update ( LwM2MClientFwOtaInfo info ) {
otaInfoStore . putFw ( info ) ;
}
private void update ( LwM2MClientOtaInfo info ) {
otaInfoStore . put ( info ) ;
private void update ( LwM2MClientSw OtaInfo info ) {
otaInfoStore . putSw ( info ) ;
}
private void sendStateUpdateToTelemetry ( LwM2mClient client , LwM2MClientOtaInfo fwInfo , OtaPackageUpdateStatus status , String log ) {
private void sendStateUpdateToTelemetry ( LwM2mClient client , LwM2MClientOtaInfo < ? , ? , ? > fwInfo , OtaPackageUpdateStatus status , String log ) {
List < TransportProtos . KeyValueProto > result = new ArrayList < > ( ) ;
TransportProtos . KeyValueProto . Builder kvProto = TransportProtos . KeyValueProto . newBuilder ( ) . setKey ( getAttributeKey ( fwInfo . getType ( ) , STATE ) ) ;
kvProto . setType ( TransportProtos . KeyValueType . STRING_V ) . setStringV ( status . name ( ) ) ;
@ -462,22 +608,31 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
}
}
private static Optional < OtaPackageUpdateStatus > toOtaPackageUpdateStatus ( SoftwareUpdateState swUpdateState ) {
switch ( swUpdateState ) {
case INITIAL :
return Optional . empty ( ) ;
case DOWNLOAD_STARTED :
return Optional . of ( DOWNLOADING ) ;
case DOWNLOADED :
return Optional . of ( DOWNLOADING ) ;
case DELIVERED :
return Optional . of ( DOWNLOADED ) ;
case INSTALLED :
return Optional . empty ( ) ;
default :
throw new CodecException ( "Invalid value stateSw %d for SoftwareUpdateState." , swUpdateState ) ;
}
}
/ * *
* FirmwareUpdateStatus {
* DOWNLOADING , DOWNLOADED , VERIFIED , UPDATING , UPDATED , FAILED
* /
public static Optional < OtaPackageUpdateStatus > toSwSateResultUpdateStatus ( SoftwareUpdateState softwareUpdateState , SoftwareUpdateResult softwareUpdateResult ) {
public static Optional < OtaPackageUpdateStatus > toOtaPackageUpdateStatus ( SoftwareUpdateResult softwareUpdateResult ) {
switch ( softwareUpdateResult ) {
case INITIAL :
switch ( softwareUpdateState ) {
case INITIAL :
case DOWNLOAD_STARTED :
return Optional . of ( DOWNLOADING ) ;
case DOWNLOADED :
return Optional . of ( DOWNLOADED ) ;
case DELIVERED :
return Optional . of ( VERIFIED ) ;
}
return Optional . empty ( ) ;
case DOWNLOADING :
return Optional . of ( DOWNLOADING ) ;
case SUCCESSFULLY_INSTALLED :
@ -495,7 +650,7 @@ public class DefaultLwM2MOtaUpdateService extends LwM2MExecutorAwareService impl
case UN_INSTALL_FAILURE :
return Optional . of ( FAILED ) ;
default :
throw new CodecException ( "Invalid value stateFw %s %s for FirmwareUpdateStatus." , softwareUpdateState . name ( ) , softwareUpdateResult . name ( ) ) ;
throw new CodecException ( "Invalid value stateFw %s for FirmwareUpdateStatus." , softwareUpdateResult . name ( ) ) ;
}
}