blob: c970ce1b336f87b43a714adbddd67eec01c6873c [file] [log] [blame]
// 2017-07-31 carota Rock FOTA ua porting file
#define ROCK_FOTA_SUPPORT
#ifdef ROCK_FOTA_SUPPORT
#include "iot_rock.h"
#include "iot_rock_ipl.h"
#include "sha.h"
#include <log/log.h>
#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <stdint.h>
#include <hardware/boot_control.h>
#include <hardware/hardware.h>
#include <sys/reboot.h>
#include "liblog/lynq_deflog.h"
#include "mtk_device_wrap.h"
#include <include/lynq_uci.h>
#define ROCK_DEFAULT_BLOCK_SIZE 0x40000
#define ROCK_RAM_LEN (1024*1024)
#define LOG_TAG "LYNQ_FOTA"
#define ROCK_BACKUP_LEN ROCK_DEFAULT_BLOCK_SIZE
#define FILENAME_SIZE 50
//#define DEV_DELTA "/dev/disk/by-partlabel/delta"
#if 0
#define DEV_DELTA "/dev/disk/by-partlabel/delta"
#else
#define DEV_DELTA "/dev/mtd41"
#endif
char partition_filename_a[][FILENAME_SIZE] = {
{"/dev/disk/by-partlabel/system_a"},
{"/dev/disk/by-partlabel/boot_a"},
{"/dev/disk/by-partlabel/tee_a"},
{"/dev/disk/by-partlabel/md1img_a"},
{"/dev/disk/by-partlabel/md1dsp_a"},
{"/dev/disk/by-partlabel/vbmeta_a"},
{"/dev/disk/by-partlabel/oemapp_a"},
{"/dev/disk/by-partlabel/oemapp2_a"},
{"/dev/disk/by-partlabel/medmcu_a"},
{"/dev/disk/by-partlabel/spm_a"},
{"/dev/disk/by-partlabel/protect_a"},
{"/dev/disk/by-partlabel/mcf1_a"},
{"/dev/disk/by-partlabel/mcf2_a"},
{"/dev/disk/by-partlabel/mcupm_a"},
{"/dev/disk/by-partlabel/sspm_a"},
{"/dev/disk/by-partlabel/dpm_a"},
{"/dev/disk/by-partlabel/pi_img_a"},
{"/dev/disk/by-partlabel/hsm_os_a"},
{"/dev/disk/by-partlabel/bl2_a"},
{"/dev/disk/by-partlabel/bl33_a"}
};
char partition_filename_b[][FILENAME_SIZE] = {
{"/dev/disk/by-partlabel/system_b"},
{"/dev/disk/by-partlabel/boot_b"},
{"/dev/disk/by-partlabel/tee_b"},
{"/dev/disk/by-partlabel/md1img_b"},
{"/dev/disk/by-partlabel/md1dsp_b"},
{"/dev/disk/by-partlabel/vbmeta_b"},
{"/dev/disk/by-partlabel/oemapp_b"},
{"/dev/disk/by-partlabel/oemapp2_b"},
{"/dev/disk/by-partlabel/medmcu_b"},
{"/dev/disk/by-partlabel/spm_b"},
{"/dev/disk/by-partlabel/protect_b"},
{"/dev/disk/by-partlabel/mcf1_b"},
{"/dev/disk/by-partlabel/mcf2_b"},
{"/dev/disk/by-partlabel/mcupm_b"},
{"/dev/disk/by-partlabel/sspm_b"},
{"/dev/disk/by-partlabel/dpm_b"},
{"/dev/disk/by-partlabel/pi_img_b"},
{"/dev/disk/by-partlabel/hsm_os_b"},
{"/dev/disk/by-partlabel/bl2_b"},
{"/dev/disk/by-partlabel/bl33_b"}
};
char partition_filename[][FILENAME_SIZE] = {
{"system"},
{"boot"},
{"tee"},
{"md1img"},
{"md1dsp"},
{"vbmeta"},
{"oemapp"},
{"oemapp2"},
{"medmcu"},
{"spm"},
{"protect"},
{"mcf1"},
{"mcf2"},
{"mcupm"},
{"sspm"},
{"dpm"},
{"pi_img"},
{"hsm_os"},
{"bl2"},
{"bl33"}
};
//+10
unsigned int delta_head[128]={0}; //512/4 128/2=64
#define FOTA_UCI_MODULE "lynq_fota"
#define FOTA_UCI_FILE "lynq_uci"
#define FOTA_UCI_ADDR "lynq_fota_addr"
#define FOTA_UCI_STATE "lynq_fota_state"
#define FILE_UPDATE_STATE "/data/.update_status"
#define FILE_UPDATE_FLAG "/tmp/update_flag"
#define FILE_FOTA_STATE "/data/.fota_status"
#define NAND_PAGE_SIZE 4096
#define BOOTDEV_TYPE_NAND 1
#define BACKUP_ADDR_FLAG 0xffffffff
#define FILE_BACKUP "/data/.backup"
#define SLOT_A 0
#define SLOT_B 1
#define FULL_HEAD "full-ota"
//xf.li@20230822 add for ab rollback start
#define DEV_SYSTEM_A "/dev/disk/by-partlabel/system_a"
#define DEV_SYSTEM_B "/dev/disk/by-partlabel/system_b"
#define DEV_BOOT_A "/dev/disk/by-partlabel/boot_a"
#define DEV_BOOT_B "/dev/disk/by-partlabel/boot_b"
#define DEV_SPM_A "/dev/disk/by-partlabel/spm_a"
#define DEV_SPM_B "/dev/disk/by-partlabel/spm_b"
#define DEV_MD1IMG_A "/dev/disk/by-partlabel/md1img_a"
#define DEV_MD1IMG_B "/dev/disk/by-partlabel/md1img_b"
#define DEV_TEE_A "/dev/disk/by-partlabel/tee_a"
#define DEV_TEE_B "/dev/disk/by-partlabel/tee_b"
#define DEV_VBMETA_A "/dev/disk/by-partlabel/vbmeta_a"
#define DEV_VBMETA_B "/dev/disk/by-partlabel/vbmeta_b"
#define DEV_BL2_A "/dev/disk/by-partlabel/bl2_a"
#define DEV_BL2_B "/dev/disk/by-partlabel/bl2_b"
#define DEV_BL33_A "/dev/disk/by-partlabel/bl33_a"
#define DEV_BL33_B "/dev/disk/by-partlabel/bl33_b"
#define DEV_MEDMCU_A "/dev/disk/by-partlabel/medmcu_a"
#define DEV_MEDMCU_B "/dev/disk/by-partlabel/medmcu_b"
#define DEV_OEMAPP_A "/dev/disk/by-partlabel/oemapp_a"
#define DEV_OEMAPP_B "/dev/disk/by-partlabel/oemapp_b"
#define DEV_OEMAPP2_A "/dev/disk/by-partlabel/oemapp2_a"
#define DEV_OEMAPP2_B "/dev/disk/by-partlabel/oemapp2_b"
#define DEV_MISC "/dev/disk/by-partlabel/misc"
#define BACKUP_UBI_NUM 31 //max ubi number
#define MTD_SYSTEM_A 14
#define MTD_SYSTEM_B 15
#define MD5_RETRY_TIME 3
#define MD5_VERFY_ERROR 5
#define MD5_READ_BUFFER_LEN 4*1024
#define FOTA_FIRST 0
#define RECOVER_FIRST 1
int fota_interrupt = 1;
//xf.li@20230822 add for ab rollback end
//int fd_system_a,fd_system_b,fd_boot_a,fd_boot_b,fd_tee_a,fd_tee_b,fd_bl2,fd_bl33,fd_delta,fd_curr,fd_log,fd_update_status,fd_md1img_a,fd_md1img_b,fd_fota_status,fd_md1dsp_a,fd_md1dsp_b,fd_vbmeta_a,fd_vbmeta_b,fd_oemapp_a,fd_oemapp_b,fd_oemapp2_a,fd_oemapp2_b,fd_medmcu_a,fd_medmcu_b,fd_bl33_a,fd_bl33_b;
int fd_delta,fd_curr,fd_log,fd_update_status,fd_fota_status;
int fd_write,fd_read;
static unsigned int delta_offset = 0;
static unsigned int now_patch = 0;
unsigned int current_slot = 0;
unsigned char rock_debug_buffer[512];
OTA_STATUS fota_status;
UPDATE_INFO up_info;
extern const hw_module_t HAL_MODULE_INFO_SYM;
boot_control_module_t* module;
static void lynq_init_wake_lock_func(void);
static void lynq_fota_grab_artial_wake_lock(void);
static void lynq_fota_release_wake_lock(void);
int check(int sys_size);
int check_cpu();
static const char hex_chars[] = "0123456789abcdef";
/**
* @brief The following is the wake up
* start
*/
#define ANDROID_WAKE_LOCK_NAME "fota-interface"
void *dlHandle_wakelock;
enum {
PARTIAL_WAKE_LOCK = 1, // the cpu stays on, but the screen is off
FULL_WAKE_LOCK = 2 // the screen is also on
};
// while you have a lock held, the device will stay on at least at the
// level you request.
int (*acquire_wake_lock)(int lock, const char* id);
int (*release_wake_lock)(const char* id);
void convert_hex(unsigned char *sha, unsigned char *shastr)
{
int i;
int j = 0;
unsigned int c;
for (i = 0; i < 20; i++) {
c = (sha[i] >> 4) & 0x0f;
shastr[j++] = hex_chars[c];
shastr[j++] = hex_chars[sha[i] & 0x0f];
}
shastr[40] = '\0';
}
int rock_mismatch(void* ctx, unsigned char* buf, unsigned int start, unsigned int size,
unsigned int source_hash,unsigned int target_hash) {
return 0;
}
int rock_fatal(void* ctx, int error_code) {
return 0;
}
void rock_trace(void* ctx, const char* fmt, ...) {
va_list ap;
memset(rock_debug_buffer,0x0,sizeof(rock_debug_buffer));
va_start (ap, fmt);
vsnprintf(rock_debug_buffer,sizeof(rock_debug_buffer),fmt,ap);
LYDBGLOG("+[UA]: %s",rock_debug_buffer);
va_end (ap);
}
static int save_fota_status()
{
int err;
fd_fota_status = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
if (fd_fota_status < 0) {
err = errno;
RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
return -err;
}
write(fd_fota_status, &fota_status,sizeof(fota_status));
sync();
close(fd_fota_status);
}
static int save_fota_info()
{
int err;
fd_update_status = open(FILE_UPDATE_STATE,O_RDWR);
if (fd_update_status < 0) {
err = errno;
RLOGD("+[UA]: save_fota_status: Error opening metadata file: %s\n",strerror(errno));
return -err;
}
write(fd_update_status, &up_info, sizeof(fota_status));
sync();
close(fd_update_status);
}
void rock_progress(void* ctx, int percent) {
int i = 0;
static int tmp_percent = -1;
rock_trace(ctx, "rock update progress %d\n", percent);
if (tmp_percent != percent) {
tmp_percent = percent;
if (percent > 20) {
i = fota_status.ota_run;
if (fota_status.update_status[i-1].check_delta != PASS) {
fota_status.update_status[i-1].check_delta = PASS;
fota_status.update_status[i-1].check_rom= PASS;
save_fota_status();
}
}
}
}
int rock_process_block(void* ctx, unsigned char* data, unsigned int start, unsigned int size){
//rock_trace(ctx, "rock update progress block %d\n", size);
int writen = 0;
int ret,err;
if (start == BACKUP_ADDR_FLAG) {
int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
while (writen < size) {
write(fd_backup,data,ROCK_DEFAULT_BLOCK_SIZE);
sync();
writen += ROCK_DEFAULT_BLOCK_SIZE;
}
close(fd_backup);
return size;
}
writen = 0;
if (mtk_device_wrap_seek(fd_write, start, SEEK_SET) < 0) {
err = errno;
rock_trace(ctx, "mtk_device_wrap_seek write\n");
return err;
}
while (writen < size) {
ret = mtk_device_wrap_write(fd_write,data+writen, ROCK_DEFAULT_BLOCK_SIZE);
writen += ROCK_DEFAULT_BLOCK_SIZE;
}
return size;
}
int rock_write_block(void* ctx, unsigned char* src, unsigned int start, unsigned int size){
#if 0
int writen = 0;
int ret,err;
if (start == BACKUP_ADDR_FLAG) {
int fd_backup = open(FILE_BACKUP,O_RDWR | O_CREAT,0777);
while (writen < size) {
write(fd_backup,src,ROCK_DEFAULT_BLOCK_SIZE);
sync();
writen += ROCK_DEFAULT_BLOCK_SIZE;
}
close(fd_backup);
return size;
}
writen = 0;
if (mtk_device_wrap_seek(fd_curr, start, SEEK_SET) < 0) {
err = errno;
rock_trace(ctx, "mtk_device_wrap_seek write\n");
return err;
}
while (writen < size) {
ret = mtk_device_wrap_write(fd_curr,src+writen, ROCK_DEFAULT_BLOCK_SIZE);
writen += ROCK_DEFAULT_BLOCK_SIZE;
}
#endif
return size;
}
int rock_read_block(void* ctx, unsigned char* dest, unsigned int start, unsigned int size){
int ret,err;
if (start == BACKUP_ADDR_FLAG) {
int fd_backup = open(FILE_BACKUP,O_RDONLY);
read(fd_backup,dest,size);
sync();
close(fd_backup);
return size;
}
if (mtk_device_wrap_seek(fd_read, start, SEEK_SET) < 0) {
err = errno;
rock_trace(ctx, "mtk_device_wrap_seek read block err\n");
}
do {
ret = mtk_device_wrap_read(fd_read, dest, size);
if (ret == 0) {
break;
} else if (ret < 0) {
if (errno == EINTR) {
continue;
}
err = -errno;
rock_trace(ctx,"%s Error reading metadata file\n");
mtk_device_wrap_close(fd_read);
return err;
}
size -= ret;
dest += ret;
} while(size > 0);
return ret;
}
int rock_read_delta(void* ctx, unsigned char* dest, unsigned int offset, unsigned int size){
int ret = 0,err = 0;
if (lseek(fd_delta, offset + delta_offset, SEEK_SET) < 0) {
err = -errno;
rock_trace(ctx, "mtk_device_wrap_seek df_delta err\n");
return err;
}
do {
ret = read(fd_delta, dest, size);
if (ret == 0) {
break;
} else if (ret < 0) {
if (errno == EINTR) {
continue;
}
err = -errno;
rock_trace(ctx," Error reading metadata file\n");
close(fd_delta);
return err;
}
size -= ret;
dest += ret;
} while(size > 0);
return ret;
}
int rock_get_blocksize(void* ctx) {
return ROCK_DEFAULT_BLOCK_SIZE;
}
int rock_read_file(void* ctx, void* name, unsigned char* dest, unsigned int offset, unsigned int size){return 0;}
int rock_write_file(void* ctx, void* name, unsigned char* src, unsigned int offset, unsigned int size){return 0;}
int rock_delete_file(void* ctx, void* name){return 0;}
/* ROCK IPL end */
static int init_dev_fd()
{
int err;
char lynq_fota_addr[64] = {0};
char fota_name[]= "fota.delta";
int n;
if(0 != lynq_fota_get_addr_value(lynq_fota_addr))
{
return E_ROCK_FOTA_ADDR;
}
RLOGD("+[UA]: get fota pack addr: %s\n",lynq_fota_addr);
fd_delta = open(lynq_fota_addr,O_RDWR);
if (fd_delta < 0) {
err = errno;
RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
return -err;
}
fd_update_status = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
if (fd_update_status < 0) {
err = errno;
RLOGD("+[UA]: Error opening metadata file: %s\n",strerror(errno));
return -err;
}
memset(&up_info, 0, sizeof(up_info));
lseek(fd_update_status,0,SEEK_SET);
read(fd_update_status,(unsigned char *)&up_info,sizeof(up_info));
close(fd_update_status);
return 0;
}
static int close_dev_fd(int fd)
{
close(fd);
}
static int reboot_device() {
reboot(RB_AUTOBOOT);
while (1) pause();
}
int test_write_delta(char *source, char *target)
{
int fd_source,fd_target,size;
char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
fd_source = open(source,O_RDONLY);
if (fd_source < 0) {
RLOGD("+[UA]: open source error\n");
return 1;
}
fd_target = mtk_device_wrap_open(target,O_RDWR);
if (fd_target < 0) {
mtk_device_wrap_close(fd_target);
close(fd_source);
RLOGD("+[UA]: open target error\n");
return 1;
}
while(( size = read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
}
mtk_device_wrap_close(fd_target);
close(fd_source);
return 0;
}
int nand_copyto_nand(char *source, char *target)
{
int fd_source,fd_target,size;
char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
fd_source = mtk_device_wrap_open(source,O_RDONLY);
if (fd_source < 0) {
RLOGD("+[UA]: open source error\n");
return 1;
}
fd_target = mtk_device_wrap_open(target,O_RDWR);
if (fd_target < 0) {
mtk_device_wrap_close(fd_target);
mtk_device_wrap_close(fd_source);
RLOGD("+[UA]: open target error\n");
return 1;
}
while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0) {
mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
}
mtk_device_wrap_close(fd_target);
mtk_device_wrap_close(fd_source);
return 0;
}
int delta_copyto_nand(unsigned int start,int size)
{
char delta_data[NAND_PAGE_SIZE];
unsigned int ret = 0;
int err;
if (lseek(fd_delta, start, SEEK_SET) < 0) {
LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
return -1;
}
if (mtk_device_wrap_seek(fd_curr, 0, SEEK_SET) < 0) {
LYERRLOG("+[UA]: delta_copyto_nand seek err\n");
return -1;
}
do {
memset(delta_data,0,NAND_PAGE_SIZE);
ret = read(fd_delta, delta_data, NAND_PAGE_SIZE);
if (ret == 0) {
break;
} else if (ret < 0) {
if (errno == EINTR) {
continue;
}
err = -errno;
return err;
}
size -= NAND_PAGE_SIZE;
mtk_device_wrap_write(fd_curr,delta_data,NAND_PAGE_SIZE);
//mtk_device_wrap_write(fd_curr,delta_data,ret);
} while(size > 0);
return 0;
}
unsigned char ram_buffer[ROCK_RAM_LEN];
int check(int sys_size)
{
int fd;
int i=0;
int j=0;
int num=i;
int n = 0;
const uint8_t data[] = { 0x74, 0x77, 0x6f, 0x63, 0x6f, 0x72, 0x65};
const char * core_flag="twocore\n";
uint8_t buffer[16];
if(sys_size == 0)//for only upgrade oemapp and oemapp2
{
return 0;
}
n = strlen(core_flag);
lseek(fd_delta,520,SEEK_SET);
lseek(fd_delta,sys_size,SEEK_CUR);
lseek(fd_delta, -1*n, SEEK_CUR);
read(fd_delta, buffer, n);
lseek(fd_delta,0,SEEK_SET);//file reset
if (memcmp(buffer, core_flag, n) == 0)
{
return 0;
}
return -1;
}
int check_cpu(void)
{
int i=0;
int ret;
char buffer[3][64];
FILE *fp;
char num;
fp = popen("od -x /proc/device-tree/chosen/atag,devinfo","r");
for(i=0;i<3;i++)
{
fgets(buffer[i], 64, fp);
}
for(i=0;i<3;i++)
{
RLOGD("buffer[i] = %s\n",buffer[i]);
}
RLOGD("%c\n", buffer[2][14]);
num = buffer[2][14];
RLOGD("num=%c\n", num);
if(num == '0' || num == '1')
{
printf("this is four core\n");
return 4;
}
else if(num == '2' || num == '3')
{
printf("this is two core\n");
return 2;
}
else
{
RLOGD("this char is error\n");
return -1;
}
pclose(fp);
return -1;
}
static int rock_update_main(unsigned int rom_base, unsigned int backup_base, unsigned int backup_len, int read_rom_directly, int first_run, int switch_slot_flag, int
reboot_flag, int backup_mode) {
int status,err,start,fd;
int ret = 0;
int i = 0;
int retry_cnt = 0;
int cpu_flag;
IOT_UPDATA_CONTEXT ctx;
//OTA_STATUS fota_status;
const hw_module_t* hw_module;
unsigned int slot;
unsigned int update_mode = MODE_NORMAL;
unsigned int delta_size;
unsigned char full_header[9];
char digest_s[SHA_DIGEST_SIZE];
char digest_t[SHA_DIGEST_SIZE];
char str_sha[40];
char cmd_sys[100];
int core_num;
int sha_size = 0;
int is_need_fullupdate = 0;
int fd_partition_a,fd_partition_b;
//xf.li@20230830 add for ab_recover start
fd = open(FILE_UPDATE_FLAG,O_RDWR | O_CREAT,0777);
if (fd < 0)
{
RLOGD("+[UA]: can't open file /tmp/update_flag.\n");
return -1;
}
close(fd);
//xf.li@20230830 add for ab_recover end
hw_module = &HAL_MODULE_INFO_SYM;
if (!hw_module ||
strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
ret = -EINVAL;
}
if (ret != 0) {
RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
return -1;
}
module = (boot_control_module_t*)hw_module;
module->init(module);
if (module == NULL) {
RLOGD("+[UA]: Error getting bootctrl module.\n");
return -1;
}
lynq_init_wake_lock_func();
lynq_fota_grab_artial_wake_lock();
/************* Bootctrl Init End *************/
current_slot = module->getCurrentSlot(module);
int is_successful = module->isSlotMarkedSuccessful(module, current_slot);
RLOGD("Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
memset(&ctx, 0, sizeof(ctx));
ctx.rom_base = 0;
ctx.ram_base =(unsigned char *)&ram_buffer[0];
ctx.ram_len = ROCK_RAM_LEN;
ctx.backup_base = BACKUP_ADDR_FLAG;
//ctx.backup_len = ROCK_DEFAULT_BLOCK_SIZE;
ctx.backup_len = 0;
ctx.update_nvram = 0;
ctx.read_rom_directly = read_rom_directly;
//ctx.first_run = first_run;
ctx.first_run = 1;
if(0 != init_dev_fd())
{
RLOGD("+[UA]: get fota addr error\n");
system("echo fota-interface >/sys/power/wake_unlock");
return E_ROCK_FOTA_ADDR;
}
memset(&fota_status,0,sizeof(fota_status));
RLOGD("+[UA]: up_info.ota_run = %d\n",up_info.ota_run);
#if 0
if ((up_info.ota_run>PATCH_BL33)||(up_info.ota_run<PATCH_SYSTEM))
{
up_info.ota_run = 0;
}
#endif
up_info.ota_run = 0;
if(backup_mode == 1)
{
if(current_slot == 0)
{
update_mode = MODE_A2B;
}else
{
update_mode = MODE_B2A;
}
}
else
{
update_mode = MODE_NORMAL;
}
RLOGD("+[UA]: up_info.fota_flag = %s\n",up_info.fota_flag);
RLOGD("+[UA]: update_mode = %d\n",update_mode);
//memset(&da_head, 0, sizeof(da_head));
//read(fd_delta, (unsigned char*)&da_head, sizeof(da_head));
memset(&delta_head, 0, sizeof(delta_head));
read(fd_delta, (char *)&delta_head[0], sizeof(delta_head));
delta_size = 0;
sha_size = 0;
for (i = 0;i<REAL_OTA_ROLE; i++) {
if (delta_head[i] > 0) {
fota_status.update_status[i].need_update = 1;
delta_size+=delta_head[i];
}
RLOGD("+[UA]: %s,delta size = %d\n",partition_filename[i],delta_head[i]);
}
for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE); i++) {
if (delta_head[i] > 0) {
fota_status.update_status[i].need_update = 1;
sha_size+=delta_head[i];
}
RLOGD("+[UA]: %s,full size = %d, i=%d\n",partition_filename[i-MAX_OTA_ROLE/2],delta_head[i], i);
}
core_num= check_cpu();
if(core_num == 2)
{
cpu_flag = check(delta_head[64]);
if(cpu_flag < 0)
{
RLOGD("cpu core is error\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
else
{
RLOGD("cpu core match\n");
}
}
else if(core_num == 4)
{
RLOGD("the cpu core is four!!!\n");
}
else
{
RLOGD("read the cpu core fail");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
fota_status.switch_slot = WAIT;
save_fota_status();
//delta_size = da_head.sys + da_head.boot + da_head.tee + da_head.md1img + da_head.md1dsp + da_head.vbmeta + da_head.oemapp + da_head.oemapp2 + da_head.medmcu+da_head.bl33;
//sha_size = da_head.full_sys + da_head.full_boot + da_head.full_tee + da_head.full_md1img + da_head.full_md1dsp + da_head.full_vbmeta + da_head.full_oemapp + da_head.full_oemapp2 + da_head.full_medmcu+da_head.full_bl33
is_need_fullupdate = 0;
if(sha_size>0) {
is_need_fullupdate = 1;
sha_size+=8;
}
sha_size+=delta_size;
memset(digest_s,0,SHA_DIGEST_SIZE);
memset(digest_t,0,SHA_DIGEST_SIZE);
memset(str_sha,0,40);
lseek(fd_delta, sha_size + sizeof(delta_head), SEEK_SET);
read(fd_delta, digest_s, SHA_DIGEST_SIZE);
convert_hex(digest_s,str_sha);
RLOGD("+[UA]: delta save sha = %s\n",str_sha);
ROCK_SHA_FILE_COMMON(fd_delta,sizeof(delta_head),sha_size,digest_t);
memset(str_sha,0,40);
convert_hex(digest_t,str_sha);
RLOGD("+[UA]: delta calc sha = %s\n",str_sha);
if(memcmp(digest_s,digest_t,SHA_DIGEST_SIZE)==0) {
RLOGD("sha verify pass\n");
}else{
RLOGD("delta sha verify fial!\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
memset(digest_s,0,SHA_DIGEST_SIZE);
memset(digest_t,0,SHA_DIGEST_SIZE);
//delta_offset = DELTA_HEARD_SIZE;
delta_offset = sizeof(delta_head);
for(i = 0;i<REAL_OTA_ROLE; i++){ //diff
//now_patch = i+1;
if (i>0) {
delta_offset+=delta_head[i-1];
}
if((delta_head[i]>0) && (up_info.ota_run<=(i+1))){
now_patch = i + 1;
#if 0
if (up_info.ota_run == now_patch) //升级ps断电?
{
ctx.first_run = 0;
}else{
ctx.first_run = 1;
}
#endif
ctx.first_run = 1; //always
RLOGD("+[UA]: PATCH %s,ctx.first_run = %d\n", partition_filename[i] ,ctx.first_run);
up_info.ota_run = now_patch;
if(current_slot==SLOT_B) {
sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i]);
}else{
sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i]);
}
system(cmd_sys);
fd_partition_a = mtk_device_wrap_open(partition_filename_a[i],O_RDWR);
if (fd_partition_a < 0) {
err = errno;
RLOGD("+[UA]: Error opening id_a[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
fd_partition_b = mtk_device_wrap_open(partition_filename_b[i],O_RDWR);
if (fd_partition_b < 0) {
err = errno;
RLOGD("+[UA]: Error opening id_b[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
if(current_slot==SLOT_B){
fd_read = fd_partition_b;
fd_write = fd_partition_a;
} else {
fd_read = fd_partition_a;
fd_write = fd_partition_b;
}
fota_status.ota_run = i;
fota_status.update_status[i].check_delta = WAIT;
fota_status.update_status[i].check_rom = WAIT;
fota_status.update_status[i].update_result= WAIT;
save_fota_status();
up_info.ota_run = i+1;
save_fota_info();
RLOGD("+[UA]: Start upgrading %s.\n",partition_filename[i]);
status = iot_patch(&ctx);
RLOGD("+[UA]: %s upgrade result:%d\n",partition_filename[i],status);
//up_info.ota_run = 0;
//fota_status.ota_run = 0;
fota_status.update_status[i].update_result= status;
fota_status.update_result= status;
if((status == 0)||(status ==1))
{
fota_status.update_status[i].check_delta = PASS;
fota_status.update_status[i].check_rom = PASS;
RLOGD("+[UA]: %s upgrade success!!!\n",partition_filename[i]);
}else if(status == E_ROCK_INVALID_DELTA) {
fota_status.update_status[i].check_delta = ERROR;
fota_status.update_status[i].check_rom = WAIT;
}else if((status == E_ROCK_DELTA_MISMATCH)||(status == E_ROCK_DELTA_CHUNK_MISMATCH)) {
fota_status.update_status[i].check_delta = PASS;
fota_status.update_status[i].check_rom = ERROR;
}else{
//fota_status.update_status[PATCH_SYSTEM -1].check_delta = PASS;
//fota_status.update_status[PATCH_SYSTEM -1].check_rom = WAIT;
}
save_fota_status();
if ((status != 0) &&(status != 1))
{
up_info.fota_flag[0] = 'e';
up_info.fota_flag[1] = 'n';
up_info.fota_flag[2] = 'd';
up_info.update_result = status;
up_info.ota_run = 0;
save_fota_info();
mtk_device_wrap_close(fd_read);
mtk_device_wrap_close(fd_write);
system("echo fota-interface >/sys/power/wake_unlock");
return status;
}
mtk_device_wrap_close(fd_read);
mtk_device_wrap_close(fd_write);
}
}
if (is_need_fullupdate == 1)
{
now_patch = 0;
up_info.ota_run = 0;
memset(&fota_status,0,sizeof(fota_status));
fota_status.switch_slot = WAIT;
save_fota_status();
if (lseek(fd_delta, DELTA_HEARD_SIZE + delta_size, SEEK_SET) < 0) {
err = errno;
RLOGD("+[UA]: mtk_device_wrap_seek df_delta err\n");
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
read(fd_delta, full_header, DELTA_FULL_HEARD_SIZE);
if (memcmp(full_header, "full-ota", DELTA_FULL_HEARD_SIZE) != 0) {
RLOGD("+[UA]: invalid full delta header\r\n");
up_info.fota_flag[0] = 'e';
up_info.fota_flag[1] = 'n';
up_info.fota_flag[2] = 'd';
up_info.update_result = -1;
up_info.ota_run = 0;
save_fota_info();
//for (i = FULL_SYSTEM;i<=FULL_BL33;i++){
for (i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++){
if (fota_status.update_status[i].need_update ==1) {
fota_status.ota_run = i;
fota_status.update_status[i].check_delta = ERROR;
fota_status.update_status[i].check_rom= WAIT;
fota_status.update_status[i].update_result= ERROR;
}
}
fota_status.update_result = ERROR;
save_fota_status();
system("echo fota-interface >/sys/power/wake_unlock");
return -1;
}
}
delta_offset = DELTA_HEARD_SIZE + delta_size + DELTA_FULL_HEARD_SIZE;
for(i = MAX_OTA_ROLE/2;i<(MAX_OTA_ROLE/2+REAL_OTA_ROLE);i++) {
if (i>MAX_OTA_ROLE/2) {
delta_offset+=delta_head[i-1];
}
if(delta_head[i]>0) {
if(current_slot==SLOT_B) {
sprintf(cmd_sys,"flash_eraseall %s",partition_filename_a[i-MAX_OTA_ROLE/2]);
} else {
sprintf(cmd_sys,"flash_eraseall %s",partition_filename_b[i-MAX_OTA_ROLE/2]);
}
system(cmd_sys);
if(current_slot==SLOT_B) {
fd_partition_a = mtk_device_wrap_open(partition_filename_a[i-MAX_OTA_ROLE/2],O_RDWR);
if (fd_partition_a < 0) {
err = errno;
RLOGD("+[UA]: Error opening full id_a[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
fd_curr = fd_partition_a;
}else{
fd_partition_b = mtk_device_wrap_open(partition_filename_b[i-MAX_OTA_ROLE/2],O_RDWR);
if (fd_partition_b < 0) {
err = errno;
RLOGD("+[UA]: Error opening full_id_b[%d] file: %s\n",i,strerror(errno));
system("echo fota-interface >/sys/power/wake_unlock");
return -err;
}
fd_curr = fd_partition_b;
}
fota_status.ota_run = i+1;
save_fota_status();
up_info.ota_run = i+1;
save_fota_info();
retry_cnt = 0;
RLOGD("+[UA]: Start upgrading %s full.\n",partition_filename[i-MAX_OTA_ROLE/2]);
do{
status = delta_copyto_nand(delta_offset,delta_head[i]);
ROCK_SHA_FILE_COMMON(fd_delta,delta_offset,delta_head[i],digest_s);
ROCK_SHA_FILE(fd_curr,0,delta_head[i],digest_t);
retry_cnt++;
}while((strncmp(digest_s,digest_t,SHA_DIGEST_SIZE)!=0)&&(retry_cnt <= 3));
mtk_device_wrap_close(fd_curr);
RLOGD("+[UA]: %s full retry_cnt = %d\n",partition_filename[i-MAX_OTA_ROLE/2],retry_cnt);
if (retry_cnt>3) {
if (status == 0) {
status = retry_cnt;
}
if(current_slot==SLOT_B) {
nand_copyto_nand(partition_filename_b[i-MAX_OTA_ROLE/2],partition_filename_a[i-MAX_OTA_ROLE/2]);
}
else{
nand_copyto_nand(partition_filename_a[i-MAX_OTA_ROLE/2],partition_filename_b[i-MAX_OTA_ROLE/2]);
}
}
RLOGD("+[UA]: %s full upgrade result:%d\n",partition_filename[i-MAX_OTA_ROLE/2],status);
fota_status.update_result = status;
fota_status.update_status[i].update_result = status;
save_fota_status();
if (status != 0)
{
up_info.fota_flag[0] = 'e';
up_info.fota_flag[1] = 'n';
up_info.fota_flag[2] = 'd';
up_info.update_result = status;
up_info.ota_run = 0;
save_fota_info();
system("echo fota-interface >/sys/power/wake_unlock");
return status;
}
}
}
if(update_mode != MODE_NORMAL){ //need backup
if(current_slot == SLOT_A) {
up_info.fota_flag[0] = 'B';
up_info.fota_flag[1] = '-';
up_info.fota_flag[2] = 'A';
}else{
up_info.fota_flag[0] = 'A';
up_info.fota_flag[1] = '-';
up_info.fota_flag[2] = 'B';
}
}else{
up_info.fota_flag[0] = 'e';
up_info.fota_flag[1] = 'n';
up_info.fota_flag[2] = 'd';
}
up_info.update_result = status;
up_info.ota_run = 0;
save_fota_info();
//close_dev_fd(fd_curr);
close(fd_update_status);
sync();
slot = (current_slot == 0) ? 1 : 0;
RLOGD("+[UA]: slot SLOT = %d\n",slot);
if(switch_slot_flag==1)
{
module->setActiveBootSlot(module,slot);
RLOGD("+[UA]: upgrade is success!!!!\n");
}
fota_status.ota_run = 0;
fota_status.switch_slot = PASS;
fota_status.update_result = status;
save_fota_status();
sleep(5);
sync();
sleep(5);
system("echo fota-interface >/sys/power/wake_unlock");
if(reboot_flag==1){
reboot_device();
}
return status;
}
static void rock_fail_handler()
{
int ret = 0;
RLOGD("rock_fail_handler start\n");
//ret = rock_update_main(0, 0, 0, 0, 1, 1);
if(ret)
{
RLOGD("fota update fail again!\n");
}
}
/* main entrpoint */
int lynq_rock_main(int first_run)
{
int ret = 0;
#if 0
printf("-********copy delta ***-\n");
test_write_delta("/data/delta",DEV_DELTA);
#endif
ret = rock_update_main(0, 0, 0, 0, first_run, 1, 1, 1);
RLOGD("rock_update_main ret = %d\n", ret);
if(ret)
{
RLOGD("fota update fail!\n");
}
return ret;
}
#endif
//xf.li@20230403 add for verfy start
int lynq_file_md5_verfy(char *source, unsigned char *source_md5, char *target)
{
int fd, size, ret, is_system = 0;
int need_copy = 1;
int system_mtd_num = 0;
int system_ubi_num = BACKUP_UBI_NUM;//max ubi number
char cmd_ubi_attach[128] = {0};
char cmd_ubi_detach[128] = {0};
char md5_target_file_patch[128] = {0};
RLOGD("in lynq_file_md5_verfy, source:%s, target:%s\n", source, target);
if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
{
RLOGD("verfy system.img\n");
is_system = 1;
if(strcmp(source, DEV_SYSTEM_A) == 0)
{
system_mtd_num = MTD_SYSTEM_B;
}
else if(strcmp(source, DEV_SYSTEM_B) == 0)
{
system_mtd_num = MTD_SYSTEM_A;
}
else
{
RLOGD("source:%s, target:%s\n", source, target);
}
for( ; system_ubi_num >= 10; system_ubi_num--)//try from ubi31 to ubi10
{
sprintf(md5_target_file_patch, "/dev/ubi%d", system_ubi_num);
RLOGD("ubi_num = %d\n", system_ubi_num);
if((access(md5_target_file_patch, F_OK)) == -1)
{
RLOGD("no the ubi file, can use this ubi.\n");
break;
}
}
if(system_ubi_num < 10)
{
RLOGE("no the ubi file, can use this ubi.\n");
return -1;
}
}
//=========================caculate md5sum start=====================
if(is_system == 1)
{
RLOGD("in system caculate\n");
RLOGD("system_mtd_num = %d, ubi_num = %d\n", system_mtd_num, system_ubi_num);
sprintf(cmd_ubi_attach, "ubiattach /dev/ubi_ctrl -m %d -d %d", system_mtd_num, system_ubi_num);
RLOGD("cmd_ubi_attach:%s", cmd_ubi_attach);
ret = system(cmd_ubi_attach);
if(ret != 0)
{
RLOGE("ubi attach error!!!\n");
return need_copy;
}
RLOGD("attach over\n");
//attach success
sprintf(md5_target_file_patch, "/dev/ubi%d_0", system_ubi_num);
RLOGD("md5_target_file_patch:%s", md5_target_file_patch);
//make sure the ubi volume is exist
if((access(md5_target_file_patch, F_OK)) == -1)
{
RLOGD("no the ubi file.\n");
sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
ret = system(cmd_ubi_detach);
if(ret != 0)
{
RLOGD("ubi dettach error!!!\n");
}
return need_copy;
}
//calculate md5sum
//ret = lynq_md5_two_file_verfy("/dev/ubi0_0", md5_target_file_patch);
ret = lynq_md5_file_verfy_ab(md5_target_file_patch, source_md5);
if(ret == MD5_VERFY_ERROR)
{
//ubidetach
sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
ret = system(cmd_ubi_detach);
if(ret != 0)
{
RLOGD("ubi dettach error!!!\n");
}
return need_copy;
}
if(ret != 0)
{
//ubidetach
sprintf(cmd_ubi_detach, "ubidetach -m %d", system_mtd_num);
ret = system(cmd_ubi_detach);
if(ret != 0)
{
RLOGD("ubi dettach error!!!\n");
}
RLOGD("calculate system error!!!\n");
return -1;
}
RLOGD("verfy system.img over\n");
}
else
{
RLOGD("verfy else img\n");
//calculate md5sum
//ret = lynq_md5_two_file_verfy(source, target);
ret = lynq_md5_file_verfy_ab(target, source_md5);
if(ret == MD5_VERFY_ERROR)
{
return need_copy;
}
if(ret != 0)
{
RLOGD("calculate %s and %s error!!!\n", source, target);
return -1;
}
}
//====================caculate md5sum end======================
return 0;
}
//xf.li@20230403 add for verfy end
//xf.li@20230401 add for ab rollback start
int backup_nand_copyto_nand(char *source, char *target)
{
int fd_source, fd_target, size;
int ret = -1;
int sleep_count = 0;
char cmd_erase_target[128] = {0};
int retry = MD5_RETRY_TIME;
unsigned char source_md5[MD5_READ_BUFFER_LEN] = {0};
char delta_data[ROCK_DEFAULT_BLOCK_SIZE];
//caclculate source md5 start
if(strcmp(source, DEV_SYSTEM_A) == 0 || strcmp(source, DEV_SYSTEM_B) == 0)
{
RLOGD("backup_nand_copyto_nand: verfy system.img\n");
ret = calculate_file_md5_value("/dev/ubi0_0", source_md5);
if(ret < 0)
{
RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
return ret;
}
RLOGD("source_md5 is %s\n", source_md5);
}
else
{
ret = calculate_file_md5_value(source, source_md5);
if(ret < 0)
{
RLOGD("[+MD5]:calculate source md5 value ERROE!!!\n");
return ret;
}
RLOGD("source_md5 is %s\n", source_md5);
}
//caclculate source md5 end
//ret = lynq_file_md5_verfy(source, target);//verfy md5 value
ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
if(ret == 0)
{
RLOGD("+[UA]: nand_copyto_nand don't neet copy\n");
}
for(; ret > 0 && retry > 0; retry--)
{
//erase nand-target start
if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
{
RLOGD("+[UA]: fota runing\n");
return -1;
}
acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
RLOGD("+[UA]: ready to flash_erase\n");
sprintf(cmd_erase_target, "flash_erase %s 0 0", target);
ret = system(cmd_erase_target);
release_wake_lock("ab_recover");//unlock
if(ret != 0)
{
RLOGD("+[UA]: erase %s fail\n", target);
return -1;
}
sleep(1);//sleep 1s
//erase nand-target end
RLOGD("+[UA]: ready to copy\n");
fd_source = mtk_device_wrap_open(source, O_RDONLY);
if (fd_source < 0) {
RLOGD("+[UA]: open source error\n");
return -1;
}
fd_target = mtk_device_wrap_open(target, O_RDWR);
if (fd_target < 0) {
RLOGD("+[UA]: open target error\n");
return -1;
}
ret = 0;//init ret
acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");//lock
while(( size = mtk_device_wrap_read(fd_source,delta_data,ROCK_DEFAULT_BLOCK_SIZE))>0)
{
if(fota_interrupt == FOTA_FIRST && (access(FILE_UPDATE_FLAG, F_OK)) == 0)
{
RLOGD("+[UA]: fota runing\n");
ret = -1;
break;
}
usleep(40000);//sleep 40ms
mtk_device_wrap_write(fd_target,delta_data,ROCK_DEFAULT_BLOCK_SIZE);
usleep(60000);//sleep 60ms
sleep_count++;
if(sleep_count >= 20)
{
//unlock
release_wake_lock("ab_recover");
sleep(1);//sleep 1s
//lock
acquire_wake_lock(PARTIAL_WAKE_LOCK, "ab_recover");
sleep_count = 0;
RLOGD("+[UA]: try sleep one time");
}
}
release_wake_lock("ab_recover");//unlock
RLOGD("+[UA]: copy end\n");
mtk_device_wrap_close(fd_target);
mtk_device_wrap_close(fd_source);
if(ret < 0)
{
RLOGD("+[UA]: ret < 0\n");
return -1;
}
RLOGD("+[UA]: ready to md5_verfy\n");
//ret = lynq_file_md5_verfy(source, target);//verfy md5 value
ret = lynq_file_md5_verfy(source, source_md5, target);//verfy md5 value
RLOGD("+[UA]: md5_file_verfy :ret=%d\n", ret);
if(ret == 0)
{
RLOGD("+[UA]: nand_copyto_nand copy success\n");
break;
}
}
if(ret != 0)
{
RLOGD("+[UA]: md5_file_verfy FAIL!!!\n");
}
return ret;
}
//xf.li@20230401 add for ab rollback end
//xf.li@20230822 add for ab rollback start
int lynq_backup_main()
{
const hw_module_t* hw_module;
hw_module = &HAL_MODULE_INFO_SYM;
int is_successful;
int ret = 0;
if (!hw_module || strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0)
{
ret = -1;
}
RLOGD("ret = %d\n", ret);
if (ret != 0)
{
RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
return -1;
}
module = (boot_control_module_t*)hw_module;
module->init(module);
if (module == NULL)
{
RLOGD("+[UA]: Error getting bootctrl module.\n");
return -1;
}
lynq_init_wake_lock_func();
current_slot = module->getCurrentSlot(module);
is_successful = module->isSlotMarkedSuccessful(module, current_slot);
RLOGD("+[UA]: Booting slot = %d, : isSlotMarkedSuccessful= %d\n",current_slot,is_successful);
fota_interrupt = RECOVER_FIRST;
if(current_slot==SLOT_B)
{
ret = backup_nand_copyto_nand(DEV_SPM_B,DEV_SPM_A);
if(ret != 0)
{
RLOGD("+[UA]: backup spm_a fail\n");
return 1;
}
fota_interrupt = FOTA_FIRST;
ret = backup_nand_copyto_nand(DEV_SYSTEM_B,DEV_SYSTEM_A);
if(ret != 0)
{
RLOGD("+[UA]: backup system_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BOOT_B,DEV_BOOT_A);
if(ret != 0)
{
RLOGD("+[UA]: backup boot_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_TEE_B,DEV_TEE_A);
if(ret != 0)
{
RLOGD("+[UA]: backup tee_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_MD1IMG_B,DEV_MD1IMG_A);
if(ret != 0)
{
RLOGD("+[UA]: backup md1img_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_VBMETA_B,DEV_VBMETA_A);
if(ret != 0)
{
RLOGD("+[UA]: backup vbmeta_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_MEDMCU_B,DEV_MEDMCU_A);
if(ret != 0)
{
RLOGD("+[UA]: backup medmcu_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BL2_B,DEV_BL2_A);
if(ret != 0)
{
RLOGD("+[UA]: backup bl2_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BL33_B,DEV_BL33_A);
if(ret != 0)
{
RLOGD("+[UA]: backup bl33_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_OEMAPP_B,DEV_OEMAPP_A);
if(ret != 0)
{
RLOGD("+[UA]: backup oemapp_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_OEMAPP2_B,DEV_OEMAPP2_A);
if(ret != 0)
{
RLOGD("+[UA]: backup oemapp2_a fail\n");
return 1;
}
}
else
{
ret = backup_nand_copyto_nand(DEV_SPM_A,DEV_SPM_B);
if(ret != 0)
{
RLOGD("+[UA]: backup spm_a fail\n");
return 1;
}
fota_interrupt = FOTA_FIRST;
ret = backup_nand_copyto_nand(DEV_SYSTEM_A,DEV_SYSTEM_B);
if(ret != 0)
{
RLOGD("+[UA]: backup system_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BOOT_A,DEV_BOOT_B);
if(ret != 0)
{
RLOGD("+[UA]: backup boot_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_TEE_A,DEV_TEE_B);
if(ret != 0)
{
RLOGD("+[UA]: backup tee_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_MD1IMG_A,DEV_MD1IMG_B);
if(ret != 0)
{
RLOGD("+[UA]: backup md1img_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_VBMETA_A,DEV_VBMETA_B);
if(ret != 0)
{
RLOGD("+[UA]: backup vbmeta_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_MEDMCU_A,DEV_MEDMCU_B);
if(ret != 0)
{
RLOGD("+[UA]: backup medmcu_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BL2_A,DEV_BL2_B);
if(ret != 0)
{
RLOGD("+[UA]: backup bl2_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_BL33_A,DEV_BL33_B);
if(ret != 0)
{
RLOGD("+[UA]: backup bl33_a fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_OEMAPP_A,DEV_OEMAPP_B);
if(ret != 0)
{
RLOGD("+[UA]: backup oemapp_b fail\n");
return 1;
}
ret = backup_nand_copyto_nand(DEV_OEMAPP2_A,DEV_OEMAPP2_B);
if(ret != 0)
{
RLOGD("+[UA]: backup oemapp2_b fail\n");
return 1;
}
}
RLOGD("+[UA]: lynq_backup_main success \n");
return 0;
}
//xf.li@20230822 add for ab rollback end
int lynq_check_oemapp(char* name)
{
FILE *fp;
char check_result[64];
if(strcmp(name, "oemapp") == 0)
{
RLOGD("lynq_check_oemapp oemapp");
if(system("df -lh|grep oemapp |grep -v oemapp2") != 0)
{
return 0;
}
else
{
return 1;
}
}
else if(strcmp(name, "oemapp2") == 0)
{
RLOGD("lynq_check_oemapp oemapp2");
if(system("df -lh|grep oemapp2") != 0)
{
return 0;
}
else
{
return 1;
}
}
}
//lt add @2021.9.23 for deal with power down \ backup or upgrade.
int lynq_fota_func(void)
{
int fd;
int first_run = 1;
int ret = 0;
UPDATE_INFO lynq_up_info;
//xf.li@20230822 add for ab backup start
unsigned int current_slot, other_slot;
int is_other_slot_bootable;
const hw_module_t* hw_module;
//xf.li@20230822 add for ab backup end
RLOGD("[+UP]: ******lynq_fota_func start******\n");
//xf.li@20230822 add for ab backup start
//----------get current slot and whether other slot is bootable
hw_module = &HAL_MODULE_INFO_SYM;
if (!hw_module ||
strcmp(BOOT_CONTROL_HARDWARE_MODULE_ID, hw_module->id) != 0) {
ret = -EINVAL;
}
if (ret != 0) {
RLOGD("+[UA]: Error loading boot_control HAL implementation.\n");
return -1;
}
module = (boot_control_module_t*)hw_module;
module->init(module);
if (module == NULL) {
RLOGD("+[UA]: Error getting bootctrl module.\n");
return -1;
}
current_slot = module->getCurrentSlot(module);
other_slot = (current_slot == 0) ? 1 : 0;
is_other_slot_bootable = module->isSlotBootable(module, other_slot);
//-----------end
RLOGD("current slot:%u, is_other_slot_bootable : %d\n",current_slot, is_other_slot_bootable);
//xf.li@20230822 add for ab backup end
memset(&lynq_up_info, 0, sizeof(lynq_up_info));
fd = open(FILE_UPDATE_STATE,O_RDWR | O_CREAT,0777);
if (fd < 0)
{
return -1;
}
read(fd,(unsigned char *)&lynq_up_info,sizeof(lynq_up_info));
close(fd);
RLOGD("[+UP]: lynq_up_info.ota_run=%d\n",lynq_up_info.ota_run);
if((lynq_check_oemapp("oemapp") == 0) || (lynq_check_oemapp("oemapp2") == 0))
{
RLOGD("ENTER LYNQ_CHECK_OEMAPP\n");
system("echo mode 001 0 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
system("echo dir 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
system("echo out 001 1 > /sys/devices/platform/10005000.pinctrl/mt_gpio");
RLOGD("need setUnbootable.\n");
module->setSlotAsUnbootable(module,current_slot);
RLOGD("+[UA]: setSlotAsUnbootable!!!!\n");
sync();
if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
{
RLOGD("mark oemapp mount fail\n");
lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_STATE, "1");
}
sleep(5);
reboot_device();
}
if(lynq_up_info.ota_run != 0)
{
//Power off, call UA
RLOGD("[+UP]: ***Power off, call UA***\n");
ret = rock_update_main(0, 0, 0, 0, first_run, 1, 0, 1);
RLOGD("rock_update_main ret = %d\n", ret);
if(ret)
{
RLOGD("fota update fail!\n");
}
}
if(((lynq_up_info.fota_flag[0]=='A')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='B'))||
((lynq_up_info.fota_flag[0]=='B')&&(lynq_up_info.fota_flag[1]=='-')&&(lynq_up_info.fota_flag[2]=='A')))
{
//Upgrade the other side and call UA
RLOGD("[+UP]: ***Upgrade the other side and call UA***\n");
ret = rock_update_main(0, 0, 0, 0, first_run, 0, 0, 0);
RLOGD("rock_update_main ret = %d\n", ret);
if(ret)
{
RLOGD("fota update fail!\n");
}
}
//xf.li@20230822 add for ab backup start
else if(is_other_slot_bootable == 0)
{
RLOGD("need backup\n");
ret = lynq_backup_main();
if(ret != 0)
{
RLOGD("ERROE: backup fail!!!\n");
}
else
{
RLOGD("backup success!!!\n");
module->setCompleteBackup(module, current_slot);
}
}
else
{
RLOGD("Don't need backup\n");
}
//xf.li@20230822 add for ab backup end
return 0;
}
int lynq_nand_open(const char *pathname, int flags)
{
// printf("pathname:%s---flags:%d",pathname,flags);
return open(pathname,flags);
}
ssize_t lynq_nand_read(int fd, void *buf, size_t count)
{
// printf("rfd:%d---buf:%s---count:%d",fd,buf,count);
return read(fd,buf,count);
}
ssize_t lynq_nand_write(int fd, void *buf, size_t count)
{
// printf("wfd:%d---buf:%s---count:%d",fd,buf,count);
return write(fd,buf,count);
}
int lynq_nand_close(int fd)
{
return close(fd);
}
/**
* @brief Obtain the upgrade result
*
* @param void
* @return 0xff:open file fail,0:upgrade success,1,upgrade wait
*/
int lynq_get_upgrade_status(void)
{
int lynq_state_fd;
int lynq_upgrade_wait = 1;
OTA_STATUS lynq_ota_status;
memset(&lynq_ota_status, 0, sizeof(lynq_ota_status));
lynq_state_fd = open(FILE_FOTA_STATE,O_RDWR | O_CREAT,0777);
if (lynq_state_fd < 0)
{
return 0xff;
}
read(lynq_state_fd,(unsigned char *)&lynq_ota_status,sizeof(lynq_ota_status));
close(lynq_state_fd);
if((lynq_ota_status.ota_run != 0) && (lynq_ota_status.update_result == 0))
{
return lynq_upgrade_wait;
}
return lynq_ota_status.update_result;
}
/**
* @brief reboot device
*
* @param void
* @return void
*/
void lynq_reboot_device(void)
{
reboot_device();
return ;
}
/**
* @brief fota no resatrt
*
* @param void
* @return 0:fota success -Other values:fota fail
*/
int lynq_fota_nrestart(void)
{
int ret = 0;
#if 0
printf("-********copy delta ***-\n");
test_write_delta("/data/delta",DEV_DELTA);
#endif
ret = rock_update_main(0, 0, 0, 0, 1, 1, 0, 1);
RLOGD("rock_update_nrestart ret = %d\n", ret);
if(ret)
{
RLOGD("fota update fail!\n");
}
return ret;
}
/**
* @brief Set the upgrade package address
*
* @param1 value:fota addr
* @param1 szie:fota addr length
* @return 0:set success other:set fail
*/
int lynq_fota_set_addr_value(char *value,int size)
{
if(size < 64)
{
return lynq_set_value(FOTA_UCI_MODULE,FOTA_UCI_ADDR, value);
}
return -1;
}
/**
* @brief get the upgrade package address
*
* @param1 value:fota addr
* @return 0:get success other:set fail
*/
int lynq_fota_get_addr_value(char *tmp)
{
return lynq_get_value(FOTA_UCI_FILE, FOTA_UCI_MODULE,FOTA_UCI_ADDR, tmp);
}
/**
* @brief Porting wakes up the demo content
*/
static void lynq_init_wake_lock_func(void)
{
const char *lynqLibPath_WakeLock = "/usr/lib64/libpower.so";
dlHandle_wakelock = dlopen(lynqLibPath_WakeLock, RTLD_NOW);
if (dlHandle_wakelock == NULL)
{
printf("dlopen lynqLibPath_WakeLock failed: %s", dlerror());
exit(EXIT_FAILURE);
}
acquire_wake_lock = (int(*)(int,const char*))dlsym(dlHandle_wakelock, "acquire_wake_lock");
if (acquire_wake_lock == NULL) {
printf("acquire_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
exit(EXIT_FAILURE);
}
release_wake_lock = (int(*)( const char*))dlsym(dlHandle_wakelock, "release_wake_lock");
if (release_wake_lock == NULL) {
printf("release_wake_lock not defined or exported in %s", lynqLibPath_WakeLock);
exit(EXIT_FAILURE);
}
dlerror(); // Clear any previous dlerror
return;
}
/**
* @brief fota wake lock
*
* @param1 value:void
* @return ;
*/
static void lynq_fota_grab_artial_wake_lock(void)
{
acquire_wake_lock(PARTIAL_WAKE_LOCK, ANDROID_WAKE_LOCK_NAME);
}
/**
* @brief get the upgrade package address
*
* @param1 value:void
* @return ;
*/
static void lynq_fota_release_wake_lock(void)
{
release_wake_lock(ANDROID_WAKE_LOCK_NAME);
}
/**
* @brief This is the wake up call
* end
*/