[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;
+}