[Feature]add MT2731_MP2_MR2_SVN388 baseline version
Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/devtools/mrdump/mrdump_tool_source/mrdump_status.c b/src/devtools/mrdump/mrdump_tool_source/mrdump_status.c
new file mode 100644
index 0000000..edc4a2e
--- /dev/null
+++ b/src/devtools/mrdump/mrdump_tool_source/mrdump_status.c
@@ -0,0 +1,265 @@
+/* printf */
+#include <stdio.h>
+
+/* open */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+/* read */
+#include <unistd.h>
+
+/* free */
+#include <stdlib.h>
+
+/* ioctl */
+#include <sys/ioctl.h>
+
+/* lseek64 */
+#ifndef _LARGEFILE64_SOURCE
+#define _LARGEFILE64_SOURCE
+#endif
+#include <sys/types.h>
+#include <unistd.h>
+
+/* bzero */
+#include <strings.h>
+
+/* strlen, memset, strncpy, strtok... */
+#include <string.h>
+
+/* errno */
+#include <errno.h>
+
+/* BLKGETSIZE64 */
+#include <linux/fs.h>
+
+/* mrdump related */
+#include "mrdump_log.h"
+#include "mrdump_common.h"
+#include "mrdump_status.h"
+#include "mrdump_status_private.h"
+
+#ifdef __YOCTO_OS__
+#define strlcpy strncpy
+#endif
+
+static int file_read_string(const char* path, char *content, int len)
+{
+ if (len <= 0) {
+ return -2;
+ }
+
+ int fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+
+ /* Preserved NULL byte */
+ len--;
+ int size = 0;
+ do {
+ int ret = read(fd, content + size, len - size);
+ if (ret <= 0)
+ break;
+ size = size + ret;
+ } while (size < len);
+ content[size] = 0;
+
+ close(fd);
+ return size;
+}
+
+static int expdb_open(struct partinfo *partinfo)
+{
+ uint64_t part_size;
+ uint32_t part_blksize;
+
+ memset(partinfo, 0, sizeof(struct partinfo));
+
+ char *pp = mrdump_get_device_node(MRDUMP_EXPDB_NAME);
+ if (pp == NULL) {
+ MD_LOGE("%s: No expdb partition found", __func__);
+ return -1;
+ }
+
+ int fd = open(pp, O_RDWR);
+ if (fd < 0) {
+ MD_LOGE("%s: open expdb failed(%d)", __func__, errno);
+ free(pp);
+ return -1;
+ }
+ free(pp);
+
+ if (ioctl(fd, BLKGETSIZE64, &part_size) < 0) {
+ MD_LOGE("%s, get expdb partition size fail(%d)", __func__, errno);
+ close(fd);
+ return -1;
+ }
+
+ if (ioctl(fd, BLKSSZGET, &part_blksize) < 0) {
+ MD_LOGE("%s, get sector size fail(%d)", __func__, errno);
+ close(fd);
+ return -1;
+ }
+
+ partinfo->fd = fd;
+ partinfo->size = part_size;
+ partinfo->blksize = part_blksize;
+
+ return 0;
+}
+
+int mrdump_is_supported(void)
+{
+ char kversion[16], lversion[16];
+ int klen, llen;
+
+ bzero(kversion, sizeof(kversion));
+ bzero(lversion, sizeof(lversion));
+
+ if (file_read_string(MRDUMP_KVER, kversion, sizeof(kversion)) < 0) {
+ MD_LOGE("%s: cannot get kernel version\n", __func__);
+ return 0;
+ }
+
+ klen = strlen(kversion);
+ if (klen == 0) {
+ MD_LOGE("%s: null kernel version\n", __func__);
+ return 0;
+ }
+
+ if (file_read_string(MRDUMP_LVER, lversion, sizeof(lversion)) < 0) {
+ MD_LOGE("%s: cannot get lk version\n", __func__);
+ return 0;
+ }
+
+ llen = strlen(lversion);
+ if (llen == 0) {
+ MD_LOGE("%s: null lk version\n", __func__);
+ return 0;
+ }
+
+ if ((klen != llen) || (strncmp(kversion, lversion, klen) != 0)) {
+ MD_LOGE("%s: kernel and lk version mismatched.\n", __func__);
+ return 0;
+ }
+
+ MD_LOGI("%s: true\n", __func__);
+ return 1;
+}
+
+bool mrdump_status_clear(void)
+{
+ struct partinfo partinfo;
+
+ if (expdb_open(&partinfo) >= 0) {
+ if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
+ MD_LOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+
+ struct mrdump_cblock_result cblock_result;
+ if (read(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
+ MD_LOGE("%s: Can't read part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+ memset(cblock_result.status, 0, sizeof(cblock_result.status));
+ strncpy(cblock_result.status, "CLEAR", 5);
+
+ if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
+ MD_LOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+ if (write(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
+ MD_LOGE("%s: Can't write part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+ close(partinfo.fd);
+ return true;
+ }
+ return false;
+}
+
+bool mrdump_status_get(struct mrdump_status_result *result)
+{
+ memset(result, 0, sizeof(struct mrdump_status_result));
+ result->struct_size = sizeof(struct mrdump_status_result);
+
+ struct partinfo partinfo;
+ if (expdb_open(&partinfo) >= 0) {
+ if (lseek64(partinfo.fd, partinfo.size - MRDUMP_OFFSET, SEEK_SET) < 0) {
+ MD_LOGE("%s: Can't seek part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+
+ struct mrdump_cblock_result cblock_result;
+ if (read(partinfo.fd, &cblock_result, sizeof(struct mrdump_cblock_result)) != sizeof(struct mrdump_cblock_result)) {
+ MD_LOGE("%s: Can't read part fd %d\n", __func__, partinfo.fd);
+ close(partinfo.fd);
+ return false;
+ }
+ close(partinfo.fd);
+
+ if (strcmp(cblock_result.sig, MRDUMP_SIG) != 0) {
+ MD_LOGE("%s: Signature mismatched (result: %s)\n", __func__, cblock_result.sig);
+ return false;
+ }
+ /* Copy/parsing status line */
+ strncpy(result->status_line, cblock_result.status, sizeof(cblock_result.status));
+ result->status_line[sizeof(result->status_line) - 1] = 0;
+
+ char *saveptr;
+ cblock_result.status[sizeof(cblock_result.status) - 1] = 0;
+ char *strval = strtok_r(cblock_result.status, "\n", &saveptr);
+ if (strval != NULL) {
+ if (strcmp(strval, "OK") == 0) {
+ result->status = MRDUMP_STATUS_OK;
+ result->output = MRDUMP_OUTPUT_NULL;
+
+ do {
+ strval = strtok_r(NULL, "\n", &saveptr);
+ if (strval != NULL) {
+ if (strncmp(strval, "OUTPUT:", 7) == 0) {
+ if (strcmp(strval + 7, "EXT4_DATA") == 0) {
+ result->output = MRDUMP_OUTPUT_DATA_FS;
+ }
+ else if (strcmp(strval + 7, "PARTITION_DATA") == 0) {
+ result->output = MRDUMP_OUTPUT_PARTITION;
+ }
+ else {
+ return false;
+ }
+ }
+ else if (strncmp(strval, "MODE:", 5) == 0) {
+ strlcpy(result->mode, strval + 5, sizeof(result->mode));
+ }
+ }
+ } while (strval != NULL);
+ }
+ else if (strcmp(strval, "NONE") == 0) {
+ result->status = MRDUMP_STATUS_NONE;
+ }
+ else if (strcmp(strval, "CLEAR") == 0) {
+ result->status = MRDUMP_STATUS_NONE;
+ }
+ else {
+ result->status = MRDUMP_STATUS_FAILED;
+ }
+ }
+ else {
+ MD_LOGE("%s: status parsing error \"%s\"\n", __func__, cblock_result.status);
+ return false;
+ }
+
+ strncpy(result->log_buf, cblock_result.log_buf, sizeof(cblock_result.log_buf));
+ result->log_buf[sizeof(result->log_buf) - 1] = 0;
+ return true;
+ }
+ return false;
+}