文件读取在下载按钮点击之后完成,通过Jeson已经转换成需要的字符串格式。
将字符串统一存储到QStringList中,下载的时候,对话正确则发送下一个包。
如果超时,则显示超时次数,超时第六次不再重发,直接终止。
/**
* @brief appendToRecord
* @param array
* @param type
* RECORD_ALL = 0,
RECORD_SEND = 1,
RECORD_RECV = 2,
RECORD_REPORT = 3,
RECORD_TIMEOUT = 4
*/
void UpdateWidget::appendToRecord(const QByteArray &array, int type)
{
static int historyValue = 0;
if(downLoadFlag == true)
{
QJsonObject json;
if(type == 4) //3.3 接收回复超时处理
{
//判断是否为当前包超时,是当前包则继续计数,不是当前包则重新计数
if(historyValue != nextValue)
{
historyValue = nextValue;
retryNum = 0;
retryNum++;
textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
}
else {
retryNum++;
textdis->append(QString("%1,当前包回复超时次数为:%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg(retryNum));
}
//判断当前包超时次数,超过5次则放弃下载
if(retryNum > 5)
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("对方无回复,终止下载!"));
loadStringList->clear();
retryNum = 0;
downLoadFlag = false;
return;
}
//判断当前下载包序号,有针对性重发,nextValue初始为0,收到第一个回复则变为2
if(nextValue == 0)
{
emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
}
else {
emit viewTransmitData("FirmWare", "Download", loadStringList->at(nextValue-1), 1);
}
}
if(arrayToJsonObject(QString(array), json))
{
//1、检测ident字段是否为 "FirmWare"
if((jsonIdentCheck(TBox_Download_TAG, json) != false)
&& (jsonMethodCheck(Method_Response, json) == true))
{
if(json.contains(TBox_Param_TAG) != true
|| json.value(TBox_Param_TAG).isObject() != true)
{
return ;
}
QJsonObject paramObj = json.value(TBox_Param_TAG).toObject();
//2、读取消息中的值,根据回复情况继续下载或者终止下载
resultValue = paramObj.value(Download_Result).toInt();//getStringValueByKey(Download_Result, json);
if(resultValue == 0)
{
seqValue = paramObj.value(Download_Seq).toInt();
nextValue = paramObj.value(Download_Next).toInt();
if(seqValue < total) // 发送未结束,发送下一个包
{
emit viewTransmitData("FirmWare", "Download", loadStringList->at(nextValue-1), 1);
DLoadBar->setValue(seqValue); //设置当前进度条值
textdis->append(QString("%1,已发送:当前/总数= %2/%3").arg(QTime::currentTime().toString("HH:mm:ss")).arg(seqValue).arg(total));
textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
}
else // 发送完成,更新状态,停止发送
{
DLoadBar->setValue(int(total)); //设置当前的运行值为100%
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("下载完成!"));
textdis->moveCursor(QTextCursor::End); //textdis显示最新消息
loadStringList->clear();
downLoadFlag = false;
return;
}
}
else if(resultValue == 1)
{
reasonValue = paramObj.value(Download_Reason).toString();
textdis->append(QString("%1,接收设备处理数据包失败,终止下载! reason:%2").
arg(QTime::currentTime().toString("HH:mm:ss")).arg(reasonValue));
loadStringList->clear();
downLoadFlag = false;
return;
}
}
}
}
}
下面是下载按钮的动作。
1.判断是否有文件路径,如果有,读取文件;如果没有,让用户选择。
2.设置进度条大小,发送第一包数据。
3.开启下载标志位。
/**
* @brief UpdateWidget::onBtnLoadClicked
*/
void UpdateWidget::onBtnLoadClicked()
{
if(fileName.isEmpty())
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("请先选择文件!"));
}
else
{
readfile();
DLoadBar->setRange(0,total); //设置进度条最小值和最大值(取值范围)
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始下载!"));
emit viewTransmitData("FirmWare", "Download", loadStringList->at(0), 1);
downLoadFlag = true; //打开下载标志位
}
}
下面是文件读取的函数,文件选择已经在浏览按钮的动作下实现了。
void UpdateWidget::readfile()
{
//读取文件
binFile = new QFile(fileName);
binFile->open (QIODevice::ReadOnly);
allDataArray = binFile->readAll();
//1.初始化计数参数和存储容器
int crc=0, length=512, listSeq=1;
QString datastring;
QByteArray temdata;
loadStringList = new QStringList;
int binfileseek = 0;
//计算下载数据包数量total
if(dataLen%512 >0)
{ total = (dataLen/512)+1; }
else
{ total = dataLen/512; }
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("开始读取!"));
//2.1 装填发送包
for(int i=0; i<=total; i++)
{
if(binfileseek >= dataLen) //2.1.1 已经全部装填
{
textdis->append(QString("%1,%2").arg(QTime::currentTime().toString("HH:mm:ss")).arg("读取完成!"));
binfileseek = 0;
allDataArray.clear();
binFile->close();
}
else if((dataLen-binfileseek) > length) //2.1.2 还有大于一包没装填
{
for (int i=0; i<length; i++, binfileseek++)
{ temdata[i] = allDataArray.at(binfileseek); }
}
else //2.1.3 还有最后一包没装填
{
int lastdata = dataLen-binfileseek;
for (int i=0; i<lastdata; binfileseek++, i++)
{ temdata[i] = allDataArray.at(binfileseek); }
}
//2.1.4 发送包格式转换
datastring.prepend(temdata);
temdata.clear();
Command *cmd = new Command;
QString loadData = cmd -> prepareLoadingData(QString(total), QString(listSeq), QString(crc), datastring);
datastring.clear();
loadStringList->append(loadData);
loadData.clear();
listSeq++;
qDebug() << "loadStringList:" << loadStringList->at(i);
}
}