[Feature][ZXW-33]merge ZXW 0428 version
Change-Id: I11f167edfea428d9fab198ff00ff1364932d1b0b
diff --git a/ap/hostapp/zdownloader/main.c b/ap/hostapp/zdownloader/main.c
new file mode 100755
index 0000000..a56e732
--- /dev/null
+++ b/ap/hostapp/zdownloader/main.c
@@ -0,0 +1,509 @@
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <time.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h>
+#include "CSerial.h"
+#include "LogInfo.h"
+#include "download.h"
+#include "devUsb.h"
+
+/*******************************************************************************
+ * 宏定义 *
+ *******************************************************************************/
+// #define OPENLOG 1
+#define KEYCODELENGTH (16)
+#define IDENTIFYCODE 0xdf, 0xf1, 0x13, 0x63, 0x1a, 0x98, 0xcd, 0xa8, 0xa5, 0x19, 0x7c, 0x1b, 0x1a, 0xba, 0x9f, 0xd7
+
+#define TTY_USB0 ("ttyUSB0")
+#define TTY_USB1 ("ttyUSB1")
+#define TTY_USB2 ("ttyUSB2")
+#define TTY_USB3 ("ttyUSB3")
+
+#define PORT_STA_NO (0)
+#define PORT_STA_AT (7)
+#define PORT_STA_DL (3)
+#define PORT_STA_BUSY (12)
+
+#define MAX_PORT_PATH_LENGTH (32)
+#define MAX_CMD_LENGTH (64)
+#define MAX_CHECK_VERSION_TIMES (10)
+#define MAX_OPEN_DL_PORT_TIMES (50)
+
+static int g_atPortInfo[3] = {0x19d2, 0x0582, 4};
+static int g_dlPortInfo[3] = {0x19d2, 0x0256, 0};
+static int g_at_ttyId = -1;
+static int g_dl_ttyId = -1;
+
+/*******************************************************************************
+ * 内部函数声明 *
+ *******************************************************************************/
+// 模块掉电重启
+static void HardWareReset(int type);
+// 校验传入参数的相应bin文件是否合法
+static int FileAnalyse(const char* path);
+// 判断AT命令是否返回相应的子串
+static int ChekATBackString(const char *atstring, const char *findversion);
+// 进入下载流程
+static enERRORCODE OpenDownloadPortAndDownload(const char *softwarepath, const char *RebackString);
+// 参数选项介绍
+static int usage(const char *exe);
+
+/*******************************************************************************
+ * 内部函数定义 *
+ *******************************************************************************/
+ /** Modem(模块)掉电重启
+ * @brief
+ * @param type 入参,重启类型,0:通过AT命令重启,1:DL口reboot重启
+ * @return
+ * @retval
+ * @note
+ * @warning
+ */
+#if 0
+void HardWareReset()
+{ /*
+ system("echo 1 > /sys/class/gpio_sw/PH12/data"); //模块下电
+ usleep(1*1000*1000); //delay
+ system("echo 0 > /sys/class/gpio_sw/PH12/data"); //模块上电
+ */
+ char * AT= "at\r\n";
+ ChekATBackString(AT,"OK");
+ char * AT_SoftwareReset = "at+zsoftreset\r\n";
+ ChekATBackString(AT_SoftwareReset,"OK");//reset
+
+}
+#endif
+static void HardWareReset(int type)
+{
+ char cversion[1024] = {0};
+ char dev_tty[MAX_PORT_PATH_LENGTH] = {0};
+ char AT_Reset[MAX_CMD_LENGTH] = "\r\nat+zsoftreset\r\n";
+ char cmdDevReboot[MAX_CMD_LENGTH] = "echo reboot > /dev/ttyUSB";
+
+ snprintf(dev_tty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_at_ttyId);
+ snprintf(cmdDevReboot, MAX_CMD_LENGTH, "echo reboot > /dev/ttyUSB%d", g_dl_ttyId);
+
+ if (type == 0)
+ {
+ SendATString(dev_tty, AT_Reset, cversion);
+ }
+ else
+ {
+ printf("HardWareReset(1):: %s \r\n", cmdDevReboot);
+ system(cmdDevReboot);
+ }
+}
+
+/**
+ * @brief 校验传入参数的相应bin文件是否合法
+ * @param path 入参,要下载的bin文件路径
+ * @return 成功返回 TRUE,失败返回 FALSE
+ * @retval
+ * @note
+ * @warning
+ */
+static BOOL FileAnalyse(const char* path)
+{
+ FILE *pf;
+ unsigned char keycode[KEYCODELENGTH] = {0};
+ int i = 0;
+ unsigned char standardkeycod[] =
+ {
+ IDENTIFYCODE};
+ if (access(path, F_OK) != 0)
+ {
+ LogInfo("software file path is not exist.");
+ return FALSE;
+ }
+ pf = fopen(path, "rb");
+ if (NULL == pf)
+ {
+ LogInfo("open %s error:%s", path, strerror(errno));
+ return FALSE;
+ }
+
+ int num = fread(keycode, sizeof(char), KEYCODELENGTH, pf);
+ if (KEYCODELENGTH != num)
+ {
+ LogInfo("read %s error", path);
+ return FALSE;
+ }
+
+ for (i = 0; i < KEYCODELENGTH; i++)
+ {
+ if (keycode[i] != standardkeycod[i])
+ {
+ fclose(pf);
+ pf = NULL;
+ return FALSE;
+ }
+ }
+ fclose(pf);
+ pf = NULL;
+ return TRUE;
+}
+
+/**
+ * @brief 判断AT命令是否返回相应的子串
+ * @param AtString 入参,发送的AT命令字符串
+ * @param findversion 入参,要比较的子串
+ * @return 成功返回0,失败返回-1
+ * @retval
+ * @note
+ * @warning
+ */
+static int ChekATBackString(const char *atstring, const char *findversion)
+{
+ char dev_tty[MAX_PORT_PATH_LENGTH] = {0};
+ char cversion[1024] = {0};
+
+ snprintf(dev_tty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_at_ttyId);
+
+ SendATString(dev_tty, atstring, cversion);
+
+ if ((cversion != NULL) && (findversion != NULL))
+ {
+ LogInfo("AT send over , cversion = %s, findversion = %s", cversion, findversion);
+ }
+ else
+ {
+ LogInfo("AT send over , version ptr is error");
+ }
+
+ printf("AT actual return = %s\n", cversion);
+ printf("AT suppose to be = %s\n", findversion);
+
+ if (strstr(cversion, findversion))
+ {
+ return 0;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/**
+ * @brief 打开下载口并进行下载流程
+ * @param softwarepath 入参,要下载的bin文件路径
+ * @param RebackString 入参,要校验的bin文件版本号
+ * @return 返回 enERRORCODE 枚举值
+ * @retval
+ * @note
+ * @warning
+ */
+static enERRORCODE OpenDownloadPortAndDownload(const char *softwarepath, const char *RebackString)
+{
+ int ret;
+ // char *diagport = DL_PORT;
+ char dev_dltty[MAX_PORT_PATH_LENGTH] = {0};
+ char *AT_GetVersion = "at+cgmr\r\n";
+ char *AT_OpenDL = "at+zflag=\"BOOT\",0\r\n";
+ char *AT_CloseDL = "at+zflag=\"BOOT\",1\r\n";
+
+ char AtReturnValue[128] = {0};
+ int portState = 0;
+ BOOL SucFlag = FALSE;
+ int i = 0, z = 0;
+
+ printf("DL version = 1.0\n");
+ // 检查是否输入版本号
+ if(RebackString[0] != '\0')
+ {
+ printf("%s:: Bin version = %s\n", __FUNCTION__, RebackString);
+ LogInfo("Bin version = %s", RebackString);
+ }
+ else
+ {
+ printf("%s:: not check version\n", __FUNCTION__);
+ LogInfo("not check version");
+ }
+ // 查找AT口
+ ret = dev_get_device(g_atPortInfo);
+ if(ret == -1)
+ {
+ printf("%s:: get at info failed, please restart module!!!\n", __FUNCTION__);
+ LogInfo("get at info failed, please restart module!!!");
+ return Download_FIND_AT_FAIL;
+ }
+ else
+ {
+ g_at_ttyId = g_usb_dev;
+ printf("%s:: Find AT port.\n", __FUNCTION__);
+ }
+
+
+ int j = 0;
+ while (j < 3)
+ {
+ if (-1 == ChekATBackString(AT_OpenDL, "OK")) // open dl port ,at command
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: AT_OpenDL send fail!, times = %d\n", j + 1);
+ }
+ else
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: AT_OpenDL send ok!, times = %d\n", j + 1);
+ break;
+ }
+ j++;
+ usleep(500 * 1000); // delay
+
+ // if (j >= 3)
+ // {
+ // LogInfo("OpenDownloadPortAndDownloadfunc:: AT_OPENDLPORT FAIL");
+ // return Download_AT_OPENDLPORT_FAIL;
+ // }
+ }
+
+ // 重启,进入下载通道
+ printf("OpenDownloadPortAndDownloadfunc:: HardWare Reset 1, please wait\r\n");
+ HardWareReset(0);
+ usleep(4000 * 1000); // 延时等待DL口枚举
+ // 查找DL口
+ ret = dev_get_device(g_dlPortInfo);
+ if(ret == -1)
+ {
+ printf("get dl info failed\n");
+ return Download_OPENDLPORT_FAIL;
+ }
+ else
+ {
+ g_dl_ttyId = g_usb_dev;
+ snprintf(dev_dltty, MAX_PORT_PATH_LENGTH, "/dev/ttyUSB%d", g_dl_ttyId);
+ }
+
+ i = MAX_OPEN_DL_PORT_TIMES;
+ while (i > 0)
+ {
+ // usleep(200*1000);
+ if (-1 == (Open(dev_dltty)))
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: Diag open Failed, times = %d\r\n", MAX_OPEN_DL_PORT_TIMES - i + 1);
+ --i;
+ continue;
+ }
+ else
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: Diag open ok!\r\n");
+ break;
+ }
+ }
+ if (i <= 0)
+ {
+ LogInfo("OpenDownloadPortAndDownloadfunc:: OPEN DLPORT FAIL");
+ return Download_OPENDLPORT_FAIL;
+ }
+
+ // 进入下载TLoader和TBoot流程
+ if (!DoDownloadBootForDL(FALSE, softwarepath))
+ {
+ LogInfo("DoDownloadBootForDL FAIL...");
+ printf("DoDownloadBootForDL FAIL\r\n");
+ Close();
+ return Download_DOWNLOAD_IMAGE_FAIL;
+ }
+ LogInfo("DoDownloadBootForDL ok...");
+ printf("DoDownloadBootForDL ok\r\n");
+
+#if (ERASENVRW == 1)
+ if (!ExecuteEraseNVRW(softwarepath))
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: ExecuteEraseNVRW Fail\r\n");
+ Close();
+ return Download_DOWNLOAD_IMAGE_FAIL;
+ }
+ printf("OpenDownloadPortAndDownloadfunc:: ExecuteEraseNVRW ok.\r\n");
+#endif
+
+ // 进入下载版本文件流程
+ if (Download_OK != PrimaryDoDownload(softwarepath))
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload fail return value = %d\r\n", Download_DOWNLOAD_IMAGE_FAIL);
+ Close();
+ return Download_DOWNLOAD_IMAGE_FAIL;
+ }
+ printf("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload OK\r\n");
+ Close();
+ LogInfo("OpenDownloadPortAndDownloadfunc:: PrimaryDoDownload end");
+
+ // 重启,进行检查版本号流程
+ usleep(100 * 1000); // delay
+ printf("OpenDownloadPortAndDownloadfunc:: HardWare Reset 2, please wait\r\n");
+ HardWareReset(1);
+
+ // 检查是否输入版本号
+ if (RebackString[0] != '\0')
+ {
+ // 延时等待AT口枚举
+ usleep(15 * 1000 * 1000);
+ printf("OpenDownloadPortAndDownloadfunc:: Begin to check version after Downloader.\r\n");
+
+ i = MAX_CHECK_VERSION_TIMES;
+ while (i > 0)
+ {
+ if (-1 == ChekATBackString(AT_GetVersion, RebackString))
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: check version fail, %d!\r\n", MAX_CHECK_VERSION_TIMES - i + 1);
+ }
+ else
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: check version OK.\r\n");
+ break;
+ }
+ i--;
+ usleep(1 * 1000 * 1000); // delay
+ }
+
+ // 检查版本号
+ if (i <= 0)
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: Check version error!\r\n");
+ LogInfo("Check version error!");
+ return Download_CHECK_VERSION_FAIL;
+ }
+ }
+
+ return Download_OK;
+#if 0
+ i=5;
+ while(i > 0)
+ {
+ if(-1 == ChekATBackString(AT_CloseDL,"OK")) //close dl port ,at command
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: close dl port fail!\r\n");
+ //return Download_AT_CLOSE_DL_FAIL;
+ }
+ else
+ {
+ printf("OpenDownloadPortAndDownloadfunc:: close dl port OK.\r\n");
+ return Download_OK;
+ }
+ i--;
+ usleep(1000*1000);//delay
+ }
+ return Download_CLOSE_DL_FAIL;
+#endif
+}
+
+/**
+ * @brief 参数选项介绍
+ * @param exe 入参,应用名
+ * @return 成功返回0
+ * @retval
+ * @note
+ * @warning
+ */
+static int usage(const char *exe)
+{
+ printf("%s -p bin_path -c check_version\n", exe);
+ printf("-h, help\n");
+ printf("-p bin_file_path\n");
+ printf("-c check_version\n");
+ printf("-s save_log_path, default path is (%s)\n", DEFAULT_LOG_PATH);
+ return 0;
+}
+
+/*******************************************************************************
+ * 主函数 *
+ *******************************************************************************/
+int main(int argc, char *argv[])
+{
+ int ch;
+ int ret = -1;
+
+ enERRORCODE DownloadResultMain = Download_OK;
+ // remove(LOG_PATH);
+ char BinPath[FILE_PATH_LENGTH_MAX] = {0}; // BinFile Path
+ char BinVersion[FILE_PATH_LENGTH_MAX] = {0};
+ strncpy(g_log_path, DEFAULT_LOG_PATH, FOLDER_PATH_LENGTH_MAX - 1);
+
+ printf("main:: downloading ...\r\n");
+ LogInfo("Program Start1");
+ if (geteuid() != 0)
+ {
+ fprintf(stderr, "main:: This program must run as root!\n");
+ LogInfo("Program close");
+ DownloadResultMain = Download_NOT_ROOT;
+ LogInfo("return Download_NOT_ROOT");
+ return DownloadResultMain;
+ }
+
+ LogInfo("Program Start2");
+ if (argc == 1)
+ {
+ fprintf(stderr, "main:: The Parameter at least need 1 input, but now is %d, error!\n", argc-1);
+ DownloadResultMain = Download_ERROR_INPUT_ARGC;
+ usage(argv[0]);
+ LogInfo("return Download_ERROR_INPUT_ARGC");
+ return DownloadResultMain;
+ }
+
+ LogInfo("Program Start3");
+ while ((ch = getopt(argc, argv, "hp:c:s:")) != -1)
+ {
+ switch (ch)
+ {
+ case 'h':
+ ret = usage(argv[0]);
+ return ret;
+ case 'p':
+ strncpy(BinPath, optarg, FILE_PATH_LENGTH_MAX - 1);
+ printf("main:: -p, BinPath = %s\n", BinPath);
+ break;
+ case 'c':
+ strncpy(BinVersion, optarg, FILE_PATH_LENGTH_MAX - 1);
+ printf("main:: -c, BinVersion = %s\n", BinVersion);
+ break;
+ case 's':
+ strncpy(g_log_path, optarg, FOLDER_PATH_LENGTH_MAX - 1);
+ printf("main:: -s, g_log_path = %s\n", g_log_path);
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
+ }
+ if(BinPath[0] == '\0')
+ {
+ printf("main:: BinPath is NULL, please add -p bin_path\n");
+ LogInfo("BinPath is NULL, please add -p bin_path");
+ return Download_ERROR_INPUT_ARGC;
+ }
+ if(BinVersion[0] == '\0')
+ {
+ printf("main:: BinVersion is NULL, not check\n");
+ LogInfo("BinVersion is NULL, not check");
+ }
+
+ LogInfo("Program Start4");
+ if (!FileAnalyse(BinPath))
+ {
+ LogInfo("FileAnalyse Failed");
+ DownloadResultMain = Download_CHECK_BIN_FAIL;
+ LogInfo("return Download_CHECK_BIN_FAIL");
+ return DownloadResultMain;
+ }
+
+ LogInfo("Program Start5");
+ DownloadResultMain = OpenDownloadPortAndDownload(BinPath, BinVersion);
+ LogInfo("DownloadResultMain = %d", DownloadResultMain);
+
+ if (DownloadResultMain == Download_OK)
+ {
+ LogInfo("download success...................");
+ printf("main:: download success...................\n");
+ }
+ else
+ {
+ LogInfo("download fail...................");
+ printf("main:: download fail...................\n");
+ return DownloadResultMain;
+ }
+
+ return Download_OK;
+}
\ No newline at end of file