Add mbtk_otad
Change-Id: I472a8f3acdc6207a17800352bf7ce5e6fff167a9
diff --git a/mbtk/mbtk_otad/src/mbtk_ota.c b/mbtk/mbtk_otad/src/mbtk_ota.c
new file mode 100755
index 0000000..9e49589
--- /dev/null
+++ b/mbtk/mbtk_otad/src/mbtk_ota.c
@@ -0,0 +1,235 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <mtd/mtd-user.h>
+
+#include "otad.h"
+#include "mbtk_type.h"
+#include "mbtk_device.h"
+
+typedef struct {
+ char name[32];
+ char dev[16];
+ uint32 partition_start;
+ uint32 partition_size;
+ uint32 erase_size;
+} partition_info_t;
+
+/*
+* revision_out start from 0x1000.
+*/
+#define REVISION_OUT_ADDR 0x1000
+
+char revision_out[48] = {0};
+static bool revision_out_found = FALSE;
+
+static int partition_get(char *partition_name, partition_info_t *info)
+{
+ FILE *fp = fopen("/proc/mtd", "r");
+ if(fp == NULL) {
+ OTA_ERR("fopen(/proc/mtd) fail:%d", errno);
+ return -1;
+ }
+
+ char buff[64];
+ char size_str[16];
+ char erase_size_str[16];
+ char name[32];
+ memset(buff, 0x0, sizeof(buff));
+ while(fgets(buff, sizeof(buff), fp)) {
+ if(strstr(buff, partition_name)) {
+ memset(size_str, 0x0, sizeof(size_str));
+ memset(erase_size_str, 0x0, sizeof(erase_size_str));
+ memset(name, 0x0, sizeof(name));
+ memcpy(info->dev, "/dev/", 5);
+ if(4 == sscanf(buff, "%s %s %s %s", info->dev + 5, size_str, erase_size_str, name)) {
+ if(name[0] == '\"' && name[strlen(name) - 1] == '\"') {
+ memcpy(info->name, name + 1, strlen(name) - 2); // No copy ""
+ } else {
+ OTA_ERR("partition(%s) name error.", buff);
+ return -1;
+ }
+
+ if(info->dev[strlen(info->dev) - 1] == ':') {
+ info->dev[strlen(info->dev) - 1] = '\0';
+ }
+
+ info->partition_size = (uint32)strtoul(size_str, NULL, 16);
+ info->erase_size = (uint32)strtoul(erase_size_str, NULL, 16);
+ //info->partition_start += info->partition_size;
+ break;
+ } else {
+ OTA_ERR("sscanf(%s) fail:%d", buff, errno);
+ return -1;
+ }
+ }
+ memset(buff, 0x0, sizeof(buff));
+ }
+ fclose(fp);
+
+ return 0;
+}
+
+
+void revision_out_find(char *data, int len, unsigned int processed_cnt)
+{
+ if(!revision_out_found) {
+ if(processed_cnt + len > REVISION_OUT_ADDR) { // µ½´ï 0x1000
+ char *start = NULL;
+ if(strlen(revision_out) > 0) {
+ start = data;
+ } else {
+ start = data + REVISION_OUT_ADDR - processed_cnt;
+ }
+
+ if(data[len - 1] == '\0') { // Last char is '\0',get the complete version.
+ if(strlen(start) > 0) {
+ memcpy(revision_out + strlen(revision_out), start, strlen(start));
+ }
+ revision_out_found = TRUE;
+ OTA_DEBUG("Found complete version : %s", revision_out);
+ } else {
+ memcpy(revision_out + strlen(revision_out), start, data + len - start);
+ OTA_DEBUG("Found version : %s", revision_out);
+ }
+ }
+ }
+}
+
+int revision_out_update()
+{
+ if(strlen(revision_out) == 0) {
+ OTA_ERR("revision_out not set.");
+ revision_out_found = FALSE;
+ return -1;
+ }
+
+ partition_info_t info;
+ memset(&info, 0x0, sizeof(partition_info_t));
+ if(partition_get("device_info", &info)) {
+ OTA_ERR("partition_get() fail.");
+ return -1;
+ }
+
+ OTA_DEBUG("device_info name : %s, dev : %s, addr : %08x, size : %08x, erase_size : %08x", info.name,
+ info.dev, info.partition_start, info.partition_size, info.erase_size);
+
+ if(info.erase_size <= 0 || info.partition_size <= 0) {
+ OTA_ERR("partition info error.");
+ return -1;
+ }
+
+#if 0
+ int fd = open(dev, O_RDWR);
+ if (fd < 0) {
+ OTA_ERR("Fatal error: can't open device_info %s\n", dev);
+ return -1;
+ }
+
+ mbtk_device_info_header_t info_header;
+ memset(&info_header, 0x0, sizeof(mbtk_device_info_header_t));
+ int len = read(fd, &info_header, sizeof(mbtk_device_info_header_t));
+ if (len != sizeof(mbtk_device_info_header_t)) {
+ OTA_ERR("Fatal error: read %d bytes(expect %d)\n", len, sizeof(mbtk_device_info_header_t));
+ goto fail;
+ }
+
+ if(info_header.tag != MBTK_DEVICE_INFO_PARTITION_TAG) {
+ OTA_ERR("TAG error : %08x", info_header.tag);
+ goto fail;
+ }
+
+ if(info_header.version != MBTK_DEVICE_INFO_CURR_VERSION) {
+ OTA_ERR("Version error : %d", info_header.version);
+ goto fail;
+ }
+
+ if(info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr == 0) {
+ OTA_ERR("No found item : %d", MBTK_DEVICE_INFO_ITEM_BASIC);
+ goto fail;
+ }
+
+ lseek(fd, info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr, SEEK_SET);
+ mbtk_device_info_basic_t info_basic;
+ memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
+ if (read(fd, &info_basic, sizeof(mbtk_device_info_basic_t)) != sizeof(mbtk_device_info_basic_t)) {
+ OTA_ERR("Read fail:%d", errno);
+ goto fail;
+ }
+
+ memset(info_basic.revision_out, 0, sizeof(info_basic.revision_out));
+ memcpy(info_basic.revision_out, revision_out, strlen(revision_out));
+
+ lseek(fd, info_header.item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr, SEEK_SET);
+ if (write(fd, &info_basic, sizeof(mbtk_device_info_basic_t)) != sizeof(mbtk_device_info_basic_t)) {
+ OTA_ERR("Write fail:%d", errno);
+ goto fail;
+ }
+#else
+ int fd = open(info.dev, O_RDWR);
+ if (fd < 0) {
+ OTA_ERR("Fatal error: can't open device_info %s\n", info.dev);
+ return -1;
+ }
+
+ char *mtd_buff = (char*)malloc(info.erase_size);
+ if(mtd_buff == NULL) {
+ OTA_ERR("malloc() failed\n");
+ return -1;
+ }
+ memset(mtd_buff, 0, info.erase_size);
+ int len = read(fd, mtd_buff, info.erase_size);
+ if (len != info.erase_size) {
+ OTA_ERR("Fatal error: read %d[%d] bytes(expect %d)\n", len, errno, info.erase_size);
+ goto fail;
+ }
+
+ struct erase_info_user mtdEraseInfo;
+ if (lseek(fd, 0, SEEK_SET) < 0)
+ {
+ OTA_ERR("seek failed\n");
+ return -1;
+ }
+
+ mtdEraseInfo.length = info.partition_size;
+ mtdEraseInfo.start = 0;
+ ioctl(fd, MEMUNLOCK, &mtdEraseInfo);
+ ioctl(fd, MEMERASE, &mtdEraseInfo);
+
+ mbtk_device_info_header_t *info_header = (mbtk_device_info_header_t*)mtd_buff;
+ mbtk_device_info_basic_t *info_basic = (mbtk_device_info_basic_t*)(mtd_buff + info_header->item_header[MBTK_DEVICE_INFO_ITEM_BASIC].addr);
+ OTA_DEBUG("Old version : %s", info_basic->revision_out);
+ memset(info_basic->revision_out, 0, sizeof(info_basic->revision_out));
+ memcpy(info_basic->revision_out, revision_out, strlen(revision_out));
+
+ lseek(fd, 0, SEEK_SET);
+ if (write(fd, mtd_buff, info.erase_size) != info.erase_size) {
+ OTA_ERR("Write fail:%d", errno);
+ goto fail;
+ }
+
+ if(mtd_buff) {
+ free(mtd_buff);
+ }
+
+#endif
+
+ close(fd);
+
+ OTA_DEBUG("Set revision_out : %s", revision_out);
+
+ memset(revision_out, 0x0, sizeof(revision_out));
+ revision_out_found = FALSE;
+
+ return 0;
+
+fail:
+ close(fd);
+ return -1;
+}