497 lines
13 KiB
C
497 lines
13 KiB
C
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#include "duerapp_config.h"
|
|
#include "lightduer_dcs.h"
|
|
#include "lightduer_memory.h"
|
|
#include "lightduer_types.h"
|
|
#include "lightduer_dev_info.h"
|
|
#include "lightduer_ota_updater.h"
|
|
#include "lightduer_ota_unpacker.h"
|
|
#include "lightduer_ota_notifier.h"
|
|
#include "lightduer_ota_installer.h"
|
|
#include "server/server_core.h"
|
|
#include "server/ai_server.h"
|
|
#include "update/net_update.h"
|
|
|
|
static char g_firmware_version[FIRMWARE_VERSION_LEN + 1];
|
|
|
|
static unsigned char update_succ_flag = 0;
|
|
|
|
typedef struct {
|
|
duer_ota_updater_t *updater;
|
|
void *update_fd;
|
|
void *buffer;
|
|
u32 remain;
|
|
u32 w_offset;
|
|
u32 firmware_size;
|
|
duer_ota_module_info_t module_info;
|
|
} duer_ota_handler_t;
|
|
|
|
static duer_package_info_t s_package_info = {
|
|
.product = "WIFI_STORY",
|
|
.batch = "12",
|
|
.os_info = {
|
|
.os_name = "FreeRTOS",
|
|
.developer = "lyx",
|
|
.os_version = "0.0.0.0", // This version is that you write in the Duer Cloud
|
|
.staged_version = "0.0.0.0", // This version is that you write in the Duer Cloud
|
|
}
|
|
};
|
|
|
|
void set_duer_package_info(const char *product,
|
|
const char *batch,
|
|
const char *os_name,
|
|
const char *developer,
|
|
const char *os_version,
|
|
const char *staged_version)
|
|
{
|
|
strncpy(s_package_info.product, product, NAME_LEN);
|
|
s_package_info.product[NAME_LEN] = 0;
|
|
strncpy(s_package_info.batch, batch, BATCH_LEN);
|
|
s_package_info.batch[BATCH_LEN] = 0;
|
|
strncpy(s_package_info.os_info.os_name, os_name, NAME_LEN);
|
|
s_package_info.os_info.os_name[NAME_LEN] = 0;
|
|
strncpy(s_package_info.os_info.developer, developer, NAME_LEN);
|
|
s_package_info.os_info.developer[NAME_LEN] = 0;
|
|
strncpy(s_package_info.os_info.os_version, os_version, FIRMWARE_VERSION_LEN);
|
|
s_package_info.os_info.os_version[FIRMWARE_VERSION_LEN] = 0;
|
|
strncpy(s_package_info.os_info.staged_version, staged_version, FIRMWARE_VERSION_LEN);
|
|
s_package_info.os_info.staged_version[FIRMWARE_VERSION_LEN] = 0;
|
|
strncpy(g_firmware_version, os_version, FIRMWARE_VERSION_LEN);
|
|
g_firmware_version[FIRMWARE_VERSION_LEN] = 0;
|
|
}
|
|
|
|
#define PER_RECV_SIZE (4 * 1024)
|
|
|
|
extern void JL_duer_upgrade_notify(int event, void *arg);
|
|
|
|
static int notify_ota_begin(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
int ret = DUER_OK;
|
|
duer_ota_handler_t *ota_handler = NULL;
|
|
|
|
if (custom_data == NULL || installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Argument error");
|
|
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
DUER_LOGI("OTA Flash: Notify OTA begin");
|
|
|
|
ota_handler = (duer_ota_handler_t *)custom_data;
|
|
|
|
ota_handler->update_fd = net_fopen(CONFIG_UPGRADE_OTA_FILE_NAME, "w");
|
|
if (ota_handler->update_fd == NULL) {
|
|
DUER_LOGE("open upgrade server err \n");
|
|
installer->err_msg = "Open upgrade Server Failed";
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
ota_handler->buffer = DUER_MALLOC(PER_RECV_SIZE);
|
|
if (ota_handler->buffer == NULL) {
|
|
DUER_LOGE("malloc upgrade buffer err \n");
|
|
net_fclose(ota_handler->update_fd, 1);
|
|
ota_handler->update_fd = NULL;
|
|
installer->err_msg = "Malloc OTA Handler buffer failed";
|
|
return DUER_ERR_MEMORY_OVERFLOW;
|
|
}
|
|
|
|
/* JL_duer_upgrade_notify(AI_SERVER_EVENT_UPGRADE, NULL); */
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int get_module_info(
|
|
duer_ota_installer_t *installer,
|
|
void **custom_data,
|
|
duer_ota_module_info_t const *info)
|
|
{
|
|
int ret = DUER_OK;
|
|
duer_ota_handler_t *ota_handler = NULL;
|
|
|
|
if (custom_data == NULL || info == NULL || installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Argument error");
|
|
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
DUER_LOGI("OTA Flash: Module info");
|
|
DUER_LOGI("Module name: %s", info->module_name);
|
|
DUER_LOGI("Module size: %d", info->module_size);
|
|
DUER_LOGI("Module signature: %s", info->module_signature);
|
|
DUER_LOGI("Module version: %s", info->module_version);
|
|
DUER_LOGI("Module HW version: %s", info->module_support_hardware_version);
|
|
|
|
strncpy(g_firmware_version, (const char *)info->module_version, FIRMWARE_VERSION_LEN);
|
|
g_firmware_version[FIRMWARE_VERSION_LEN] = 0;
|
|
|
|
ota_handler = (duer_ota_handler_t *)DUER_CALLOC(1, sizeof(*ota_handler));
|
|
if (ota_handler == NULL) {
|
|
DUER_LOGE("OTA Unpack OPS: Malloc failed");
|
|
installer->err_msg = "Malloc OTA Handler failed";
|
|
return DUER_ERR_MEMORY_OVERFLOW;
|
|
}
|
|
|
|
DUER_MEMMOVE(&ota_handler->module_info, info, sizeof(*info));
|
|
|
|
ota_handler->firmware_size = info->module_size;
|
|
|
|
*custom_data = ota_handler;
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int get_module_data(
|
|
duer_ota_installer_t *installer,
|
|
void *custom_data,
|
|
unsigned int offset,
|
|
unsigned char const *data,
|
|
size_t size)
|
|
{
|
|
duer_ota_handler_t *ota_handler = NULL;
|
|
u32 w_size = 0;
|
|
int ret = DUER_OK;
|
|
u32 left = 0;
|
|
|
|
if (installer == NULL || custom_data == NULL || data == NULL) {
|
|
DUER_LOGE("OTA Flash: Argument error");
|
|
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
ota_handler = (duer_ota_handler_t *)custom_data;
|
|
|
|
if (ota_handler->buffer == NULL) {
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (ota_handler->remain + size >= PER_RECV_SIZE) {
|
|
left = PER_RECV_SIZE - ota_handler->remain;
|
|
memcpy(ota_handler->buffer + ota_handler->remain, data, left);
|
|
w_size = PER_RECV_SIZE;
|
|
ota_handler->remain = 0;
|
|
} else {
|
|
memcpy(ota_handler->buffer + ota_handler->remain, data, size);
|
|
ota_handler->remain += size;
|
|
return DUER_OK;
|
|
}
|
|
|
|
if (ota_handler->w_offset == 0) {
|
|
|
|
}
|
|
|
|
if (ota_handler->update_fd) {
|
|
ret = net_fwrite(ota_handler->update_fd, ota_handler->buffer, w_size, 0);
|
|
if (ret != w_size) {
|
|
net_fclose(ota_handler->update_fd, 1);
|
|
ota_handler->update_fd = NULL;
|
|
DUER_LOGE("upgrade core error : %d", ret);
|
|
installer->err_msg = "Write Flash Failed";
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
}
|
|
ota_handler->w_offset += w_size;
|
|
|
|
if (w_size == PER_RECV_SIZE) {
|
|
memcpy(ota_handler->buffer, data + left, size - left);
|
|
ota_handler->remain = (size - left);
|
|
}
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int verify_module_data(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
DUER_LOGI("OTA Flash: Verify module data");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int update_img_begin(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
DUER_LOGI("OTA Flash: Update image begin");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int update_img(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
DUER_LOGI("OTA Flash: Updating image");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int verify_image(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
DUER_LOGI("OTA Flash: Verify image");
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int notify_ota_end(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
duer_ota_handler_t *ota_handler = NULL;
|
|
int ret = DUER_OK;
|
|
|
|
DUER_LOGI("OTA Flash: Notify OTA end");
|
|
|
|
if (custom_data == NULL || installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Argument error");
|
|
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
ota_handler = (duer_ota_handler_t *)custom_data;
|
|
|
|
if (ota_handler->buffer == NULL) {
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (ota_handler->remain && ota_handler->update_fd) {
|
|
ret = net_fwrite(ota_handler->update_fd, ota_handler->buffer, ota_handler->remain, 0);
|
|
if (ret != ota_handler->remain) {
|
|
net_fclose(ota_handler->update_fd, 1);
|
|
ota_handler->update_fd = NULL;
|
|
DUER_LOGE("upgrade core error : %d", ret);
|
|
installer->err_msg = "Final Write Flash Failed";
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
ota_handler->w_offset += ota_handler->remain;
|
|
}
|
|
|
|
if (ota_handler->update_fd) {
|
|
update_succ_flag = 1;
|
|
net_fclose(ota_handler->update_fd, 0);
|
|
ota_handler->update_fd = NULL;
|
|
}
|
|
|
|
if (ota_handler->buffer) {
|
|
DUER_FREE(ota_handler->buffer);
|
|
ota_handler->buffer = NULL;
|
|
}
|
|
|
|
DUER_FREE(ota_handler);
|
|
|
|
installer->custom_data = NULL;
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int cancel_ota_update(duer_ota_installer_t *installer, void *custom_data)
|
|
{
|
|
duer_ota_handler_t *ota_handler = NULL;
|
|
|
|
DUER_LOGI("OTA Flash: Cancel OTA update");
|
|
|
|
if (custom_data == NULL || installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Argument error");
|
|
|
|
return DUER_ERR_INVALID_PARAMETER;
|
|
}
|
|
|
|
ota_handler = (duer_ota_handler_t *)custom_data;
|
|
|
|
if (ota_handler->update_fd) {
|
|
net_fclose(ota_handler->update_fd, 1);
|
|
ota_handler->update_fd = NULL;
|
|
}
|
|
|
|
if (ota_handler->buffer) {
|
|
DUER_FREE(ota_handler->buffer);
|
|
ota_handler->buffer = NULL;
|
|
}
|
|
|
|
update_succ_flag = 0;
|
|
|
|
DUER_FREE(ota_handler);
|
|
|
|
installer->custom_data = NULL;
|
|
|
|
JL_duer_upgrade_notify(AI_SERVER_EVENT_UPGRADE_FAIL, NULL);
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static int duer_ota_reboot_cb(void *arg)
|
|
{
|
|
int ret = DUER_OK;
|
|
DUER_LOGE("OTA Unpack OPS: Prepare to restart system");
|
|
|
|
if (update_succ_flag) {
|
|
char *msg = NULL;
|
|
if (strlen(g_firmware_version) > 0) {
|
|
msg = (char *)DUER_MALLOC(strlen(g_firmware_version) + 1);
|
|
if (msg) {
|
|
strcpy(msg, g_firmware_version);
|
|
}
|
|
}
|
|
JL_duer_upgrade_notify(AI_SERVER_EVENT_UPGRADE_SUCC, msg);
|
|
} else {
|
|
JL_duer_upgrade_notify(AI_SERVER_EVENT_UPGRADE_FAIL, NULL);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int duer_ota_register_installer(void)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
duer_ota_installer_t *installer = NULL;
|
|
|
|
installer = duer_ota_installer_create_installer("JL_OTA.bin");
|
|
if (installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Create installer failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
installer->custom_data = NULL;
|
|
installer->notify_ota_begin = notify_ota_begin;
|
|
installer->notify_ota_end = notify_ota_end;
|
|
installer->get_module_info = get_module_info;
|
|
installer->get_module_data = get_module_data;
|
|
installer->verify_module_data = verify_module_data;
|
|
installer->update_image_begin = update_img_begin;
|
|
installer->update_image = update_img;
|
|
installer->verify_image = verify_image;
|
|
installer->cancel_ota_update = cancel_ota_update;
|
|
|
|
ret = duer_ota_installer_register_installer(installer);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("OTA Flash: Register installer failed");
|
|
|
|
ret = duer_ota_installer_destroy_installer(installer);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("OTA Flash: Destroy installer failed");
|
|
}
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static int duer_ota_unregister_installer(void)
|
|
{
|
|
int ret = DUER_OK;
|
|
duer_ota_installer_t *installer = NULL;
|
|
|
|
installer = duer_ota_installer_get_installer("JL_OTA.bin");
|
|
if (installer == NULL) {
|
|
DUER_LOGE("OTA Flash: Get installer failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
ret = duer_ota_installer_unregister_installer("JL_OTA.bin");
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("OTA Flash: Unregister installer failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
ret = duer_ota_installer_destroy_installer(installer);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("OTA Flash: Destroy installer failed");
|
|
|
|
return DUER_ERR_FAILED;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
static const duer_ota_init_ops_t ota_ops = {
|
|
.register_installer = duer_ota_register_installer,
|
|
.unregister_installer = duer_ota_unregister_installer,
|
|
.reboot = duer_ota_reboot_cb,
|
|
};
|
|
|
|
|
|
static int get_package_info(duer_package_info_t *info)
|
|
{
|
|
int ret = DUER_OK;
|
|
char firmware_version[FIRMWARE_VERSION_LEN + 1];
|
|
|
|
if (info == NULL) {
|
|
DUER_LOGE("Argument Error");
|
|
|
|
ret = DUER_ERR_INVALID_PARAMETER;
|
|
|
|
goto out;
|
|
}
|
|
|
|
memset(firmware_version, 0, sizeof(firmware_version));
|
|
|
|
ret = duer_get_firmware_version(firmware_version, FIRMWARE_VERSION_LEN);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Get firmware version failed");
|
|
|
|
goto out;
|
|
}
|
|
|
|
strncpy((char *)&s_package_info.os_info.os_version,
|
|
firmware_version,
|
|
FIRMWARE_VERSION_LEN + 1);
|
|
memcpy(info, &s_package_info, sizeof(*info));
|
|
|
|
out:
|
|
return ret;
|
|
}
|
|
|
|
static const duer_package_info_ops_t s_package_info_ops = {
|
|
.get_package_info = get_package_info,
|
|
};
|
|
|
|
static int get_firmware_version(char *firmware_version)
|
|
{
|
|
strncpy(firmware_version, g_firmware_version, FIRMWARE_VERSION_LEN);
|
|
|
|
return DUER_OK;
|
|
}
|
|
|
|
static const struct DevInfoOps dev_info_ops = {
|
|
.get_firmware_version = get_firmware_version,
|
|
};
|
|
|
|
int duer_app_ota_init(void)
|
|
{
|
|
int ret = DUER_OK;
|
|
|
|
ret = duer_register_device_info_ops(&dev_info_ops);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Register device info ops failed");
|
|
}
|
|
|
|
ret = duer_report_device_info();
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Report device info failed");
|
|
}
|
|
|
|
ret = duer_init_ota(&ota_ops);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Init OTA failed");
|
|
}
|
|
|
|
ret = duer_ota_register_package_info_ops(&s_package_info_ops);
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Register OTA package info ops failed");
|
|
}
|
|
|
|
ret = duer_ota_notify_package_info();
|
|
if (ret != DUER_OK) {
|
|
DUER_LOGE("Report package info failed");
|
|
}
|
|
|
|
return ret;
|
|
}
|