qt/ledset/expertwin.cpp
2022-12-16 15:08:53 +08:00

822 lines
30 KiB
C++

#include "expertwin.h"
#include "gqt.h"
#include "table.h"
#include "crc.h"
#include "screenunit.h"
#include "expertsmartpointsetwin.h"
#include "expertscreenconnwin.h"
#include <QTabWidget>
#include <QLineEdit>
#include <QPushButton>
#include <QGroupBox>
#include <QStackedWidget>
#include <QStackedLayout>
#include <QRadioButton>
#include <QCheckBox>
#include <QApplication>
#include <QFile>
#include <QJsonDocument>
#include <QJsonArray>
#include <QMessageBox>
#include <QFileDialog>
QColor colors[] {QColor(0xdd0000), QColor(0xdd6600), QColor(0x008800), QColor(0x008888), QColor(0x0000ff), QColor(0x777777), QColor(0xaaaaaa)};
ExpertWin::ExpertWin(QWidget *parent) : BaseWin{parent} {
//setWindowModality(Qt::WindowModal);
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle("专家调屏");
resize(1024, 720);
auto vBox = new QVBoxLayout(center);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(3);
vBox->addLayout(addBtns(new QHBoxLayout()));
auto tab = new QTabWidget;
tab->setStyleSheet(R"rrr(
QTabWidget::pane {border: 1px solid #888; margin-top:-1px;}
QTabBar::tab {margin-top: 4px; padding: 6px 20px; border: 1px solid #888; border-radius: 0 0 3px 3px;}
QTabBar::tab:selected {margin-top: 0; border-bottom: none; color: #acf; background-color: #000;}
)rrr");
vBox->addWidget(tab);
auto sendPanel = new QWidget;
tab->addTab(sendPanel, "发送设备");
{
auto hhh = new QHBoxLayout(sendPanel);
hhh->setContentsMargins(6,6,6,6);
auto wgtLeft = new QWidget;
wgtLeft->setMaximumWidth(400);
hhh->addWidget(wgtLeft);
auto vLeft = new QVBoxLayout(wgtLeft);
vLeft->setContentsMargins(0,0,0,0);
auto hBox = new QHBoxLayout;
hBox->addWidget(new QLabel("分辨率: "));
auto fdW = new QLineEdit(QString::number(screenWidth));
hBox->addWidget(fdW);
hBox->addWidget(new QLabel("X"));
auto fdH = new QLineEdit(QString::number(screenHeight));
hBox->addWidget(fdH);
vLeft->addLayout(hBox);
hBox = new QHBoxLayout;
hBox->addStretch();
auto btnGet = new QPushButton("刷新");
btnGet->setMinimumWidth(80);
hBox->addWidget(btnGet);
hBox->addSpacing(40);
auto btnSet = new QPushButton("设置");
btnSet->setMinimumWidth(80);
hBox->addWidget(btnSet);
hBox->addStretch();
vLeft->addLayout(hBox);
auto table = new Table{
{"face", "网口", 40},
{"x", "X", 0, QHeaderView::Stretch},
{"y", "Y", 0, QHeaderView::Stretch},
{"w", "宽度", 0, QHeaderView::Stretch},
{"h", "高度", 0, QHeaderView::Stretch},
{"audio", "音频开关", 0, QHeaderView::Stretch},
{"backup", "备份开关", 0, QHeaderView::Stretch}
};
table->setDefs();
vLeft->addWidget(table);
table->setRowCount(4);
auto canvas = new ResizeEmitedWgt;
auto screen = new QWidget(canvas);
screen->setGeometry(0, 0, screenWidth, screenHeight);
screen->setAutoFillBackground(true);
auto pal = palette();
pal.setColor(QPalette::Window, QColor(0, 0, 0));
screen->setPalette(pal);
connect(canvas, &ResizeEmitedWgt::resized, this, [this, canvas, screen] {
rate = qMin(canvas->width()/(double)screenWidth, canvas->height()/(double)screenHeight);
if(rate==0) return;
screen->resize(qRound(screenWidth*rate), qRound(screenHeight*rate));
auto children = screen->children();
foreach(auto childObj, children) {
auto unit = static_cast<ScreenUnit*>(childObj);
unit->setGeometry(qRound(unit->mX*rate), qRound(unit->mY*rate), qRound(unit->mW*rate), qRound(unit->mH*rate));
}
});
hhh->addWidget(canvas);
int idx = 0;
for(int rr=0; rr<4; rr++) {
QString name = "P"+QString::number(rr+1);
table->setValue(rr, "name", name);
table->setValue(rr, "x", QString::number(idx));
table->setValue(rr, "y", "0");
table->setValue(rr, "w", "128");
table->setValue(rr, "h", "128");
table->setValue(rr, "audio", "0");
table->setValue(rr, "backup", "0");
auto unit = new ScreenUnit(this, name, idx, 0, 128, 128, screen);
unit->setAutoFillBackground(true);
pal.setColor(QPalette::Window, colors[rr]);
unit->setPalette(pal);
idx += 128;
}
}
{
auto file = QApplication::applicationDirPath()+"/temp.screen";
QFile qFile(file);
if(qFile.open(QFile::ReadOnly)) {
auto data = qFile.readAll();
qFile.close();
QJsonParseError err;
auto json = QJsonDocument::fromJson(data, &err);
if(err.error==QJsonParseError::NoError && json.isObject() && ! json.isEmpty()) {
mBox = json["ModuleConnectionInfo"].toObject();
mModule = mBox["ModuleInfo"].toObject();
}
} else {
auto file = QApplication::applicationDirPath()+"/temp.module";
QFile qFile(file);
if(qFile.open(QFile::ReadOnly)) {
auto data = qFile.readAll();
qFile.close();
QJsonParseError err;
auto json = QJsonDocument::fromJson(data, &err);
if(err.error==QJsonParseError::NoError && json.isObject() && ! json.isEmpty()) mModule = json.object();
}
}
}
auto receivePanel = new QWidget;
tab->addTab(receivePanel, "接收卡");
{
auto vBox = new VBox(receivePanel);
auto gBox = new QGroupBox("模组信息");
vBox->addWidget(gBox);
{
auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh);
auto lb = new QLabel("驱动芯片: ");
vvv->addWidget(lb);
lb = new QLabel("译码方式: ");
vvv->addWidget(lb);
vvv = new VBox(hh);
fdChipType = new QLabel(mModule["ChipType"].toString());
vvv->addWidget(fdChipType);
fdDecodeMode = new QLabel(mModule["DecodeMode"].toString());//译码方式
vvv->addWidget(fdDecodeMode);
hh->addSpacing(20);
vvv = new VBox(hh);
lb = new QLabel("模组宽度: ");
vvv->addWidget(lb);
lb = new QLabel("模组高度: ");
vvv->addWidget(lb);
vvv = new VBox(hh);
fdModuleWidth = new QLabel(QString::number(mModule["ModuleWidth"].toInt()));
vvv->addWidget(fdModuleWidth);
fdModuleHeight = new QLabel(QString::number(mModule["ModuleHeight"].toInt()));
vvv->addWidget(fdModuleHeight);
hh->addSpacing(20);
vvv = new VBox(hh);
lb = new QLabel("扫描数: ");
vvv->addWidget(lb);
lb = new QLabel("数据数组: ");
vvv->addWidget(lb);
vvv = new VBox(hh);
fdScanNum = new QLabel(QString::number(mModule["ScanNum"].toInt()));
vvv->addWidget(fdScanNum);
fdGroupNum = new QLabel(QString::number(mModule["GroupNum"].toInt()));
vvv->addWidget(fdGroupNum);
hh->addSpacing(20);
vvv = new VBox(hh);
auto btn = new QPushButton(tr("数据线颜色"));
btn->setStyleSheet("QPushButton {border: none; }");
vvv->addWidget(btn);
btn = new QPushButton(tr("模组抽行设置"));
btn->setStyleSheet("QPushButton {border: none; }");
vvv->addWidget(btn);
hh->addStretch();
vvv = new VBox(hh);
btn = new QPushButton("模组选择");
btn->setProperty("ss","blue");
vvv->addWidget(btn);
btn = new QPushButton("智能设置");
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [this] {
(new ExpertSmartPointSetWin(this))->show();
});
vvv->addWidget(btn);
}
gBox = new QGroupBox("单卡带载");
vBox->addWidget(gBox);
{
auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh);
auto fdNormal = new QRadioButton("常规设计");
fdNormal->setChecked(true);
vvv->addWidget(fdNormal);
auto fdAdvacned = new QRadioButton("高级设计");
vvv->addWidget(fdAdvacned);
hh->addSpacing(20);
auto line = new QFrame;
line->setFrameShadow(QFrame::Sunken);
line->setFrameShape(QFrame::VLine);
hh->addWidget(line);
auto stack = new QStackedWidget;
auto poli = stack->sizePolicy();
poli.setVerticalPolicy(QSizePolicy::Maximum);
stack->setSizePolicy(poli);
hh->addWidget(stack);
auto normalPanel = new QWidget;
stack->addWidget(normalPanel);
{
auto hh = new HBox(normalPanel);
hh->setContentsMargins(0,0,0,0);
auto vvv = new VBox(hh);
auto lb = new QLabel(tr("宽度"));
vvv->addWidget(lb);
lb = new QLabel(tr("高度"));
vvv->addWidget(lb);
vvv = new VBox(hh);
fdCardWidth = new QSpinBox;
fdCardWidth->setRange(0, 99999);
fdCardWidth->setValue(mBox["ModuleRow"].toInt() * mModule["ModuleWidth"].toInt());
vvv->addWidget(fdCardWidth);
fdCardHeight = new QSpinBox;
fdCardHeight->setRange(0, 99999);
fdCardHeight->setValue(mBox["ModuleCol"].toInt() * mModule["ModuleHeight"].toInt());
vvv->addWidget(fdCardHeight);
hh->addSpacing(20);
vvv = new VBox(hh);
lb = new QLabel(tr("多开设置"));
vvv->addWidget(lb);
lb = new QLabel(tr("级联方向"));
vvv->addWidget(lb);
vvv = new VBox(hh);
fdSectorCount = new QComboBox;
fdSectorCount->addItem(tr(""), 1);
fdSectorCount->addItem(tr("双开"), 2);
fdSectorCount->addItem(tr("三开"), 3);
fdSectorCount->addItem(tr("四开"), 4);
fdSectorCount->addItem(tr("五开"), 5);
fdSectorCount->addItem(tr("六开"), 6);
fdSectorCount->addItem(tr("七开"), 7);
fdSectorCount->addItem(tr("八开"), 8);
select(fdSectorCount, mBox["SectorCount"].toInt());
vvv->addWidget(fdSectorCount);
fdDirection = new QComboBox();
fdDirection->addItem(tr("从左到右"));
fdDirection->addItem(tr("从右到左"));
fdDirection->addItem(tr("从上到下"));
fdDirection->addItem(tr("从下到上"));
fdDirection->setCurrentIndex(mBox["ModuleDirection"].toInt());
vvv->addWidget(fdDirection);
hh->addStretch();
vvv = new VBox(hh);
auto cb = new QCheckBox(tr("旋转180°"));
vvv->addWidget(cb);
auto btn = new QPushButton(tr("数据交换"));
btn->setProperty("ss","blue");
vvv->addWidget(btn);
}
auto advacnedPanel = new QWidget;
stack->addWidget(advacnedPanel);
{
auto hh = new HBox(advacnedPanel);
hh->setContentsMargins(0,0,0,0);
vvv = new VBox(hh);
auto btn = new QPushButton(tr("平面造型"));
btn->setProperty("ss","blue");
btn->setMaximumWidth(100);
vvv->addWidget(btn);
}
connect(fdNormal, &QRadioButton::toggled, this, [=](bool checked) {
stack->setCurrentWidget(checked ? normalPanel : advacnedPanel);
});
}
gBox = new QGroupBox(tr("效果测试"));
vBox->addWidget(gBox);
{
auto hh = new HBox(gBox);
hh->addSpacing(20);
auto vvv = new VBox(hh);
auto hhh = new HBox(vvv);
auto lb = new QLabel(tr("视觉刷新率:"));
hhh->addWidget(lb);
auto cbFresh = new QComboBox();
cbFresh->addItem("960");
cbFresh->addItem("1920");
cbFresh->addItem("2880");
cbFresh->addItem("3840");
hhh->addWidget(cbFresh);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK频率:"));
hhh->addWidget(lb);
auto cbDCLKf = new QComboBox();
cbDCLKf->addItem("25M");
cbDCLKf->addItem("20.83M");
cbDCLKf->addItem("17.86M");
cbDCLKf->addItem("15.63M");
cbDCLKf->addItem("13.89M");
cbDCLKf->addItem("12.5M");
cbDCLKf->addItem("11.36M");
cbDCLKf->addItem("10.42M");
cbDCLKf->addItem("9.62M");
hhh->addWidget(cbDCLKf);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK相位:"));
hhh->addWidget(lb);
auto spinDclkXw = new QSpinBox;
spinDclkXw->setRange(0, 99999);
hhh->addWidget(spinDclkXw);
hhh = new HBox(vvv);
lb = new QLabel(tr("DCLK占空比:"));
hhh->addWidget(lb);
auto spinDclkZkb = new QSpinBox;
spinDclkZkb->setRange(20, 80);
hhh->addWidget(spinDclkZkb);
hhh = new HBox(vvv);
lb = new QLabel(tr("换行时间(ns):"));
hhh->addWidget(lb);
auto spinLineNs = new QSpinBox;
spinLineNs->setRange(2, 9999);
hhh->addWidget(spinLineNs);
hh->addSpacing(20);
vvv = new VBox(hh);
hhh = new HBox(vvv);
lb = new QLabel(tr("亮度有效率:"));
hhh->addWidget(lb);
lb = new QLabel(tr("100%"));
hhh->addWidget(lb);
hhh = new HBox(vvv);
lb = new QLabel(tr("GCLK频率:"));
hhh->addWidget(lb);
auto cbGCLKf = new QComboBox();
cbGCLKf->addItem("25M");
cbGCLKf->addItem("20.83M");
cbGCLKf->addItem("17.86M");
cbGCLKf->addItem("15.63M");
cbGCLKf->addItem("13.89M");
cbGCLKf->addItem("12.5M");
cbGCLKf->addItem("11.36M");
cbGCLKf->addItem("10.42M");
cbGCLKf->addItem("9.62M");
hhh->addWidget(cbGCLKf);
hhh = new HBox(vvv);
lb = new QLabel(tr("灰度级数:"));
hhh->addWidget(lb);
auto cbGryLevel = new QComboBox();
cbGryLevel->addItem("256");
cbGryLevel->addItem("1024");
cbGryLevel->addItem("4096");
cbGryLevel->addItem("8192");
cbGryLevel->addItem("16384");
cbGryLevel->addItem("32768");
cbGryLevel->addItem("65536");
hhh->addWidget(cbGryLevel);
hhh = new HBox(vvv);
lb = new QLabel(tr("GCLK占空比:"));
hhh->addWidget(lb);
auto spinGclkZkb = new QSpinBox;
spinGclkZkb->setRange(20, 80);
hhh->addWidget(spinGclkZkb);
hhh = new HBox(vvv);
lb = new QLabel(tr("换行位置(ns):"));
hhh->addWidget(lb);
auto spinLineWz = new QSpinBox;
spinLineWz->setRange(2, 9999);
hhh->addWidget(spinLineWz);
hh->addStretch();
vvv = new VBox(hh);
hhh = new HBox(vvv);
auto btn = new QPushButton(tr("更多设置"));
btn->setProperty("ss","blue");
hhh->addWidget(btn);
}
vBox->addStretch();
//保存,发送,固话,回读区
auto hBox = new HBox(vBox);
hBox->addSpacing(20);
auto btn = new QPushButton(tr("打开配置"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("保存配置"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
auto dir = QApplication::applicationDirPath()+"/BoxFiles";
QDir(dir).mkdir(".");
auto file = QFileDialog::getSaveFileName(this, tr("保存文件"), dir, tr("Box file (*.box)"));
if(file.isEmpty()) return;
QFile qFile(file);
if(! qFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
return;
}
auto res = qFile.write(savedData());
qFile.close();
if(res < 0) {
QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
return;
}
QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
});
hBox->addWidget(btn);
hBox->addStretch();
btn = new QPushButton(tr("保存Map"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
auto dir = QApplication::applicationDirPath();
auto file = QFileDialog::getSaveFileName(this, tr("保存文件"), dir);
if(file.isEmpty()) return;
QFile qFile(file);
if(! qFile.open(QFile::WriteOnly)) {
QMessageBox::critical(this, tr("失败"), QString(tr("准备写入 %1 文件失败")).arg(file));
return;
}
QByteArray data;
addMapData(data);
auto res = qFile.write(data);
qFile.close();
if(res < 0) {
QMessageBox::critical(this, tr("失败"), QString(tr("写入 %1 文件失败")).arg(file));
return;
}
QMessageBox::information(this, tr("保存成功"), tr("保存成功"));
});
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("发送数据"));
btn->setProperty("ss","blue");
connect(btn, &QPushButton::clicked, this, [=] {
QByteArray data;
addMapData(data);
QMessageBox::information(this, tr("发送成功"), tr("发送成功"));
});
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("固化数据"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
hBox->addSpacing(20);
btn = new QPushButton(tr("回读数据"));
btn->setProperty("ss","blue");
hBox->addWidget(btn);
vBox->addStretch();
//状态栏
auto statusWgt = new QWidget;
statusWgt->setStyleSheet("QWidget{background-color:#222;}");
vBox->addWidget(statusWgt);
{
auto hh = new HBox(statusWgt);
auto lb = new QLabel(tr("状态:"));
hh->addWidget(lb);
}
}
auto connPanel = new QWidget;
tab->addTab(connPanel, tr("显示屏连接(正面看屏)"));
{
auto vBox = new QVBoxLayout(connPanel);
vBox->setContentsMargins(4, 4, 4, 4);
auto hhh = new QHBoxLayout;
vBox->addLayout(hhh);
auto bnScreen = new QPushButton("屏1");
hhh->addWidget(bnScreen);
hhh->addStretch();
auto lb = new QLabel("显示屏数目:");
hhh->addWidget(lb);
auto fdScreenCnt = new QSpinBox;
fdScreenCnt->setRange(1, 99);
fdScreenCnt->setValue(1);
hhh->addWidget(fdScreenCnt);
auto stack = new QStackedLayout;
vBox->addLayout(stack);
stack->addWidget(new ExpertScreenConnWin());
}
}
void ExpertWin::closeEvent(QCloseEvent *event) {
BaseWin::closeEvent(event);
QFile qFile(QApplication::applicationDirPath()+"/temp.screen");
if(! qFile.open(QFile::WriteOnly)) return;
qFile.write(savedData());
qFile.close();
}
QByteArray ExpertWin::savedData() {
mBox.insert("ModuleInfo", mModule);
auto ModuleWidth = mModule["ModuleWidth"].toInt();
auto ModuleHeight = mModule["ModuleHeight"].toInt();
mBox.insert("ModuleRow", (fdCardWidth->value() + ModuleWidth - 1) / ModuleWidth);
mBox.insert("ModuleCol", (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight);
mBox.insert("ModuleDirection", fdDirection->currentIndex());
mBox.insert("SectorCount", fdSectorCount->currentData().toInt());
QJsonObject obj{{"ModuleConnectionInfo", mBox}};
return QJsonDocument(obj).toJson(QJsonDocument::Indented);
}
void ExpertWin::addMapData(QByteArray &data) {
auto ModuleWidth = mModule["ModuleWidth"].toInt();
auto ModuleHeight = mModule["ModuleHeight"].toInt();
auto ModuleRow = (fdCardWidth->value() + ModuleWidth - 1) / ModuleWidth;
auto ModuleCol = (fdCardHeight->value() + ModuleHeight - 1) / ModuleHeight;
auto CardWidth = ModuleRow * ModuleWidth;
auto CardHeight = ModuleCol * ModuleHeight;
auto ModuleDirection = fdDirection->currentIndex();
//auto SectorCount = fdSectorCount->currentData().toInt();
QMap<uint, uint> map;
int memY = 0, memX = 0;
for(int boxY=0; boxY<CardHeight; boxY++) {
for(int boxX=0; boxX<CardWidth; boxX++) {
if(memX > 255) {
memX = 0;
memY++;
}
map.insert(boxY<<16|boxX, memY<<16|memX);
memX++;
}
memX = 0;
memY++;
}
auto points = mModule["Points"].toArray();
auto scans = mModule["Scans"].toArray();
auto GroupNum = mModule["GroupNum"].toInt();
auto jCnt = ModuleCol * GroupNum;
foreach(auto scan, scans) {
QList<QList<QByteArray>> chunkses;
for(int j=0; j<jCnt; j++) {
int lastMemY = INT_MIN;
int lastMemX = -1;
int cnt = 1, ttl = 1;
bool isAnti = false;
QList<QByteArray> chunks;
QByteArray chunk;
QString chstr;
for(int mm=0; mm<ModuleRow; mm++) {
int m = ModuleDirection==0 ? ModuleRow-1-mm : mm;
foreach(auto point, points) {
uint boxY = j * scans.size() + scan.toInt();
uint boxX = m * ModuleWidth + point.toInt();
if(boxX < 0) { //虚点
if(lastMemY==-1) memX = lastMemX + 1;
else {
memY = -1;
memX = 0;
}
} else {
auto mem = map[boxY<<16 | boxX];
memY = mem >> 16;
memX = mem & 0xffff;
}
if(memY==lastMemY && ttl < 64 && qAbs(memX-lastMemX)==1) {
if(cnt==1) {
isAnti = memX < lastMemX;
cnt++;
ttl++;
lastMemX = memX;
continue;
} else if(memX < lastMemX == isAnti) {
cnt++;
ttl++;
lastMemX = memX;
continue;
}
}
if(lastMemY > INT_MIN) {
uint y = lastMemY==-1 ? 0 : lastMemY;
uint x = isAnti ? lastMemX : lastMemX-cnt+1;
chunk.append((j << 2) + (y >> 8)).append(y).append(x).append((isAnti << 7)+cnt);
chstr += QString("j%1 行%2 列%3 序%4 长%5").arg(j).arg(y).arg(x).arg(isAnti).arg(cnt);
}
if(ttl>=64) {
chunks.append(chunk);
chunk = QByteArray();
qDebug() << chstr;
chstr.clear();
ttl = 1;
}
cnt = 1;
lastMemY = memY;
lastMemX = lastMemY==-1 ? 0 : memX;
}
}
uint y = lastMemY==-1 ? 0 : lastMemY;
uint x = isAnti ? lastMemX : lastMemX-cnt+1;
chunk.append((j << 2) + (y >> 8)).append(y).append(x).append((isAnti << 7)+cnt);
chstr += QString("j%1 行%2 列%3 序%4 长%5").arg(j).arg(y).arg(x).arg(isAnti).arg(cnt);
chunks.append(chunk);
chunkses.append(chunks);
qDebug() << chstr;
}
data.append(0xAA).append(scan.toInt()).append(2, 0);
auto chend = chunkses[0].size()-1;
auto start = data.size();
for(int ch=0; ch<=chend; ch++) {
data.append(0x55).append(ch==chend ? (char)(1<<7) : 0).append(2, 0);
auto start = data.size();
foreach(auto chunks, chunkses) data.append(chunks[ch]);
auto num = (data.size() - start) / 4;
data[start-2] = num;
data[start-3] = num>>8;
}
auto len = data.size() - start;
data[start-1] = len;
data[start-2] = len>>8;
}
}
#define MAX_ONCE 1482
void run() {
// quint32 idx = 0;
// while(2) {
// QByteArray bytes;
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
// bytes.append("\0\x4", 2); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append("\x35\0\xc\xbb", 4); //内存指针
// bytes.append(2, 0); //应答填充项
// auto crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-4, 4);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// //发送帧开始指令包
// auto queue = pcap_sendqueue_alloc(img.width()*img.height()*4);
// {
// struct pcap_pkthdr pktheader;
// pktheader.len = pktheader.caplen = bytes.size();
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加开始失败: ")+pcap_geterr(pcap));
// goto end;
// }
// idx = 0;
// //按行发送图像数据包
// for(int i=0; i<img.height(); i++) for(int j=0; j<lineLen; j+=once) {
// int dataLen = lineLen - j;
// if(dataLen > once) dataLen = once;
// dataLen += 4;
// bytes.clear();
// bytes.append("\x55\x55\x1\x33"); //前导, 版本号, 服务类型
// bytes.append(dataLen>>8).append(dataLen); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append(i>>8).append(i).append(j>>8).append(j); //内存指针
// bytes.append(2, 0); //应答填充项
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// bytes.append(idx>>24).append(idx>>16).append(idx>>8).append(idx);//包序号
// idx++;
// bytes.append((const char*)bits + i * bytesPerLine + j, dataLen - 4);
// crc32 = crc32_calc((uint8_t*)bytes.data()+bytes.length()-dataLen, dataLen);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// pktheader.len = pktheader.caplen = bytes.size();
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加数据失败: ")+pcap_geterr(pcap));
// goto end;
// }
// }
// bytes.clear();
// bytes.append("\x55\x55\x9a\x3d"); //前导, 版本号, 服务类型
// bytes.append(2, 0); //数据长度
// bytes.append(4, '\xff'); //目的地址
// bytes.append(4, 0); //源地址
// bytes.append("\x35\0\xc\xcc", 4); //内存指针
// bytes.append(2, 0); //应答填充项
// crc32 = crc32_calc((uint8_t*)bytes.data()+2, bytes.length()-2);
// bytes.append(crc32>>24).append(crc32>>16).append(crc32>>8).append(crc32);
// pktheader.len = pktheader.caplen = bytes.size();
// //发送帧结束指令包
// if(pcap_sendqueue_queue(queue, &pktheader, (u_char*)bytes.data()) == -1) {
// onErr(QString("添加结束失败: ")+pcap_geterr(pcap));
// goto end;
// }
// u_int res;
// if((res = pcap_sendqueue_transmit(pcap, queue, 0)) < queue->len) {
// onErr(QString::asprintf("发送包出错: %s. 仅发了 %d / %d bytes", pcap_geterr(pcap), res, queue->len));
// goto end;
// }
// }
// end:
// pcap_sendqueue_destroy(queue);
// }
}
ReceThread::ReceThread(pcap_t *pcap) : pcap(pcap) {
connect(this, &QThread::finished, this, &QThread::deleteLater);
}
void ReceThread::run() {
pcap_pkthdr *header;
const u_char *data;
int res;
while((res = pcap_next_ex(pcap, &header, &data)) >= 0) {
if(status==2) return;
if(status==1 || res == 0 || !showImg) continue; //超时
if(header->caplen<24) continue;
if(data[0]!=0x55 || data[1]!=0x55) continue;
if(data[2]==0x9a && data[3]==0x3d) {
// if(data[17]==0xBB) {
// emit onMsg(((int)data[24] << 8) + data[25], ((int)data[26] << 8) + data[27]);
// } else if(data[17]==0xCC) emit onMsg(img);
continue;
}
}
emit onErr(pcap_geterr(pcap));
}