[Feature][ZXW-33]merge ZXW 0428 version
Change-Id: I11f167edfea428d9fab198ff00ff1364932d1b0b
diff --git a/ap/hostapp/zdownloader/CSerial.c b/ap/hostapp/zdownloader/CSerial.c
new file mode 100755
index 0000000..45f932f
--- /dev/null
+++ b/ap/hostapp/zdownloader/CSerial.c
@@ -0,0 +1,626 @@
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <sys/time.h>
+#include <string.h>
+#include <errno.h>
+#include "LogInfo.h"
+#include "CSerial.h"
+
+/*******************************************************************************
+ * 宏定义 *
+ *******************************************************************************/
+#define DEV_RSP_COUNT (1024)
+
+/*******************************************************************************
+ * 全局变量 *
+ *******************************************************************************/
+static int m_fd;
+static char rspBufex[DEV_RSP_COUNT] = {0};
+
+/*******************************************************************************
+ * 函数声明 *
+ *******************************************************************************/
+static ssize_t SendAT(const char *pData, size_t length);
+static ssize_t ReadAT(BYTE *pbyReadBuffer, size_t dwReadCount);
+
+
+/*******************************************************************************
+ * 内部函数 *
+ *******************************************************************************/
+/**
+ * @brief 发送AT命令
+ * @param pData 入参,AT命令写入缓冲区
+ * @param length 入参,AT命令长度
+ * @return 成功返回成功写入的字节数,失败返回-1
+ * @retval
+ * @note length不计算结尾\0
+ * @warning
+ */
+static ssize_t SendAT(const char *pData, size_t length)
+{
+ ssize_t dwBytesWritten = -1;
+ ssize_t writeCount = 0;
+ struct timeval timeout;
+ fd_set fds, temps;
+ int result = 0;
+
+ if (m_fd < 0)
+ {
+ return -1;
+ }
+ if (pData != NULL)
+ {
+ LogInfo("pData= (%s) length = %ld ", pData, length);
+ }
+
+ // gettimeofday(&end, NULL);
+ // gettimeofday(&begin, NULL);
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+ /* 超时不能在此设置!
+ 因为调用select后,结构体timeval的成员tv_sec和tv_usec的值将被替换为超时前剩余时间.
+ 调用select函数前,每次都需要初始化timeval结构体变量.
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0; */
+
+ while (1)
+ {
+ /* 将准备好的fd_set变量reads的内容复制到temps变量,因为调用select函数后,除了发生变化的fd对应位外,
+ 剩下的所有位都将初始化为0,为了记住初始值,必须经过这种复制过程。*/
+ temps = fds;
+ // 设置超时
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ // 调用select函数
+ result = select(m_fd + 1, NULL, &temps, NULL, &timeout);
+ if (result <= 0)
+ {
+ if (0 == result)
+ {
+ LogInfo("timeout");
+ }
+ else
+ {
+ LogInfo("select() error");
+ }
+ break;
+ // return -1;
+ }
+ else
+ {
+ // 判断m_fd是否可写,若可写,写入数据
+ if (FD_ISSET(m_fd, &temps))
+ {
+ dwBytesWritten = write(m_fd, pData + writeCount, length - writeCount);
+ LogInfo("pData= (%s) dwBytesWritten = %ld ", pData, dwBytesWritten);
+ if (dwBytesWritten > 0)
+ {
+ writeCount += dwBytesWritten;
+ if (writeCount >= length)
+ {
+ break;
+ }
+ }
+ if (dwBytesWritten < 0 && errno != EINTR)
+ {
+ printf("SendAT:: write error, dwBytesWritten = %ld, %s\r\n", dwBytesWritten, strerror(errno));
+ break;
+ }
+ }
+ }
+ }
+
+ if (dwBytesWritten > 0)
+ {
+ return dwBytesWritten;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+/**
+ * @brief 接收AT命令应答
+ * @param pbyReadBuffer 出参,应答读取缓冲区
+ * @param dwReadCount 入参,应答读取长度
+ * @return 成功返回成功写入的字节数,失败返回-1
+ * @retval
+ * @note
+ * @warning
+ */
+static ssize_t ReadAT(BYTE *pbyReadBuffer, size_t dwReadCount)
+{
+ ssize_t dwBytesRead = -1;
+ ssize_t readCount = 0;
+ int result;
+ fd_set fds, temps;
+ struct timeval timeout;
+
+ if (m_fd < 0)
+ {
+ return -1;
+ }
+ LogInfo("ReadAT start");
+
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ while (1)
+ {
+ temps = fds;
+ // 设置超时
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0;
+ // 调用select函数
+ result = select(m_fd + 1, &temps, NULL, NULL, &timeout);
+ if (result <= 0)
+ {
+ if (0 == result)
+ {
+ LogInfo("timeout");
+ }
+ else
+ {
+ LogInfo("select() error");
+ }
+ return -1;
+ }
+ else
+ {
+ // 判断m_fd是否可读,若可读,读取数据
+ if (FD_ISSET(m_fd, &temps))
+ {
+ dwBytesRead = read(m_fd, pbyReadBuffer + readCount, dwReadCount - readCount);
+ LogInfo("pData= (%s) dwBytesWritten = %ld ", pbyReadBuffer, dwBytesRead);
+ if (dwBytesRead > 0)
+ {
+ readCount += dwBytesRead;
+ if (readCount >= dwReadCount)
+ {
+ break;
+ }
+ }
+ if (dwBytesRead < 0 && errno != EINTR)
+ {
+ printf("ReadAT::read error, dwBytesRead = %ld, %s\r\n", dwBytesRead, strerror(errno));
+ break;
+ }
+ }
+ }
+ }
+
+ if (dwBytesRead > 0)
+ {
+ return dwBytesRead;
+ }
+ else
+ {
+ return -1;
+ }
+}
+
+
+/*******************************************************************************
+ * 外部函数 *
+ *******************************************************************************/
+/**
+ * @brief 打开设备文件,并设置波特率等参数
+ * @param portName 入参,端口名
+ * @return 成功返回0,失败返回-1
+ * @retval
+ * @note
+ * @warning
+ */
+int Open(const char *portName)
+{
+ // char portname_full[20] = "/dev/";
+ // strcat(portname_full, portName);
+ // portName = +portName ;
+
+ struct termios attr;
+ int flags;
+
+ if (portName != NULL)
+ {
+ LogInfo("portname = (%s)", portName);
+ }
+ m_fd = open(portName, O_RDWR | O_NONBLOCK | O_NOCTTY | O_TRUNC);
+ if (m_fd < 0)
+ {
+ LogInfo("Open m_fd < 0 m_fd = %d\n", m_fd);
+ return -1;
+ }
+ else
+ {
+ LogInfo("Open m_fd > 0 m_fd = %d\n", m_fd);
+ }
+ tcflush(m_fd, TCIOFLUSH); // clear serial data
+ if (tcgetattr(m_fd, &attr) < 0)
+ {
+ close(m_fd);
+ return -1;
+ }
+ attr.c_iflag = IXON | IXOFF;
+ attr.c_oflag = 0;
+ attr.c_cflag &= ~(CSIZE | CFLAGS_TO_CLEAR | CFLAGS_HARDFLOW);
+ attr.c_cflag |= (CS8 | CFLAGS_TO_SET);
+ attr.c_cflag |= CFLAGS_HARDFLOW;
+ attr.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ISIG);
+ attr.c_lflag &= ~OPOST;
+ int i;
+#ifdef _POSIX_VDISABLE
+ attr.c_cc[0] = _POSIX_VDISABLE;
+#else
+ attr.c_cc[0] = fpathconf(m_fd, _PC_VDISABLE);
+#endif
+
+ for (i = 1; i < NCCS; i++)
+ {
+ attr.c_cc[i] = attr.c_cc[0];
+ }
+
+ attr.c_cc[VMIN] = 0;
+ attr.c_cc[VTIME] = 5;
+ cfsetispeed(&attr, BAUDRATE);
+ cfsetospeed(&attr, BAUDRATE);
+ if (tcsetattr(m_fd, TCSANOW, &attr) < 0)
+ {
+ close(m_fd);
+ return -1;
+ }
+ flags = fcntl(m_fd, F_GETFL, 0);
+ if (flags < 0)
+ {
+ close(m_fd);
+ return -1;
+ }
+ if (fcntl(m_fd, F_SETFL, flags) < 0)
+ {
+ close(m_fd);
+ return -1;
+ }
+ // m_isOpen = true;
+ // StartRead();
+ return 0;
+}
+
+/**
+ * @brief 关闭设备文件
+ * @param 无
+ * @return 成功关闭返回0,否则返回-1
+ * @retval
+ * @note
+ * @warning
+ */
+int Close()
+{
+ tcflush(m_fd, TCIOFLUSH); // clear serial data
+ if (m_fd > 0)
+ {
+ // printf("close m_fd\n");
+ close(m_fd);
+ }
+ else
+ {
+ printf("%s:: close->else\n", __FUNCTION__);
+ return -1;
+ }
+ m_fd = 0;
+ return 0;
+}
+
+/**
+ * @brief 发送AT命令并读取返回值
+ * @param Dev_tty 入参,打开的AT口设备路径
+ * @param AtString 入参,发送的AT命令字符串
+ * @param RebackString 出参,AT命令返回的字符串
+ * @return 成功返回0,失败返回-1
+ * @retval
+ * @note
+ * @warning
+ */
+int SendATString(const char *Dev_tty, const char *AtString, char *RebackString)
+{
+ BYTE tmp[1024] = {0};
+
+ printf("%s:: Before Open port, (%s)\n", __FUNCTION__, Dev_tty);
+ if (-1 == (Open(Dev_tty)))
+ {
+ if (AtString != NULL)
+ {
+ LogInfo("SendATString Failed AtString = (%s)", AtString);
+ }
+ printf("%s:: Open port error\r\n", __FUNCTION__);
+ return -1;
+ }
+ if (AtString != NULL)
+ {
+ LogInfo("SendATString OK, AtString = (%s)", AtString);
+ }
+
+ LogInfo("Before SendAT");
+ if(SendAT(AtString, strlen(AtString)) < 0)
+ {
+ LogInfo("SendAT failed");
+ Close();
+ return -1;
+ }
+ LogInfo("After SendAT");
+
+ ReadAT(tmp, 1024);
+ LogInfo("out ReadAT");
+
+ memcpy(RebackString, tmp, 1024);
+ LogInfo("after memcpy");
+
+ Close();
+ return 0;
+}
+
+/**
+ * @brief 发送数据
+ * @param pbyWriteBuffer 入参,写入数据缓冲区
+ * @param dwWriteCount 入参,写入数据长度
+ * @param dwSleepAfterAction 入参,
+ * @param dwTimeoutCount 入参,超时时间,单位秒
+ * @return 成功返回TRUE,失败返回FALSE
+ * @retval
+ * @note
+ * @warning
+ */
+BOOL SendData(const BYTE *pbyWriteBuffer, size_t dwWriteCount, DWORD dwSleepAfterAction, DWORD dwTimeoutCount)
+{
+ ssize_t sBytesWritten = -1;
+ ssize_t writeCount = 0;
+ struct timeval timeout;
+ fd_set fds, temps;
+ int result = 0;
+ // int count = 0; // 超时计数
+
+ LogInfo("writecount %d, timeout %d s", dwWriteCount, dwTimeoutCount);
+ if (m_fd < 0)
+ {
+ LogInfo("m_fd < 0");
+ return FALSE;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ tcflush(m_fd, TCIOFLUSH); // clear serial data
+
+ if (dwTimeoutCount < 10)
+ {
+ dwTimeoutCount = 10;
+ }
+ /* 超时不能在此设置!
+ 因为调用select后,结构体timeval的成员tv_sec和tv_usec的值将被替换为超时前剩余时间.
+ 调用select函数前,每次都需要初始化timeval结构体变量.
+ timeout.tv_sec = 1;
+ timeout.tv_usec = 0; */
+
+ while (1)
+ {
+ /*将准备好的fd_set变量reads的内容复制到temps变量,因为调用select函数后,除了发生变化的fd对应位外,
+ 剩下的所有位都将初始化为0,为了记住初始值,必须经过这种复制过程。*/
+ temps = fds;
+ // 设置超时
+ timeout.tv_sec = dwTimeoutCount;
+ timeout.tv_usec = 0;
+ // 调用select函数
+ result = select(m_fd + 1, NULL, &temps, NULL, &timeout);
+ LogInfo("select result = %d ", result);
+ if (-1 == result)
+ {
+ LogInfo("select() error\n");
+ perror("SendData:: select() error\n");
+ break;
+ }
+ else if (0 == result)
+ {
+ puts("SendData:: timeout\r\n");
+ break;
+ }
+ else
+ {
+ // 判断m_fd是否可写,若可写,写入数据
+ if (FD_ISSET(m_fd, &temps))
+ {
+ sBytesWritten = write(m_fd, (char *)pbyWriteBuffer + writeCount, dwWriteCount - writeCount);
+ LogInfo("pbyWriteBuffer= (%s) dwBytesWritten = %ld ", pbyWriteBuffer, sBytesWritten);
+ if (sBytesWritten > 0)
+ {
+ writeCount += sBytesWritten;
+ if (writeCount >= dwWriteCount)
+ {
+ return TRUE; // complete success
+ }
+ }
+ else
+ {
+ if (sBytesWritten < 0 && errno != EINTR)
+ {
+ printf("SendData::write error, dwBytesWritten = %ld, %s\r\n", sBytesWritten, strerror(errno));
+ }
+ return FALSE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * @brief 接收数据
+ * @param pbyReadBuffer 入参,读取数据缓冲区
+ * @param dwReadCount 入参,读取数据长度
+ * @param dwSleepAfterAction 入参,
+ * @param dwTimeoutCount 入参,超时时间,单位秒
+ * @return 成功返回TRUE,失败返回FALSE
+ * @retval
+ * @note
+ * @warning
+ */
+BOOL ReadData(BYTE *pbyReadBuffer, size_t dwReadCount, DWORD dwSleepAfterAction, DWORD dwTimeoutCount)
+{
+ ssize_t sBytesReadn = -1;
+ ssize_t readCount = 0;
+ int result;
+ fd_set fds, temps;
+ struct timeval timeout;
+ // int readCount = 0;
+ // int count = 0; // 超时计数
+
+ LogInfo("ReadData reacount %d, timeout %d s\n", dwReadCount, dwTimeoutCount);
+ if (m_fd < 0)
+ {
+ LogInfo("m_fd < 0");
+ return -1;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ if (dwTimeoutCount < 10)
+ {
+ dwTimeoutCount = 10;
+ }
+
+ while (1)
+ {
+ temps = fds;
+ timeout.tv_sec = dwTimeoutCount;
+ timeout.tv_usec = 0;
+
+ result = select(m_fd + 1, &temps, NULL, NULL, &timeout);
+ LogInfo("select result = %d ", result);
+ if (-1 == result)
+ {
+ LogInfo("select() error\n");
+ perror("ReadData:: select() error\n");
+ break;
+ }
+ else if (0 == result)
+ {
+ puts("ReadData:: timeout\n");
+ break;
+ }
+ else
+ {
+ // 判断m_fd是否可读,若可读,读取数据
+ if (FD_ISSET(m_fd, &temps))
+ {
+ sBytesReadn = read(m_fd, pbyReadBuffer + readCount, dwReadCount - readCount);
+ LogInfo("pbyReadBuffer= (%s) sBytesReadn = %ld ", pbyReadBuffer, sBytesReadn);
+ if (sBytesReadn > 0)
+ {
+ readCount += sBytesReadn;
+ if (readCount >= dwReadCount)
+ {
+ return TRUE; // complete success
+ }
+ }
+ else
+ {
+ if (sBytesReadn < 0 && errno != EINTR)
+ {
+ printf("ReadData::read error, sBytesReadn = %ld, %s\r\n", sBytesReadn, strerror(errno));
+ }
+ return FALSE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * @brief 接收数据缓冲
+ * @param dwReadCount 入参,读取数据长度
+ * @param dwSleepAfterAction 入参,
+ * @param dwTimeoutCount 入参,超时时间,单位秒
+ * @return 成功返回读取的数据指针,失败返回NULL
+ * @retval
+ * @note
+ * @warning
+ */
+BYTE *ReadDataExtraFuncB(DWORD dwReadCount, DWORD dwSleepAfterAction, DWORD dwTimeoutCount)
+{
+ ssize_t sBytesReadn = -1;
+ ssize_t readCount = 0;
+ int result;
+ fd_set fds, temps;
+ struct timeval timeout;
+
+ LogInfo("readcount %d, timeout %d s", dwReadCount, dwTimeoutCount);
+
+ memset(rspBufex, 0, DEV_RSP_COUNT);
+
+ if (m_fd < 0)
+ {
+ LogInfo("m_fd < 0");
+ return rspBufex;
+ }
+
+ FD_ZERO(&fds);
+ FD_SET(m_fd, &fds);
+
+ if (dwTimeoutCount < 10)
+ {
+ dwTimeoutCount = 10;
+ }
+
+ while (1)
+ {
+ temps = fds;
+ timeout.tv_sec = dwTimeoutCount;
+ timeout.tv_usec = 0;
+
+ result = select(m_fd + 1, &fds, NULL, NULL, &timeout);
+ LogInfo("select result = %d ", result);
+ if (-1 == result)
+ {
+ LogInfo("select() error\n");
+ perror("ReadDataExtraFuncB:: select() error\n");
+ break;
+ }
+ else if (0 == result)
+ {
+ puts("ReadDataExtraFuncB:: timeout\n");
+ break;
+ }
+ else
+ {
+ // 判断m_fd是否可读,若可读,读取数据
+ if (FD_ISSET(m_fd, &temps))
+ {
+ sBytesReadn = read(m_fd, rspBufex + readCount, DEV_RSP_COUNT - readCount);
+ LogInfo("pbyReadBuffer= (%s) sBytesReadn = %ld ", rspBufex, sBytesReadn);
+ if (sBytesReadn > 0)
+ {
+ readCount += sBytesReadn;
+ printf("ReadDataExtraFuncB:: readCount = %ld, dwReadCount = %d \r\n", readCount, dwReadCount);
+ if (readCount >= dwReadCount)
+ {
+ break; // complete success
+ }
+ }
+ else
+ {
+ if (sBytesReadn < 0 && errno != EINTR)
+ {
+ printf("ReadData::read error, sBytesReadn = %ld, %s\r\n", sBytesReadn, strerror(errno));
+ }
+ break;
+ }
+ }
+ }
+ }
+ LogInfo("rspBufex = (%s)", rspBufex);
+
+ return rspBufex;
+}
diff --git a/ap/hostapp/zdownloader/CSerial.h b/ap/hostapp/zdownloader/CSerial.h
new file mode 100755
index 0000000..67e67fe
--- /dev/null
+++ b/ap/hostapp/zdownloader/CSerial.h
@@ -0,0 +1,20 @@
+#ifndef CSERIAL_H_INCLUDED
+#define CSERIAL_H_INCLUDED
+
+#include "define.h"
+
+#define BAUDRATE B115200
+#define READLENGTH 1024
+#define CFLAGS_TO_SET (CREAD | HUPCL)
+#define CFLAGS_TO_CLEAR (CSTOPB | PARENB | CLOCAL)
+#define CFLAGS_HARDFLOW (CRTSCTS)
+
+int Open(const char *portName);
+int Close();
+/* send AT cmd, and return */
+int SendATString(const char *Dev_tty, const char *AtString, char *RebackString);
+BOOL SendData(const BYTE *pbyWriteBuffer, size_t dwWriteCount, DWORD dwSleepAfterAction, DWORD dwTimeoutCount);
+BOOL ReadData(BYTE *pbyWriteBuffer, size_t dwWriteCount, DWORD dwSleepAfterAction, DWORD dwTimeoutCount);
+BYTE *ReadDataExtraFuncB(DWORD dwReadCount, DWORD dwSleepAfterAction,DWORD dwTimeoutCount);
+
+#endif // CSERIAL_H_INCLUDED
diff --git "a/ap/hostapp/zdownloader/Linux\345\271\263\345\217\260zdownloader\345\212\237\350\203\275\344\275\277\347\224\250\344\273\213\347\273\215.pdf" "b/ap/hostapp/zdownloader/Linux\345\271\263\345\217\260zdownloader\345\212\237\350\203\275\344\275\277\347\224\250\344\273\213\347\273\215.pdf"
new file mode 100755
index 0000000..d61147d
--- /dev/null
+++ "b/ap/hostapp/zdownloader/Linux\345\271\263\345\217\260zdownloader\345\212\237\350\203\275\344\275\277\347\224\250\344\273\213\347\273\215.pdf"
Binary files differ
diff --git a/ap/hostapp/zdownloader/LogInfo.c b/ap/hostapp/zdownloader/LogInfo.c
new file mode 100755
index 0000000..4a6d6db
--- /dev/null
+++ b/ap/hostapp/zdownloader/LogInfo.c
@@ -0,0 +1,55 @@
+#include <stdio.h>
+#include <time.h>
+#include <stdarg.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+
+#include "LogInfo.h"
+#include "define.h"
+
+#define LOG_ENTRY_SIZE (BUFSIZ * 8)
+
+static int s_log_flag = 0;
+static char s_file_name[FILE_NAME_LENGTH_MAX] = {0};
+// char g_log_path[FOLDER_PATH_LENGTH_MAX] = LOG_PATH;
+
+/* 保存Log信息到文件 */
+void DownLoad_LogInfo(const int line, const char *fn,
+ const char *func_name, const char *fmt, ...)
+{
+
+ char log_fn[FILE_PATH_LENGTH_MAX] = {0};
+ struct timeval t;
+ FILE *fp_log = NULL;
+
+ gettimeofday(&t, NULL);
+ struct tm *p = localtime(&t.tv_sec);
+
+ if(s_log_flag == 0)
+ {
+ strftime(s_file_name, FILE_NAME_LENGTH_MAX, "%Y-%m-%d_%H%M%S", p);
+ s_log_flag = 1;
+ }
+ snprintf(log_fn, FILE_PATH_LENGTH_MAX, "%s/downloader_%s.log", g_log_path, s_file_name);
+ fp_log = fopen(log_fn, "a+");
+
+ va_list arglist;
+ static char buffer[LOG_ENTRY_SIZE] = ("");
+ static char tmp[LOG_ENTRY_SIZE] = ("");
+
+ va_start(arglist, fmt);
+ vsnprintf(tmp, LOG_ENTRY_SIZE, fmt, arglist);
+ va_end(arglist);
+ sprintf(buffer, "[%d-%d-%d %d:%d:%d.%ld] <%s>: #%d @ %s\n \t %s\n",
+ (1900 + p->tm_year), (1 + p->tm_mon), p->tm_mday,
+ p->tm_hour, p->tm_min, p->tm_sec, t.tv_usec,
+ func_name,
+ line, fn, tmp);
+
+ if (NULL != fp_log)
+ {
+ fprintf(fp_log, ("%s"), buffer);
+ fclose(fp_log);
+ }
+}
diff --git a/ap/hostapp/zdownloader/LogInfo.h b/ap/hostapp/zdownloader/LogInfo.h
new file mode 100755
index 0000000..f0103b2
--- /dev/null
+++ b/ap/hostapp/zdownloader/LogInfo.h
@@ -0,0 +1,16 @@
+#ifndef _DOWNLOADER_LOGINFO_H_
+#define _DOWNLOADER_LOGINFO_H_
+
+#define LOGBOTTON (1)
+#define DEFAULT_LOG_PATH ("/tmp")
+
+void DownLoad_LogInfo(const int line, const char *fn,
+ const char *func_name, const char *fmt, ...);
+
+#if (LOGBOTTON==1)
+#define LogInfo(fmt, ...) DownLoad_LogInfo(__LINE__, __FILE__, __FUNCTION__, fmt, ##__VA_ARGS__)
+#else
+#define LogInfo(fmt, ...)
+#endif
+
+#endif
\ No newline at end of file
diff --git a/ap/hostapp/zdownloader/Makefile b/ap/hostapp/zdownloader/Makefile
new file mode 100755
index 0000000..ccea03e
--- /dev/null
+++ b/ap/hostapp/zdownloader/Makefile
@@ -0,0 +1,19 @@
+
+CC=gcc -g
+RM = rm
+INCLUDES += -I./
+CFLAGS += $(INCLUDES)
+OBJS = main.o CSerial.o LogInfo.o download.o devUsb.o
+LIBS += #-lpthread
+TARGET = zdownloader
+
+all:$(TARGET)
+$(TARGET):$(OBJS) $(LIBS)
+ $(CC) $(OBJS) $(LIBS) -o $@
+
+%o:%cpp
+ $(CC) -c $(CFLAGS) $(LIBS) $< -o $@
+
+clean:
+ -$(RM) *.o $(TARGET)
+
diff --git a/ap/hostapp/zdownloader/define.h b/ap/hostapp/zdownloader/define.h
new file mode 100755
index 0000000..cda42d4
--- /dev/null
+++ b/ap/hostapp/zdownloader/define.h
@@ -0,0 +1,34 @@
+#ifndef _DEFINE_H_
+#define _DEFINE_H_
+
+#define FALSE (0)
+#define TRUE (1)
+
+#define FOLDER_PATH_LENGTH_MAX (256)
+#define FILE_NAME_LENGTH_MAX (128)
+#define FILE_PATH_LENGTH_MAX (512)
+
+typedef unsigned char BYTE;
+typedef unsigned int DWORD;
+typedef unsigned long ULONG;
+typedef int BOOL;
+typedef unsigned short WORD;
+typedef enum
+{
+ Download_OK = 0,//下载成功
+ Download_NOT_ROOT,//非root权限执行下载应用
+ Download_ERROR_INPUT_ARGC,//参数错误,比如没有带参数执行下载应用
+ Download_CHECK_BIN_FAIL,//校验传入参数的bin文件是否合法
+ Download_FIND_AT_FAIL,//找不到AT口
+ Download_SAME_VERSION_NONEED_DL,//下载前读取软件版本,如果相同则不下载,此功能视用户需求可有可无,但是枚举值保留
+ Download_AT_OPEN_DL_FAIL,//下载前发AT指令打开DL下载端口失败,此功能视用户需求可有可无,但是枚举值保留
+ Download_OPENDLPORT_FAIL,//打开下载端口失败,openport失败
+ Download_DOWNLOAD_IMAGE_FAIL,//下载版本文件失败
+ Download_CHECK_VERSION_FAIL,//下载完成后,校验版本失败,此功能视用户需求可有可无,但是枚举值保留
+ Download_AT_CLOSE_DL_FAIL,
+ Download_NONE//未定义
+}enERRORCODE;
+
+char g_log_path[FOLDER_PATH_LENGTH_MAX];
+
+#endif
diff --git a/ap/hostapp/zdownloader/devUsb.c b/ap/hostapp/zdownloader/devUsb.c
new file mode 100755
index 0000000..e48075e
--- /dev/null
+++ b/ap/hostapp/zdownloader/devUsb.c
@@ -0,0 +1,183 @@
+/*******************************************************************************
+* 版权所有 (C)2016, 中兴通讯股份有限公司。
+*
+* 文件名称: usb_dev.c
+* 文件标识: usb_dev.c
+* 内容摘要: usb设备访问工具
+*
+* 修改日期 版本号 修改标记 修改人 修改内容
+* ------------------------------------------------------------------------------
+* 2016/3/10 V1.0 Create 创建
+*
+*******************************************************************************/
+
+/*******************************************************************************
+* 头文件 *
+*******************************************************************************/
+#include<stdlib.h>
+#include<stdio.h>
+#include<string.h>
+#include<sys/types.h>
+#include<sys/stat.h>
+#include<fcntl.h>
+#include<errno.h>
+#include<getopt.h>
+#include<stdarg.h>
+#include<termios.h>
+#include<stddef.h>
+#include<dirent.h>
+#include <unistd.h>
+
+#include "devUsb.h"
+
+/*******************************************************************************
+* 宏定义 *
+*******************************************************************************/
+#define USB_DIR_FILE_NAME_SIZE (512)
+#define USB_DIR_BASE ("/sys/bus/usb/devices")
+#define SUCCESS (0)
+#define FAIL (-1)
+
+/*******************************************************************************
+* 变量定义 *
+*******************************************************************************/
+
+/*******************************************************************************
+* 数据类型定义 *
+*******************************************************************************/
+
+/*******************************************************************************
+* 函数声明 *
+*******************************************************************************/
+static int dev_get_usbsys_val(const char *sys_filename, int base);
+static int dev_strStartsWith(const char *line, const char *src);
+static int dev_get_ttyport_by_syspath(char *syspath);
+
+/*******************************************************************************
+* 局部静态变量声明 *
+*******************************************************************************/
+static char sys_filename[USB_DIR_FILE_NAME_SIZE] = {0};
+
+/*******************************************************************************
+* 全局变量定义 *
+*******************************************************************************/
+int g_usb_dev = -1;
+
+/*******************************************************************************
+* 局部函数实现 *
+*******************************************************************************/
+static int dev_get_usbsys_val(const char *sys_filename, int base)
+{
+ char buff[64] = {0};
+ int ret_val = -1;
+ int fd = -1;
+
+ fd = open(sys_filename, O_RDONLY);
+ if (fd < 0) {
+ // printf("failed to open usbsys, error is %s\n", strerror(errno));
+ return FAIL;
+ }
+
+ if (read(fd, buff, sizeof(buff)) <= 0) {
+ printf("[%s] read:%s failed\n", __func__, sys_filename);
+ }
+ else {
+ ret_val = strtoul(buff, NULL, base);
+ }
+ close(fd);
+
+ return ret_val;
+}
+
+static int dev_strStartsWith(const char *line, const char *src)
+{
+ int ret = -1;
+
+ for ( ; *line != '\0' && *src != '\0'; line++, src++) {
+ if (*line != *src) {
+ return FAIL;
+ }
+ }
+ ret = atoi(line);
+ return ret;
+}
+
+static int dev_get_ttyport_by_syspath(char *syspath)
+{
+ DIR *usbdir = NULL;
+ struct dirent *dent = NULL;
+ int usb_port = -1;
+
+ usbdir = opendir(syspath);
+ if (usbdir == NULL) {
+ printf("%s: open [%s] busdir failed\n", __func__, syspath);
+ return FAIL;
+ }
+
+ while ((dent = readdir(usbdir)) != NULL)
+ {
+ usb_port = dev_strStartsWith(dent->d_name, "ttyUSB");
+ if ( usb_port >= 0) {
+ closedir(usbdir);
+ usbdir = NULL;
+ return usb_port;
+ }
+ }
+
+ if (usbdir) {
+ closedir(usbdir);
+ usbdir = NULL;
+ }
+ return FAIL;
+}
+
+int dev_get_device(int *pPortInfo)
+{
+ DIR *usbdir = NULL;
+ struct dirent *dent = NULL;
+ int idVendor = 0, idProduct = 0;
+ int bConfigurationValue = 0;
+ int num = 0;
+ usbdir = opendir(USB_DIR_BASE);
+ if (usbdir == NULL)
+ return -1;
+
+ while ((dent = readdir(usbdir)) != NULL){
+ if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) {
+ continue;
+ }
+
+ snprintf(sys_filename, sizeof(sys_filename), "%s/%s/idVendor", USB_DIR_BASE, dent->d_name);
+ if ((idVendor = dev_get_usbsys_val(sys_filename, 16)) <= 0) {
+ continue;
+ }
+
+ snprintf(sys_filename, sizeof(sys_filename), "%s/%s/idProduct", USB_DIR_BASE, dent->d_name);
+ if ((idProduct = dev_get_usbsys_val(sys_filename, 16)) <= 0) {
+ continue;
+ }
+
+ snprintf(sys_filename, sizeof(sys_filename), "%s/%s/bConfigurationValue", USB_DIR_BASE, dent->d_name);
+ if ((bConfigurationValue = dev_get_usbsys_val(sys_filename, 10)) <= 0) {
+ continue;
+ }
+
+ if (idVendor == pPortInfo[0] && idProduct == pPortInfo[1]){
+ snprintf(sys_filename, sizeof(sys_filename), "%s/%s/%s:%d.%d", USB_DIR_BASE, dent->d_name, dent->d_name, bConfigurationValue, pPortInfo[2]);
+ g_usb_dev = dev_get_ttyport_by_syspath(sys_filename);
+ printf("port found: /dev/ttyUSB%d -- %s\n", g_usb_dev, sys_filename);
+ closedir(usbdir);
+ usbdir = NULL;
+ return 0;
+ }
+ usleep(10000);
+ }
+ if (usbdir) {
+ closedir(usbdir);
+ usbdir = NULL;
+ }
+ printf("Can not find port.\n");
+
+ return -1;
+}
+
diff --git a/ap/hostapp/zdownloader/devUsb.h b/ap/hostapp/zdownloader/devUsb.h
new file mode 100755
index 0000000..8745a41
--- /dev/null
+++ b/ap/hostapp/zdownloader/devUsb.h
@@ -0,0 +1,8 @@
+#ifndef _DEV_USB_H_
+#define _DEV_USB_H_
+
+int g_usb_dev;
+
+int dev_get_device(int *pPortInfo);
+
+#endif
\ No newline at end of file
diff --git a/ap/hostapp/zdownloader/download.c b/ap/hostapp/zdownloader/download.c
new file mode 100755
index 0000000..500f89c
--- /dev/null
+++ b/ap/hostapp/zdownloader/download.c
@@ -0,0 +1,2053 @@
+
+#include <stdio.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+// #include <io.h>
+#include "LogInfo.h"
+#include "CSerial.h"
+#include "download.h"
+
+/*******************************************************************************
+ * 宏定义 *
+ *******************************************************************************/
+#define ERASENVRW (0)
+#define LOWORD(l) ((WORD)(l))
+#define MAXFILENUM (50)
+// 大小端转换
+#define ExchangeEndian(data) (data = ((data >> 24) & 0x000000FF) | ((data >> 8) & 0x0000FF00) | ((data << 8) & 0x00FF0000) | ((data << 24) & 0xFF000000))
+
+/*******************************************************************************
+ * 全局变量 *
+ *******************************************************************************/
+const stSTAT m_DownloadImageTable[] =
+ {
+ {STAT_TERMINATE, STAT_TERMINATE}, // 0
+ {STAT_TERMINATE, STAT_TERMINATE}, // 1
+ {STAT_TERMINATE, STAT_TERMINATE}, // 2
+ {STAT_TERMINATE, STAT_TERMINATE}, // 3
+ {STAT_TERMINATE, STAT_TERMINATE}, // 4
+ {STAT_EXECUTE_CODE, STAT_TERMINATE}, // 5
+ {STAT_ERASE_SEG_ST_ADDR, STAT_TERMINATE}, // 6
+ {STAT_TERMINATE, STAT_TERMINATE}, // 7
+ {STAT_TERMINATE, STAT_TERMINATE}, // 8
+ {STAT_PROG_DEV_END_ADDR, STAT_TERMINATE}, // 9
+ {STAT_SET_PACKET_SIZE, STAT_TERMINATE}, // 10
+ {STAT_DATAPACKET, STAT_TERMINATE}, // 11
+ {STAT_TERMINATE, STAT_TERMINATE}, // 12
+ {STAT_ERASE_SEG_END_ADDR, STAT_TERMINATE}, // 13
+ {STAT_PROG_DEV_ST_ADDR, STAT_TERMINATE}, // 14
+ {STAT_TERMINATE, STAT_TERMINATE}, // 15
+ {STAT_TERMINATE, STAT_TERMINATE}, // 16
+ {STAT_TERMINATE, STAT_TERMINATE} // 17
+};
+
+const stSTAT m_DownloadRAMImageTable[] =
+ {
+ {STAT_TERMINATE, STAT_TERMINATE}, // 0
+ {STAT_TERMINATE, STAT_TERMINATE}, // 1
+ {STAT_TERMINATE, STAT_TERMINATE}, // 2
+ {STAT_TERMINATE, STAT_TERMINATE}, // 3
+ {STAT_TERMINATE, STAT_TERMINATE}, // 4
+ {STAT_EXECUTE_CODE, STAT_TERMINATE}, // 5
+ {STAT_PROG_DEV_ST_ADDR, STAT_TERMINATE}, // 6
+ {STAT_TERMINATE, STAT_TERMINATE}, // 7
+ {STAT_TERMINATE, STAT_TERMINATE}, // 8
+ {STAT_PROG_DEV_END_ADDR, STAT_TERMINATE}, // 9
+ {STAT_SET_PACKET_SIZE, STAT_TERMINATE}, // 10
+ {STAT_DATAPACKET, STAT_TERMINATE}, // 11
+ {STAT_TERMINATE, STAT_TERMINATE}, // 12
+ {STAT_TERMINATE, STAT_TERMINATE}, // 13
+ {STAT_TERMINATE, STAT_TERMINATE}, // 14
+ {STAT_TERMINATE, STAT_TERMINATE}, // 15
+ {STAT_TERMINATE, STAT_TERMINATE}, // 16
+ {STAT_TERMINATE, STAT_TERMINATE} // 17
+};
+
+FILE *pf = NULL; // 版本文件FILE指针
+char g_path[FILE_PATH_LENGTH_MAX]; // 版本文件路径
+DWORD m_dwPartitionSize;
+DWORD m_dwBootStage1StartAddress; // Tloader起始地址
+DWORD m_dwBootStage1Size; // Tloader大小
+DWORD m_dwBootStage2StartAddress; // Tboot起始地址
+DWORD m_dwBootStage2Size; // Tboot大小
+DWORD m_iFileNum; // 文件总数
+BOOL m_StartAMT;
+BOOL m_StartAMT_MODEM;
+BOOL m_StartAMT_AP;
+BOOL m_bBackUpNV;
+BOOL m_bCRCCheck; // CRC校验标志位
+const stSTAT *m_pProtocolTable;
+stBinMasterInfo m_stMasterInfo; // 大BIN版本head结构
+stFileItem FileItem[MAXFILENUM]; // 用于存放image信息
+int g_DownLoadFileNum = 0; // 真正要下载的文件个数
+
+/*******************************************************************************
+ * 声明 *
+ *******************************************************************************/
+// 擦除NVRW
+static BOOL EraseNVRW();
+// 对下载文件进行解析
+static BOOL PreInitBoot();
+
+// 下载boot
+static BOOL DownloadOneBoot(DWORD dwBootStartAddress, DWORD dwBootSize, FILE *pBootFile, size_t dwPacketSize, DWORD dwOffset, BOOL SYNC);
+// 同步, 配置分区
+static BOOL DownloadPartition(size_t dwPartitionSize, FILE *pFile, DWORD dwPacketSize, DWORD dwOffset, BOOL bCheckPartition);
+// 释放boot资源
+static BOOL UnPreInitBoot();
+
+// 下载版本文件前初始化
+static BOOL Initialize();
+// 进行解析bin文件信息
+static BOOL FileAnalysis();
+// 获取版本文件信息接口
+static void GetFileList(BOOL bDownload, enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize, DWORD nIndex);
+// 解析大BIN文件信息总接口
+static void CollectDownloadImage(enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize);
+// 跳入下一个下载阶段
+static enSTAT GotoNextState(enSTAT enCurrentStat, BOOL bRet);
+// 下载文件
+static BOOL DownloadOneImage(stDownloadConfig CurrentConfig);
+// 下载文件接口
+static BOOL DownloadImage(stFileItem ImageInfo, BOOL bExecuteCode);
+// 下载文件总接口
+static BOOL ExchangeImage();
+// 下载版本文件后释放资源
+static BOOL UnInitialize();
+// 下载版本文件
+static BOOL DoDownload(enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize, BOOL bBackupNV, enDownloadNVBackupMethod Method, BOOL bEableCRCCheck);
+
+/*******************************************************************************
+ * 内部函数 *
+ *******************************************************************************/
+static BOOL EraseNVRW()
+{
+ BOOL bRet = FALSE;
+ BYTE *AckBuffer;
+ char buf[100];
+ LogInfo("start...");
+ BYTE *WriteBufferErase = (BYTE *)malloc(200);
+ memset(WriteBufferErase, 0, 200);
+ memcpy(WriteBufferErase, "erase nvrw", 10);
+
+ bRet = SendData(WriteBufferErase, 11, 10, 1);
+ usleep(1000 * 1000);
+ if (bRet)
+ {
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(4, 20, 30);
+ }
+ memset(buf, 0, 100);
+ if (AckBuffer == NULL)
+ {
+ LogInfo("AckBuffer is null...");
+ return bRet;
+ }
+ strcpy(buf, (char *)AckBuffer);
+ if (bRet && (!memcmp(buf, "OKAY", 5)))
+ {
+ LogInfo("Erase OK...");
+
+ usleep(100 * 1000); // 延时必须要加,否则下载文件失败
+
+ bRet = TRUE;
+ }
+ else
+ {
+ LogInfo("Erase FAIL...");
+ bRet = FALSE;
+ }
+ return bRet;
+}
+
+// 如果打不开待下载的代理文件,则失败
+static BOOL PreInitBoot()
+{
+ m_dwBootStage1StartAddress = 0x00082000;
+ m_dwBootStage2StartAddress = 0x21ef0000;
+ printf("PreInitBootfunc:: g_path=%s.\n", g_path);
+
+ if (access(g_path, 0) != 0)
+ {
+ printf("PreInitBootfunc:: software file path is error.\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+
+ if (pf == NULL)
+ {
+ LogInfo("Open file FAIL... %s", g_path);
+ return FALSE;
+ }
+ stBinMasterInfo MasterHead;
+ stFileItem FileItem;
+
+ int num = fread((BYTE *)&MasterHead, 1, sizeof(MasterHead), pf);
+ if (num == 0)
+ {
+ LogInfo("Read file FAIL... %s", g_path);
+ return FALSE;
+ }
+ m_iFileNum = MasterHead.nTotalFileNum;
+ m_stMasterInfo.nTotalFileNum = MasterHead.nTotalFileNum;
+
+ m_stMasterInfo.nFlashType = MasterHead.nFlashType;
+ m_stMasterInfo.nNVCoalition = MasterHead.nNVCoalition;
+ memcpy(m_stMasterInfo.chVersionIN, MasterHead.chVersionIN, sizeof(MasterHead.chVersionIN));
+ memcpy(m_stMasterInfo.chVersionOUT, MasterHead.chVersionOUT, sizeof(MasterHead.chVersionOUT));
+ m_stMasterInfo.iFileSize = MasterHead.iFileSize;
+ m_stMasterInfo.iImageStructOffset = MasterHead.iImageStructOffset;
+ m_stMasterInfo.PartitionLength = MasterHead.PartitionLength;
+ m_stMasterInfo.PartitionOffset = MasterHead.PartitionOffset;
+
+ m_stMasterInfo.tloaderLength = MasterHead.tloaderLength;
+ m_stMasterInfo.tloaderOffset = MasterHead.tloaderOffset;
+ m_stMasterInfo.tBootLength = MasterHead.tBootLength - 64;
+ m_stMasterInfo.tBootOffset = MasterHead.tBootOffset + 64;
+
+ m_dwBootStage2Size = m_stMasterInfo.tBootLength;
+ m_dwBootStage1Size = m_stMasterInfo.tloaderLength;
+ m_dwPartitionSize = m_stMasterInfo.PartitionLength;
+
+ LogInfo("PreInitBootfunc:: m_iFileNum = %d", m_iFileNum);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.nTotalFileNum = %d", m_stMasterInfo.nTotalFileNum);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.nFlashType = %d", m_stMasterInfo.nFlashType);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.nNVCoalition = %d", m_stMasterInfo.nNVCoalition);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.chVersionIN = %s", m_stMasterInfo.chVersionIN);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.chVersionOUT = %s", m_stMasterInfo.chVersionOUT);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.iFileSize = %d", m_stMasterInfo.iFileSize);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.iImageStructOffset = %d", m_stMasterInfo.iImageStructOffset);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.PartitionLength = %d", m_stMasterInfo.PartitionLength);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.PartitionOffset = %d", m_stMasterInfo.PartitionOffset);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.tloaderLength = %d", m_stMasterInfo.tloaderLength);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.tloaderOffset = %d", m_stMasterInfo.tloaderOffset);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.tBootLength = %d", m_stMasterInfo.tBootLength);
+ LogInfo("PreInitBootfunc:: m_stMasterInfo.tBootOffset = %d", m_stMasterInfo.tBootOffset);
+ LogInfo("PreInitBootfunc:: m_dwBootStage2Size = %d", m_dwBootStage2Size);
+ LogInfo("PreInitBootfunc:: m_dwBootStage1Size = %d", m_dwBootStage1Size);
+ LogInfo("PreInitBootfunc:: m_dwPartitionSize = %d", m_dwPartitionSize);
+
+ // 从tboot文件前面的64个字节中获取tboot下载和启动地址
+ unsigned char header[64] = {0};
+ fseek(pf, MasterHead.tBootOffset, 0);
+ if (fread(header, 1, sizeof(header), pf) != sizeof(header))
+ {
+ LogInfo("Read tboot FAIL...");
+ return FALSE;
+ }
+ // 获取TBoot下载地址
+ m_dwBootStage2StartAddress = (header[20] << 24) | (header[21] << 16) | (header[22] << 8) | (header[23]);
+ LogInfo("m_dwBootStage2StartAddress = 0x%x", m_dwBootStage2StartAddress);
+
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ }
+ return TRUE;
+}
+
+static BOOL DownloadOneBoot(DWORD dwBootStartAddress, DWORD dwBootSize, FILE *pBootFile, size_t dwPacketSize, DWORD dwOffset, BOOL SYNC)
+{
+ enSTAT State = STAT_SYNC;
+ BOOL bRet = FALSE;
+ BOOL bExit = FALSE;
+ DWORD dwCurrentSize = 0;
+ DWORD dwPacketCount = 0;
+
+ if (access(g_path, 0) != 0)
+ {
+ printf("DownloadOneBootfunc:: software file path is error.\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+ if (pf == NULL)
+ {
+ LogInfo("DownloadOneBootfunc:: PreInitBoot Open file FAIL... %s", g_path);
+ return FALSE;
+ }
+ if (SYNC == FALSE)
+ {
+ State = STAT_START_BYTE;
+ LogInfo("DownloadOneBootfunc:: not need STAT_SYNC 0X5A...");
+ }
+
+ LogInfo("DownloadOneBootfunc:: dwOffset = %d...dwPacketSize = %d", dwOffset, dwPacketSize);
+ while (!bExit)
+ {
+ switch (State)
+ {
+ //------------------------------同步---------------------------------
+ case STAT_SYNC:
+ {
+ BYTE nCommand = 0;
+ BYTE nAck = 0;
+
+ // PrintInfo(_T("开始同步DownloadOneBoot..."));
+ nCommand = CMD_SYNC_TBOOT;
+ bRet = SendData(&nCommand, 1, 10, 20);
+ if (bRet)
+ {
+ bRet = ReadData(&nAck, 1, 20, 20);
+ }
+
+ if (bRet && (CMD_SYNC_BYTE_ACK_BOOTROM == nAck))
+ {
+ // PrintInfo(_T("同步完毕!"));
+ LogInfo("DownloadOneBootfunc:: Send STAT_SYNC OK...");
+ State = STAT_START_BYTE;
+ }
+ else
+ {
+ // 同步失败后退出
+ // PrintInfo(_T("同步失败!"));
+ LogInfo("DownloadOneBootfunc:: Send STAT_SYNC FAIL...nAck = 0x%x", nAck);
+ bExit = TRUE;
+ bRet = FALSE;
+ }
+ }
+ break;
+
+ //-----------------------------设置寄存器---------------------------------
+ case STAT_START_BYTE:
+ {
+ State = STAT_NO_MODIFY_REG; // 不执行配置,直接进入下一个流程
+ }
+ break;
+
+ case STAT_NO_MODIFY_REG:
+ {
+ BYTE nCommand = CMD_SEND_DATA_BOOTROM;
+
+ // PrintInfo(_T("设置寄存器..."));
+ bRet = SendData(&nCommand, 1, 10, 1);
+ if (bRet)
+ {
+ // PrintInfo(_T("设置寄存器完毕!"));
+ LogInfo("DownloadOneBootfunc:: Send CMD_SEND_DATA_BOOTROM OK...");
+ State = STAT_ADDRESS;
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Send CMD_SEND_DATA_BOOTROM FAIL...");
+ State = STAT_TERMINATE;
+ }
+ }
+ break;
+
+ //------------------------------地址---------------------------------
+ case STAT_ADDRESS:
+ {
+ DWORD dwStartAddress = dwBootStartAddress;
+ // PrintInfo(_T("设置地址..."));
+ ExchangeEndian(dwStartAddress);
+ bRet = SendData((BYTE *)&dwStartAddress, sizeof(DWORD), 10, 1);
+ if (bRet)
+ {
+ // PrintInfo(_T("设置地址完毕!"));
+ LogInfo("DownloadOneBootfunc:: Send dwStartAddress OK...");
+ State = STAT_DATA_LEN;
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Send dwStartAddress FAIL...");
+ State = STAT_TERMINATE;
+ }
+ }
+ break;
+
+ //----------------------------数据长度-------------------------------
+ case STAT_DATA_LEN:
+ {
+ DWORD dwSize = dwBootSize;
+ BYTE nAck = 0;
+
+ // PrintInfo(_T("设置数据长度..."));
+ ExchangeEndian(dwSize);
+ bRet = SendData((BYTE *)&dwSize, sizeof(DWORD), 20, 1);
+ if (bRet)
+ {
+ bRet = ReadData(&nAck, 1, 20, 20);
+ if (bRet && (CMD_SEND_ADDRESS_LEN_ACK_BOOTROM == nAck))
+ {
+ LogInfo("DownloadOneBootfunc:: Set address and length OK...");
+ // printf("DownloadOneBootfunc:: Set address and length OK...\n");
+ // 判断Boot文件的状态
+ if (NULL == pf)
+ {
+ LogInfo("DownloadOneBootfunc:: pf not exsist...");
+ State = STAT_TERMINATE;
+ }
+ else
+ {
+ fseek(pf, dwOffset, 0);
+ dwCurrentSize = dwBootSize;
+ LogInfo("DownloadOneBootfunc:: dwOffset = %d, dwBootSize = %d", dwOffset, dwBootSize);
+ // PrintInfo(_T("开始发送Boot数据..."));
+ State = STAT_DATAPACKET;
+ LogInfo("DownloadOneBootfunc:: start send BootFile...");
+ }
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Get ADDRESS_LEN_ACK FAIL!bRet=%d, nAck=%d", bRet, nAck);
+ State = STAT_TERMINATE;
+ }
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Send dwBootSize FAIL...");
+ State = STAT_TERMINATE;
+ }
+ }
+ break;
+
+ //----------------------------boot数据---------------------------------
+ case STAT_DATAPACKET:
+ {
+ BYTE WriteBuffer[PACKET_SIZE_BOOT] = {0};
+ BYTE nAck = 0;
+ size_t dwSendSize = 0;
+
+ if (dwPacketSize > PACKET_SIZE_BOOT)
+ {
+ // PrintInfo(_T("数据包长度越界!"));
+ LogInfo("DownloadOneBootfunc:: dwPacketSize>PACKET_SIZE_BOOT too big...");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: dwPacketSize = %d PACKET_SIZE_BOOT = %d", dwPacketSize, PACKET_SIZE_BOOT);
+ }
+
+ memset(WriteBuffer, 0, sizeof(WriteBuffer));
+ if (dwCurrentSize >= dwPacketSize)
+ {
+ LogInfo("DownloadOneBootfunc:: dwCurrentSize >= dwPacketSize...");
+ if (fread(&WriteBuffer[0], 1, dwPacketSize, pf) != dwPacketSize) // pBootFile->Read(&WriteBuffer[0], dwPacketSize) != dwPacketSize)
+ {
+ // PrintInfo(_T("Boot文件读取失败!"));
+ LogInfo("DownloadOneBootfunc:: Read bootfile FAIL...");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ break;
+ }
+ LogInfo("DownloadOneBootfunc:: dwPacketSize = %d", dwPacketSize);
+ bRet = SendData(WriteBuffer, dwPacketSize, 10, 1);
+ LogInfo("DownloadOneBootfunc:: dwPacketCount = %d...bRet = %d", dwPacketCount, bRet);
+ if (bRet)
+ {
+ LogInfo("DownloadOneBootfunc:: send bootfile one packet OK...");
+ dwPacketCount++;
+ dwCurrentSize -= dwPacketSize;
+ if (0x00 == dwCurrentSize)
+ {
+ bRet = ReadData(&nAck, 1, 20, 20);
+ if (bRet && (CMD_SEND_DATA_ACK_BOOTROM == nAck))
+ {
+ State = STAT_EXECUTE_CODE; // 下载完成后,下一状态是执行代码 zxw 20121010
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Get send bootfile ACK FAIL!");
+ printf("DownloadOneBootfunc:: Get send bootfile ACK FAIL!\n");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ }
+ }
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: send bootfile one packet FAIL...");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ }
+ }
+ else if (dwCurrentSize > 0)
+ {
+ if ((dwCurrentSize % 512) == 0)
+ {
+ dwSendSize = dwCurrentSize - 8; // 512整包时,拆包
+ LogInfo("DownloadOneImagefunc:: STAT_DATAPACKET split packet");
+ // printf("DownloadOneImagefunc:: STAT_DATAPACKET split packet\n");
+ }
+ else
+ {
+ dwSendSize = dwCurrentSize;
+ usleep(2 * 1000); // 最后一包,等待一段时间
+ }
+
+ LogInfo("DownloadOneBootfunc:: dwCurrentSize > 0 but <packetsize...");
+ if (fread(&WriteBuffer[0], 1, dwSendSize, pf) != dwSendSize) // pBootFile->Read(&WriteBuffer[0], dwCurrentSize) != dwCurrentSize)
+ {
+ // PrintInfo(_T("Boot文件读取失败!"));
+ LogInfo("DownloadOneBootfunc:: Read bootfile FAIL...");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ break;
+ }
+ bRet = SendData(WriteBuffer, dwSendSize, 10, 1);
+ LogInfo("DownloadOneBootfunc:: dwPacketCount = %d...", dwPacketCount);
+ if (bRet)
+ {
+ dwPacketCount++;
+ dwCurrentSize -= dwSendSize;
+ if (dwCurrentSize == 0)
+ {
+ bRet = ReadData(&nAck, 1, 20, 20);
+ if (bRet && (CMD_SEND_DATA_ACK_BOOTROM == nAck))
+ {
+ State = STAT_EXECUTE_CODE; // 下载完成后,下一状态是执行代码 zxw 20121010
+ LogInfo("DownloadOneBootfunc:: send bootfile last packet OK...");
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Get send bootfile ACK FAIL!");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ }
+ }
+ }
+ else
+ {
+ // PrintInfo(_T("BOOT数据发送失败!"));
+ LogInfo("DownloadOneBootfunc:: send bootfile one packet FAIL...");
+ bRet = FALSE;
+ State = STAT_TERMINATE;
+ }
+ }
+ else
+ {
+ bRet = TRUE;
+ State = STAT_EXECUTE_CODE; // 下载完成后,下一状态是执行代码 zxw 20121010
+ }
+ }
+ break;
+ case STAT_EXECUTE_CODE:
+ {
+ unsigned char buf[5];
+ BYTE nAck = 0;
+ DWORD dwStartAddress = dwBootStartAddress;
+ buf[0] = CMD_STARTUP_BOOTROM;
+ ExchangeEndian(dwStartAddress);
+ memcpy(&buf[1], &dwStartAddress, sizeof(DWORD));
+ // PrintInfo(_T("开始启动BOOT..."));
+ bRet = SendData(buf, sizeof(buf), 10, 1);
+ if (bRet)
+ {
+ bRet = ReadData(&nAck, 1, 20, 20);
+ if (bRet && (CMD_STARTUP_ACK_BOOTROM == nAck))
+ {
+ // PrintInfo(_T("启动Boot完毕!"));
+ LogInfo("DownloadOneBootfunc:: start boot OK...");
+ State = STAT_TERMINATE;
+ bRet = TRUE;
+ }
+ else
+ {
+ LogInfo("DownloadOneBootfunc:: Get start boot ACK FAIL...");
+ State = STAT_TERMINATE;
+ bRet = FALSE;
+ }
+ }
+ else
+ {
+ // PrintInfo(_T("启动Boot失败!"));
+ LogInfo("DownloadOneBootfunc:: send boot start command FAIL...");
+ State = STAT_TERMINATE;
+ bRet = FALSE;
+ }
+ }
+ break;
+ default:
+ bExit = TRUE;
+ break;
+ }
+ }
+
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ }
+ return bRet;
+}
+
+static BOOL DownloadPartition(size_t dwPartitionSize, FILE *pFile, DWORD dwPacketSize, DWORD dwOffset, BOOL bCheckPartition)
+{
+ enParpSTAT State = STAT_SYNC_PARTIITON;
+ BOOL bRet = FALSE;
+ BOOL bExit = FALSE;
+
+ DWORD dwCurrentSize = 0;
+ DWORD dwPacketCount = 0;
+
+ BYTE *AckBuffer;
+ if (access(g_path, 0) != 0)
+ {
+ printf("DownloadPartitionfunc:: software file path is error.\r\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+ if (pf == NULL)
+ {
+ LogInfo("DownloadPartitionfunc:: Open file FAIL... %s", g_path);
+ return FALSE;
+ }
+
+ while (!bExit)
+ {
+ switch (State)
+ {
+ //------------------------------同步---------------------------------
+ case STAT_SYNC_PARTIITON:
+ {
+ BYTE nCommand = 0;
+ BYTE nAck = 0;
+
+ // PrintInfo(_T("开始同步DownloadPartition1..."));
+ LogInfo("DownloadPartitionfunc:: STAT_SYNC_PARTIITON DownloadPartition...");
+ nCommand = CMD_SYNC_TBOOT;
+ bRet = SendData(&nCommand, 1, 10, 1);
+ if (bRet)
+ {
+ bRet = ReadData(&nAck, 1, 10, 10);
+ }
+
+ if (bRet && (CMD_SYNC_ACK_TBOOT == nAck))
+ {
+ // PrintInfo(_T("同步完毕!"));
+ LogInfo("DownloadPartitionfunc:: STAT_SYNC_PARTIITON DownloadPartition OK...");
+ printf("DownloadPartitionfunc:: STAT_SYNC_PARTIITON DownloadPartition OK...\n");
+
+ State = STAT_SET_PARTITION_CMD;
+ }
+ else
+ {
+ // 空片下载的时候需要遍历flash生产坏块分区表需要一定的时间。
+ // PrintInfo(_T("同步失败!"));
+ LogInfo("DownloadPartitionfunc:: STAT_SYNC_PARTIITON DownloadPartition FAIL...");
+ State = STAT_SYNC_PARTIITON;
+ int count = 0;
+ count++;
+ if (count > 20)
+ {
+ State = STAT_EXIT;
+ bExit = TRUE;
+ bRet = FALSE;
+ }
+ }
+ usleep(10 * 1000);
+ }
+ break;
+
+ case STAT_SET_PARTITION_CMD:
+ {
+ BYTE CommandHead[] = "set partitions 1000\0";
+ BYTE CommandBuf[200] = {0};
+ BYTE bRead = 0;
+ BYTE ByteBuf[17] = {0};
+
+ // memset(CommandBuf,0,200);
+ // memset(AckBuffer,0,150);
+ memcpy(CommandBuf, CommandHead, sizeof(CommandHead));
+ // CommandBuf[sizeof(CommandHead)] = dwPartitionSize;
+
+ LogInfo("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD strlen((char*)CommandBuf)) = %d...", strlen((char *)CommandBuf));
+ bRet = SendData(CommandBuf, strlen((char *)CommandBuf) + 1, 10, 1);
+ if (bRet)
+ {
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(17, 10, 20);
+ }
+ if (AckBuffer != NULL)
+ {
+ LogInfo("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD AckBuffer = %s...", AckBuffer);
+ }
+ else
+ {
+ LogInfo("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD AckBuffer is NULL");
+ }
+
+ if (bRet && (!memcmp(AckBuffer, "OKAY RECV_TABLES", 16)))
+ {
+ // PrintInfo(_T("设置分区表命令成功!"));
+ LogInfo("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD set partitions OK...");
+ printf("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD set partitions OK...\n");
+
+ State = STAT_SEND_PARTIITON;
+ }
+ else
+ {
+ LogInfo("DownloadPartitionfunc:: STAT_SET_PARTITION_CMD set partitions FAIL...");
+ // PrintInfo(_T("设置分区表命令失败!"));
+ State = STAT_EXIT;
+
+ bExit = TRUE;
+ bRet = FALSE;
+ }
+ }
+ break;
+
+ case STAT_SEND_PARTIITON:
+ {
+ // memset(AckBuffer,0,150);
+ char *strfail1 = "FAIL INVALID_PARTITION_TABLE"; // 分区表自身内容不合法
+ char *strfail2 = "FAIL ACCEPTABLE_PARTITION_CHANGE"; // 分区表对比出错,但NV分区一致
+ char *strfail3 = "FAIL UNACCEPTABLE_PARTITION_CHANGE"; // 分区表对比出错,NV分区不一致
+ BYTE bRead = 0;
+
+ BYTE *WriteBuffer = (BYTE *)malloc(dwPartitionSize);
+ if (!WriteBuffer)
+ {
+ printf("DownloadPartitionfunc:: malloc WriteBuffer failed\n");
+ bRet = FALSE;
+ break;
+ }
+
+ fseek(pf, dwOffset, 0);
+ if (fread(WriteBuffer, 1, dwPartitionSize, pf) != dwPartitionSize)
+ {
+ // PrintInfo(_T("分区表文件读取失败!"));
+ LogInfo("DownloadPartitionfunc:: STAT_SEND_PARTIITON read partition data FAIL...");
+ if (WriteBuffer != NULL)
+ {
+ free(WriteBuffer);
+ WriteBuffer = NULL;
+ }
+ bRet = FALSE;
+ break;
+ }
+
+ int dlPTindex = 0;
+ int dlTime = dwPartitionSize / 1000;
+
+ printf("DownloadPartitionfunc:: STAT_SEND_PARTIITON start !\n");
+ for (dlPTindex = 0; dlPTindex < dlTime; dlPTindex++)
+ {
+ bRet = SendData(WriteBuffer + 1000 * dlPTindex, 1000, 10, 1);
+ printf("DownloadPartitionfunc:: STAT_SEND_PARTIITON dlPTindex = %d.\n", dlPTindex);
+ }
+ if (dwPartitionSize % 1000 != 0)
+ {
+ bRet = SendData(WriteBuffer + 1000 * dlTime, dwPartitionSize % 1000, 10, 1);
+ printf("DownloadPartitionfunc:: STAT_SEND_PARTIITON SendData\n");
+ }
+ if (bRet)
+ {
+ usleep(10 * 1000);
+ // bRet = ReadData(&bRead,1,50,20);
+ // bRet = ReadData(AckBuffer,strlen(strfail3)+1,50,20);
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(strlen(strfail3) + 1, 10, 5);
+ }
+ printf("DownloadPartitionfunc:: STAT_SEND_PARTIITON ReadDataExtraFuncB\n");
+
+ char buf[100];
+ memset(buf, 0, 100);
+ strcpy(buf, (char *)AckBuffer);
+
+ if (buf[0] == '\0')
+ {
+ LogInfo("DownloadPartitionfunc:: STAT_SEND_PARTIITON read error !");
+ bExit = TRUE;
+ bRet = FALSE;
+ State = STAT_EXIT;
+ break;
+ }
+ if (!memcmp(buf, "OKAY", 4))
+ {
+ // PrintInfo("分区文件下载成功!");
+ LogInfo("DownloadPartitionfunc:: STAT_SEND_PARTIITON send partition OK...");
+ printf("DownloadPartitionfunc:: STAT_SEND_PARTIITON send partition OK...\n");
+
+ State = STAT_EXIT;
+ bRet = TRUE;
+ break;
+ }
+ if (!memcmp(buf, strfail1, strlen(strfail1)))
+ {
+ // PrintInfo("生成的分区表有问题!");
+ LogInfo("DownloadPartitionfunc:: STAT_SEND_PARTIITON partition has some problem..");
+ bExit = TRUE;
+ bRet = FALSE;
+ State = STAT_EXIT;
+ break;
+ }
+ if (!memcmp(buf, strfail2, strlen(strfail2)))
+ {
+ // memset(AckBuffer,0,150);
+ // PrintInfo("分区表发生变化,需要擦除所有分区除了NV分区进行下载!");
+
+ LogInfo("DownloadPartitionfunc:: FAIL ACCEPTABLE_PARTITION_CHANGE...");
+ printf("DownloadPartitionfunc:: PARTITION_CHANGE...\n");
+
+ BYTE *WriteBufferErase = (BYTE *)malloc(200);
+
+ memset(WriteBufferErase, 0, 200);
+ memcpy(WriteBufferErase, "erase auto", 10);
+
+ bRet = SendData(WriteBufferErase, 11, 10, 1);
+ if (bRet)
+ {
+ bRet = ReadData(AckBuffer, 5, 20, 4 * 60); // 适配nor flash,最大超时时间改为4分钟
+ }
+
+ memset(buf, 0, 100);
+ strcpy(buf, (char *)AckBuffer);
+
+ if (bRet && (!memcmp(buf, "OKAY", 5)))
+ {
+ if (WriteBuffer != NULL)
+ {
+ free(WriteBuffer);
+ WriteBuffer = NULL;
+ }
+
+ LogInfo("DownloadPartitionfunc:: Erase Partition OK...");
+ printf("DownloadPartitionfunc:: Erase Partition OK...\n");
+
+ // PrintInfo("擦除分区成功!");
+ usleep(100 * 1000); // 延时必须要加,否则下载文件失败
+ bExit = TRUE;
+
+ bRet = TRUE;
+ State = STAT_EXIT;
+ break;
+ }
+ else
+ {
+ if (WriteBuffer != NULL)
+ {
+ free(WriteBuffer);
+ WriteBuffer = NULL;
+ }
+ LogInfo("DownloadPartitionfunc:: Erase Partition FAIL...");
+ // PrintInfo("擦除分区失败!");
+ bExit = TRUE;
+ bRet = FALSE;
+ State = STAT_EXIT;
+ break;
+ }
+ }
+ if (!memcmp(buf, strfail3, strlen(strfail3)))
+ {
+ // PrintInfo("分区表信息发生变化,NV分区发生变化,下载异常中止!");
+ LogInfo("DownloadPartitionfunc:: Partition change, stop download...");
+ State = STAT_EXIT;
+
+ bExit = TRUE;
+ bRet = FALSE;
+
+ State = STAT_EXIT;
+ break;
+ }
+ else
+ {
+ LogInfo("DownloadPartitionfunc:: Partition other fail, stop download...");
+ State = STAT_EXIT;
+
+ bExit = TRUE;
+ bRet = FALSE;
+
+ State = STAT_EXIT;
+ break;
+ }
+ }
+ break;
+
+ default:
+ bExit = TRUE;
+ }
+ }
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ }
+ return bRet;
+}
+
+static BOOL UnPreInitBoot()
+{
+ return TRUE;
+}
+
+static BOOL Initialize()
+{
+ // 下载小系统使用,下载完小系统,该标志为真
+ // 当该标志为真时,PC侧会发送一个结束命令使UE启动小系统
+ m_StartAMT = FALSE;
+ m_StartAMT_MODEM = FALSE;
+ m_StartAMT_AP = FALSE;
+ // 清空协议指针
+ m_pProtocolTable = (stSTAT *)NULL;
+ return TRUE;
+}
+
+static BOOL FileAnalysis()
+{
+ int fileIndex = 0;
+ BOOL bRet = FALSE;
+ stBinImageHead BinFileHeader;
+ int i = 0;
+ if (access(g_path, 0) != 0)
+ {
+ printf("FileAnalysisfunc:: software file path is error.\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+ if (pf == NULL)
+ {
+ // 文件打开失败
+ if (g_path != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: Open file FAIL... %s", g_path);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: g_path ptr is NULL");
+ }
+ }
+ else
+ {
+ if (g_path != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: Open file OK... %s", g_path);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: g_path ptr is NULL");
+ }
+ }
+ if (m_iFileNum <= 0)
+ {
+ LogInfo("FileAnalysisfunc:: file num error m_iFileNum = %d", m_iFileNum);
+ return bRet;
+ }
+ fseek(pf, sizeof(m_stMasterInfo), 0);
+ // 逐个文件添加到上/下载列表中
+ for (i = 0; i < m_iFileNum; i++)
+ {
+ if (fread((BYTE *)&BinFileHeader, 1, sizeof(stBinImageHead), pf) != sizeof(stBinImageHead)) // pBootFile->Read(&WriteBuffer[0], dwPacketSize) != dwPacketSize)
+ {
+ LogInfo("FileAnalysisfunc:: Read file FAIL...");
+ bRet = FALSE;
+ }
+ if (memcmp(BinFileHeader.PartitionName, "NVR", 3) != 0)
+ {
+ if (BinFileHeader.PartitionName != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: not NVR file, BinFileHeader.PartitionName = %s", BinFileHeader.PartitionName);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: not NVR file, BinFileHeader.PartitionName ptr is NULL");
+ }
+ fileIndex++;
+ g_DownLoadFileNum++;
+ }
+ else
+ {
+ if (BinFileHeader.PartitionName != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: NVR file, BinFileHeader.PartitionName = %s", BinFileHeader.PartitionName);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: NVR file, BinFileHeader.PartitionName ptr is NULL");
+ }
+ continue;
+ }
+ // 上载/下载
+ FileItem[fileIndex].bDownload = TRUE;
+
+ // 文件名称(包含路径)
+ FileItem[fileIndex].strFileName = g_path;
+
+ // 是否使用相对路径
+ FileItem[fileIndex].bUseRelativePath = 0;
+
+ // 是否直接从文件读取数据
+ FileItem[fileIndex].bReadFromFile = 1;
+
+ // 自动回收缓存空间
+ FileItem[fileIndex].bAutoDeleteImageCache = FALSE;
+
+ // 若从缓存中读取数据,赋值缓存指针
+ FileItem[fileIndex].pImageCache = NULL;
+
+ // 相对于文件/缓存的偏移地址
+ FileItem[fileIndex].dwOffset = BinFileHeader.iFileOffset;
+
+ // 分区名
+ strcpy(FileItem[fileIndex].PartitionName, (char *)BinFileHeader.PartitionName);
+
+ // 待写入的长度,单位:字节
+ FileItem[fileIndex].dwLength = BinFileHeader.iFileLength;
+
+ // 分区的偏移地址
+ FileItem[fileIndex].nPartitionOffset = BinFileHeader.iPartitionOffset;
+
+ // 分区文件类型 raw nv fs nand
+ strcpy(FileItem[fileIndex].PartitionType, (char *)BinFileHeader.PartitionType);
+
+ FileItem[fileIndex].nType = nand;
+
+ // 打印Log
+ LogInfo("FileAnalysisfunc:: FileItem[%d].bDownload = %d", fileIndex, FileItem[fileIndex].bDownload);
+ if (FileItem[fileIndex].strFileName != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].strFileName = %s", fileIndex, FileItem[fileIndex].strFileName);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].strFileName ptr is NULL", fileIndex);
+ }
+ LogInfo("FileAnalysisfunc:: FileItem[%d].bUseRelativePath = %d", fileIndex, FileItem[fileIndex].bUseRelativePath);
+ LogInfo("FileAnalysisfunc:: FileItem[%d].bReadFromFile = %d", fileIndex, FileItem[fileIndex].bReadFromFile);
+
+ LogInfo("FileAnalysisfunc:: FileItem[%d].bAutoDeleteImageCache = %d", fileIndex, FileItem[fileIndex].bAutoDeleteImageCache);
+
+ if (FileItem[fileIndex].pImageCache != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].pImageCache = %s", fileIndex, FileItem[fileIndex].pImageCache);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].pImageCache ptr is NULL", fileIndex);
+ }
+ LogInfo("FileAnalysisfunc:: FileItem[%d].dwOffset = %d", fileIndex, FileItem[fileIndex].dwOffset);
+ if (FileItem[fileIndex].PartitionName != NULL)
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].PartitionName = %s", fileIndex, FileItem[fileIndex].PartitionName);
+ }
+ else
+ {
+ LogInfo("FileAnalysisfunc:: FileItem[%d].PartitionName ptr is NULL", fileIndex);
+ }
+ LogInfo("FileAnalysisfunc:: FileItem[%d].dwLength = %d", fileIndex, FileItem[fileIndex].dwLength);
+ LogInfo("FileAnalysisfunc:: FileItem[%d].nPartitionOffset = %d", fileIndex, FileItem[fileIndex].nPartitionOffset);
+ LogInfo("FileAnalysisfunc:: FileItem[%d].PartitionType = %d", fileIndex, FileItem[fileIndex].PartitionType);
+ LogInfo("FileAnalysisfunc:: FileItem[%d].nType = %d", fileIndex, FileItem[fileIndex].nType);
+ // 计算单个文件的CRC校验值
+ // if(m_bCRCCheck)
+ //{
+ // if(!GetCRCValue(&FileItem))
+ // {
+ // return bRet;
+ // }
+ // }
+ }
+ bRet = TRUE;
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ LogInfo("FileAnalysisfunc:: fclose(pf)... ");
+ }
+ return bRet;
+}
+
+static void GetFileList(BOOL bDownload, enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize, DWORD nIndex)
+{
+ switch (LOWORD(DownloadType))
+ {
+ case DOWNLOAD_TYPE_IMAGE:
+ // 下载版本文件信息
+ if (FileAnalysis())
+ {
+ LogInfo("GetFileListfunc:: FileAnalysis OK");
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void CollectDownloadImage(enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize)
+{
+ GetFileList(TRUE, DownloadType, pBuffer, dwSize, 0);
+ LogInfo("CollectDownloadImagefunc:: GetFileList OK... ");
+}
+
+static enSTAT GotoNextState(enSTAT enCurrentStat, BOOL bRet)
+{
+ enSTAT NextState = STAT_TERMINATE;
+ int nDim = 0;
+
+ if (NULL == m_pProtocolTable)
+ {
+ LogInfo("GotoNextStatefunc:: NULL == m_pProtocolTable...");
+ return NextState;
+ }
+
+ if (m_DownloadImageTable == m_pProtocolTable)
+ {
+ nDim = sizeof(m_DownloadImageTable) / sizeof(m_DownloadImageTable[0]);
+ }
+ else if (m_DownloadRAMImageTable == m_pProtocolTable)
+ {
+ nDim = sizeof(m_DownloadRAMImageTable) / sizeof(m_DownloadRAMImageTable[0]);
+ }
+ else
+ {
+ nDim = 0;
+ }
+
+ if (enCurrentStat >= nDim)
+ {
+ if (m_DownloadImageTable == m_pProtocolTable)
+ {
+ LogInfo("GotoNextStatefunc:: m_pProtocolTable -> m_DownloadImageTable...");
+ }
+ else if (m_DownloadRAMImageTable == m_pProtocolTable)
+ {
+ LogInfo("GotoNextStatefunc:: m_pProtocolTable -> m_DownloadRAMImageTable...");
+ }
+ else
+ {
+ LogInfo("GotoNextStatefunc:: error state...");
+ }
+ return NextState;
+ }
+
+ if (TRUE == bRet)
+ {
+ NextState = m_pProtocolTable[enCurrentStat].mNextTRUE;
+ }
+ else
+ {
+ NextState = m_pProtocolTable[enCurrentStat].mNextFALSE;
+ }
+
+ return NextState;
+}
+
+static BOOL DownloadOneImage(stDownloadConfig CurrentConfig)
+{
+ enSTAT State = CurrentConfig.mStartState;
+
+ BOOL bRet = FALSE;
+ BOOL bExit = FALSE;
+ ULONG ulAckCRCValue = 0;
+
+ DWORD dwCurrentSize = 0;
+ DWORD dwPacketCount = 0;
+
+ BYTE CommandBuffer[255] = {0};
+ BYTE *AckBuffer;
+
+ BYTE Buftmp[20] = {0}; // 用于临时存放数据, add zxw 20130422
+ size_t dwPacketSize = 0; // add zxw 20130422 数据包长度
+ DWORD dwDDRPacketSize = 0;
+ BYTE *pBuffer = CurrentConfig.mCurrentFile.pImageCache;
+ DWORD dwFileSize = 0;
+
+ if (access(g_path, 0) != 0)
+ {
+ printf("DownloadOneImagefunc:: software file path is error.\r\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+ if (pf == NULL)
+ {
+ // 文件打开失败
+ if (g_path != NULL)
+ {
+ LogInfo("DownloadOneImagefunc:: Open file FAIL... %s", g_path);
+ printf("33333333333333333333333\n");
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: g_path ptr is NULL", g_path);
+ printf("44444444444444444444\n");
+ }
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: Open file OK ");
+ printf("DownloadOneImagefunc:: Open file OK \n");
+ }
+ fseek(pf, CurrentConfig.mCurrentFile.dwOffset, 0);
+ while (!bExit)
+ {
+ switch (State)
+ {
+ //-------------------------设置Packet长度----------------------------
+ case STAT_SET_PACKET_SIZE:
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE");
+ printf("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE\n");
+
+ memset(CommandBuffer, 0, 255);
+ sprintf(CommandBuffer, "compat_write %s %08x %0x", CurrentConfig.mCurrentFile.PartitionName, CurrentConfig.mCurrentFile.nPartitionOffset, CurrentConfig.mCurrentFile.dwLength);
+ LogInfo("DownloadOneImagefunc:: CommandBuffer = %s", CommandBuffer);
+ printf("DownloadOneImagefunc:: CommandBuffer = %s\n", CommandBuffer);
+ dwFileSize = CurrentConfig.mCurrentFile.dwLength;
+ bRet = SendData(CommandBuffer, strlen((const char *)CommandBuffer) + 1, 20, 1);
+ if (bRet)
+ {
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(14, 10, 4 * 60); // 适配nor flash,最大超时时间改为4分钟
+ LogInfo("DownloadOneImagefunc:: AckBuffer = %x", AckBuffer[0]);
+ }
+ if ((AckBuffer[0] == 0x00) && (AckBuffer[1] == 0x44))
+ {
+ int indexextra = 0;
+ for (indexextra = 0; indexextra < 14; indexextra++)
+ {
+ AckBuffer[indexextra] = AckBuffer[indexextra + 1];
+ }
+ }
+ if (bRet && (!memcmp(AckBuffer, "DATA", 4)))
+ {
+ // 成功
+ LogInfo("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE OK");
+ printf("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE OK\n");
+
+ dwDDRPacketSize = strtoul((char *)AckBuffer + 4, 0, 16);
+ // 将此包不是发送的一包的长度值实际是是DDR中设置的一包内存的大小。
+ if (dwDDRPacketSize > CurrentConfig.mCurrentFile.dwLength)
+ // 如果返回待写数据长度,大于镜像文件长度,则失败
+ {
+ LogInfo("DownloadOneImagefunc:: return data length greater than file total length, fail...dwDDRPacketSize = %d, CurrentConfig.mCurrentFile.dwLength = %d", dwDDRPacketSize, CurrentConfig.mCurrentFile.dwLength);
+ printf("DownloadOneImagefunc:: return data length greater than file total length, fail...dwDDRPacketSize = %d, CurrentConfig.mCurrentFile.dwLength = %d\n", dwDDRPacketSize, CurrentConfig.mCurrentFile.dwLength);
+
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: return data length <= file total length, dwDDRPacketSize = %d, CurrentConfig.mCurrentFile.dwLength = %d", dwDDRPacketSize, CurrentConfig.mCurrentFile.dwLength);
+ // 执行下一项流程
+ dwCurrentSize = dwDDRPacketSize;
+ State = GotoNextState(State, TRUE);
+ }
+ }
+ else // 失败
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE fail");
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ }
+ }
+ break;
+
+ //------------------------Image数据-----------------------------
+ case STAT_DATAPACKET:
+ {
+ dwFileSize -= dwCurrentSize;
+ if (dwCurrentSize >= CurrentConfig.mPacketSize)
+ {
+ dwPacketSize = CurrentConfig.mPacketSize;
+ }
+ else
+ {
+ dwPacketSize = dwCurrentSize;
+ }
+
+ BYTE *WriteBuffer = (BYTE *)malloc(dwPacketSize);
+ if (dwCurrentSize > 0)
+ {
+ while (1)
+ {
+ // 读取磁盘数据
+ memset(WriteBuffer, 0, dwPacketSize);
+
+ if (CurrentConfig.mCurrentFile.bReadFromFile)
+ {
+ if (dwCurrentSize > dwPacketSize)
+ {
+ dwPacketSize = dwPacketSize;
+ }
+ else
+ {
+ dwPacketSize = dwCurrentSize;
+
+ if ((dwPacketSize % 512) == 0)
+ {
+ dwPacketSize -= 8;
+ // usb若不支持长度是512整数包,用0包表示结束时,则在此处拆包。
+ LogInfo("DownloadOneImagefunc:: STAT_DATAPACKET split packet");
+ // printf("DownloadOneImagefunc:: STAT_DATAPACKET split packet\n");
+ }
+ else
+ {
+ usleep(2 * 1000);
+ // 由于有拆包动作,最后一包需要等待先前数据发送完成。
+ }
+ }
+ if (fread(&WriteBuffer[0], 1, dwPacketSize, pf) != dwPacketSize)
+ {
+ LogInfo("DownloadOneImagefunc:: read packte fail");
+
+ State = GotoNextState(State, FALSE);
+ if (WriteBuffer != NULL)
+ {
+ free(WriteBuffer);
+ WriteBuffer = NULL;
+ }
+ bRet = FALSE;
+ break;
+ }
+ }
+ else
+ {
+ if (CurrentConfig.mCurrentFile.pImageCache != NULL)
+ {
+ memcpy(&WriteBuffer[0], pBuffer, dwPacketSize);
+ pBuffer += dwPacketSize;
+ }
+ }
+
+ // 发送数据到UE
+ bRet = SendData(WriteBuffer, dwPacketSize, 20, 1);
+ if (bRet == TRUE)
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_DATAPACKET :send one packet success");
+ // printf("DownloadOneImagefunc:: STAT_DATAPACKET :send one packet success\n");
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_DATAPACKET :send one packet FAIL!");
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ break;
+ }
+ dwCurrentSize -= dwPacketSize;
+ if (dwCurrentSize == 0)
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_DATAPACKET :dwCurrentSize == 0");
+ if (dwFileSize > 0) //
+ {
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(14, 10, 4 * 60); // 适配nor flash,最大超时时间改为4分钟
+ LogInfo("DownloadOneImagefunc:: AckBuffer = %x", AckBuffer[0]);
+ if ((AckBuffer[0] == 0x00) && (AckBuffer[1] == 0x44))
+ {
+ int indexextra = 0;
+ for (indexextra = 0; indexextra < 14; indexextra++)
+ {
+ AckBuffer[indexextra] = AckBuffer[indexextra + 1];
+ }
+ }
+ if (bRet && (!memcmp(AckBuffer, "DATA", 4)))
+ {
+ // 成功
+ LogInfo("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE OK");
+ printf("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE OK\n");
+
+ dwDDRPacketSize = strtoul((char *)AckBuffer + 4, 0, 16);
+ // 将此包不是发送的一包的长度值实际是是DDR中设置的一包内存的大小。
+ if (dwDDRPacketSize > CurrentConfig.mCurrentFile.dwLength)
+ // 如果返回待写数据长度,大于镜像文件长度,则失败
+ {
+ LogInfo("DownloadOneImagefunc:: return data length greater than file total length, fail...dwDDRPacketSize = %d, CurrentConfig.mCurrentFile.dwLength = %d", dwDDRPacketSize, CurrentConfig.mCurrentFile.dwLength);
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: return data length <= file total length, dwDDRPacketSize = %d, CurrentConfig.mCurrentFile.dwLength = %d", dwDDRPacketSize, CurrentConfig.mCurrentFile.dwLength);
+ // 执行下一项流程
+ dwCurrentSize = dwDDRPacketSize;
+ }
+ }
+ else // 失败
+ {
+ LogInfo("DownloadOneImagefunc:: STAT_SET_PACKET_SIZE fail");
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ }
+ }
+ else // 文件的最后一包
+ {
+
+ // lx,如果支持CRC校验,boot回复CRC校验值,否则回复OKEY
+ if (m_bCRCCheck)
+ {
+ bRet = ReadData((BYTE *)&ulAckCRCValue, 4, 30, 4 * 60); // 适配nor flash,最大超时时间改为4分钟
+ LogInfo("DownloadOneImagefunc:: CurrentConfig.mCurrentFile.ulCRCValue = %ld ulAckCRCValue = %ld", CurrentConfig.mCurrentFile.ulCRCValue, ulAckCRCValue);
+ // printf("DownloadOneImagefunc:: CurrentConfig.mCurrentFile.ulCRCValue = %ld ulAckCRCValue = %ld\n", CurrentConfig.mCurrentFile.ulCRCValue, ulAckCRCValue);
+ if (bRet && (CurrentConfig.mCurrentFile.ulCRCValue == ulAckCRCValue))
+ {
+ // PrintInfo(_T("Image data send success!"));
+ LogInfo("DownloadOneImagefunc:: Image data send success!CurrentConfig.mCurrentFile.ulCRCValue = %ld ulAckCRCValue = %ld", CurrentConfig.mCurrentFile.ulCRCValue, ulAckCRCValue);
+ // printf("DownloadOneImagefunc:: Image data send success!CurrentConfig.mCurrentFile.ulCRCValue = %ld ulAckCRCValue = %ld\n", CurrentConfig.mCurrentFile.ulCRCValue, ulAckCRCValue);
+ bRet = TRUE;
+ State = GotoNextState(State, TRUE);
+ }
+ else
+ {
+ // PrintInfo(_T("Image data send fail!"));
+ LogInfo("DownloadOneImagefunc:: Image data send fail!");
+ bRet = FALSE;
+ State = GotoNextState(State, FALSE);
+ }
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: not CRCCheck");
+ printf("DownloadOneImagefunc:: not CRCCheck\n");
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(5, 10, 4 * 60); // 适配nor flash,最大超时时间改为4分钟
+ // bRet = ReadDataExtraFuncA(14, 10 , 100);
+ if (AckBuffer != NULL)
+ {
+ LogInfo("DownloadOneImagefunc:: AckBuffer... %s", AckBuffer);
+ // printf("DownloadOneImagefunc:: AckBuffer... %s\n", AckBuffer);
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: AckBuffer is NULL");
+ }
+ if (bRet && (!memcmp(AckBuffer, "OKAY", 4)))
+ {
+ LogInfo("DownloadOneImagefunc:: Image data send success!");
+ printf("DownloadOneImagefunc:: Image data send success!\n");
+ bRet = TRUE;
+ State = GotoNextState(State, TRUE);
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: Image data send fail!");
+ State = GotoNextState(State, FALSE);
+ bRet = FALSE;
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ if (WriteBuffer != NULL)
+ {
+ free(WriteBuffer);
+ WriteBuffer = NULL;
+ }
+ }
+ break;
+ //--------------------------执行代码-----------------------------
+ case STAT_EXECUTE_CODE:
+ {
+ LogInfo("DownloadOneImagefunc:: EXECUTE_CODE IN mbExecuteCode = %d PartitionType = %s", CurrentConfig.mbExecuteCode, CurrentConfig.mCurrentFile.PartitionType);
+ // printf("DownloadOneImagefunc:: EXECUTE_CODE IN mbExecuteCode = %d PartitionType = %s\n", CurrentConfig.mbExecuteCode, CurrentConfig.mCurrentFile.PartitionType);
+ if ((TRUE == CurrentConfig.mbExecuteCode) && (memcmp(CurrentConfig.mCurrentFile.PartitionType, "zftl", 3) == 0))
+ {
+ LogInfo("DownloadOneImagefunc:: start EXECUTE_CODE");
+ printf("DownloadOneImagefunc:: start EXECUTE_CODE\n");
+ memset(CommandBuffer, 0, sizeof(CommandBuffer));
+ memcpy(CommandBuffer, ("reboot"), strlen(("reboot")));
+ bRet = SendData(CommandBuffer, strlen((const char *)CommandBuffer) + 1, 10, 1);
+ if (bRet)
+ {
+ AckBuffer = (BYTE *)ReadDataExtraFuncB(14, 10, 10);
+ if (AckBuffer != NULL)
+ {
+ LogInfo("DownloadOneImagefunc:: AckBuffer... %s", AckBuffer);
+ // printf("DownloadOneImagefunc:: AckBuffer... %s\n", AckBuffer);
+ }
+ else
+ {
+ LogInfo("DownloadOneImagefunc:: AckBuffer is NULL");
+ }
+ }
+ if (bRet && !memcmp(AckBuffer, "OKAY REBOOT", 11))
+ {
+ // PrintInfo(_T("正在执行代码..."));
+ LogInfo("DownloadOneImagefunc:: EXECUTE_CODE on doing...");
+ printf("DownloadOneImagefunc:: EXECUTE_CODE on doing...\n");
+ }
+ else
+ {
+ char *strInfo;
+ char *strTemp;
+
+ // sprintf(strInfo,"bRet = %d",bRet);
+ // sprintf(strTemp,"%s",&AckBuffer[0]);
+ LogInfo("DownloadOneImagefunc:: EXECUTE_CODE fail");
+
+ bRet = FALSE;
+ }
+ }
+ else
+ {
+ bRet = TRUE;
+ }
+ State = GotoNextState(State, TRUE);
+ }
+ break;
+ default:
+ bExit = TRUE;
+ break;
+ }
+ }
+
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ LogInfo("DownloadOneImagefunc:: fclose(pf) ");
+ }
+ return bRet;
+}
+
+// 修改这个函数的打印 bufantong
+static BOOL DownloadImage(stFileItem ImageInfo, BOOL bExecuteCode)
+{
+ BOOL bRet = FALSE;
+ stDownloadConfig CurrentConfig;
+ CurrentConfig.mCurrentFile = ImageInfo;
+
+ // 判断文件的类型
+ switch (ImageInfo.nType)
+ {
+ case nand: // 类型为nand 时,写操作之前全部擦除。
+ LogInfo("DownloadImagefunc:: case nand...");
+ printf("DownloadImagefunc:: case nand...\n");
+
+ m_pProtocolTable = m_DownloadImageTable;
+
+ CurrentConfig.mPacketSize = PACKET_SIZE_FLASH;
+
+ // 下载到Flash中的文件是不需要打开启动AMT的标志的
+ m_StartAMT = FALSE;
+ break;
+
+ case fs:
+ LogInfo("DownloadImagefunc:: case fs...");
+ printf("DownloadImagefunc:: case fs...\n");
+ m_pProtocolTable = m_DownloadImageTable;
+
+ CurrentConfig.mPacketSize = PACKET_SIZE_FLASH;
+
+ // 下载到Flash中的文件是不需要打开启动AMT的标志的
+ m_StartAMT = FALSE;
+ break;
+
+ case zftl: // 该分支是下载NVR分区用的 分区名是NVR,NVRW ,RAMDISK三个分区是该类型,写操作时,是先备份再擦写再覆盖。
+ LogInfo("DownloadImagefunc:: case zftl...");
+ printf("DownloadImagefunc:: case zftl...\n");
+ ImageInfo.nType = zftl;
+ m_pProtocolTable = m_DownloadImageTable;
+ CurrentConfig.mPacketSize = PACKET_SIZE_FLASH;
+
+ // 下载NV备份文件是不需要打开启动AMT的标志的
+ m_StartAMT = FALSE;
+ break;
+
+ case ddr:
+ // pImageInfo->nType = EXTSRAM;
+ LogInfo("DownloadImagefunc:: case ddr...");
+ printf("DownloadImagefunc:: case ddr...\n");
+ ImageInfo.nType = ddr;
+ m_pProtocolTable = m_DownloadRAMImageTable;
+ CurrentConfig.mPacketSize = PACKET_SIZE_IMAGE;
+ CurrentConfig.mCurrentFile.PartitionName[0] = 'd';
+ CurrentConfig.mCurrentFile.PartitionName[1] = 'd';
+ CurrentConfig.mCurrentFile.PartitionName[2] = 'r';
+ CurrentConfig.mCurrentFile.PartitionName[3] = '\0';
+
+ m_StartAMT = TRUE;
+ break;
+ case zloader:
+ LogInfo("DownloadImagefunc:: case zloader...");
+ printf("DownloadImagefunc:: case zloader...\n");
+ // pImageInfo->nType = EXTSRAM;
+ ImageInfo.nType = zloader;
+ m_pProtocolTable = m_DownloadRAMImageTable;
+ CurrentConfig.mPacketSize = PACKET_SIZE_IMAGE;
+ CurrentConfig.mCurrentFile.PartitionName[0] = 'z';
+ CurrentConfig.mCurrentFile.PartitionName[1] = 'l';
+ CurrentConfig.mCurrentFile.PartitionName[2] = 'o';
+ CurrentConfig.mCurrentFile.PartitionName[3] = 'a';
+ CurrentConfig.mCurrentFile.PartitionName[4] = 'd';
+ CurrentConfig.mCurrentFile.PartitionName[5] = 'e';
+ CurrentConfig.mCurrentFile.PartitionName[6] = 'r';
+ CurrentConfig.mCurrentFile.PartitionName[7] = '\0';
+
+ m_StartAMT = TRUE;
+ break;
+
+ default:
+ {
+ LogInfo("DownloadImagefunc:: not right type...");
+ printf("DownloadImagefunc:: not right type...\n");
+ return TRUE;
+ }
+ break;
+ }
+
+ if (ImageInfo.bReadFromFile)
+ {
+ if (access(g_path, 0) != 0)
+ {
+ printf("DownloadImagefunc:: software file path is error.\r\n");
+ return FALSE;
+ }
+ pf = fopen(g_path, "rb");
+ if (pf == NULL)
+ {
+ LogInfo("DownloadImagefunc:: Open file FAIL... %s", g_path);
+ }
+ }
+ CurrentConfig.mStartState = STAT_SET_PACKET_SIZE;
+ // CurrentConfig.mpFile = pf;
+ CurrentConfig.mbExecuteCode = bExecuteCode;
+ // 这个函数里也加了打印
+ bRet = DownloadOneImage(CurrentConfig);
+ // usleep(10*1000);
+ if (ImageInfo.bReadFromFile)
+ {
+ if (pf != NULL)
+ {
+ fclose(pf);
+ pf = NULL;
+ LogInfo("DownloadImagefunc:: fclose(pf) ");
+ }
+ }
+ return bRet;
+}
+
+static BOOL ExchangeImage()
+{
+ BOOL bRet = FALSE;
+ BOOL bExecuteCode = FALSE;
+ LogInfo("ExchangeImagefunc:: g_DownLoadFileNum = %d ...", g_DownLoadFileNum);
+ if (g_DownLoadFileNum == 0)
+ {
+ LogInfo("ExchangeImagefunc:: g_DownLoadFileNum == 0 ...", g_DownLoadFileNum);
+ return bRet;
+ }
+ int fileIndex = 0;
+ for (fileIndex = 1; fileIndex <= g_DownLoadFileNum; fileIndex++)
+ {
+ LogInfo("CYF start ExchangeImage = %d ...", fileIndex);
+
+ LogInfo("ExchangeImagefunc:: FileItem[%d].bDownload = %d", fileIndex, FileItem[fileIndex].bDownload);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].strFileName = %s", fileIndex, FileItem[fileIndex].strFileName);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].bUseRelativePath = %d", fileIndex, FileItem[fileIndex].bUseRelativePath);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].bReadFromFile = %d", fileIndex, FileItem[fileIndex].bReadFromFile);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].bAutoDeleteImageCache = %d", fileIndex, FileItem[fileIndex].bAutoDeleteImageCache);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].pImageCache = %s", fileIndex, FileItem[fileIndex].pImageCache);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].dwOffset = %d", fileIndex, FileItem[fileIndex].dwOffset);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].PartitionName = %s", fileIndex, FileItem[fileIndex].PartitionName);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].dwLength = %d", fileIndex, FileItem[fileIndex].dwLength);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].nPartitionOffset = %d", fileIndex, FileItem[fileIndex].nPartitionOffset);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].PartitionType = %d", fileIndex, FileItem[fileIndex].PartitionType);
+ LogInfo("ExchangeImagefunc:: FileItem[%d].nType = %d", fileIndex, FileItem[fileIndex].nType);
+
+ LogInfo("ExchangeImagefunc:: bDownload FileItem[fileIndex].bDownload = %d...", FileItem[fileIndex].bDownload);
+ if (FileItem[fileIndex].bDownload)
+ {
+ if (fileIndex == g_DownLoadFileNum)
+ {
+ LogInfo("ExchangeImagefunc:: bExecuteCode == TRUE ..., fileIndex = %d", fileIndex);
+ bExecuteCode = FALSE;
+ }
+ else
+ {
+ LogInfo("ExchangeImagefunc:: bExecuteCode == FALSE ..., fileIndex = %d", fileIndex);
+ }
+ LogInfo("ExchangeImagefunc:: bDownload true ...");
+ bRet = DownloadImage(FileItem[fileIndex], bExecuteCode);
+ usleep(10 * 1000);
+ }
+ else
+ {
+ LogInfo("ExchangeImagefunc:: bDownload false...");
+ }
+
+ if (bRet)
+ {
+ LogInfo("ExchangeImagefunc:: %d OK...", fileIndex);
+ printf("ExchangeImagefunc:: %d OK...\r\n", fileIndex);
+ }
+ else
+ {
+ LogInfo("ExchangeImagefunc:: %d FAIL...", fileIndex);
+ printf("ExchangeImagefunc:: %d FAIL...\r\n", fileIndex);
+ break;
+ }
+ }
+ return bRet;
+}
+
+static BOOL UnInitialize()
+{
+ return TRUE;
+}
+
+static BOOL DoDownload(enDownloadType DownloadType, BYTE *pBuffer, DWORD dwSize, BOOL bBackupNV, enDownloadNVBackupMethod Method, BOOL bEableCRCCheck)
+{
+ BOOL bRet = FALSE;
+ BOOL bReturn = FALSE;
+ BOOL bExit = FALSE;
+ typedef enum
+ {
+ STAT_INIT,
+ STAT_COLLECT_UPLOAD_NV_INFO,
+ STAT_COLLECT_DOWNLOAD_IMAGE_INFO,
+ STAT_EXCHANGE_IMAGE,
+ STAT_START_AMT,
+ STAT_UNINIT,
+ STAT_EXIT
+ } STAT_ITEM;
+ int nState = STAT_INIT;
+ LogInfo("DoDownloadfunc:: start...");
+ m_bBackUpNV = bBackupNV;
+ while (!bExit)
+ {
+ switch (nState)
+ {
+ case STAT_INIT: // 初始化资源
+ bRet = Initialize();
+ if (bRet)
+ {
+ LogInfo("DoDownloadfunc:: STAT_INIT OK...");
+ // PrintInfo(_T("init sucess!"));
+ nState = STAT_COLLECT_UPLOAD_NV_INFO;
+ }
+ else
+ {
+ // PrintInfo(_T("init fail!"));
+ LogInfo("DoDownloadfunc:: STAT_INIT FAIL...");
+ nState = STAT_EXIT;
+ }
+ break;
+
+ case STAT_COLLECT_UPLOAD_NV_INFO: // 收集备份NV上载信息
+ // lx增加CRC校验握手状态
+ if (bEableCRCCheck)
+ {
+ nState = STAT_CRC_ON;
+ }
+ else if (m_bCRCCheck)
+ {
+ nState = STAT_CRC_OFF;
+ }
+ else
+ {
+ nState = STAT_COLLECT_DOWNLOAD_IMAGE_INFO;
+ }
+ break;
+
+ case STAT_CRC_ON:
+ {
+ // 打开CRC校验
+ BYTE CommandBuffer[255] = {0};
+ BYTE AckBuffer[255] = {0};
+ memset(CommandBuffer, 0, sizeof(CommandBuffer));
+ memset(AckBuffer, 0, sizeof(AckBuffer));
+ memcpy(&CommandBuffer[0], "CRC ON", 6);
+ bRet = SendData(CommandBuffer, strlen((const char *)CommandBuffer) + 1, 10, 1);
+ if (bRet)
+ {
+ bRet = ReadData(AckBuffer, 5, 10, 30);
+ }
+ if (bRet && (!memcmp(AckBuffer, "OKAY", 4)))
+ {
+ // boot支持CRC校验
+ // PrintInfo(_T("CRC校验打开成功!"));
+ LogInfo("DoDownloadfunc:: CRC open OK...");
+ m_bCRCCheck = TRUE;
+ nState = STAT_COLLECT_DOWNLOAD_IMAGE_INFO;
+ }
+ else // 失败
+ {
+ // PrintInfo(_T("CRC校验打开失败!"));
+ LogInfo("DoDownloadfunc:: CRC open FAIL..");
+ m_bCRCCheck = FALSE;
+ nState = STAT_COLLECT_DOWNLOAD_IMAGE_INFO;
+ }
+ }
+ break;
+ case STAT_CRC_OFF:
+ {
+ // 关闭CRC校验
+ BYTE CommandBuffer[255] = {0};
+ BYTE AckBuffer[255] = {0};
+ memset(CommandBuffer, 0, sizeof(CommandBuffer));
+ memset(AckBuffer, 0, sizeof(AckBuffer));
+ memcpy(&CommandBuffer[0], "CRC OFF", 7);
+ bRet = SendData(CommandBuffer, strlen((const char *)CommandBuffer) + 1, 10, 1);
+ if (bRet)
+ {
+ bRet = ReadData(AckBuffer, 5, 10, 30);
+ }
+ if (bRet && (!memcmp(AckBuffer, "OKAY", 4)))
+ {
+ // boot支持CRC校验
+ // PrintInfo(_T("CRC校验关闭成功!"));
+ LogInfo("DoDownloadfunc:: CRC close OK...");
+ m_bCRCCheck = FALSE;
+ nState = STAT_COLLECT_DOWNLOAD_IMAGE_INFO;
+ }
+ else // 失败
+ {
+ // PrintInfo(_T("CRC校验关闭失败!"));
+ LogInfo("DoDownloadfunc:: CRC close FAIL...");
+ m_bCRCCheck = TRUE;
+ nState = STAT_COLLECT_DOWNLOAD_IMAGE_INFO;
+ }
+ }
+ break;
+
+ case STAT_COLLECT_DOWNLOAD_IMAGE_INFO: // 收集下载Image信息
+ // 收集下载Image信息
+ LogInfo("DoDownloadfunc:: Collect image...");
+ CollectDownloadImage(DownloadType, pBuffer, dwSize);
+ nState = STAT_EXCHANGE_IMAGE;
+ break;
+
+ case STAT_EXCHANGE_IMAGE: // Exchange数据
+
+ LogInfo("DoDownloadfunc:: ExchangeImage...");
+ bRet = ExchangeImage();
+ if (bRet)
+ {
+ // PrintInfo(_T("Exchange data success!"));
+ nState = STAT_START_AMT;
+ }
+ else
+ {
+ // PrintInfo(_T("Exchange data fail!"));
+ nState = STAT_UNINIT;
+ }
+ break;
+
+ case STAT_START_AMT: // 发送启动AMT标志
+ bReturn = TRUE;
+ nState = STAT_UNINIT;
+ break;
+
+ case STAT_UNINIT: // 释放资源
+ bRet = UnInitialize();
+ if (bRet)
+ {
+ // PrintInfo(_T("release success!"));
+ }
+ else
+ {
+ // PrintInfo(_T("release fail!"));
+ bReturn = FALSE;
+ }
+ nState = STAT_EXIT;
+ break;
+
+ default:
+ bExit = TRUE;
+ }
+ }
+
+ return bReturn;
+}
+
+/*******************************************************************************
+ * 外部函数 *
+ *******************************************************************************/
+BOOL ExecuteEraseNVRW(const char *softwarepath)
+{
+ BOOL bRet = FALSE;
+
+ LogInfo("ExecuteEraseNVRWfunc:: start...");
+ printf("ExecuteEraseNVRWfunc:: start...");
+
+ strcpy(g_path, (char *)softwarepath);
+
+ if (!EraseNVRW())
+ {
+ LogInfo("ExecuteEraseNVRWfunc:: EraseNVRW FAIL...");
+ }
+ else
+ {
+ LogInfo("ExecuteEraseNVRWfunc:: EraseNVRW OK...");
+ bRet = TRUE;
+ }
+ return bRet;
+}
+
+int PrimaryDoDownload(const char *softwarepath)
+{
+ // 打开log文件
+ // 提示开始下载
+ printf("PrimaryDoDownloadfunc:: start\r\n");
+ LogInfo("PrimaryDoDownloadfunc:: start\r\n");
+
+ enERRORCODE DownloadResult = Download_OK;
+ strcpy(g_path, softwarepath);
+
+ // 下载版本文件
+ if (!DoDownload(DOWNLOAD_TYPE_IMAGE, NULL, 0, FALSE, METHOD_NORMAL, FALSE))
+ {
+ LogInfo("PrimaryDoDownloadfunc:: DoDownload Image FAIL...");
+ DownloadResult = Download_DOWNLOAD_IMAGE_FAIL;
+ }
+ else
+ {
+ LogInfo("PrimaryDoDownloadfunc:: DoDownload Image OK...");
+ }
+ LogInfo("PrimaryDoDownloadfunc:: DoDownload Image DownloadResult=%d", DownloadResult);
+
+ return DownloadResult;
+}
+
+// 下载tloader, tboot, partion
+BOOL DoDownloadBootForDL(BOOL bCheckPartition, const char *softwarepath)
+{
+ long n = 1000000;
+ double duration = 0;
+
+ clock_t start;
+ clock_t finish;
+ DWORD nStartTime = 0;
+ DWORD nStopTime = 0;
+ BOOL bRet = FALSE;
+ BOOL bTotalRet = TRUE;
+ BOOL bExit = FALSE;
+ typedef enum
+ {
+ STAT_INIT,
+ STAT_DOWNLOAD_BOOT1,
+ STAT_DOWNLOAD_BOOT2,
+
+ STAT_DOWNLOAD_PARTITION,
+ STAT_UNINIT,
+ STAT_EXIT
+ } STAT;
+ int nState = STAT_INIT;
+ int nWhile = 0;
+
+ strcpy(g_path, softwarepath);
+
+ LogInfo("DoDownloadBootForDL:: start...");
+ printf("DoDownloadBootForDL:: start...\n");
+
+ while (!bExit)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: nWhile = %d\n", nWhile);
+ printf("DoDownloadBootForDLfunc:: nWhile = %d\n", nWhile);
+ nWhile++;
+
+ switch (nState)
+ {
+ case STAT_INIT: // 初始化资源
+
+ bRet = PreInitBoot();
+
+ if (bRet)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: PreInitBoot OK...");
+ nState = STAT_DOWNLOAD_BOOT1;
+ }
+ else
+ {
+ LogInfo("DoDownloadBootForDLfunc:: PreInitBoot FAIL...");
+ printf("DoDownloadBootForDLfunc:: PreInitBoot FAIL...\n");
+
+ bTotalRet = FALSE;
+ nState = STAT_EXIT;
+ }
+ break;
+ /*********************add zxw 20121009 for 296301 begin************************************/
+ case STAT_DOWNLOAD_BOOT1: // 下载stage1, TLoader
+
+ start = clock(); // 记录开始时间
+ LogInfo("DoDownloadBootForDLfunc:: start download BOOT1...");
+ printf("DoDownloadBootForDLfunc:: start download BOOT1...\n");
+
+ bRet = DownloadOneBoot(m_dwBootStage1StartAddress, m_dwBootStage1Size, pf, 4000, m_stMasterInfo.tloaderOffset, TRUE);
+
+ finish = clock(); // 结束时间
+ duration = (double)(finish - start) / CLOCKS_PER_SEC;
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT1 communication time: %lf", duration);
+
+ if (bRet)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT1 OK");
+ nState = STAT_DOWNLOAD_BOOT2;
+ }
+ else
+ {
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT1 FAIL");
+ printf("DoDownloadBootForDLfunc:: download BOOT1 FAIL\n");
+
+ bTotalRet = FALSE;
+ nState = STAT_UNINIT;
+ }
+ break;
+
+ case STAT_DOWNLOAD_BOOT2: // 下载stage2, TBoot
+
+ start = clock(); // 记录开始时间
+ LogInfo("DoDownloadBootForDLfunc:: start download BOOT2...");
+ printf("DoDownloadBootForDLfunc:: start download BOOT2...\n");
+
+ bRet = DownloadOneBoot(m_dwBootStage2StartAddress, m_dwBootStage2Size, pf, 4000, m_stMasterInfo.tBootOffset, TRUE);
+
+ finish = clock(); // 结束时间
+ duration = (double)(finish - start) / CLOCKS_PER_SEC;
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT2 communication time: %lf", duration);
+
+ if (bRet)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT2 OK");
+ nState = STAT_DOWNLOAD_PARTITION;
+ }
+ else
+ {
+ LogInfo("DoDownloadBootForDLfunc:: download BOOT2 FAIL");
+ printf("DoDownloadBootForDLfunc:: download BOOT2 FAIL\n");
+
+ nState = STAT_UNINIT;
+ bTotalRet = FALSE;
+ }
+ break;
+ /*********************add zxw 20121009 for 296301 end************************************/
+ case STAT_DOWNLOAD_PARTITION:
+
+ start = clock(); // 记录开始时间
+ LogInfo("DoDownloadBootForDLfunc:: start download PARTITION");
+ printf("DoDownloadBootForDLfunc:: start download PARTITION\n");
+
+ bRet = DownloadPartition((size_t)m_dwPartitionSize, pf, 4096, m_stMasterInfo.PartitionOffset, FALSE);
+
+ finish = clock(); // 结束时间
+ duration = (double)(finish - start) / CLOCKS_PER_SEC;
+ LogInfo("DoDownloadBootForDLfunc:: download PARTITION communication time: %lf", duration);
+
+ if (bRet)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: DownloadPartition : download OK");
+ }
+ else
+ {
+ LogInfo("DoDownloadBootForDLfunc:: DownloadPartition : download FAIL");
+ printf("DoDownloadBootForDLfunc:: DownloadPartition : download FAIL\n");
+ bTotalRet = FALSE;
+ }
+
+ nState = STAT_UNINIT;
+ break;
+
+ case STAT_UNINIT:
+ bRet = UnPreInitBoot();
+ if (bRet)
+ {
+ LogInfo("DoDownloadBootForDLfunc:: UnPreInitBoot OK");
+ }
+ else
+ {
+ LogInfo("DoDownloadBootForDLfunc:: UnPreInitBoot FAIL");
+ bTotalRet = FALSE;
+ }
+ nState = STAT_EXIT;
+ break;
+
+ default:
+
+ bExit = TRUE;
+ break;
+ }
+ }
+ return bTotalRet;
+}
diff --git a/ap/hostapp/zdownloader/download.h b/ap/hostapp/zdownloader/download.h
new file mode 100755
index 0000000..0fae875
--- /dev/null
+++ b/ap/hostapp/zdownloader/download.h
@@ -0,0 +1,476 @@
+#ifndef _DOWNLOAD_H_
+#define _DOWNLOAD_H_
+
+#include "define.h"
+
+// BI层最大支持线程数
+#define TSP_THREAD_NUM 64
+
+// 下载文件类型
+#define FLASH (0x01)
+#define EXTSRAM (0x02)
+#define FPGA (0x03)
+#define RAMIMAGE (0x04)
+#define NVBACKUP (0x05)
+#define ZPHY_ERFC_CA_NUMBER 2
+
+// 串行口参数配置
+#define READ_INTERVAL_TIMEOUT (0)
+#define READ_TOTAL_TIMEOUT_MULTIPLIER (0)
+#define READ_TOTAL_TIMEOUT_CONSTANT (0)
+#define WRITE_TOTAL_TIMEOUT_MULTIPLIER (0)
+#define WRITE_TOTAL_TIMEOUT_CONSTANT (1000)
+
+// 收发数据包大小
+#define READ_QUEUE (4096)
+#define WRITE_QUEUE (4096)
+
+// 波特率设置选项
+#define NO_OF_PARAMS (7)
+#define COM_PORT (1)
+#define BAUD_RATE (2)
+#define PARITY (3)
+#define STOP_BITS (4)
+#define DATA_BITS (5)
+#define READ_INTVL (6)
+#define TOTAL_TIME (7)
+
+//
+//#define BUFFERLEN 1100
+#define AT_CMD_TYPE_TEST 1000
+#define AT_CMD_TYPE_AT 1001
+#define INFO_PACKET_LEN 1024
+// 下载的配置文件选项
+#define VERSION_NUM 4
+
+#define CONFIG_SECTION_CFG _T("Configuration")
+#define CONFIG_SECTION_VERSION _T("Version")
+#define CONFIG_SECTION_CHIPDETAILS _T("ChipDetails")
+#define CONFIG_SECTION_ARM_BIN _T("ArmBin")
+#define CONFIG_SECTION_ZSP_BIN _T("ZspBin")
+#define CONFIG_SECTION_ZSPCC_BIN _T("ZspCCBin")
+#define CONFIG_SECTION_ARM1_BIN _T("Arm1Bin")
+#define CONFIG_SECTION_TDNV_BIN _T("TDNVBin")
+#define CONFIG_SECTION_AP_BIN _T("APBin")
+#define CONFIG_SECTION_RAMDISK_BIN _T("RAMDiskBin")
+#define CONFIG_SECTION_PHY_FILES_INFO _T("AMT_PHY_FILES_INFO")
+#define CONFIG_SECTION_DOWNLOAD_IMAGE _T("DownloadImage")
+#define CONFIG_SECTION_NV_BACKUP _T("NVBackup")
+#define CONFIG_SECTION_INDEX_LIST _T("IndexList")
+#define CONFIG_SECTION_IN_SOFTVERSION _T("SoftVersionIn")
+#define CONFIG_SECTION_OUT_SOFTVERSION _T("SoftVersionOut")
+#define CONFIG_SECTION_SSID_FLAG _T("SSIDFlag")
+#define CONFIG_SECTION_SSID _T("SSID")
+
+#define CONFIG_SECTION_BUILD_DATE _T("BuildDate")
+#define CONFIG_SECTION_BUILD_TIME _T("BuildTime")
+#define CONFIG_SECTION_RALETIVEPATHBOOT _T("RaletivePathBOOT")
+#define CONFIG_SECTION_RALETIVEPATHAT _T("RaletivePathAT")
+#define CONFIG_SECTION_RALETIVEPATHATLC _T("RaletivePathATLC")
+#define CONFIG_SECTION_RALETIVEPATHLOG _T("RaletivePathLOG")
+#define CONFIG_SECTION_RALETIVEPATHFT _T("RaletivePathFT")
+#define CONFIG_KEY_VERSION _T("Version")
+#define CONFIG_KEY_FILE _T("File")
+#define CONFIG_KEY_STARTADDRESS _T("StartAddress")
+#define CONFIG_KEY_ENDADDRESS _T("EndAddress")
+#define CONFIG_KEY_TYPE _T("Type")
+#define CONFIG_KEY_DEBUGINFO _T("DebugInfo")
+#define CONFIG_KEY_OPENLOGPORT _T("IsOpenLogPort")
+#define CONFIG_KEY_NVBACKUPCOUNT _T("NVItemCount")
+#define CONFIG_KEY_TLFILE _T("TLFile")
+#define CONFIG_KEY_TLSTARTADDRESS _T("TLStartAddress")
+#define CONFIG_KEY_TDPSTARTADDRESS _T("TDPStartAddress")
+#define CONFIG_KEY_FLASHSTARTADDRESS _T("FlashStartAddress")
+#define CONFIG_KEY_COUNT _T("Count")
+#define CONFIG_KEY_MANUID _T("ManuID")
+#define CONFIG_KEY_DEVICEID _T("DeviceID")
+#define CONFIG_KEY_TDPPATH _T("TDPPath")
+#define CONFIG_KEY_RELATIVEPATH _T("UseRelativePath")
+#define CONFIG_KEY_READFROMFILE _T("ReadFromFile")
+#define CONFIG_KEY_FILESYSTEM _T("FileSystem")
+#define CONFIG_KEY_LENGTH _T("Length")
+#define CONFIG_KEY_BUILD_DATE _T("BuildDate")
+#define CONFIG_KEY_BUILD_TIME _T("BuildTime")
+#define CONFIG_KEY_SN_INDEX _T("SNIndex")
+// ....by wong
+#define CONFIG_KEY_HARDWARE_SN_INDEX _T("HARDWARE_SNIndex")
+#define CONFIG_KEY_IMEI_INDEX _T("IMEIIndex")
+#define CONFIG_KEY_WIFI_MAC_INDEX _T("WIFIIndex")
+#define CONFIG_KEY_RJ45_MAC_INDEX _T("RJ45MACIndex")
+#define CONFIG_KEY_TESTINFO_INDEX _T("TestInfoIndex")
+#define CONFIG_KEY_SN_BACKUP_INDEX _T("SNBackupIndex")
+#define CONFIG_KEY_IMEI_BACKUP_INDEX _T("IMEIBackupIndex")
+#define CONFIG_KEY_TESTINFO_BACKUP_INDEX _T("TestInfoBackupIndex")
+#define CONFIG_KEY_BBACKUPAREA _T("bBackupArea")
+#define CONFIG_KEY_RALETIVEPATH _T("RaletivePath")
+#define CONFIG_KEY_ATVERSION _T("AtVersion")
+#define CONFIG_KEY_TESTINFODOWNLOAD _T("TestInfoDLPV")
+
+//#define CONFIG_KET_ISBOOTROM _T("IsBootRom")
+#define CONFIG_KEY_USBORUARTPORT _T("USBORUARTPORT")
+#define CONFIG_KEY_BOOTSTAGE1FILE _T("BootStage1File") //add zxw 20130422 for 296301
+#define CONFIG_KEY_BOOTSTAGE1STARTADDRESS _T("BootStage1StartAddress")
+#define CONFIG_KEY_BOOTSTAGE2FILE _T("BootStage2File") //add zxw 20120422 for 296301
+#define CONFIG_KEY_BOOTSTAGE2STARTADDRESS _T("BootStage2StartAddress")
+#define CONFIG_KEY_PARTITIONFILE _T("PartitionFile") //add zxw 20120422 for 296301
+#define CONFIG_KEY_PARTITIONSTARTADDRESS _T("PartitionStartAddress")
+#define CONFIG_KEY_PARTITIONNAME _T("PartitionName")
+#define CONFIG_KEY_PARTITIONTYPE _T("PartitionType")
+#define CONFIG_KEY_STARTAMTCMD _T("StartAMTCMD")
+#define CONFIG_KEY_ISDOWNLOAD_PV _T("ISDownLoadPV")
+#define CONFIG_KEY_PHY_FILE_NUMS _T("FileNumber")
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// For CDownload
+#define BI_TSP_ERROR_BASE_CDownload (BI_TSP_ERROR_BASE_CTransmit + 10000)
+
+typedef enum
+{
+ TYPE_BOOT, // 从TYPE_BOOT到TYPE_TEST_AUTO
+ TYPE_BOOT_AUTO, // 属于老版本设计的思路,其初衷
+ TYPE_EVB_TEST, // 是按照EVB、FWP、DATACARD进行
+ TYPE_EVB_LOG, // 分类,根据配置界面(校准的脚本)
+ TYPE_FWP_TEST, // 设置对应的值,达到找到对应端口
+ TYPE_FWP_LOG, // 的目的。这种做法看似简单,但
+ TYPE_DATACARD_TEST, // 带来了维护方面的困难,因此,
+ TYPE_DATACARD_LOG, // 将采用新的方法进行兼容性过度
+ TYPE_TEST_AUTO,
+ TYPE_AT, // 过度的准则是:在配置文件中设置对应端口的匹配信息
+ TYPE_LOG, // 所有项目通过这对统一的入口与端口对接
+ TYPE_FT, // 打开FT的AT口
+ TYPE_BOOT_P93B, // P93B的Boot口
+ TYPE_AT_P93B, // P93B的AT口
+ TYPE_AT_LC,
+ TYPE_INVALID = 99,
+} enCOMTYPE;
+
+typedef enum
+{
+ TYPE_GPIB = 0,
+ TYPE_LAN,
+
+} enTransferType;
+
+typedef enum
+{
+ OFF_STATE =0,
+ ON_STATE,
+ ERR_STATE,
+
+} enBootFlag;
+// BOOT口列表
+#define TYPE_BOOT_LIST TYPE_BOOT, TYPE_BOOT_P93B
+// AT口列表
+#define TYPE_AT_LIST TYPE_EVB_TEST, TYPE_FWP_TEST, TYPE_DATACARD_TEST, TYPE_AT, TYPE_FT, TYPE_AT_P93B
+// LOT口列表
+#define TYPE_LOG_LIST TYPE_EVB_LOG, TYPE_FWP_LOG, TYPE_DATACARD_LOG
+
+typedef struct _COMSTRUCT
+{
+#pragma pack(1)
+ BYTE byByteSize;
+ BYTE byParity;
+ BYTE byStopBits;
+ DWORD dwBaudRate;
+ DWORD dwReadInterval;
+ DWORD dwTotalTime;
+#pragma pack()
+} COMSTRUCT;
+
+typedef struct
+{
+ int cmd;
+ unsigned char Msg[INFO_PACKET_LEN];
+}Msg_PACKET;
+
+// start =============================================================================================
+#define DLTYPE_CONTROL_BEGIN() \
+typedef enum{ \
+DLTYPE_OWNERSTATE_START = 0x00, \
+
+#define DLTYPE_CONTROL_END() \
+DLTYPE_OWNERSTATE_END = 0X11, \
+}enDLTYPE_CONTROL;
+// CDownload绑定状态位索引
+// 下载类型绑定状态位,enDownloadType高字合计2个字节空间,支持16个小bool位控制从BI传入BL
+// 如: 免PV的标志位IsNoPVDownLoad变量传入
+// 若已经使用某一位,则不可再复用
+
+#define STATEFLAG(x) (1<<x)
+
+DLTYPE_CONTROL_BEGIN() // start 在此内部添加[下载类型绑定状态位]传入BL
+ DLTYPE_OWNERSTATE_NONEPV = STATEFLAG(0), // 免PV控制开关
+ DLTYPE_OWNERSTATE_NONEPV_ERASEAUTO = STATEFLAG(1),
+ DLTYPE_OWNERSTATE_NONEPV_ERASEALL = STATEFLAG(2),
+ // TODO
+
+DLTYPE_CONTROL_END() // end
+// end =============================================================================================
+
+
+//CDownload
+typedef enum
+{
+ DOWNLOAD_TYPE_AMT,
+ DOWNLOAD_TYPE_AMT_MODEM, //modem 小系统
+ DOWNLOAD_TYPE_AMT_AP, // AP小系统
+ DOWNLOAD_TYPE_IMAGE, // 版本文件
+ DOWNLOAD_TYPE_NV_IMAGE, // NV镜像文件
+ DOWNLOAD_TYPE_NV, // NV 备份文件
+ DOWNLOAD_TYPE_SN, // SN文件
+ DOWNLOAD_TYPE_IMEI, // IMEI文件
+ DOWNLOAD_TYPE_TESTINFO, // TESTINFO文件
+ DOWNLOAD_TYPE_SN_BACKUP, // SN Backup文件
+ DOWNLOAD_TYPE_IMEI_BACKUP, // IMEI Backup文件
+ DOWNLOAD_TYPE_TESTINFO_BACKUP, // TESTINFO Backup文件
+ DOWNLOAD_TYPE_IN_SOFTVERSION, // SoftVersion文件
+ DOWNLOAD_TYPE_MAC_WIFI,
+ DOWNLOAD_TYPE_SSID_FLAG,
+ DOWNLOAD_TYPE_SSID,
+ DOWNLOAD_TYPE_FS_FLAG,
+ DOWNLOAD_TYPE_OUT_SOFTVERSION, // SoftVersion文件
+ DOWNLOAD_TYPE_HARDWARE_SN, // HARDWARE_SN 下载硬件版本号
+ DOWNLOAD_TYPE_TESTINFO_DL_PV, // 下载PV版本的生产测试标志位
+ DOWNLOAD_TYPE_TESTINFO_DL_RELEASE, // 下载发货版本的生产测试标志位
+ DOWNLOAD_TYPE_TESTINFO_DL_AMT, // 下载AMT版本的生产测试标志位
+ DOWNLOAD_TYPE_MAC_RJ45,
+} enDownloadType;
+
+typedef enum
+{
+ METHOD_NORMAL, // 只备份工作区
+ METHOD_WORK_BACKUP, // 根据标志位,备份工作区、备份区
+ METHOD_WRITE_TO_FILE, // 备份时,若板号不为空,则将NV数据写入文件
+} enDownloadNVBackupMethod;
+
+// 待下载镜像文件信息 CDownload
+typedef struct
+{
+ BOOL bDownload; // 上/下载功能标志,TRUE = 下载;FALSE = 上载
+ char * strFileName; // 文件路径
+ BOOL bUseRelativePath; // 文件路径是否为相对路径;TRUE = 相对路径;FALSE = 绝对路径
+ BOOL bReadFromFile; // 下载时,是否直接从文件读取;TRUE = 数据取自文件;FALSE = 数据取自内存
+ // BOOL bFileSystem; // 镜像文件是否为文件系统;TRUE = 文件系统文件;FALSE = 非文件系统文件
+ BOOL bAutoDeleteImageCache; // 是否自动回收镜像缓存
+ BYTE *pImageCache; // 镜像缓存
+ // DWORD dwStartAddress; // 下载/上载绝对起始地址
+
+ DWORD dwOffset; // 相对于文件/缓存的偏移
+ DWORD dwLength; // 下载/上载数据长度
+ int nType; // 下载类型
+ char PartitionName[16]; //分区名 add zxw 20130422
+ char FileName[16];
+ char PartitionType[16] ;
+ DWORD nPartitionOffset;
+ //新增文件的CRC校验值
+ ULONG ulCRCValue;
+
+} stFileItem;
+
+// NV备份信息
+typedef struct
+{
+ enDownloadType nType; // NV备份的类型
+ BYTE *pBuffer; // NV备份的缓存
+ DWORD dwStartAddress;// NV备份的下载地址
+ DWORD dwLength; // NV备份的长度
+} stNVItem;
+
+typedef struct
+{
+ unsigned long dwResult;
+} stResult;
+
+//////////////////////////////////////////////////////////////////////////
+typedef unsigned int UINT32;
+typedef signed int SINT32;
+typedef unsigned short UINT16;
+typedef signed short SINT16;
+
+// 分区表相关的信息
+#define MAX_ENTRY 16
+
+// add cxh 7510 下载分区文件类型
+#define nand (0x01)
+#define fs (0x02)
+//#define NV (0x03)
+#define zftl (0x03)
+#define ddr (0x04)
+#define raw (0x05)
+#define zloader (0x06)
+
+// 合并BIN文件中Masterhead结构
+typedef struct
+{
+ BYTE FileId[16];
+ BYTE chVersionIN[32];
+ BYTE chVersionOUT[32];
+ DWORD nTotalFileNum;
+ DWORD nFlashType;
+ DWORD nNVCoalition;
+ DWORD iFileSize;
+ DWORD iCkeckSum;
+ DWORD iImageStructOffset;
+ DWORD tloaderOffset;
+ DWORD tloaderLength;
+ DWORD tBootOffset;
+ DWORD tBootLength;
+ DWORD PartitionOffset;
+ DWORD PartitionLength;
+ BYTE UnUsed[80]; //预留区
+}stBinMasterInfo;
+
+
+typedef struct
+{
+ BYTE PartitionName[16];
+ BYTE PartitionType[16];
+ unsigned int PartitionSize;
+ unsigned int PartitionOffset;
+}partition_entry;
+
+typedef struct
+{
+ unsigned int iPartitionMagic;
+ BYTE PlatformName[16];
+ unsigned int iPartitionVersion; /* 分区版本 */
+ unsigned int iPartitionEntrys; /* 总的分区个数 */
+ unsigned int iPartitionCrc;
+ partition_entry PartitionTable[MAX_ENTRY];
+}partition_table;
+
+
+// 合并BIN文件的文件头部信息 CDownload
+typedef struct
+{
+ BYTE nTotalFileNum; // BIN文件中包含的子文件总数量
+ BYTE UnUsed[15]; // 未使用
+} stBinInfo;
+
+// 合并BIN文件的每个文件信息 CDownload
+typedef struct
+{
+ DWORD dwOffset; // 子文件相对于BIN文件起始的偏移
+ DWORD dwLength; // 子文件长度
+ DWORD dwStartAddress; // 子文件待下载的绝对地址
+ DWORD nType; // 子文件的类型
+ BYTE bFileSystem; // 子文件的文件系统标志
+
+} stBinFileHeader;
+
+typedef struct
+{
+ BYTE FileName[64];
+ BYTE PartitionName[16];
+ BYTE PartitionType[16];
+ unsigned int iFileLength;
+ unsigned int iPartitionOffset;
+ unsigned int iFileOffset; // 子文件相对于BIN文件起始的偏移
+ //相对于分区起始地址的偏移
+ BYTE UnUsed[20];
+}stBinImageHead;
+
+typedef enum
+{
+ HDT_W_MAIN = 0,
+ HDT_W_ASSIST,
+ HDT_W_MAANDAS,
+}E_HDT_WAGCTYPE;
+
+typedef struct
+{
+ int iErrorCode;
+ char cBarcode[21];
+} stDLDBInfo;
+
+typedef enum
+{
+ STAT_SYNC, // 0
+ STAT_START_BYTE, // 1
+ STAT_NO_MODIFY_REG, // 2
+ STAT_ADDRESS, // 3
+ STAT_DATA_LEN, // 4
+ STAT_DATAPACKET, // 5
+ STAT_LINK_EST, // 6
+ STAT_DEVICEINFO, // 7
+ STAT_CONFIGTDP, // 8
+ STAT_PROG_DEV_ST_ADDR, // 9
+ STAT_PROG_DEV_END_ADDR, // 10
+ STAT_SET_PACKET_SIZE, // 11
+ STAT_CHANGE_CONFIG, // 12
+ STAT_ERASE_SEG_ST_ADDR, // 13
+ STAT_ERASE_SEG_END_ADDR, // 14
+ STAT_DEV_BASE_ADDR, // 15
+ STAT_EXECUTE_CODE, // 16
+ STAT_TERMINATE, // 17
+ STAT_RVRS_DWNLD, // 18
+ STAT_UPLD_DATA_SIZE, // 19
+ STAT_SUCCESS, // 20
+ STAT_CRC_ON,
+ STAT_CRC_OFF,
+ // New stat add code here
+} enSTAT;
+
+
+//Bootrom & TLoader公用下载协议
+#define CMD_SYNC_BYTE_BOOTROM 0x5A
+#define CMD_SYNC_BYTE_ACK_BOOTROM 0xA5
+#define CMD_SEND_REG_CONFIG_BOOTROM 0x6A
+#define CMD_SEND_DATA_BOOTROM 0x7A
+#define CMD_STARTUP_BOOTROM 0x8A
+
+//7520V2 bootrom&TLoader新增回复命令
+#define CMD_SEND_ADDRESS_LEN_ACK_BOOTROM 0xA1
+#define CMD_SEND_DATA_ACK_BOOTROM 0xA7
+#define CMD_STARTUP_ACK_BOOTROM 0xA8
+
+
+//TBoot运行同步协议
+#define CMD_SYNC_TBOOT 0x5A
+#define CMD_SYNC_ACK_TBOOT 0xA7
+
+#define PACKET_SIZE_BOOT 131072
+//#define PACKET_SIZE_BOOT 131072
+
+#define PACKET_SIZE_TL 1024
+#define PACKET_SIZE_TDP 4096
+
+#define PACKET_SIZE_FLASH 4096
+
+//#define PACKET_SIZE_FLASH 2097152
+#define PACKET_SIZE_IMAGE 131072
+#define PACKET_SIZE_FILESYSTEM 135168
+
+//partiiton协议
+typedef enum
+{ // STAT_TBOOT_OK,
+ STAT_SYNC_PARTIITON,
+ STAT_SET_PARTITION_CMD,
+ STAT_SEND_PARTIITON,
+ STAT_EXIT,
+
+}enParpSTAT;
+
+typedef struct
+{
+ enSTAT mNextTRUE;
+ enSTAT mNextFALSE;
+} stSTAT;
+
+typedef struct DownloadConfig
+{
+ enSTAT mStartState;
+ BOOL mbExecuteCode; //下载后,是否启动运行,暂时无用 zxw 20130422
+ stFileItem mCurrentFile;
+ DWORD mPacketSize; //数据包大小,新方案由UE侧上传,暂无用处 zxw 20130422 //这个还是有用的,大小不超过2M就可以
+} stDownloadConfig;
+
+// 执行擦除NVRW
+BOOL ExecuteEraseNVRW(const char *softwarepath);
+// 下载boot和tloader
+BOOL DoDownloadBootForDL(BOOL bCheckPartition, const char *softwarepath);
+// 下载主流程
+int PrimaryDoDownload(const char *softwarepath);
+
+#endif
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