添加上传下载配置
This commit is contained in:
parent
0eb563da4e
commit
69eecc6824
@ -70,8 +70,54 @@ void MyTcpClient::onConnected() {
|
||||
}
|
||||
|
||||
void MyTcpClient::onReadyRead() {
|
||||
QByteArray data = socket->readAll();
|
||||
emit dataReceived(data);
|
||||
while (socket->bytesAvailable() > 0) {
|
||||
if (m_waitingForHeader) {
|
||||
// 1. 先尝试读取头部(固定长度)
|
||||
if (socket->bytesAvailable() < sizeof(PackageHead)) {
|
||||
return; // 数据不够,等待下次触发
|
||||
}
|
||||
|
||||
// 读取头部
|
||||
socket->read(reinterpret_cast<char*>(&m_currentHead), sizeof(PackageHead));
|
||||
|
||||
// 验证头部标识(0xAA55AA)
|
||||
if (m_currentHead.head[0] != 0xAA ||
|
||||
m_currentHead.head[1] != 0x55 ||
|
||||
m_currentHead.head[2] != 0xAA) {
|
||||
qWarning() << "Invalid header! Disconnecting...";
|
||||
return;
|
||||
}
|
||||
|
||||
// 进入等待数据状态
|
||||
m_waitingForHeader = false;
|
||||
m_buffer.clear();
|
||||
m_buffer.append(reinterpret_cast<char*>(&m_currentHead), sizeof(PackageHead)); // 先存头部
|
||||
} else {
|
||||
// 2. 根据头部的 len 读取剩余数据
|
||||
qint64 remainingBytes = m_currentHead.len - (m_buffer.size() - sizeof(PackageHead));
|
||||
|
||||
if (remainingBytes <= 0) {
|
||||
// 数据已经完整,触发信号
|
||||
emit dataReceived(m_buffer);
|
||||
m_waitingForHeader = true; // 重置状态,准备接收下一个包
|
||||
break; // 继续处理缓冲区可能的下一个包
|
||||
}
|
||||
|
||||
// 读取剩余数据(不超过 remainingBytes)
|
||||
QByteArray newData = socket->read(remainingBytes);
|
||||
qDebug() << "Read" << newData.size() << "bytes";
|
||||
m_buffer.append(newData);
|
||||
|
||||
// 检查是否已经读完
|
||||
if (m_buffer.size() - sizeof(PackageHead) >= m_currentHead.len) {
|
||||
qDebug() << "m_buffer" << m_buffer.size() << "bytes";
|
||||
emit dataReceived(m_buffer);
|
||||
m_waitingForHeader = true; // 准备接收下一个包
|
||||
}
|
||||
}
|
||||
}
|
||||
// QByteArray data = socket->readAll();
|
||||
// emit dataReceived(data);
|
||||
}
|
||||
|
||||
void MyTcpClient::onDisconnected() {
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <QTcpSocket>
|
||||
#include <QTimer>
|
||||
#include <QObject>
|
||||
#include "data_config.h"
|
||||
|
||||
class MyTcpClient : public QObject {
|
||||
Q_OBJECT
|
||||
@ -39,6 +40,10 @@ private:
|
||||
quint16 serverPort;
|
||||
bool shouldReconnect; // 标记是否需要重连
|
||||
static MyTcpClient* m_instance;
|
||||
|
||||
QByteArray m_buffer; // 存储当前正在接收的数据
|
||||
bool m_waitingForHeader = true; // 是否在等待头部
|
||||
PackageHead m_currentHead; // 当前包的头部信息
|
||||
};
|
||||
|
||||
#endif // MYTCPCLIENT_H
|
||||
|
@ -326,7 +326,7 @@ void ConfigMgr::Load(QString filename) {
|
||||
// filter
|
||||
QJsonArray filter_array = channel["filter"].toArray();
|
||||
for (int k = 0; k < filter_array.size(); k++) {
|
||||
QJsonObject filter_ele = filter_array[i].toObject();
|
||||
QJsonObject filter_ele = filter_array[k].toObject();
|
||||
variable->filter_[k].low = filter_ele["low"].toInt();
|
||||
variable->filter_[k].high = filter_ele["high"].toInt();
|
||||
variable->filter_[k].checked = filter_ele["checked"].toBool();
|
||||
|
@ -58,9 +58,28 @@ enum CMTCommand {
|
||||
kGetVersionInfo = 4,
|
||||
kRelaySetting = 5,
|
||||
kRelayStatus = 6,
|
||||
kUpgradeProgress = 7
|
||||
kUpgradeProgress = 7,
|
||||
kCalibrationMode = 8,
|
||||
kGetDcValue = 9,
|
||||
kSetCalibrationCoe = 10,
|
||||
kGetCalibrationCoe = 11,
|
||||
kClearCalibrationCoe = 12,
|
||||
kGetWaveData = 13,
|
||||
kUploadConfigFile = 14,
|
||||
kDownloadConfigFile = 15,
|
||||
kConfigSubCard = 16, // 请求无包体,响应有包体
|
||||
kRS485BaudrateSet = 17, // RS485波特率配置
|
||||
kRS485BaudrateGet = 18, // RS485波特率获取
|
||||
};
|
||||
enum RS485Baudrate {
|
||||
kBaudrate2400 = 0,
|
||||
kBaudrate4800 = 1,
|
||||
kBaudrate9600 = 2, // 默认值
|
||||
kBaudrate19200 = 3,
|
||||
kBaudrate38400 = 4,
|
||||
kBaudrate57600 = 5,
|
||||
kBaudrate115200 = 6
|
||||
};
|
||||
|
||||
// 振动板采样率
|
||||
typedef enum {
|
||||
kVibSR16K = 0, // 16k
|
||||
@ -198,6 +217,7 @@ typedef struct {
|
||||
double scale_factor;
|
||||
} Transducer;
|
||||
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
uint8_t head[3]; // 固定值:0xAA55AA
|
||||
@ -244,6 +264,30 @@ typedef struct {
|
||||
uint8_t status; // 7 测试状态,8 手动状态,9 工作状态
|
||||
} RelayStatusRsp;
|
||||
|
||||
typedef struct {
|
||||
char data[0];
|
||||
} UploadConfigReq, DownloadConfigRsp;
|
||||
|
||||
typedef struct {
|
||||
uint8_t code;
|
||||
} UploadConfigRsp, DownloadConfigReq;
|
||||
|
||||
typedef struct {
|
||||
uint8_t card_id;
|
||||
} ConfigSubCardReq;
|
||||
|
||||
typedef struct {
|
||||
uint8_t code; // 0: success 1: 无配置文件 2:失败
|
||||
} ConfigSubCardRsp;
|
||||
|
||||
typedef struct {
|
||||
uint8_t baudrate; // kRS485BaudrateSet, kRS485BaudrateGet
|
||||
} BaudrateSetReq, BaudrateGetRsp;
|
||||
|
||||
typedef struct {
|
||||
uint8_t code; // 0: success
|
||||
} BaudrateSetRsp;
|
||||
|
||||
#pragma pack()
|
||||
|
||||
#endif // DATA_CONFIG_H
|
||||
|
138
mainwindow.cpp
138
mainwindow.cpp
@ -87,7 +87,7 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
connect(btnGroup_slot, SIGNAL(buttonClicked(QAbstractButton *)), this, SLOT(OnButtonGroup(QAbstractButton *)));
|
||||
QSettings settingsread(QCoreApplication::applicationDirPath() + "\\config\\config.ini", QSettings::IniFormat);
|
||||
g_strServerIp = settingsread.value("Server/IP").toString();
|
||||
//connectServer();
|
||||
connectServer();
|
||||
// 设置自定义日志处理函数
|
||||
#ifndef QT_DEBUG
|
||||
qInstallMessageHandler(messageHandler);
|
||||
@ -199,6 +199,7 @@ void MainWindow::createMenu(const QString &rootTitle, QPushButton *parent) {
|
||||
QAction *proximitor_2 = proximitor_menu->addAction("/HAM824 三冗余板卡");
|
||||
proximitor_2->setData(kCardVibTMRPrimary);
|
||||
QAction *rpm_1 = rpm_menu->addAction("/OPM844 单板卡");
|
||||
rpm_1->setData(kCardSpeedSingle);
|
||||
// 创建第二层子菜单:/KPM834 键相模块
|
||||
QAction *keyphasor_1 = keyphasor->addAction("/KPM834 单板卡");
|
||||
keyphasor_1->setData(kCardKeyphaseSingle);
|
||||
@ -342,7 +343,7 @@ void MainWindow::onMenuActionTriggered() {
|
||||
button->setText(chan_display);
|
||||
}
|
||||
if (action->text() == "重置模块") {
|
||||
if (map_slot_config[button_id].rack_type == "TMR1") {
|
||||
if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRPrimary) {
|
||||
map_slot_config[button_id].slot_type = "";
|
||||
map_slot_config[button_id].rack_type = "0";
|
||||
map_slot_config[button_id].slot_btn->setText("");
|
||||
@ -355,7 +356,7 @@ void MainWindow::onMenuActionTriggered() {
|
||||
map_slot_config[button_id + 2].rack_type = "0";
|
||||
map_slot_config[button_id + 2].slot_btn->setText("");
|
||||
map_slot_config[button_id + 2].chan_display = "";
|
||||
} else if (map_slot_config[button_id].rack_type == "TMR2") {
|
||||
} else if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardRelayTMRBackup) {
|
||||
map_slot_config[button_id - 1].slot_type = "";
|
||||
map_slot_config[button_id - 1].rack_type = "0";
|
||||
map_slot_config[button_id - 1].slot_btn->setText("");
|
||||
@ -368,44 +369,11 @@ void MainWindow::onMenuActionTriggered() {
|
||||
map_slot_config[button_id + 1].rack_type = "0";
|
||||
map_slot_config[button_id + 1].slot_btn->setText("");
|
||||
map_slot_config[button_id + 1].chan_display = "";
|
||||
} else if (map_slot_config[button_id].rack_type == "TMR3") {
|
||||
map_slot_config[button_id - 2].slot_type = "";
|
||||
map_slot_config[button_id - 2].rack_type = "0";
|
||||
map_slot_config[button_id - 2].slot_btn->setText("");
|
||||
map_slot_config[button_id - 2].chan_display = "";
|
||||
map_slot_config[button_id - 1].slot_type = "";
|
||||
map_slot_config[button_id - 1].rack_type = "0";
|
||||
map_slot_config[button_id - 1].slot_btn->setText("");
|
||||
map_slot_config[button_id - 1].chan_display = "";
|
||||
map_slot_config[button_id].slot_type = "";
|
||||
map_slot_config[button_id].rack_type = "0";
|
||||
}else if (ConfigMgr::Instance()->card_type_[button_id - 1] == kCardVibSingle ||
|
||||
ConfigMgr::Instance()->card_type_[button_id - 1] == kCardSpeedSingle ||
|
||||
ConfigMgr::Instance()->card_type_[button_id - 1] == kCardKeyphaseSingle) {
|
||||
ConfigMgr::Instance()->card_type_[button_id - 1] = kCardNone;
|
||||
map_slot_config[button_id].slot_btn->setText("");
|
||||
map_slot_config[button_id].chan_display = "";
|
||||
}
|
||||
if (map_slot_config[button_id].rack_type == "Double1") {
|
||||
map_slot_config[button_id].slot_type = "";
|
||||
map_slot_config[button_id].rack_type = "0";
|
||||
map_slot_config[button_id].slot_btn->setText("");
|
||||
map_slot_config[button_id].chan_display = "";
|
||||
map_slot_config[button_id + 1].slot_type = "";
|
||||
map_slot_config[button_id + 1].rack_type = "0";
|
||||
map_slot_config[button_id + 1].slot_btn->setText("");
|
||||
map_slot_config[button_id + 1].chan_display = "";
|
||||
} else if (map_slot_config[button_id].rack_type == "Double2") {
|
||||
map_slot_config[button_id - 1].slot_type = "";
|
||||
map_slot_config[button_id - 1].rack_type = "0";
|
||||
map_slot_config[button_id - 1].slot_btn->setText("");
|
||||
map_slot_config[button_id - 1].chan_display = "";
|
||||
map_slot_config[button_id].slot_type = "";
|
||||
map_slot_config[button_id].rack_type = "0";
|
||||
map_slot_config[button_id].slot_btn->setText("");
|
||||
map_slot_config[button_id].chan_display = "";
|
||||
}
|
||||
if (map_slot_config[button_id].rack_type == "Single") {
|
||||
map_slot_config[button_id].slot_type = "";
|
||||
map_slot_config[button_id].rack_type = "0";
|
||||
map_slot_config[button_id].slot_btn->setText("");
|
||||
map_slot_config[button_id].chan_display = "";
|
||||
}
|
||||
} else if (action->text() == "升级固件") {
|
||||
sendUpgradePackage(button_id);
|
||||
@ -527,9 +495,64 @@ void MainWindow::onMenuAction_relay() {
|
||||
relay_setting->setWindowModality(Qt::ApplicationModal);
|
||||
relay_setting->show();
|
||||
}
|
||||
|
||||
uint8_t calculate_crc(uint8_t c, const QByteArray &data) {
|
||||
uint8_t crc = c;
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
crc += static_cast<uint8_t>(data[i]); // 累加每个字节
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
void MainWindow::on_pushButton_save_clicked() {
|
||||
ConfigMgr::Instance()->Save();
|
||||
// 读取文件内容
|
||||
QFile file(QCoreApplication::applicationDirPath() + "\\config\\tsi_config_file.json");
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "Failed to open update file.";
|
||||
return;
|
||||
}
|
||||
QByteArray fileData = file.readAll();
|
||||
int fileSize = fileData.size();
|
||||
if (fileSize > 10 * 1024 * 1024) {
|
||||
QMessageBox::information(this, QStringLiteral("提示"), "文件大小超过10M,请重新选择!");
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
qDebug() << "fileSize" << fileSize ;
|
||||
// 创建 PackageHead 结构体
|
||||
PackageHead header = { {0xAA, 0x55, 0xAA}, kUploadConfigFile, fileSize, 0, {} };
|
||||
// 计算文件的 CRC 校验和
|
||||
header.crc = calculate_crc(0, fileData);
|
||||
header.len = fileSize;
|
||||
char *send_buf = NULL;
|
||||
send_buf = (char *)malloc(sizeof(PackageHead) + fileData.size() + 1);
|
||||
memset(send_buf, 0, sizeof(PackageHead) + fileData.size() + 1);
|
||||
memcpy(send_buf, &header, sizeof(PackageHead));
|
||||
memcpy(send_buf + sizeof(PackageHead), fileData.data(), fileData.size());
|
||||
int length = sizeof(PackageHead) + fileData.size();
|
||||
const int MAX_CHUNK_SIZE = 50 * 1024; // 50 KB
|
||||
qint64 bytesSent = 0;
|
||||
qint64 totalBytes = length;
|
||||
qDebug() << "totalBytes" << totalBytes ;
|
||||
while (bytesSent < totalBytes) {
|
||||
qint64 chunkSize = 0;
|
||||
if (MAX_CHUNK_SIZE < totalBytes - bytesSent) {
|
||||
chunkSize = MAX_CHUNK_SIZE;
|
||||
} else {
|
||||
chunkSize = totalBytes - bytesSent;
|
||||
}
|
||||
qint64 bytesWritten = m_tcpClient->sendData(send_buf + bytesSent, chunkSize);
|
||||
qDebug() << "bytesWritten" << bytesWritten << "bytesSent" << bytesSent << "chunkSize" << chunkSize ;
|
||||
if (bytesWritten == -1) {
|
||||
break;
|
||||
}
|
||||
bytesSent += bytesWritten;
|
||||
}
|
||||
qDebug() << "bytesSent" << bytesSent;
|
||||
m_tcpClient->waitForRead();
|
||||
file.close();
|
||||
if (send_buf != NULL) {
|
||||
free(send_buf);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButton_open_clicked() {
|
||||
@ -559,13 +582,6 @@ void MainWindow::on_pushButton_open_clicked() {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t calculate_crc(uint8_t c, const QByteArray &data) {
|
||||
uint8_t crc = c;
|
||||
for (int i = 0; i < data.size(); ++i) {
|
||||
crc += static_cast<uint8_t>(data[i]); // 累加每个字节
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
uint32_t myHtonl(uint32_t value) {
|
||||
return ((value >> 24) & 0x000000FF) | // 提取最高的8位
|
||||
@ -702,5 +718,31 @@ void MainWindow::readData(const QByteArray &data) {
|
||||
statusBar()->showMessage("升级完成!", 3000); // 显示3秒
|
||||
}
|
||||
//qDebug() << "Server response: " << upgrade_resp.code;
|
||||
} else if(header.cmd == kDownloadConfigFile){
|
||||
//qDebug() << "header.len" << header.len;
|
||||
char *config_file = NULL;
|
||||
config_file = (char*)malloc(header.len + 1);
|
||||
memset(config_file,0,header.len + 1);
|
||||
memcpy(config_file, data.data() + sizeof(PackageHead), header.len);
|
||||
QString filename_ = QCoreApplication::applicationDirPath() + "\\config\\tsi_config_file2.json";
|
||||
//qDebug() << config_file ;
|
||||
QFile file(filename_);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(config_file,header.len);
|
||||
file.close();
|
||||
if(config_file != NULL)
|
||||
free(config_file);
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_pushButton_download_clicked()
|
||||
{
|
||||
PackageHead header = { {0xAA, 0x55, 0xAA}, kDownloadConfigFile, 1, 0, {} };
|
||||
char send_buf[20] = {0};
|
||||
memcpy(send_buf, (char *)&header, sizeof(PackageHead));
|
||||
int length = sizeof(PackageHead);
|
||||
qint64 bytesWritten = m_tcpClient->sendData(send_buf, length);
|
||||
m_tcpClient->waitForRead();
|
||||
qDebug() << "bytesWritten: " << bytesWritten;
|
||||
}
|
||||
|
||||
|
@ -72,5 +72,6 @@ private slots:
|
||||
void on_pushButton_point_name_clicked();
|
||||
void on_pushButton_save_clicked();
|
||||
void on_pushButton_open_clicked();
|
||||
void on_pushButton_download_clicked();
|
||||
};
|
||||
#endif // MAINWINDOW_H
|
||||
|
@ -122,7 +122,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_23">
|
||||
<widget class="QPushButton" name="pushButton_download">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
@ -144,7 +144,7 @@
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
<string>下载</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton_24">
|
||||
|
@ -11,7 +11,7 @@
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Form</string>
|
||||
<string>触发配置</string>
|
||||
</property>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="geometry">
|
||||
|
Loading…
x
Reference in New Issue
Block a user