[Feature][ZXW-33]merge ZXW 0428 version

Change-Id: I11f167edfea428d9fab198ff00ff1364932d1b0b
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;
+}