diff --git a/candatagrid.cpp b/candatagrid.cpp index 7b85cbb..45faa09 100644 --- a/candatagrid.cpp +++ b/candatagrid.cpp @@ -18,10 +18,10 @@ CANDataGrid::CANDataGrid(QWidget *parent) : memset(refData, 0, 64); memset(usedData, 0, 64); for (int j = 0; j < 512; j++) usedSignalNum[j] = -1; - bytesToDraw = 16; //default to the old behavior + bytesToDraw = 8; //default to the old behavior for (int x = 0; x < 8; x++) for (int y = 0; y < 64; y++) - textStates[x][y] = GridTextState::NORMAL; + textStates[y][x] = GridTextState::NORMAL; blackBrush = QBrush(Qt::black); whiteBrush = QBrush(Qt::white); @@ -64,33 +64,43 @@ void CANDataGrid::mousePressEvent(QMouseEvent *event) clickedPoint -= upperLeft; if (clickedPoint.x() < 0 || clickedPoint.y() < 0) { - //qDebug() << "Clicked outside the grid you wanker"; + //qDebug() << "Clicked outside the grid"; return; } int x = clickedPoint.x() / gridSize.x(); int y = clickedPoint.y() / gridSize.y(); qDebug() << "Grid square clicked " << x << " " << y; - emit gridClicked(x,y); + int bitClicked = gridToBitPosition(x, y); + //this control is the ultimate authority on which bit is at which grid so what we're going to do now + //is return the actual bit so everyone else doesn't have to try to calculate it. When someone clicks + //what the parent GUI really cares about is which bit that was. + emit gridClicked(bitClicked); + } + if (event->button() == Qt::MiddleButton) //cycle through the various grid layouts for frame sizes + { + //qDebug() << "Middle Button"; + if (bytesToDraw < 9) bytesToDraw = 16; + else if (bytesToDraw < 31) bytesToDraw = 32; + else if (bytesToDraw < 63) bytesToDraw = 64; + else if (bytesToDraw > 32) bytesToDraw = 8; + this->update(); } } -void CANDataGrid::setCellTextState(int x, int y, GridTextState state) +void CANDataGrid::setCellTextState(int bitPos, GridTextState state) { - if (x < 0) return; - if (x > 7) return; - if (y < 0) return; - if (y > 63) return; - textStates[x][y] = state; + //textStates has two dimensions but they are NOT X and Y and don't necessarily correspond to X and Y in the grid + int byte = bitPos / 8; + int bit = bitPos & 7; + textStates[byte][bit] = state; this->update(); } -GridTextState CANDataGrid::getCellTextState(int x, int y) +GridTextState CANDataGrid::getCellTextState(int bitPos) { - if (x < 0) return GridTextState::NORMAL; - if (x > 7) return GridTextState::NORMAL; - if (y < 0) return GridTextState::NORMAL; - if (y > 63) return GridTextState::NORMAL; - return textStates[x][y]; + int byte = bitPos / 8; + int bit = bitPos & 7; + return textStates[byte][bit]; } void CANDataGrid::setSignalNames(int sigIdx, const QString sigName) @@ -129,8 +139,7 @@ void CANDataGrid::paintEvent(QPaintEvent *event) Q_UNUSED(event); paintCommonBeginning(); - if (gridMode == GridMode::CHANGED_BITS) paintChangedBits(); - if (gridMode == GridMode::SIGNAL_VIEW) paintSignalView(); + paintGridCells(); paintCommonEnding(); } @@ -177,7 +186,7 @@ void CANDataGrid::paintCommonBeginning() bigTextSize = qMin(viewport.size().height(), viewport.size().width()) / 12; smallTextSize = qMin(viewport.size().height(), viewport.size().width()) / 24; } - sigNameTextSize = qMin(viewport.size().height(), viewport.size().width()) / (textRestrict * 4); + sigNameTextSize = qMin(viewport.size().height(), viewport.size().width()) / (textRestrict * 4.5); painter->setPen(QPen(QApplication::palette().color(QPalette::Text))); mainFont.setPixelSize(bigTextSize); @@ -240,7 +249,7 @@ void CANDataGrid::paintCommonBeginning() painter->setFont(mainFont); } -void CANDataGrid::paintChangedBits() +void CANDataGrid::paintGridCells() { int x, y, bit; unsigned char prevByte, thisByte; @@ -248,6 +257,21 @@ void CANDataGrid::paintChangedBits() int usedSigNum; QString prevSigName; + //if this is true then generate unique colors for each signal + if ((signalColors.count() == 0) && (signalNames.count() > 0) && gridMode == GridMode::SIGNAL_VIEW) + { + qDebug() << "Generating colors"; + signalColors.resize(signalNames.count()); + for (int i = 0; i < signalNames.count(); i++) + { + QColor newColor; + while (newColor.saturation() < 40) + newColor.setRgb(QRandomGenerator::global()->bounded(160) + 60,QRandomGenerator::global()->bounded(160) + 60, QRandomGenerator::global()->bounded(160) + 60); + qDebug() << newColor; + signalColors[i] = newColor; + } + } + //now, color the bitfield by seeing if a given bit is freshly set/unset in the new data //compared to the old. Bits that are not set in either are white, bits set in both are black //bits that used to be set but now are unset are red, bits that used to be unset but now are set @@ -271,11 +295,13 @@ void CANDataGrid::paintChangedBits() { if (prevBit) { - painter->setBrush(blackBrush); + if ((signalColors.count() > 0) && (gridMode == GridMode::SIGNAL_VIEW)) painter->setBrush(blackHashBrush); + else painter->setBrush(blackBrush); } else { - painter->setBrush(greenBrush); + if ((signalColors.count() > 0) && (gridMode == GridMode::SIGNAL_VIEW)) painter->setBrush(greenHashBrush); + else painter->setBrush(greenBrush); } } else @@ -285,18 +311,23 @@ void CANDataGrid::paintChangedBits() painter->setBrush(redBrush); } else - { + { usedSigNum = -1; if ((usedData[byteIdx] & (1 << bitIdx)) == (1 << bitIdx)) { - grayBrush = QBrush(QColor(0xB6, 0xB6, 0xB6), Qt::BDiagPattern); - painter->setBrush(grayBrush); + if (gridMode == GridMode::SIGNAL_VIEW) usedSigNum = getUsedSignalNum(bit); + if (usedSigNum == -1) + { + grayBrush = QBrush(QColor(0xB6, 0xB6, 0xB6), Qt::BDiagPattern); + painter->setBrush(grayBrush); + } + else painter->setBrush(QBrush(signalColors[usedSigNum])); } else painter->setBrush(whiteBrush); } } painter->drawRect(nearX + (x * xSector), nearY + (y * ySector), xSector, ySector); - switch (textStates[bitIdx][byteIdx]) + switch (textStates[byteIdx][bitIdx]) { case GridTextState::NORMAL: if (thisBit && prevBit) painter->setPen(QPen(Qt::gray)); @@ -317,130 +348,31 @@ void CANDataGrid::paintChangedBits() //if (thisBit) painter->setFont(boldFont); // else painter->setFont(mainFont); painter->setFont(smallFont); - - painter->drawText(QRect(nearX + (x * xSector), nearY + (y * ySector), xSector, ySector), Qt::AlignCenter, QString::number(bit)); - - painter->setFont(mainFont); - painter->setPen(QPen(Qt::black)); - } - } -} - - -//not converted to the new format where CAN-FD is supported. This is probably broken badly! -void CANDataGrid::paintSignalView() -{ - int x, y, bit; - unsigned char prevByte, thisByte; - bool thisBit, prevBit; - int usedSigNum; - QString prevSigName; - - //if this is true then generate unique colors for each signal - if ((signalColors.count() == 0) && (signalNames.count() > 0)) - { - qDebug() << "Generating colors"; - signalColors.resize(signalNames.count()); - for (int i = 0; i < signalNames.count(); i++) - { - QColor newColor; - while (newColor.saturation() < 40) - newColor.setRgb(QRandomGenerator::global()->bounded(160) + 60,QRandomGenerator::global()->bounded(160) + 60, QRandomGenerator::global()->bounded(160) + 60); - qDebug() << newColor; - signalColors[i] = newColor; - } - } - - for (y = 0; y < 8; y++) - { - thisByte = data[y]; - prevByte = refData[y]; - for (x = 0; x < 8; x++) - { - bit = (y * 8) + (7 - x); - thisBit = false; - prevBit = false; - if ((thisByte & (1 << (7-x))) == (1 << (7-x))) thisBit = true; - if ((prevByte & (1 << (7-x))) == (1 << (7-x))) prevBit = true; - - if (thisBit) - { - if (prevBit) - { - if (signalColors.count() > 0) painter->setBrush(blackHashBrush); - else painter->setBrush(blackBrush); - } - else - { - if (signalColors.count() > 0) painter->setBrush(greenHashBrush); - else painter->setBrush(greenBrush); - } - } + if (gridMode != GridMode::SIGNAL_VIEW) + painter->drawText(QRect(nearX + (x * xSector), nearY + (y * ySector), xSector, ySector), Qt::AlignCenter, QString::number(bit)); //center center of grid else - { - if (prevBit) - { - painter->setBrush(redBrush); - } - else - { - usedSigNum = -1; - if ((usedData[y] & (1 << (7-x))) == (1 << (7-x))) - { - usedSigNum = getUsedSignalNum(bit); - if (usedSigNum == -1) - { - grayBrush = QBrush(QColor(0xB6, 0xB6, 0xB6), Qt::BDiagPattern); - painter->setBrush(grayBrush); - } - else painter->setBrush(QBrush(signalColors[usedSigNum])); - } - else painter->setBrush(whiteBrush); - } - } - - //painter->fillRect(viewport.left() + (x+2) * xSector, viewport.top() + (y+2) * ySector, xSector, ySector, redBrush); - painter->drawRect(viewport.left() + (x) * xSector, viewport.top() + (y) * ySector, xSector, ySector); - switch (textStates[x][y]) - { - case GridTextState::NORMAL: - //if (thisBit && prevBit) painter->setPen(QPen(Qt::gray)); - /*else*/ painter->setPen(QPen(Qt::black)); - painter->setFont(mainFont); - break; - case GridTextState::BOLD_BLUE: - painter->setPen(QPen(Qt::blue)); - painter->setFont(boldFont); - break; - case GridTextState::INVERT: - painter->setFont(mainFont); - QColor brushColor = painter->brush().color(); - painter->setPen(QColor(255-brushColor.red(), 255-brushColor.green(), 255-brushColor.blue())); - break; - } - //change style of bit number output for current signal - //if (thisBit) painter->setFont(boldFont); - // else painter->setFont(mainFont); - painter->setFont(smallFont); - - painter->drawText(viewport.left() + (x) * xSector + (xSector / 8), viewport.top() + (y + 1) * ySector - (ySector * 0.7), QString::number(bit)); + painter->drawText(QRect(nearX + (x * xSector), nearY + (y * ySector), xSector, ySector), Qt::AlignLeft, QString::number(bit)); //upper left of grid painter->setFont(mainFont); painter->setPen(QPen(Qt::black)); } } + //now if signal names are loaded we'll go through all the bits again and try to label over top of the grid if (signalNames.count() > 0) { painter->setFont(sigNameFont); - for (y = 0; y < 8; y++) + + for (y = 0; y < neededYDivisions; y++) { - for (x = 0; x < 8; x++) + for (x = 0; x < neededXDivisions; x++) { - bit = (y * 8) + (7 - x); + int byteIdx = (y * (neededXDivisions / 8) + (x / 8)); + int bitIdx = ((neededXDivisions - 1) - x) & 7; + bit = (byteIdx * 8) + bitIdx; usedSigNum = -1; - if ((usedData[y] & (1 << (7-x))) == (1 << (7-x))) + if ((usedData[byteIdx] & (1 << bitIdx)) == (1 << bitIdx)) { usedSigNum = getUsedSignalNum(bit); if (prevSigName != signalNames[usedSigNum]) @@ -452,17 +384,17 @@ void CANDataGrid::paintSignalView() if (textWidth > xSector) //signal name is too long for a single cell. Try to wrap it { int numAvgChars = xSector / smallMetric->averageCharWidth(); - painter->drawText(viewport.left() + (x) * xSector, viewport.top() + (y + 1) * ySector - (ySector * 0.4), prevSigName.left(numAvgChars - 1)); + painter->drawText(nearX + x * xSector + 5, nearY + (y * ySector) + smallMetric->height() * 2, prevSigName.left(numAvgChars - 1)); QString remainder = prevSigName.mid(numAvgChars - 1, -1); textWidth = smallMetric->horizontalAdvance(prevSigName); if (textWidth > xSector) { - painter->drawText(viewport.left() + (x) * xSector, viewport.top() + (y + 1) * ySector - (ySector * 0.2), remainder.left(numAvgChars - 1)); - + painter->drawText(nearX + x * xSector + 12, nearY + (y * ySector) + smallMetric->height() * 3, remainder.left(numAvgChars - 1)); } - else painter->drawText(viewport.left() + (x) * xSector, viewport.top() + (y + 1) * ySector - (ySector * 0.2), remainder); + else painter->drawText(nearX + x * xSector + 12, nearY + (y * ySector) + smallMetric->height() * 3, remainder); + } - else painter->drawText(viewport.left() + (x) * xSector, viewport.top() + (y + 1) * ySector - (ySector * 0.4), prevSigName); + else painter->drawText(nearX + x * xSector + 5, nearY + (y * ySector) + smallMetric->height() * 2, prevSigName); } } } @@ -470,6 +402,7 @@ void CANDataGrid::paintSignalView() } } + void CANDataGrid::paintCommonEnding() { //these are used to make it easy to figure out which grid has been clicked on during mousedown events @@ -483,6 +416,30 @@ void CANDataGrid::paintCommonEnding() delete smallMetric; } +//given a grid cell we return which bit position that is within the CAN frame. +int CANDataGrid::gridToBitPosition(int x, int y) +{ + int byteIdx = (y * (neededXDivisions / 8) + (x / 8)); + int bitIdx = ((neededXDivisions - 1) - x) & 7; + int bit = (byteIdx * 8) + bitIdx; + return bit; +} + +//inverse of above. Given a bit position we calculate where that would be in our grid +QPoint CANDataGrid::getGridPointFromBitPosition(int bitPos) +{ + int tempBit = bitPos; + //neededXDivisions tells us how many bits are on a single line. + //From there we can easily determine which Y row we're in with simple division + int y = bitPos / neededXDivisions; + //x is more complicated because the bits go in a sort of stairstep pattern 7654321076543210 + tempBit = (bitPos - (neededXDivisions * y)); + int x = tempBit & 0xF8; //get the byte offset in the line + x = x + (7- (tempBit & 7)); //reverse the bits in the byte + + return QPoint(x, y); +} + void CANDataGrid::saveImage(QString filename, int width, int height) { Q_UNUSED(width); //currently unused but I want to use them in the future diff --git a/candatagrid.h b/candatagrid.h index 8c9d5a0..d52f43e 100644 --- a/candatagrid.h +++ b/candatagrid.h @@ -46,13 +46,13 @@ class CANDataGrid : public QWidget public: explicit CANDataGrid(QWidget *parent = 0); ~CANDataGrid(); - void paintEvent(QPaintEvent *event); + void paintEvent(QPaintEvent *event) override; void setReference(unsigned char *, bool); void updateData(unsigned char *, bool); void setUsed(unsigned char *, bool); void saveImage(QString filename, int width, int height); - void setCellTextState(int x, int y, GridTextState state); - GridTextState getCellTextState(int x, int y); + void setCellTextState(int bitPos, GridTextState state); + GridTextState getCellTextState(int bitPos); void setUsedSignalNum(int bit, int signal); void setSignalNames(int sigIdx, const QString sigName); void clearSignalNames(); @@ -65,7 +65,7 @@ protected: void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE; signals: - void gridClicked(int x,int y); + void gridClicked(int bitClicked); private: Ui::CANDataGrid *ui; @@ -76,7 +76,7 @@ private: int usedSignalNum[512]; //so we can specify which signal claims this bit QVector signalNames; QVector signalColors; - GridTextState textStates[8][64]; //first dimension is bits, second is bytes + GridTextState textStates[64][8]; //first dimension is bytes, second is bits QPoint upperLeft, gridSize; GridMode gridMode; QBrush blackBrush, whiteBrush, redBrush, greenBrush, grayBrush; @@ -99,10 +99,11 @@ private: QFont sigNameFont; QFontMetrics *smallMetric; - void paintChangedBits(); - void paintSignalView(); + void paintGridCells(); void paintCommonBeginning(); - void paintCommonEnding(); + void paintCommonEnding(); + int gridToBitPosition(int x, int y); + QPoint getGridPointFromBitPosition(int bitPos); }; #endif // CANDATAGRID_H diff --git a/re/flowviewwindow.cpp b/re/flowviewwindow.cpp index 9d1f58a..c4f416d 100644 --- a/re/flowviewwindow.cpp +++ b/re/flowviewwindow.cpp @@ -26,10 +26,10 @@ FlowViewWindow::FlowViewWindow(const QVector *frames, QWidget *parent) playbackActive = false; playbackForward = true; - memset(refBytes, 0, 8); - memset(currBytes, 0, 8); + memset(refBytes, 0, 64); + memset(currBytes, 0, 64); memset(triggerValues, -1, sizeof(int) * 8); - triggerBits = 0; + for (int i = 0; i < 8; i++) triggerBits[i] = 0; //ui->graphView->setInteractions(); @@ -131,7 +131,7 @@ FlowViewWindow::FlowViewWindow(const QVector *frames, QWidget *parent) connect(ui->graphView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestGraph(QPoint))); ui->flowView->setContextMenuPolicy(Qt::CustomContextMenu); connect(ui->flowView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(contextMenuRequestFlow(QPoint))); - connect(ui->flowView, SIGNAL(gridClicked(int,int)), this, SLOT(gotCellClick(int,int))); + connect(ui->flowView, SIGNAL(gridClicked(int)), this, SLOT(gotCellClick(int))); // Prevent annoying accidental horizontal scrolling when filter list is populated with long interpreted message names ui->listFrameID->horizontalScrollBar()->setEnabled(false); @@ -262,13 +262,14 @@ void FlowViewWindow::changeGraphVisibility(int state){ ui->graphView->replot(); } } -void FlowViewWindow::gotCellClick(int x, int y) +void FlowViewWindow::gotCellClick(int bitPosition) { - int bitnum = (7-x) + (8 * y); - triggerBits = triggerBits ^ (1ull << bitnum); - if (triggerBits & (1ull << bitnum)) ui->flowView->setCellTextState(x, y, GridTextState::BOLD_BLUE); - else ui->flowView->setCellTextState(x, y, GridTextState::NORMAL); - qDebug() << "Bit Num: " << bitnum << " Hex of trigger bits: " << QString::number(triggerBits, 16); + int chunk = bitPosition / 64; + int idx = bitPosition & 63; + triggerBits[chunk] = triggerBits[chunk] ^ (1ull << idx); + if (triggerBits[chunk] & (1ull << idx)) ui->flowView->setCellTextState(bitPosition, GridTextState::BOLD_BLUE); + else ui->flowView->setCellTextState(bitPosition, GridTextState::NORMAL); + qDebug() << "Bit Num: " << bitPosition << " Hex of trigger bits: " << QString::number(triggerBits[chunk], 16); } void FlowViewWindow::graphRangeChanged(int range) { @@ -454,8 +455,8 @@ void FlowViewWindow::updatedFrames(int numFrames) refreshIDList(); updateFrameLabel(); removeAllGraphs(); - memset(refBytes, 0, 8); - memset(currBytes, 0, 8); + memset(refBytes, 0, 64); + memset(currBytes, 0, 64); updateDataView(); } else if (numFrames == -2) //all new set of frames. Reset @@ -518,9 +519,9 @@ void FlowViewWindow::updatedFrames(int numFrames) if (ui->cbLiveMode->checkState() == Qt::Checked) { currentPosition = frameCache.count() - 1; - memset(currBytes, 0, 8); + memset(currBytes, 0, 64); memcpy(currBytes, frameCache.at(currentPosition).payload().data(), frameCache.at(currentPosition).payload().length()); - memcpy(refBytes, currBytes, 8); + memcpy(refBytes, currBytes, 64); } if (needRefresh) @@ -657,9 +658,9 @@ void FlowViewWindow::changeID(QString newID) updateGraphLocation(); - memset(currBytes, 0, 8); + memset(currBytes, 0, 64); memcpy(currBytes, frameCache.at(currentPosition).payload().constData(), frameCache.at(currentPosition).payload().length()); - memcpy(refBytes, currBytes, 8); + memcpy(refBytes, currBytes, 64); updateDataView(); ui->check_0->setChecked(true); @@ -705,9 +706,9 @@ void FlowViewWindow::btnStopClick() playbackActive = false; currentPosition = 0; - memset(currBytes, 0, 8); + memset(currBytes, 0, 64); memcpy(currBytes, frameCache.at(currentPosition).payload().constData(), frameCache.at(currentPosition).payload().length()); - memcpy(refBytes, currBytes, 8); + memcpy(refBytes, currBytes, 64); updateFrameLabel(); updateDataView(); @@ -831,31 +832,36 @@ void FlowViewWindow::updatePosition(bool forward) if (ui->cbAutoRef->isChecked()) { - memcpy(refBytes, currBytes, 8); + memcpy(refBytes, currBytes, 64); } //figure out which bits changed since the previous frame and then AND that with the trigger bits. If any bits //get through that then they're changed and a trigger so we stop playback at this frame. - uint64_t changedBits = 0; - uint8_t cngByte; - for (int i = 0; i < frameCache.at(currentPosition).payload().length(); i++) + //This is complicated by the fact that CAN-FD frames might have far more than 64 bits. It is necessary + //to thus process them 64 bits at a time and just move chunk to chunk until done. + for (int chunk = 0; chunk < frameCache.at(currentPosition).payload().length(); chunk += 8) { - unsigned char thisByte = static_cast(frameCache.at(currentPosition).payload().data()[i]); - cngByte = currBytes[i] ^ thisByte; - changedBits |= (uint64_t)cngByte << (8ull * i); - } + uint64_t changedBits = 0; + uint8_t cngByte; + int maxVal = qMin(chunk * 8 + 8, frameCache.at(currentPosition).payload().length()); + for (int i = chunk * 8; i < maxVal; i++) + { + unsigned char thisByte = static_cast(frameCache.at(currentPosition).payload().data()[i]); + cngByte = currBytes[i] ^ thisByte; + changedBits |= (uint64_t)cngByte << (8ull * (i & 7)); + } - qDebug() << "ChangedBits: " << QString::number(changedBits, 16); - qDebug() << "TriggerBits: " << QString::number(triggerBits, 16); - changedBits &= triggerBits; - qDebug() << "Final ChangedBits: " << QString::number(changedBits, 16); - if (changedBits) - { - playbackActive = false; - playbackTimer->stop(); + qDebug() << "ChangedBits: " << QString::number(changedBits, 16); + qDebug() << "TriggerBits: " << QString::number(triggerBits[chunk / 8], 16); + changedBits &= triggerBits[chunk / 8]; + qDebug() << "Final ChangedBits: " << QString::number(changedBits, 16); + if (changedBits) + { + playbackActive = false; + playbackTimer->stop(); + } } - - memset(currBytes, 0, 8); + memset(currBytes, 0, 64); memcpy(currBytes, frameCache.at(currentPosition).payload().constData(), frameCache.at(currentPosition).payload().length()); if (ui->cbSync->checkState() == Qt::Checked) emit sendCenterTimeID(frameCache[currentPosition].frameId(), frameCache[currentPosition].timeStamp().microSeconds() / 1000000.0); diff --git a/re/flowviewwindow.h b/re/flowviewwindow.h index 9f437f2..9d13330 100644 --- a/re/flowviewwindow.h +++ b/re/flowviewwindow.h @@ -39,7 +39,7 @@ private slots: void plottableDoubleClick(QCPAbstractPlottable* plottable, QMouseEvent* event); void gotCenterTimeID(uint32_t ID, double timestamp); void updateTriggerValues(); - void gotCellClick(int x, int y); + void gotCellClick(int bitPosition); void graphRangeChanged(int range); void changeGraphVisibility(int state); @@ -51,10 +51,10 @@ private: QList foundID; QList frameCache; const QVector *modelFrames; - unsigned char refBytes[8]; - unsigned char currBytes[8]; + unsigned char refBytes[64]; + unsigned char currBytes[64]; int triggerValues[8]; - uint64_t triggerBits; + uint64_t triggerBits[8]; int currentPosition; QTimer *playbackTimer; bool playbackActive; diff --git a/re/fuzzingwindow.cpp b/re/fuzzingwindow.cpp index c320248..d7c84a4 100644 --- a/re/fuzzingwindow.cpp +++ b/re/fuzzingwindow.cpp @@ -26,7 +26,7 @@ FuzzingWindow::FuzzingWindow(const QVector *frames, QWidget *parent) : connect(ui->spinTiming, SIGNAL(valueChanged(int)), this, SLOT(changePlaybackSpeed(int))); connect(ui->listID, &QListWidget::itemChanged, this, &FuzzingWindow::idListChanged); connect(ui->spinBytes, SIGNAL(valueChanged(int)), this, SLOT(changedNumDataBytes(int))); - connect(ui->bitfield, SIGNAL(gridClicked(int,int)), this, SLOT(bitfieldClicked(int,int))); + connect(ui->bitfield, SIGNAL(gridClicked(int)), this, SLOT(bitfieldClicked(int))); connect(ui->txtByte0, &QLineEdit::returnPressed, this, [=](){changedDataByteText(0, ui->txtByte0->text());}); connect(ui->txtByte1, &QLineEdit::returnPressed, this, [=](){changedDataByteText(1, ui->txtByte1->text());}); connect(ui->txtByte2, &QLineEdit::returnPressed, this, [=](){changedDataByteText(2, ui->txtByte2->text());}); @@ -43,7 +43,7 @@ FuzzingWindow::FuzzingWindow(const QVector *frames, QWidget *parent) : currentlyFuzzing = false; - for (int j = 0; j < 64; j++) bitGrid[j] = 1; + for (int j = 0; j < 512; j++) bitGrid[j] = 1; numBits = 64; bitAccum = 0; redrawGrid(); @@ -146,8 +146,10 @@ void FuzzingWindow::changedNumDataBytes(int newVal) ui->txtByte6->setEnabled((newVal > 6) ? true : false); ui->txtByte7->setEnabled((newVal > 7) ? true : false); + ui->bitfield->setBytesToDraw(newVal); + int byt; - for (int i = 0; i < 64; i++) + for (int i = 0; i < 511; i++) { byt = i / 8; if (byt >= newVal) @@ -448,20 +450,18 @@ void FuzzingWindow::idListChanged(QListWidgetItem *item) } /* -bitGrid stores the state of all 64 bits. +bitGrid stores the state of all bits. The grid is capable of showing the following colors: White = not used (left as 0) Gray = past the end of the valid bits (because of # of data bytes requested) Green = fuzz it black = always keep it set to 1 */ -void FuzzingWindow::bitfieldClicked(int x, int y) +void FuzzingWindow::bitfieldClicked(int bitPos) { - qDebug() << "X: " << x << " Y: " << y; - int bit = (7 - x) + (y * 8); - if (bitGrid[bit] == 3) return; //naughty! - bitGrid[bit]++; - if (bitGrid[bit] > 2) bitGrid[bit] = 0; + if (bitGrid[bitPos] == 3) return; //naughty! + bitGrid[bitPos]++; + if (bitGrid[bitPos] > 2) bitGrid[bitPos] = 0; redrawGrid(); } @@ -469,11 +469,11 @@ void FuzzingWindow::bitfieldClicked(int x, int y) void FuzzingWindow::redrawGrid() { //now update the bits in the bitfield control - uint8_t refBytes[8]; - uint8_t dataBytes[8]; - uint8_t usedBytes[8]; + uint8_t refBytes[64]; + uint8_t dataBytes[64]; + uint8_t usedBytes[64]; - for (int j = 0; j < 8; j++) + for (int j = 0; j < 64; j++) { refBytes[j] = 0; dataBytes[j] = 0; @@ -482,7 +482,7 @@ void FuzzingWindow::redrawGrid() numBits = 0; - for (int i = 0; i < 64; i++) + for (int i = 0; i < 512; i++) { int byt = i / 8; int bit = i % 8; diff --git a/re/fuzzingwindow.h b/re/fuzzingwindow.h index 23a7ece..6b52da4 100644 --- a/re/fuzzingwindow.h +++ b/re/fuzzingwindow.h @@ -39,7 +39,7 @@ private slots: void setAllFilters(); void toggleFuzzing(); void idListChanged(QListWidgetItem *item); - void bitfieldClicked(int, int); + void bitfieldClicked(int); void changedNumDataBytes(int newVal); void updatedFrames(int numFrames); @@ -54,8 +54,8 @@ private: bool seqIDScan, rangeIDSelect; int bitSequenceType; bool currentlyFuzzing; - uint8_t currentBytes[8]; - uint8_t bitGrid[64]; + uint8_t currentBytes[64]; + uint8_t bitGrid[512]; uint8_t numBits; uint64_t bitAccum; int numSentFrames; diff --git a/re/graphingwindow.cpp b/re/graphingwindow.cpp index df8e29f..bf6da55 100644 --- a/re/graphingwindow.cpp +++ b/re/graphingwindow.cpp @@ -1046,6 +1046,7 @@ void GraphingWindow::loadDefinitions() gp.bias = tokens[6].toFloat(); gp.scale = tokens[7].toFloat(); gp.stride = tokens[8].toInt(); + gp.bus = -1; gp.lineColor.setRed( tokens[9].toInt() ); gp.lineColor.setGreen( tokens[10].toInt() ); @@ -1080,6 +1081,7 @@ void GraphingWindow::loadDefinitions() else //one of the two older formats then { gp.ID = tokens[0].toUInt(nullptr, 16); + gp.bus = -1; if (tokens[1] == "S") //old signal based graph definition { //tokens[2] is the signal name. Need to use the message ID and this name to look it up diff --git a/re/newgraphdialog.cpp b/re/newgraphdialog.cpp index 59fcde5..db122b2 100644 --- a/re/newgraphdialog.cpp +++ b/re/newgraphdialog.cpp @@ -44,7 +44,7 @@ NewGraphDialog::NewGraphDialog(DBCHandler *handler, QWidget *parent) : ui->coPointStyle->addItem("Peace Sign"); connect(ui->cbMessages, SIGNAL(currentIndexChanged(int)), this, SLOT(loadSignals(int))); - connect(ui->gridData, SIGNAL(gridClicked(int,int)), this, SLOT(bitfieldClicked(int,int))); + connect(ui->gridData, SIGNAL(gridClicked(int)), this, SLOT(bitfieldClicked(int))); connect(ui->txtDataLen, SIGNAL(textChanged(QString)), this, SLOT(handleDataLenUpdate())); connect(ui->cbIntel, SIGNAL(toggled(bool)), this, SLOT(drawBitfield())); connect(ui->btnCopySignal, SIGNAL(clicked(bool)), this, SLOT(copySignalToParamsUI())); @@ -300,10 +300,8 @@ void NewGraphDialog::loadSignals(int idx) checkSignalAgreement(); } -void NewGraphDialog::bitfieldClicked(int x,int y) +void NewGraphDialog::bitfieldClicked(int bit) { - int bit = (y * 8 + (7-x)); - qDebug() << "Clicked bit: " << bit; startBit = bit; drawBitfield(); @@ -312,20 +310,25 @@ void NewGraphDialog::bitfieldClicked(int x,int y) void NewGraphDialog::drawBitfield() { qDebug() << "Draw Bitfield"; - int64_t bitField = 0; + uint8_t bitField[64]; int endBit, sBit; - bitField |= 1ull << (startBit); //make the start bit a different color to set it apart + memset(bitField, 0, 64); + + //make the start bit a different color to set it apart + bitField[Utility::getByteFromBitPosition(startBit)] |= 1 << Utility::getBitFromBitPosition(startBit); + ui->gridData->setReference((unsigned char *)&bitField, false); if (ui->cbIntel->isChecked()) { endBit = startBit + dataLen - 1; if (startBit < 0) startBit = 0; - if (endBit > 63) endBit = 63; + if (endBit > 511) endBit = 511; for (int y = startBit; y <= endBit; y++) { - bitField |= 1ull << y; + //bitField |= 1ull << y; + bitField[Utility::getByteFromBitPosition(y)] |= 1 << Utility::getBitFromBitPosition(y); } } else //big endian / motorola format @@ -335,11 +338,12 @@ void NewGraphDialog::drawBitfield() sBit = startBit; while (size > 0) { - bitField |= 1ull << sBit; + //bitField |= 1ull << sBit; + bitField[Utility::getByteFromBitPosition(sBit)] |= 1 << Utility::getBitFromBitPosition(sBit); size--; if ((sBit % 8) == 0) sBit += 15; else sBit--; - if (sBit > 63) sBit = 63; + if (sBit > 511) sBit = 511; } } @@ -352,7 +356,7 @@ void NewGraphDialog::handleDataLenUpdate() { dataLen = ui->txtDataLen->text().toInt(); if (dataLen < 1) dataLen = 1; - if (dataLen > 63) dataLen = 63; + if (dataLen > 64) dataLen = 64; drawBitfield(); checkSignalAgreement(); } diff --git a/re/newgraphdialog.h b/re/newgraphdialog.h index 26283c3..3729542 100644 --- a/re/newgraphdialog.h +++ b/re/newgraphdialog.h @@ -27,7 +27,7 @@ private slots: void fillSwatchClick(); void loadMessages(); void loadSignals(int idx); - void bitfieldClicked(int,int); + void bitfieldClicked(int); void handleDataLenUpdate(); void drawBitfield(); void copySignalToParamsUI(); diff --git a/ui/fuzzingwindow.ui b/ui/fuzzingwindow.ui index ba6e22f..1600b97 100644 --- a/ui/fuzzingwindow.ui +++ b/ui/fuzzingwindow.ui @@ -6,8 +6,8 @@ 0 0 - 760 - 671 + 1188 + 701 @@ -45,7 +45,7 @@ - 8 + 64 8 @@ -264,7 +264,6 @@ - 75 true @@ -283,7 +282,6 @@ - 75 true @@ -299,7 +297,6 @@ - 75 true @@ -315,7 +312,6 @@ - 75 true @@ -331,7 +327,6 @@ - 75 true @@ -347,7 +342,6 @@ - 75 true @@ -363,7 +357,6 @@ - 75 true @@ -379,7 +372,6 @@ - 75 true @@ -391,6 +383,86 @@ + + + + 8 + + + + + + + + + + 9 + + + + + + + + + + 10 + + + + + + + + + + 11 + + + + + + + + + + 12 + + + + + + + + + + 13 + + + + + + + + + + 14 + + + + + + + + + + 15 + + + + + + @@ -427,7 +499,6 @@ 11 - 75 true diff --git a/utility.h b/utility.h index 47a6e96..b3daba8 100644 --- a/utility.h +++ b/utility.h @@ -199,6 +199,16 @@ public: return builder; } + static int getByteFromBitPosition(int bitPos) + { + return bitPos / 8; + } + + static int getBitFromBitPosition(int bitPos) + { + return bitPos & 7; + } + //simple linear interpolation between value1 and value2. sample point is 0.0 to 1.0 static double Lerp(double value1, double value2, double samplePoint) {