Files
giesCANne/re/sniffer/snifferitem.cpp
T
Collin Kidder 0baffa300f A partial commit that changes CANFrame over to be based on
QCanBusFrame so that things are more compatible with other Qt based
CAN bus code. Not complete yet but getting there.
2019-12-11 21:17:33 -05:00

160 lines
4.5 KiB
C++

#include <QVariant>
#include <QDebug>
#include "snifferitem.h"
SnifferItem::SnifferItem(const CANFrame& pFrame, quint32 seq):
mID(pFrame.ID)
{
for (int i = 0; i < 8; i++) {
mNotch[i] =0;
mMarker.data[i] = 0;
mMarker.dataTimestamp[i] = 0;
mCurrent.data[i] = pFrame.payload()[i];
mCurrent.dataTimestamp[i] = seq;
}
mLastMarker = mMarker;
mCurrent.len = pFrame.payload().length();
/* that's dirty */
update(pFrame, seq, false);
update(pFrame, seq, false);
}
SnifferItem::~SnifferItem()
{
}
quint64 SnifferItem::getId() const
{
return mID;
}
float SnifferItem::getDelta() const
{
return ((float)(mCurrentTime-mLastTime))/1000000;
}
//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 : mCurrent.data[i];
}
quint8 SnifferItem::getNotchPattern(uchar i) const
{
return (i >= mCurrent.len) ? -1 : mNotch[i];
}
quint8 SnifferItem::getLastData(uchar i) const
{
return (i >= mLast.len) ? -1 : mLast.data[i];
}
quint32 SnifferItem::getDataTimestamp(uchar i) const
{
return (i >= mCurrent.len) ? 0 : mCurrent.dataTimestamp[i];
}
quint32 SnifferItem::getSeqInterval(uchar i) const
{
return mCurrSeqVal - getDataTimestamp(i);
}
//Return whether a given data byte (by index 0-7) has incremented, deincremented, or stayed the same
//since the last message
//The If checks first that we aren't past the actual data length
// then checks whether lastMarker shows that some bits have changed in the previous 200ms cycle
// then we check if the byte in mNotch has bits set and if it does we say nothing changed (notched out)
dc SnifferItem::dataChange(uchar i) const
{
if (i >= mCurrent.len) return dc::NO;
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
return (byt >= last ? dc::INC : dc::DEINC);
else //mNotch contained a bit pattern so use masks and do things more complicated
{
byt &= ~notch; //mask off bits that were notched
if (byt == 0) return dc::NO; //and if result is null then nothing changed (other than maybe notched bits and they don't count)
last &= ~notch; //need to mask last too
if (last == byt) return dc::NO;
return (byt >= last ? dc::INC : dc::DEINC); //then compare the masked copies to see which way the bit(s) went
}
}
return dc::NO;
}
int SnifferItem::elapsed() const
{
return mTime.elapsed();
}
//called when a new frame comes in that matches our same ID
//timeSeq is stored so we can figure out the last time a specific byte was updated
//mute is used to specify whether to mask the byte against the notching filter
//in order to hide any updates of the notched bits. This is toggleable
void SnifferItem::update(const CANFrame& pFrame, quint32 timeSeq, bool mute)
{
unsigned char maskedCurr, maskedData;
//qDebug() << "update with ts: " << timeSeq;
/* copy current to last */
mLast = mCurrent;
mLastTime = mCurrentTime;
mCurrSeqVal = timeSeq;
/* copy new value */
for (int i = 0; i < 8; i++)
{
maskedData = pFrame.payload()[i];
if (mute) maskedData &= ~mNotch[i];
maskedCurr = mCurrent.data[i];
if (mute) maskedCurr &= ~mNotch[i];
if (maskedCurr != maskedData)
{
mCurrent.data[i] = pFrame.payload()[i];
mCurrent.dataTimestamp[i] = timeSeq;
}
}
mCurrent.len = pFrame.payload().length();
mCurrentTime = pFrame.timeStamp().microSeconds();
/* update marker */
//We "OR" our stored marker with the changed bits.
//this accumulates changed bits into the marker
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 */
mTime.restart();
}
//Called in refresh from the model. Interval about 200ms currently.
//So, this means the marker only accumulates for 200ms then resets
void SnifferItem::updateMarker()
{
mLastMarker = mMarker;
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)
{
for (int i = 0; i < 8; i++) mNotch[i] |= mLastMarker.data[i]; //add changed bits to notch value
}
else
for (int i = 0; i < 8; i++) mNotch[i] = 0;
}