[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/mtd.c b/ap/lib/libcpnv/mtd.c
new file mode 100755
index 0000000..61be26d
--- /dev/null
+++ b/ap/lib/libcpnv/mtd.c
@@ -0,0 +1,129 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/vfs.h>
+
+
+#include <mtd/mtd-abi.h>
+#include <errno.h>
+
+#include <sys/ioctl.h>
+#include "mtd.h"
+
+
+int mtd_find(const char *i_parti_name, char *o_mtd_path, device_type_t device_type, unsigned int o_mtd_path_len)
+{
+	FILE *fd_mtd = 0;
+	char buf[128];
+	char *line_str;
+
+	if (!o_mtd_path_len)
+		return -1;
+
+	fd_mtd = fopen("/proc/mtd", "r+");
+	if (NULL == fd_mtd) {
+		printf("fs_check open file error:%s", strerror(errno));
+		//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open file error:%s", strerror(errno));
+		goto error0;
+	}
+	//printf("fs_check partition name:%s\n", i_parti_name);
+
+	while (1) {
+		int matches = 0;
+		char mtdname[64] = {0};
+		int  mtdnum = 0;
+		unsigned int  mtdsize, mtderasesize;
+        memset(buf, 0x00, sizeof(buf));
+		line_str = fgets(buf, sizeof(buf), fd_mtd);
+
+		if (NULL == line_str) {
+			printf("fs_check get info from mtd error:%s\n", strerror(errno));
+			//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get info from mtd error:%s\n", strerror(errno));
+			goto error1;
+		}
+		//mtd5: 00100000 00020000 "fotaflag"
+		matches = sscanf(buf, "mtd%d: %x %x \"%63[^\"]",
+		                 &mtdnum, &mtdsize, &mtderasesize, mtdname);
+		mtdname[63] = '\0';
+		
+		if ((matches == 4) && (strcmp(mtdname, i_parti_name) == 0)) {
+			memset(o_mtd_path, 0x00, o_mtd_path_len);
+			if (device_type == DEVICE_MTD_BLOCK) {
+				snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtdblock%d", mtdnum);
+			} else if (device_type == DEVICE_MTD) {
+				snprintf(o_mtd_path, o_mtd_path_len, "/dev/mtd%d", mtdnum);
+			} else if (device_type == DEVICE_ZFTL) {
+				snprintf(o_mtd_path, o_mtd_path_len, "/dev/zftl%d", mtdnum);
+			} else {
+				printf("fs_check unknown device type %d\n", device_type);
+				//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check unknown device type %d\n", device_type);
+				goto error1;
+			}
+			//printf("fs_check o_mtd_path=[%s]\n", o_mtd_path);
+			break;
+		}
+
+	}
+	fclose(fd_mtd);
+	return 0;
+
+error1:
+	fclose(fd_mtd);
+error0:
+	return -1;
+}
+
+int mtd_erase_partition(const char* partition_name)
+{
+	int ret = 0;
+	char mtd_path[MAX_PATH] = {0};
+	int fd_mtd = -1;
+
+	struct mtd_info_user meminfo = {0};
+	struct erase_info_user64 erase_info = {0};
+
+	if (NULL == partition_name) {
+		return -1;
+	}
+	ret = mtd_find(partition_name, mtd_path, DEVICE_MTD, MAX_PATH);
+	if (ret < 0) {
+		printf("fs_check mtd_find %s failed\n", partition_name);
+		//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check mtd_find %s failed\n", partition_name);
+		ret = -1;
+		goto out;
+	}
+	fd_mtd = open(mtd_path, O_RDWR);
+	if (fd_mtd < 0) {
+		printf("fs_check open %s error, %s\n", partition_name, strerror(errno));
+		//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check open %s error, %s\n", partition_name, strerror(errno));
+		ret = -1;
+		goto out;
+	}
+	if (ioctl(fd_mtd, MEMGETINFO, &meminfo) != 0) {
+		printf("fs_check get %s info error, %s\n", partition_name, strerror(errno));
+		//sc_debug_info_record(MODULE_ID_AP_FS_CHECK, "fs_check get %s info error, %s\n", partition_name, strerror(errno));
+		ret = -1;
+		goto out;
+	}
+	erase_info.length = meminfo.erasesize;
+	for (erase_info.start = 0; erase_info.start < meminfo.size; erase_info.start += meminfo.erasesize) {
+		if (ioctl(fd_mtd, MEMGETBADBLOCK, &(erase_info.start)) > 0) {
+			printf("fs_check mtd, not erasing bad block at 0x%llx\n", erase_info.start);
+			continue;
+		}
+		if (ioctl(fd_mtd, MEMERASE64, &erase_info) < 0) {
+			printf("fs_check mtd, erasing failure at 0x%llx\n", erase_info.start);
+		}
+	}
+	ret = 0;
+out:
+	if (fd_mtd >= 0) {
+		close(fd_mtd);
+	}
+	return ret;
+}