Updated Sniffer help, added a lot of functionality to Sniffer Window

Sniffer can now
keep all ids without expiring
Fade out bytes that aren't changing
This commit is contained in:
Collin Kidder
2018-10-22 22:29:21 -04:00
parent c427115d7c
commit dd1c6b8a6e
7 changed files with 132 additions and 28 deletions
+4 -3
View File
@@ -8,11 +8,12 @@ Sniffer Window
Using the Sniffer Window
=========================
This window is essentially a graphical version of the linux can_utils. The general idea here is to display a list of frames such that you only see frames that are actively updating. If a given ID has not been seen in 4 seconds the ID portion will turn RED and then disappear from the list. In this way only frames that are updating are in the list. They are ordered by last update time. Bytes that have deincremented will be red and bytes that have incremented will be green. You can use the "Filters" area to mask away some IDs so that they never show up. This can help to declutter the list.
This window is essentially a graphical version of the linux can_utils program "cansniffer". The general idea here is to display a list of frames such that you only see frames that are actively updating. If a given ID has not been seen in 5 seconds the ID portion will turn RED and then disappear from the list. In this way only frames that are updating are in the list. They are ordered by ID. Bytes that have deincremented will be red and bytes that have incremented will be green. You can use the "Filters" area to mask away some IDs so that they never show up. This can help to declutter the list.
This window updates with a 200ms interval.
Notching and Unnotching
========================
Honestly, I don't know. It seems that notching means to store the current value of the data bytes for each frame and then use that notch data for the comparison for increment / deincrement to color the bytes. Unnotching would then be clearing that out so that it uses the previous value from the last time the frame ID was seen. But, don't quote me on that. This should be figured out definitively and corrected.
While the window is running it keeps a running list each 200ms cycle of all the bits that changed in that timespan. Each 200ms this list is backed up and reset. If you push the notch button the system will remember all the bits that were set in the last 200ms window and will not color the output if those bits are toggled in the future. They will thus somewhat be ignored except that you can visually still see them updating. If you click the Notch button repeatedly it will add any new changed bits to the old changed bits. In this way you can build up a set of bits to ignore. Un-notching causes all notched (ignored) bits to be reset and thus all changes will be colored once again.
+36 -16
View File
@@ -4,14 +4,17 @@
SnifferItem::SnifferItem(const CANFrame& pFrame):
mNotch(0),
mID(pFrame.ID)
{
mMarker = {0,0};
mLastMarker = {0,0};
for (int i = 0; i < 8; i++) {
mNotch[i] =0;
mMarker.data[i] = 0;
mMarker.dataTimestamp[i] = 0;
}
mLastMarker = mMarker;
/* that's dirty */
update(pFrame);
update(pFrame);
update(pFrame, 0);
update(pFrame, 0);
}
@@ -33,7 +36,12 @@ float SnifferItem::getDelta() const
//Get a data byte by index 0-7 (but not more than the length of the actual frame)
int SnifferItem::getData(uchar i) const
{
return (i >= mCurrent.len) ? -1 : ((uchar*) &mCurrent.data)[i];
return (i >= mCurrent.len) ? -1 : mCurrent.data[i];
}
quint32 SnifferItem::getDataTimestamp(uchar i) const
{
return (i >= mCurrent.len) ? 0 : mCurrent.dataTimestamp[i];
}
//Return whether a given data byte (by index 0-7) has incremented, deincremented, or stayed the same
@@ -45,10 +53,10 @@ dc SnifferItem::dataChange(uchar i) const
{
if (i >= mCurrent.len) return dc::NO;
uchar notch = ((uchar*) &mNotch)[i];
uchar byt = ((uchar*) &mCurrent.data)[i];
uchar last = ((uchar*) &mLast.data)[i];
uchar lastMark = ((uchar*) &mLastMarker.data)[i];
uchar notch = mNotch[i];
uchar byt = mCurrent.data[i];
uchar last = mLast.data[i];
uchar lastMark = mLastMarker.data[i];
if( lastMark )
{
if (!notch) //if no notching is set
@@ -66,27 +74,36 @@ dc SnifferItem::dataChange(uchar i) const
return dc::NO;
}
int SnifferItem::elapsed() const
{
return mTime.elapsed();
}
//called when a new frame comes in that matches our same ID
void SnifferItem::update(const CANFrame& pFrame)
void SnifferItem::update(const CANFrame& pFrame, quint32 timeSeq)
{
/* copy current to last */
mLast = mCurrent;
mLastTime = mCurrentTime;
/* copy new value */
memcpy(&mCurrent.data, pFrame.data, 8);
for (int i = 0; i < 8; i++)
{
if (mCurrent.data[i] != pFrame.data[i])
{
mCurrent.data[i] = pFrame.data[i];
mCurrent.dataTimestamp[i] = timeSeq;
}
}
mCurrent.len = pFrame.len;
mCurrentTime = pFrame.timestamp;
/* update marker */
//We "OR" our stored marker with the changed bits.
//this accumulates changed bits into the marker
mMarker.data |= mLast.data ^ mCurrent.data; //XOR causes only changed bits to be 1's
for (int i = 0 ; i < 8; i++) mMarker.data[i] |= mLast.data[i] ^ mCurrent.data[i]; //XOR causes only changed bits to be 1's
mMarker.len |= mLast.len ^ mCurrent.len;
/* restart timeout */
@@ -98,14 +115,17 @@ void SnifferItem::update(const CANFrame& pFrame)
void SnifferItem::updateMarker()
{
mLastMarker = mMarker;
mMarker = {0, 0};
for (int i = 0; i < 8; i++) mMarker.data[i] = 0;
}
//Notch or un-notch this snifferitem / frame
void SnifferItem::notch(bool pNotch)
{
if(pNotch)
mNotch |= mLastMarker.data; //add changed bits to notch value
{
for (int i = 0; i < 8; i++) mNotch[i] |= mLastMarker.data[i]; //add changed bits to notch value
}
else
mNotch = 0;
for (int i = 0; i < 8; i++) mNotch[i] = 0;
}
+7 -4
View File
@@ -7,7 +7,8 @@
struct fstCan
{
quint64 data;
quint8 data[8];
quint32 dataTimestamp[8];
int len;
};
@@ -28,18 +29,20 @@ public:
quint64 getId() const;
float getDelta() const;
int getData(uchar i) const;
quint32 getDataTimestamp(uchar i) const;
dc dataChange(uchar) const;
int elapsed() const;
void update(const CANFrame& pFrame);
void update(const CANFrame& pFrame, quint32 timeSeq);
void updateMarker();
void notch(bool);
private:
quint64 mID;
quint32 mID;
struct fstCan mLast;
struct fstCan mCurrent;
struct fstCan mLastMarker;
struct fstCan mMarker;
quint64 mNotch;
quint8 mNotch[8];
quint64 mLastTime;
quint64 mCurrentTime;
+49 -4
View File
@@ -5,7 +5,11 @@
SnifferModel::SnifferModel(QObject *parent)
: QAbstractItemModel(parent),
mFilter(false)
mFilter(false),
mNeverExpire(false),
mFadeInactive(false),
mMuteNotched(false),
mTimeSequence(0)
{
}
@@ -61,11 +65,20 @@ QVariant SnifferModel::data(const QModelIndex &index, int role) const
}
break;
}
case Qt::ForegroundRole:
{
if (!mFadeInactive || col < 2) return QBrush(Qt::black);
int v = (mTimeSequence - item->getDataTimestamp(col - 2)) * 20;
if (v > 215) v = 215;
return QBrush(QColor(v,v,v,255));
break;
}
case Qt::BackgroundRole:
{
if(tc::ID==col)
{
if(item->elapsed()>4000)
if(item->elapsed() > 4000)
return QBrush(Qt::red);
}
else if(tc::DATA_0<=col && col<=tc::DATA_7)
@@ -143,6 +156,35 @@ QModelIndex SnifferModel::parent(const QModelIndex &) const
return QModelIndex();
}
bool SnifferModel::getNeverExpire()
{
return mNeverExpire;
}
bool SnifferModel::getFadeInactive()
{
return mFadeInactive;
}
bool SnifferModel::getMuteNotched()
{
return mMuteNotched;
}
void SnifferModel::setNeverExpire(bool val)
{
mNeverExpire = val;
}
void SnifferModel::setFadeInactive(bool val)
{
mFadeInactive = val;
}
void SnifferModel::setMuteNotched(bool val)
{
mMuteNotched = val;
}
void SnifferModel::clear()
{
@@ -161,13 +203,15 @@ void SnifferModel::refresh()
QVector<quint32> toRemove;
SnifferItem* item;
mTimeSequence++;
/* update markers */
for (i = mMap.begin(); i != mMap.end(); ++i)
{
i.value()->updateMarker();
if(i.value()->elapsed()>5000)
if(i.value()->elapsed()>5000 && !mNeverExpire)
toRemove.append(i.key());
}
@@ -238,13 +282,14 @@ void SnifferModel::update(CANConnection*, QVector<CANFrame>& pFrames)
/* add the frame */
beginInsertRows(QModelIndex(), index, index);
mMap[frame.ID] = new SnifferItem(frame);
mMap[frame.ID]->update(frame, mTimeSequence);
endInsertRows();
emit idChange(frame.ID, true);
}
else
//updateData
mMap[frame.ID]->update(frame);
mMap[frame.ID]->update(frame, mTimeSequence);
}
}
+11
View File
@@ -40,6 +40,13 @@ public:
void refresh();
void clear();
void filter(fltType pType, int pId=0);
bool getNeverExpire();
bool getFadeInactive();
bool getMuteNotched();
void setNeverExpire(bool val);
void setFadeInactive(bool val);
void setMuteNotched(bool val);
public slots:
void update(CANConnection*, QVector<CANFrame>&);
@@ -53,6 +60,10 @@ private:
QMap<quint32, SnifferItem*> mMap;
QMap<quint32, SnifferItem*> mFilters;
bool mFilter;
bool mNeverExpire;
bool mFadeInactive;
bool mMuteNotched;
quint32 mTimeSequence;
};
#endif // SNIFFERMODEL_H
+3
View File
@@ -37,6 +37,9 @@ SnifferWindow::SnifferWindow(QWidget *parent) :
connect(&mModel, &SnifferModel::idChange, this, &SnifferWindow::idChange);
connect(ui->listWidget, &QListWidget::itemChanged, this, &SnifferWindow::itemChanged);
connect(ui->cbFadeInactive, &QCheckBox::stateChanged, this, [this](int val){mModel.setFadeInactive(val);});
connect(ui->cbMuteNotched, &QCheckBox::stateChanged, this, [this](int val){mModel.setMuteNotched(val);});
connect(ui->cbNoExpire, &QCheckBox::stateChanged, this, [this](int val){mModel.setNeverExpire(val);});
}
SnifferWindow::~SnifferWindow()
+22 -1
View File
@@ -6,7 +6,7 @@
<rect>
<x>0</x>
<y>0</y>
<width>602</width>
<width>710</width>
<height>752</height>
</rect>
</property>
@@ -82,6 +82,27 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbNoExpire">
<property name="text">
<string>Never Expire IDs</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbMuteNotched">
<property name="text">
<string>Mute notched bits</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cbFadeInactive">
<property name="text">
<string>Fade inactive bytes</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">