Support R311 OTA

This commit is contained in:
HuangXin 2018-08-30 14:27:59 +08:00
parent 2ef21de6ed
commit 7e4f34424f
1 changed files with 296 additions and 619 deletions

View File

@ -12,7 +12,7 @@
#include <sys/sendfile.h>
#include <uthash/utstring.h>
#if defined(PLATFORM_R16) || defined (PLATFORM_CPU)
#if defined(PLATFORM_R311) || defined (PLATFORM_CPU)
#include "log.h"
#include "libuv_dbus.h"
#include "crypto.h"
@ -30,51 +30,62 @@
#include <uvdbus/inet_api.h>
#endif
#define MD5_CHKSUM_LEN (16)
#define MD5_STR_LEN (32 + 4)
#define MAX_IPL_ITEM (4)
#define IPL_PARAMS_PARTITION ("/dev/by-name/IPL3")
#define IPL3_MAGIC_NAME ("R16IPL3\0")
#define GET_STA_CNT(s) (s & 0xFF)
#define SET_STA_CNT(s, v) (s = (s & 0xFFFFFF00) | ((v) & 0xFF))
#define GET_STA_CMD(s) ((s >> 8) & 0xFF)
#define SET_STA_CMD(s, v) (s = (s & 0xFFFF00FF) | (((v) & 0xFF) << 8))
#define GET_STA_FLAG(s) ((s >> 16) & 0xFF)
#define SET_STA_FLAG(s, v) (s = (s & 0xFF00FFFF) | (((v) & 0xFF) << 16))
#define GET_STA_ERR(s) ((s >> 24) & 0xFF)
#define SET_STA_ERR(s, v) (s = (s & 0x00FFFFFF) | (((v) & 0xFF) << 24))
#define OTA_PARAMS_PARTITION ("/dev/by-name/ota_info")
#define OTA_PARAMS_TAG ("OTA163\0")
#define BOOT_IMG_FILE_NAME ("boot.img")
#define ROOTFS_IMG_FILE_NAME ("rootfs.img")
#define EXT_FS_UUID_FILE ("/etc/.extroot-uuid")
#define OTA_TEMP_DIR ("/tmp/ota")
#define OTA_FILE_DOWNLOAD_DIR ("/mnt/UDISK/ota")
#define OTA_MEMORY_DOWNLOAD_DIR ("/tmp/UDISK/ota")
typedef enum
{
OTA_PARTITION_BOOT = 0,
OTA_PARTITION_ROOTFS,
OTA_PARTITION_IPL_BOOT,
OTA_PARTITION_IPL_ROOTFS,
OTA_PARTITION_IPL_PARAMS,
OTA_PARTITION_MAX
} OTA_PARTITION_NAME;
#define OTA_TEMP_DIR ("/mnt/UDISK/ota/unzip")
#define OTA_FILE_DOWNLOAD_DIR ("/mnt/UDISK/ota/dl")
typedef struct
{
OTA_PARTITION_NAME partName;
const char *pPartPath;
unsigned int partSize;
} OTA_PARTITION_INFO, *POTA_PARTITION_INFO;
char tags[8];
unsigned int otaStatus;
char otaVer[MD5_STR_LEN];
char bootChksum[MD5_STR_LEN];
unsigned int bootfileSize;
char rootfsChksum[MD5_STR_LEN];
unsigned int rootfsfileSize;
char paramsChksum[MD5_STR_LEN];
} OTA_PARAMS, *POTA_PARAMS;
typedef struct {
typedef enum
{
CMD_RUN_OTA = 1,
CMD_RUN_BOOT,
CMD_RUN_VERIFY,
} OTA_COMMAND;
typedef enum
{
FLAG_NORMAL = 0,
FLAG_EXEC_OTA = 1,
} OTA_FLAG;
typedef struct
{
unsigned int fileSize;
unsigned char md5sum[MD5_CHKSUM_LEN];
int reserved[4];
} IPL_DATA_ITEM, *PIPL_DATA_ITEM;
typedef struct {
char pMagicTag[8];
unsigned int setupStatus;
SETUP_MODE setupMode;
int curVersion;
// int kernelVer;
// char rfsVersion[1024];
IPL_DATA_ITEM iplItem[OTA_PARTITION_MAX - 1];
unsigned char md5sum[MD5_CHKSUM_LEN];
}IPL_DATA_INFO, *PIPL_DATA_INFO;
typedef struct
{
OTA_FILE_INFO fileInfo;
@ -85,25 +96,27 @@ typedef struct
uv_barrier_t* puvBarrier;
} DOWNLOAD_TASK_INFO, *PDOWNLOAD_TASK_INFO;
static IPL_DATA_INFO g_iplInfo;
static char g_otaDownloadPath[MAX_PATH];
static SETUP_MODE g_sSetupStatus = NORMAL_SETUP;
static OTA_PARTITION_INFO g_otaPartInfo[] = {
{OTA_PARTITION_BOOT, "/dev/by-name/boot", 0},
{OTA_PARTITION_ROOTFS, "/dev/by-name/rootfs", 0},
{OTA_PARTITION_IPL_BOOT, "/dev/by-name/IPL1", 0},
{OTA_PARTITION_IPL_ROOTFS, "/dev/by-name/IPL2", 0},
{OTA_PARTITION_IPL_PARAMS, "/dev/by-name/IPL3", 0},
};
static unsigned int g_IsOTAMode = 0;
static uv_barrier_t g_otaBarrier;
static uv_loop_t* g_pMainLoop = NULL;
static int g_isDownloading = FALSE;
static int g_isBackupMode = FALSE;
static OTA_PARAMS g_otaParams;
static const char *g_umountPart[] = { "/usr", "/overlay", "/boot", "/rom", "/" };
static void __ota_print_params(POTA_PARAMS pInfo, const char* pTips)
{
LOG_EX2(LOG_Debug, "%s--------------------------\n", pTips ? pTips : "");
LOG_EX2(LOG_Debug, "tags: %s\n", pInfo->tags);
LOG_EX2(LOG_Debug, "status: 0x%08X\n", pInfo->otaStatus);
LOG_EX2(LOG_Debug, "version: %s\n", pInfo->otaVer);
LOG_EX2(LOG_Debug, "boot_ver: %s\n", pInfo->bootChksum);
LOG_EX2(LOG_Debug, "boot_size: %u\n", pInfo->bootfileSize);
LOG_EX2(LOG_Debug, "rootfs_ver: %s\n", pInfo->rootfsChksum);
LOG_EX2(LOG_Debug, "rootfs_size: %u\n", pInfo->rootfsfileSize);
LOG_EX2(LOG_Debug, "params_chksum: %s\n", pInfo->paramsChksum);
}
static void __printfOTANotifyCmd(const char* pTags, POTA_DATA_INFO pInfo)
{
@ -156,17 +169,6 @@ static int __otaRspStatus(OTA_STATUS_TYPE type, int val)
return (ret);
}
#if 0
static void __dlThreadRuntimeCb(void *pParams)
{
PDOWNLOAD_TASK_INFO pDlInfo = (PDOWNLOAD_TASK_INFO)pParams;
LOG_EX(LOG_Debug, "Cleanup barrier\n");
uv_barrier_wait(pDlInfo->puvBarrier);
pthread_detach(pthread_self());
}
#endif
void __onHttpResponseCb(void* pData, unsigned int size, const char* pReqUrl, const char* pDlPath, const char* pTaskUuid, int iFinished, void* pUserData)
{
PDOWNLOAD_TASK_INFO pDlInfo = (PDOWNLOAD_TASK_INFO)pUserData;
@ -186,21 +188,10 @@ void __onHttpResponseCb(void *pData, unsigned int size, const char *pReqUrl, con
if(pDlInfo)
{
// int err;
uv_thread_t uvThread;
pDlInfo->retCode = iFinished;
// LOG_EX(LOG_Debug, "Cleanup barrier task start: %u\n", g_ThreadCnt);
LOG_EX(LOG_Debug, "Cleanup barrier\n");
uv_barrier_wait(pDlInfo->puvBarrier);
#if 0
g_ThreadCnt++;
err = uv_thread_create(&uvThread, __dlThreadRuntimeCb, pDlInfo);
if(err != 0)
{
LOG_EX(LOG_Error, "1:Create Thread Error: %d\n", err);
}
#endif
}
else
{
@ -220,165 +211,85 @@ void __onProgressNotifyCb(const char *pReqUrl, const char *pTaskUuid, unsigned c
}
}
static void __printIPLParams(PIPL_DATA_INFO pIPLInfo, const char* pTags)
{
int i;
char md5[MD5_CHKSUM_STR_LEN];
if(pTags != NULL && strlen(pTags) > 0)
{
LOG_EX2(LOG_Debug, "%s\n", pTags);
LOG_EX2(LOG_Debug, "------------------------------------------------\n");
}
LOG_EX2(LOG_Debug, "Magic Tag : %s\n", pIPLInfo->pMagicTag);
LOG_EX2(LOG_Debug, "Setup Status : %u\n", pIPLInfo->setupStatus);
LOG_EX2(LOG_Debug, "Setup Module : %d(0x%08X)\n", pIPLInfo->setupMode, pIPLInfo->setupMode);
LOG_EX2(LOG_Debug, "Version : %d\n", pIPLInfo->curVersion);
memset(md5, 0, MD5_CHKSUM_STR_LEN);
IHW_bin2hex(md5, pIPLInfo->md5sum, MD5_CHKSUM_LEN);
LOG_EX2(LOG_Debug, "MD5 Checksum : %s\n", md5);
LOG_EX2(LOG_Debug, "-------------------------------------------------------------------\n");
LOG_EX2(LOG_Debug, "| Partition | size | MD5 Checksum |\n");
LOG_EX2(LOG_Debug, "-------------------------------------------------------------------\n");
for(i = 0; i < sizeof(pIPLInfo->iplItem) / sizeof(pIPLInfo->iplItem[0]); i++)
{
char *pPartName = strdup(g_otaPartInfo[i].pPartPath);
memset(md5, 0, MD5_CHKSUM_STR_LEN);
IHW_bin2hex(md5, pIPLInfo->iplItem[i].md5sum, MD5_CHKSUM_LEN);
LOG_EX2(LOG_Debug, "| %9s | %16u | %32s |\n", basename_v2(pPartName), pIPLInfo->iplItem[i].fileSize, md5);
free(pPartName);
}
LOG_EX2(LOG_Debug, "-------------------------------------------------------------------\n");
}
static int __ReadIPLParams(PIPL_DATA_INFO pIPLInfo)
static int __ota_read_params(POTA_PARAMS pInfo)
{
uv_fs_t uvOpen, uvRead, uvClose;
int ret, rdSize = 0;
unsigned char md5Buf[MD5_CHKSUM_LEN];
char md5str[MD5_STR_LEN];
uv_loop_t* pLoop = g_pMainLoop;
uv_buf_t uvBuf = uv_buf_init((char*)pIPLInfo, sizeof(IPL_DATA_INFO));
uv_buf_t uvBuf = uv_buf_init((char*)pInfo, sizeof(OTA_PARAMS));
if(pIPLInfo == NULL)
if(pInfo == NULL)
{
return (-ERR_INPUT_PARAMS);
}
memset(pIPLInfo, 0, sizeof(IPL_DATA_INFO));
memset(md5str, 0, MD5_STR_LEN);
memset(pInfo, 0, sizeof(OTA_PARAMS));
ret = system("sync");
if(uv_fs_open(pLoop, &uvOpen, IPL_PARAMS_PARTITION, O_RDWR, 0, NULL) == -1)
if(uv_fs_open(pLoop, &uvOpen, OTA_PARAMS_PARTITION, O_RDWR, 0, NULL) == -1)
{
LOG_EX(LOG_Error, "Open Partition %s Error\n", IPL_PARAMS_PARTITION);
LOG_EX(LOG_Error, "Open Partition %s Error\n", OTA_PARAMS_PARTITION);
return (-ERR_OPEN_FILE);
}
if((rdSize = uv_fs_read(pLoop, &uvRead, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(IPL_DATA_INFO))
if((rdSize = uv_fs_read(pLoop, &uvRead, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(OTA_PARAMS))
{
LOG_EX(LOG_Error, "Read Partition Error: Read %d Bytes, Need Read %d Bytes %d\n", rdSize, sizeof(IPL_DATA_INFO));
LOG_EX(LOG_Error, "Read Partition Error: Read %d Bytes, Need Read %d Bytes %d\n", rdSize, sizeof(OTA_PARAMS));
return (-ERR_READ_FILE);
}
uv_fs_close(pLoop, &uvClose, uvOpen.result, NULL);
if(memcmp(pIPLInfo->pMagicTag, IPL3_MAGIC_NAME, 8) != 0)
if(strncmp(pInfo->tags, OTA_PARAMS_TAG, 8) != 0)
{
LOG_EX(LOG_Error, "Check Magic Head Error: [%s], need [%s]\n", pIPLInfo->pMagicTag, IPL3_MAGIC_NAME);
LOG_EX(LOG_Error, "Check Magic Head Error: [%s], need [%s]\n", pInfo->tags, OTA_PARAMS_TAG);
return (-ERR_NO_INIT_IPL3);
}
EvpMD5HashBuf((const unsigned char *)pIPLInfo, sizeof(IPL_DATA_INFO) - MD5_CHKSUM_LEN, md5Buf, &rdSize);
EvpMD5HashBuf((const unsigned char*)pInfo, sizeof(OTA_PARAMS) - MD5_STR_LEN, md5Buf, &rdSize);
if(memcmp(pIPLInfo->md5sum, md5Buf, MD5_CHKSUM_LEN) != 0)
IHW_bin2hex(md5str, md5Buf, MD5_CHKSUM_LEN);
if(strcmp(pInfo->paramsChksum, md5str) != 0)
{
//print_hex_dump_bytes("CACL_", DUMP_PREFIX_ADDRESS, md5Buf, MD5_CHKSUM_LEN);
//print_hex_dump_bytes("SAVE_", DUMP_PREFIX_ADDRESS, pIPLInfo->md5sum, MD5_CHKSUM_LEN);
LOG_EX(LOG_Error, "Verify MD5 Error\n");
LOG_EX(LOG_Error, "Verify MD5 Error: %s --> %s\n", md5str, pInfo->paramsChksum);
return (-ERR_BAD_IPL3);
}
//print_hex_dump_bytes("IPL3", DUMP_PREFIX_ADDRESS, pIPLInfo, sizeof(IPL_DATA_INFO));
return (0);
}
static int __Write2NandPartition(OTA_PARTITION_NAME partName, const char *pFilePath)
{
int fileSize = 0;
char bufCmd[MAX_PATH];
if(partName < 0 || partName >= OTA_PARTITION_MAX || pFilePath == NULL || strlen(pFilePath) == 0)
{
LOG_EX(LOG_Error, "Input params error\n");
return (-ERR_INPUT_PARAMS);
}
if(access(pFilePath, F_OK) == -1)
{
LOG_EX(LOG_Error, "File %s not exist\n", pFilePath);
return (-ERR_FILE_NOT_EXISTS);
}
GET_FILE_SIZE(pFilePath, fileSize);
if(fileSize > g_otaPartInfo[partName].partSize || fileSize == -1)
{
LOG_EX(LOG_Error, "File %s size %d more than partition size %u\n",
pFilePath, fileSize, g_otaPartInfo[partName].partSize);
return (-ERR_BAD_FILE_SIZE);
}
memset(bufCmd, 0, MAX_PATH);
if(partName == OTA_PARTITION_IPL_ROOTFS || partName == OTA_PARTITION_ROOTFS)
{
sprintf(bufCmd, "dd if=%s of=%s bs=128k conv=sync", pFilePath, g_otaPartInfo[partName].pPartPath);
}
else
{
sprintf(bufCmd, "dd if=%s of=%s bs=4k conv=sync", pFilePath, g_otaPartInfo[partName].pPartPath);
}
LOG_EX(LOG_Debug, "Run OTA: [%s]\n", bufCmd);
fileSize = system(bufCmd);
fileSize = system("sync");
return (0);
}
static int __SaveIPLParams(PIPL_DATA_INFO pIPLInfo)
static int __ota_save_params(POTA_PARAMS pInfo)
{
int ret, wrSize = 0;
uv_fs_t uvOpen, uvWrite, uvSync, uvClose;
unsigned char md5Buf[MD5_CHKSUM_LEN];
unsigned char buf[MAX_PATH];
char buf[MAX_PATH];
char cmd[MAX_PATH];
char md5str[MD5_STR_LEN];
uv_loop_t* pLoop = g_pMainLoop;
uv_buf_t uvBuf = uv_buf_init((char*)pIPLInfo, sizeof(IPL_DATA_INFO));
uv_buf_t uvBuf = uv_buf_init((char*)pInfo, sizeof(OTA_PARAMS));
if(pIPLInfo == NULL)
if(pInfo == NULL)
{
return (-ERR_INPUT_PARAMS);
}
if(memcmp(pIPLInfo->pMagicTag, IPL3_MAGIC_NAME, 8) != 0)
memset(md5str, 0, MD5_STR_LEN);
if(strncmp(pInfo->tags, OTA_PARAMS_TAG, 8) != 0)
{
memcpy(pIPLInfo->pMagicTag, IPL3_MAGIC_NAME, 8);
LOG_EX(LOG_Error, "Check Magic Head Error: [%s], need [%s]\n", pIPLInfo->pMagicTag, IPL3_MAGIC_NAME);
return (-ERR_NO_INIT_IPL3);
memset(pInfo->tags , 0, 8);
strcpy(pInfo->tags, OTA_PARAMS_TAG);
}
EvpMD5HashBuf((const unsigned char *)pIPLInfo, sizeof(IPL_DATA_INFO) - MD5_CHKSUM_LEN, md5Buf, &wrSize);
EvpMD5HashBuf((const unsigned char *)pInfo, sizeof(OTA_PARAMS) - MD5_STR_LEN, md5Buf, &wrSize);
if(wrSize != MD5_CHKSUM_LEN)
{
@ -386,60 +297,38 @@ static int __SaveIPLParams(PIPL_DATA_INFO pIPLInfo)
return (-ERR_BAD_IPL3);
}
memcpy(pIPLInfo->md5sum, md5Buf, MD5_CHKSUM_LEN);
IHW_bin2hex(md5str, md5Buf, MD5_CHKSUM_LEN);
memset(pInfo->paramsChksum, 0, MD5_STR_LEN);
strcpy(pInfo->paramsChksum, md5str);
memset(buf, 0, MAX_PATH);
ret = system("mkdir -p /tmp/ota_param/");
sprintf(buf, "/tmp/ota_param/ota_%d.params", pIPLInfo->curVersion);
//print_hex_dump_bytes("IPL3", DUMP_PREFIX_ADDRESS, pIPLInfo, sizeof(IPL_DATA_INFO));
sprintf(buf, "/tmp/ota_param/ota_%s.params", pInfo->otaVer);
if(uv_fs_open(pLoop, &uvOpen, buf, O_RDWR | O_CREAT | O_TRUNC,
S_IRUSR | S_IWUSR, NULL) == -1)
{
LOG_EX(LOG_Error, "Open Partition %s Error\n", IPL_PARAMS_PARTITION);
LOG_EX(LOG_Error, "Open File %s Error\n", buf);
return (-ERR_OPEN_FILE);
}
if((wrSize = uv_fs_write(pLoop, &uvWrite, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(IPL_DATA_INFO))
if((wrSize = uv_fs_write(pLoop, &uvWrite, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(OTA_PARAMS))
{
LOG_EX(LOG_Error, "Write Partition Error: Read %d Bytes, Need Read %d Bytes %d\n", wrSize, sizeof(IPL_DATA_INFO));
LOG_EX(LOG_Error, "Write Error: Read %d Bytes, Need Read %d Bytes %d\n", wrSize, sizeof(OTA_PARAMS));
return (-ERR_READ_FILE);
}
uv_fs_fdatasync(pLoop, &uvSync, uvOpen.result, NULL);
uv_fs_close(pLoop, &uvClose, uvOpen.result, NULL);
ret = __Write2NandPartition(OTA_PARTITION_IPL_PARAMS, (const char*)buf);
memset(cmd, 0, MAX_PATH);
sprintf(cmd, "dd if=%s of=/dev/by-name/ota_info bs=4k conv=sync > /dev/zero && sync", buf);
if(ret != 0)
{
LOG_EX(LOG_Error, "Write OTA Params Error: %d\n", ret);
return (-ERR_OTA_WRITE_IPL3);
}
ret = system(cmd);
return (0);
}
static int __otaBackupWifi(int iBackup)
{
int ret = 0;
if(iBackup == TRUE)
{
const char *pBackCmd = "mkdir -p /mnt/UDISK/ota/wifi_bak/ && rm -rf /mnt/UDISK/ota/wifi_bak/* \
&& cp -rf /etc/wifi/* /mnt/UDISK/ota/wifi_bak/";
ret = system(pBackCmd);
}
else
{
const char *pBackCmd = "rm -rf /etc/wifi/*.* && cp -rf /mnt/UDISK/ota/wifi_bak/*.* /etc/wifi/";
ret = system(pBackCmd);
}
return ret;
}
static int __otaRunning(char* pCheckSumFile, int ver)
{
ssize_t rdRet;
@ -519,7 +408,6 @@ static int __otaRunning(char* pCheckSumFile, int ver)
if(strcmp(pMD5Str, pItem[0]) != 0)
{
free(pRdLine);
fclose(pFile);
LOG_EX(LOG_Error, "%s Check MD5 error: [%s] need [%s]\n", basePath, pMD5Str, pItem[0]);
@ -528,14 +416,17 @@ static int __otaRunning(char* pCheckSumFile, int ver)
if(strcmp(pItem[1], BOOT_IMG_FILE_NAME) == 0)
{
memcpy(g_iplInfo.iplItem[OTA_PARTITION_BOOT].md5sum, pMD5Val, MD5_CHKSUM_LEN);
GET_FILE_SIZE(basePath, fileSize);
memset(g_otaParams.bootChksum, 0, MD5_STR_LEN);
strncpy(g_otaParams.bootChksum, pMD5Str, MD5_STR_LEN);
g_otaParams.bootfileSize = fileSize;
}
else if(strcmp(pItem[1], ROOTFS_IMG_FILE_NAME) == 0)
{
GET_FILE_SIZE(basePath, fileSize);
//fprintf(stdout, "fileSize = %lu\n", fileSize);
memcpy(g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].md5sum, pMD5Val, MD5_CHKSUM_LEN);
g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].fileSize = fileSize;
memset(g_otaParams.rootfsChksum, 0, MD5_STR_LEN);
strncpy(g_otaParams.rootfsChksum, pMD5Str, MD5_STR_LEN);
g_otaParams.rootfsfileSize = fileSize;
}
}
@ -545,115 +436,29 @@ static int __otaRunning(char* pCheckSumFile, int ver)
}
fclose(pFile);
LOG_EX(LOG_Debug, "Step %d: Remove EXT4 UUID File %s .......\n", step++, EXT_FS_UUID_FILE);
remove(EXT_FS_UUID_FILE);
__otaRspStatus(OTA_VERIFY_FILE, NO_OTA_STATUS_VAL_TAG);
#if 0
for(i = 0; i < sizeof(g_umountPart) / sizeof(g_umountPart[0]); i++)
{
char *pRet = NULL;
memset(cmdBuf, 0, MAX_PATH);
sprintf(cmdBuf, "cat /proc/mounts | awk '{printf $2\"\\n\"}' | grep -Fx \"%s\" | wc -L", g_umountPart[i]);
if(GetShellExecResult(cmdBuf, &pRet) == 0)
{
unsigned int tarLen = strtoul(pRet, NULL, 10);
free(pRet);
if(strlen(g_umountPart[i]) != tarLen)
{
continue;
}
}
LOG_EX(LOG_Debug, "Step %d: Umount %s Partition .......\n", step++, g_umountPart[i]);
memset(cmdBuf, 0, MAX_PATH);
sprintf(cmdBuf, "umount %s", g_umountPart[i]);
ret = system(cmdBuf);
}
#else
ret = system("umount /rom");
#endif
__otaRspStatus(OTA_UPGRADE_PARTITION, OTA_PARTITION_BOOT);
// write to partition
LOG_EX(LOG_Debug, "Step %d: OTA %s Partition .......\n", step++, g_otaPartInfo[OTA_PARTITION_BOOT].pPartPath);
memset(basePath, 0, MAX_PATH);
sprintf(basePath, "%s/%s", dirPath, BOOT_IMG_FILE_NAME);
ret = __Write2NandPartition(OTA_PARTITION_BOOT, basePath);
if(ret != 0)
{
LOG_EX(LOG_Error, "OTA OTA_PARTITION_BOOT Error: %d\n", ret);
return (-ERR_OTA_WRITE_BOOT);
}
__otaRspStatus(OTA_UPGRADE_PARTITION, OTA_PARTITION_ROOTFS);
LOG_EX(LOG_Debug, "Step %d: OTA %s Partition .......\n", step++, g_otaPartInfo[OTA_PARTITION_ROOTFS].pPartPath);
memset(basePath, 0, MAX_PATH);
sprintf(basePath, "%s/%s", dirPath, ROOTFS_IMG_FILE_NAME);
ret = __Write2NandPartition(OTA_PARTITION_ROOTFS, basePath);
if(ret != 0)
{
LOG_EX(LOG_Error, "OTA ROOTFS_IMG_FILE_NAME Error: %d\n", ret);
return (-ERR_OTA_WRITE_ROOTFS);
}
LOG_EX(LOG_Debug, "Step %d: Verify Partition %d .......\n", step++, OTA_PARTITION_BOOT);
__otaRspStatus(OTA_VERIFY_PARTITION, OTA_PARTITION_BOOT);
pChkMD5 = EvpMD5HashFile(g_otaPartInfo[OTA_PARTITION_BOOT].pPartPath);
IHW_bin2hex(strMD5, g_iplInfo.iplItem[OTA_PARTITION_BOOT].md5sum, MD5_CHKSUM_LEN);
if(strcmp(pChkMD5, strMD5) != 0)
{
LOG_EX(LOG_Error, "Verify %s Partition MD5 Error: %s --> %s\n", g_otaPartInfo[OTA_PARTITION_BOOT].pPartPath, pChkMD5, strMD5);
return (-ERR_VERIFY_PARTITION_MD5);
}
__otaRspStatus(OTA_VERIFY_PARTITION, OTA_PARTITION_ROOTFS);
LOG_EX(LOG_Debug, "Step %d: Verify Partition %d .......\n", step++, OTA_PARTITION_ROOTFS);
CopyFileWithSize(g_otaPartInfo[OTA_PARTITION_ROOTFS].pPartPath, "/tmp/dump_rootfs.img", g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].fileSize);
pChkMD5 = EvpMD5HashFile("/tmp/dump_rootfs.img");
IHW_bin2hex(strMD5, g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].md5sum, MD5_CHKSUM_LEN);
if(strcmp(pChkMD5, strMD5) != 0)
{
LOG_EX(LOG_Error, "Verify %s Partition MD5 Error: %s --> %s\n", g_otaPartInfo[OTA_PARTITION_ROOTFS].pPartPath, pChkMD5, strMD5);
return (-ERR_VERIFY_PARTITION_MD5);
}
#if 0
LOG_EX(LOG_Debug, "Step %d: Upgrade Partition %d MD5 Checksum .......\n", step++, OTA_PARTITION_ROOTFS);
EvpMD5HashFileV2(g_otaPartInfo[OTA_PARTITION_ROOTFS].pPartPath, g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].md5sum);
g_iplInfo.iplItem[OTA_PARTITION_ROOTFS].fileSize = g_otaPartInfo[OTA_PARTITION_ROOTFS].partSize;
#endif
LOG_EX(LOG_Debug, "Step %d: Save OTA Information .......\n", step++);
g_iplInfo.curVersion = ver;
g_iplInfo.setupStatus = 0;
memset(g_otaParams.otaVer, 0, MD5_STR_LEN);
sprintf(g_otaParams.otaVer, "%d.%d.%d.%d",
(ver >> 24) & 0xFF,
(ver >> 16) & 0xFF,
(ver >> 8) & 0xFF,
ver & 0xFF);
if(g_iplInfo.setupMode != RECOVERY_SETUP)
{
g_iplInfo.setupMode = SYSTEM_OTA;
}
SET_STA_CMD(g_otaParams.otaStatus, CMD_RUN_OTA);
ret = __SaveIPLParams(&g_iplInfo);
ret = __ota_save_params(&g_otaParams);
if(ret != 0)
{
LOG_EX(LOG_Error, "Save IPL3 Error: %d\n", ret);
LOG_EX(LOG_Error, "Save OTA Params Error: %d\n", ret);
return (-ERR_OTA_WRITE_PARAMS);
}
//print_hex_dump_bytes("IPL3", DUMP_PREFIX_ADDRESS, &g_iplInfo, sizeof(IPL_DATA_INFO));
__printIPLParams(&g_iplInfo, "OTA Succesed_____:");
__ota_print_params(&g_otaParams, "OTA Finished");
LOG_EX(LOG_Debug, "Step %d: Waitting for reboot ......\n", step++);
@ -733,24 +538,15 @@ static void __otaFromLocalImage(void *pParams)
OTA_TEMP_DIR, version,
OTA_TEMP_DIR, version,
pFileName);
free(pFileName);
ret = system(buf);
memset(buf, 0, MAX_PATH);
sprintf(buf, "%s/%d/ota.md5", OTA_TEMP_DIR, version);
SetHBLAutoExit(FALSE);
__otaRspStatus(OTA_UPGRADE_START, NO_OTA_STATUS_VAL_TAG);
LOG_EX(LOG_Debug, "Step %d: OTA write to partition .......\n", step++);
//__otaBackupWifi(TRUE);
//LOG_EX(LOG_Debug, "Step %d: OTA Backup WIFI .......\n", step++);
LOG_EX(LOG_Debug, "System into mini ramfs mode\n");
ret = system("/sbin/ramfs.sh");
LOG_EX(LOG_Debug, "Ramfs ready......\n");
memset(buf, 0, MAX_PATH);
sprintf(buf, "%s/%d/ota.md5", OTA_TEMP_DIR, version);
reTry = 3;
while(reTry--)
@ -761,6 +557,19 @@ static void __otaFromLocalImage(void *pParams)
}
}
if(ret == 0)
{
ret = system("rm -f /mnt/UDISK/ota/*.img /mnt/UDISK/ota/*.md5 > /dev/null");
memset(buf, 0, MAX_PATH);
sprintf(buf, "cp %s/%d/* /mnt/UDISK/ota > /dev/null", OTA_TEMP_DIR, version);
ret = system(buf);
memset(buf, 0, MAX_PATH);
sprintf(buf, "rm %s/* > /dev/null", g_otaDownloadPath);
ret = system(buf);
}
if(ret == ERR_OPEN_FILE
|| ret == ERR_MD5_FILE
|| ret == ERR_MD5_CHECK_SUM
@ -773,45 +582,6 @@ static void __otaFromLocalImage(void *pParams)
__otaRspStatus(OTA_REBOOT_SYSTEM, NO_OTA_STATUS_VAL_TAG);
#if 0
LOG_EX(LOG_Debug, "Step %d: Clean resource and evn ......\n", step++);
for(i = 0; i < sizeof(g_processName) / sizeof(g_processName[0]); i++)
{
memset(buf, 0, MAX_PATH);
sprintf(buf, "killall -9 %s > /dev/null", g_processName[i]);
ret = system(buf);
}
#endif
#if 0
SysPointMarkUpload();
LogUploadCurLogFile();
ret = system("sync && ubus call system watchdog \'{\"stop\" : true}\'");
reTry = 3;
do
{
sleep(1);
} while(reTry--);
reTry = 0;
LOG_EX(LOG_Debug, "Reboot System By Power Control Chips\n");
sleep(1);
ret = system("sync && echo 3140 > /sys/bus/platform/devices/axp22_board/axp22_reg");
sleep(10);
while(TRUE)
{
LOG_EX(LOG_Debug, "Reboot System: %d times\n", reTry++);
ret = system("reboot -f");
sleep(3);
}
#endif
reTry = 300;
while(reTry--)
@ -899,10 +669,12 @@ static int __isPreDownloader(POTA_DATA_INFO pInfo)
free(pMD5Val);
utstring_free(pDlPath);
utstring_free(pChkPath);
if(pMD5Chk)
{
free((void*)pMD5Chk);
}
return -ERR_MD5_CHECK_SUM;
}
@ -1041,25 +813,6 @@ static void __otaDownloadImageCb(void *pParams)
pthread_detach(pthread_self());
}
static void __dBusDeameonCb(MODULE_NAME modName, int status)
{
if(status)
{
LOG_EX(LOG_Error, "Daemon(%d) Msg: [%s]\n", modName, status == 0 ? "Connect" : "Disconnect");
}
else
{
LOG_EX(LOG_Info, "Daemon(%d) Msg: [%s]\n", modName, status == 0 ? "Connect" : "Disconnect");
}
if(modName == MODULE_CONTROLLER && status == 0)
{
__otaRspStatus(OTA_CURRENT_VERSION, g_iplInfo.curVersion);
__otaRspStatus(OTA_CURRENT_SETUP_MODE, g_iplInfo.setupMode);
__otaRspStatus(OTA_CURRENT_REBOOT_TIME, g_iplInfo.setupStatus);
}
}
static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, PDBUS_MSG_PACK pMsg)
{
int err;
@ -1086,6 +839,7 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
__otaRspStatus(OTA_ERR_CODE, -ERR_OTA_NOT_READY);
LOG_EX(LOG_Error, "Current Not In OTA Mode\n");
}
break;
case CMD_MISC_QUERY_DL_STATUS:
@ -1097,6 +851,7 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
{
__otaRspStatus(OTA_DOWNLOAD_FILE, 0);
}
break;
case CMD_MISC_QUERY_OTA_STATUS:
@ -1112,6 +867,10 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
{
__otaRspStatus(OTA_SUCCESED, 1);
}
__otaRspStatus(OTA_CURRENT_VERSION, 0);
__otaRspStatus(OTA_CURRENT_SETUP_MODE, g_sSetupStatus);
__otaRspStatus(OTA_CURRENT_REBOOT_TIME, GET_STA_CNT(g_otaParams.otaStatus));
break;
case CMD_SYSTEM_STANDBY:
@ -1122,15 +881,15 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
if(g_IsOTAMode == 0)
{
if(g_iplInfo.setupMode == SYSTEM_OTA)
if(g_sSetupStatus == SYSTEM_OTA)
{
LOG_EX(LOG_Debug, "Current System Mode: SYSTEM_OTA\n");
}
else if(g_iplInfo.setupMode == RECOVERY_SETUP)
else if(g_sSetupStatus == RECOVERY_SETUP)
{
LOG_EX(LOG_Debug, "Current System Mode: RECOVERY_SETUP\n");
}
else if(g_iplInfo.setupMode == SYSTEM_OTA_OK)
else if(g_sSetupStatus == SYSTEM_OTA_OK)
{
LOG_EX(LOG_Debug, "Current System Mode: SYSTEM_OTA_OK\n");
}
@ -1153,8 +912,7 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
}
else
{
//unsigned long long uDiskFreeSize = GetPartitionFreeSize("/mnt/UDISK/");
unsigned long long uMemFreeSize = GetPartitionFreeSize("/tmp/");
unsigned long long uDiskFreeSize = GetPartitionFreeSize("/mnt/UDISK/");
unsigned long long uUsedSize = 0;
g_IsOTAMode = TRUE;
@ -1168,51 +926,15 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
uUsedSize = pInfo->otaFileInfo.size + (1024 * 1024 * 10);
if(g_isBackupMode)
{
LOG_EX(LOG_Debug, "OTA on recovery mode\n");
pInfo->otaMode == OTA_MODE_FORCE_NOW;
}
else
{
LOG_EX(LOG_Debug, "OTA on normal mode\n");
}
#if 0
if(uUsedSize > uDiskFreeSize)
{
LOG_EX(LOG_Error, "Error: File Size = %u bytes, Need %llu bytes, UDISK Free %llu bytes\n",
pInfo->otaFileInfo.size, uUsedSize, uDiskFreeSize);
if(uUsedSize > uMemFreeSize)
{
LOG_EX(LOG_Error, "Error: Not Enought Space, Memory Free %llu bytes\n", uMemFreeSize);
__otaRspStatus(OTA_DISK_FULL, pInfo->otaCmd);
break;
}
else
{
memset(g_otaDownloadPath, 0, MAX_PATH);
strcpy(g_otaDownloadPath, OTA_MEMORY_DOWNLOAD_DIR);
LOG_EX(LOG_Warn, "Warnning: Storage OTA File To Memory: %s\n", g_otaDownloadPath);
}
}
#else
if(uUsedSize > uMemFreeSize)
{
g_IsOTAMode = FALSE;
LOG_EX(LOG_Error, "Error: Not Enought Space, Memory Free %llu bytes\n", uMemFreeSize);
__otaRspStatus(OTA_DISK_FULL, pInfo->otaCmd);
free(pInfo);
break;
}
else
{
memset(g_otaDownloadPath, 0, MAX_PATH);
strcpy(g_otaDownloadPath, OTA_MEMORY_DOWNLOAD_DIR);
LOG_EX(LOG_Warn, "Warnning: Storage OTA File To Memory: %s\n", g_otaDownloadPath);
}
#endif
switch(pInfo->otaCmd)
{
@ -1226,20 +948,24 @@ static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, P
else
{
err = uv_thread_create(&uvThread, __otaDownloadImageCb, pInfo);
if(err != 0)
{
LOG_EX(LOG_Error, "Create Thread Error: %d\n", err);
}
}
break;
case OTA_CMD_USED_LOCAL_IMAGE:
case OTA_CMD_EXEC:
err = uv_thread_create(&uvThread, __otaFromLocalImage, (void*)(intptr_t)pInfo->version);
if(err != 0)
{
LOG_EX(LOG_Error, "Create Thread Error: %d\n", err);
}
free(pInfo);
break;
@ -1269,6 +995,7 @@ int main(int argc, char **argv)
int i, ret = 0;
char buf[256];
DBusConnection* pBus;
int otaCmd, otaFlag, cnt;
//struct tm *pTm = NULL;
g_pMainLoop = GetDBusDefaultLoop();
@ -1276,7 +1003,7 @@ int main(int argc, char **argv)
pBus = DBusWithLibuvInit(g_pMainLoop,
g_pModInfoTable[MODULE_OTA].modAliase,
__dBusOnMessage,
__dBusDeameonCb,
NULL,
NULL,
&ret);
@ -1293,98 +1020,48 @@ int main(int argc, char **argv)
sprintf(buf, "mkdir -p %s", OTA_FILE_DOWNLOAD_DIR);
ret = system(buf);
memset(buf, 0, 256);
sprintf(buf, "mkdir -p %s", OTA_MEMORY_DOWNLOAD_DIR);
ret = system(buf);
for(i = 0; i < OTA_PARTITION_MAX; i++)
if(__ota_read_params(&g_otaParams) == 0)
{
char *pCmdRet = NULL;
memset(buf, 0, 256);
sprintf(buf, "cat /proc/partitions | grep `readlink %s | xargs basename` | awk '{print $3}'",
g_otaPartInfo[i].pPartPath);
if((ret = GetShellExecResult((const char *)buf, &pCmdRet)) == 0)
{
g_otaPartInfo[i].partSize = strtoul(pCmdRet, NULL, 10);
if(errno == ERANGE || errno == EINVAL)
{
g_otaPartInfo[i].partSize = 0;
__ota_print_params(&g_otaParams, "System setup");
}
g_otaPartInfo[i].partSize *= 1024;
otaCmd = GET_STA_CMD(g_otaParams.otaStatus);
otaFlag = GET_STA_FLAG(g_otaParams.otaStatus);
ret = GET_STA_ERR(g_otaParams.otaStatus);
cnt = GET_STA_CNT(g_otaParams.otaStatus);
//fprintf(stdout, "%d: %s --> %s\n", i, g_otaPartInfo[i].pPartPath, pCmdRet);
free(pCmdRet);
}
if(ret != 0)
{
LOG_EX(LOG_Error, "System setup error: code = %d, flag = %d, otaCmd = %d\n",
ret, otaFlag, otaCmd);
}
LOG_EX(LOG_Debug, "__ReadIPLParams: %d\n", __ReadIPLParams(&g_iplInfo));
if(ret == 0)
if(cnt >= 3)
{
__printIPLParams(&g_iplInfo, "Current OTA Information:");
LOG_EX(LOG_Error, "Reboot more than %d times\n", cnt);
}
g_sSetupStatus = g_iplInfo.setupMode;
if(g_iplInfo.setupMode == SYSTEM_OTA)
if(otaFlag == FLAG_EXEC_OTA)
{
LOG_EX(LOG_Debug, "System setup on OTA mode\n");
if(g_iplInfo.setupStatus > 3 && g_iplInfo.setupStatus != 0xFFFFFFFF)
{
LOG_EX(LOG_Error, "Check OTA error more than 3 times, Ask server todo next step.....\n");
__otaRspStatus(OTA_SUCCESED, -1);
g_sSetupStatus = SYSTEM_OTA_OK;
}
else if(g_iplInfo.setupStatus <= 3)
else if(otaFlag == FLAG_NORMAL)
{
LOG_EX(LOG_Error, "Check OTA error less than 3 times, Redo OTA used last image.....\n");
g_IsOTAMode = 1;
__otaFromLocalImage(&g_iplInfo.curVersion);
g_IsOTAMode = 0;
}
}
else if(g_iplInfo.setupMode == RECOVERY_SETUP)
{
g_isBackupMode = TRUE;
LOG_EX(LOG_Error, "System on recovery mode\n");
__otaRspStatus(OTA_CURRENT_SETUP_MODE, RECOVERY_SETUP);
}
else if(g_iplInfo.setupMode == SYSTEM_OTA_OK)
{
LOG_EX(LOG_Info, "System OTA OK\n");
__otaRspStatus(OTA_CURRENT_SETUP_MODE, SYSTEM_OTA_OK);
}
else
{
LOG_EX(LOG_Debug, "System setup on normal mode\n");
g_sSetupStatus = NORMAL_SETUP;
}
if(g_iplInfo.setupStatus != 0)
{
if(g_iplInfo.setupMode == SYSTEM_OTA_OK)
{
g_iplInfo.setupMode = NORMAL_SETUP;
}
SET_STA_CNT(g_otaParams.otaStatus, 0);
SET_STA_CMD(g_otaParams.otaStatus, CMD_RUN_BOOT);
SET_STA_FLAG(g_otaParams.otaStatus, FLAG_NORMAL);
g_iplInfo.setupStatus = 0;
__SaveIPLParams(&g_iplInfo);
}
__ota_save_params(&g_otaParams);
// Make sure continue last download task
__otaRspStatus(OTA_DOWNLOAD_FILE, -28);
__otaRspStatus(OTA_CURRENT_VERSION, 0);
RunUVLoop(g_pMainLoop);
while(TRUE)
{
usleep(1000);
}
return (0);
}