266 lines
6.5 KiB
C++
266 lines
6.5 KiB
C++
#include "YmodemFileReceive.h"
|
|
#include <iostream>
|
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
|
#include <boost/thread/thread.hpp>
|
|
#include <boost/bind.hpp>
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <boost/algorithm/string/split.hpp>
|
|
#include <boost/log/trivial.hpp>
|
|
#include "TimeoutSerial.h"
|
|
|
|
using namespace std;
|
|
using namespace boost;
|
|
|
|
#define READ_TIME_OUT (10)
|
|
#define WRITE_TIME_OUT (100)
|
|
|
|
YmodemFileReceive::YmodemFileReceive() :
|
|
io(), readTimer(io), writeTimer(io)
|
|
{
|
|
setTimeDivide(499);
|
|
setTimeMax(5);
|
|
setErrorMax(999);
|
|
|
|
}
|
|
|
|
YmodemFileReceive::~YmodemFileReceive()
|
|
{
|
|
// delete file;
|
|
// delete readTimer;
|
|
// delete writeTimer;
|
|
// delete serialPort;
|
|
}
|
|
|
|
void YmodemFileReceive::setFilePath(const string &path)
|
|
{
|
|
filePath = path + "/";
|
|
}
|
|
|
|
void YmodemFileReceive::setDefaultFileName(const string &file)
|
|
{
|
|
defaultFileName = file;
|
|
}
|
|
|
|
void YmodemFileReceive::setSerialPort(TimeoutSerial *port)
|
|
{
|
|
serialPort = port;
|
|
}
|
|
|
|
TimeoutSerial *YmodemFileReceive::getSerialPort()
|
|
{
|
|
return serialPort;
|
|
}
|
|
|
|
bool YmodemFileReceive::startReceive()
|
|
{
|
|
progress = 0;
|
|
status = StatusEstablish;
|
|
|
|
BOOST_LOG_TRIVIAL(debug) << "Statring receive";
|
|
|
|
serialPort->setTimeout(posix_time::seconds(0));
|
|
readTimer.expires_from_now(boost::posix_time::millisec(READ_TIME_OUT));
|
|
readTimer.async_wait(boost::bind(&YmodemFileReceive::readTimeOut,this,_1));
|
|
io.run();
|
|
|
|
return true;
|
|
}
|
|
|
|
void YmodemFileReceive::stopReceive()
|
|
{
|
|
file.close();
|
|
abort();
|
|
status = StatusAbort;
|
|
}
|
|
|
|
int YmodemFileReceive::getReceiveProgress()
|
|
{
|
|
return progress;
|
|
}
|
|
|
|
Ymodem::Status YmodemFileReceive::getReceiveStatus()
|
|
{
|
|
return status;
|
|
}
|
|
|
|
|
|
void YmodemFileReceive::readTimeOut(const boost::system::error_code& e)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "Read timeout";
|
|
|
|
|
|
receive();
|
|
|
|
BOOST_LOG_TRIVIAL(debug) << "Status: " << status;
|
|
|
|
if((status == StatusEstablish) || (status == StatusTransmit))
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "Set read timer ";
|
|
|
|
readTimer.expires_from_now(boost::posix_time::millisec(READ_TIME_OUT));
|
|
readTimer.async_wait(boost::bind(&YmodemFileReceive::readTimeOut,this,_1));
|
|
}
|
|
}
|
|
|
|
void YmodemFileReceive::writeTimeOut(const boost::system::error_code& e)
|
|
{
|
|
// writeTimer.cancel();
|
|
//serialPort->close();
|
|
// receiveStatus(status);
|
|
}
|
|
|
|
Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
|
|
{
|
|
BOOST_LOG_TRIVIAL(debug) << "Callback status: " << status;
|
|
|
|
switch(status)
|
|
{
|
|
case StatusEstablish:
|
|
{
|
|
if(buff[0] != 0)
|
|
{
|
|
int i = 0;
|
|
char name[128] = {0};
|
|
char size[128] = {0};
|
|
|
|
for(int j = 0; buff[i] != 0; i++, j++)
|
|
{
|
|
name[j] = buff[i];
|
|
}
|
|
|
|
i++;
|
|
|
|
for(int j = 0; buff[i] != 0; i++, j++)
|
|
{
|
|
size[j] = buff[i];
|
|
}
|
|
|
|
if (defaultFileName != "") {
|
|
fileName = defaultFileName;
|
|
} else {
|
|
fileName = name;
|
|
}
|
|
string file_desc(size);
|
|
string sizeStr = file_desc.substr(0,file_desc.find_first_of(' '));
|
|
fileSize = stol(sizeStr);
|
|
fileCount = 0;
|
|
|
|
|
|
BOOST_LOG_TRIVIAL(debug) << "File open: " << filePath + fileName << " Size:" << fileSize << " Original: " << name;
|
|
|
|
file.open(filePath + fileName, ios::out | ios::binary);
|
|
|
|
if(file.is_open() == true)
|
|
{
|
|
YmodemFileReceive::status = StatusEstablish;
|
|
|
|
receiveStatus(StatusEstablish);
|
|
|
|
return CodeAck;
|
|
}
|
|
else
|
|
{
|
|
YmodemFileReceive::status = StatusError;
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeCan;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
YmodemFileReceive::status = StatusError;
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeCan;
|
|
}
|
|
}
|
|
|
|
case StatusTransmit:
|
|
{
|
|
if((fileSize - fileCount) > *len)
|
|
{
|
|
file.write((char *)buff, *len);
|
|
|
|
fileCount += *len;
|
|
}
|
|
else
|
|
{
|
|
file.write((char *)buff, fileSize - fileCount);
|
|
|
|
fileCount += fileSize - fileCount;
|
|
}
|
|
|
|
progress = (int)(fileCount * 100 / fileSize);
|
|
|
|
YmodemFileReceive::status = StatusTransmit;
|
|
|
|
receiveProgress(progress);
|
|
receiveStatus(StatusTransmit);
|
|
|
|
return CodeAck;
|
|
}
|
|
|
|
case StatusFinish:
|
|
{
|
|
file.close();
|
|
|
|
YmodemFileReceive::status = StatusFinish;
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeAck;
|
|
}
|
|
|
|
case StatusAbort:
|
|
{
|
|
file.close();
|
|
|
|
YmodemFileReceive::status = StatusAbort;
|
|
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeCan;
|
|
}
|
|
|
|
case StatusTimeout:
|
|
{
|
|
YmodemFileReceive::status = StatusTimeout;
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeCan;
|
|
}
|
|
|
|
default:
|
|
{
|
|
file.close();
|
|
|
|
YmodemFileReceive::status = StatusError;
|
|
|
|
writeTimer.expires_from_now(boost::posix_time::millisec(WRITE_TIME_OUT));
|
|
writeTimer.async_wait(boost::bind(&YmodemFileReceive::writeTimeOut,this,_1));
|
|
|
|
return CodeCan;
|
|
}
|
|
}
|
|
}
|
|
|
|
int32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
|
|
{
|
|
|
|
return serialPort->read((char *)buff, len);
|
|
}
|
|
|
|
int32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
|
|
{
|
|
return serialPort->write((char *)buff, len);
|
|
}
|