Tizen Update Control Native API
Update Control API allows to control the system software version of the IoT device. System software version control includes:
- Checking for the latest version
- Downloading and updating to the latest version in a synchronous or an asynchronous manner
- Making a time reservation for the update.
The update procedure and the server may vary depending on the platform developer. Therefore, this API only offers general update functions, and platform developers must develop the application using Update Control API properly.
Prerequisites
Steps to enable your application to use the update control functionality:
-
To use the Update Control API, the application must request permissions by adding the following privileges to the
tizen-manifest.xml
file:<privileges> <privilege>http://tizen.org/privilege/updatecontrol.admin</privilege> </privileges>
-
To use the functions and data types of the Update Control API, include the
<update_control.h>
header file in your application:#include <update_control.h>
Connecting to Server
The new version of the platform is usually uploaded at the server and each device must connect to server to get the new version.
In some cases, connecting to server might require the procedure for getting the account information. The account information is obtained using update_control_initialize()
or at the each update operations such as checking or downloading and updating the latest version.
Example: Initializing update control
int error_code;
error_code = update_control_initialize();
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
// Use `update_control_*()` functions here
Note
After you used
update_control_initialize()
and are done usingupdate_control_*()
functions, remember to deinitialize withupdate_control_deinitialize()
.
Checking the Latest Version
The device can query the latest version of current platform to the server. It can be implemented as the following:
int error_code;
error_code = update_control_check_new_version();
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
If the newer version of platform is available, the correct value and type for UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE
that depends on the platform developer will be set. The application can get this value through the update_control_get_property()
function:
int error_code;
int* is_available;
error_code = update_control_get_property(UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE, (void **)(&is_available));
if (error_code == UPDATE_CONTROL_ERROR_NONE) {
if (*is_available) {
// New version platform is available
...
}
// Note: the function allocates memory and the caller has to free
free(is_available);
}
Downloading and Updating to New Version - basic usage
If the newer version is available, you can download and update the system software to the latest available version.
The functions update_control_download_package()
and update_control_do_update()
are offered and their usage is similar to update_control_check_new_version()
:
int error_code;
error_code = update_control_download_package();
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
error_code = update_control_do_update();
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
Usually, downloading and updating are processed sequentially but the application also can call each function separately (for example to only download) to perform the intended operation.
Updating to New Version - advanced usage
There are 3 types of update routines: update_control_do_update()
is the basic way to trigger an upgrade. The other two
functions: update_control_do_ro_update_async()
and update_control_do_finish_update_async()
allow to hook up callbacks
which will be triggered when the associated operation is completed.
-
update_control_do_update()
- triggers the upgrade script and tells it to execute both the RO upgrade and the RW upgrade operations (full upgrade process, with reboot). This function only runs the upgrade script in the background and returns quickly. It doesn’t check the return value of the upgrade script. It only allows to check if the RO and RW upgrade have been triggered successfully which doesn’t guarantee successful completion. -
update_control_do_ro_update_async()
- triggers the upgrade script and tells it to execute RO upgrade only. This function does not perform the RW upgrade, nor does it trigger reboot. Once the operation has completed, the callback set by theupdate_control_set_ro_update_cb()
will be triggered. -
update_control_do_finish_update_async()
- triggers the upgrade script and tells it to reboot and execute only the RW upgrade after reboot. This function does not perform the RO upgrade. For it to be successful, RO upgrade has to be completed beforehand. To trigger the RO upgrade useupdate_control_do_ro_update_async()
. Once the operation has finished, the callback set byupdate_control_set_finish_update_cb()
will be triggered on failure. In case of success the callback will not be called, because the system will restart. The callback will provideUPDATE_CONTROL_ERROR_RO_UPDATE_IN_PROGRESS
if RO upgrade is still in progress andUPDATE_CONTROL_ERROR_RO_UPDATE_NOT_COMPLETED
if RO upgrade is not in progress and has not completed (either never triggered or stopped mid run). In other cases, a code provided by the callback will indicate a failure. -
update_control_set_ro_update_cb()
- sets a callback to trigger once RO upgrade operation has completed (either successfully or erroneously). -
update_control_unset_ro_update_cb()
- unsets the callback set byudpate_control_set_ro_update_cb()
. -
update_control_set_finish_update_cb()
- sets a callback to trigger once RW upgrade operation has completed (either successfully or erroneously). -
update_control_unset_finish_update_cb()
- unsets the callback set byudpate_control_set_finish_update_cb()
.
Making an Update Reservation
The availability of the IoT device might be critical for its operation. Because updating procedure might include
unavailable time (for example, rebooting), it needs to schedule software update at a specific time.
In this case, the application can use the update_control_make_reservation()
function:
int error_code;
struct tm time;
// Set the "time" to trigger the update
error_code = update_control_make_reservation(&time);
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
The reserved update task can also be canceled by update_control_cancel_reservation()
.
int error_code;
error_code = update_control_cancel_reservation();
if (error_code != UPDATE_CONTROL_ERROR_NONE)
return;
Note
It assumes only one update reservation can be set. If the platform supports multiple reservations, then they must properly manage cancel request. Also, an implementation might cancel the reservation if
update_control_deinitialize()
is called or the calling process is killed.
Example
The following example initializes the update-control API, checks for a new version and if present downloads the update package,
hooks up an RO upgrade callback, and triggers the RO upgrade with the asynchronous update_control_do_ro_update_async
API function.
The callback will be called regardless of the success of the operation, because the upgrade is RO. Note that if we were to call
update_control_do_finish_update_async()
instead, the callback will not be triggered if it’s successful - the system will reboot.
#include <gio/gio.h>
#include <stdio.h>
#include <update_control.h>
static GMainLoop *main_loop = NULL;
void ro_update_control_cb(const update_control_error_e result, const void *user_data)
{
if (result != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "RO upgrade failed, error code: %d\n", result);
}
else {
fprintf(stderr, "RO upgrade succeeded\n");
}
g_main_loop_quit(main_loop);
g_main_loop_unref(main_loop);
}
int main(int argc, char **argv)
{
int error_code;
int *available;
error_code = update_control_initialize();
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Cannot initialize update control, error code: %d\n", error_code);
return 1;
}
error_code = update_control_check_new_version();
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Cannot check for new version, error code: %d\n", error_code);
return 1;
}
error_code = update_control_get_property(UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE, (void **) &available);
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Unable to get property %d, error code: %d\n", UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE, error_code);
return 1;
}
if (!(*available)) {
printf("New package is not available - not performing upgrade\n");
return 0;
}
error_code = update_control_download_package();
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Failed to download update package, error code: %d\n", error_code);
return 1;
}
// Needed for callbacks
main_loop = g_main_loop_new(NULL, FALSE);
error_code = update_control_set_ro_update_cb(ro_update_control_cb, NULL);
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Failed to set callback for RO upgrade, error code: %d\n", error_code);
return 1;
}
error_code = update_control_do_ro_update_async();
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Failed to trigger RO upgrade, error code: %d\n", error_code);
return 1;
}
// Waits on a callback
g_main_loop_run(main_loop);
// You need to deinitialize in case of an error - for brevity's sake we only deinitialize if everything was a success
error_code = update_control_deinitialize();
if (error_code != UPDATE_CONTROL_ERROR_NONE) {
fprintf(stderr, "Failed to deinitialize update control, error code:: %d\n", error_code);
return 1;
}
// Similar to the remark above; this needs to be freed in case of an error as well
free(available);
return 0;
}
Update Properties
Besides UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE
mentioned in the code, there more properties related to update-control.
You can get them through update_control_get_property()
function following keys:
Key | Description | Type (example) |
---|---|---|
UPDATE_CONTROL_PROPERTY_NEW_VERSION |
The value of new version (For example, string, and number). | string |
UPDATE_CONTROL_PROPERTY_PACKAGE_URI |
URI of update package | string |
UPDATE_CONTROL_PROPERTY_RESULT |
The current upgrade progress value ($[0, 100]$ or negative) | int |
UPDATE_CONTROL_PROPERTY_PACKAGE_SIZE |
The size of update package to be downloaded. | unsigned int |
UPDATE_CONTROL_PROPERTY_DESCRIPTION |
The description about found version. | string |
UPDATE_CONTROL_PROPERTY_UPDATE_AVAILABLE |
The flag of update availability. | int |
Because their actual types depend on platform developer, the value that will be returned for each key must be known to the application.
Note
Key support is implementation dependent. Be sure to check
update_control_get_property()
return value.
Error Codes
The following error codes (not necessarily indicating an error) may occur while working with the update-control API functions:
Error code | Description |
---|---|
UPDATE_CONTROL_ERROR_NONE |
Successful |
UPDATE_CONTROL_ERROR_INVALID_PARAMETER |
Invalid parameter |
UPDATE_CONTROL_ERROR_OUT_OF_MEMORY |
Out of memory |
UPDATE_CONTROL_ERROR_FILE_NO_SPACE_ON_DEVICE |
No space left on device |
UPDATE_CONTROL_ERROR_KEY_NOT_FOUND |
Specified key is not available |
UPDATE_CONTROL_ERROR_KEY_REJECTED |
Key is not available |
UPDATE_CONTROL_ERROR_NOT_SUPPORTED |
Not supported |
UPDATE_CONTROL_ERROR_PERMISSION_DENIED |
Permission denied |
UPDATE_CONTROL_ERROR_CONNECTION_ABORTED |
Software caused connection abort |
UPDATE_CONTROL_ERROR_CONNECTION_REFUSED |
Connection refused |
UPDATE_CONTROL_ERROR_PROTOCOL_NOT_SUPPORTED |
Protocol not supported |
UPDATE_CONTROL_ERROR_TIMED_OUT |
Time out |
UPDATE_CONTROL_ERROR_RESOURCE_BUSY |
Device or resource busy |
UPDATE_CONTROL_ERROR_INVALID_OPERATION |
Function not implemented |
UPDATE_CONTROL_ERROR_INVALID_PACKAGE |
Invalid package |
UPDATE_CONTROL_ERROR_INVALID_URI |
Invalid URI |
UPDATE_CONTROL_ERROR_PACKAGE_NOT_SUPPORTED |
Package type not supported |
UPDATE_CONTROL_ERROR_SYSTEM_ERROR |
System error |
UPDATE_CONTROL_ERROR_RO_UPDATE_IN_PROGRESS |
RO update is in progress |
UPDATE_CONTROL_ERROR_RO_UPDATE_NOT_COMPLETED |
RO update has not completed |