#include "Ymodem.h"
static int PACKET_SLEEP_TIME = 0; //us
CDataPackage::CDataPackage(char* lpFile, DWORD dwSizeOfPerPackage)
{
m_dwSizeOfPerPackage = 0;
m_iIndexOfPackage = 1;
m_iTotalCountOfPackage = 0;
m_pFileMemory = NULL;
m_dwSize = 0;
FILE *m_hFile = fopen(lpFile, "rb");
if (NULL == m_hFile)
{
perror("fopen");
printf("Open file %s fail.\n", lpFile);
}
else
{
fseek(m_hFile,0,SEEK_END);
m_dwSize = ftell(m_hFile);
if (m_dwSize != -1)
{
m_pFileMemory = (LPBYTE)malloc(m_dwSize+1);
if (m_pFileMemory != NULL)
{
memset(m_pFileMemory,0,m_dwSize+1);
fseek(m_hFile,0,SEEK_SET);
if (0 == fread(m_pFileMemory, m_dwSize, 1, m_hFile))
{
printf("Read file %s fail\n", lpFile);
}
else
{
m_iTotalCountOfPackage = (m_dwSize%dwSizeOfPerPackage) ? (m_dwSize/dwSizeOfPerPackage+1) : (m_dwSize/dwSizeOfPerPackage);
m_dwSizeOfPerPackage = dwSizeOfPerPackage;
printf("Read file %s OK. size[%d] pack[%d]\n", lpFile, m_dwSize, m_iTotalCountOfPackage);
}
}
}
else
{
printf("Get file %s size fail\n", lpFile);
}
fclose(m_hFile);
}
}
CDataPackage::~CDataPackage()
{
if (m_pFileMemory != NULL)
{
free(m_pFileMemory);
}
}
BOOL CDataPackage::GetPackage(int iIndexofPackage, char* pBuffer, LPDWORD pdwsize)
{
BOOL bret = FALSE;
LPBYTE pSrc = NULL;
pSrc = m_pFileMemory + (iIndexofPackage-1)*m_dwSizeOfPerPackage;
if (m_pFileMemory != NULL && pSrc != NULL)
{
if (iIndexofPackage == m_iTotalCountOfPackage) //the last package
{
*pdwsize = m_dwSize - (m_iTotalCountOfPackage-1)*m_dwSizeOfPerPackage;
}
else
{
*pdwsize = m_dwSizeOfPerPackage;
}
if (*pdwsize > 0)
{
memcpy(pBuffer, pSrc, *pdwsize);
m_iIndexOfPackage = iIndexofPackage;
bret = TRUE;
}
}
return bret;
}
BOOL CDataPackage::IsLastPackage()
{
return (m_iIndexOfPackage == m_iTotalCountOfPackage);
}
DWORD CDataPackage::GetFileSize()
{
return m_dwSize;
}
CYmodemProtocol::CYmodemProtocol(CSerialPort *pSerial, char* lpFile, int iTimeElapse)
{
m_pDatapackage = NULL;
m_pSerialport = pSerial;
{
m_pDatapackage = new CDataPackage(lpFile, PACKET_1K_SIZE);
printf("[CYmodemProtocol::CYmodemProtocol][113] mcu_bin_path is %s\n", lpFile);
string cspath(lpFile);
int pos = cspath.rfind('/');
const char* ptch = cspath.c_str() + pos + 1;
strcpy(m_csFileName,ptch);
printf("[CYmodemProtocol::CYmodemProtocol][118]mcu_bin_file name is %s\n", m_csFileName);
memset(m_package, 0, SEND_PACKET_SIZE);
PACKET_SLEEP_TIME = iTimeElapse*1000;//ms-->us
printf("PACKET_SLEEP_TIME = %d us\n", PACKET_SLEEP_TIME);
}
}
CYmodemProtocol::~CYmodemProtocol()
{
if (m_pDatapackage != NULL)
{
delete m_pDatapackage;
}
}
void CYmodemProtocol::SetSerialPort(CSerialPort *pSerial)
{
m_pSerialport = pSerial;
}
BOOL CYmodemProtocol::StartProtocol(BOOL bNeedSendUpdateCmd)
{
BOOL bret = TRUE;
if (m_pSerialport != NULL && m_pDatapackage != NULL && m_pDatapackage->GetFileSize())
{
bret = ProtocolProcess(bNeedSendUpdateCmd);
}
else
bret = FALSE;
return bret;
}
void CYmodemProtocol::ConstuctSOHPackage(LPDWORD packsize)
{
memset(m_package, 0, SEND_PACKET_SIZE);
m_package[0] = SOH;
m_package[1] = 0x00;
m_package[2] = 0xFF;
//SOH : 01 00 FF (file name) 00 (file size)........CRC_H CRC_L
//total 133 bytes
int nByte = strlen(m_csFileName);
strcpy(m_package+PACKET_HEADER,m_csFileName);
snprintf(m_package+PACKET_HEADER+nByte+1, SOH_PACKET_SIZE-nByte-1,"%d",m_pDatapackage->GetFileSize());
U16 crc = CRC16(m_package+PACKET_HEADER, SOH_PACKET_SIZE);
m_package[PACKET_HEADER+SOH_PACKET_SIZE+1] = crc;//lower bytes
m_package[PACKET_HEADER+SOH_PACKET_SIZE] = crc>>8;//high bytes
*packsize = SOH_TYPE_GROUP_SIZE;
printf("soh pack size %d, crc lower %02x;crc high %02x\n",*packsize, m_package[PACKET_HEADER+SOH_PACKET_SIZE+1],crc>>8);
}
void CYmodemProtocol::ConstructRealDataPackage(int iIndex,LPDWORD packsize)
{
memset(m_package, 0, SEND_PACKET_SIZE);
m_package[0] = STX;
BYTE sendIndex = (BYTE)iIndex;
if(iIndex >= 256)
{
sendIndex = iIndex - 256;
}
m_package[1] = sendIndex;
m_package[2] = 0xFF - sendIndex;
DWORD dwPacketSize;
m_pDatapackage->GetPackage(iIndex, m_package+PACKET_HEADER, &dwPacketSize);
if (dwPacketSize != STX_PACKET_SIZE)//not enough 1K,fill 0xFF into NULL buffer until enough
{
for (DWORD i=0 ; i<STX_PACKET_SIZE-dwPacketSize; i++)
{
m_package[PACKET_HEADER+dwPacketSize+i] = 0xFF;
}
}
U16 crc = CRC16(m_package+PACKET_HEADER,STX_PACKET_SIZE);
m_package[PACKET_HEADER + STX_PACKET_SIZE +1] = crc;
m_package[PACKET_HEADER + STX_PACKET_SIZE] = crc>>8;
*packsize = STX_TYPE_GROUP_SIZE;
}
void CYmodemProtocol::ConstructZeroPackage(LPDWORD packsize)
{
memset(m_package, 0, SEND_PACKET_SIZE);
m_package[0] = SOH;
m_package[1] = 0x00;
m_package[2] = 0xFF;
*packsize = SOH_TYPE_GROUP_SIZE;
}
BOOL CYmodemProtocol::SendPackage(DWORD packagesize, int OnePackSize)
{
//OnePackSize = 133 bytes or 1029 bytes
//when SOH pack ,OnePackSize=133 bytes;when real data ,OnePackSize=1029 bytes
BOOL bret = FALSE;
int iCount = packagesize/OnePackSize;
//printf("[SendPackage][iCount:%d]\n",iCount);
for (int i=0; i<iCount;i++)
{
bret = m_pSerialport->SendData(m_package+(i*OnePackSize), OnePackSize);
//usleep(PACKET_SLEEP_TIME);//
}
if(iCount > 1) //for last package
{
bret = m_pSerialport->SendData(m_package+iCount*OnePackSize, packagesize-(iCount*OnePackSize));
//usleep(PACKET_SLEEP_TIME);
}
return bret;
}
BOOL CYmodemProtocol::SendSOHPackage()
{
DWORD sohsize;
ConstuctSOHPackage(&sohsize);
printf("[Send SOH pack]\n");
SendPackage(sohsize, SOH_TYPE_GROUP_SIZE);
usleep(2000);
return 1;
}
BOOL CYmodemProtocol::SendEOTPackage()
{
char pack = EOT;
printf("[Send EOT pack]\n");
return m_pSerialport->SendData(&pack, 1);
}
BOOL CYmodemProtocol::SendZeroPackage()
{
DWORD zerosize;
ConstructZeroPackage(&zerosize);
printf("[Send Zero pack]\n");
SendPackage(zerosize, SOH_TYPE_GROUP_SIZE);
usleep(2000);
return 1;
}
BOOL CYmodemProtocol::SendRealDataPackage(int iIndex)
{
DWORD dwPackSize;
ConstructRealDataPackage(iIndex, &dwPackSize);//dwPackSize = 1029 bytes
printf("Send Real Data.\n");
SendPackage(dwPackSize,STX_TYPE_GROUP_SIZE);
usleep(PACKET_SLEEP_TIME);
return 1;
}
BOOL CYmodemProtocol::SendUpdateCmdPackage()
{
char UpdateCmd[11]={0};
UpdateCmd[0] = 'H';
UpdateCmd[1] = 'S';
UpdateCmd[2] = 0x01;
UpdateCmd[3] = 0x00;
UpdateCmd[4] = 0x01;
UpdateCmd[5] = 0x01;
UpdateCmd[6] = 0x04;
UpdateCmd[7] = 0x0B;
UpdateCmd[8] = 0x00;
UpdateCmd[9] = CalculateXOR((unsigned char*)UpdateCmd, 9);
printf("[CYmodemProtocol::SendUpdateCmdPackage] crc=0x%01x\n", UpdateCmd[9]);
m_pSerialport->SendData(UpdateCmd, 10);
usleep(1000);
return TRUE;
}
BOOL CYmodemProtocol::ProtocolProcess(BOOL bNeedSendUpdateCmd)
{
char readbyte[11] = {0xFF};
int len = 0;
int iIndexOfPackage = 0;
BOOL isZeroSended = FALSE, isEOTSended = FALSE;
int total = m_pDatapackage->GetTotalCountOfPackage();
//printf("[CYmodemProtocol::ProtocolProcess][324] bNeedSendUpdateCmd %d\n", bNeedSendUpdateCmd);
if(bNeedSendUpdateCmd)
{
SendUpdateCmdPackage();
}
int time_out_count=0;
for ( ; ; )
{
len = m_pSerialport->RecvData(readbyte, 10);
if(0 == len)
{
if (time_out_count < 5)//continuous count of time_out is < 5
{
printf("Recv data from MCU time out and count of time_out < 10(50s).so continue to recv.\n");
time_out_count++;
continue;
}
else//continuous count of time_out is >5
{
printf("continuous count of time_out is >5 .update fail.................\n");
return FALSE;
}
}
else if(len > 0)
{
if (time_out_count > 0)
{
time_out_count--;
}
}
else
{
printf("[CYmodemProtocol::ProtocolProcess]recv data len = -1, read byte :%02x,continue to recv.\n",readbyte[0]);
continue;
}
printf("[CYmodemProtocol::ProtocolProcess]recv data\n");
for (in
评论1
最新资源