From 6b8e98b73583e7f25d23ca134b3505b83c99d15b Mon Sep 17 00:00:00 2001 From: wh201906 <62299611+wh201906@users.noreply.github.com> Date: Tue, 21 Apr 2020 19:12:44 +0800 Subject: [PATCH] Refactor the basic connect function(using QThread) --- mainwindow.cpp | 147 +++++++++++++++++++++++++++++++++++-------------- mainwindow.h | 16 +++++- pm3process.cpp | 59 ++++++++++---------- pm3process.h | 14 +++-- 4 files changed, 159 insertions(+), 77 deletions(-) diff --git a/mainwindow.cpp b/mainwindow.cpp index 720de88..1c0e6ce 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -6,17 +6,27 @@ MainWindow::MainWindow(QWidget *parent) , ui(new Ui::MainWindow) { ui->setupUi(this); - pm3 = new PM3Process; + + pm3Thread=new QThread(this); + pm3 = new PM3Process(pm3Thread); +// pm3->moveToThread(pm3Thread); +// pm3->init(); + pm3Thread->start(); + pm3state=false; + mifare = new Mifare; - connect(pm3, &PM3Process::readyRead, this, &MainWindow::refresh); - connect(pm3, &PM3Process::PM3disconnected, this, &MainWindow::onPM3disconnected); - connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG); + uiInit(); + signalInit(); } MainWindow::~MainWindow() { delete ui; + pm3Thread->exit(0); + pm3Thread->wait(5000); + delete pm3; + delete pm3Thread; } // ******************** basic functions ******************** @@ -25,7 +35,20 @@ void MainWindow::on_PM3_refreshPortButton_clicked() { ui->PM3_portBox->clear(); ui->PM3_portBox->addItem(""); - foreach(QString port, pm3->findPort()) + QSerialPort serial; + QStringList serialList; + foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) + { + qDebug()<PM3_portBox->addItem(port); } @@ -33,36 +56,36 @@ void MainWindow::on_PM3_refreshPortButton_clicked() void MainWindow::on_PM3_connectButton_clicked() { + qDebug()<<"Main:"<PM3_portBox->currentText(); if(port == "") QMessageBox::information(NULL, "Info", "Plz choose a port first", QMessageBox::Ok); else { - pm3->setRequiringOutput(true); - if(pm3->start(ui->PM3_pathEdit->text(), port)) - { - while(pm3->waitForReadyRead()) - ; - QString result = pm3->getRequiredOutput(); - pm3->setRequiringOutput(false); - result = result.mid(result.indexOf("os: ")); - result = result.left(result.indexOf("\r\n")); - result = result.mid(3, result.lastIndexOf(" ") - 3); - setStatusBar(PM3VersionBar, result); - setStatusBar(connectStatusBar,"Connected"); - } + emit requiringOutput(true); + emit connectPM3(ui->PM3_pathEdit->text(), port); } } -void MainWindow::on_PM3_disconnectButton_clicked() +void MainWindow::onPM3StateChanged(bool st, QString info) { - pm3->kill(); - pm3->setSerialListener("",false); - onPM3disconnected(); + pm3state=st; + if(st==true) + { + setStatusBar(PM3VersionBar,info); + setStatusBar(connectStatusBar,"Connected"); + } + else + { + setStatusBar(connectStatusBar,"Not Connected"); + } } -void MainWindow::onPM3disconnected() +void MainWindow::on_PM3_disconnectButton_clicked() { + pm3state=false; + emit killPM3(); + emit setSerialListener("", false); setStatusBar(connectStatusBar,"Not Connected"); } @@ -179,8 +202,8 @@ void MainWindow::on_MF_RW_readAllButton_clicked() { QApplication::processEvents(); result = ""; - isKeyAValid=false; - isKeyBValid=false; + isKeyAValid = false; + isKeyBValid = false; // check keys and read the first block of each sector if(ui->MF_keyWidget->item(i, 1) != nullptr && MF_isKeyValid(ui->MF_keyWidget->item(i, 1)->text())) @@ -191,7 +214,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() + ui->MF_keyWidget->item(i, 1)->text(), waitTime); if(result.indexOf("isOk:01") != -1) { - isKeyAValid=true; + isKeyAValid = true; ui->MF_dataWidget->setItem(4 * i, 2, new QTableWidgetItem(result.mid(result.indexOf("isOk:01") + 13, 47).toUpper())); } } @@ -204,7 +227,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() + ui->MF_keyWidget->item(i, 2)->text(), waitTime); if(result.indexOf("isOk:01") != -1) { - isKeyBValid=true; + isKeyBValid = true; ui->MF_dataWidget->setItem(4 * i, 2, new QTableWidgetItem(result.mid(result.indexOf("isOk:01") + 13, 47).toUpper())); } } @@ -221,7 +244,7 @@ void MainWindow::on_MF_RW_readAllButton_clicked() + (isKeyAValid ? "A" : "B") + " " + ui->MF_keyWidget->item(i, (isKeyAValid ? 1 : 2))->text(), waitTime); - result=result.mid(result.indexOf("isOk:01") + 13, 47).toUpper(); + result = result.mid(result.indexOf("isOk:01") + 13, 47).toUpper(); ui->MF_dataWidget->setItem(4 * i + j, 2, new QTableWidgetItem(result)); } @@ -233,12 +256,12 @@ void MainWindow::on_MF_RW_readAllButton_clicked() // // the structure is not symmetric, since you cannot get KeyA from output // this program will only process the provided KeyA(in MF_keyWidget) - result=ui->MF_dataWidget->item(4 * i + 3, 2)->text(); + result = ui->MF_dataWidget->item(4 * i + 3, 2)->text(); if(isKeyAValid) { for(int j = 0; j < 6; j++) { - result = result.replace(j * 3, 2, ui->MF_keyWidget->item(i,1)->text().mid(j * 2, 2)); + result = result.replace(j * 3, 2, ui->MF_keyWidget->item(i, 1)->text().mid(j * 2, 2)); } } else @@ -251,24 +274,24 @@ void MainWindow::on_MF_RW_readAllButton_clicked() { for(int j = 0; j < 6; j++) { - result = result.replace(30 + j * 3, 2, ui->MF_keyWidget->item(i,2)->text().mid(j * 2, 2)); + result = result.replace(30 + j * 3, 2, ui->MF_keyWidget->item(i, 2)->text().mid(j * 2, 2)); ui->MF_dataWidget->setItem(4 * i + 3, 2, new QTableWidgetItem(result)); } } else { - QString tmpKey=result.right(18).replace(" ",""); + QString tmpKey = result.right(18).replace(" ", ""); result = execCMDWithOutput("hf mf rdbl " - + QString::number(4 * i + 3) - + " B " - + tmpKey, waitTime); + + QString::number(4 * i + 3) + + " B " + + tmpKey, waitTime); if(result.indexOf("isOk:01") != -1) { ui->MF_keyWidget->setItem(i, 2, new QTableWidgetItem(tmpKey)); } else { - result=ui->MF_dataWidget->item(4 * i + 3, 2)->text(); + result = ui->MF_dataWidget->item(4 * i + 3, 2)->text(); result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); ui->MF_dataWidget->setItem(4 * i + 3, 2, new QTableWidgetItem(result)); } @@ -298,14 +321,14 @@ void MainWindow::on_MF_RW_readBlockButton_clicked() result = result.replace(i * 3, 2, ui->MF_RW_keyEdit->text().mid(i * 2, 2)); } ui->MF_RW_dataEdit->setText(result); - QString tmpKey=result.right(18).replace(" ",""); + QString tmpKey = result.right(18).replace(" ", ""); result = execCMDWithOutput("hf mf rdbl " - + ui->MF_RW_keyTypeBox->currentText() - + " B " - + tmpKey); + + ui->MF_RW_keyTypeBox->currentText() + + " B " + + tmpKey); if(result.indexOf("isOk:01") == -1) { - result= ui->MF_RW_dataEdit->text(); + result = ui->MF_RW_dataEdit->text(); result = result.replace(30, 17, "?? ?? ?? ?? ?? ??"); ui->MF_RW_dataEdit->setText(result); } @@ -340,6 +363,32 @@ void MainWindow::on_MF_RW_writeBlockButton_clicked() } } +void MainWindow::on_MF_RW_writeAllButton_clicked() +{ + QString result; + for(int i = 0; i < 16; i++) + { + for(int j = 0; j < 4; j++) + { + result = execCMDWithOutput("hf mf wrbl " + + QString::number(i * 4 + j) + + " A " + + ui->MF_keyWidget->item(i, 1)->text() + + " " + + ui->MF_dataWidget->item(2, i * 4 + j)->text().replace(" ", "")); + if(result.indexOf("isOk:01") == -1) + { + result = execCMDWithOutput("hf mf wrbl " + + QString::number(i * 4 + j) + + " B " + + ui->MF_keyWidget->item(i, 2)->text() + + " " + + ui->MF_dataWidget->item(2, i * 4 + j)->text().replace(" ", "")); + } + } + } +} + // ************************************************ @@ -365,6 +414,8 @@ void MainWindow::sendMSG() void MainWindow::uiInit() { + connect(ui->Raw_CMDEdit, &QLineEdit::editingFinished, this, &MainWindow::sendMSG); + connectStatusBar = new QLabel(this); programStatusBar = new QLabel(this); PM3VersionBar = new QLabel(this); @@ -401,7 +452,7 @@ void MainWindow::uiInit() ui->MF_keyWidget->setColumnWidth(1, 200); ui->MF_keyWidget->setColumnWidth(2, 200); - for(int i=0;i<64;i++) + for(int i = 0; i < 64; i++) { ui->MF_RW_blockBox->addItem(QString::number(i)); ui->MF_UID_blockBox->addItem(QString::number(i)); @@ -411,6 +462,16 @@ void MainWindow::uiInit() on_PM3_refreshPortButton_clicked(); } +void MainWindow::signalInit() +{ + connect(pm3, &PM3Process::readyRead, this, &MainWindow::refresh); + + connect(this,&MainWindow::requiringOutput,pm3,&PM3Process::setRequiringOutput); + connect(this,&MainWindow::connectPM3,pm3,&PM3Process::connectPM3); + connect(pm3, &PM3Process::PM3StatedChanged, this, &MainWindow::onPM3StateChanged); + connect(this,&MainWindow::killPM3,pm3,&PM3Process::kill); +} + void MainWindow::setStatusBar(QLabel* target, const QString & text) { if(target == PM3VersionBar) @@ -452,3 +513,5 @@ bool MainWindow::MF_isKeyValid(const QString key) } // *********************************************** + + diff --git a/mainwindow.h b/mainwindow.h index 0b4a42f..4633a38 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -2,10 +2,14 @@ #define MAINWINDOW_H #include +#include #include #include #include #include +#include +#include + #include "pm3process.h" #include "mifare.h" #include "mf_attack_hardnesteddialog.h" @@ -28,7 +32,7 @@ public slots: void refresh(); void setStatusBar(QLabel* target,const QString & text); void execCMD(QString cmd, bool gotoRawTab); - void onPM3disconnected(); + void onPM3StateChanged(bool st, QString info); private slots: void on_PM3_connectButton_clicked(); @@ -66,13 +70,23 @@ private slots: void on_MF_Attack_infoButton_clicked(); + void on_MF_RW_writeAllButton_clicked(); + private: Ui::MainWindow *ui; PM3Process* pm3; + bool pm3state; + QThread* pm3Thread; Mifare* mifare; void uiInit(); QLabel* connectStatusBar; QLabel* programStatusBar; QLabel* PM3VersionBar; + void signalInit(); +signals: + void requiringOutput(bool st); + void connectPM3(const QString path, const QString port); + void killPM3(); + void setSerialListener(const QString &name, bool state); }; #endif // MAINWINDOW_H diff --git a/pm3process.cpp b/pm3process.cpp index f06cbac..89afea0 100644 --- a/pm3process.cpp +++ b/pm3process.cpp @@ -1,46 +1,40 @@ #include "pm3process.h" -PM3Process::PM3Process(QObject* parent): QProcess(parent) +PM3Process::PM3Process(QThread* thread, QObject* parent): QProcess(parent) { + moveToThread(thread); setProcessChannelMode(PM3Process::MergedChannels); isRequiringOutput=false; requiredOutput=new QString(); - serialListener=new QTimer(this); + serialListener=new QTimer(); // if using new QTimer(this), the debug output will show "Cannot create children for a parent that is in a different thread." + serialListener->moveToThread(this->thread());// I've tried many ways to creat a QTimer instance, but all of the instances are in the main thread(UI thread), so I have to move it manually serialListener->setInterval(1000); serialListener->setTimerType(Qt::VeryCoarseTimer); connect(serialListener,&QTimer::timeout,this,&PM3Process::onTimeout); } -QStringList PM3Process::findPort() +void PM3Process::connectPM3(const QString path, const QString port) { - QSerialPort serial; - QStringList retList; - foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) - { - qDebug()<start(); + qDebug()<thread(); } else { @@ -87,7 +82,13 @@ void PM3Process::onTimeout() qDebug()<isBusy(); if(!portInfo->isBusy()) { - emit PM3disconnected(); + kill(); + emit PM3StatedChanged(false); setSerialListener("",false); } } + +void PM3Process::testThread() +{ + qDebug()<<"PM3:"< +#include #include #include #include @@ -12,13 +13,16 @@ class PM3Process : public QProcess { Q_OBJECT public: - explicit PM3Process(QObject* parent=nullptr); - bool start(const QString path, const QString port); - QStringList findPort(); + explicit PM3Process(QThread* thread, QObject* parent=nullptr); QByteArray readLine(qint64 maxlen = 0); - void setRequiringOutput(bool st); QString getRequiredOutput(); bool waitForReadyRead(int msecs = 2000); + + void testThread(); + +public slots: + void setRequiringOutput(bool st); + void connectPM3(const QString path, const QString port); void setSerialListener(const QString &name, bool state); private slots: void onTimeout(); @@ -28,7 +32,7 @@ private: QTimer* serialListener; QSerialPortInfo* portInfo; signals: - void PM3disconnected(); + void PM3StatedChanged(bool st, QString info=""); }; #endif // PM3PROCESS_H