QT port
This commit is contained in:
@@ -4,7 +4,7 @@ project(TEST)
|
|||||||
|
|
||||||
## Target
|
## Target
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
set(TEST_SRCS main.cpp TimeoutSerial.cpp xymodem.cpp)
|
set(TEST_SRCS main.cpp TimeoutSerial.cpp Ymodem.cpp YmodemFileReceive.cpp)
|
||||||
add_definitions(-DBOOST_LOG_DYN_LINK)
|
add_definitions(-DBOOST_LOG_DYN_LINK)
|
||||||
add_executable(timeout ${TEST_SRCS})
|
add_executable(timeout ${TEST_SRCS})
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
|
|||||||
1
SerialPortYmodem
Submodule
1
SerialPortYmodem
Submodule
Submodule SerialPortYmodem added at dd5ce17f9f
44
Thread.h
44
Thread.h
@@ -1,44 +0,0 @@
|
|||||||
#ifndef THREAD_HH
|
|
||||||
#define THREAD_HH
|
|
||||||
|
|
||||||
#include <boost/thread.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class Thread {
|
|
||||||
private:
|
|
||||||
boost::thread* thread;
|
|
||||||
bool isRunning;
|
|
||||||
public:
|
|
||||||
// Ctor
|
|
||||||
Thread() : thread(NULL), isRunning(false) {
|
|
||||||
}
|
|
||||||
virtual ~Thread() {
|
|
||||||
kill();
|
|
||||||
}
|
|
||||||
|
|
||||||
void start() {
|
|
||||||
T* derived = dynamic_cast<T*>(this);
|
|
||||||
thread = new boost::thread(boost::bind(&Thread::doIt, this, boost::ref(*derived)));
|
|
||||||
}
|
|
||||||
void doIt(T& derived) {
|
|
||||||
}
|
|
||||||
bool isFinished() {
|
|
||||||
return isRunning;
|
|
||||||
}
|
|
||||||
void join() {
|
|
||||||
if(thread) {
|
|
||||||
thread->join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void kill() {
|
|
||||||
if(thread) {
|
|
||||||
thread->interrupt();
|
|
||||||
delete thread;
|
|
||||||
thread = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
1791
Ymodem.cpp
Normal file
1791
Ymodem.cpp
Normal file
File diff suppressed because it is too large
Load Diff
143
Ymodem.h
Normal file
143
Ymodem.h
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file Ymodem.h
|
||||||
|
* @author XinLi
|
||||||
|
* @version v1.0
|
||||||
|
* @date 21-January-2018
|
||||||
|
* @brief Header file for Ymodem.cpp module.
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
*
|
||||||
|
* <h2><center>Copyright © 2018 XinLi</center></h2>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __YMODEM_H
|
||||||
|
#define __YMODEM_H
|
||||||
|
|
||||||
|
/* Header includes -----------------------------------------------------------*/
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* Macro definitions ---------------------------------------------------------*/
|
||||||
|
#define YMODEM_PACKET_HEADER (3)
|
||||||
|
#define YMODEM_PACKET_TRAILER (2)
|
||||||
|
#define YMODEM_PACKET_OVERHEAD (YMODEM_PACKET_HEADER + YMODEM_PACKET_TRAILER)
|
||||||
|
#define YMODEM_PACKET_SIZE (128)
|
||||||
|
#define YMODEM_PACKET_1K_SIZE (1024)
|
||||||
|
|
||||||
|
#define YMODEM_CODE_CAN_NUMBER (5)
|
||||||
|
|
||||||
|
/* Type definitions ----------------------------------------------------------*/
|
||||||
|
class Ymodem
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Code
|
||||||
|
{
|
||||||
|
CodeNone = 0x00,
|
||||||
|
CodeSoh = 0x01,
|
||||||
|
CodeStx = 0x02,
|
||||||
|
CodeEot = 0x04,
|
||||||
|
CodeAck = 0x06,
|
||||||
|
CodeNak = 0x15,
|
||||||
|
CodeCan = 0x18,
|
||||||
|
CodeC = 0x43,
|
||||||
|
CodeA1 = 0x41,
|
||||||
|
CodeA2 = 0x61
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Stage
|
||||||
|
{
|
||||||
|
StageNone,
|
||||||
|
StageEstablishing,
|
||||||
|
StageEstablished,
|
||||||
|
StageTransmitting,
|
||||||
|
StageFinishing,
|
||||||
|
StageFinished
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Status
|
||||||
|
{
|
||||||
|
StatusEstablish,
|
||||||
|
StatusTransmit,
|
||||||
|
StatusFinish,
|
||||||
|
StatusAbort,
|
||||||
|
StatusTimeout,
|
||||||
|
StatusError
|
||||||
|
};
|
||||||
|
|
||||||
|
Ymodem(uint32_t timeDivide = 499, uint32_t timeMax = 5, uint32_t errorMax = 999);
|
||||||
|
|
||||||
|
void setTimeDivide(uint32_t timeDivide);
|
||||||
|
uint32_t getTimeDivide();
|
||||||
|
|
||||||
|
void setTimeMax(uint32_t timeMax);
|
||||||
|
uint32_t getTimeMax();
|
||||||
|
|
||||||
|
void setErrorMax(uint32_t errorMax);
|
||||||
|
uint32_t getErrorMax();
|
||||||
|
|
||||||
|
void receive();
|
||||||
|
void transmit();
|
||||||
|
void abort();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Code receivePacket();
|
||||||
|
|
||||||
|
void receiveStageNone();
|
||||||
|
void receiveStageEstablishing();
|
||||||
|
void receiveStageEstablished();
|
||||||
|
void receiveStageTransmitting();
|
||||||
|
void receiveStageFinishing();
|
||||||
|
void receiveStageFinished();
|
||||||
|
|
||||||
|
void transmitStageNone();
|
||||||
|
void transmitStageEstablishing();
|
||||||
|
void transmitStageEstablished();
|
||||||
|
void transmitStageTransmitting();
|
||||||
|
void transmitStageFinishing();
|
||||||
|
void transmitStageFinished();
|
||||||
|
|
||||||
|
uint16_t crc16(uint8_t *buff, uint32_t len);
|
||||||
|
|
||||||
|
virtual Code callback(Status status, uint8_t *buff, uint32_t *len) = 0;
|
||||||
|
|
||||||
|
virtual uint32_t read(uint8_t *buff, uint32_t len) = 0;
|
||||||
|
virtual uint32_t write(uint8_t *buff, uint32_t len) = 0;
|
||||||
|
|
||||||
|
uint32_t timeDivide;
|
||||||
|
uint32_t timeMax;
|
||||||
|
uint32_t errorMax;
|
||||||
|
|
||||||
|
uint32_t timeCount;
|
||||||
|
uint32_t errorCount;
|
||||||
|
uint8_t dataCount;
|
||||||
|
|
||||||
|
Code code;
|
||||||
|
Stage stage;
|
||||||
|
|
||||||
|
uint8_t rxBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
|
||||||
|
uint8_t txBuffer[YMODEM_PACKET_1K_SIZE + YMODEM_PACKET_OVERHEAD];
|
||||||
|
uint32_t rxLength;
|
||||||
|
uint32_t txLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Variable declarations -----------------------------------------------------*/
|
||||||
|
/* Variable definitions ------------------------------------------------------*/
|
||||||
|
/* Function declarations -----------------------------------------------------*/
|
||||||
|
/* Function definitions ------------------------------------------------------*/
|
||||||
|
|
||||||
|
#endif /* __YMODEM_H */
|
||||||
231
YmodemFileReceive.cpp
Normal file
231
YmodemFileReceive.cpp
Normal file
@@ -0,0 +1,231 @@
|
|||||||
|
#include "YmodemFileReceive.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
#include <boost/thread/thread.hpp>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string.hpp>
|
||||||
|
#include <boost/algorithm/string/split.hpp>
|
||||||
|
#include "TimeoutSerial.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace boost;
|
||||||
|
|
||||||
|
#define READ_TIME_OUT (10)
|
||||||
|
#define WRITE_TIME_OUT (100)
|
||||||
|
|
||||||
|
YmodemFileReceive::YmodemFileReceive() :
|
||||||
|
{
|
||||||
|
setTimeDivide(499);
|
||||||
|
setTimeMax(5);
|
||||||
|
setErrorMax(999);
|
||||||
|
|
||||||
|
//connect(readTimer, SIGNAL(timeout()), this, SLOT(readTimeOut()));
|
||||||
|
//connect(writeTimer, SIGNAL(timeout()), this, SLOT(writeTimeOut()));
|
||||||
|
}
|
||||||
|
|
||||||
|
YmodemFileReceive::~YmodemFileReceive()
|
||||||
|
{
|
||||||
|
delete file;
|
||||||
|
delete readTimer;
|
||||||
|
delete writeTimer;
|
||||||
|
delete serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YmodemFileReceive::setFilePath(const string &path)
|
||||||
|
{
|
||||||
|
filePath = path + "/";
|
||||||
|
}
|
||||||
|
|
||||||
|
void YmodemFileReceive::setSerialPort(TimeoutSerial *port)
|
||||||
|
{
|
||||||
|
serialPort = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
TimeoutSerial *YmodemFileReceive::getSerialPort()
|
||||||
|
{
|
||||||
|
return serialPort;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool YmodemFileReceive::startReceive()
|
||||||
|
{
|
||||||
|
progress = 0;
|
||||||
|
status = StatusEstablish;
|
||||||
|
|
||||||
|
serialPort->setTimeout(posix_time::seconds(10));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void YmodemFileReceive::stopReceive()
|
||||||
|
{
|
||||||
|
file->close();
|
||||||
|
abort();
|
||||||
|
status = StatusAbort;
|
||||||
|
}
|
||||||
|
|
||||||
|
int YmodemFileReceive::getReceiveProgress()
|
||||||
|
{
|
||||||
|
return progress;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ymodem::Status YmodemFileReceive::getReceiveStatus()
|
||||||
|
{
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void YmodemFileReceive::readTimeOut()
|
||||||
|
{
|
||||||
|
readTimer->stop();
|
||||||
|
|
||||||
|
receive();
|
||||||
|
|
||||||
|
if((status == StatusEstablish) || (status == StatusTransmit))
|
||||||
|
{
|
||||||
|
readTimer->start(READ_TIME_OUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void YmodemFileReceive::writeTimeOut()
|
||||||
|
{
|
||||||
|
writeTimer->stop();
|
||||||
|
serialPort->close();
|
||||||
|
receiveStatus(status);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
Ymodem::Code YmodemFileReceive::callback(Status status, uint8_t *buff, uint32_t *len)
|
||||||
|
{
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = name;
|
||||||
|
string file_desc(size);
|
||||||
|
string sizeStr = file_desc.substr(0,file_desc.find_first_of(' '));
|
||||||
|
fileSize = stol(sizeStr);
|
||||||
|
fileCount = 0;
|
||||||
|
|
||||||
|
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->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
return CodeCan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
YmodemFileReceive::status = StatusError;
|
||||||
|
|
||||||
|
writeTimer->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
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->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
return CodeAck;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StatusAbort:
|
||||||
|
{
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
YmodemFileReceive::status = StatusAbort;
|
||||||
|
|
||||||
|
writeTimer->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
return CodeCan;
|
||||||
|
}
|
||||||
|
|
||||||
|
case StatusTimeout:
|
||||||
|
{
|
||||||
|
YmodemFileReceive::status = StatusTimeout;
|
||||||
|
|
||||||
|
writeTimer->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
return CodeCan;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
file->close();
|
||||||
|
|
||||||
|
YmodemFileReceive::status = StatusError;
|
||||||
|
|
||||||
|
writeTimer->start(WRITE_TIME_OUT);
|
||||||
|
|
||||||
|
return CodeCan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t YmodemFileReceive::read(uint8_t *buff, uint32_t len)
|
||||||
|
{
|
||||||
|
return serialPort->read((char *)buff, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t YmodemFileReceive::write(uint8_t *buff, uint32_t len)
|
||||||
|
{
|
||||||
|
return serialPort->write((char *)buff, len);
|
||||||
|
}
|
||||||
57
YmodemFileReceive.h
Normal file
57
YmodemFileReceive.h
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef YMODEMFILERECEIVE_H
|
||||||
|
#define YMODEMFILERECEIVE_H
|
||||||
|
|
||||||
|
#include "TimeoutSerial.h"
|
||||||
|
#include "Ymodem.h"
|
||||||
|
#include <boost/signals2.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
class YmodemFileReceive : public Ymodem
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit YmodemFileReceive();
|
||||||
|
~YmodemFileReceive();
|
||||||
|
|
||||||
|
void setFilePath(const string &path);
|
||||||
|
|
||||||
|
void setSerialPort(TimeoutSerial *port);
|
||||||
|
TimeoutSerial *getSerialPort();
|
||||||
|
|
||||||
|
bool startReceive();
|
||||||
|
void stopReceive();
|
||||||
|
|
||||||
|
int getReceiveProgress();
|
||||||
|
Status getReceiveStatus();
|
||||||
|
|
||||||
|
boost::signals2::signal<void (int)> receiveProgress;
|
||||||
|
boost::signals2::signal<void (YmodemFileReceive::Status status)> receiveStatus;
|
||||||
|
/*
|
||||||
|
private slots:
|
||||||
|
void readTimeOut();
|
||||||
|
void writeTimeOut();
|
||||||
|
*/
|
||||||
|
private:
|
||||||
|
Code callback(Status status, uint8_t *buff, uint32_t *len);
|
||||||
|
|
||||||
|
uint32_t read(uint8_t *buff, uint32_t len);
|
||||||
|
uint32_t write(uint8_t *buff, uint32_t len);
|
||||||
|
|
||||||
|
ofstream file;
|
||||||
|
QTimer *readTimer;
|
||||||
|
QTimer *writeTimer;
|
||||||
|
TimeoutSerial *serialPort;
|
||||||
|
|
||||||
|
int progress;
|
||||||
|
Status status;
|
||||||
|
string filePath;
|
||||||
|
string fileName;
|
||||||
|
uint64_t fileSize;
|
||||||
|
uint64_t fileCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // YMODEMFILERECEIVE_H
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
{
|
{
|
||||||
"directoryIndex" : 0,
|
"directoryIndex" : 0,
|
||||||
"id" : "timeout::@6890427a1f51a3e7e1df",
|
"id" : "timeout::@6890427a1f51a3e7e1df",
|
||||||
"jsonFile" : "target-timeout-Debug-85a0f71a1db986bd99c5.json",
|
"jsonFile" : "target-timeout-Debug-d7af418a1b6c2d259633.json",
|
||||||
"name" : "timeout",
|
"name" : "timeout",
|
||||||
"projectIndex" : 0
|
"projectIndex" : 0
|
||||||
}
|
}
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"objects" :
|
"objects" :
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"jsonFile" : "codemodel-v2-4167e22d1c847713af64.json",
|
"jsonFile" : "codemodel-v2-2f061e11e865d7291da7.json",
|
||||||
"kind" : "codemodel",
|
"kind" : "codemodel",
|
||||||
"version" :
|
"version" :
|
||||||
{
|
{
|
||||||
@@ -76,7 +76,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"jsonFile" : "codemodel-v2-4167e22d1c847713af64.json",
|
"jsonFile" : "codemodel-v2-2f061e11e865d7291da7.json",
|
||||||
"kind" : "codemodel",
|
"kind" : "codemodel",
|
||||||
"version" :
|
"version" :
|
||||||
{
|
{
|
||||||
@@ -99,7 +99,8 @@
|
|||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2
|
2,
|
||||||
|
3
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -182,7 +183,8 @@
|
|||||||
[
|
[
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
2
|
2,
|
||||||
|
3
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -203,7 +205,13 @@
|
|||||||
{
|
{
|
||||||
"backtrace" : 1,
|
"backtrace" : 1,
|
||||||
"compileGroupIndex" : 0,
|
"compileGroupIndex" : 0,
|
||||||
"path" : "xymodem.cpp",
|
"path" : "Ymodem.cpp",
|
||||||
|
"sourceGroupIndex" : 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"backtrace" : 1,
|
||||||
|
"compileGroupIndex" : 0,
|
||||||
|
"path" : "YmodemFileReceive.cpp",
|
||||||
"sourceGroupIndex" : 0
|
"sourceGroupIndex" : 0
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -150,6 +150,60 @@ TimeoutSerial.cpp.s:
|
|||||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.s
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/TimeoutSerial.cpp.s
|
||||||
.PHONY : TimeoutSerial.cpp.s
|
.PHONY : TimeoutSerial.cpp.s
|
||||||
|
|
||||||
|
Ymodem.o: Ymodem.cpp.o
|
||||||
|
|
||||||
|
.PHONY : Ymodem.o
|
||||||
|
|
||||||
|
# target to build an object file
|
||||||
|
Ymodem.cpp.o:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/Ymodem.cpp.o
|
||||||
|
.PHONY : Ymodem.cpp.o
|
||||||
|
|
||||||
|
Ymodem.i: Ymodem.cpp.i
|
||||||
|
|
||||||
|
.PHONY : Ymodem.i
|
||||||
|
|
||||||
|
# target to preprocess a source file
|
||||||
|
Ymodem.cpp.i:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/Ymodem.cpp.i
|
||||||
|
.PHONY : Ymodem.cpp.i
|
||||||
|
|
||||||
|
Ymodem.s: Ymodem.cpp.s
|
||||||
|
|
||||||
|
.PHONY : Ymodem.s
|
||||||
|
|
||||||
|
# target to generate assembly for a file
|
||||||
|
Ymodem.cpp.s:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/Ymodem.cpp.s
|
||||||
|
.PHONY : Ymodem.cpp.s
|
||||||
|
|
||||||
|
YmodemFileReceive.o: YmodemFileReceive.cpp.o
|
||||||
|
|
||||||
|
.PHONY : YmodemFileReceive.o
|
||||||
|
|
||||||
|
# target to build an object file
|
||||||
|
YmodemFileReceive.cpp.o:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/YmodemFileReceive.cpp.o
|
||||||
|
.PHONY : YmodemFileReceive.cpp.o
|
||||||
|
|
||||||
|
YmodemFileReceive.i: YmodemFileReceive.cpp.i
|
||||||
|
|
||||||
|
.PHONY : YmodemFileReceive.i
|
||||||
|
|
||||||
|
# target to preprocess a source file
|
||||||
|
YmodemFileReceive.cpp.i:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/YmodemFileReceive.cpp.i
|
||||||
|
.PHONY : YmodemFileReceive.cpp.i
|
||||||
|
|
||||||
|
YmodemFileReceive.s: YmodemFileReceive.cpp.s
|
||||||
|
|
||||||
|
.PHONY : YmodemFileReceive.s
|
||||||
|
|
||||||
|
# target to generate assembly for a file
|
||||||
|
YmodemFileReceive.cpp.s:
|
||||||
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/YmodemFileReceive.cpp.s
|
||||||
|
.PHONY : YmodemFileReceive.cpp.s
|
||||||
|
|
||||||
main.o: main.cpp.o
|
main.o: main.cpp.o
|
||||||
|
|
||||||
.PHONY : main.o
|
.PHONY : main.o
|
||||||
@@ -177,33 +231,6 @@ main.cpp.s:
|
|||||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/main.cpp.s
|
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/main.cpp.s
|
||||||
.PHONY : main.cpp.s
|
.PHONY : main.cpp.s
|
||||||
|
|
||||||
xymodem.o: xymodem.cpp.o
|
|
||||||
|
|
||||||
.PHONY : xymodem.o
|
|
||||||
|
|
||||||
# target to build an object file
|
|
||||||
xymodem.cpp.o:
|
|
||||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/xymodem.cpp.o
|
|
||||||
.PHONY : xymodem.cpp.o
|
|
||||||
|
|
||||||
xymodem.i: xymodem.cpp.i
|
|
||||||
|
|
||||||
.PHONY : xymodem.i
|
|
||||||
|
|
||||||
# target to preprocess a source file
|
|
||||||
xymodem.cpp.i:
|
|
||||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/xymodem.cpp.i
|
|
||||||
.PHONY : xymodem.cpp.i
|
|
||||||
|
|
||||||
xymodem.s: xymodem.cpp.s
|
|
||||||
|
|
||||||
.PHONY : xymodem.s
|
|
||||||
|
|
||||||
# target to generate assembly for a file
|
|
||||||
xymodem.cpp.s:
|
|
||||||
$(MAKE) -f CMakeFiles/timeout.dir/build.make CMakeFiles/timeout.dir/xymodem.cpp.s
|
|
||||||
.PHONY : xymodem.cpp.s
|
|
||||||
|
|
||||||
# Help Target
|
# Help Target
|
||||||
help:
|
help:
|
||||||
@echo "The following are some of the valid targets for this Makefile:"
|
@echo "The following are some of the valid targets for this Makefile:"
|
||||||
@@ -216,12 +243,15 @@ help:
|
|||||||
@echo "... TimeoutSerial.o"
|
@echo "... TimeoutSerial.o"
|
||||||
@echo "... TimeoutSerial.i"
|
@echo "... TimeoutSerial.i"
|
||||||
@echo "... TimeoutSerial.s"
|
@echo "... TimeoutSerial.s"
|
||||||
|
@echo "... Ymodem.o"
|
||||||
|
@echo "... Ymodem.i"
|
||||||
|
@echo "... Ymodem.s"
|
||||||
|
@echo "... YmodemFileReceive.o"
|
||||||
|
@echo "... YmodemFileReceive.i"
|
||||||
|
@echo "... YmodemFileReceive.s"
|
||||||
@echo "... main.o"
|
@echo "... main.o"
|
||||||
@echo "... main.i"
|
@echo "... main.i"
|
||||||
@echo "... main.s"
|
@echo "... main.s"
|
||||||
@echo "... xymodem.o"
|
|
||||||
@echo "... xymodem.i"
|
|
||||||
@echo "... xymodem.s"
|
|
||||||
.PHONY : help
|
.PHONY : help
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,12 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"directory": "/home/jaro/serialport-downloader/build",
|
"directory": "/home/jaro/serialport-downloader/build",
|
||||||
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_CHRONO_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_LOG_DYN_LINK -DBOOST_REGEX_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/xymodem.cpp.o -c /home/jaro/serialport-downloader/xymodem.cpp",
|
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_CHRONO_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_LOG_DYN_LINK -DBOOST_REGEX_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/Ymodem.cpp.o -c /home/jaro/serialport-downloader/Ymodem.cpp",
|
||||||
"file": "/home/jaro/serialport-downloader/xymodem.cpp"
|
"file": "/home/jaro/serialport-downloader/Ymodem.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "/home/jaro/serialport-downloader/build",
|
||||||
|
"command": "/bin/c++ -DBOOST_ALL_NO_LIB -DBOOST_ATOMIC_DYN_LINK -DBOOST_CHRONO_DYN_LINK -DBOOST_DATE_TIME_DYN_LINK -DBOOST_FILESYSTEM_DYN_LINK -DBOOST_LOG_DYN_LINK -DBOOST_REGEX_DYN_LINK -DBOOST_SYSTEM_DYN_LINK -DBOOST_THREAD_DYN_LINK -g -std=gnu++11 -o CMakeFiles/timeout.dir/YmodemFileReceive.cpp.o -c /home/jaro/serialport-downloader/YmodemFileReceive.cpp",
|
||||||
|
"file": "/home/jaro/serialport-downloader/YmodemFileReceive.cpp"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
585
xymodem.cpp
585
xymodem.cpp
@@ -1,585 +0,0 @@
|
|||||||
/*
|
|
||||||
* xymodem file transferts
|
|
||||||
*
|
|
||||||
* (C) Copyright 2011 Angelo Dureghello <angelo70@gmail.com>
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License as
|
|
||||||
* published by the Free Software Foundation; either version 2 of
|
|
||||||
* the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
||||||
* MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <boost/utility.hpp>
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <boost/algorithm/string/split.hpp>
|
|
||||||
#include <boost/log/trivial.hpp>
|
|
||||||
#include <boost/thread/future.hpp>
|
|
||||||
#include "xymodem.h"
|
|
||||||
#include "Thread.h"
|
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace boost;
|
|
||||||
|
|
||||||
static const unsigned char ZPAD = 0x2a;
|
|
||||||
static const unsigned char ZDLE = 0x18;
|
|
||||||
static const unsigned char ZBIN = 0x41;
|
|
||||||
static const unsigned char ZHEX = 0x42;
|
|
||||||
static const unsigned char XON = 0x11;
|
|
||||||
|
|
||||||
static const unsigned char ZMABORT[] = {ZDLE,ZDLE,ZDLE,ZDLE,ZDLE};
|
|
||||||
|
|
||||||
static const unsigned char ESC_HEXHDR[] = {ZPAD,ZPAD,ZDLE,ZHEX};
|
|
||||||
static const unsigned char ZRQINIT[] = "0000000000195E";
|
|
||||||
static const unsigned char ZTERM[]= {0x0d,0x0a,XON};
|
|
||||||
|
|
||||||
|
|
||||||
class __tools {
|
|
||||||
public:
|
|
||||||
__tools () {}
|
|
||||||
|
|
||||||
public:
|
|
||||||
unsigned short crc16_ccitt( char *buf, int len )
|
|
||||||
{
|
|
||||||
unsigned short crc = 0;
|
|
||||||
while( len-- ) {
|
|
||||||
int i;
|
|
||||||
crc ^= *(char *)buf++ << 8;
|
|
||||||
for( i = 0; i < 8; ++i ) {
|
|
||||||
if( crc & 0x8000 )
|
|
||||||
crc = (crc << 1) ^ 0x1021;
|
|
||||||
else
|
|
||||||
crc = crc << 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
unsigned char calc_xmodem_checksum (unsigned char *buf, int sz)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int cks = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < sz; ++i) {
|
|
||||||
cks += (int)buf[i];
|
|
||||||
}
|
|
||||||
return cks%256;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* XMODEM */
|
|
||||||
static const unsigned char SOH = 0x01;
|
|
||||||
static const unsigned char STX = 0x02;
|
|
||||||
static const unsigned char EOT = 0x04;
|
|
||||||
static const unsigned char ACK = 0x06;
|
|
||||||
static const unsigned char NAK = 0x15;
|
|
||||||
static const unsigned char ETB = 0x17;
|
|
||||||
static const unsigned char CAN = 0x18;
|
|
||||||
static const unsigned char SYN = 0x43;
|
|
||||||
static const unsigned char CPMEOF = 0x1a;
|
|
||||||
|
|
||||||
Operator::Operator (TimeoutSerial &c) : com(&c)
|
|
||||||
{
|
|
||||||
obuff.resize (512 , 0);
|
|
||||||
obuff.resize (2048, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::SessionStartup (const string &file)
|
|
||||||
{
|
|
||||||
fname = file;
|
|
||||||
|
|
||||||
f.open(file.c_str(), fstream::binary | fstream::in);
|
|
||||||
|
|
||||||
/* adding a cr, C was probably on the screen */
|
|
||||||
if (!f.is_open())
|
|
||||||
{
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Cannot open file " << file << " please check the path";
|
|
||||||
}
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "File: " << file;
|
|
||||||
|
|
||||||
/* getting file size */
|
|
||||||
f.seekg (0, ios::end);
|
|
||||||
fsize = f.tellg();
|
|
||||||
f.seekg (0, ios::beg);
|
|
||||||
|
|
||||||
stringstream ss;
|
|
||||||
string size;
|
|
||||||
|
|
||||||
ss << fsize;
|
|
||||||
ss >> size;
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Size: " << size << " bytes";
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::StartTransfert ()
|
|
||||||
{
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Starting file transfer ...";
|
|
||||||
|
|
||||||
Entry();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::SendBlock(char *block, int size)
|
|
||||||
{
|
|
||||||
int hsz, csz;
|
|
||||||
|
|
||||||
/* prepare block header */
|
|
||||||
hsz = SetupBlockHdr();
|
|
||||||
|
|
||||||
/* prepare block binary data */
|
|
||||||
memcpy (&obuff[hsz], block, size);
|
|
||||||
csz = SetupCheckSum (&obuff[hsz], &obuff[hsz+size]);
|
|
||||||
|
|
||||||
q->write (&obuff[0], hsz+size+csz);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A thread process the entire transfert and allows UI to be free of operating
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum states {
|
|
||||||
SESSION_START,
|
|
||||||
SESSION_BLOCKS,
|
|
||||||
SESSION_CLOSE,
|
|
||||||
SESSION_CLOSE_WAIT_ACK,
|
|
||||||
SESSION_END,
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Operator::GetChar()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
q->read(&ibuff[0], 1);
|
|
||||||
return true;
|
|
||||||
} catch(boost::system::system_error& e)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Operator::IsChar ()
|
|
||||||
{ return (ibuff[0]!=0); }
|
|
||||||
|
|
||||||
bool Operator::IsAck ()
|
|
||||||
{
|
|
||||||
return (ibuff[0] == GetAck());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Operator::IsSync ()
|
|
||||||
{
|
|
||||||
return (ibuff[0] == GetSync());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Operator::IsNack ()
|
|
||||||
{
|
|
||||||
return (ibuff[0] == GetNack());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Operator::IsCan ()
|
|
||||||
{
|
|
||||||
return (ibuff[0] == GetCan());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::SendEot ()
|
|
||||||
{
|
|
||||||
char c[2];
|
|
||||||
|
|
||||||
c[0] = GetEot();
|
|
||||||
q->write (c, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::SetupInfoBlock (string &block)
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
|
|
||||||
unsigned int i = fname.rfind('/');
|
|
||||||
|
|
||||||
if (i==string::npos)
|
|
||||||
i = fname.rfind('\\');
|
|
||||||
|
|
||||||
if (i!=string::npos)
|
|
||||||
{
|
|
||||||
fname = fname.substr(i+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
i=fname.size();
|
|
||||||
|
|
||||||
ss << fsize;
|
|
||||||
pkt = 0;
|
|
||||||
|
|
||||||
/* prepare first block */
|
|
||||||
memcpy(&block[0],&fname[0], i);
|
|
||||||
block[i++]=0;
|
|
||||||
memcpy(&block[i],ss.str().c_str(),ss.str().size());
|
|
||||||
/*
|
|
||||||
* space after length should be needed only if mod date is sent
|
|
||||||
* but some receiver (u-boot) need it.
|
|
||||||
*/
|
|
||||||
block[i+ss.str().size()] = ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
void Operator::UpdateProgress (int size)
|
|
||||||
{
|
|
||||||
stringstream ss;
|
|
||||||
|
|
||||||
if (!size) {
|
|
||||||
psize = GetBlockSize() * count++;
|
|
||||||
} else
|
|
||||||
psize += size;
|
|
||||||
|
|
||||||
ss << psize << "/" << fsize;
|
|
||||||
|
|
||||||
// EvtDel ();
|
|
||||||
// EvtMsg (ss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
int Operator::Entry()
|
|
||||||
{
|
|
||||||
string block(1024,0);
|
|
||||||
|
|
||||||
struct y_modem_data ymd;
|
|
||||||
|
|
||||||
int state = SESSION_START;
|
|
||||||
int bsize = GetBlockSize();
|
|
||||||
int blnum = fsize / bsize;
|
|
||||||
int reminder=0;
|
|
||||||
|
|
||||||
count=1;
|
|
||||||
|
|
||||||
/* progress size */
|
|
||||||
psize=0;
|
|
||||||
|
|
||||||
stringstream ss;
|
|
||||||
string ascii_bsize;
|
|
||||||
|
|
||||||
ss << bsize;
|
|
||||||
ss >> ascii_bsize;
|
|
||||||
|
|
||||||
/* clone */
|
|
||||||
q = com;
|
|
||||||
|
|
||||||
pkt = 1;
|
|
||||||
|
|
||||||
if (GetProto()=='Y')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* always sending file size allows a faster close of
|
|
||||||
* the session from the receiver.
|
|
||||||
*
|
|
||||||
* = SPEC =
|
|
||||||
* The pathname (conventionally, the file name) is sent as a null
|
|
||||||
* terminated ASCII string.
|
|
||||||
* No spaces are included in the pathname. Normally only the file name
|
|
||||||
* stem (no directory prefix) is transmitted unless the sender has
|
|
||||||
* selected YAM's f option to send the full pathname. The source drive
|
|
||||||
* (A:, B:, etc.) is not sent.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
SetupInfoBlock(block);
|
|
||||||
blnum++;
|
|
||||||
|
|
||||||
/* signal to skip update progress for first info block */
|
|
||||||
ymd.first_pkt = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
/* read first block from file*/
|
|
||||||
f.read(&block[0], bsize);
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
/* always, wait for tranfert occour and proper replies */
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(10));
|
|
||||||
|
|
||||||
if (GetChar()==false) continue;
|
|
||||||
|
|
||||||
switch (state) {
|
|
||||||
case SESSION_START:
|
|
||||||
if (IsSync()) {
|
|
||||||
if (ymd.first_ack) {
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Entry() : YMODEM FIRST C after ACK";
|
|
||||||
/*
|
|
||||||
* YMODEM, as per spec we expect receiver
|
|
||||||
* sends this furhter 'C'
|
|
||||||
*/
|
|
||||||
state++;
|
|
||||||
/*
|
|
||||||
* clear rx data for walkthrough and
|
|
||||||
* send 1st block
|
|
||||||
*/
|
|
||||||
ibuff[0]=0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (GetProto()=='X')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* C here mean receiver wants
|
|
||||||
* 16bit CRC mode and
|
|
||||||
* assumes we know it if we send
|
|
||||||
* a block
|
|
||||||
*/
|
|
||||||
SetMode(XMODEMCRC);
|
|
||||||
/* send and promote */
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
/* received SYN */
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Sync received, transfert start";
|
|
||||||
/*
|
|
||||||
* resend same initial packet
|
|
||||||
* note: non sense for Y-MODEM use 1024
|
|
||||||
*/
|
|
||||||
SetSize(128);
|
|
||||||
SendBlock (&block[0], 128);
|
|
||||||
if (GetProto()=='Y') SetSize(1024);
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(10));;
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (IsAck()) {
|
|
||||||
if (GetProto()=='Y') {
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Entry() : YMODEM FIRST ACK";
|
|
||||||
|
|
||||||
ymd.first_ack=true;
|
|
||||||
/* back up to get C after ack */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (IsNack()) {
|
|
||||||
/*
|
|
||||||
* note ! programs as rx or lrz need filename as
|
|
||||||
* additional parameter, otherwise they sends
|
|
||||||
* C.. C and a CAN just after.
|
|
||||||
*/
|
|
||||||
if (GetProto()=='X') {
|
|
||||||
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Nack received, transfert start\r\n";
|
|
||||||
/* resend same initial packet*/
|
|
||||||
SendBlock (&block[0], bsize);
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(10));
|
|
||||||
/* promoted */
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Entry() : NACK FIRST";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// NO BREAK,
|
|
||||||
// FALL THROUGH IS INTENTIONAL
|
|
||||||
case SESSION_BLOCKS:
|
|
||||||
if (IsChar() && !IsAck()) {
|
|
||||||
if (IsSync()) {
|
|
||||||
if (GetProto()=='Y')
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* first synch after first
|
|
||||||
* block sent, do nothing here
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (IsNack()) {
|
|
||||||
//EvtMsg("Nack/Sync\r\n");
|
|
||||||
/* resend */
|
|
||||||
if (GetProto()=='Y' ||
|
|
||||||
(GetProto()=='X' && pkt!=1))
|
|
||||||
{
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "entry() : NACK, RESEND";
|
|
||||||
SendBlock (&block[0], bsize);
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (IsCan())
|
|
||||||
{
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Transfert canceled from receiver";
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(100));
|
|
||||||
/* destroy object and the thread */
|
|
||||||
return (void*)1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* to do, if some other chances */
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// ACK received, so progress
|
|
||||||
if (blnum)
|
|
||||||
{
|
|
||||||
if (GetProto()=='Y')
|
|
||||||
{
|
|
||||||
if (ymd.first_pkt) ymd.first_pkt=false;
|
|
||||||
else
|
|
||||||
UpdateProgress();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
// XMODEM, always
|
|
||||||
UpdateProgress();
|
|
||||||
|
|
||||||
/* if multiple of 256/1024 close */
|
|
||||||
if (blnum==1 && psize==fsize) {
|
|
||||||
blnum--;
|
|
||||||
goto close_session;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
close_session:
|
|
||||||
/* completed */
|
|
||||||
UpdateProgress (reminder);
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Closing session ...";
|
|
||||||
SendEot();
|
|
||||||
if (GetProto()=='X') state=SESSION_END; else state++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
blnum--;
|
|
||||||
pkt++;
|
|
||||||
/* end of blocks ? */
|
|
||||||
if (blnum>0) {
|
|
||||||
f.read(&block[0], bsize);
|
|
||||||
SendBlock (&block[0], bsize);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
reminder=fsize%bsize;
|
|
||||||
if (reminder)
|
|
||||||
{
|
|
||||||
f.read(&block[0], reminder);
|
|
||||||
memset (&block[reminder],CPMEOF,bsize-reminder);
|
|
||||||
SendBlock (&block[0], bsize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SESSION_CLOSE:
|
|
||||||
/* YMODEM ONLY */
|
|
||||||
if (IsAck()) state++;
|
|
||||||
else
|
|
||||||
if (IsNack())
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* in YMODEM termination is EOT-> NACK<-,
|
|
||||||
* EOT-> ACK<-
|
|
||||||
*/
|
|
||||||
SendEot();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SESSION_CLOSE_WAIT_ACK:
|
|
||||||
/* YMODEM ONLY */
|
|
||||||
if (IsSync())
|
|
||||||
{
|
|
||||||
/* Synch, terminating.. */
|
|
||||||
memset (&block[0], 0, 128);
|
|
||||||
SetSize(128);
|
|
||||||
pkt=0;
|
|
||||||
SendBlock (&block[0], 128);
|
|
||||||
|
|
||||||
state++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SESSION_END:
|
|
||||||
if (!IsAck()) continue;
|
|
||||||
BOOST_LOG_TRIVIAL(debug) << "Transfert complete";
|
|
||||||
boost::this_thread::sleep(posix_time::milliseconds(100));
|
|
||||||
/* destroy object and the thread */
|
|
||||||
//delete q;
|
|
||||||
//EvtEnd ();
|
|
||||||
return (void*)1;
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
XModem::XModem (TimeoutSerial &c) : Operator (c), t(*new __tools)
|
|
||||||
{
|
|
||||||
xmodem_mode = 0;
|
|
||||||
psize = LEN_B_XMODEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
int XModem::SetupBlockHdr()
|
|
||||||
{
|
|
||||||
obuff[0]=(xmodem_mode&XMODEM1K)?STX:SOH;
|
|
||||||
obuff[1]=pkt;
|
|
||||||
obuff[2]=0xff-pkt;
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int XModem::SetupCheckSum (char *data, char *dest)
|
|
||||||
{
|
|
||||||
if (xmodem_mode&XMODEMCRC)
|
|
||||||
{
|
|
||||||
unsigned short crc = t.crc16_ccitt(data, psize);
|
|
||||||
|
|
||||||
*(unsigned short*)dest = (unsigned short)
|
|
||||||
((crc<<8)&0xFF00) | ((crc>>8)&0xff);
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
unsigned char crc =
|
|
||||||
t.calc_xmodem_checksum((unsigned char*)data, psize);
|
|
||||||
|
|
||||||
*dest = crc;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char XModem::GetSync () { return SYN; }
|
|
||||||
inline char XModem::GetAck () { return ACK; }
|
|
||||||
inline char XModem::GetNack () { return NAK; }
|
|
||||||
inline char XModem::GetCan () { return CAN; }
|
|
||||||
inline char XModem::GetEot () { return EOT; }
|
|
||||||
inline char XModem::GetProto() { return 'X'; }
|
|
||||||
|
|
||||||
inline void XModem::SetSize (int size) { psize = size; }
|
|
||||||
|
|
||||||
YModem::YModem (TimeoutSerial &c) : Operator (c), t(*new __tools)
|
|
||||||
{
|
|
||||||
psize = LEN_B_YMODEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* YModem allows 128 (std) blocks or 1024
|
|
||||||
*/
|
|
||||||
int YModem::SetupBlockHdr()
|
|
||||||
{
|
|
||||||
obuff[0]=(psize==LEN_B_YMODEM)?STX:SOH;
|
|
||||||
obuff[1]=pkt;
|
|
||||||
obuff[2]=0xff-pkt;
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
int YModem::SetupCheckSum (char *data, char *dest)
|
|
||||||
{
|
|
||||||
unsigned short crc = t.crc16_ccitt(data, psize);
|
|
||||||
|
|
||||||
*(unsigned short*)dest = (unsigned short)((crc<<8)&0xFF00) | ((crc>>8)&0xff);
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline char YModem::GetSync () { return SYN; }
|
|
||||||
inline char YModem::GetAck () { return ACK; }
|
|
||||||
inline char YModem::GetNack () { return NAK; }
|
|
||||||
inline char YModem::GetCan () { return CAN; }
|
|
||||||
inline char YModem::GetEot () { return EOT; }
|
|
||||||
inline char YModem::GetProto() { return 'Y'; }
|
|
||||||
|
|
||||||
inline void YModem::SetSize (int size) { psize = size; }
|
|
||||||
141
xymodem.h
141
xymodem.h
@@ -1,141 +0,0 @@
|
|||||||
#ifndef modem_HH
|
|
||||||
#define modem_HH
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <fstream>
|
|
||||||
#include "Thread.h"
|
|
||||||
#include "TimeoutSerial.h"
|
|
||||||
|
|
||||||
using std::fstream;
|
|
||||||
using std::string;
|
|
||||||
|
|
||||||
class __tools;
|
|
||||||
|
|
||||||
struct y_modem_data
|
|
||||||
{
|
|
||||||
y_modem_data() : first_ack(false) {}
|
|
||||||
|
|
||||||
bool first_ack;
|
|
||||||
bool first_pkt;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Operator: public Thread< Operator >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Operator (TimeoutSerial &c);
|
|
||||||
private:
|
|
||||||
int Entry(); //Strting point
|
|
||||||
|
|
||||||
void SetupInfoBlock (string &block);
|
|
||||||
void UpdateProgress (int = 0);
|
|
||||||
|
|
||||||
bool GetChar();
|
|
||||||
bool IsChar ();
|
|
||||||
bool IsAck ();
|
|
||||||
bool IsSync ();
|
|
||||||
bool IsNack ();
|
|
||||||
bool IsCan ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void SendBlock(char *p, int size);
|
|
||||||
void SendEot ();
|
|
||||||
|
|
||||||
virtual int GetBlockSize () = 0;
|
|
||||||
virtual int SetupBlockHdr () = 0;
|
|
||||||
virtual int SetupCheckSum (char *data, char *dest) = 0;
|
|
||||||
virtual char GetSync () = 0;
|
|
||||||
virtual char GetAck () = 0;
|
|
||||||
virtual char GetCan () = 0;
|
|
||||||
virtual char GetNack () = 0;
|
|
||||||
virtual char GetEot () = 0;
|
|
||||||
virtual char GetProto() = 0;
|
|
||||||
|
|
||||||
virtual void SetSize (int) {}
|
|
||||||
virtual void SetMode (int) {}
|
|
||||||
virtual int GetMode () { return 0; }
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
void SessionStartup (const string &);
|
|
||||||
void StartTransfert ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
TimeoutSerial *com, *q;
|
|
||||||
fstream f;
|
|
||||||
int pkt;
|
|
||||||
int fsize,psize;
|
|
||||||
int count;
|
|
||||||
string fname;
|
|
||||||
string ibuff;
|
|
||||||
string obuff;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const int LEN_B_XMODEM = 128;
|
|
||||||
|
|
||||||
// bitmask
|
|
||||||
enum {
|
|
||||||
XMODEM1K=0x01,
|
|
||||||
XMODEMCRC=0x02,
|
|
||||||
};
|
|
||||||
|
|
||||||
class XModem : public Operator {
|
|
||||||
public:
|
|
||||||
XModem (TimeoutSerial &c);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int GetBlockSize () { return psize; }
|
|
||||||
int SetupBlockHdr ();
|
|
||||||
int SetupCheckSum (char *data, char *dest);
|
|
||||||
|
|
||||||
char GetSync ();
|
|
||||||
char GetAck ();
|
|
||||||
char GetNack ();
|
|
||||||
char GetCan ();
|
|
||||||
char GetProto();
|
|
||||||
char GetEot ();
|
|
||||||
int GetMode () {return xmodem_mode;}
|
|
||||||
|
|
||||||
void SetSize (int size);
|
|
||||||
void SetMode (int mode) {
|
|
||||||
xmodem_mode|=mode;
|
|
||||||
if (mode&XMODEM1K) psize=1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
int xmodem_mode;
|
|
||||||
|
|
||||||
private:
|
|
||||||
__tools &t;
|
|
||||||
int psize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* we don't use the standard 128 block but 1024 only
|
|
||||||
*/
|
|
||||||
static const int LEN_B_YMODEM = 1024;
|
|
||||||
|
|
||||||
class YModem : public Operator {
|
|
||||||
public:
|
|
||||||
YModem (TimeoutSerial &c);
|
|
||||||
|
|
||||||
private:
|
|
||||||
int GetBlockSize () { return psize; }
|
|
||||||
int SetupBlockHdr ();
|
|
||||||
int SetupCheckSum (char *data, char *dest);
|
|
||||||
|
|
||||||
char GetSync ();
|
|
||||||
char GetAck ();
|
|
||||||
char GetNack ();
|
|
||||||
char GetCan ();
|
|
||||||
char GetProto();
|
|
||||||
char GetEot ();
|
|
||||||
|
|
||||||
void SetSize (int size);
|
|
||||||
|
|
||||||
private:
|
|
||||||
__tools &t;
|
|
||||||
int psize;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif // modem_HH
|
|
||||||
63
ymodem.h
63
ymodem.h
@@ -1,63 +0,0 @@
|
|||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* @file IAP/inc/ymodem.h
|
|
||||||
* @author MCD Application Team
|
|
||||||
* @version V3.3.0
|
|
||||||
* @date 10/15/2010
|
|
||||||
* @brief This file provides all the software function headers of the ymodem.c
|
|
||||||
* file.
|
|
||||||
******************************************************************************
|
|
||||||
* @copy
|
|
||||||
*
|
|
||||||
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
|
|
||||||
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
|
|
||||||
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
|
|
||||||
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
|
|
||||||
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
|
|
||||||
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
|
|
||||||
*
|
|
||||||
* <h2><center>© COPYRIGHT 2010 STMicroelectronics</center></h2>
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef _YMODEM_H_
|
|
||||||
#define _YMODEM_H_
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* Exported types ------------------------------------------------------------*/
|
|
||||||
/* Exported constants --------------------------------------------------------*/
|
|
||||||
#define PACKET_SEQNO_INDEX (1)
|
|
||||||
#define PACKET_SEQNO_COMP_INDEX (2)
|
|
||||||
|
|
||||||
#define PACKET_HEADER (3)
|
|
||||||
#define PACKET_TRAILER (2)
|
|
||||||
#define PACKET_OVERHEAD (PACKET_HEADER + PACKET_TRAILER)
|
|
||||||
#define PACKET_SIZE (128)
|
|
||||||
#define PACKET_1K_SIZE (1024)
|
|
||||||
|
|
||||||
#define FILE_NAME_LENGTH (256)
|
|
||||||
#define FILE_SIZE_LENGTH (16)
|
|
||||||
|
|
||||||
#define SOH (0x01) /* start of 128-byte data packet */
|
|
||||||
#define STX (0x02) /* start of 1024-byte data packet */
|
|
||||||
#define EOT (0x04) /* end of transmission */
|
|
||||||
#define ACK (0x06) /* acknowledge */
|
|
||||||
#define NAK (0x15) /* negative acknowledge */
|
|
||||||
#define CA (0x18) /* two of these in succession aborts transfer */
|
|
||||||
#define CRC16 (0x43) /* 'C' == 0x43, request 16-bit CRC */
|
|
||||||
|
|
||||||
#define ABORT1 (0x41) /* 'A' == 0x41, abort by user */
|
|
||||||
#define ABORT2 (0x61) /* 'a' == 0x61, abort by user */
|
|
||||||
|
|
||||||
#define NAK_TIMEOUT (0x100000)
|
|
||||||
#define MAX_ERRORS (5)
|
|
||||||
|
|
||||||
/* Exported macro ------------------------------------------------------------*/
|
|
||||||
/* Exported functions ------------------------------------------------------- */
|
|
||||||
int32_t Ymodem_Receive (uint8_t *);
|
|
||||||
uint8_t Ymodem_Transmit (uint8_t *,const uint8_t* , uint32_t );
|
|
||||||
|
|
||||||
#endif /* _YMODEM_H_ */
|
|
||||||
|
|
||||||
/*******************(C)COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
|
|
||||||
Reference in New Issue
Block a user