[Feature][ZXW-130]merge P50U02 version
Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No
Change-Id: I4f29ec5bb7c59385f23738d2b7ca84e67c100f69
diff --git a/ap/lib/libcpnv/nvro.c b/ap/lib/libcpnv/nvro.c
new file mode 100755
index 0000000..0e5880c
--- /dev/null
+++ b/ap/lib/libcpnv/nvro.c
@@ -0,0 +1,338 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "openssl/md5.h"
+#include "mtd.h"
+#include "libcpnv.h"
+#include "cfg_api.h"
+#include "flags_api.h"
+#include "zxicbasic_api.h"
+
+
+/*******************************************************************************
+* 功能描述: copyfile
+* 参数说明:
+* (传入参数) to:目标文件
+* (传入参数) from:源文件
+* 返 回 值: 0表示成功,负值失败
+* 其它说明:
+*******************************************************************************/
+static int copyfile(const char *from, const char *to)
+{
+ int fd_to;
+ int fd_from;
+ char buf[4096];
+ ssize_t nread;
+ int ret = -1;
+
+ fd_from = open(from, O_RDONLY);
+ if (fd_from < 0)
+ return -2;
+
+ fd_to = open(to, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0640);
+ if (fd_to < 0) {
+ ret = -3;
+ goto out_error;
+ }
+
+ while (1)
+ {
+ char *out_ptr;
+ ssize_t nwritten;
+
+ nread = read(fd_from, buf, sizeof(buf));
+ if (nread == 0)
+ {
+ break; /* read file done*/
+ }
+ else
+ {
+ if (nread < 0 )
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ continue;
+ }
+ else
+ {
+ ret = -4;
+ goto out_error;
+ }
+ }
+ }
+
+ out_ptr = buf;
+ do
+ {
+ nwritten = write(fd_to, out_ptr, nread);
+ if (nwritten > 0)
+ {
+ nread -= nwritten;
+ out_ptr += nwritten;
+ }
+ else
+ {
+ if (nwritten < 0)
+ {
+ if (errno == EINTR || errno == EAGAIN)
+ {
+ continue;
+ }
+ else
+ {
+ ret = -5;
+ goto out_error;
+ }
+ }
+ }
+ } while (nread > 0);
+ }
+
+ ret = fsync(fd_to);
+ if (ret < 0) {
+ printf("Sync Failed:%s, file path:%s", strerror(errno), to);
+ goto out_error;
+ }
+
+ if (close(fd_to) < 0)
+ {
+ fd_to = -1;
+ ret = -6;
+ goto out_error;
+ }
+ close(fd_from);
+
+ /* Success! */
+ return 0;
+
+out_error:
+ printf("copyfile %s to %s error:%d\n", from, to, ret);
+ close(fd_from);
+ if (fd_to >= 0)
+ close(fd_to);
+
+ return ret;
+}
+
+int nvrofs2_mount(int rw)
+{
+ if (rw)
+ return zxic_system("/bin/mount -t jffs2 -o rw,sync mtd:nvrofs2 /mnt/nvrofs2");
+ else
+ return zxic_system("/bin/mount -t jffs2 -o ro mtd:nvrofs2 /mnt/nvrofs2");
+}
+int nvrofs2_umount(void)
+{
+ return zxic_system("/bin/umount -f -l /mnt/nvrofs2");
+}
+
+unsigned char *bin2hex(const unsigned char *old, const size_t oldlen)
+{
+ unsigned char *result = (unsigned char *)malloc(oldlen * 2 + 1);
+ size_t i, j;
+ int b = 0;
+
+ for (i = j = 0; i < oldlen; i++)
+ {
+ b = old[i] >> 4;
+ result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
+ b = old[i] & 0xf;
+ result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
+ }
+ result[j] = '\0';
+ return result;
+}
+
+int calc_file_hash(const char *file_in, unsigned char *hash_value)
+{
+ MD5_CTX ctx;
+ unsigned char *buf;
+ int offset;
+ int fd;
+ ssize_t len;
+
+ fd = open(file_in, O_RDONLY);
+ if (fd < 0)
+ return -1;
+ buf = malloc(4096);
+ if (buf == NULL)
+ return -1;
+ MD5_Init(&ctx);
+ do
+ {
+ len = full_read(fd, buf, 4096);
+ MD5_Update(&ctx, buf, len);
+ if (len < 4096)
+ break;
+ } while(1);
+
+ MD5_Final(hash_value, &ctx);
+ free(buf);
+ return 0;
+}
+
+int file_hash(const char *file_in, const char *file_hash)
+{
+ unsigned char hash_value[16] = {0};
+ unsigned char *hash_str;
+ int ret;
+ ssize_t ret_s;
+
+ ret = calc_file_hash(file_in, hash_value);
+ if (ret < 0)
+ return -1;
+ hash_str = bin2hex(hash_value, 16);
+ ret_s = open_write_close(file_hash, hash_str, 32);
+ free(hash_str);
+ if (ret_s != 32)
+ return -1;
+ return 0;
+}
+int file_hash_check(const char *file_in, const char *file_hash)
+{
+ unsigned char hash_value[16] = {0};
+ unsigned char *hash_str;
+ unsigned char hash_str2[33] = {0};
+ int ret;
+ ssize_t ret_s;
+
+ ret = calc_file_hash(file_in, hash_value);
+ if (ret < 0)
+ return -1;
+ hash_str = bin2hex(hash_value, 16);
+ memset(hash_str2, 0, sizeof(hash_str2));
+ ret_s = open_read_close(file_hash, hash_str2, 32);
+ if (ret_s != 32)
+ return -1;
+ if (strcmp(hash_str, hash_str2) == 0)
+ {
+ return 0;
+ }
+ return -1;
+}
+
+unsigned int cpnv_NvroBackup(void)
+{
+ char mtd_path[MAX_PATH] = {0};
+ int ret;
+
+ ret = mtd_find("nvrofs2", mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
+ if (ret < 0)
+ {
+ printf("[error]cpnv can not find nvrofs2\n");
+ return CPNV_ERROR;
+ }
+ ret = mtd_erase_partition("nvrofs2");
+ if (ret != 0)
+ {
+ printf("[error]cpnv erase nvrofs2\n");
+ return CPNV_ERROR;
+ }
+
+ nvrofs2_umount();
+ ret = nvrofs2_mount(1);
+ if (ret != 0)
+ {
+ printf("[error]cpnv nvrofs2_mount\n");
+ return CPNV_ERROR;
+ }
+ ret = copyfile("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs2/nvroall.bin");
+ if (ret != 0)
+ {
+ printf("[error]cpnv nvrofs2 copyfile\n");
+ goto out_err;
+ }
+ ret = file_hash("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
+ if (ret != 0)
+ {
+ printf("[error]cpnv file_hash\n");
+ goto out_err;
+ }
+ ret = nvrofs2_umount();
+ if (ret < 0)
+ {
+ printf("[error]cpnv nvrofs2_umount\n");
+ return CPNV_ERROR;
+ }
+
+ ret = flags_set_nvroflag(NVRO_BACKED_UP);
+ if (ret != 0)
+ {
+ printf("[error]cpnv NVRO_BACKED_UP\n");
+ return CPNV_ERROR;
+ }
+ return CPNV_OK;
+
+out_err:
+ nvrofs2_umount();
+
+ return CPNV_ERROR;
+}
+
+unsigned int cpnv_NvroRestore(void)
+{
+ int ret;
+ unsigned int ret_u;
+ unsigned int nvro_flag;
+
+ nvro_flag = flags_get_nvroflag();
+ if (nvro_flag != NVRO_RESTORING)
+ {
+ printf("[error]cpnv_NvroRestore nvro flag error\n");
+ return CPNV_ERROR;
+ }
+ nvrofs2_umount();
+ ret = nvrofs2_mount(0);
+ if (ret != 0)
+ {
+ printf("[error]cpnv nvrofs2_mount\n");
+ return CPNV_ERROR;
+ }
+ ret = file_hash_check("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
+ if (ret != 0)
+ {
+ printf("[error]cpnv file_hash_check\n");
+ goto out_err;
+ }
+ ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
+ if (ret_u != CPNV_OK)
+ {
+ printf("[error]cpnv nvrofs Attr 1\n");
+ goto out_err;
+ }
+ ret = copyfile("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs/nvroall.bin");
+ if (ret != 0)
+ {
+ printf("[error]cpnv nvrofs2 restore copyfile\n");
+ goto out_err;
+ }
+ ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
+ if (ret_u != CPNV_OK)
+ {
+ printf("[error]cpnv nvrofs Attr 0\n");
+ goto out_err;
+ }
+ ret = nvrofs2_umount();
+ if (ret < 0)
+ {
+ printf("[error]cpnv nvrofs2_umount\n");
+ return CPNV_ERROR;
+ }
+ ret = flags_set_nvroflag(NVRO_BACKED_UP);
+ if (ret != 0)
+ {
+ printf("[error]cpnv_NvroRestore set NVRO_BACKED_UP\n");
+ return CPNV_ERROR;
+ }
+ return CPNV_OK;
+
+out_err:
+ nvrofs2_umount();
+
+ return CPNV_ERROR;
+}