anjay
fw_update.h File Reference
#include <anjay/anjay_config.h>
#include <anjay/dm.h>

Go to the source code of this file.

Data Structures

struct  anjay_fw_update_initial_state_t
 
struct  anjay_fw_update_handlers_t
 

Macros

Firmware update result codes

The following result codes may be returned from anjay_fw_update_stream_write_t, anjay_fw_update_stream_finish_t or anjay_fw_update_perform_upgrade_t to control the value of the Update Result Resource after the failure.

Their values correspond to negated numeric values of that resource. However, attempting to use other negated value will be checked and cause a fall-back to a value default for a given handler.

#define ANJAY_FW_UPDATE_ERR_NOT_ENOUGH_SPACE    (-(int) ANJAY_FW_UPDATE_RESULT_NOT_ENOUGH_SPACE)
 
#define ANJAY_FW_UPDATE_ERR_OUT_OF_MEMORY    (-(int) ANJAY_FW_UPDATE_RESULT_OUT_OF_MEMORY)
 
#define ANJAY_FW_UPDATE_ERR_INTEGRITY_FAILURE    (-(int) ANJAY_FW_UPDATE_RESULT_INTEGRITY_FAILURE)
 
#define ANJAY_FW_UPDATE_ERR_UNSUPPORTED_PACKAGE_TYPE    (-(int) ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PACKAGE_TYPE)
 

Typedefs

typedef int anjay_fw_update_stream_open_t(void *user_ptr, const char *package_uri, const struct anjay_etag *package_etag)
 
typedef int anjay_fw_update_stream_write_t(void *user_ptr, const void *data, size_t length)
 
typedef int anjay_fw_update_stream_finish_t(void *user_ptr)
 
typedef void anjay_fw_update_reset_t(void *user_ptr)
 
typedef const char * anjay_fw_update_get_name_t(void *user_ptr)
 
typedef const char * anjay_fw_update_get_version_t(void *user_ptr)
 
typedef int anjay_fw_update_perform_upgrade_t(void *user_ptr)
 
typedef int anjay_fw_update_get_security_config_t(void *user_ptr, anjay_security_config_t *out_security_info, const char *download_uri)
 
typedef avs_coap_udp_tx_params_t anjay_fw_update_get_coap_tx_params_t(void *user_ptr, const char *download_uri)
 
typedef avs_time_duration_t anjay_fw_update_get_tcp_request_timeout_t(void *user_ptr, const char *download_uri)
 

Enumerations

enum  anjay_fw_update_result_t {
  ANJAY_FW_UPDATE_RESULT_INITIAL = 0 , ANJAY_FW_UPDATE_RESULT_SUCCESS = 1 , ANJAY_FW_UPDATE_RESULT_NOT_ENOUGH_SPACE = 2 , ANJAY_FW_UPDATE_RESULT_OUT_OF_MEMORY = 3 ,
  ANJAY_FW_UPDATE_RESULT_CONNECTION_LOST = 4 , ANJAY_FW_UPDATE_RESULT_INTEGRITY_FAILURE = 5 , ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PACKAGE_TYPE = 6 , ANJAY_FW_UPDATE_RESULT_INVALID_URI = 7 ,
  ANJAY_FW_UPDATE_RESULT_FAILED = 8 , ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PROTOCOL = 9
}
 
enum  anjay_fw_update_initial_result_t {
  ANJAY_FW_UPDATE_INITIAL_UPDATING = -3 , ANJAY_FW_UPDATE_INITIAL_DOWNLOADED = -2 , ANJAY_FW_UPDATE_INITIAL_DOWNLOADING = -1 , ANJAY_FW_UPDATE_INITIAL_NEUTRAL = 0 ,
  ANJAY_FW_UPDATE_INITIAL_SUCCESS = 1 , ANJAY_FW_UPDATE_INITIAL_INTEGRITY_FAILURE = 5 , ANJAY_FW_UPDATE_INITIAL_FAILED = 8
}
 

Functions

int anjay_fw_update_install (anjay_t *anjay, const anjay_fw_update_handlers_t *handlers, void *user_arg, const anjay_fw_update_initial_state_t *initial_state)
 
int anjay_fw_update_set_result (anjay_t *anjay, anjay_fw_update_result_t result)
 
void anjay_fw_update_pull_suspend (anjay_t *anjay)
 
int anjay_fw_update_pull_reconnect (anjay_t *anjay)
 

Macro Definition Documentation

◆ ANJAY_FW_UPDATE_ERR_INTEGRITY_FAILURE

#define ANJAY_FW_UPDATE_ERR_INTEGRITY_FAILURE    (-(int) ANJAY_FW_UPDATE_RESULT_INTEGRITY_FAILURE)

◆ ANJAY_FW_UPDATE_ERR_NOT_ENOUGH_SPACE

#define ANJAY_FW_UPDATE_ERR_NOT_ENOUGH_SPACE    (-(int) ANJAY_FW_UPDATE_RESULT_NOT_ENOUGH_SPACE)

◆ ANJAY_FW_UPDATE_ERR_OUT_OF_MEMORY

#define ANJAY_FW_UPDATE_ERR_OUT_OF_MEMORY    (-(int) ANJAY_FW_UPDATE_RESULT_OUT_OF_MEMORY)

◆ ANJAY_FW_UPDATE_ERR_UNSUPPORTED_PACKAGE_TYPE

#define ANJAY_FW_UPDATE_ERR_UNSUPPORTED_PACKAGE_TYPE    (-(int) ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PACKAGE_TYPE)

Typedef Documentation

◆ anjay_fw_update_get_coap_tx_params_t

typedef avs_coap_udp_tx_params_t anjay_fw_update_get_coap_tx_params_t(void *user_ptr, const char *download_uri)

Returns tx_params used to override default ones.

If this handler is not implemented at all (with the corresponding field set to NULL), udp_tx_params from anjay_t object are used.

NOTE: This callback is called even for non-CoAP downloads, but the returned transmission parameters are ignored in that case.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install .
download_uriTarget firmware URI.
Returns
Object with CoAP transmission parameters.

◆ anjay_fw_update_get_name_t

typedef const char* anjay_fw_update_get_name_t(void *user_ptr)

Returns the name of downloaded firmware package.

The name will be exposed in the data model as the PkgName Resource. If this callback returns NULL or is not implemented at all (with the corresponding field set to NULL), that Resource will not be present in the data model.

It only makes sense for this handler to return non-NULL values if there is a valid package already downloaded. The library will not call this handler in any state other than Downloaded.

The library will not attempt to deallocate the returned pointer. User code must assure that the pointer will remain valid at least until return from anjay_serve or anjay_sched_run .

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
Returns
The callback shall return a pointer to a null-terminated string containing the package name, or NULL if it is not currently available.

◆ anjay_fw_update_get_security_config_t

typedef int anjay_fw_update_get_security_config_t(void *user_ptr, anjay_security_config_t *out_security_info, const char *download_uri)

Queries security information that shall be used for an encrypted connection with a PULL-mode download server.

May be called before anjay_fw_update_stream_open_t if the download is to be performed in PULL mode and the connection needs to use TLS or DTLS encryption.

Note that the anjay_security_config_t contains references to file paths, binary security keys, and/or ciphersuite lists. It is the user's responsibility to appropriately allocate them and ensure proper lifetime of the returned pointers. The returned security information may only be invalidated in a call to anjay_fw_update_reset_t or after a call to anjay_delete .

If this handler is not implemented at all (with the corresponding field set to NULL), anjay_security_config_from_dm will be used as a default way to get security information.

WARNING: If the aforementioned anjay_security_config_from_dm function won't find any server connection that matches the download_uri by protocol, hostname and port triple, it'll attempt to match a configuration just by the hostname. This may cause Anjay to use wrong security configuration, e.g. in case when both CoAPS LwM2M server and HTTPS firmware package server have the same hostname, but require different security configs.

If no user-defined handler is provided and the call to anjay_security_config_from_dm fails (including case when no matching LwM2M Security Object instance is found, even just by the hostname), anjay_security_config_pkix will be used as an additional fallback if ANJAY_WITH_LWM2M11 is enabled and a valid trust store is available (either specified through use_system_trust_store, trust_store_certs or trust_store_crls fields in anjay_configuration_t, or obtained via /est/crts request if est_cacerts_policy is set to ANJAY_EST_CACERTS_IF_EST_CONFIGURED or ANJAY_EST_CACERTS_ALWAYS).

You may also use those aforementioned functions (anjay_security_config_from_dm, anjay_security_config_pkix) in your callback, for example as a fallback mechanism.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
out_security_configPointer in which the handler shall fill in security configuration to use for download. Note that leaving this value as empty without filling it in will result in a configuration that is valid, but very insecure: it will cause any server certificate to be accepted without validation. Any pointers used within the supplied structure shall remain valid until either a call to anjay_fw_update_reset_t, or exit to the event loop (from either anjay_serve, anjay_sched_run or anjay_fw_update_install), whichever happens first. Anjay will not attempt to deallocate anything automatically.
download_uriTarget firmware URI.
Returns
The callback shall return 0 if successful or a negative value in case of error. If one of the ANJAY_FW_UPDATE_ERR_* value is returned, an equivalent value will be set in the Update Result Resource.

◆ anjay_fw_update_get_tcp_request_timeout_t

typedef avs_time_duration_t anjay_fw_update_get_tcp_request_timeout_t(void *user_ptr, const char *download_uri)

Returns request timeout to be used during firmware update over CoAP+TCP or HTTP.

If this handler is not implemented at all (with the corresponding field set to NULL), coap_tcp_request_timeout from anjay_t object will be used for CoAP+TCP, and AVS_NET_SOCKET_DEFAULT_RECV_TIMEOUT (i.e., 30 seconds) will be used for HTTP.

NOTE: This callback is called even for non-TCP downloads, but the returned transmission parameters are ignored in that case.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install .
download_uriTarget firmware URI.
Returns
The desired request timeout. If the value returned is non-positive (including zero and invalid value), the default will be used.

◆ anjay_fw_update_get_version_t

typedef const char* anjay_fw_update_get_version_t(void *user_ptr)

Returns the version of downloaded firmware package.

The version will be exposed in the data model as the PkgVersion Resource. If this callback returns NULL or is not implemented at all (with the corresponding field set to NULL), that Resource will not be present in the data model.

It only makes sense for this handler to return non-NULL values if there is a valid package already downloaded. The library will not call this handler in any state other than Downloaded.

The library will not attempt to deallocate the returned pointer. User code must assure that the pointer will remain valid at least until return from anjay_serve or anjay_sched_run .

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
Returns
The callback shall return a pointer to a null-terminated string containing the package version, or NULL if it is not currently available.

◆ anjay_fw_update_perform_upgrade_t

typedef int anjay_fw_update_perform_upgrade_t(void *user_ptr)

Performs the actual upgrade with previously downloaded package.

Will be called at request of the server, after a package has been downloaded.

Most users will want to implement firmware update in a way that involves a reboot. In such case, it is expected that this callback will do either one of the following:

  • perform firmware upgrade, terminate outermost event loop and return, call reboot after anjay_event_loop_run()
  • perform the firmware upgrade internally and then reboot, it means that the return will never happen (although the library won't be able to send the acknowledgement to execution of Update resource)

After rebooting, the result of the upgrade process may be passed to the library during initialization via the initial_result argument to anjay_fw_update_install .

Alternatively, if the update can be performed without reinitializing Anjay, you can use anjay_fw_update_set_result (either from within the handler or some time after returning from it) to pass the update result.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
Returns
The callback shall return a negative value if it can be determined without a reboot that the firmware upgrade cannot be successfully performed.

If one of the ANJAY_FW_UPDATE_ERR_* values is returned, an equivalent value will be set in the Update Result Resource. Otherwise, if a non-zero value is returned, the Update Result Resource is set to generic "Firmware update failed" code.

◆ anjay_fw_update_reset_t

typedef void anjay_fw_update_reset_t(void *user_ptr)

Resets the firmware update state and performs any applicable cleanup of temporary storage if necessary.

Will be called at request of the server, or after a failed download. Note that it may be called without previously calling anjay_fw_update_stream_finish_t, so it shall also close the currently open download stream, if any.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install

◆ anjay_fw_update_stream_finish_t

typedef int anjay_fw_update_stream_finish_t(void *user_ptr)

Closes the download stream and prepares the firmware package to be flashed.

Will be called after a series of anjay_fw_update_stream_write_t calls after the whole package is downloaded.

The intended way of implementing this handler is to e.g. call fclose() and perform integrity check on the downloaded file. It might also be uncompressed or decrypted as necessary, so that it is ready to be flashed. The exact split of responsibility between anjay_fw_update_stream_finish_t and anjay_fw_update_perform_upgrade_t is not clearly defined and up to the implementor.

Note that regardless of the return value, the stream is considered to be closed. That is, upon successful return, the Firmware Update object is considered to be in the Downloaded state, and upon returning an error - in the Idle state.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
Returns
The callback shall return 0 if successful or a negative value in case of error. If one of the ANJAY_FW_UPDATE_ERR_* value is returned, an equivalent value will be set in the Update Result Resource.

◆ anjay_fw_update_stream_open_t

typedef int anjay_fw_update_stream_open_t(void *user_ptr, const char *package_uri, const struct anjay_etag *package_etag)

Opens the stream that will be used to write the firmware package to.

The intended way of implementing this handler is to open a temporary file using fopen() or allocate some memory buffer that may then be used to store the downloaded data in. The library will not attempt to call anjay_fw_update_stream_write_t without having previously called anjay_fw_update_stream_open_t . Please see anjay_fw_update_handlers_t for more information about state transitions.

Note that this handler will NOT be called after initializing the object with the ANJAY_FW_UPDATE_INITIAL_DOWNLOADING option, so any necessary resources shall be already open before calling anjay_fw_update_install .

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
package_uriURI of the package from which a Pull-mode download is performed, or NULL if it is a Push-mode download. This argument may either be ignored, or persisted in non-volatile storage if the client supports download resumption after an unexpected reboot (see anjay_fw_update_initial_state_t and its fields).
package_etagETag of the data being downloaded in Pull mode, or NULL if it is a Push-mode download or ETags are not supported by the remote server. This argument may either be ignored, or persisted in non-volatile storage if the client supports download resumption after an unexpected reboot (see anjay_fw_update_initial_state_t and its fields).
Returns
The callback shall return 0 if successful or a negative value in case of error. Error codes are NOT handled here, so attempting to return ANJAY_FW_UPDATE_ERR_* values will NOT cause any effect different than any other negative value.

◆ anjay_fw_update_stream_write_t

typedef int anjay_fw_update_stream_write_t(void *user_ptr, const void *data, size_t length)

Writes data to the download stream.

May be called multipled times after anjay_fw_update_stream_open_t, once for each consecutive chunk of downloaded data.

Parameters
user_ptrOpaque pointer to user data, as passed to anjay_fw_update_install
dataPointer to a chunk of the firmware package being downloaded. Guaranteed to be non-NULL.
lengthNumber of bytes in the chunk pointed to by data. Guaranteed to be greater than zero.
Returns
The callback shall return 0 if successful or a negative value in case of error. If one of the ANJAY_FW_UPDATE_ERR_* value is returned, an equivalent value will be set in the Update Result Resource.

Enumeration Type Documentation

◆ anjay_fw_update_initial_result_t

Possible values that control the State and Update Result resources at the time of initialization of the Firmware Update object.

Enumerator
ANJAY_FW_UPDATE_INITIAL_UPDATING 

Corresponds to the "Updating" State and "Initial" Result. Shall be used when the device rebooted as part of the update process, but the firmware image is not fully applied yet. The application MUST use anjay_fw_update_set_result to set the result to success or failure after the update process is complete.

ANJAY_FW_UPDATE_INITIAL_DOWNLOADED 

Corresponds to the "Downloaded" State and "Initial" Result. Shall be used when the device unexpectedly rebooted when the firmware image has already been downloaded into some non-volatile memory.

ANJAY_FW_UPDATE_INITIAL_DOWNLOADING 

Corresponds to the "Downloading" State and "Initial" Result. Shall be used when the device can determine that it unexpectedly rebooted during the download of the firmware image, and it has all the information necessary to resume the download. Such information shall then be passed via other fields in the anjay_fw_update_initial_state_t structure.

ANJAY_FW_UPDATE_INITIAL_NEUTRAL 

Corresponds to the "Idle" State and "Initial" Result. Shall be used when the library is initializing normally, not after a firmware update attempt.

ANJAY_FW_UPDATE_INITIAL_SUCCESS 

Corresponds to the "Idle" State and "Firmware updated successfully" Result. Shall be used when the device has just rebooted after successfully updating the firmware.

ANJAY_FW_UPDATE_INITIAL_INTEGRITY_FAILURE 

Corresponds to the "Idle" State and "Integrity check failure" Result. Shall be used when the device has just rebooted after an unsuccessful firmware update attempt that failed due to failed integrity check of the firmware package.

ANJAY_FW_UPDATE_INITIAL_FAILED 

Corresponds to the "Idle" State "Firmware update failed" Result. Shall be used when the device has just rebooted after a firmware upgrade attempt that was unsuccessful for reason any other than integrity check.

◆ anjay_fw_update_result_t

Numeric values of the Firmware Update Result resource. See LwM2M specification for details.

Note: they SHOULD only be used with anjay_fw_update_set_result .

Enumerator
ANJAY_FW_UPDATE_RESULT_INITIAL 
ANJAY_FW_UPDATE_RESULT_SUCCESS 
ANJAY_FW_UPDATE_RESULT_NOT_ENOUGH_SPACE 
ANJAY_FW_UPDATE_RESULT_OUT_OF_MEMORY 
ANJAY_FW_UPDATE_RESULT_CONNECTION_LOST 
ANJAY_FW_UPDATE_RESULT_INTEGRITY_FAILURE 
ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PACKAGE_TYPE 
ANJAY_FW_UPDATE_RESULT_INVALID_URI 
ANJAY_FW_UPDATE_RESULT_FAILED 
ANJAY_FW_UPDATE_RESULT_UNSUPPORTED_PROTOCOL 

Function Documentation

◆ anjay_fw_update_install()

int anjay_fw_update_install ( anjay_t anjay,
const anjay_fw_update_handlers_t handlers,
void *  user_arg,
const anjay_fw_update_initial_state_t initial_state 
)

Installs the Firmware Update object in an Anjay object.

The Firmware Update module does not require explicit cleanup; all resources will be automatically freed up during the call to anjay_delete.

Parameters
anjayAnjay object for which the Firmware Update Object is installed.
handlersPointer to a set of handler functions that handle the platform-specific part of firmware update process. Note: Contents of the structure are NOT copied, so it needs to remain valid for the lifetime of the object.
user_argOpaque user pointer that will be passed as the first argument to handler functions.
initial_stateInformation about the state to initialize the Firmware Update object in. It is intended to be used after either an orderly reboot caused by a firmware update attempt to report the update result, or by an unexpected reboot in the middle of the download process. If the object shall be initialized in a neutral initial state, NULL might be passed.
Returns
0 on success, or a negative value in case of error.

◆ anjay_fw_update_pull_reconnect()

int anjay_fw_update_pull_reconnect ( anjay_t anjay)

Reconnects any ongoing PULL-mode downloads in the Firmware Update module. Which could be disconnected due to connection loss or deliberate suspend. In the latter case, when PULL-mode downloads are suspended (see anjay_fw_update_pull_suspend), resumes normal operation.

If an ongoing PULL-mode download exists, this will call anjay_download_reconnect internally, so you may want to reference the documentation of that function for details.

Parameters
anjayAnjay object to operate on.
Returns
0 for success; -1 if anjay does not have the Firmware Update object installed or if the call to anjay_download_reconnect fails.

◆ anjay_fw_update_pull_suspend()

void anjay_fw_update_pull_suspend ( anjay_t anjay)

Suspends the operation of PULL-mode downloads in the Firmware Update module.

This will have the effect of suspending any ongoing downloads (see anjay_download_suspend for details), as well as preventing new downloads from being started.

When PULL-mode downloads are suspended, anjay_fw_update_stream_open_t will NOT be called when a download request is issued. However, anjay_fw_update_get_security_config_t, anjay_fw_update_get_coap_tx_params_t and anjay_fw_update_get_tcp_request_timeout_t will be called. You may call anjay_fw_update_pull_reconnect from one of these functions if you decide to accept the download immediately after all.

Parameters
anjayAnjay object to operate on.

◆ anjay_fw_update_set_result()

int anjay_fw_update_set_result ( anjay_t anjay,
anjay_fw_update_result_t  result 
)

Sets the Firmware Update Result to result, interrupting the update process.

A successful call to this function always sets Update State to Idle (0). If the function fails, neither Update State nor Update Result are changed.

Some state transitions are disallowed and cause this function to fail:

  • ANJAY_FW_UPDATE_RESULT_INITIAL and ANJAY_FW_UPDATE_RESULT_UPDATE_CANCELLED are never allowed and cause this function to fail.
  • ANJAY_FW_UPDATE_RESULT_SUCCESS is only allowed if the firmware application process was started by the server (an Execute operation was already performed on the Update resource of the Firmware Update object or ANJAY_FW_UPDATE_INITIAL_UPDATING was used in a call to anjay_fw_update_install). Otherwise, the function fails.
  • Other values of result (various error codes) are only allowed if Firmware Update State is not Idle (0), i.e. firmware is being downloaded, was already downloaded or is being applied.

WARNING: calling this in anjay_fw_update_perform_upgrade_t handler is supported, but the result of using it from within any other of anjay_fw_update_handlers_t handlers is undefined.

Parameters
anjayAnjay object to operate on.
resultValue of the Update Result resource to set.
Returns
0 on success, or a negative value in case of error.