6 Commits

Author SHA1 Message Date
wh201906 bac6207634 V0.2.1 2021-03-16 11:23:01 +08:00
wh201906 ccb07651cc Mifare: Optimize read logic
Fix bug #16 mentioned in http://www.proxmark.org/forum/viewtopic.php?pid=42123 (see the 17th post)
This is caused by the output change in RRG repo
Optimize _readsec() logic
Implement getTrailerBlockId()
2021-03-16 11:06:26 +08:00
wh201906 f706d59c48 Update UI 2021-03-15 11:29:17 +08:00
wh201906 9e31496131 Fail to support non-ASCII chars in path
Using "chcp" seems to have no effect there
I fix a small bug then
2021-03-12 11:59:51 +08:00
wh201906 a232e4ec83 Fix #15 partially
The path of the start script or the client can contain spaces now(on Windows)
TODO:
Test the issue on Linux and implement the fix if it's needed
Support non-ASCII chars in the path
2021-03-11 00:46:56 +08:00
wh201906 1bec73d1ad T55xx: Add some useless UI 2021-03-08 23:02:16 +08:00
10 changed files with 1568 additions and 481 deletions
+1 -1
View File
@@ -56,7 +56,7 @@ qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target !isEmpty(target.path): INSTALLS += target
VERSION = 0.2.0 VERSION = 0.2.1
QMAKE_TARGET_PRODUCT = "Proxmark3GUI" QMAKE_TARGET_PRODUCT = "Proxmark3GUI"
QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI" QMAKE_TARGET_DESCRIPTION = "Proxmark3GUI"
QMAKE_TARGET_COMPANY = "wh201906" QMAKE_TARGET_COMPANY = "wh201906"
+5
View File
@@ -65,6 +65,11 @@ Great thanks to him.
## Update Log: ## Update Log:
### V0.2.1
+ Optimize MIFARE Classic reading logic
+ Fix bug #16
+ Fix bug #15 partially (the path can contain spaces now)
### V0.2 ### V0.2
+ Use Dock widget for more flexible layout + Use Dock widget for more flexible layout
+ Support basic LF commands + Support basic LF commands
+5
View File
@@ -64,6 +64,11 @@ release页面中有含客户端的GUI。这个GUI也可以搭配你自己的客
## 更新日志: ## 更新日志:
### V0.2.1
+ 优化MIFARE Classic读卡逻辑
+ 修复 #16 (配合新版RRG固件时无法读取扇区数据)
+ 修复 #15 (路径中支持空格)
### V0.2 ### V0.2
+ 使用浮动窗口,界面配置更加灵活 + 使用浮动窗口,界面配置更加灵活
+ 支持部分低频命令 + 支持部分低频命令
+393 -201
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.
+381 -189
View File
File diff suppressed because it is too large Load Diff
+59 -26
View File
@@ -419,7 +419,6 @@ QStringList Mifare::_readsec(int sectorId, KeyType keyType, const QString& key,
+ " " + " "
+ key, + key,
waitTime); waitTime);
offset = result.indexOf("isOk:01"); // find successful flag
} }
else if(targetType == TARGET_UID) else if(targetType == TARGET_UID)
{ {
@@ -427,9 +426,18 @@ QStringList Mifare::_readsec(int sectorId, KeyType keyType, const QString& key,
"hf mf cgetsc " "hf mf cgetsc "
+ QString::number(sectorId), + QString::number(sectorId),
waitTime); waitTime);
offset = result.indexOf("error") == -1 ? 0 : -1; // find failed flag
} }
if(offset != -1) else if(targetType == TARGET_EMULATOR)
{
for(int i = 0; i < cardType.blk[sectorId]; i++)
data[i] = _readblk(cardType.blks[sectorId] + i, keyType, key, targetType, waitTime);
return data;
}
// for TARGET_MIFARE and TARGET_UID
reMatch = dataPattern->match(result);
offset = reMatch.capturedStart();
if(reMatch.hasMatch()) // read successful
{ {
for(int i = 0; i < cardType.blk[sectorId]; i++) for(int i = 0; i < cardType.blk[sectorId]; i++)
{ {
@@ -444,13 +452,11 @@ QStringList Mifare::_readsec(int sectorId, KeyType keyType, const QString& key,
} }
} }
} }
// if failed, try to read them seperately. // when one of the block cannot be read, the rdsc will return nothing, so you need to read the rest of blocks manually
// (when one of the block cannot be read, the rdsc will return nothing, so you need to read the rest of blocks manually) // the following rdbl operation is not handled there, for better speed(rdsc_A->rdsc_B->rdbl0~3)
else if(targetType == TARGET_UID || targetType == TARGET_EMULATOR) // if the targetType is Chinese Magic Card, then the result implies the backdoor command is invalid. else if(targetType == TARGET_UID) // treat as MIFARE
{ data = _readsec(sectorId, keyType, key, TARGET_MIFARE, waitTime);
for(int i = 0; i < cardType.blk[sectorId]; i++)
data[i] = _readblk(cardType.blks[sectorId] + i, keyType, key, targetType, waitTime);
}
//process trailer(like _readblk()) //process trailer(like _readblk())
QString trailer = data[cardType.blk[sectorId] - 1]; QString trailer = data[cardType.blk[sectorId] - 1];
@@ -493,7 +499,6 @@ void Mifare::readOne(TargetType targetType)
void Mifare::readSelected(TargetType targetType) void Mifare::readSelected(TargetType targetType)
{ {
QStringList data, dataA, dataB;
QString trailerA, trailerB; QString trailerA, trailerB;
QList<bool> selectedSectors; QList<bool> selectedSectors;
QList<int> selectedBlocks; QList<int> selectedBlocks;
@@ -513,12 +518,11 @@ void Mifare::readSelected(TargetType targetType)
} }
for(int i = 0; i < cardType.sector_size; i++) for(int i = 0; i < cardType.sector_size; i++)
{
{ {
if(!selectedSectors[i]) if(!selectedSectors[i])
{
continue; continue;
}
QStringList data, dataA, dataB;
for(int j = 0; j < cardType.blk[i]; j++) for(int j = 0; j < cardType.blk[i]; j++)
{ {
// dataA is always filled with "" because of the _readsec() // dataA is always filled with "" because of the _readsec()
@@ -529,24 +533,41 @@ void Mifare::readSelected(TargetType targetType)
dataA = _readsec(i, Mifare::KEY_A, keyAList->at(i), targetType); dataA = _readsec(i, Mifare::KEY_A, keyAList->at(i), targetType);
// in other situations, the key doesn't matters // in other situations, the key doesn't matters
// so the dataA is the final result
//
// if the targetType is TARGET_MIFARE and the dataA has unknown part, try to read by keyB
if(targetType == TARGET_MIFARE && (dataA.contains("") || dataA[cardType.blk[i] - 1].right(12) == "????????????")) if(targetType == TARGET_MIFARE && (dataA.contains("") || dataA[cardType.blk[i] - 1].right(12) == "????????????"))
dataB = _readsec(i, Mifare::KEY_B, keyBList->at(i), targetType); dataB = _readsec(i, Mifare::KEY_B, keyBList->at(i), targetType);
// process trailer block seperately
if(dataA[cardType.blk[i] - 1] == "" && selectedBlocks.contains(getTrailerBlockId(i)))
dataA[cardType.blk[i] - 1] = _readblk(getTrailerBlockId(i), Mifare::KEY_A, keyAList->at(i), targetType);
if(dataB[cardType.blk[i] - 1] == "" && dataA[cardType.blk[i] - 1].right(12) == "????????????" && selectedBlocks.contains(getTrailerBlockId(i)))
dataB[cardType.blk[i] - 1] = _readblk(getTrailerBlockId(i), Mifare::KEY_B, keyBList->at(i), targetType);
for(int j = 0; j < cardType.blk[i]; j++) for(int j = 0; j < cardType.blk[i]; j++)
{ {
if(dataA[j] != "") if(dataA[j] != "")
data[j] = dataA[j]; data[j] = dataA[j];
else else
data[j] = dataB[j]; data[j] = dataB[j];
if(data[j] == "" && selectedBlocks.contains(cardType.blks[i] + j)) // try rdbl seperately
{
data[j] = _readblk(cardType.blks[i] + j, Mifare::KEY_A, keyAList->at(i), targetType);
if(data[j] == "")
data[j] = _readblk(cardType.blks[i] + j, Mifare::KEY_B, keyBList->at(i), targetType);
}
} }
// process trailer block seperately // process trailer block seperately
trailerA = dataA[cardType.blk[i] - 1]; trailerA = dataA[cardType.blk[i] - 1];
trailerB = dataB[cardType.blk[i] - 1]; trailerB = dataB[cardType.blk[i] - 1];
if(trailerA != "" && trailerB != "") if(trailerA != "" && trailerB != "") // if KeyA and KeyB can both read the trailer, then concat them
{ {
QString ACbits = trailerA.mid(12, 8); QString ACbits = trailerA.mid(12, 8);
QString key_A = trailerA.left(12); QString key_A = trailerA.left(12); // KeyA cannot be read by KeyB
QString key_B = trailerA.at(31) != '?' ? trailerA.right(12) : trailerB.right(12); QString key_B = trailerA.at(31) != '?' ? trailerA.right(12) : trailerB.right(12);
data[cardType.blk[i] - 1] = key_A + ACbits + key_B; data[cardType.blk[i] - 1] = key_A + ACbits + key_B;
} }
@@ -560,7 +581,7 @@ void Mifare::readSelected(TargetType targetType)
} }
} }
if(selectedBlocks.contains(cardType.blks[i] + cardType.blk[i] - 1)) if(selectedBlocks.contains(getTrailerBlockId(i)))
{ {
// data widget has been updated, so this is just a temporary varient. // data widget has been updated, so this is just a temporary varient.
if(data[cardType.blk[i] - 1] == "") if(data[cardType.blk[i] - 1] == "")
@@ -574,8 +595,6 @@ void Mifare::readSelected(TargetType targetType)
data_syncWithKeyWidget(false, i, KEY_A); data_syncWithKeyWidget(false, i, KEY_A);
data_syncWithKeyWidget(false, i, KEY_B); data_syncWithKeyWidget(false, i, KEY_B);
} }
}
} }
} }
@@ -1090,7 +1109,7 @@ bool Mifare::data_loadKeyFile(const QString& filename)
{ {
for(int i = 0; i < cardType.sector_size; i++) for(int i = 0; i < cardType.sector_size; i++)
{ {
int blk = cardType.blks[i] + cardType.blk[i] - 1; int blk = getTrailerBlockId(i);
QString tmp = bin2text(buff, blk, 16); QString tmp = bin2text(buff, blk, 16);
keyAList->replace(i, tmp.left(12).toUpper()); keyAList->replace(i, tmp.left(12).toUpper());
keyBList->replace(i, tmp.right(12).toUpper()); keyBList->replace(i, tmp.right(12).toUpper());
@@ -1230,17 +1249,17 @@ void Mifare::data_key2Data()
else else
tmp += "????????????"; tmp += "????????????";
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") if(dataList->at(getTrailerBlockId(i)) == "")
tmp += "FF078069"; // default control bytes tmp += "FF078069"; // default control bytes
else else
tmp += dataList->at(cardType.blks[i] + cardType.blk[i] - 1).mid(12, 8); tmp += dataList->at(getTrailerBlockId(i)).mid(12, 8);
if(data_isKeyValid(keyBList->at(i))) if(data_isKeyValid(keyBList->at(i)))
tmp += keyBList->at(i); tmp += keyBList->at(i);
else else
tmp += "????????????"; tmp += "????????????";
dataList->replace(cardType.blks[i] + cardType.blk[i] - 1, tmp); dataList->replace(getTrailerBlockId(i), tmp);
data_syncWithDataWidget(); data_syncWithDataWidget();
} }
} }
@@ -1249,15 +1268,15 @@ void Mifare::data_data2Key()
{ {
for(int i = 0; i < cardType.sector_size; i++) for(int i = 0; i < cardType.sector_size; i++)
{ {
if(dataList->at(cardType.blks[i] + cardType.blk[i] - 1) == "") if(dataList->at(getTrailerBlockId(i)) == "")
{ {
keyAList->replace(i, "????????????"); keyAList->replace(i, "????????????");
keyBList->replace(i, "????????????"); keyBList->replace(i, "????????????");
} }
else else
{ {
keyAList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).left(12)); keyAList->replace(i, dataList->at(getTrailerBlockId(i)).left(12));
keyBList->replace(i, dataList->at(cardType.blks[i] + cardType.blk[i] - 1).right(12)); keyBList->replace(i, dataList->at(getTrailerBlockId(i)).right(12));
} }
data_syncWithKeyWidget(); data_syncWithKeyWidget();
} }
@@ -1348,3 +1367,17 @@ QString Mifare::data_getUID()
else else
return ""; return "";
} }
quint16 Mifare::getTrailerBlockId(quint8 sectorId, qint8 cardTypeId)
{
if(cardTypeId == 0)
return (card_mini.blks[sectorId] + card_mini.blk[sectorId] - 1);
else if(cardTypeId == 1)
return (card_1k.blks[sectorId] + card_1k.blk[sectorId] - 1);
else if(cardTypeId == 2)
return (card_2k.blks[sectorId] + card_2k.blk[sectorId] - 1);
else if(cardTypeId == 4)
return (card_4k.blks[sectorId] + card_4k.blk[sectorId] - 1);
else
// other cardTypeId: use current cardtype(include default -1)
return (cardType.blks[sectorId] + cardType.blk[sectorId] - 1);
}
+1
View File
@@ -112,6 +112,7 @@ public:
static int data_b2s(int block); static int data_b2s(int block);
static bool data_isACBitsValid(const QString& text, QList<quint8> *returnHalfBytes = nullptr); static bool data_isACBitsValid(const QString& text, QList<quint8> *returnHalfBytes = nullptr);
QString data_getUID(); QString data_getUID();
quint16 getTrailerBlockId(quint8 sectorId, qint8 cardTypeId = -1); // -1: use current cardtype
public slots: public slots:
signals: signals:
+16 -12
View File
@@ -123,20 +123,32 @@ void MainWindow::on_PM3_connectButton_clicked()
if(envScriptPath.exists()) if(envScriptPath.exists())
{ {
qDebug() << envScriptPath.absoluteFilePath(); qDebug() << envScriptPath.absoluteFilePath();
// use the shell session to keep the environment then read it
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
// cmd /c "<path>">>nul && set // cmd /c "<path>">>nul && set
envSetProcess.start("cmd /c \"" + envScriptPath.absoluteFilePath() + "\">>nul && set"); envSetProcess.start("cmd");
envSetProcess.write(QString("\"" + envScriptPath.absoluteFilePath() + "\">>nul\r\n").toLatin1());
envSetProcess.waitForReadyRead(10000);
envSetProcess.readAll();
envSetProcess.write("set\r\n");
#else #else
// need implementation(or test if space works)
// sh -c '. "<path>">>/dev/null && env' // sh -c '. "<path>">>/dev/null && env'
envSetProcess.start("sh -c \' . \"" + envScriptPath.absoluteFilePath() + "\">>/dev/null && env"); envSetProcess.start("sh -c \' . \"" + envScriptPath.absoluteFilePath() + "\">>/dev/null && env");
#endif #endif
envSetProcess.waitForReadyRead(10000); envSetProcess.waitForReadyRead(10000);
clientEnv = QString(envSetProcess.readAll()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); QString envSetResult = QString(envSetProcess.readAll());
clientEnv = envSetResult.split(QRegExp("[\r\n]{1,2}"), QString::SkipEmptyParts);
if(clientEnv.size() > 2) // the first element is "set" and the last element is the current path
{
clientEnv.removeFirst();
clientEnv.removeLast();
emit setProcEnv(&clientEnv);
}
// qDebug() << "Get Env List" << clientEnv; // qDebug() << "Get Env List" << clientEnv;
} }
else else
clientEnv.clear(); clientEnv.clear();
emit setProcEnv(&clientEnv);
clientWorkingDir->setPath(QApplication::applicationDirPath()); clientWorkingDir->setPath(QApplication::applicationDirPath());
qDebug() << clientWorkingDir->absolutePath(); qDebug() << clientWorkingDir->absolutePath();
@@ -152,7 +164,7 @@ void MainWindow::on_PM3_connectButton_clicked()
else if(!keepClientActive) else if(!keepClientActive)
emit setSerialListener(false); emit setSerialListener(false);
envSetProcess.kill();
} }
void MainWindow::onPM3StateChanged(bool st, const QString& info) void MainWindow::onPM3StateChanged(bool st, const QString& info)
@@ -967,17 +979,9 @@ void MainWindow::uiInit()
ui->statusbar->addPermanentWidget(programStatusBar, 1); ui->statusbar->addPermanentWidget(programStatusBar, 1);
ui->statusbar->addPermanentWidget(stopButton); ui->statusbar->addPermanentWidget(stopButton);
ui->MF_dataWidget->setColumnCount(3);
ui->MF_dataWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
ui->MF_dataWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("Blk")));
ui->MF_dataWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Data")));
ui->MF_dataWidget->setColumnWidth(0, 55); ui->MF_dataWidget->setColumnWidth(0, 55);
ui->MF_dataWidget->setColumnWidth(1, 55); ui->MF_dataWidget->setColumnWidth(1, 55);
ui->MF_keyWidget->setColumnCount(3);
ui->MF_keyWidget->setHorizontalHeaderItem(0, new QTableWidgetItem(tr("Sec")));
ui->MF_keyWidget->setHorizontalHeaderItem(1, new QTableWidgetItem(tr("KeyA")));
ui->MF_keyWidget->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("KeyB")));
ui->MF_keyWidget->setColumnWidth(0, 45); ui->MF_keyWidget->setColumnWidth(0, 45);
MF_widgetReset(); MF_widgetReset();
+661 -6
View File
@@ -136,7 +136,7 @@
</sizepolicy> </sizepolicy>
</property> </property>
<property name="currentIndex"> <property name="currentIndex">
<number>0</number> <number>2</number>
</property> </property>
<widget class="QWidget" name="mifareTab"> <widget class="QWidget" name="mifareTab">
<attribute name="title"> <attribute name="title">
@@ -198,6 +198,21 @@
<attribute name="verticalHeaderDefaultSectionSize"> <attribute name="verticalHeaderDefaultSectionSize">
<number>20</number> <number>20</number>
</attribute> </attribute>
<column>
<property name="text">
<string>Sec</string>
</property>
</column>
<column>
<property name="text">
<string>Blk</string>
</property>
</column>
<column>
<property name="text">
<string>Data</string>
</property>
</column>
</widget> </widget>
</item> </item>
<item> <item>
@@ -360,6 +375,21 @@
<attribute name="verticalHeaderDefaultSectionSize"> <attribute name="verticalHeaderDefaultSectionSize">
<number>20</number> <number>20</number>
</attribute> </attribute>
<column>
<property name="text">
<string>Sec</string>
</property>
</column>
<column>
<property name="text">
<string>KeyA</string>
</property>
</column>
<column>
<property name="text">
<string>KeyB</string>
</property>
</column>
</widget> </widget>
</item> </item>
</layout> </layout>
@@ -1853,15 +1883,640 @@ or the communication between a tag and a reader.</string>
<attribute name="title"> <attribute name="title">
<string>T55xx</string> <string>T55xx</string>
</attribute> </attribute>
<widget class="QTableWidget" name="T55_dataWidget"> <widget class="QGroupBox" name="groupBox">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>20</x> <x>360</x>
<y>10</y> <y>20</y>
<width>256</width> <width>281</width>
<height>192</height> <height>511</height>
</rect> </rect>
</property> </property>
<property name="title">
<string>Basic Configuration(Page 0 Block 0)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_21">
<property name="leftMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout_4">
<item row="0" column="0">
<widget class="QLabel" name="label_43">
<property name="text">
<string>Hex:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_44">
<property name="text">
<string>Bin:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_23">
<item>
<spacer name="horizontalSpacer_15">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Get from Data</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Set to Data</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_14">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QFormLayout" name="formLayout_2">
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_28">
<property name="text">
<string>Locked:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
<string>Master Key:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_30">
<property name="text">
<string>Data Bit Rate:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_31">
<property name="text">
<string>eXtended Mode:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_32">
<property name="text">
<string>Modulation:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_33">
<property name="text">
<string>PSK Clock Freq:</string>
</property>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_34">
<property name="text">
<string>Answer on Request:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QCheckBox" name="checkBox_2"/>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBox_2"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_35">
<property name="text">
<string>One Time Pad:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_36">
<property name="text">
<string>Max Block:</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_37">
<property name="text">
<string>Password:</string>
</property>
</widget>
</item>
<item row="10" column="0">
<widget class="QLabel" name="label_38">
<property name="text">
<string>Seq. Terminator:</string>
</property>
</widget>
</item>
<item row="11" column="0">
<widget class="QLabel" name="label_39">
<property name="text">
<string>Seq. Start Marker:</string>
</property>
</widget>
</item>
<item row="12" column="0">
<widget class="QLabel" name="label_40">
<property name="text">
<string>Fast Downlink:</string>
</property>
</widget>
</item>
<item row="13" column="0">
<widget class="QLabel" name="label_41">
<property name="text">
<string>Inverse Data:</string>
</property>
</widget>
</item>
<item row="14" column="0">
<widget class="QLabel" name="label_42">
<property name="text">
<string>Init-Delay:</string>
</property>
</widget>
</item>
<item row="14" column="1">
<widget class="QCheckBox" name="checkBox_3"/>
</item>
<item row="13" column="1">
<widget class="QCheckBox" name="checkBox_4"/>
</item>
<item row="12" column="1">
<widget class="QCheckBox" name="checkBox_5"/>
</item>
<item row="11" column="1">
<widget class="QCheckBox" name="checkBox_6"/>
</item>
<item row="10" column="1">
<widget class="QCheckBox" name="checkBox_7"/>
</item>
<item row="9" column="1">
<widget class="QCheckBox" name="checkBox_8"/>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox"/>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="comboBox_3"/>
</item>
<item row="6" column="1">
<widget class="QCheckBox" name="checkBox_9"/>
</item>
<item row="7" column="1">
<widget class="QCheckBox" name="checkBox_10"/>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="spinBox_2"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox_3">
<property name="geometry">
<rect>
<x>670</x>
<y>20</y>
<width>311</width>
<height>511</height>
</rect>
</property>
<property name="title">
<string>Analog Front-End Option(Page 1 Block 3)</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_22">
<property name="leftMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<item>
<layout class="QFormLayout" name="formLayout_5">
<item row="0" column="0">
<widget class="QLabel" name="label_45">
<property name="text">
<string>Hex:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_46">
<property name="text">
<string>Bin:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="lineEdit_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>4</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="lineEdit_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>1</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_24">
<item>
<spacer name="horizontalSpacer_16">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>Get from Data</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>Set to Data</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_20">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QFormLayout" name="formLayout_6">
<property name="rowWrapPolicy">
<enum>QFormLayout::WrapLongRows</enum>
</property>
<property name="horizontalSpacing">
<number>5</number>
</property>
<property name="verticalSpacing">
<number>5</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="label_47">
<property name="text">
<string>Locked:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QCheckBox" name="checkBox_11"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_48">
<property name="text">
<string>Option Key:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="spinBox_3"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_49">
<property name="text">
<string>Soft Modulation:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="comboBox_4"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_50">
<property name="text">
<string>Clamp Voltage:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="comboBox_7"/>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_51">
<property name="text">
<string>Modulation Voltage:</string>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="QComboBox" name="comboBox_5"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_52">
<property name="text">
<string>Clock Detection Threshold:</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QComboBox" name="comboBox_6"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="label_53">
<property name="text">
<string>Gap Detection Threshold:</string>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QComboBox" name="comboBox_8"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="label_54">
<property name="text">
<string>Write Dampling:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_55">
<property name="text">
<string>Demod Delay:</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QLabel" name="label_56">
<property name="text">
<string>Downlink Protocol:</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QComboBox" name="comboBox_9"/>
</item>
<item row="8" column="1">
<widget class="QComboBox" name="comboBox_10"/>
</item>
<item row="9" column="1">
<widget class="QComboBox" name="comboBox_11"/>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_11">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>50</x>
<y>150</y>
<width>221</width>
<height>201</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_19">
<item>
<widget class="QLabel" name="label_57">
<property name="text">
<string>Data:</string>
</property>
</widget>
</item>
<item>
<widget class="QTableWidget" name="T55_dataWidget"/>
</item>
</layout>
</widget>
<widget class="QGroupBox" name="groupBox_4">
<property name="geometry">
<rect>
<x>50</x>
<y>370</y>
<width>194</width>
<height>231</height>
</rect>
</property>
<property name="title">
<string>T55xx Read Config</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_20">
<item>
<layout class="QFormLayout" name="formLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="label_58">
<property name="text">
<string>Modulation:</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_59">
<property name="text">
<string>Bit Rate:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label_60">
<property name="text">
<string>Seq. Term.</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_61">
<property name="text">
<string>Offset:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_62">
<property name="text">
<string>Inverted:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QComboBox" name="comboBox_12"/>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="comboBox_13"/>
</item>
<item row="2" column="1">
<widget class="QCheckBox" name="checkBox_12">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="spinBox_4"/>
</item>
<item row="4" column="1">
<widget class="QCheckBox" name="checkBox_13">
<property name="text">
<string/>
</property>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_28">
<item>
<widget class="QRadioButton" name="radioButton">
<property name="text">
<string>T5577</string>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButton_2">
<property name="text">
<string>T5555</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_12">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget> </widget>
</widget> </widget>
<widget class="QWidget" name="rawTab"> <widget class="QWidget" name="rawTab">