#include <stdio.h>
#include <stdlib.h>
#include <storage.h>
+#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <vconf.h>
}
return 0;
-}
\ No newline at end of file
+}
+++ /dev/null
-#include "../common/common.h"
-#include "fota-manager.h"
-
-#define FOTA_DELTA_BUILD_STRING_DIR "/tmp"
-#define FOTA_DELTA_BUILD_STRING_FILENAME "build_id.txt"
-#define FOTA_DELTA_BUILD_STRING_PATH FOTA_DELTA_BUILD_STRING_DIR "/" FOTA_DELTA_BUILD_STRING_FILENAME
-
-int fota_delta_verify(const char *path, const char *old_build_string, const char *new_build_string)
-{
- int ret = 0, status = 0;
- char buf[MAX_BUFFER_SIZE] = {0, };
- FILE *fp = NULL;
-
- if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
- _FLOGI("Not found delta in %s", path);
- status = -2;
- goto verify_destroy;
- }
-
- if (old_build_string == NULL) {
- _FLOGE("Failed to try verify, old build string must be passed");
- status = -3;
- goto verify_destroy;
- }
-
- _FLOGI("Found delta in %s, start process to verify", path);
- ret = util_file_untar(path, FOTA_DELTA_BUILD_STRING_DIR, FOTA_DELTA_BUILD_STRING_FILENAME);
- if (ret < 0) {
- status = -1;
- goto verify_destroy;
- }
-
- fp = fopen(FOTA_DELTA_BUILD_STRING_PATH, "r");
- if (fp == NULL) {
- _FLOGE("Failed to open : %s", FOTA_DELTA_BUILD_STRING_PATH);
- status = -1;
- goto verify_destroy;
- }
-
- if (fgets(buf, MAX_BUFFER_SIZE, fp) == NULL) {
- _FLOGE("Failed to read : %s", FOTA_DELTA_BUILD_STRING_PATH);
- status = -1;
- goto verify_destroy;
- }
-
- if (g_strrstr(buf, old_build_string) == NULL) {
- _FLOGI("Unmatched occur, old_build_string : %s, delta : %s", old_build_string, buf);
- status = -4;
- goto verify_destroy;
- }
-
- if (new_build_string != NULL) {
- if (fgets(buf, MAX_BUFFER_SIZE, fp) == NULL) {
- _FLOGE("Failed to read : %s", FOTA_DELTA_BUILD_STRING_PATH);
- status = -1;
- goto verify_destroy;
- }
-
- if (g_strrstr(buf, new_build_string) == NULL) {
- _FLOGI("Unmatched occur, new_build_string : %s, delta : %s", new_build_string, buf);
- status = -4;
- goto verify_destroy;
- }
- }
-
- _FLOGI("Success to verify %s, old : %s, new : %s", path, old_build_string, new_build_string);
-
-verify_destroy:
- util_file_remove(FOTA_DELTA_BUILD_STRING_PATH);
-
- if (fp)
- fclose(fp);
-
- return status;
-}
\ No newline at end of file
#include "fota-manager.h"
#define SYSTEM_INFO_BUILD_STRING "tizen.org/system/build.string"
-#define SYSTEM_INFO_PLATFORM_VERSION "tizen.org/feature/platform.version"
static char *build_string = NULL;
-static char *platform_version = NULL;
char *fota_info_get_build_string()
{
return build_string;
}
-char *fota_info_get_platform_version()
-{
- return platform_version;
-}
-
int fota_info_checker_init()
{
int ret = 0;
return -1;
}
- ret = system_info_get_platform_string(SYSTEM_INFO_PLATFORM_VERSION, &platform_version);
- if (ret != SYSTEM_INFO_ERROR_NONE) {
- _FLOGE("system_info_get_platform_string failed : %d", ret);
- return -1;
- }
-
- _FLOGI("Success to get fota information, platform : %s, build_string : %s",
- platform_version, build_string);
+ _FLOGI("Success to get fota information, build_string : %s", build_string);
return 0;
}
if (build_string)
free(build_string);
- if (platform_version)
- free(platform_version);
-
return 0;
-}
\ No newline at end of file
+}
#define APP_SHARED_DATA "shared/data"
#define FOTA_DIR "/opt/usr/data/fota"
-#define FOTA_DELTA_PATH FOTA_DIR "/" FOTA_DELTA_FILENAME
-#define FOTA_DELTA_UA_FILE "delta.ua"
+#define FOTA_TRIGGER_FILE "upgrade-trigger.sh"
+#define FOTA_TRIGGER_PATH FOTA_DIR "/" FOTA_TRIGGER_FILE
-#define FOTA_STATUS_DELTA_PATH FOTA_STATUS_DIR "/DELTA.PATH"
+#define FOTA_INSTALL_REBOOT_REASON "fota"
-int fota_installer_setup_delta()
-{
- int ret = 0;
- char *appid = NULL, *build_string = NULL;
- gchar *shared_path = NULL;
- ret = util_file_mkdir(FOTA_DIR);
- if (ret < 0)
- return -1;
+int fota_installer_execute()
+{
+ int ret = 0, status = 0, exec_status = 0;
+ char buf[MAX_BUFFER_SIZE] = {0, };
+ char *appid = NULL, *old_build_string = NULL;
+ gchar *client_delta_path = NULL;
+ pid_t pid;
+ /* 1. Check client have delta.tar */
appid = fota_client_info_get_appid();
if (appid == NULL) {
_FLOGE("Failed to get client app id");
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- build_string = fota_info_get_build_string();
- if (build_string == NULL) {
- _FLOGE("Failed to get build string");
- return -1;
+ client_delta_path = g_strjoin("/", APP_SHARED_DIR, appid, APP_SHARED_DATA, FOTA_DELTA_FILENAME, NULL);
+ if (!g_file_test(client_delta_path, G_FILE_TEST_EXISTS)) {
+ _FLOGI("%s doesn't have delta.tar", appid);
+ status = -2;
+ goto execute_destroy;
}
- shared_path = g_strjoin("/", APP_SHARED_DIR, appid, APP_SHARED_DATA, FOTA_DELTA_FILENAME, NULL);
- ret = fota_delta_verify(shared_path, build_string, NULL);
+ /* 2. Check client have appropriate delta */
+ ret = util_file_untar(client_delta_path, FOTA_DELTA_BUILD_STRING_DIR, FOTA_DELTA_BUILD_STRING_FILENAME);
if (ret < 0) {
- _FLOGE("Failed to verify delta : %d, path : %s, old_build_string : %s",
- ret, shared_path, build_string);
- g_free(shared_path);
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- ret = util_file_symlink(shared_path, FOTA_DELTA_PATH);
+ ret = util_file_read_single_line(FOTA_DELTA_BUILD_STRING_PATH, buf);
if (ret < 0) {
- g_free(shared_path);
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- g_free(shared_path);
-
- ret = util_file_untar(FOTA_DELTA_PATH, FOTA_DIR, FOTA_DELTA_UA_FILE);
- if (ret < 0)
- return -1;
- _FLOGI("Success to setup delta to %s", FOTA_DIR);
- return 0;
-}
-
-int fota_installer_setup_platform_version()
-{
- int ret = 0;
- char *platform_version = NULL;
- gchar *formatted_version = NULL;
-
- platform_version = fota_info_get_platform_version();
- if (platform_version == NULL) {
- _FLOGE("Failed to get platform version");
- return -1;
+ old_build_string = fota_info_get_build_string();
+ if(old_build_string == NULL) {
+ _FLOGE("Failed to get current image build string");
+ status = -1;
+ goto execute_destroy;
}
- switch(strlen(platform_version)) {
- case 1:
- formatted_version = g_strconcat("OLD_VER=", platform_version, ".0.0.0\n", NULL);
- break;
- case 3:
- formatted_version = g_strconcat("OLD_VER=", platform_version, ".0.0\n", NULL);
- break;
- case 5:
- formatted_version = g_strconcat("OLD_VER=", platform_version, ".0\n", NULL);
- break;
- case 7:
- formatted_version = g_strconcat("OLD_VER=", platform_version, "\n", NULL);
- break;
- default:
- _FLOGE("Unexpected version string : %s", platform_version);
- return -1;
+ if (g_str_has_prefix(buf, old_build_string) != TRUE) {
+ _FLOGI("%s doesn't have appropriate delta(%s), delta build string(%s)",
+ appid, old_build_string, buf);
+ status = -3;
+ goto execute_destroy;
}
-
- ret = util_file_write_line(FOTA_INSTALL_PLATFORM_VERSION_PATH, formatted_version);
- if (ret < 0) {
- g_free(formatted_version);
- return -1;
- }
-
- _FLOGI("Success to setup version to %s : %s", FOTA_INSTALL_PLATFORM_VERSION_PATH, formatted_version);
- g_free(formatted_version);
-
- return 0;
-}
-
-int fota_installer_setup_status()
-{
- int ret = 0;
+ /* 3. Setup local update flag */
ret = util_file_mkdir(FOTA_STATUS_DIR);
- if (ret < 0)
- return -1;
+ if (ret < 0) {
+ status = -1;
+ goto execute_destroy;
+ }
ret = util_file_write_line(FOTA_STATUS_FLAG_PATH, NULL);
- if (ret < 0)
- return -1;
-
- ret = util_file_write_line(FOTA_STATUS_DELTA_PATH, FOTA_DIR);
- if (ret < 0)
- return -1;
-
- _FLOGI("Success to setup fota status");
- return 0;
-}
-
-int fota_installer_execute()
-{
- int ret = 0;
-
- ret = fota_installer_setup_delta();
if (ret < 0) {
- _FLOGE("Failed to setup delta.tar : %d", ret);
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- ret = fota_installer_setup_platform_version();
+ /* 4. Trigger update */
+ ret = util_file_mkdir(FOTA_DIR);
if (ret < 0) {
- _FLOGE("Failed to setup platform version : %d", ret);
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- ret = fota_installer_setup_status();
+ ret = util_file_untar(client_delta_path, FOTA_DIR, FOTA_TRIGGER_FILE);
if (ret < 0) {
- _FLOGE("Failed to setup fota status : %d", ret);
- return -1;
+ status = -1;
+ goto execute_destroy;
+ }
+
+ pid = fork();
+ if (pid < 0) {
+ _FLOGE("Failed to fork");
+ status = -1;
+ goto execute_destroy;
+ } else if (pid == 0) {
+ ret = execl(FOTA_TRIGGER_PATH, FOTA_TRIGGER_PATH, client_delta_path, NULL);
+ if (ret == -1)
+ _FLOGE("Failed to execl(%s %s)", FOTA_TRIGGER_PATH, client_delta_path);
+
+ exit(EXIT_FAILURE);
+ }
+
+ ret = wait(&exec_status);
+ if (ret == -1) {
+ _FLOGE("Failed to wait child");
+ status = -1;
+ goto execute_destroy;
+ }
+
+ if (WIFEXITED(exec_status) == TRUE) {
+ exec_status = WEXITSTATUS(exec_status);
+ if (exec_status != 100) {
+ _FLOGE("Trigger fota failed, exit code(%d)", exec_status);
+ status = -4;
+ goto execute_destroy;
+ }
+ } else if (WIFSIGNALED(exec_status) == TRUE) {
+ _FLOGE("Trigger fota killed, signal(%d)", WTERMSIG(exec_status));
+ status = -4;
+ goto execute_destroy;
+ } else if (WIFSTOPPED(exec_status) == TRUE) {
+ _FLOGE("Trigger fota stoped, signal(%d)", WSTOPSIG(exec_status));
+ status = -4;
+ goto execute_destroy;
+ } else {
+ _FLOGE("Unexpected wait error");
+ status = -1;
+ goto execute_destroy;
}
ret = device_power_reboot(FOTA_INSTALL_REBOOT_REASON);
if (ret != DEVICE_ERROR_NONE) {
_FLOGE("Failed to reboot with %s", FOTA_INSTALL_REBOOT_REASON);
- return -1;
+ status = -1;
+ goto execute_destroy;
}
- _FLOGI("Success to reboot with %s, device will reboot", FOTA_INSTALL_REBOOT_REASON);
- return 0;
+ _FLOGI("Success to trigger fota, device will be rebooted");
+
+execute_destroy:
+ util_file_remove(FOTA_DELTA_BUILD_STRING_PATH);
+
+ if (client_delta_path)
+ free(client_delta_path);
+
+ return status;
}
/* Constant */
#define FOTA_DELTA_FILENAME "delta.tar"
-#define FOTA_INSTALL_PLATFORM_VERSION_PATH "/opt/etc/version"
-#define FOTA_INSTALL_REBOOT_REASON "fota"
+#define FOTA_DELTA_BUILD_STRING_DIR "/tmp"
+#define FOTA_DELTA_BUILD_STRING_FILENAME "build_string.txt"
+#define FOTA_DELTA_BUILD_STRING_PATH FOTA_DELTA_BUILD_STRING_DIR "/" FOTA_DELTA_BUILD_STRING_FILENAME
#define FOTA_STATUS_DIR "/opt/data/update"
#define FOTA_STATUS_FLAG_PATH FOTA_STATUS_DIR "/is-first-boot-after-fota"
int fota_client_info_checker_fini(void);
char *fota_client_info_get_appid(void);
-int fota_delta_verify(const char *, const char *, const char *);
-
int fota_info_checker_init(void);
int fota_info_checker_fini(void);
char *fota_info_get_build_string(void);
-char *fota_info_get_platform_version(void);
int fota_installer_execute(void);
-
int fota_result_sender_execute(void);
int fota_status_checker_init(void);
#include "../common/common.h"
#include "fota-manager.h"
-#define FOTA_STORAGE_FOLDER_TOKEN "@"
-
static int fota_storage_id = -1;
-int fota_storage_verify_delta(const char* mount_path, const char *folder_name, gchar **delta_path)
+
+gchar *fota_storage_find_delta(const char* mount_path, const char *folder_name)
{
- int ret = 0, status = 0;
+ int ret = 0;
+ bool is_appropriate = false;
+ char buf[MAX_BUFFER_SIZE] = {0, };
char *old_build_string = NULL;
- gchar *new_build_string = NULL, *path = NULL;
+ gchar *storage_delta_path = NULL;
+ /* 1. Check storage support current image */
old_build_string = fota_info_get_build_string();
if (old_build_string == NULL) {
- _FLOGE("Failed to get build string");
- return -1;
+ _FLOGE("Failed to get current image build string");
+ goto verify_destroy;
}
if (g_str_has_prefix(folder_name, old_build_string) != TRUE) {
- _FLOGI("Folder %s is not start with %s, pass", folder_name, old_build_string);
- return -1;
+ _FLOGI("Storage doesn't support current image(%s), folder name(%s)",
+ old_build_string, folder_name);
+ goto verify_destroy;
}
- new_build_string = strstr(folder_name, FOTA_STORAGE_FOLDER_TOKEN);
- if (new_build_string == NULL) {
- _FLOGI("Folder %s doesn't have token : %s", folder_name, FOTA_STORAGE_FOLDER_TOKEN);
- return -1;
+ /* 2. Check storage have delta.tar */
+ storage_delta_path = g_strjoin("/", mount_path, folder_name, FOTA_DELTA_FILENAME, NULL);
+ if (!g_file_test(storage_delta_path, G_FILE_TEST_EXISTS)) {
+ _FLOGI("Storage doesn't have %s", storage_delta_path);
+ goto verify_destroy;
}
- new_build_string = new_build_string + 1;
- path = g_strjoin("/", mount_path, folder_name, FOTA_DELTA_FILENAME, NULL);
- if (!g_file_test(path, G_FILE_TEST_EXISTS)) {
- _FLOGI("Folder %s doesn't have delta.tar", folder_name);
- status = -1;
+ /* 3. Check storage have appropriate delta */
+ ret = util_file_untar(storage_delta_path, FOTA_DELTA_BUILD_STRING_DIR, FOTA_DELTA_BUILD_STRING_FILENAME);
+ if (ret < 0)
goto verify_destroy;
- }
- ret = fota_delta_verify(path, old_build_string, new_build_string);
- if (ret < 0) {
- _FLOGE("Failed to verify delta : %d, path : %s, old_build_string : %s, new_build_string : %s",
- ret, path, old_build_string, new_build_string);
- status = -1;
+ ret = util_file_read_single_line(FOTA_DELTA_BUILD_STRING_PATH, buf);
+ if (ret < 0)
+ goto verify_destroy;
+
+ if (g_str_equal(folder_name, buf) != TRUE) {
+ _FLOGI("Storage doesn't have appropriate delta(%s), delta build string(%s)",
+ folder_name, buf);
goto verify_destroy;
}
- *delta_path = path;
+ _FLOGI("Success to find delta from storage(%s)", storage_delta_path);
+ is_appropriate = true;
verify_destroy:
- if (status != 0) {
- g_free(path);
+ util_file_remove(FOTA_DELTA_BUILD_STRING_PATH);
+
+ if (!is_appropriate && storage_delta_path) {
+ free(storage_delta_path);
+ storage_delta_path = NULL;
}
- return status;
+ return storage_delta_path;
}
-int fota_storage_search_delta_path(const char *mount_path, gchar **delta_path)
+gchar *fota_storage_search_delta_path(const char *mount_path)
{
- int ret = 0, status = 0;
- const gchar *folder_name = NULL;
GFile *mount = NULL;
GFileEnumerator *enumerator = NULL;
GFileInfo *info = NULL;
GError* error = NULL;
+ gchar* delta_path = NULL;
mount = g_file_new_for_path(mount_path);
enumerator = g_file_enumerate_children(mount, G_FILE_ATTRIBUTE_STANDARD_NAME, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, &error);
if (enumerator == NULL) {
_FLOGE("Failed to get enumerator : %s", error->message);
g_clear_error(&error);
- status = -1;
goto search_destroy;
}
while ((info = g_file_enumerator_next_file(enumerator, NULL, NULL)) != NULL) {
- if (g_file_info_get_file_type(info) != G_FILE_TYPE_DIRECTORY) {
- g_object_unref(info);
- continue;
- }
-
- folder_name = g_file_info_get_name(info);
- ret = fota_storage_verify_delta(mount_path, folder_name, delta_path);
- if (ret < 0) {
- _FLOGE("Failed to verify storage delta : %d", ret);
- status = -1;
- g_object_unref(info);
- continue;
- }
-
- if (*delta_path != NULL) {
- _FLOGI("Success to find verified delta in %s", *delta_path);
- status = 0;
- goto search_destroy;
+ if (g_file_info_get_file_type(info) == G_FILE_TYPE_DIRECTORY) {
+ delta_path = fota_storage_find_delta(mount_path, g_file_info_get_name(info));
+ if (delta_path != NULL)
+ break;
}
g_object_unref(info);
}
- status = -1;
search_destroy:
if (enumerator)
g_object_unref(mount);
- return status;
+ return delta_path;
}
void fota_storage_checker_plug(int storage_id, const char *mount_path)
gchar *delta_path = NULL;
_FLOGI("Storage mounted with %s, start process to check local delta", mount_path);
- ret = fota_storage_search_delta_path(mount_path, &delta_path);
- if (ret < 0) {
- _FLOGE("Failed to search delta path : %d", ret);
+ delta_path = fota_storage_search_delta_path(mount_path);
+ if (delta_path == NULL) {
+ _FLOGI("Failed to search delta path from %s", mount_path);
goto plug_destroy;
}
void fota_storage_checker_unplug(int storage_id, const char *mount_path)
{
int ret = 0;
+
if (storage_id == fota_storage_id) {
ret = fota_client_controller_add_event(FOTA_EVENT_UNPLUG, mount_path);
- if (ret < 0) {
+ if (ret < 0)
_FLOGE("Failed to add fota client event : %d, idx : %d, value : %s",
ret, FOTA_EVENT_UNPLUG, mount_path);
- }
+
fota_storage_id = -1;
}
}