Add mbtk_reboot

Change-Id: I16682b505016b15c9f69819bd100da7e7fd75ae4
diff --git a/mbtk/include/mbtk/mbtk_device.h b/mbtk/include/mbtk/mbtk_device.h
index f25a7e6..fcf9846 100755
--- a/mbtk/include/mbtk/mbtk_device.h
+++ b/mbtk/include/mbtk/mbtk_device.h
@@ -8,12 +8,14 @@
 */
 #ifndef _MBTK_DEVICE_H
 #define _MBTK_DEVICE_H
-#include "mbtk_type.h"
+//#include "mbtk_type.h"
 
 #define MBTK_DEVICE_INFO_PARTITION_NAME "device_info"
 #define MBTK_DEVICE_INFO_PARTITION_TAG 0x87878787
 #define MBTK_DEVICE_INFO_CURR_VERSION 1
 
+#define MBTK_DEV_INFO_PARTITION_ADDR 0x02A20000
+
 // 78,147,482,134742231
 #define MBTK_BAND_ALL_GSM_DEFAULT 78             // GSM : ASR default.
 #define MBTK_BAND_ALL_WCDMA_DEFAULT 147          // WCDMA : ASR default.
@@ -27,6 +29,10 @@
 #define MBTK_BAND_EU_WCDMA_DEFAULT 145          // WCDMA : B1/B5/B8
 #define MBTK_BAND_EU_TDLTE_DEFAULT 416          // TDD-LTE : B38/B40/B41
 #define MBTK_BAND_EU_FDDLTE_DEFAULT 134742229   // FDD-LTE : B1/B3/B5/B7/B8/B20/B28
+#define MBTK_BAND_SA_GSM_DEFAULT 79             // GSM : B2/B3/B5/B8(GSM 850/PGSM 900/EGSM 900/DCS GSM 1800/PCS GSM 1900)
+#define MBTK_BAND_SA_WCDMA_DEFAULT 155          // WCDMA : B1/B2/B4/B5/B8
+#define MBTK_BAND_SA_TDLTE_DEFAULT 128          // TDD-LTE : B40
+#define MBTK_BAND_SA_FDDLTE_DEFAULT 134217951  // FDD-LTE : B1/B2/B3/B4/B5/B7/B8/B28/B66
 
 #define MBTK_DEVICE_INFO_ITEM_STR_BASIC "BASIC"
 #define MBTK_DEVICE_INFO_ITEM_STR_FOTA "FOTA"
@@ -54,12 +60,18 @@
     mbtk_device_info_item_header_t item_header[MBTK_DEVICE_INFO_ITEM_NUM];
 } mbtk_device_info_header_t;
 
+typedef enum {
+    MBTK_REBOOT_FLAG_NORMAL = 0,
+    MBTK_REBOOT_FLAG_DOWNLOAD
+} mbtk_device_info_reboot_flag_enum;
+
 typedef struct {
     uint8 name[16];
     uint32 version;             // Default : 0x01
     uint8 project[16];          // T108 / L508_X6
     uint8 project_cust[16];     // T108_C1 / L508_X6_C1  (Refer to: Custom_Model in blf file.)
     uint32 ab_support;          // 1 for ab
+    mbtk_device_info_reboot_flag_enum reboot_flag;
     uint8 revision_out[48];     // L508_X6v01.01b04.00
     uint8 revision_in[64];
 } mbtk_device_info_basic_t;
@@ -73,7 +85,8 @@
 typedef enum {
     MBTK_MODEM_BAND_AREA_ALL,
     MBTK_MODEM_BAND_AREA_CN,
-    MBTK_MODEM_BAND_AREA_EU
+    MBTK_MODEM_BAND_AREA_EU,
+    MBTK_MODEM_BAND_AREA_SA
 } mbtk_modem_band_area_enum;
 
 typedef struct {
@@ -84,6 +97,7 @@
     uint32 band_wcdma;
     uint32 band_tdlte;
     uint32 band_fddlte;
+    uint32 band_lte_ext;
 } mbtk_device_info_modem_t;
 
 typedef struct {
@@ -100,5 +114,6 @@
 * MBTK_DEVICE_INFO_ITEM_LOG - mbtk_device_info_log_t
 */
 int mbtk_dev_info_read(mbtk_device_info_item_enum item_type, void *item_ptr, int item_size);
+int mbtk_dev_info_write(mbtk_device_info_item_enum item_type, void *item_ptr, int item_size);
 
 #endif /* _MBTK_DEVICE_H */
diff --git a/mbtk/include/mbtk/mbtk_mtd.h b/mbtk/include/mbtk/mbtk_mtd.h
index c6fe59b..b2935b9 100755
--- a/mbtk/include/mbtk/mbtk_mtd.h
+++ b/mbtk/include/mbtk/mbtk_mtd.h
@@ -17,10 +17,12 @@
     char dev[16];
     uint32 partition_start;
     uint32 partition_size;
+    uint32 erase_size;
 
     bool used;
 } mbtk_partition_info_t;
 
 mbtk_partition_info_t* mbtk_partition_get();
+int mbtk_partition_get_by_name(char *partition_name, mbtk_partition_info_t *info);
 
 #endif /* _MBTK_MTD_H */
diff --git a/mbtk/libmbtk_lib/src/mbtk_device_info.c b/mbtk/libmbtk_lib/src/mbtk_device_info.c
index 4aa87dc..31d9523 100755
--- a/mbtk/libmbtk_lib/src/mbtk_device_info.c
+++ b/mbtk/libmbtk_lib/src/mbtk_device_info.c
@@ -20,7 +20,10 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <sys/ioctl.h>
+#include <mtd/mtd-user.h>
 
+#include "mbtk_type.h"
 #include "mbtk_device.h"
 #include "mbtk_log.h"
 #include "mbtk_str.h"
@@ -143,3 +146,117 @@
     return -1;
 }
 
+int mbtk_dev_info_write(mbtk_device_info_item_enum item_type, void *item_ptr, int item_size)
+{
+    if(item_ptr == NULL) {
+        LOGE("ARG error.");
+        return -1;
+    }
+
+    switch(item_type) {
+        case MBTK_DEVICE_INFO_ITEM_BASIC:
+        {
+            if(item_size != sizeof(mbtk_device_info_basic_t)) {
+                LOGE("item_size != sizeof(mbtk_device_info_basic_t)\n\r");
+                return -1;
+            }
+            break;
+        }
+        case MBTK_DEVICE_INFO_ITEM_FOTA:
+        {
+            if(item_size != sizeof(mbtk_device_info_fota_t)) {
+                LOGE("item_size != sizeof(mbtk_device_info_fota_t)\n\r");
+                return -1;
+            }
+            break;
+        }
+        case MBTK_DEVICE_INFO_ITEM_MODEM:
+        {
+            if(item_size != sizeof(mbtk_device_info_modem_t)) {
+                LOGE("item_size != sizeof(mbtk_device_info_modem_t)\n\r");
+                return -1;
+            }
+            break;
+        }
+        case MBTK_DEVICE_INFO_ITEM_LOG:
+        {
+            if(item_size != sizeof(mbtk_device_info_log_t)) {
+                LOGE("item_size != sizeof(mbtk_device_info_log_t)\n\r");
+                return -1;
+            }
+            break;
+        }
+        default:
+        {
+            LOGE("Item type[%d] error.\n\r", item_type);
+            return -1;
+        }
+    }
+
+    mbtk_partition_info_t info;
+    memset(&info, 0x0, sizeof(mbtk_partition_info_t));
+    if(mbtk_partition_get_by_name("device_info", &info)) {
+        LOGE("mbtk_partition_get_by_name() fail.");
+        return -1;
+    }
+
+    LOGD("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) {
+        LOGE("partition info error.");
+        return -1;
+    }
+
+    int fd = open(info.dev, O_RDWR);
+    if (fd < 0) {
+        LOGE("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) {
+        LOGE("malloc() failed\n");
+		return -1;
+    }
+    memset(mtd_buff, 0xFF, info.erase_size);
+    int len = read(fd, mtd_buff, info.erase_size);
+    if (len != info.erase_size) {
+        LOGE("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)
+	{
+		LOGE("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;
+    memcpy(mtd_buff + info_header->item_header[item_type].addr, item_ptr, item_size);
+
+    lseek(fd, 0, SEEK_SET);
+    if (write(fd, mtd_buff, info.erase_size) != info.erase_size) {
+        LOGE("Write fail:%d", errno);
+        goto fail;
+    }
+
+    if(mtd_buff) {
+        free(mtd_buff);
+    }
+
+    close(fd);
+    return 0;
+
+fail:
+    close(fd);
+    return -1;
+}
+
+
diff --git a/mbtk/libmbtk_lib/src/mbtk_mtd.c b/mbtk/libmbtk_lib/src/mbtk_mtd.c
index 4f1c2be..6129bc1 100755
--- a/mbtk/libmbtk_lib/src/mbtk_mtd.c
+++ b/mbtk/libmbtk_lib/src/mbtk_mtd.c
@@ -42,12 +42,14 @@
     int index = 0;
     char size_str[16];
     char name[32];
+    char erase_size_str[16];
     memset(buff, 0x0, 64);
     while(fgets(buff, 64, fp)) {
         if(str_startwith(buff, "mtd")) {
             memset(size_str, 0x0, 16);
+            memset(erase_size_str, 0x0, sizeof(erase_size_str));
             memset(name, 0x0, 32);
-            if(3 == sscanf(buff, "%s %s %*s %s", partition_list[index].dev, size_str, name)) {
+            if(4 == sscanf(buff, "%s %s %s %s", partition_list[index].dev, size_str, erase_size_str, name)) {
                 if(name[0] == '\"' && name[strlen(name) - 1] == '\"') {
                     memcpy(partition_list[index].name, name + 1, strlen(name) - 2); // No copy ""
                 } else {
@@ -60,6 +62,7 @@
                 }
 
                 partition_list[index].partition_size = (uint32)strtoul(size_str, NULL, 16);
+                partition_list[index].erase_size = (uint32)strtoul(erase_size_str, NULL, 16);
                 if(index > 0) {
                     partition_list[index].partition_start = partition_list[index - 1].partition_start + partition_list[index - 1].partition_size;
                 }
@@ -87,4 +90,51 @@
     return partition_list;
 }
 
+int mbtk_partition_get_by_name(char *partition_name, mbtk_partition_info_t *info)
+{
+    FILE *fp = fopen("/proc/mtd", "r");
+    if(fp == NULL) {
+        LOGE("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 {
+                    LOGE("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 {
+                LOGE("sscanf(%s) fail:%d", buff, errno);
+                return -1;
+            }
+        }
+        memset(buff, 0x0, sizeof(buff));
+    }
+    fclose(fp);
+
+    return 0;
+}
+
 
diff --git a/mbtk/mbtk_rild/src/mbtk_info_server.c b/mbtk/mbtk_rild/src/mbtk_info_server.c
old mode 100644
new mode 100755
index d6b4d44..435fb62
--- a/mbtk/mbtk_rild/src/mbtk_info_server.c
+++ b/mbtk/mbtk_rild/src/mbtk_info_server.c
@@ -31,6 +31,7 @@
     uint32 band_wcdma;
     uint32 band_tdlte;
     uint32 band_fddlte;
+    uint32 band_lte_ext;
 } band_set_info_t;
 
 static int sock_listen_fd = -1;
@@ -6359,6 +6360,8 @@
                     property_set("persist.mbtk.band_config", "CN");
                 } else if(band_set_info.band_area == MBTK_MODEM_BAND_AREA_EU) {
                     property_set("persist.mbtk.band_config", "EU");
+                } else if(band_set_info.band_area == MBTK_MODEM_BAND_AREA_SA) {
+                    property_set("persist.mbtk.band_config", "SA");
                 } else {
                     property_set("persist.mbtk.band_config", "ALL");
                 }
@@ -6667,12 +6670,14 @@
         band_set_info.band_wcdma = MBTK_BAND_ALL_WCDMA_DEFAULT;
         band_set_info.band_tdlte = MBTK_BAND_ALL_TDLTE_DEFAULT;
         band_set_info.band_fddlte = MBTK_BAND_ALL_FDDLTE_DEFAULT;
+        band_set_info.band_lte_ext = 0;
     } else {
         band_set_info.band_area = info_modem.band_area;
         band_set_info.band_gsm = info_modem.band_gsm;
         band_set_info.band_wcdma = info_modem.band_wcdma;
         band_set_info.band_tdlte = info_modem.band_tdlte;
         band_set_info.band_fddlte = info_modem.band_fddlte;
+        band_set_info.band_lte_ext = info_modem.band_lte_ext;
     }
 
     bool is_first = TRUE;
diff --git a/mbtk/mbtk_utils/device_info.c b/mbtk/mbtk_utils/device_info.c
index 3dd9b2a..0993c06 100755
--- a/mbtk/mbtk_utils/device_info.c
+++ b/mbtk/mbtk_utils/device_info.c
@@ -1,3 +1,4 @@
+#include "mbtk_type.h"
 #include "mbtk_device.h"
 
 static char* band_2_str(mbtk_modem_band_area_enum band_area)
@@ -35,6 +36,7 @@
     printf("Revision_Out:%s\n", info_basic.revision_out);
     printf("Revision_In:%s\n", info_basic.revision_in);
     printf("AB System:%s\n", info_basic.ab_support ? "Yes" : "No");
+    printf("Reboot flag:%d\n", info_basic.reboot_flag);
 
     mbtk_device_info_modem_t info_modem;
     memset(&info_modem, 0, sizeof(mbtk_device_info_modem_t));
diff --git a/mbtk/mbtk_utils/mbtk_reboot.c b/mbtk/mbtk_utils/mbtk_reboot.c
new file mode 100755
index 0000000..3263d73
--- /dev/null
+++ b/mbtk/mbtk_utils/mbtk_reboot.c
@@ -0,0 +1,57 @@
+#include "mbtk_type.h"
+#include "mbtk_device.h"
+
+static char* band_2_str(mbtk_modem_band_area_enum band_area)
+{
+    switch(band_area)
+    {
+        case MBTK_MODEM_BAND_AREA_CN:
+            return "CN";
+        case MBTK_MODEM_BAND_AREA_EU:
+            return "EU";
+        default:
+            return "ALL";
+    }
+}
+
+static void help()
+{
+    printf("mbtk_reboot [download]\n");
+}
+
+int main(int argc, char *argv[])
+{
+    if(argc == 1) {
+        system("reboot -f");
+    } else if(argc == 2) {
+        if(strcmp(argv[1], "download")) {
+            help();
+            return 0;
+        }
+    } else {
+        help();
+        return 0;
+    }
+
+    mbtk_device_info_basic_t info_basic;
+    memset(&info_basic, 0, sizeof(mbtk_device_info_basic_t));
+    int result = mbtk_dev_info_read(MBTK_DEVICE_INFO_ITEM_BASIC, &info_basic, sizeof(mbtk_device_info_basic_t));
+    if(result) {
+        printf("mbtk_dev_info_read(BASIC) fail.\n");
+        return -1;
+    }
+
+    info_basic.reboot_flag = MBTK_REBOOT_FLAG_DOWNLOAD;
+    result = mbtk_dev_info_write(MBTK_DEVICE_INFO_ITEM_BASIC, &info_basic, sizeof(mbtk_device_info_basic_t));
+    if(result) {
+        printf("mbtk_dev_info_write(BASIC) fail.\n");
+        return -1;
+    }
+
+    system("sync");
+    system("reboot -f");
+
+    return 0;
+}
+
+
diff --git a/mbtk/mbtk_utils_linux/device_info_generate.c b/mbtk/mbtk_utils_linux/device_info_generate.c
index 5be2289..0102031 100755
--- a/mbtk/mbtk_utils_linux/device_info_generate.c
+++ b/mbtk/mbtk_utils_linux/device_info_generate.c
@@ -7,6 +7,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 
+#include "mbtk_type.h"
 #include "mbtk_device.h"
 
 static mbtk_device_info_header_t info_header = {
@@ -27,6 +28,7 @@
     .project = {0},
     .project_cust = {0},
     .ab_support = 1,            // Default for ab system.
+    .reboot_flag = MBTK_REBOOT_FLAG_NORMAL,
     .revision_out = {0},
     .revision_in = {0}
 };
@@ -44,7 +46,8 @@
     .band_gsm = MBTK_BAND_ALL_GSM_DEFAULT,
     .band_wcdma = MBTK_BAND_ALL_WCDMA_DEFAULT,
     .band_tdlte = MBTK_BAND_ALL_TDLTE_DEFAULT,
-    .band_fddlte = MBTK_BAND_ALL_FDDLTE_DEFAULT
+    .band_fddlte = MBTK_BAND_ALL_FDDLTE_DEFAULT,
+    .band_lte_ext = 0
 };
 
 static mbtk_device_info_log_t item_log = {
@@ -115,7 +118,7 @@
 
 /*
 *
-* device_info_generate -a [a/ab] -b [revision_out] -c [revision_in] -d [project] -e [project_cust] -f [cn/eu/all] -o [out_bin]
+* device_info_generate -a [a/ab] -b [revision_out] -c [revision_in] -d [project] -e [project_cust] -f [cn/eu/sa/all] -o [out_bin]
 *
 */
 int main(int argc, char *argv[])
@@ -164,6 +167,12 @@
                     item_modem.band_wcdma = MBTK_BAND_EU_WCDMA_DEFAULT;
                     item_modem.band_tdlte = MBTK_BAND_EU_TDLTE_DEFAULT;
                     item_modem.band_fddlte = MBTK_BAND_EU_FDDLTE_DEFAULT;
+                } else if(strcmp(optarg, "sa") == 0) {
+                    item_modem.band_area = MBTK_MODEM_BAND_AREA_SA;
+                    item_modem.band_gsm = MBTK_BAND_SA_GSM_DEFAULT;
+                    item_modem.band_wcdma = MBTK_BAND_SA_WCDMA_DEFAULT;
+                    item_modem.band_tdlte = MBTK_BAND_SA_TDLTE_DEFAULT;
+                    item_modem.band_fddlte = MBTK_BAND_SA_FDDLTE_DEFAULT;
                 } else {
                     item_modem.band_area = MBTK_MODEM_BAND_AREA_ALL;
                     item_modem.band_gsm = MBTK_BAND_ALL_GSM_DEFAULT;
diff --git a/mbtk/mbtk_utils_linux/ota_update.c b/mbtk/mbtk_utils_linux/ota_update.c
index 50ef62a..d064e1b 100755
--- a/mbtk/mbtk_utils_linux/ota_update.c
+++ b/mbtk/mbtk_utils_linux/ota_update.c
@@ -6,7 +6,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-
+#include "mbtk_type.h"
 #include "mbtk_device.h"
 
 /*