diff --git a/ledset/expertsmartpointsetwin.cpp b/ledset/expertsmartpointsetwin.cpp index 7c41db6..41f088d 100644 --- a/ledset/expertsmartpointsetwin.cpp +++ b/ledset/expertsmartpointsetwin.cpp @@ -28,7 +28,7 @@ struct ModUnitMap { byte decodeMode{ipp(2)}; byte ex3{ipp(4)}; byte smartset{ipp(4)}; - byte smartset2{ipp(4)}; + byte smartsetRes{ipp(4)}; byte 走点len{ipp(4)}; byte endFlag{ipp(4)}; byte end{fi}; @@ -453,6 +453,86 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e vv->addStretch(); + vv = new VBox(stack); + vv->setContentsMargins(50, 50, 6, 6); + + lb = new QLabel(tr("数据极性选择")); + gFont(lb, 16); + lb->setPalette(bkBlue); + vv->addWidget(lb); + vv->addSpacing(50); + + auto hh = new HBox(vv); + hh->addStretch(); + auto vvv = new VBox(hh); + + lb = new QLabel(tr("点击状态 1,状态 2,观察 LED 模块,选择全亮状态: ")); + vvv->addWidget(lb); + vvv->addSpacing(30); + + hhhh = new HBox(vvv); + hhhh->addStretch(); + + auto fdPolaStat1 = new QRadioButton(tr("状态 1")); + fdPolaStat1->setChecked(true); + hhhh->addWidget(fdPolaStat1); + hhhh->addStretch(); + + auto fdPolaStat2 = new QRadioButton(tr("状态 2")); + hhhh->addWidget(fdPolaStat2); + hhhh->addStretch(); + + auto fdPolaStat = new QButtonGroup(fdPolaStat1); + fdPolaStat->addButton(fdPolaStat1, 0); + fdPolaStat->addButton(fdPolaStat2, 1); + connect(fdPolaStat, &QButtonGroup::idClicked, this, [this] (int id) { + send(0x11, {0x01000000u | id}); + }); + + vvv->addStretch(); + hh->addStretch(); + + + vv = new VBox(stack); + vv->setContentsMargins(50, 50, 6, 6); + + lb = new QLabel(tr("OE极性选择")); + gFont(lb, 16); + lb->setPalette(bkBlue); + vv->addWidget(lb); + vv->addSpacing(50); + + hh = new HBox(vv); + hh->addStretch(); + vvv = new VBox(hh); + + lb = new QLabel(tr("点击状态 1,状态 2,观察 LED 模块,选择高亮状态: ")); + vvv->addWidget(lb); + vvv->addSpacing(30); + + hhhh = new HBox(vvv); + hhhh->addStretch(); + + auto fdOEStat1 = new QRadioButton(tr("状态 1")); + fdOEStat1->setChecked(true); + hhhh->addWidget(fdOEStat1); + hhhh->addStretch(); + + auto fdOEStat2 = new QRadioButton(tr("状态 2")); + hhhh->addWidget(fdOEStat2); + hhhh->addStretch(); + + auto fdOEStat = new QButtonGroup(fdOEStat1); + fdOEStat->addButton(fdOEStat1, 0); + fdOEStat->addButton(fdOEStat2, 1); + connect(fdOEStat, &QButtonGroup::idClicked, this, [this] (int id) { + send(0x11, {0x01100000u | id}); + }); + + vvv->addStretch(); + hh->addStretch(); + + vv = new VBox(stack); vv->setContentsMargins(50, 50, 6, 6); @@ -462,10 +542,10 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e vv->addWidget(lb); vv->addSpacing(50); - auto hBox = new HBox(vv); - hBox->addStretch(); + hh = new HBox(vv); + hh->addStretch(); - auto vvv = new VBox(hBox); + vvv = new VBox(hh); lb = new QLabel(tr("根据亮线的行/列数确定扫描行/列数: ")); vvv->addWidget(lb); @@ -483,7 +563,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e hhhh->addWidget(fdCol); hhhh->addStretch(); - auto grp = new QButtonGroup; + auto grp = new QButtonGroup(fdRow); grp->addButton(fdRow, 0); grp->addButton(fdCol, 1); @@ -495,18 +575,18 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e lb = new QLabel(tr("亮线的行/列数: ")); hhhh->addWidget(lb); - auto fdNum = new QSpinBox; - fdNum->setRange(0, 9999); - fdNum->setValue(1); - hhhh->addWidget(fdNum); + auto fdLightNum = new QSpinBox; + fdLightNum->setRange(0, 9999); + fdLightNum->setValue(2); + hhhh->addWidget(fdLightNum); hhhh->addStretch(); vvv->addStretch(); - hBox->addStretch(); + hh->addStretch(); - vvv = new VBox(hBox); + vvv = new VBox(hh); lb = new QLabel(tr("芯片245版本: ")); vvv->addWidget(lb); @@ -524,7 +604,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e hhhh->addStretch(); vvv->addStretch(); - hBox->addStretch(); + hh->addStretch(); vv = new VBox(stack); @@ -546,46 +626,26 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e grid->setColumnStretch(2, 1); grid->setColumnStretch(7, 1); - auto fdStas = new QButtonGroup(grid); - auto fdRs = new QButtonGroup(grid); - auto fdGs = new QButtonGroup(grid); - auto fdBs = new QButtonGroup(grid); - auto fdNos = new QButtonGroup(grid); + auto fdRGBStat = new QButtonGroup(grid); + QButtonGroup *fdRGBs[3]; for(int rr = 0; rr < 3; ++rr) { - fdStas->addButton(new QRadioButton(tr("状态")+QString::number(rr+1)), rr); - fdRs->addButton(new QRadioButton(tr("红")), rr); - fdGs->addButton(new QRadioButton(tr("绿")), rr); - fdBs->addButton(new QRadioButton(tr("蓝")), rr); - fdNos->addButton(new QRadioButton(tr("黑")), rr); - grid->addWidget(fdStas->button(rr), rr, 1); - grid->addWidget(fdRs->button(rr), rr, 3); - grid->addWidget(fdGs->button(rr), rr, 4); - grid->addWidget(fdBs->button(rr), rr, 5); - grid->addWidget(fdNos->button(rr), rr, 6); + fdRGBStat->addButton(new QRadioButton(tr("状态")+QString::number(rr+1)), rr); + fdRGBs[rr] = new QButtonGroup(grid); + fdRGBs[rr]->addButton(new QRadioButton(tr("红")), 1); + fdRGBs[rr]->addButton(new QRadioButton(tr("绿")), 2); + fdRGBs[rr]->addButton(new QRadioButton(tr("蓝")), 3); + fdRGBs[rr]->addButton(new QRadioButton(tr("黑")), 0); + fdRGBs[rr]->button(rr+1)->setChecked(true); + grid->addWidget(fdRGBStat->button(rr), rr, 1); + grid->addWidget(fdRGBs[rr]->button(1), rr, 3); + grid->addWidget(fdRGBs[rr]->button(2), rr, 4); + grid->addWidget(fdRGBs[rr]->button(3), rr, 5); + grid->addWidget(fdRGBs[rr]->button(0), rr, 6); } - fdStas->button(0)->setChecked(true); - fdRs->button(0)->setChecked(true); - fdGs->button(1)->setChecked(true); - fdBs->button(2)->setChecked(true); + fdRGBStat->button(0)->setChecked(true); - connect(fdStas, &QButtonGroup::idClicked, this, [this] (int id) { - auto msg = QByteArray::fromHex("5555 01AD 000A FFFFFFFF 0000ABCD B1000011 0000 D10CD484 AD000011 0004 01200000 0BF4F928"); - msg[msg.size()-5] = id; - auto check = (quint32_be*)(msg.data()+msg.size()-4); - *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-4-headMap.body); - qDebug()<<"check"<close(); - QMessageBox::critical(this, "Error", tr("请求超时")); - return; - } - waitingDlg->close(); - qDebug()<<"resp back. RGB status:"<addStretch(); @@ -667,26 +727,21 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e auto realCnt = cnt - virtualCnt; table->setText(row, col, QString::number(realCnt))->setTextAlignment(Qt::AlignCenter); if(realCnt!=ModuleWidth) { - sendPoint(cnt); + if(send(0x11, {0x01400000u | cnt}) == 0) qDebug()<<"resp back. col:"<setText(row, col, "S"+QString::number(size))->setTextAlignment(Qt::AlignCenter); - if(size!=ScanNum) sendPoint(size<<10); - else { + if(size!=ScanNum) { + if(send(0x11, {0x01400000u | (size<<10)}) == 0) qDebug()<<"resp back. row:"<close(); - qDebug()<<"resp back. point end."; + send(0x11, {0}); save(); } } @@ -708,7 +763,7 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e vBox->addWidget(tableRow); } - hBox = new HBox(vBox); + auto hBox = new HBox(vBox); hBox->addStretch(); auto btnPrev = new QPushButton(tr("上一步")); @@ -737,75 +792,66 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e GroupMode = fdGroupMode->currentText(); // 开始标识 保留 长度 换行间/刻 OE宽 放电间 芯片通道数 模组类型数 auto msg = QByteArray::fromHex("5555 01AD 0062 FFFFFFFF 0000ABCD B1000000 0000 415F94A7 AD000000 005C AA55AA55 0000 0036 1770 0000 0280 0000 32 10 00 00 0A 01 00 00 001000 01 " - "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 00000000 00000008 00400020 00001400 FF00FF00 3C000000 00000000 1B022020 00000040 55AA55AA 00000000 39F424F6 351B0E53"); + "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB 00000000 00000008 00200020 00001400 FF00FF00 3C000000 01000000 1B020010 00000020 55AA55AA 00000000 39F424F6 351B0E53"); // UUID type len w h ex1 chip/decode ex3 smartset smartset2 走点len endFlag auto unitptr = msg.data()+headMap.end+modMap.Unit; auto w = (quint16_be*)(unitptr+modUnitMap.w); *w = ModuleWidth; auto h = (quint16_be*)(unitptr+modUnitMap.h); *h = ModuleHeight; - auto groupNum = unitptr+modUnitMap.smartset2 + 1; - *groupNum = GroupNum; auto chipType = (quint16_be*)(unitptr+modUnitMap.chipType); *chipType = ChipTypeCode; auto decodeMode = (quint16_be*)(unitptr+modUnitMap.decodeMode); *decodeMode = DecodeModeCode; + auto smartset = unitptr+modUnitMap.smartset+3; + *smartset = fdPolaStat->checkedId(); + + auto groupNum = unitptr+modUnitMap.smartsetRes + 1; + *groupNum = GroupNum; + auto scanNum = unitptr+modUnitMap.smartsetRes + 3; + *scanNum = ModuleHeight / GroupNum; + auto 走点len = (quint32_be*)(unitptr+modUnitMap.走点len); + *走点len = (ModuleWidth+15) / 16 * 16; auto check = (quint32_be*)(msg.data()+headMap.end+modMap.check); *check = crc32_calc((byte*)msg.data()+headMap.end+modMap.换行时间, modMap.check - modMap.换行时间); - check = (quint32_be*)(msg.data()+headMap.end+modMap.end); *check = crc32_calc((byte*)msg.data()+headMap.body, modMap.end+6); - qDebug()<<"check"<close(); - QMessageBox::critical(this, "Error", tr("请求超时")); - return; - } - auto msg = QByteArray::fromHex(QByteArray("5555 01AD 000A FFFFFFFF 0000ABCD B1000011 0000 D10CD484 AD000011 0004 01300000 17D25A58")); - auto res = sendMsg(msg, 0x1EA, 10000, [=](int code, const QByteArray data) { - if(code==5) { - waitingDlg->close(); - QMessageBox::critical(this, "Error", tr("请求超时")); - return; - } - waitingDlg->close(); - auto iii = idx+1; - stack->setCurrentIndex(iii); - btnPrev->setEnabled(iii > 0); - btnNext->setEnabled(iii < stack->count()-1); - }, waitingDlg); - if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); - }, waitingDlg); - if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); + auto res = sendMsgSync(msg, 0x1EA, 10000, waitingDlg); + if(res==5) {QMessageBox::critical(this, "Error", tr("请求超时")); return;} + else if(res) {QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); return;} + waitingDlg->close(); } else if(idx==1) { - //GroupMode = fdNum->value(); - auto msg = QByteArray::fromHex("5555 01AD 000A FFFFFFFF 0000ABCD B1000011 0000 D10CD484 AD000011 0004 01200000 0BF4F928"); - auto id = fdStas->checkedId(); - if(id) { - msg[msg.size()-5] = id; - auto check = (quint32_be*)(msg.data()+msg.size()-4); - *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-4-headMap.body); - } - auto waitingDlg = new WaitingDlg(this, tr("Setting")+" ..."); - auto res = sendMsg(msg, 0x1EA, 10000, [=](int code, const QByteArray data) { - if(code==5) { - waitingDlg->close(); - QMessageBox::critical(this, "Error", tr("请求超时")); - return; - } - waitingDlg->close(); - auto iii = idx+1; - stack->setCurrentIndex(iii); - btnPrev->setEnabled(iii > 0); - btnNext->setEnabled(iii < stack->count()-1); - }, waitingDlg); - if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); + res12 &= ~(1u<<31); + res12 |= (uint)fdPolaStat->checkedId()<<31; + if(send(0x11, {0x01100000u | fdOEStat->checkedId(), res12})) return; } else if(idx==2) { - if(sendPoint(0)) return; + res12 &= ~(1u<<30); + res12 |= (uint)fdOEStat->checkedId()<<30; + if(send(0x11, {0x01300000u, res12})) return; + } else if(idx==3) { + lightNum = fdLightNum->value(); + res12 &= ~0xffffu; + res12 |= (uint)(lightNum / GroupNum - 1)<<8; //折返次数 + res12 |= (uint)(ModuleHeight / lightNum); //扫描类型 + if(send(0x11, {0x01200000u | fdRGBStat->checkedId(), res12, ((uint)ModuleWidth+15) / 16 * 16 * lightNum / GroupNum})) return; + } else if(idx==4) { + bool hases[4]{true,true,true,true}; + uint ids[4]; + for(int i=0; i<3; ++i) { + ids[i] = fdRGBs[i]->checkedId(); + hases[ids[i]] = false; + } + for(int i=0; i<4; ++i) if(hases[i]) { + ids[3] = i; + break; + } + res12 &= ~(0xffu<<22); + res12 |= (ids[0]<<6 | ids[1]<<4 | ids[2]<<2 | ids[3]) << 22; + if(send(0x11, {0x01400000u, res12})) return; table->setColumnCount(ModuleWidth); table->setRowCount(ModuleHeight); QColor altColor(0x445566); @@ -813,33 +859,49 @@ ExpertSmartPointSetWin::ExpertSmartPointSetWin(ExpertWin *expertWin) : BaseWin{e if((r&7)!=7) for(int c=7; citemValid(r, c)->setBackground(altColor); else for(int c=0; citemValid(r, c)->setBackground(altColor); } - auto iii = idx+1; - stack->setCurrentIndex(iii); - btnPrev->setEnabled(iii > 0); - btnNext->setEnabled(iii < stack->count()-1); } + stack->setCurrentIndex(++idx); + btnPrev->setEnabled(idx > 0); + btnNext->setEnabled(idx < stack->count()-1); }); auto btnCcl = new QPushButton("取消"); + connect(btnCcl, &QPushButton::clicked, this, [=] { + send(0x11, {0}); + close(); + }); btnCcl->setMinimumSize(90, 30); hBox->addWidget(btnCcl); hBox->addSpacing(30); } -int ExpertSmartPointSetWin::sendPoint(uint cnt) { - auto msg = QByteArray::fromHex("5555 01AD 000A FFFFFFFF 0000ABCD B1000011 0000 D10CD484 AD000011 0004 01400000 43233208"); - if(cnt) { - auto idx = (quint32_be*)(msg.data()+msg.size()-8); - *idx |= cnt; - auto check = (quint32_be*)(msg.data()+msg.size()-4); - *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-4-headMap.body); + +int ExpertSmartPointSetWin::send(uint ptr, const std::initializer_list &data) { + auto msg = QByteArray::fromHex("5555 01AD 0000 FFFFFFFF 0000ABCD B1000000 0000 00000000 AD000000 0000"); + msg.append((data.size()+1)<<2, 0); + auto plen = (quint16_be*)(msg.data()+headMap.len); + *plen |= (data.size()<<2)+6; + plen = (quint16_be*)(msg.data()+headMap.bodylen); + *plen |= data.size()<<2; + auto pptr = (quint32_be*)(msg.data()+headMap.ptr); + *pptr |= ptr; + pptr = (quint32_be*)(msg.data()+headMap.body); + *pptr |= ptr; + auto pdata = (quint32_be*) (msg.data()+headMap.end); + for(auto dat : data) { + *pdata = dat; + pdata++; } + auto check = (quint32_be*)(msg.data()+headMap.chk); + *check = crc32_calc((byte*)msg.data()+2, headMap.chk-2); + check = (quint32_be*)(msg.data()+msg.size()-4); + *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-4-headMap.body); + auto waitingDlg = new WaitingDlg(this, tr("Setting")+" ..."); auto res = sendMsgSync(msg, 0x1EA, 10000, waitingDlg); if(res==5) QMessageBox::critical(this, "Error", tr("请求超时")); else if(res) QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+QString::fromLocal8Bit(pcap_geterr(pcapSend))); else waitingDlg->close(); - qDebug()<<"resp back. point:"< #include +class WaitingDlg; class ExpertSmartPointSetWin : public BaseWin { Q_OBJECT public: explicit ExpertSmartPointSetWin(ExpertWin *parent = nullptr); - int sendPoint(uint); + int send(uint, const std::initializer_list &); void save(); ExpertWin *expertWin; @@ -26,9 +27,13 @@ public: QLineEdit *fdChipType, *fdDecodeMode; Table *tableChipType, *tableDecodeMode; QComboBox *fdGroupMode; - int ModuleWidth{16}, ModuleHeight{8}, GroupNum{2}, ScanNum{4}; + int ModuleWidth{32}, ModuleHeight{16}, GroupNum{2}, ScanNum{4}; int ChipTypeCode, DecodeModeCode; QString ChipType, DecodeMode, GroupMode; + + int lightNum{2}; + + uint res12; }; #endif // EXPERTSMARTPOINTSETWIN_H diff --git a/ledset/expertwin.h b/ledset/expertwin.h index 8d78c2b..a3778f6 100644 --- a/ledset/expertwin.h +++ b/ledset/expertwin.h @@ -21,8 +21,8 @@ public: QLabel *fdModuleWidth, *fdModuleHeight, *fdGroupNum, *fdScanNum; QLabel *fdChipType, *fdDecodeMode; QJsonObject mModule { - {"ModuleWidth", 16}, - {"ModuleHeight", 8}, + {"ModuleWidth", 32}, + {"ModuleHeight", 16}, {"GroupNum", 2}, {"ScanNum", 4}, {"ChipType", "通用"}, diff --git a/ledset/globalfunc.cpp b/ledset/globalfunc.cpp index 0eeb10b..6d5a2b7 100644 --- a/ledset/globalfunc.cpp +++ b/ledset/globalfunc.cpp @@ -7,6 +7,24 @@ #include HeadMap headMap; + +byte *getSepas() { + auto sepas = new byte[headMap.end+4]{0}; + sepas[headMap.ver] = ' '; + sepas[headMap.srv] = ' '; + sepas[headMap.len] = ' '; + sepas[headMap.tgtAddr] = ' '; + sepas[headMap.srcAddr] = ' '; + sepas[headMap.ptr] = ' '; + sepas[headMap.ans] = ' '; + sepas[headMap.chk] = ' '; + sepas[headMap.body] = '\n'; + sepas[headMap.bodylen] = ' '; + sepas[headMap.end] = ' '; + return sepas; +} + +byte *sepas = getSepas(); pcap_t *pcapSend{0}; PcapReThread *reThd{0}; diff --git a/ledset/globalfunc.h b/ledset/globalfunc.h index ba7d541..09be0b4 100644 --- a/ledset/globalfunc.h +++ b/ledset/globalfunc.h @@ -46,6 +46,7 @@ struct HeadMap { }; extern HeadMap headMap; +extern byte *sepas; extern pcap *pcapSend; class PcapReThread; extern PcapReThread *reThd; diff --git a/ledset/imgs/video.png b/ledset/imgs/test.png similarity index 100% rename from ledset/imgs/video.png rename to ledset/imgs/test.png diff --git a/ledset/ledset.pro b/ledset/ledset.pro index a8af2e5..ab51294 100644 --- a/ledset/ledset.pro +++ b/ledset/ledset.pro @@ -51,8 +51,8 @@ SOURCES += \ mainwin.cpp \ moduleunit.cpp \ pcaprethread.cpp \ - pcapwin.cpp \ screenunit.cpp \ + testwin.cpp \ videowin.cpp \ waitingdlg.cpp @@ -70,8 +70,8 @@ HEADERS += \ mainwin.h \ moduleunit.h \ pcaprethread.h \ - pcapwin.h \ screenunit.h \ + testwin.h \ videowin.h \ waitingdlg.h diff --git a/ledset/mainwin.cpp b/ledset/mainwin.cpp index 237fe34..9fbd963 100644 --- a/ledset/mainwin.cpp +++ b/ledset/mainwin.cpp @@ -3,7 +3,7 @@ #include "fast.h" #include "expertwin.h" #include "brightwin.h" -#include "pcapwin.h" +#include "testwin.h" #include "videowin.h" #include #include @@ -83,36 +83,36 @@ MainWin::MainWin() { QHBoxLayout *imgsBar = new QHBoxLayout(); auto btnImg = addImg(imgsBar, QPixmap(":/imgs/fast.png").scaledToWidth(128, Qt::SmoothTransformation), "快速调屏"); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { (new Fast(this))->show(); }); btnImg = addImg(imgsBar, QPixmap(":/imgs/expert.png").scaledToWidth(128, Qt::SmoothTransformation), tr("专家调屏")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { (new ExpertWin(this))->show(); }); btnImg = addImg(imgsBar, QPixmap(":/imgs/bright.png").scaledToWidth(128, Qt::SmoothTransformation), tr("亮度控制")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { (new BrightWin(this))->show(); }); btnImg = addImg(imgsBar, QPixmap(":/imgs/correct.png").scaledToWidth(128, Qt::SmoothTransformation), tr("相机矫正")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { }); btnImg = addImg(imgsBar, QPixmap(":/imgs/monitor.png").scaledToWidth(128, Qt::SmoothTransformation), tr("屏体监控")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { }); btnImg = addImg(imgsBar, QPixmap(":/imgs/multi.png").scaledToWidth(128, Qt::SmoothTransformation), tr("多功能卡")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { //win->move(win->x()-1, win->y()); }); - btnImg = addImg(imgsBar, QPixmap(":/imgs/video.png").scaledToWidth(128, Qt::SmoothTransformation), tr("协议调试")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ - auto ins = PcapWin::newIns(net_name, this); - if(ins) ins->show(); + btnImg = addImg(imgsBar, QPixmap(":/imgs/test.png").scaledToWidth(128, Qt::SmoothTransformation), tr("协议调试")); + connect(btnImg, &ImgBtn::clicked, this, [=] { + if(reThd->status) return; + (new TestWin(this))->show(); }); btnImg = addImg(imgsBar, QPixmap(":/imgs/idea.png").scaledToWidth(128, Qt::SmoothTransformation), tr("模拟同步")); - connect(btnImg, &ImgBtn::clicked, this, [=](){ + connect(btnImg, &ImgBtn::clicked, this, [=] { auto ins = VideoWin::newIns(net_name, this); if(ins) ins->show(); }); @@ -141,7 +141,7 @@ MainWin::MainWin() { if(name.isEmpty()) return; //PCAP_OPENFLAG_DATATX_UDP:2,它定义了数据传输(假如是远程抓包)是否用UDP协议来处理。 //PCAP_OPENFLAG_NOCAPTURE_RPCAP:4,它定义了远程探测器是否捕获它自己产生的数据包。 - char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; + char errbuf[PCAP_ERRBUF_SIZE]{0}; auto pcapR = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf); if(pcapR == 0) { QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf); @@ -173,7 +173,7 @@ MainWin::MainWin() { auto name = config.value("net_name").toByteArray(); name = getNetDev(this, name, true); if(! name.isEmpty()) { - char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; + char errbuf[PCAP_ERRBUF_SIZE]{0}; auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS|4|8|16, 50, errbuf); if(pcapRe == 0) QMessageBox::critical(this, "Error", QString(tr("打开网卡失败"))+errbuf); else { diff --git a/ledset/pcaprethread.cpp b/ledset/pcaprethread.cpp index 8526b1c..8428de8 100644 --- a/ledset/pcaprethread.cpp +++ b/ledset/pcaprethread.cpp @@ -5,7 +5,7 @@ PcapReThread::PcapReThread(pcap_t *pcap) : pcap(pcap) { qRegisterMetaType("FuncIntByte"); connect(this, &QThread::finished, this, &QThread::deleteLater); - connect(this, &PcapReThread::onMsg, this, [](FuncIntByte callback, int code, const QByteArray data) { + connect(this, &PcapReThread::onCallback, this, [](FuncIntByte callback, int code, const QByteArray data) { callback(code, data); }); } @@ -46,15 +46,13 @@ void PcapReThread::run() { const u_char *data; int cnt; while((cnt = pcap_next_ex(pcap, &header, &data)) >= 0) { - if(status==2) return; - if(resps.isEmpty()) continue; - { + if(! resps.isEmpty()) { std::lock_guard lock(mtx); - if(status==0 && cnt && data[0]==0x55 && data[1]==0x55) { + if(cnt && data[0]==0x55 && data[1]==0x55) { int id = data[2]<<8 | data[3]; for(int i=0; iid==id) { auto resp = resps.takeAt(i); - if(resp->notCancelled) emit onMsg(resp->callback, 0, QByteArray((char*)data, header->caplen)); + if(resp->notCancelled) emit onCallback(resp->callback, 0, QByteArray((char*)data, header->caplen)); delete resp; break; } @@ -62,10 +60,44 @@ void PcapReThread::run() { auto now = std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); for(int i=0; itimeout <= now && resps[i]->timeout > 0) { auto resp = resps.takeAt(i); - if(resp->notCancelled) emit onMsg(resp->callback, 5, QByteArray()); + if(resp->notCancelled) emit onCallback(resp->callback, 5, QByteArray()); delete resp; } } + if(status==1) { + if(cnt == 0 || data[0]!=0x55 || data[1]!=0x55) continue; + QString msg; + msg.append(QDateTime::fromSecsSinceEpoch(header->ts.tv_sec).toString("yy-MM-dd HH:mm:ss.")+QString::number(header->ts.tv_usec)) + .append(" len:").append(QString::number(header->caplen)).append("/").append(QString::number(header->len)).append("\n"); + if(fmt==1) { + char line[LineLen + 1]; + int l = 0; + for(uint i=0; icaplen; i++) { + msg.append(QString::asprintf("%.2X ", data[i])); + if(i > 13) { + if(isgraph(data[i]) || data[i] == ' ') line[l] = data[i]; + else line[l] = '.'; + if(l==15) { + line[16] = 0; + msg.append(" ").append(line).append("\n"); + l = 0; + } else l++; + } else if(i == 13) { + msg.append("\n"); + } + } + line[l] = 0; + msg.append(" ").append(line); + } else { + for(uint i=0; icaplen; i++) { + if(i>headMap.end) msg.append(' '); + else if(sepas[i]) msg.append(sepas[i]); + msg.append(QString::asprintf("%.2X", data[i])); + } + } + msg.append("\n\n"); + emit onMsg(msg); + } } emit onError(pcap_geterr(pcap)); } diff --git a/ledset/pcaprethread.h b/ledset/pcaprethread.h index 21226ef..f9cadc5 100644 --- a/ledset/pcaprethread.h +++ b/ledset/pcaprethread.h @@ -6,6 +6,7 @@ #include typedef std::function FuncIntByte; +#define LineLen 16 struct PcapResp { FuncIntByte callback; @@ -20,12 +21,14 @@ public: ~PcapReThread(); int sendMsgNet(const byte *msg, int size, int id, qint64 timeout, FuncIntByte callback, WaitingDlg *waitingDlg = 0); - std::atomic status{0}; QList resps; std::mutex mtx; pcap *pcap; + std::atomic status{0}; + char fmt{0}; signals: - void onMsg(FuncIntByte callback, int code, const QByteArray data); + void onCallback(FuncIntByte callback, int code, const QByteArray data); + void onMsg(const QString &); void onError(char *); protected: void run(); diff --git a/ledset/pcapwin.cpp b/ledset/pcapwin.cpp deleted file mode 100644 index 5a81245..0000000 --- a/ledset/pcapwin.cpp +++ /dev/null @@ -1,165 +0,0 @@ -#include "pcapwin.h" -#include -#include -#include -#include -#include -#include -#include - -PcapWin *PcapWin::newIns(QByteArray &name, QWidget *parent) { - if(name.isEmpty()) return 0; - char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; - auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf); - if(pcapRe == 0) { - QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf); - return 0; - } - auto pcapSend = pcap_open_live(name.data(), 65536, 0, 50, errbuf); - if(pcapSend == 0) { - QMessageBox::critical(parent, "Error", QString(tr("打开网卡失败"))+errbuf); - return 0; - } - return new PcapWin(pcapRe, pcapSend, parent); -} - -PcapWin::PcapWin(pcap_t *pcapRece, pcap_t *pcapSend, QWidget *parent) : BaseWin{parent}, pcap(pcapSend) { - setWindowModality(Qt::WindowModal); - setAttribute(Qt::WA_DeleteOnClose); - setWindowTitle(tr("网口通信")); - resize(1024, 720); - - auto vBox = new QVBoxLayout(center); - vBox->setContentsMargins(0,0,0,0); - vBox->setSpacing(3); - vBox->addLayout(addBtns(new QHBoxLayout())); - - auto fdReceive = new QTextEdit; - fdReceive->setFontFamily("Consolas"); - fdReceive->setReadOnly(true); - fdReceive->document()->setMaximumBlockCount(200); - - auto hBox = new QHBoxLayout; - { - auto vBox = new QVBoxLayout; - auto hBox2 = new QHBoxLayout; - - hBox2->addWidget(new QLabel(tr("接收:"))); - hBox2->addStretch(); - - auto fdStart = new QRadioButton(tr("开始")); - fdStart->setChecked(true); - connect(fdStart, &QPushButton::toggled, this, [this](bool checked) { - thd->status = checked ? 0 : 1; - }); - hBox2->addWidget(fdStart); - hBox2->addSpacing(20); - - auto fdEnd = new QRadioButton(tr("暂停")); - hBox2->addWidget(fdEnd); - - hBox2->addStretch(); - - auto btnClear = new QPushButton(tr("清除")); - btnClear->setMinimumWidth(120); - connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear); - hBox2->addWidget(btnClear); - - hBox2->addStretch(); - - vBox->addLayout(hBox2); - - vBox->addWidget(fdReceive); - - hBox->addLayout(vBox); - } - { - auto wgt = new QWidget; - wgt->setMaximumWidth(400); - - auto vBox = new QVBoxLayout(wgt); - vBox->setContentsMargins(0,0,0,0); - vBox->setSpacing(3); - - auto hBox2 = new QHBoxLayout; - hBox2->addStretch(); - - auto btnSend = new QPushButton(tr("发送")); - btnSend->setMinimumWidth(120); - hBox2->addWidget(btnSend); - - hBox2->addStretch(); - - auto btnClear = new QPushButton(tr("清除")); - btnClear->setMinimumWidth(120); - hBox2->addWidget(btnClear); - hBox2->addStretch(); - - vBox->addLayout(hBox2); - - auto fdSend = new QTextEdit; - fdSend->setFontFamily("Consolas"); - vBox->addWidget(fdSend); - - connect(btnSend, &QPushButton::clicked, this, [this, fdSend] { - auto text = fdSend->toPlainText(); - auto len = text.size(); - QByteArray bytes; - for(int i=0; i='0' && ch<='9') || (ch>='A' && ch<='F') || (ch>='a' && ch<='f')) bytes.append(ch); - } - if(bytes.size() % 2) bytes.append('0'); - bytes = QByteArray::fromHex(bytes); - if(pcap_sendpacket(pcap, (u_char*)bytes.data(), bytes.size())) { - QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcap)); - return; - } - }); - connect(btnClear, &QPushButton::clicked, fdSend, &QTextEdit::clear); - - hBox->addWidget(wgt); - } - vBox->addLayout(hBox); - - thd = new PcapThread(pcapRece); - connect(thd, &PcapThread::onMsg, fdReceive, &QTextEdit::append); - thd->start(); -} - -PcapThread::PcapThread(pcap_t *pcap) : pcap(pcap) { - connect(this, &QThread::finished, this, &QThread::deleteLater); -} -void PcapThread::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) continue; //超时 - if(data[0]!=0x55 || data[1]!=0x55) continue; - QString data_str; - data_str.append(QDateTime::fromSecsSinceEpoch(header->ts.tv_sec).toString("yy-MM-dd HH:mm:ss.")+QString::number(header->ts.tv_usec)); - data_str.append(" len:").append(QString::number(header->caplen)).append("/").append(QString::number(header->len)).append("\n"); - char line[LINE_LEN + 1]; - int l = 0; - for(uint i=0; icaplen; i++) { - data_str.append(QString::asprintf("%.2x ", data[i])); - if(i > 13) { - if(isgraph(data[i]) || data[i] == ' ') line[l] = data[i]; - else line[l] = '.'; - if(l==15) { - line[16] = 0; - data_str.append(" ").append(line).append("\n"); - l = 0; - } else l++; - } else if(i == 13) { - data_str.append("\n"); - } - } - line[l] = 0; - data_str.append(" ").append(line).append("\n\n"); - emit onMsg(data_str); - } - emit onError(pcap_geterr(pcap)); -} diff --git a/ledset/pcapwin.h b/ledset/pcapwin.h deleted file mode 100644 index d994704..0000000 --- a/ledset/pcapwin.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef PCAPWIN_H -#define PCAPWIN_H - -#include "basewin.h" -#define HAVE_REMOTE -#include "pcap.h" -#include - -#define LINE_LEN 16 - -class PcapThread : public QThread { - Q_OBJECT -public: - explicit PcapThread(pcap *pcap); - ~PcapThread() { - pcap_close(pcap); - } - pcap *pcap; - std::atomic status{0}; -protected: - void run(); -signals: - void onMsg(const QString &); - void onError(char *); -}; - -class PcapWin : public BaseWin { - Q_OBJECT -public: - static PcapWin *newIns(QByteArray &, QWidget *); - - explicit PcapWin(pcap *, pcap *, QWidget *parent = nullptr); - ~PcapWin() { - pcap_close(pcap); - thd->status = 2; - } - PcapThread *thd{0}; - pcap *pcap; -}; - -#endif // PCAPWIN_H diff --git a/ledset/res.qrc b/ledset/res.qrc index 7270d14..71b1d39 100644 --- a/ledset/res.qrc +++ b/ledset/res.qrc @@ -12,7 +12,7 @@ imgs/monitor.png imgs/multi.png imgs/idea.png - imgs/video.png + imgs/test.png imgs/conn1.png imgs/conn2.png imgs/conn3.png diff --git a/ledset/testwin.cpp b/ledset/testwin.cpp new file mode 100644 index 0000000..97451fc --- /dev/null +++ b/ledset/testwin.cpp @@ -0,0 +1,230 @@ +#include "testwin.h" +#include "gutil/qgui.h" +#include "globalfunc.h" +#include "crc.h" +#include +#include +#include +#include +#include +#include +#include +#include + +TestWin::TestWin(QWidget *parent) : QWidget{parent, Qt::Window} { + setAttribute(Qt::WA_DeleteOnClose); + setWindowTitle(tr("协议调试")); + resize(800, 800); + + auto mainVBox = new VBox(this); + mainVBox->setContentsMargins(0,0,0,0); + + auto tab = new QTabWidget; + mainVBox->addWidget(tab); + + TestPanel *pnl; + tab->addTab(pnl = new TestPanel, "调试窗口1"); + fdReceives.append(pnl->fdReceive); + tab->addTab(pnl = new TestPanel, "调试窗口2"); + fdReceives.append(pnl->fdReceive); + tab->addTab(pnl = new TestPanel, "调试窗口3"); + fdReceives.append(pnl->fdReceive); + + auto splitter = new QSplitter; + tab->addTab(splitter, "全局调试"); + + auto wgt = new QWidget; + splitter->addWidget(wgt); + + auto vv = new VBox(wgt); + vv->setContentsMargins(0,0,0,0); + vv->setSpacing(3); + + auto hh = new HBox(vv); + + hh->addWidget(new QLabel(tr("接收:"))); + hh->addStretch(); + + auto fdStart = new QRadioButton(tr("开始")); + fdStart->setChecked(true); + connect(fdStart, &QPushButton::toggled, this, [](bool checked) { + reThd->status = checked ? 1 : 2; + }); + hh->addWidget(fdStart); + hh->addSpacing(20); + + auto fdEnd = new QRadioButton(tr("暂停")); + hh->addWidget(fdEnd); + + hh->addStretch(); + + auto btnClear = new QPushButton(tr("清空")); + btnClear->setMinimumWidth(120); + hh->addWidget(btnClear); + hh->addStretch(); + + auto fdReceive = new QTextEdit; + fdReceive->setFontFamily("Consolas"); + fdReceive->setReadOnly(true); + fdReceive->document()->setMaximumBlockCount(200); + vv->addWidget(fdReceive); + fdReceives.append(fdReceive); + + connect(btnClear, &QPushButton::clicked, fdReceive, &QTextEdit::clear); + + splitter->addWidget(wgt = new QWidget); + vv = new VBox(wgt); + vv->setContentsMargins(0,0,0,0); + vv->setSpacing(3); + + hh = new HBox(vv); + hh->addStretch(); + + auto btnSend = new QPushButton(tr("发送")); + btnSend->setMinimumWidth(120); + hh->addWidget(btnSend); + + hh->addStretch(); + + btnClear = new QPushButton(tr("清空")); + btnClear->setMinimumWidth(120); + hh->addWidget(btnClear); + hh->addStretch(); + + auto fdSend = new QTextEdit; + fdSend->setFontFamily("Consolas"); + vv->addWidget(fdSend); + + splitter->setSizes({3000, 2000}); + + connect(btnSend, &QPushButton::clicked, this, [this, fdSend] { + auto text = fdSend->toPlainText(); + auto len = text.size(); + QByteArray bytes; + for(int i=0; i='0' && ch<='9') || (ch>='A' && ch<='F') || (ch>='a' && ch<='f')) bytes.append(ch); + } + if(bytes.size() % 2) bytes.append('0'); + bytes = QByteArray::fromHex(bytes); + if(pcap_sendpacket(pcapSend, (u_char*)bytes.data(), bytes.size())) { + QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend)); + return; + } + }); + connect(btnClear, &QPushButton::clicked, fdSend, &QTextEdit::clear); + + + connect(reThd, &PcapReThread::onMsg, fdReceive, [=](const QString &msg) { + for(auto fdReceive : fdReceives) if(fdReceive->isVisible()) fdReceive->append(msg); + }); + reThd->status = 1; +} +TestWin::~TestWin() { + reThd->status = 0; +} + + + +TestPanel::TestPanel(QWidget *parent) : QWidget{parent} { + auto vBox = new VBox(this); + vBox->setContentsMargins(0,0,0,0); + vBox->setSpacing(3); + + auto hBox = new HBox(vBox); + + auto fdVer = new QLineEdit("01"); + fdVer->setMaximumWidth(30); + hBox->addWidget(fdVer); + + auto fdSrv = new QLineEdit("AD"); + fdSrv->setMaximumWidth(30); + hBox->addWidget(fdSrv); + + auto fdAddr = new QLineEdit("FFFFFFFF 0000ABCD"); + fdAddr->setMaximumWidth(180); + hBox->addWidget(fdAddr); + + auto fdPtr = new QComboBox; + fdPtr->setEditable(true); + fdPtr->addItem("B0000000 (系统配置)"); + fdPtr->addItem("B1000000 (模组寄存器)"); + fdPtr->addItem("B2000000 (保留)"); + fdPtr->addItem("B3000000 (箱体寄存器)"); + fdPtr->addItem("B4000000 (灰度寄存器)"); + fdPtr->addItem("B5100000 (驱动ic寄存器 DCLK)"); + fdPtr->addItem("B5200000 (驱动ic寄存器 LAT)"); + fdPtr->addItem("B5300000 (驱动ic寄存器 R)"); + fdPtr->addItem("B5400000 (驱动ic寄存器 G)"); + fdPtr->addItem("B5500000 (驱动ic寄存器 B)"); + fdPtr->addItem("B6000000 (Flash存储地址)"); + fdPtr->addItem("D0000000 (SDRAM内存地址)"); + fdPtr->addItem("A0000000 (其他)"); + hBox->addWidget(fdPtr); + hBox->addStretch(); + + auto btnSend = new QPushButton(tr("发送")); + hBox->addWidget(btnSend); + + auto btnClear = new QPushButton(tr("清空")); + btnClear->setMaximumWidth(60); + hBox->addWidget(btnClear); + + auto btnClearRece = new QPushButton(tr("清空接收")); + hBox->addWidget(btnClearRece); + + auto splitter = new QSplitter(Qt::Vertical); + vBox->addWidget(splitter); + + auto fdBody = new QTextEdit; + fdBody->setPlainText("00 00 00 00"); + fdBody->setFontFamily("Consolas"); + splitter->addWidget(fdBody); + connect(btnSend, &QPushButton::clicked, this, [=] { + auto body = QByteArray::fromHex(fdBody->toPlainText().toLatin1()); + if(body.isEmpty()) { + QMessageBox::critical(this, "Error", "发送内容为空"); + return; + } + auto bLen = body.size(); + QByteArray msg; + msg.reserve(headMap.end+bLen+16); + msg.append("\x55\x55"); + msg.append(QByteArray::fromHex(fdVer->text().toLatin1())[0]); + byte srv = QByteArray::fromHex(fdSrv->text().toLatin1())[0]; + msg.append(srv); + auto bodyLen = bLen + 6; + msg.append(bodyLen>>8).append(bodyLen); + msg.append(QByteArray::fromHex(fdAddr->text().toLatin1())); + auto ptrRaw = fdPtr->currentText(); + auto idx = ptrRaw.indexOf('('); + if(idx > -1) ptrRaw = ptrRaw.left(idx); + auto ptr = QByteArray::fromHex(ptrRaw.toLatin1()); + msg.append(ptr); + msg.append(6, 0); + auto check = (quint32_be*)(msg.data() + msg.size() - 4); + *check = crc32_calc((byte*)msg.data()+2, msg.size()-6); + msg.append(ptr); + msg[msg.size()-4] = srv; + msg.append(bLen>>8).append(bLen); + msg.append(body); + msg.append(4, 0); + check = (quint32_be*)(msg.data() + msg.size() - 4); + *check = crc32_calc((byte*)msg.data()+headMap.body, msg.size()-headMap.body-4); + + if(pcap_sendpacket(pcapSend, (u_char*)msg.data(), msg.size())) { + QMessageBox::critical(this, "Error", QString(tr("发送失败: "))+pcap_geterr(pcapSend)); + return; + } + }); + connect(btnClear, &QPushButton::clicked, fdBody, &QTextEdit::clear); + + fdReceive = new QTextEdit; + fdReceive->setFontFamily("Consolas"); + fdReceive->setReadOnly(true); + fdReceive->document()->setMaximumBlockCount(200); + splitter->addWidget(fdReceive); + splitter->setSizes({1000, 3000}); + + connect(btnClearRece, &QPushButton::clicked, fdReceive, &QTextEdit::clear); +} diff --git a/ledset/testwin.h b/ledset/testwin.h new file mode 100644 index 0000000..04fd862 --- /dev/null +++ b/ledset/testwin.h @@ -0,0 +1,22 @@ +#ifndef TESTWIN_H +#define TESTWIN_H + +#include + +class TestWin : public QWidget { + Q_OBJECT +public: + explicit TestWin(QWidget* parent); + ~TestWin(); + + QList fdReceives; +}; + +class TestPanel : public QWidget { + Q_OBJECT +public: + explicit TestPanel(QWidget* parent = 0); + QTextEdit *fdReceive; +}; + +#endif // TESTWIN_H diff --git a/ledset/videowin.cpp b/ledset/videowin.cpp index 9f679d7..d5b6f32 100644 --- a/ledset/videowin.cpp +++ b/ledset/videowin.cpp @@ -15,7 +15,7 @@ using namespace std; VideoWin *VideoWin::newIns(QByteArray &name, QWidget *parent) { if(name.isEmpty()) return 0; - char errbuf[PCAP_ERRBUF_SIZE]{'\0'}; + char errbuf[PCAP_ERRBUF_SIZE]{0}; auto pcapRe = pcap_open_live(name.data(), 65536, PCAP_OPENFLAG_PROMISCUOUS, 50, errbuf); if(pcapRe == 0) { QMessageBox::critical(parent, "Error", QString("打开网卡失败")+errbuf);