diff --git a/.travis.yml b/.travis.yml
index cdfafe0..6923721 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -24,7 +24,7 @@ matrix:
- wget -c -nv "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage"
- chmod a+x linuxdeployqt-continuous-x86_64.AppImage
# export VERSION=... # linuxdeployqt uses this for naming the file
- - ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/local/share/applications/SavvyCAN.desktop -appimage -extra-plugins=iconengines,platformthemes.libqgtk3.so
+ - ./linuxdeployqt-continuous-x86_64.AppImage appdir/usr/local/share/applications/SavvyCAN.desktop -appimage -extra-plugins=iconengines,platformthemes/libqgtk3.so,canbus
after_success:
# find appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq # for debugging
@@ -50,7 +50,8 @@ matrix:
script:
- qmake CONFIG+=release -spec macx-xcode SavvyCAN.pro
- xcodebuild
- - cp *.q* Release/SavvyCAN.app/Contents/MacOS/
+ - mkdir Release/SavvyCAN.app/Contents/MacOS/help
+ - cp -R help/*.* Release/SavvyCAN.app/Contents/MacOS/help
- cd Release
- ls SavvyCAN.app/Contents/MacOS
- macdeployqt SavvyCAN.app -dmg
@@ -78,7 +79,8 @@ matrix:
- rm *.cpp
- rm *.h
- rm *.obj
- - cp ../*.q* .
+ - mkdir help
+ - cp -R ../help/*.* ./help
- cp -r ../examples .
- 7z a -tzip SavvyCAN32.zip -r *
@@ -92,6 +94,6 @@ matrix:
draft: false
branches:
- only:
- - master
- - WIP
+ except:
+ - # Do not build tags that we create when we upload to GitHub Releases
+ - /^(?i:continuous)/
diff --git a/SavvyCAN.pro b/SavvyCAN.pro
index f954497..605b90b 100644
--- a/SavvyCAN.pro
+++ b/SavvyCAN.pro
@@ -68,7 +68,8 @@ SOURCES += main.cpp\
blfhandler.cpp \
re/sniffer/SnifferDelegate.cpp \
connections/newconnectiondialog.cpp \
- re/temporalgraphwindow.cpp
+ re/temporalgraphwindow.cpp \
+ filterutility.cpp
HEADERS += mainwindow.h \
can_structs.h \
@@ -127,7 +128,8 @@ HEADERS += mainwindow.h \
blfhandler.h \
re/sniffer/SnifferDelegate.h \
connections/newconnectiondialog.h \
- re/temporalgraphwindow.h
+ re/temporalgraphwindow.h \
+ filterutility.h
FORMS += ui/candatagrid.ui \
ui/connectionwindow.ui \
@@ -186,8 +188,8 @@ iconfiles.files=icons
iconfiles.path = $$PREFIX/share/icons
INSTALLS += iconfiles
-helpfiles.files=SavvyCAN.q*
-helpfiles.path = $$PREFIX/bin
+helpfiles.files=help/*
+helpfiles.path = $$PREFIX/bin/help
INSTALLS += helpfiles
INSTALLS += target
diff --git a/SavvyCAN.qch b/SavvyCAN.qch
deleted file mode 100644
index 997519a..0000000
Binary files a/SavvyCAN.qch and /dev/null differ
diff --git a/SavvyCAN.qhc b/SavvyCAN.qhc
deleted file mode 100644
index e218082..0000000
Binary files a/SavvyCAN.qhc and /dev/null differ
diff --git a/SavvyCAN.qhcp b/SavvyCAN.qhcp
deleted file mode 100644
index fad8e16..0000000
--- a/SavvyCAN.qhcp
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
- SavvyCAN 189 documentation
- qthelp://org.sphinx.savvycan.189/doc/index.html
- qthelp://org.sphinx.savvycan.189/doc/index.html
-
-
-
-
- SavvyCAN.qhp
-
-
-
-
- SavvyCAN.qch
-
-
-
\ No newline at end of file
diff --git a/SavvyCAN.qhp b/SavvyCAN.qhp
deleted file mode 100644
index c5acc7a..0000000
--- a/SavvyCAN.qhp
+++ /dev/null
@@ -1,170 +0,0 @@
-
-
- org.sphinx.savvycan.189
- doc
-
- SavvyCAN
- 189
-
-
- SavvyCAN
- 189
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- bisector.html
- connectionwindow.html
- customsender.html
- dbc_editor.html
- dbc_manager.html
- filecomparison.html
- firmwareuploader.html
- flowview.html
- framedetails.html
- fuzzingwindow.html
- genindex.html
- graphsetup.html
- graphwindow.html
- index.html
- isotp_decoder.html
- mainscreen.html
- playbackwindow.html
- preferences.html
- rangestate.html
- scriptingwindow.html
- search.html
- signaleditor.html
- sniffer.html
- uds_scanner.html
- _static/ajax-loader.gif
- _static/alabaster.css
- _static/basic.css
- _static/comment-bright.png
- _static/comment-close.png
- _static/comment.png
- _static/down-pressed.png
- _static/down.png
- _static/file.png
- _static/minus.png
- _static/nonav.css
- _static/plus.png
- _static/pygments.css
- _static/up-pressed.png
- _static/up.png
- _images/Bisector.png
- _images/ConnectionWindow.png
- _images/CustomSender.png
- _images/DBCEditor.png
- _images/DBCManager.png
- _images/FileComparator.png
- _images/FlowView.png
- _images/FrameInfoWindow.png
- _images/FuzzingWindow.png
- _images/GraphSetup.png
- _images/GraphingView.png
- _images/ISOTPDecoder.png
- _images/MainScreen.png
- _images/Playback.png
- _images/Preferences.png
- _images/RangeState.png
- _images/ScriptingWindow.png
- _images/SignalEditor.png
- _images/Sniffer.png
- _images/UDS_Scanner.png
-
-
-
\ No newline at end of file
diff --git a/bisectwindow.cpp b/bisectwindow.cpp
index 22d3e78..99a27ca 100644
--- a/bisectwindow.cpp
+++ b/bisectwindow.cpp
@@ -66,7 +66,7 @@ void BisectWindow::refreshIDList()
int id;
for (int i = 0; i < modelFrames->count(); i++)
{
- id = modelFrames->at(i).ID;
+ id = modelFrames->at(i).frameId();
if (!foundID.contains(id))
{
foundID.append(id);
@@ -129,7 +129,7 @@ void BisectWindow::handleCalculateButton()
uint32_t upperID = Utility::ParseStringToNum2(ui->cbIDUpper->currentText());
for (int i = 0; i < modelFrames->count(); i++)
{
- if (modelFrames->at(i).ID >= lowerID && modelFrames->at(i).ID <= upperID) splitFrames.append(modelFrames->at(i));
+ if (modelFrames->at(i).frameId() >= lowerID && modelFrames->at(i).frameId() <= upperID) splitFrames.append(modelFrames->at(i));
}
}
refreshFrameNumbers();
diff --git a/blfhandler.cpp b/blfhandler.cpp
index 7dde7b3..9c3fb1a 100644
--- a/blfhandler.cpp
+++ b/blfhandler.cpp
@@ -78,7 +78,7 @@ bool BLFHandler::loadBLF(QString filename, QVector* frames)
}
qDebug() << "Uncompressed size: " << uncompressedData.count();
pos = 0;
- bool foundHeader = false;
+ //bool foundHeader = false;
//first skip forward to find a header signature - usually not necessary
while ( (int)(pos + sizeof(BLF_OBJ_HEADER)) < uncompressedData.count())
{
@@ -100,19 +100,20 @@ bool BLFHandler::loadBLF(QString filename, QVector* frames)
memcpy(&canObject, fileData.constData(), sizeof(BLF_CAN_OBJ));
CANFrame frame;
frame.bus = canObject.channel;
- frame.extended = (canObject.id & 0x80000000ull)?true:false;
- frame.ID = canObject.id & 0x1FFFFFFFull;
+ frame.setExtendedFrameFormat((canObject.id & 0x80000000ull)?true:false);
+ frame.setFrameId(canObject.id & 0x1FFFFFFFull);
frame.isReceived = true;
- frame.len = canObject.dlc;
+ QByteArray bytes(canObject.dlc, 0);
if (canObject.flags & BLF_REMOTE_FLAG) {
- frame.remote = true;
+ frame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else {
- frame.remote = false;
- for (int i = 0; i < 8; i++) frame.data[i] = canObject.data[i];
+ frame.setFrameType(QCanBusFrame::DataFrame);
+ for (int i = 0; i < 8; i++) bytes[i] = canObject.data[i];
}
+ frame.setPayload(bytes);
//Should we divide by a thousand or a million? Unsure here. It appears some logs are stamped in microseconds and some in milliseconds?
- frame.timestamp = obj.header.v1Obj.uncompSize / 1000.0; //uncompsize field also used for timestamp oddly enough
+ frame.setTimeStamp(QCanBusFrame::TimeStamp(0, obj.header.v1Obj.uncompSize / 1000.0)); //uncompsize field also used for timestamp oddly enough
frames->append(frame);
}
else if (obj.header.base.objType == BLF_CAN_MSG2)
@@ -120,19 +121,19 @@ bool BLFHandler::loadBLF(QString filename, QVector* frames)
memcpy(&canObject2, fileData.constData(), sizeof(BLF_CAN_OBJ2));
CANFrame frame;
frame.bus = canObject2.channel;
- frame.extended = (canObject2.id & 0x80000000ull)?true:false;
- frame.ID = canObject2.id & 0x1FFFFFFFull;
+ frame.setExtendedFrameFormat((canObject2.id & 0x80000000ull)?true:false);
+ frame.setFrameId(canObject2.id & 0x1FFFFFFFull);
frame.isReceived = true;
- frame.len = canObject2.dlc;
+ QByteArray bytes(canObject2.dlc, 0);
if (canObject2.flags & BLF_REMOTE_FLAG) {
- frame.remote = true;
+ frame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else {
- frame.remote = false;
- for (int i = 0; i < 8; i++) frame.data[i] = canObject2.data[i];
+ frame.setFrameType(QCanBusFrame::DataFrame);
+ for (int i = 0; i < 8; i++) bytes[i] = canObject2.data[i];
}
//Should we divide by a thousand or a million? Unsure here. It appears some logs are stamped in microseconds and some in milliseconds?
- frame.timestamp = obj.header.v1Obj.uncompSize / 1000.0; //uncompsize field also used for timestamp oddly enough
+ frame.setTimeStamp(QCanBusFrame::TimeStamp(0, obj.header.v1Obj.uncompSize / 1000.0)); //uncompsize field also used for timestamp oddly enough
frames->append(frame);
}
else
@@ -162,5 +163,7 @@ bool BLFHandler::loadBLF(QString filename, QVector* frames)
bool BLFHandler::saveBLF(QString filename, QVector *frames)
{
+ Q_UNUSED(filename)
+ Q_UNUSED(frames)
return false;
}
diff --git a/bus_protocols/isotp_handler.cpp b/bus_protocols/isotp_handler.cpp
index 840bbd7..d56477c 100644
--- a/bus_protocols/isotp_handler.cpp
+++ b/bus_protocols/isotp_handler.cpp
@@ -9,7 +9,6 @@ ISOTP_HANDLER::ISOTP_HANDLER()
processAll = false;
lastSenderBus = 0;
lastSenderID = 0;
- issuedMultiFrame = false;
modelFrames = MainWindow::getReference()->getCANFrameModel()->getListReference();
@@ -48,10 +47,10 @@ void ISOTP_HANDLER::setReception(bool mode)
}
}
-void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data)
+void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QByteArray data)
{
CANFrame frame;
- frame.remote = false;
+ frame.setFrameType(QCanBusFrame::DataFrame);
int currByte = 0;
int index = 0;
if (bus < 0) return;
@@ -62,29 +61,28 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data)
if (data.length() < 8)
{
- issuedMultiFrame = false;
- frame.bus = bus;
- frame.ID = ID;
- if (ID > 0x7FF) frame.extended = true;
- else frame.extended = false;
- frame.len = 8;
- for (int b = 0; b < 8; b++) frame.data[b] = 0x00;
- frame.data[0] = data.length();
- for (int i = 0; i < frame.data[0]; i++) frame.data[i + 1] = data[i];
+ frame.bus = bus;
+ frame.setFrameId(ID);
+ if (ID > 0x7FF) frame.setExtendedFrameFormat(true);
+ else frame.setExtendedFrameFormat(false);
+ QByteArray bytes(8,0);
+ bytes.resize(8);
+ bytes[0] = data.length();
+ for (int i = 0; i < data.length(); i++) bytes[i + 1] = data[i];
+ frame.setPayload(bytes);
CANConManager::getInstance()->sendFrame(frame);
}
else //need to send a multi-part ISO_TP message - Respects timing and frame number based flow control
{
- issuedMultiFrame = true;
frame.bus = bus;
- frame.ID = ID;
- if (ID > 0x7FF) frame.extended = true;
- else frame.extended = false;
- frame.len = 8;
- for (int b = 0; b < 8; b++) frame.data[b] = 0x00;
- frame.data[0] = 0x10 + (data.length() / 256);
- frame.data[1] = data.length() & 0xFF;
- for (int i = 0; i < 6; i++) frame.data[2 + i] = data[currByte++];
+ frame.setFrameId(ID);
+ if (ID > 0x7FF) frame.setExtendedFrameFormat(true);
+ else frame.setExtendedFrameFormat(false);
+ QByteArray bytes(8, 0);
+ bytes[0] = 0x10 + (data.length() / 256);
+ bytes[1] = data.length() & 0xFF;
+ for (int i = 0; i < 6; i++) bytes[2 + i] = data[currByte++];
+ frame.setPayload(bytes);
CANConManager::getInstance()->sendFrame(frame);
//Queue up the rest of the frames
waitingForFlow = true;
@@ -93,13 +91,13 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector data)
frameTimer.start();
while (currByte < data.length())
{
- for (int b = 0; b < 8; b++) frame.data[b] = 0x00;
- frame.data[0] = 0x20 + index;
+ for (int b = 0; b < 8; b++) bytes[b] = 0x00;
+ bytes[0] = 0x20 + index;
index = (index + 1) & 0xF;
int bytesToGo = data.length() - currByte;
if (bytesToGo > 7) bytesToGo = 7;
- for (int i = 0; i < bytesToGo; i++) frame.data[1 + i] = data[currByte++];
- frame.len = 8;
+ for (int i = 0; i < bytesToGo; i++) bytes[1 + i] = data[currByte++];
+ frame.setPayload(bytes);
sendingFrames.append(frame);
//CANConManager::getInstance()->sendFrame(frame);
}
@@ -141,7 +139,7 @@ void ISOTP_HANDLER::rapidFrames(const CANConnection* conn, const QVector(frame.payload().data());
+ //int dataLen = frame.payload().count();
frameType = 0;
frameLen = 0;
@@ -168,14 +168,14 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
if (useExtendedAddressing)
{
ID = ID << 8;
- ID += frame.data[0];
- frameType = frame.data[1] >> 4;
- frameLen = frame.data[1] & 0xF;
+ ID += data[0];
+ frameType = data[1] >> 4;
+ frameLen = data[1] & 0xF;
}
else
{
- frameType = frame.data[0] >> 4;
- frameLen = frame.data[0] & 0xF;
+ frameType = data[0] >> 4;
+ frameLen = data[0] & 0xF;
}
switch(frameType)
@@ -188,87 +188,89 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
if (frameLen > 7) return;
msg.bus = frame.bus;
- msg.extended = frame.extended;
- msg.ID = ID;
+ msg.setExtendedFrameFormat( frame.hasExtendedFrameFormat() );
+ msg.setFrameId(ID);
msg.isReceived = frame.isReceived;
- msg.len = frameLen;
- msg.data.reserve(frameLen);
- msg.timestamp = frame.timestamp;
- if (useExtendedAddressing) for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+2]);
- else for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+1]);
+ msg.payload().reserve(frameLen);
+ msg.reportedLength = frameLen;
+ msg.setTimeStamp(frame.timeStamp());
+ msg.isMultiframe = false;
+ if (useExtendedAddressing) for (int j = 0; j < frameLen; j++) msg.payload().append(frame.payload()[j+2]);
+ else for (int j = 0; j < frameLen; j++) msg.payload().append(frame.payload()[j+1]);
//qDebug() << "Emitting single frame ISOTP message";
emit newISOMessage(msg);
break;
case 1: //first frame of a multi-frame message
checkNeedFlush(ID);
msg.bus = frame.bus;
- msg.extended = frame.extended;
- msg.ID = ID;
- msg.timestamp = frame.timestamp;
+ msg.setExtendedFrameFormat( frame.hasExtendedFrameFormat() );
+ msg.setFrameId(ID);
+ msg.setTimeStamp(frame.timeStamp());
msg.isReceived = frame.isReceived;
- issuedMultiFrame = true;
+ msg.isMultiframe = true;
frameLen = frameLen << 8;
if (useExtendedAddressing)
{
- frameLen += frame.data[2];
+ frameLen += data[2];
frameLen = frameLen & 0xFFF;
- msg.len = frameLen;
- msg.data.reserve(frameLen);
- for (int j = 0; j < 5; j++) msg.data.append(frame.data[3 + j]);
+ msg.payload().reserve(frameLen);
+ msg.reportedLength = frameLen;
+ for (int j = 0; j < 5; j++) msg.payload().append(frame.payload()[3 + j]);
}
else
{
- frameLen += frame.data[1];
+ frameLen += data[1];
frameLen = frameLen & 0xFFF;
- msg.len = frameLen;
- msg.data.reserve(frameLen);
- for (int j = 0; j < 6; j++) msg.data.append(frame.data[2 + j]);
+ msg.payload().reserve(frameLen);
+ msg.reportedLength = frameLen;
+ for (int j = 0; j < 6; j++) msg.payload().append(frame.payload()[2 + j]);
}
+ msg.lastSequence = -1;
messageBuffer.append(msg);
//The sending ID is set to the last ID we used to send from this class which is
//very likely to be correct. But, caution, there is a chance that it isn't. Beware.
- if (issueFlowMsgs && lastSenderID > 0 && issuedMultiFrame)
+ if (issueFlowMsgs && lastSenderID > 0)
{
CANFrame outFrame;
outFrame.bus = lastSenderBus;
- outFrame.extended = false;
- outFrame.ID = lastSenderID;
- outFrame.len = 8;
- for (int b = 0; b < 8; b++) outFrame.data[b] = 0x00;
- outFrame.data[0] = 0x30; //flow control, go ahead and send
- outFrame.data[1] = 0; //dont ask again about flow control
- outFrame.data[2] = 3; //separation time in milliseconds between messages.
+ outFrame.setExtendedFrameFormat(false);
+ outFrame.setFrameId(lastSenderID);
+ QByteArray bytes(8, 0);
+ bytes[0] = 0x30; //flow control, go ahead and send
+ bytes[1] = 0; //dont ask again about flow control
+ bytes[2] = 3; //separation time in milliseconds between messages.
+ outFrame.setPayload(bytes);
CANConManager::getInstance()->sendFrame(outFrame);
}
break;
case 2: //subsequent frames for multi-frame messages
- pMsg = NULL;
+ pMsg = nullptr;
for (int i = 0; i < messageBuffer.length(); i++)
{
- if (messageBuffer[i].ID == ID)
+ if (messageBuffer[i].frameId() == ID)
{
pMsg = &messageBuffer[i];
break;
}
}
if (!pMsg) return;
- ln = pMsg->len - pMsg->data.count();
+ if (!pMsg->isMultiframe) return; //if we didn't get a frame type 1 (start of multiframe) first then ignore this frame.
+ ln = pMsg->payload().length() - pMsg->payload().count();
//offset = pMsg->data.count();
if (useExtendedAddressing)
{
if (ln > 6) ln = 6;
- for (int j = 0; j < ln; j++) pMsg->data.append(frame.data[j+2]);
+ for (int j = 0; j < ln; j++) pMsg->payload().append(frame.payload()[j+2]);
}
else
{
if (ln > 7) ln = 7;
- for (int j = 0; j < ln; j++) pMsg->data.append(frame.data[j+1]);
+ for (int j = 0; j < ln; j++) pMsg->payload().append(frame.payload()[j+1]);
}
- if (pMsg->len <= pMsg->data.count())
+ if (pMsg->reportedLength <= pMsg->payload().count())
{
//qDebug() << "Emitting multiframe ISOTP message";
- issuedMultiFrame = false;
- emit newISOMessage(*pMsg);
+ checkNeedFlush(pMsg->frameId());
}
break;
case 3: //flow control messages
@@ -277,10 +279,10 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
case 0: //continue to send frames but maybe change inter-frame delay
waitingForFlow = false;
//data[1] contains number of frames to send before waiting for next flow control
- framesUntilFlow = frame.data[1];
+ framesUntilFlow = data[1];
if (framesUntilFlow == 0) framesUntilFlow = -1; //-1 means don't count frames and just keep going
//data[2] contains the interframe delay to use (0xF1 through 0xF9 are special through)
- if (frame.data[2] < 0xF1) frameTimer.start(frame.data[2]); //set proper delay between frames
+ if (data[2] < 0xF1) frameTimer.start(data[2]); //set proper delay between frames
else frameTimer.start(1); //can't do sub-millisecond sending with this code so just use 1ms timing
break;
case 1: //wait - do not send any more frames until other side says so
@@ -303,12 +305,21 @@ void ISOTP_HANDLER::checkNeedFlush(uint64_t ID)
{
for (int i = 0; i < messageBuffer.length(); i++)
{
- if (messageBuffer[i].ID == ID)
+ if (messageBuffer[i].frameId() == ID)
{
//used to pass by reference but now newISOMessage should pass by value which makes it easier to use cross thread
- //qDebug() << "Flushing a partial frame";
+ if (messageBuffer[i].frameId() > 0x600 && messageBuffer[i].frameId() < 0x630)
+ {
+ if (messageBuffer[i].reportedLength <= messageBuffer[i].payload().count())
+ {
+ qDebug() << "Flushing full frame" << QString::number(messageBuffer[i].frameId(), 16) << " " << messageBuffer[i].reportedLength << " " << messageBuffer[i].payload().count();
+ }
+ else
+ {
+ qDebug() << "Flushing a partial frame " << QString::number(messageBuffer[i].frameId(), 16) << " " << messageBuffer[i].reportedLength << " " << messageBuffer[i].payload().count();
+ }
+ }
emit newISOMessage(messageBuffer[i]);
- issuedMultiFrame = false;
messageBuffer.removeAt(i);
return;
}
diff --git a/bus_protocols/isotp_handler.h b/bus_protocols/isotp_handler.h
index 1aa4652..72ada5e 100644
--- a/bus_protocols/isotp_handler.h
+++ b/bus_protocols/isotp_handler.h
@@ -1,5 +1,4 @@
-#ifndef ISOTP_HANDLER_H
-#define ISOTP_HANDLER_H
+#pragma once
#include
#include
@@ -20,7 +19,7 @@ public:
~ISOTP_HANDLER();
void setExtendedAddressing(bool mode);
void setReception(bool mode); //set whether to accept and forward frames or not
- void sendISOTPFrame(int bus, int ID, QVector data);
+ void sendISOTPFrame(int bus, int ID, QByteArray data);
void setProcessAll(bool state);
void setFlowCtrl(bool state);
void addFilter(uint32_t pBusId, uint32_t ID, uint32_t mask);
@@ -46,7 +45,6 @@ private:
int framesUntilFlow;
bool processAll;
bool issueFlowMsgs;
- bool issuedMultiFrame;
QTimer frameTimer;
uint32_t lastSenderID;
uint32_t lastSenderBus;
@@ -54,5 +52,3 @@ private:
void processFrame(const CANFrame &frame);
void checkNeedFlush(uint64_t ID);
};
-
-#endif // ISOTP_HANDLER_H
diff --git a/bus_protocols/isotp_message.h b/bus_protocols/isotp_message.h
index 5de2c21..788a069 100644
--- a/bus_protocols/isotp_message.h
+++ b/bus_protocols/isotp_message.h
@@ -1,18 +1,18 @@
#ifndef ISOTP_MESSAGE_H
#define ISOTP_MESSAGE_H
-//the same as the CANFrame struct but with arbitrary data size.
-class ISOTP_MESSAGE
+#include
+#include
+#include
+
+//Now a child class of CANFrame. We just add the ability to track how long it was supposed to be and other
+//ISOTP related details. But, mostly just CANFrame.
+class ISOTP_MESSAGE : public CANFrame
{
public:
- uint32_t ID;
- int bus;
- bool extended;
- bool isReceived;
- uint32_t len; //# of bytes this message should have (as reported)
- uint32_t actualSize; //# we actually got
- QVector data;
- uint64_t timestamp;
+ int reportedLength;
+ int lastSequence;
+ bool isMultiframe;
};
#endif // ISOTP_MESSAGE_H
diff --git a/bus_protocols/uds_handler.cpp b/bus_protocols/uds_handler.cpp
index e9e0ed0..e0fb085 100644
--- a/bus_protocols/uds_handler.cpp
+++ b/bus_protocols/uds_handler.cpp
@@ -4,14 +4,14 @@
#include "isotp_handler.h"
#include
-QVector UDS_DIAG_CTRL_SUB = {
+static QVector UDS_DIAG_CTRL_SUB = {
{1,"DFLT_SESS", "Default session"},
{2,"PROG_SESS", "Programming Session"},
{3,"EXT_SESS", "Extended Diagnostics Session"},
{4,"SAFETY_SESS", "Safety System Diagnostics Session"},
};
-QVector UDS_ECU_RESET_SUB = {
+static QVector UDS_ECU_RESET_SUB = {
{1,"HARD_RESET", "Hard reset of ECU"},
{2,"KEYOFFON_RESET", "Simulated key off then on reset"},
{3,"SOFT_RESET", "Soft reset - leaving RAM intact"},
@@ -19,7 +19,7 @@ QVector UDS_ECU_RESET_SUB = {
{5,"DIS_POWERDOWN_RESET", "Disable sleep mode"},
};
-QVector UDS_COMM_CTRL_SUB = {
+static QVector UDS_COMM_CTRL_SUB = {
{0,"COMM_NORMAL", "Enable both Rx and Tx of normal messages"},
{1,"COMM_DIS_TX", "Enable reception of normal messages but don't Tx them"},
{3,"COMM_DIS_ALL", "Disable both Rx and Tx of non-diagnostics messages"},
@@ -27,13 +27,13 @@ QVector UDS_COMM_CTRL_SUB = {
{5,"COMM_ENHANC", "Addressed bus master should set related sub-bus to app scheduling mode"},
};
-QVector UDS_ROUTINE_SUB = {
+static QVector UDS_ROUTINE_SUB = {
{1,"START_ROUTINE", "Start routine by given ID"},
{2,"STOP_ROUTINE", "Stop routine by given ID"},
{3,"GET_ROUTINE_RESULTS", "Get results from routine specified by ID"},
};
-QVector UDS_SERVICE_DESC = {
+static QVector UDS_SERVICE_DESC = {
{1, "OBDII_SHOW_CURRENT", "OBDII - Show current data"},
{2, "OBDII_SHOW_FREEZE", "OBDII - Show freeze data"},
{3, "OBDII_SHOW_STORED_DTC", "OBDII - Show stored DTC codes"},
@@ -50,7 +50,8 @@ QVector UDS_SERVICE_DESC = {
{0x14, "CLEAR_DIAG", "Clear diagnostic trouble codes"},
{0x19, "READ_DTC", "Read diagnostic trouble codes"},
{0x1A, "GMLAN_READ_DIAGNOSTIC_ID", "GMLAN - Read diagnostics ID"},
- {0x20, "RETURN_TO_NORMAL", "Return to normal mode"},
+ {0x20, "RETURN_TO_NORMAL", "Return to normal mode"},
+ {0x21, "READ_BY_LOCALID", "Read data by Local ID"},
{0x22, "READ_BY_ID", "Read data by ID"},
{0x23, "READ_BY_ADDR", "Read data by address"},
{0x24, "READ_SCALING_ID", "Read scaling data by ID"},
@@ -84,7 +85,7 @@ QVector UDS_SERVICE_DESC = {
{0xFF, "UNKNOWN_CODE", "Unknown, likely proprietary UDS function code"}
};
-QVector UDS_NEG_RESPONSE =
+static QVector UDS_NEG_RESPONSE =
{
{0x10, "GENERAL_REJECT", "General rejection (no other codes matched)"},
{0x11, "SERVICE_NOTSUPP", "ECU does not support this service code"},
@@ -157,7 +158,6 @@ UDS_MESSAGE::UDS_MESSAGE()
subFunc = 0;
service = 0;
subFuncLen = 1;
- extended = false;
isErrorReply = false;
}
@@ -177,35 +177,39 @@ UDS_HANDLER::~UDS_HANDLER()
void UDS_HANDLER::gotISOTPFrame(ISOTP_MESSAGE msg)
{
qDebug() << "UDS handler got ISOTP frame";
+ unsigned char *data = reinterpret_cast(msg.payload().data());
+ int dataLen = msg.payload().count();
UDS_MESSAGE udsMsg;
udsMsg.bus = msg.bus;
- udsMsg.extended = msg.extended;
- udsMsg.ID = msg.ID;
+ udsMsg.setExtendedFrameFormat(msg.hasExtendedFrameFormat());
+ udsMsg.setFrameId(msg.frameId());
udsMsg.isReceived = msg.isReceived;
- udsMsg.timestamp = msg.timestamp;
- udsMsg.actualSize = msg.actualSize;
- udsMsg.len = msg.len;
- if (msg.data.length() > 0) {
- udsMsg.service = msg.data.at(0);
+ udsMsg.setTimeStamp(msg.timeStamp());
+ udsMsg.reportedLength = msg.reportedLength;
+ udsMsg.service = 0;
+ udsMsg.subFunc = 0;
+ udsMsg.subFuncLen = 0;
+ udsMsg.isErrorReply = false;
+ udsMsg.setPayload(msg.payload());
+ if (dataLen > 0) {
+ udsMsg.service = data[0];
if (udsMsg.service == 0x7F)
{
udsMsg.isErrorReply = true;
- if (msg.data.length() > 1)
+ if (dataLen > 1)
{
- udsMsg.service = msg.data.at(1);
- if (msg.data.length() > 2) udsMsg.subFunc = msg.data.at(2);
+ udsMsg.service = data[1];
+ if (dataLen > 2) udsMsg.subFunc = data[2];
else return;
}
else return;
- udsMsg.data = msg.data.mid(2, -1); //don't copy error byte nor service byte
- udsMsg.len -= 2; //and remove those bytes from the length reported too.
+ udsMsg.payload().remove(0, 2);
}
else
{
udsMsg.isErrorReply = false;
- if (msg.data.length() > 1) udsMsg.subFunc = msg.data.at(1);
- udsMsg.data = msg.data.mid(1, -1); //don't copy service byte
- udsMsg.len -= 1; //and remove service byte from length too.
+ if (dataLen > 1) udsMsg.subFunc = data[1];
+ udsMsg.payload().remove(0, 1);
}
}
else return;
@@ -240,7 +244,7 @@ void UDS_HANDLER::setReception(bool mode)
void UDS_HANDLER::sendUDSFrame(const UDS_MESSAGE &msg)
{
- QVector data;
+ QByteArray data;
if (msg.bus < 0) return;
if (msg.bus >= CANConManager::getInstance()->getNumBuses()) return;
if (msg.service > 0xFF) return;
@@ -251,8 +255,8 @@ void UDS_HANDLER::sendUDSFrame(const UDS_MESSAGE &msg)
data.append((msg.subFunc >> (8 * b)) & 0xFF);
}
- data.append(msg.data);
- isoHandler->sendISOTPFrame(msg.bus, msg.ID, data);
+ data.append(msg.payload());
+ isoHandler->sendISOTPFrame(msg.bus, msg.frameId(), data);
qDebug() << "Sent UDS service: " << getServiceShortDesc(msg.service) << " on bus " << msg.bus;
}
@@ -323,6 +327,8 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
bool isResponse = true;
int dataSize;
int addrSize;
+ unsigned char *data = reinterpret_cast(msg.payload().data());
+ int dataLen = msg.payload().length();
if (msg.isErrorReply)
{
@@ -358,15 +364,15 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
case UDS_SERVICES::DIAG_CONTROL + 0x40: //positive response
buildString.append("Session Request: " + getLongDesc(UDS_DIAG_CTRL_SUB, msg.subFunc));
//there should be four extra bytes now
- if (msg.data.length() < 5) //5 because subfunc codes are left in data so it starts with one subfunc byte
+ if (dataLen < 5) //5 because subfunc codes are left in data so it starts with one subfunc byte
{
//buildString.append("\nReturned data payload wasn't at least \n4 bytes like it should have been");
}
else
{
- int p2 = msg.data[1] * 256 + msg.data[2];
+ int p2 = data[1] * 256 + data[2];
buildString.append("\nP2MAX (Max Wait / Resp Time): " + QString::number(p2) + "ms");
- p2 = (msg.data[3] * 256 + msg.data[4]) * 10;
+ p2 = (data[3] * 256 + data[4]) * 10;
buildString.append("\nP2 Ext MAX: " + QString::number(p2) + "ms");
}
break;
@@ -377,11 +383,11 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
case UDS_SERVICES::ECU_RESET + 0x40:
buildString.append("Reset Type: " + getLongDesc(UDS_ECU_RESET_SUB, msg.subFunc));
//There should be one additional byte which encodes power down time
- if (msg.data.length() > 1)
+ if (dataLen > 1)
{
- if (msg.data[1] < 0xFF)
+ if (data[1] < 0xFF)
{
- buildString.append("\nMinimum powered down time: " + QString::number(msg.data[1]));
+ buildString.append("\nMinimum powered down time: " + QString::number(data[1]));
}
else buildString.append("\nPowerdown time not available");
}
@@ -390,11 +396,11 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
case UDS_SERVICES::COMM_CTRL:
//Comm control has potentially a lot of parameters. control type, comm type, nodeID
buildString.append("Control type: " + getLongDesc(UDS_COMM_CTRL_SUB, msg.subFunc));
- if (msg.data.length() > 1)
- buildString.append("\nComm Type: " + QString::number(msg.data[1])); //TODO: no attempt to interpret yet
- if (msg.data.length() > 3)
+ if (dataLen > 1)
+ buildString.append("\nComm Type: " + QString::number(data[1])); //TODO: no attempt to interpret yet
+ if (dataLen > 3)
{
- int nodeID = (msg.data[2] * 256 + msg.data[3]);
+ int nodeID = (data[2] * 256 + data[3]);
buildString.append("\nNode ID: " + Utility::formatHexNum(nodeID));
}
break;
@@ -402,19 +408,19 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
if ((msg.subFunc % 2) == 1)
{
buildString.append("Seed request for security level: " + QString::number(msg.subFunc) + "\n");
- if (msg.data.length()> 1)
+ if (dataLen > 1)
{
buildString.append("Data payload: ");
- for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
+ for (int j = 1; j < dataLen; j++) buildString.append(Utility::formatHexNum(data[j]) + " ");
}
}
else
{
buildString.append("Key sending for security level: " + QString::number(msg.subFunc - 1));
- if (msg.data.length()> 1) //and it sure as hell should be!
+ if (dataLen > 1) //and it sure as hell should be!
{
buildString.append("KEY: ");
- for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
+ for (int j = 1; j < dataLen; j++) buildString.append(Utility::formatHexNum(data[j]) + " ");
}
}
break;
@@ -422,10 +428,10 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
if ((msg.subFunc % 2) == 1)
{
buildString.append("Seed response for security level: " + QString::number(msg.subFunc) + "\n");
- if (msg.data.length()> 1) //be kinda pointless if it weren't
+ if (dataLen > 1) //be kinda pointless if it weren't
{
buildString.append("SEED: ");
- for (int j = 1; j < msg.data.length(); j++) buildString.append(Utility::formatHexNum(msg.data[j]) + " ");
+ for (int j = 1; j < dataLen; j++) buildString.append(Utility::formatHexNum(data[j]) + " ");
}
}
else
@@ -436,33 +442,33 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
break;
case UDS_SERVICES::READ_BY_ID:
//parameter is groups of two bytes, each of which specify an ID to read
- if (msg.data.length() > 2)
+ if (dataLen > 2)
{
uint32_t id;
- for (int i = 1; i < msg.data.length(); i = i + 2)
+ for (int i = 1; i < dataLen; i = i + 2)
{
- id = (msg.data[i] * 256) + msg.data[i+1];
+ id = (data[i] * 256) + data[i+1];
buildString.append("\nID to read: " + Utility::formatHexNum(id));
}
}
break;
case UDS_SERVICES::READ_BY_ID + 0x40: //reply
buildString.append("Reply is non-standard and so no decoding is done. The format is (ID) followed by how ever much data that ID returns, followed by more ID/data pairs if applicable.\nPayload: ");
- for (int i = 1; i < msg.data.length(); i++)
+ for (int i = 1; i < dataLen; i++)
{
- buildString.append(Utility::formatHexNum(msg.data[i]) + " ");
+ buildString.append(Utility::formatHexNum(data[i]) + " ");
}
break;
case UDS_SERVICES::READ_BY_ADDR:
//subfunc byte specifies address and length format, then address, then size
dataSize = msg.subFunc >> 4;
addrSize = msg.subFunc & 0xF;
- if (msg.data.length() > (dataSize + addrSize))
+ if (dataLen > (dataSize + addrSize))
{
buildString.append("Address: 0x");
- for (int i = 0; i < addrSize; i++) buildString.append(QString::number(msg.data[1+i], 16).toUpper().rightJustified(2,'0'));
+ for (int i = 0; i < addrSize; i++) buildString.append(QString::number(data[1+i], 16).toUpper().rightJustified(2,'0'));
buildString.append("\nSize: 0x");
- for (int i = 0; i < dataSize; i++) buildString.append(QString::number(msg.data[1+i+addrSize], 16).toUpper().rightJustified(2,'0'));
+ for (int i = 0; i < dataSize; i++) buildString.append(QString::number(data[1+i+addrSize], 16).toUpper().rightJustified(2,'0'));
}
else
{
@@ -471,44 +477,44 @@ QString UDS_HANDLER::getDetailedMessageAnalysis(const UDS_MESSAGE &msg)
break;
case UDS_SERVICES::READ_BY_ADDR + 0x40:
buildString.append("Reply is a raw packet of data of the size requested.\nPayload: ");
- for (int i = 1; i < msg.data.length(); i++)
+ for (int i = 1; i < dataLen; i++)
{
- buildString.append(Utility::formatHexNum(msg.data[i]) + " ");
+ buildString.append(Utility::formatHexNum(data[i]) + " ");
}
break;
case UDS_SERVICES::WRITE_BY_ID:
break;
case UDS_SERVICES::ROUTINE_CTRL:
buildString.append("Routine Control: " + getLongDesc(UDS_ROUTINE_SUB, msg.subFunc));
- if (msg.data.length() > 2)
+ if (dataLen > 2)
{
int routineID;
- routineID = (msg.data[1] * 256 + msg.data[2]);
+ routineID = (data[1] * 256 + data[2]);
buildString.append("\nRoutine ID: " + Utility::formatHexNum(routineID));
}
- if (msg.data.length() > 3)
+ if (dataLen > 3)
{
buildString.append("\nParameter bytes to routine: ");
- for (int i = 4; i < msg.data.length(); i++)
+ for (int i = 4; i < dataLen; i++)
{
- buildString.append(Utility::formatHexNum(msg.data[i]) + " ");
+ buildString.append(Utility::formatHexNum(data[i]) + " ");
}
}
break;
case UDS_SERVICES::ROUTINE_CTRL + 0x40:
buildString.append("Routine Control: " + getLongDesc(UDS_ROUTINE_SUB, msg.subFunc));
- if (msg.data.length() > 2)
+ if (dataLen > 2)
{
int routineID;
- routineID = (msg.data[1] * 256 + msg.data[2]);
+ routineID = (data[1] * 256 + data[2]);
buildString.append("\nRoutine ID: " + Utility::formatHexNum(routineID));
}
- if (msg.data.length() > 3)
+ if (dataLen > 3)
{
buildString.append("\nBytes returned by routine: ");
- for (int i = 4; i < msg.data.length(); i++)
+ for (int i = 4; i < dataLen; i++)
{
- buildString.append(Utility::formatHexNum(msg.data[i]) + " ");
+ buildString.append(Utility::formatHexNum(data[i]) + " ");
}
}
break;
diff --git a/bus_protocols/uds_handler.h b/bus_protocols/uds_handler.h
index b17af69..5c5ea4f 100644
--- a/bus_protocols/uds_handler.h
+++ b/bus_protocols/uds_handler.h
@@ -65,7 +65,7 @@ namespace UDS_SERVICES
struct CODE_STRUCT
{
- unsigned int code;
+ int code;
QString shortDesc;
QString longDesc;
};
@@ -73,9 +73,9 @@ struct CODE_STRUCT
class UDS_MESSAGE: public ISOTP_MESSAGE
{
public:
- unsigned int service;
- unsigned int subFunc;
- unsigned int subFuncLen;
+ int service;
+ int subFunc;
+ int subFuncLen;
bool isErrorReply;
UDS_MESSAGE();
diff --git a/can_structs.h b/can_structs.h
index df976f5..6b8cdee 100644
--- a/can_structs.h
+++ b/can_structs.h
@@ -4,35 +4,32 @@
#include
#include
#include
+#include
-struct CANFrame
+//Now inherits from the built-in CAN frame class from Qt. This should be more future proof and easier to integrate with other code
+
+struct CANFrame : public QCanBusFrame
{
public:
- uint32_t ID;
- uint32_t bus;
- bool extended;
- bool remote;
+ int bus;
bool isReceived; //did we receive this or send it?
- uint32_t len;
- unsigned char data[8];
- uint64_t timestamp;
uint64_t timedelta;
uint32_t frameCount; //used in overwrite mode
friend bool operator<(const CANFrame& l, const CANFrame& r)
{
- return l.timestamp < r.timestamp;
+ qint64 lStamp = l.timeStamp().seconds() * 1000000 + l.timeStamp().microSeconds();
+ qint64 rStamp = r.timeStamp().seconds() * 1000000 + r.timeStamp().microSeconds();
+ return lStamp < rStamp;
}
CANFrame()
{
- ID = 0;
+ setFrameId(0);
bus = 0;
- extended = false;
- remote = false;
+ setExtendedFrameFormat(false);
+ setFrameType(QCanBusFrame::DataFrame);
isReceived = true;
- len = 0;
- timestamp = 0;
timedelta = 0;
frameCount = 1;
}
diff --git a/canframemodel.cpp b/canframemodel.cpp
index 79f557c..167f822 100644
--- a/canframemodel.cpp
+++ b/canframemodel.cpp
@@ -102,7 +102,7 @@ void CANFrameModel::setSysTimeMode(bool mode)
}
}
-void CANFrameModel::setInterpetMode(bool mode)
+void CANFrameModel::setInterpretMode(bool mode)
{
//if the state of interpretFrames changes then we need to reset the model
//so that QT will refresh the view properly
@@ -114,6 +114,11 @@ void CANFrameModel::setInterpetMode(bool mode)
}
}
+bool CANFrameModel::getInterpretMode()
+{
+ return interpretFrames;
+}
+
void CANFrameModel::setTimeFormat(QString format)
{
Utility::timeFormat = format;
@@ -128,23 +133,23 @@ void CANFrameModel::normalizeTiming()
{
mutex.lock();
if (frames.count() == 0) return;
- timeOffset = frames[0].timestamp;
+ timeOffset = frames[0].timeStamp().microSeconds();
//find the absolute lowest timestamp in the whole time. Needed because maybe timestamp was reset in the middle.
for (int j = 0; j < frames.count(); j++)
{
- if (frames[j].timestamp < timeOffset) timeOffset = frames[j].timestamp;
+ if (frames[j].timeStamp().microSeconds() < timeOffset) timeOffset = frames[j].timeStamp().microSeconds();
}
for (int i = 0; i < frames.count(); i++)
{
- frames[i].timestamp -= timeOffset;
+ frames[i].setTimeStamp(QCanBusFrame::TimeStamp(0, frames[i].timeStamp().microSeconds() - timeOffset));
}
this->beginResetModel();
for (int i = 0; i < filteredFrames.count(); i++)
{
- filteredFrames[i].timestamp -= timeOffset;
+ filteredFrames[i].setTimeStamp(QCanBusFrame::TimeStamp(0, filteredFrames[i].timeStamp().microSeconds() - timeOffset));
}
this->endResetModel();
@@ -190,29 +195,32 @@ uint64_t CANFrameModel::getCANFrameVal(int row, Column col)
{
case Column::TimeStamp:
if (overwriteDups) return frame.timedelta;
- return frame.timestamp;
+ return frame.timeStamp().microSeconds();
case Column::FrameId:
- return frame.ID;
+ return frame.frameId();
case Column::Extended:
- if (frame.extended) return 1;
+ if (frame.hasExtendedFrameFormat()) return 1;
return 0;
case Column::Remote:
if (overwriteDups) return frame.frameCount;
- if (frame.remote) return 1;
+ if (frame.frameType() == QCanBusFrame::RemoteRequestFrame) return 1;
return 0;
case Column::Direction:
if (frame.isReceived) return 1;
return 0;
case Column::Bus:
- return frame.bus;
+ return static_cast(frame.bus);
case Column::Length:
- return frame.len;
+ return static_cast(frame.payload().length());
case Column::ASCII: //sort both the same for now
case Column::Data:
- for (int i = 0; i < frame.len; i++) temp += ((uint64_t)frame.data[i] << (56 - (8 * i)));
+ for (int i = 0; i < frame.payload().length(); i++) temp += (static_cast(frame.payload()[i]) << (56 - (8 * i)));
//qDebug() << temp;
return temp;
+ case Column::NUM_COLUMN:
+ return 0;
}
+ return 0;
}
void CANFrameModel::qSortCANFrameAsc(QVector *frames, Column column, int lowerBound, int upperBound)
@@ -295,9 +303,6 @@ void CANFrameModel::recalcOverwrite()
qDebug() << "recalcOverwrite called in model";
- int lastUnique = 0;
- bool found;
-
mutex.lock();
beginResetModel();
@@ -306,7 +311,7 @@ void CANFrameModel::recalcOverwrite()
uint64_t idAugmented; //id in lower 29 bits, bus number shifted up 29 bits
foreach(CANFrame frame, frames)
{
- idAugmented = frame.ID;
+ idAugmented = frame.frameId();
idAugmented = idAugmented + (frame.bus << 29ull);
if (!overWriteFrames.contains(idAugmented))
{
@@ -316,7 +321,7 @@ void CANFrameModel::recalcOverwrite()
}
else
{
- frame.timedelta = frame.timestamp - overWriteFrames[idAugmented].timestamp;
+ frame.timedelta = frame.timeStamp().microSeconds() - overWriteFrames[idAugmented].timeStamp().microSeconds();
frame.frameCount = overWriteFrames[idAugmented].frameCount + 1;
overWriteFrames[idAugmented] = frame;
}
@@ -330,7 +335,7 @@ void CANFrameModel::recalcOverwrite()
for (int i = 0; i < frames.count(); i++)
{
- if (filters[frames[i].ID])
+ if (filters[frames[i].frameId()])
{
filteredFrames.append(frames[i]);
}
@@ -342,7 +347,6 @@ void CANFrameModel::recalcOverwrite()
QVariant CANFrameModel::data(const QModelIndex &index, int role) const
{
- int dLen;
QString tempString;
CANFrame thisFrame;
static bool rowFlip = false;
@@ -356,12 +360,15 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
thisFrame = filteredFrames.at(index.row());
+ unsigned char *data = reinterpret_cast(thisFrame.payload().data());
+ int dataLen = thisFrame.payload().count();
+
if (role == Qt::BackgroundColorRole)
{
- if (dbcHandler != NULL && interpretFrames)
+ if (dbcHandler != nullptr && interpretFrames)
{
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
- if (msg != NULL)
+ if (msg != nullptr)
{
return msg->bgColor;
}
@@ -378,10 +385,10 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
if (role == Qt::TextColorRole)
{
- if (dbcHandler != NULL && interpretFrames)
+ if (dbcHandler != nullptr && interpretFrames)
{
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
- if (msg != NULL)
+ if (msg != nullptr)
{
return msg->fgColor;
}
@@ -399,17 +406,17 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
if (timeSeconds) return QString::number(thisFrame.timedelta / 1000000.0, 'f', 5);
return QString::number(thisFrame.timedelta);
}
- else ts = Utility::formatTimestamp(thisFrame.timestamp);
+ else ts = Utility::formatTimestamp(thisFrame.timeStamp().microSeconds());
if (ts.type() == QVariant::Double) return QString::number(ts.toDouble(), 'f', 5); //never scientific notation, 5 decimal places
if (ts.type() == QVariant::LongLong) return QString::number(ts.toLongLong()); //never scientific notion, all digits shown
if (ts.type() == QVariant::DateTime) return ts.toDateTime().toString(timeFormat); //custom set format for dates and times
- return Utility::formatTimestamp(thisFrame.timestamp);
+ return Utility::formatTimestamp(thisFrame.timeStamp().microSeconds());
case Column::FrameId:
- return Utility::formatCANID(thisFrame.ID, thisFrame.extended);
+ return Utility::formatCANID(thisFrame.frameId(), thisFrame.hasExtendedFrameFormat());
case Column::Extended:
- return QString::number(thisFrame.extended);
+ return QString::number(thisFrame.hasExtendedFrameFormat());
case Column::Remote:
- if (!overwriteDups) return QString::number(thisFrame.remote);
+ if (!overwriteDups) return QString::number(thisFrame.frameType() == QCanBusFrame::RemoteRequestFrame);
return QString::number(thisFrame.frameCount);
case Column::Direction:
if (thisFrame.isReceived) return QString(tr("Rx"));
@@ -417,47 +424,44 @@ QVariant CANFrameModel::data(const QModelIndex &index, int role) const
case Column::Bus:
return QString::number(thisFrame.bus);
case Column::Length:
- return QString::number(thisFrame.len);
+ return QString::number(dataLen);
case Column::ASCII:
- if (thisFrame.ID >= 0x7FFFFFF0ull)
+ if (thisFrame.frameId() >= 0x7FFFFFF0ull)
{
tempString.append("MARK ");
- tempString.append(QString::number(thisFrame.ID & 0x7));
+ tempString.append(QString::number(thisFrame.frameId() & 0x7));
return tempString;
}
- dLen = thisFrame.len;
- if (!thisFrame.remote) {
- if (dLen < 0) dLen = 0;
- if (dLen > 8) dLen = 8;
- for (int i = 0; i < dLen; i++)
+ if (thisFrame.frameType() != QCanBusFrame::RemoteRequestFrame) {
+ if (dataLen < 0) dataLen = 0;
+ //if (dLen > 8) dLen = 8;
+ for (int i = 0; i < dataLen; i++)
{
- quint8 byt = thisFrame.data[i];
+ char byt = thisFrame.payload()[i];
//0x20 through 0x7E are printable characters. Outside of that range they aren't. So use dots instead
if (byt < 0x20) byt = 0x2E; //dot character
if (byt > 0x7E) byt = 0x2E;
- tempString.append(QString::fromUtf8((char *)&byt, 1));
+ tempString.append(QString::fromUtf8(&byt, 1));
}
}
return tempString;
case Column::Data:
- dLen = thisFrame.len;
- if (dLen < 0) dLen = 0;
- if (dLen > 8) dLen = 8;
+ if (dataLen < 0) dataLen = 0;
//if (useHexMode) tempString.append("0x ");
- if (thisFrame.remote) {
+ if (thisFrame.frameType() == QCanBusFrame::RemoteRequestFrame) {
return tempString;
}
- for (int i = 0; i < dLen; i++)
+ for (int i = 0; i < dataLen; i++)
{
- if (useHexMode) tempString.append( QString::number(thisFrame.data[i], 16).toUpper().rightJustified(2, '0'));
- else tempString.append(QString::number(thisFrame.data[i], 10));
+ if (useHexMode) tempString.append( QString::number(data[i], 16).toUpper().rightJustified(2, '0'));
+ else tempString.append(QString::number(data[i], 10));
tempString.append(" ");
}
//now, if we're supposed to interpret the data and the DBC handler is loaded then use it
- if (dbcHandler != NULL && interpretFrames)
+ if (dbcHandler != nullptr && interpretFrames)
{
DBC_MESSAGE *msg = dbcHandler->findMessage(thisFrame);
- if (msg != NULL)
+ if (msg != nullptr)
{
tempString.append(" \n");
tempString.append(msg->name + "\n" + msg->comment + "\n");
@@ -547,25 +551,25 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
mutex.lock();
CANFrame tempFrame;
tempFrame = frame;
- tempFrame.timestamp -= timeOffset;
+ tempFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, tempFrame.timeStamp().microSeconds() - timeOffset));
lastUpdateNumFrames++;
//if this ID isn't found in the filters list then add it and show it by default
- if (!filters.contains(tempFrame.ID))
+ if (!filters.contains(tempFrame.frameId()))
{
// if there are any filters already configured, leave the new filter disabled
if (any_filters_are_configured())
- filters.insert(tempFrame.ID, false);
+ filters.insert(tempFrame.frameId(), false);
else
- filters.insert(tempFrame.ID, true);
+ filters.insert(tempFrame.frameId(), true);
needFilterRefresh = true;
}
if (!overwriteDups)
{
frames.append(tempFrame);
- if (filters[tempFrame.ID])
+ if (filters[tempFrame.frameId()])
{
if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count());
tempFrame.frameCount = 1;
@@ -578,10 +582,10 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
bool found = false;
for (int i = 0; i < frames.count(); i++)
{
- if ( (frames[i].ID == tempFrame.ID) && (frames[i].bus == tempFrame.bus) )
+ if ( (frames[i].frameId() == tempFrame.frameId()) && (frames[i].bus == tempFrame.bus) )
{
tempFrame.frameCount = frames[i].frameCount + 1;
- tempFrame.timedelta = tempFrame.timestamp - frames[i].timestamp;
+ tempFrame.timedelta = tempFrame.timeStamp().microSeconds() - frames[i].timeStamp().microSeconds();
frames.replace(i, tempFrame);
found = true;
break;
@@ -590,7 +594,7 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
if (!found)
{
frames.append(tempFrame);
- if (filters[tempFrame.ID])
+ if (filters[tempFrame.frameId()])
{
if (autoRefresh) beginInsertRows(QModelIndex(), filteredFrames.count(), filteredFrames.count());
tempFrame.frameCount = 1;
@@ -603,7 +607,7 @@ void CANFrameModel::addFrame(const CANFrame& frame, bool autoRefresh = false)
{
for (int j = 0; j < filteredFrames.count(); j++)
{
- if ( (filteredFrames[j].ID == tempFrame.ID) && (filteredFrames[j].bus == tempFrame.bus) )
+ if ( (filteredFrames[j].frameId() == tempFrame.frameId()) && (filteredFrames[j].bus == tempFrame.bus) )
{
if (autoRefresh) beginResetModel();
filteredFrames.replace(j, tempFrame);
@@ -637,7 +641,7 @@ void CANFrameModel::sendRefresh()
int count = frames.count();
for (int i = 0; i < count; i++)
{
- if (filters[frames[i].ID])
+ if (filters[frames[i].frameId()])
{
tempContainer.append(frames[i]);
}
@@ -713,12 +717,12 @@ void CANFrameModel::insertFrames(const QVector &newFrames)
for (int i = 0; i < newFrames.count(); i++)
{
frames.append(newFrames[i]);
- if (!filters.contains(newFrames[i].ID))
+ if (!filters.contains(newFrames[i].frameId()))
{
- filters.insert(newFrames[i].ID, true);
+ filters.insert(newFrames[i].frameId(), true);
needFilterRefresh = true;
}
- if (filters[newFrames[i].ID])
+ if (filters[newFrames[i].frameId()])
{
insertedFiltered++;
filteredFrames.append(newFrames[i]);
@@ -735,12 +739,12 @@ void CANFrameModel::insertFrames(const QVector &newFrames)
int CANFrameModel::getIndexFromTimeID(unsigned int ID, double timestamp)
{
int bestIndex = -1;
- uint64_t intTimeStamp = timestamp * 1000000l;
+ int64_t intTimeStamp = static_cast (timestamp * 1000000l);
for (int i = 0; i < frames.count(); i++)
{
- if ((frames[i].ID == ID))
+ if ((frames[i].frameId() == ID))
{
- if (frames[i].timestamp <= intTimeStamp) bestIndex = i;
+ if (frames[i].timeStamp().microSeconds() <= intTimeStamp) bestIndex = i;
else break; //drop out of loop as soon as we pass the proper timestamp
}
}
@@ -763,7 +767,7 @@ void CANFrameModel::loadFilterFile(QString filename)
if (line.length() > 2)
{
QList tokens = line.split(',');
- ID = tokens[0].toInt(NULL, 16);
+ ID = tokens[0].toInt(nullptr, 16);
if (tokens[1].toUpper() == "T") filters.insert(ID, true);
else filters.insert(ID, false);
}
diff --git a/canframemodel.h b/canframemodel.h
index 011bf8f..51762a1 100644
--- a/canframemodel.h
+++ b/canframemodel.h
@@ -42,7 +42,8 @@ public:
void sendRefresh(int);
int sendBulkRefresh();
void clearFrames();
- void setInterpetMode(bool);
+ void setInterpretMode(bool);
+ bool getInterpretMode();
void setOverwriteMode(bool);
void setHexMode(bool);
void setSysTimeMode(bool);
@@ -87,7 +88,7 @@ private:
bool timeSeconds;
bool useSystemTime;
bool needFilterRefresh;
- uint64_t timeOffset;
+ int64_t timeOffset;
int lastUpdateNumFrames;
uint32_t preallocSize;
bool sortDirAsc;
diff --git a/connections/canconfactory.cpp b/connections/canconfactory.cpp
index d40dd98..d506524 100644
--- a/connections/canconfactory.cpp
+++ b/connections/canconfactory.cpp
@@ -17,5 +17,5 @@ CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDri
default: {}
}
- return NULL;
+ return nullptr;
}
diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp
index 6e5020d..9ae1f11 100644
--- a/connections/canconmanager.cpp
+++ b/connections/canconmanager.cpp
@@ -4,7 +4,7 @@
#include "canconmanager.h"
#include "canconfactory.h"
-CANConManager* CANConManager::mInstance = NULL;
+CANConManager* CANConManager::mInstance = nullptr;
CANConManager* CANConManager::getInstance()
{
@@ -43,7 +43,7 @@ void CANConManager::resetTimeBasis()
CANConManager::~CANConManager()
{
mTimer.stop();
- mInstance = NULL;
+ mInstance = nullptr;
}
void CANConManager::stopAllConnections()
@@ -142,7 +142,7 @@ CANConnection* CANConManager::getByName(const QString& pName) const
return conn_p;
}
- return NULL;
+ return nullptr;
}
@@ -159,9 +159,9 @@ void CANConManager::refreshConnection(CANConnection* pConn_p)
emit connectionStatusUpdated(buses);
}
- if (pConn_p->getQueue().peek() == NULL) return;
+ if (pConn_p->getQueue().peek() == nullptr) return;
- CANFrame* frame_p = NULL;
+ CANFrame* frame_p = nullptr;
QVector frames;
//Each connection only knows about its own bus numbers
@@ -220,11 +220,11 @@ bool CANConManager::sendFrame(const CANFrame& pFrame)
workingFrame.isReceived = false;
if (useSystemTime)
{
- workingFrame.timestamp = (QDateTime::currentMSecsSinceEpoch() * 1000);
+ workingFrame.setTimeStamp(QCanBusFrame::TimeStamp(0,QDateTime::currentMSecsSinceEpoch() * 1000));
}
else
{
- workingFrame.timestamp = mElapsedTimer.nsecsElapsed() / 1000;
+ workingFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, mElapsedTimer.nsecsElapsed() / 1000));
//workingFrame.timestamp -= mTimestampBasis;
}
txFrame = conn->getQueue().get();
@@ -253,13 +253,13 @@ bool CANConManager::sendFrames(const QList& pFrames)
//the bus numbers if bus wasn't -1 so that they're local to the device
bool CANConManager::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
- int tempBusVal;
+ //int tempBusVal;
int busBase = 0;
foreach (CANConnection* conn, mConns)
{
if (pBusId == -1) conn->addTargettedFrame(pBusId, ID, mask, receiver);
- else if (pBusId < (uint32_t)(busBase + conn->getNumBuses()))
+ else if (pBusId < (busBase + conn->getNumBuses()))
{
qDebug() << "Forwarding targetted frame setting to a connection object";
conn->addTargettedFrame(pBusId - busBase, ID, mask, receiver);
@@ -272,13 +272,13 @@ bool CANConManager::addTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QO
bool CANConManager::removeTargettedFrame(int pBusId, uint32_t ID, uint32_t mask, QObject *receiver)
{
- int tempBusVal;
+ //int tempBusVal;
int busBase = 0;
foreach (CANConnection* conn, mConns)
{
if (pBusId == -1) conn->removeTargettedFrame(pBusId, ID, mask, receiver);
- else if (pBusId < (uint32_t)(busBase + conn->getNumBuses()))
+ else if (pBusId < (busBase + conn->getNumBuses()))
{
qDebug() << "Forwarding targetted frame setting to a connection object";
conn->removeTargettedFrame(pBusId - busBase, ID, mask, receiver);
diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp
index 6a41758..27850ff 100644
--- a/connections/canconnection.cpp
+++ b/connections/canconnection.cpp
@@ -16,7 +16,7 @@ CANConnection::CANConnection(QString pPort,
mIsCapSuspended(false),
mStatus(CANCon::NOT_CONNECTED),
mStarted(false),
- mThread_p(NULL)
+ mThread_p(nullptr)
{
/* register types */
qRegisterMetaType("CANBus");
@@ -48,7 +48,7 @@ CANConnection::~CANConnection()
mThread_p->quit();
mThread_p->wait();
delete mThread_p;
- mThread_p = NULL;
+ mThread_p = nullptr;
}
mBusData.clear();
@@ -343,7 +343,7 @@ void CANConnection::checkTargettedFrame(CANFrame &frame)
foreach (const CANFltObserver filt, mBusData[frame.bus].mTargettedFrames)
{
//qDebug() << "Checking filter with id " << filt.id << " mask " << filt.mask;
- maskedID = frame.ID & filt.mask;
+ maskedID = frame.frameId() & filt.mask;
if (maskedID == filt.id) {
qDebug() << "In connection object I got a targetted frame. Forwarding it.";
QMetaObject::invokeMethod(filt.observer, "gotTargettedFrame",Qt::QueuedConnection, Q_ARG(CANFrame, frame));
diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp
index 6c68564..35a0c1e 100644
--- a/connections/canconnectionmodel.cpp
+++ b/connections/canconnectionmodel.cpp
@@ -70,10 +70,10 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const
//qDebug() << "Row: " << index.row();
CANConnection *conn_p = getAtIdx(index.row());
- bool ret;
+
if (!conn_p) return QVariant();
- bool isSocketCAN = (conn_p->getType() == CANCon::SERIALBUS) ? true: false;
+ //bool isSocketCAN = (conn_p->getType() == CANCon::SERIALBUS) ? true: false;
if (role == Qt::DisplayRole) {
@@ -87,11 +87,11 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const
case CANCon::GVRET_SERIAL: return "GVRET";
default: {}
}
- else qDebug() << "Tried to show connection type but connection was NULL";
+ else qDebug() << "Tried to show connection type but connection was nullptr";
break;
case Column::Port:
if (conn_p) return conn_p->getPort();
- else qDebug() << "Tried to show connection port but connection was NULL";
+ else qDebug() << "Tried to show connection port but connection was nullptr";
break;
case Column::Subtype:
return conn_p->getDriver();
@@ -138,7 +138,7 @@ void CANConnectionModel::replace(int idx , CANConnection* pConn_p)
CANConnection* CANConnectionModel::getAtIdx(int pIdx) const
{
if (pIdx < 0)
- return NULL;
+ return nullptr;
QList& conns = CANConManager::getInstance()->getConnections();
@@ -147,6 +147,8 @@ CANConnection* CANConnectionModel::getAtIdx(int pIdx) const
void CANConnectionModel::refresh(int pIndex)
{
+ Q_UNUSED(pIndex)
+
beginResetModel();
endResetModel();
/*
diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp
index 56dff96..3a5fabf 100644
--- a/connections/connectionwindow.cpp
+++ b/connections/connectionwindow.cpp
@@ -312,8 +312,8 @@ void ConnectionWindow::populateBusDetails(int offset)
}
else
{
- bool ret;
- int numBuses;
+ //bool ret;
+ //int numBuses;
CANConnection* conn_p = connModel->getAtIdx(selIdx);
CANBus bus;
@@ -365,7 +365,7 @@ void ConnectionWindow::currentRowChanged(const QModelIndex ¤t, const QMode
}
else
{
- bool ret;
+ //bool ret;
ui->groupBus->setEnabled(true);
int numBuses;
diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp
index 0d42518..d84a875 100644
--- a/connections/gvretserial.cpp
+++ b/connections/gvretserial.cpp
@@ -15,9 +15,9 @@ GVRetSerial::GVRetSerial(QString portName, bool useTcp) :
{
sendDebug("GVRetSerial()");
- serial = NULL;
- tcpClient = NULL;
- udpClient = NULL;
+ serial = nullptr;
+ tcpClient = nullptr;
+ udpClient = nullptr;
rx_state = IDLE;
rx_step = 0;
validationCounter = 10; //how many times we can miss validation before we die
@@ -46,7 +46,7 @@ void GVRetSerial::sendDebug(const QString debugText)
void GVRetSerial::sendToSerial(const QByteArray &bytes)
{
- if (serial == NULL && tcpClient == NULL && udpClient == NULL)
+ if (serial == nullptr && tcpClient == nullptr && udpClient == nullptr)
{
sendDebug("Attempt to write to serial port when it has not been initialized!");
return;
@@ -192,14 +192,14 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
sendDebug("Got signal to update bauds. 1: " + QString::number((can0Baud & 0xFFFFFFF)) + " 2: " + QString::number((can1Baud & 0xFFFFFFF)));
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 5; //setup canbus
- buffer[2] = (unsigned char)(can0Baud & 0xFF); //four bytes of ID LSB first
- buffer[3] = (unsigned char)(can0Baud >> 8);
- buffer[4] = (unsigned char)(can0Baud >> 16);
- buffer[5] = (unsigned char)(can0Baud >> 24);
- buffer[6] = (unsigned char)(can1Baud & 0xFF); //four bytes of ID LSB first
- buffer[7] = (unsigned char)(can1Baud >> 8);
- buffer[8] = (unsigned char)(can1Baud >> 16);
- buffer[9] = (unsigned char)(can1Baud >> 24);
+ buffer[2] = (char)(can0Baud & 0xFF); //four bytes of ID LSB first
+ buffer[3] = (char)(can0Baud >> 8);
+ buffer[4] = (char)(can0Baud >> 16);
+ buffer[5] = (char)(can0Baud >> 24);
+ buffer[6] = (char)(can1Baud & 0xFF); //four bytes of ID LSB first
+ buffer[7] = (char)(can1Baud >> 8);
+ buffer[8] = (char)(can1Baud >> 16);
+ buffer[9] = (char)(can1Baud >> 24);
buffer[10] = 0;
sendToSerial(buffer);
}
@@ -210,18 +210,18 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
sendDebug("Got signal to update extended bus speeds SWCAN: " + QString::number(swcanBaud) + " LIN1: " + QString::number(lin1Baud) + " LIN2: " + QString::number(lin2Baud));
buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 14; //setup extended buses
- buffer[2] = (unsigned char)(swcanBaud & 0xFF); //four bytes of ID LSB first
- buffer[3] = (unsigned char)(swcanBaud >> 8);
- buffer[4] = (unsigned char)(swcanBaud >> 16);
- buffer[5] = (unsigned char)(swcanBaud >> 24);
- buffer[6] = (unsigned char)(lin1Baud & 0xFF); //four bytes of ID LSB first
- buffer[7] = (unsigned char)(lin1Baud >> 8);
- buffer[8] = (unsigned char)(lin1Baud >> 16);
- buffer[9] = (unsigned char)(lin1Baud >> 24);
- buffer[10] = (unsigned char)(lin2Baud & 0xFF); //four bytes of ID LSB first
- buffer[11] = (unsigned char)(lin2Baud >> 8);
- buffer[12] = (unsigned char)(lin2Baud >> 16);
- buffer[13] = (unsigned char)(lin2Baud >> 24);
+ buffer[2] = (char)(swcanBaud & 0xFF); //four bytes of ID LSB first
+ buffer[3] = (char)(swcanBaud >> 8);
+ buffer[4] = (char)(swcanBaud >> 16);
+ buffer[5] = (char)(swcanBaud >> 24);
+ buffer[6] = (char)(lin1Baud & 0xFF); //four bytes of ID LSB first
+ buffer[7] = (char)(lin1Baud >> 8);
+ buffer[8] = (char)(lin1Baud >> 16);
+ buffer[9] = (char)(lin1Baud >> 24);
+ buffer[10] = (char)(lin2Baud & 0xFF); //four bytes of ID LSB first
+ buffer[11] = (char)(lin2Baud >> 8);
+ buffer[12] = (char)(lin2Baud >> 16);
+ buffer[13] = (char)(lin2Baud >> 24);
buffer[14] = 0;
sendToSerial(buffer);
}
@@ -231,14 +231,14 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus)
bool GVRetSerial::piSendFrame(const CANFrame& frame)
{
QByteArray buffer;
- unsigned int c;
- int ID;
+ int c;
+ quint32 ID;
//qDebug() << "Sending out GVRET frame with id " << frame.ID << " on bus " << frame.bus;
framesRapid++;
- if (serial == NULL && tcpClient == NULL && udpClient == NULL) return false;
+ if (serial == nullptr && tcpClient == nullptr && udpClient == nullptr) return false;
if (serial && !serial->isOpen()) return false;
if (tcpClient && !tcpClient->isOpen()) return false;
if (udpClient && !udpClient->isOpen()) return false;
@@ -246,25 +246,25 @@ bool GVRetSerial::piSendFrame(const CANFrame& frame)
// Doesn't make sense to send an error frame
// to an adapter
- if (frame.ID & 0x20000000) {
+ if (frame.frameId() & 0x20000000) {
return true;
}
- ID = frame.ID;
- if (frame.extended) ID |= 1 << 31;
+ ID = frame.frameId();
+ if (frame.hasExtendedFrameFormat()) ID |= 1u << 31;
- buffer[0] = (unsigned char)0xF1; //start of a command over serial
+ buffer[0] = (char)0xF1; //start of a command over serial
buffer[1] = 0; //command ID for sending a CANBUS frame
- buffer[2] = (unsigned char)(ID & 0xFF); //four bytes of ID LSB first
- buffer[3] = (unsigned char)(ID >> 8);
- buffer[4] = (unsigned char)(ID >> 16);
- buffer[5] = (unsigned char)(ID >> 24);
- buffer[6] = (unsigned char)((frame.bus) & 3);
- buffer[7] = (unsigned char)frame.len;
- for (c = 0; c < frame.len; c++)
+ buffer[2] = (char)(ID & 0xFF); //four bytes of ID LSB first
+ buffer[3] = (char)(ID >> 8);
+ buffer[4] = (char)(ID >> 16);
+ buffer[5] = (char)(ID >> 24);
+ buffer[6] = (char)((frame.bus) & 3);
+ buffer[7] = (char)frame.payload().length();
+ for (c = 0; c < frame.payload().length(); c++)
{
- buffer[8 + c] = frame.data[c];
+ buffer[8 + c] = frame.payload()[c];
}
- buffer[8 + frame.len] = 0;
+ buffer[8 + frame.payload().length()] = 0;
sendToSerial(buffer);
@@ -375,18 +375,18 @@ void GVRetSerial::deviceConnected()
{
sendDebug("Connecting to GVRET Device!");
QByteArray output;
- output.append((unsigned char)0xE7); //this puts the device into binary comm mode
- output.append((unsigned char)0xE7);
+ output.append((char)0xE7); //this puts the device into binary comm mode
+ output.append((char)0xE7);
- output.append((unsigned char)0xF1);
- output.append((unsigned char)0x0C); //get number of actually implemented buses. Not implemented except on M2RET
+ output.append((char)0xF1);
+ output.append((char)0x0C); //get number of actually implemented buses. Not implemented except on M2RET
mNumBuses = 2; //the proper number if C/12 is not implemented
- output.append((unsigned char)0xF1); //signal we want to issue a command
- output.append((unsigned char)0x06); //request canbus stats from the board
+ output.append((char)0xF1); //signal we want to issue a command
+ output.append((char)0x06); //request canbus stats from the board
- output.append((unsigned char)0xF1); //another command to the GVRET
- output.append((unsigned char)0x07); //request device information
+ output.append((char)0xF1); //another command to the GVRET
+ output.append((char)0x07); //request device information
/*output.append((char)0xF1);
output.append((char)0x08); //setting singlewire mode
@@ -399,11 +399,11 @@ void GVRetSerial::deviceConnected()
output.append((char)0xFF); //signal we don't want single wire mode
}*/
- output.append((unsigned char)0xF1); //and another command
- output.append((unsigned char)0x01); //Time Sync - Not implemented until 333 but we can try
+ output.append((char)0xF1); //and another command
+ output.append((char)0x01); //Time Sync - Not implemented until 333 but we can try
- output.append((unsigned char)0xF1); //yet another command
- output.append((unsigned char)0x09); //comm validation command
+ output.append((char)0xF1); //yet another command
+ output.append((char)0x09); //comm validation command
continuousTimeSync = true;
@@ -422,7 +422,7 @@ void GVRetSerial::deviceConnected()
}
void GVRetSerial::disconnectDevice() {
- if (serial != NULL)
+ if (serial != nullptr)
{
if (serial->isOpen())
{
@@ -432,9 +432,9 @@ void GVRetSerial::disconnectDevice() {
}
serial->disconnect(); //disconnect all signals
delete serial;
- serial = NULL;
+ serial = nullptr;
}
- if (tcpClient != NULL)
+ if (tcpClient != nullptr)
{
if (tcpClient->isOpen())
{
@@ -442,9 +442,9 @@ void GVRetSerial::disconnectDevice() {
}
tcpClient->disconnect();
delete tcpClient;
- tcpClient = NULL;
+ tcpClient = nullptr;
}
- if (udpClient != NULL)
+ if (udpClient != nullptr)
{
if (udpClient->isOpen())
{
@@ -452,7 +452,7 @@ void GVRetSerial::disconnectDevice() {
}
udpClient->disconnect();
delete udpClient;
- udpClient = NULL;
+ udpClient = nullptr;
}
setStatus(CANCon::NOT_CONNECTED);
@@ -659,57 +659,59 @@ void GVRetSerial::procRXChar(unsigned char c)
switch (rx_step)
{
case 0:
- buildFrame.timestamp = c;
+ buildTimestamp = c;
break;
case 1:
- buildFrame.timestamp |= (uint)(c << 8);
+ buildTimestamp |= (uint)(c << 8);
break;
case 2:
- buildFrame.timestamp |= (uint)c << 16;
+ buildTimestamp |= (uint)c << 16;
break;
case 3:
- buildFrame.timestamp |= (uint)c << 24;
+ buildTimestamp |= (uint)c << 24;
- buildFrame.timestamp += timeBasis;
+ buildTimestamp += timeBasis;
if (useSystemTime)
{
- buildFrame.timestamp = QDateTime::currentMSecsSinceEpoch() * 1000l;
+ buildTimestamp = QDateTime::currentMSecsSinceEpoch() * 1000l;
}
+ buildFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, buildTimestamp));
break;
case 4:
- buildFrame.ID = c;
+ buildId = c;
break;
case 5:
- buildFrame.ID |= c << 8;
+ buildId |= c << 8;
break;
case 6:
- buildFrame.ID |= c << 16;
+ buildId |= c << 16;
break;
case 7:
- buildFrame.ID |= c << 24;
- if ((buildFrame.ID & 1 << 31) == 1u << 31)
+ buildId |= c << 24;
+ if ((buildId & 1 << 31) == 1u << 31)
{
- buildFrame.ID &= 0x7FFFFFFF;
- buildFrame.extended = true;
+ buildId &= 0x7FFFFFFF;
+ buildFrame.setExtendedFrameFormat(true);
}
- else buildFrame.extended = false;
+ else buildFrame.setExtendedFrameFormat(false);
+ buildFrame.setFrameId(buildId);
break;
case 8:
- buildFrame.len = c & 0xF;
- if (buildFrame.len > 8) buildFrame.len = 8;
+ buildData.resize(c & 0xF);
buildFrame.bus = (c & 0xF0) >> 4;
break;
default:
- if (rx_step < buildFrame.len + 9)
+ if (rx_step < buildData.length() + 9)
{
- buildFrame.data[rx_step - 9] = c;
+ buildData[rx_step - 9] = c;
}
else
{
rx_state = IDLE;
rx_step = 0;
buildFrame.isReceived = true;
-
+ buildFrame.setPayload(buildData);
+ buildFrame.setFrameType(QCanBusFrame::FrameType::DataFrame);
if (!isCapSuspended())
{
/* get frame from queue */
@@ -717,8 +719,7 @@ void GVRetSerial::procRXChar(unsigned char c)
if(frame_p) {
//qDebug() << "GVRET got frame on bus " << frame_p->bus;
/* copy frame */
- *frame_p = buildFrame;
- frame_p->remote = false;
+ *frame_p = buildFrame;
checkTargettedFrame(buildFrame);
/* enqueue frame */
getQueue().queue();
@@ -941,6 +942,7 @@ void GVRetSerial::procRXChar(unsigned char c)
break;
case 9:
lin1Baud |= c << 24;
+ break;
case 10:
lin2Enabled = (c & 0xF);
break;
@@ -1004,7 +1006,7 @@ void GVRetSerial::handleTick()
//qDebug() << validationCounter;
if (validationCounter == 0 && doValidation)
{
- if (serial == NULL && tcpClient == NULL) return;
+ if (serial == nullptr && tcpClient == nullptr) return;
if ( (serial && serial->isOpen()) || (tcpClient && tcpClient->isOpen()) || (udpClient && udpClient->isOpen())) //if it's still false we have a problem...
{
sendDebug("Comm validation failed.");
@@ -1018,7 +1020,10 @@ void GVRetSerial::handleTick()
return;
}
}
- else if (doValidation); //qDebug() << "Comm connection validated";
+ else if (doValidation)
+ {
+ //qDebug() << "Comm connection validated";
+ }
}
if (doValidation && serial && serial->isOpen()) sendCommValidation();
if (doValidation && tcpClient && tcpClient->isOpen()) sendCommValidation();
diff --git a/connections/gvretserial.h b/connections/gvretserial.h
index dba664f..3df1350 100644
--- a/connections/gvretserial.h
+++ b/connections/gvretserial.h
@@ -93,6 +93,9 @@ protected:
STATE rx_state;
uint32_t rx_step;
CANFrame buildFrame;
+ qint64 buildTimestamp;
+ quint32 buildId;
+ QByteArray buildData;
int can0Baud, can1Baud, swcanBaud, lin1Baud, lin2Baud;
bool can0Enabled, can1Enabled, swcanEnabled, lin1Enabled, lin2Enabled;
bool can0ListenOnly, can1ListenOnly, swcanListenOnly;
diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp
index 03891ff..72e1e90 100644
--- a/connections/serialbusconnection.cpp
+++ b/connections/serialbusconnection.cpp
@@ -77,7 +77,7 @@ bool SerialBusConnection::piGetBusSettings(int pBusIdx, CANBus& pBus)
void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus)
{
- CANConStatus stats;
+ //CANConStatus stats;
/* sanity checks */
if(0 != pBusIdx)
return;
@@ -115,22 +115,11 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus)
bool SerialBusConnection::piSendFrame(const CANFrame& pFrame)
{
/* sanity checks */
- if(0 != pFrame.bus || pFrame.len>8)
+ if(0 != pFrame.bus /*|| pFrame.len>8*/)
return false;
if (!mDev_p) return false;
- /* fill frame */
- QCanBusFrame frame;
- frame.setExtendedFrameFormat(pFrame.extended);
- frame.setFrameId(pFrame.ID);
- if (pFrame.remote) {
- frame.setFrameType(QCanBusFrame::FrameType::RemoteRequestFrame);
- } else {
- frame.setFrameType(QCanBusFrame::FrameType::DataFrame);
- }
- frame.setPayload(QByteArray(reinterpret_cast(pFrame.data),
- static_cast(pFrame.len)));
- return mDev_p->writeFrame(frame);
+ return mDev_p->writeFrame(pFrame);
}
@@ -193,14 +182,16 @@ void SerialBusConnection::framesReceived()
if (recFrame.payload().length() <= 8) {
CANFrame* frame_p = getQueue().get();
if(frame_p) {
- frame_p->len = static_cast(recFrame.payload().length());
- frame_p->bus = 0;
+ frame_p->setPayload(recFrame.payload());
+ frame_p->bus = 0;
if (recFrame.frameType() == QCanBusFrame::ErrorFrame) {
// Constants defined in include/uapi/linux/can/error.h
+ //since the whole program uses QCanBusFrame now we can just grab errors directly out of the proper place from now on
+ /*
switch (recFrame.error()) {
case QCanBusFrame::TransmissionTimeoutError:
- frame_p->ID = 0x20000001;
+ frame_p->setFrameId(0x20000001);
break;
case QCanBusFrame::LostArbitrationError:
frame_p->ID = 0x20000002;
@@ -230,19 +221,21 @@ void SerialBusConnection::framesReceived()
break;
}
frame_p->extended = true;
+ */
} else {
- frame_p->extended = recFrame.hasExtendedFrameFormat();
- frame_p->ID = recFrame.frameId();
- frame_p->remote = (recFrame.frameType() == recFrame.RemoteRequestFrame);
- memcpy(frame_p->data, recFrame.payload().data(), frame_p->len);
+ frame_p->setExtendedFrameFormat(recFrame.hasExtendedFrameFormat());
+ frame_p->setFrameId(recFrame.frameId());
+ frame_p->setTimeStamp(recFrame.timeStamp());
+ frame_p->setFrameType(recFrame.frameType());
+ frame_p->setError(recFrame.error());
frame_p->isReceived = true;
}
frame_p->isReceived = true;
if (useSystemTime) {
- frame_p->timestamp = QDateTime::currentMSecsSinceEpoch() * 1000ul;
+ frame_p->setTimeStamp(QCanBusFrame::TimeStamp(0, QDateTime::currentMSecsSinceEpoch() * 1000ul));
}
- else frame_p->timestamp = (recFrame.timeStamp().seconds() * 1000000ul + recFrame.timeStamp().microSeconds()) - timeBasis;
+ else frame_p->setTimeStamp(QCanBusFrame::TimeStamp(0, (recFrame.timeStamp().seconds() * 1000000ul + recFrame.timeStamp().microSeconds()) - timeBasis));
checkTargettedFrame(*frame_p);
diff --git a/dbc/dbc_classes.cpp b/dbc/dbc_classes.cpp
index f46b4b7..c0f11ac 100644
--- a/dbc/dbc_classes.cpp
+++ b/dbc/dbc_classes.cpp
@@ -47,7 +47,7 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString, bool o
QString buildString;
int startByte = startBit / 8;
int bytes = signalSize / 8;
- for (int x = 0; x < bytes; x++) buildString.append(frame.data[startByte + x]);
+ for (int x = 0; x < bytes; x++) buildString.append(frame.payload().data()[startByte + x]);
outString = buildString;
cachedValue = outString;
return true;
@@ -56,7 +56,7 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString, bool o
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (isMultiplexed)
{
- if (parentMessage->multiplexorSignal != NULL)
+ if (parentMessage->multiplexorSignal != nullptr)
{
int val;
if (!parentMessage->multiplexorSignal->processAsInt(frame, val)) return false;
@@ -68,7 +68,7 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString, bool o
if (valType == SIGNED_INT) isSigned = true;
if (valType == SIGNED_INT || valType == UNSIGNED_INT)
{
- result = Utility::processIntegerSignal(frame.data, startBit, signalSize, intelByteOrder, isSigned);
+ result = Utility::processIntegerSignal(frame.payload(), startBit, signalSize, intelByteOrder, isSigned);
endResult = ((double)result * factor) + bias;
result = (int64_t)endResult;
}
@@ -79,19 +79,19 @@ bool DBC_SIGNAL::processAsText(const CANFrame &frame, QString &outString, bool o
//that the bytes that make up the integer are instead treated as having made up
//a 32 bit single precision float. That's evil incarnate but it is very fast and small
//in terms of new code.
- result = Utility::processIntegerSignal(frame.data, startBit, 32, false, false);
+ result = Utility::processIntegerSignal(frame.payload(), startBit, 32, intelByteOrder, false);
endResult = (*((float *)(&result)) * factor) + bias;
}
else //double precision float
{
- if ( frame.len < 8 )
+ if ( frame.payload().length() < 8 )
{
result = 0;
return false;
}
//like the above, this is rotten and evil and wrong in so many ways. Force
//calculation of a 64 bit integer and then cast it into a double.
- result = Utility::processIntegerSignal(frame.data, 0, 64, false, false);
+ result = Utility::processIntegerSignal(frame.payload(), 0, 64, intelByteOrder, false);
endResult = (*((double *)(&result)) * factor) + bias;
}
@@ -145,7 +145,7 @@ bool DBC_SIGNAL::processAsInt(const CANFrame &frame, int32_t &outValue)
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (isMultiplexed)
{
- if (parentMessage->multiplexorSignal != NULL)
+ if (parentMessage->multiplexorSignal != nullptr)
{
int val;
if (!parentMessage->multiplexorSignal->processAsInt(frame, val)) return false;
@@ -155,15 +155,16 @@ bool DBC_SIGNAL::processAsInt(const CANFrame &frame, int32_t &outValue)
}
if (valType == SIGNED_INT) isSigned = true;
- if ( frame.len*8 < (startBit+signalSize) )
+ if ( static_cast(frame.payload().length() * 8) < (startBit + signalSize) )
{
result = 0;
return false;
}
- result = Utility::processIntegerSignal(frame.data, startBit, signalSize, intelByteOrder, isSigned);
- double endResult = ((double)result * factor) + bias;
- result = (int32_t)endResult;
+ result = static_cast(Utility::processIntegerSignal(frame.payload(), startBit, signalSize, intelByteOrder, isSigned));
+
+ double endResult = (result * factor) + bias;
+ result = static_cast(endResult);
cachedValue = result;
outValue = result;
return true;
@@ -187,7 +188,7 @@ bool DBC_SIGNAL::processAsDouble(const CANFrame &frame, double &outValue)
//if this is a multiplexed signal then we have to see if it is even found in the current message
if (isMultiplexed)
{
- if (parentMessage->multiplexorSignal != NULL)
+ if (parentMessage->multiplexorSignal != nullptr)
{
int val;
if (!parentMessage->multiplexorSignal->processAsInt(frame, val)) return false;
@@ -199,19 +200,19 @@ bool DBC_SIGNAL::processAsDouble(const CANFrame &frame, double &outValue)
if (valType == SIGNED_INT) isSigned = true;
if (valType == SIGNED_INT || valType == UNSIGNED_INT)
{
- if ( frame.len*8 < (startBit+signalSize) )
+ if ( frame.payload().length() * 8 < (startBit+signalSize) )
{
result = 0;
return false;
}
- result = Utility::processIntegerSignal(frame.data, startBit, signalSize, intelByteOrder, isSigned);
+ result = Utility::processIntegerSignal(frame.payload(), startBit, signalSize, intelByteOrder, isSigned);
endResult = ((double)result * factor) + bias;
result = (int64_t)endResult;
}
/*TODO: It should be noted that the below floating point has not even been tested. For shame! Test it!*/
else if (valType == SP_FLOAT)
{
- if ( frame.len*8 < (startBit+32) )
+ if ( frame.payload().length() * 8 < (startBit + 32) )
{
result = 0;
return false;
@@ -221,19 +222,19 @@ bool DBC_SIGNAL::processAsDouble(const CANFrame &frame, double &outValue)
//that the bytes that make up the integer are instead treated as having made up
//a 32 bit single precision float. That's evil incarnate but it is very fast and small
//in terms of new code.
- result = Utility::processIntegerSignal(frame.data, startBit, 32, false, false);
+ result = Utility::processIntegerSignal(frame.payload(), startBit, 32, false, false);
endResult = (*((float *)(&result)) * factor) + bias;
}
else //double precision float
{
- if ( frame.len < 8 )
+ if ( frame.payload().length() < 8 )
{
result = 0;
return false;
}
//like the above, this is rotten and evil and wrong in so many ways. Force
//calculation of a 64 bit integer and then cast it into a double.
- result = Utility::processIntegerSignal(frame.data, 0, 64, false, false);
+ result = Utility::processIntegerSignal(frame.payload(), 0, 64, false, false);
endResult = (*((double *)(&result)) * factor) + bias;
}
cachedValue = endResult;
@@ -243,7 +244,7 @@ bool DBC_SIGNAL::processAsDouble(const CANFrame &frame, double &outValue)
DBC_ATTRIBUTE_VALUE *DBC_SIGNAL::findAttrValByName(QString name)
{
- if (attributes.length() == 0) return NULL;
+ if (attributes.length() == 0) return nullptr;
for (int i = 0; i < attributes.length(); i++)
{
if (attributes[i].attrName.compare(name, Qt::CaseInsensitive) == 0)
@@ -251,19 +252,19 @@ DBC_ATTRIBUTE_VALUE *DBC_SIGNAL::findAttrValByName(QString name)
return &attributes[i];
}
}
- return NULL;
+ return nullptr;
}
DBC_ATTRIBUTE_VALUE *DBC_SIGNAL::findAttrValByIdx(int idx)
{
- if (idx < 0) return NULL;
- if (idx >= attributes.count()) return NULL;
+ if (idx < 0) return nullptr;
+ if (idx >= attributes.count()) return nullptr;
return &attributes[idx];
}
DBC_ATTRIBUTE_VALUE *DBC_MESSAGE::findAttrValByName(QString name)
{
- if (attributes.length() == 0) return NULL;
+ if (attributes.length() == 0) return nullptr;
for (int i = 0; i < attributes.length(); i++)
{
if (attributes[i].attrName.compare(name, Qt::CaseInsensitive) == 0)
@@ -271,19 +272,19 @@ DBC_ATTRIBUTE_VALUE *DBC_MESSAGE::findAttrValByName(QString name)
return &attributes[i];
}
}
- return NULL;
+ return nullptr;
}
DBC_ATTRIBUTE_VALUE *DBC_MESSAGE::findAttrValByIdx(int idx)
{
- if (idx < 0) return NULL;
- if (idx >= attributes.count()) return NULL;
+ if (idx < 0) return nullptr;
+ if (idx >= attributes.count()) return nullptr;
return &attributes[idx];
}
DBC_ATTRIBUTE_VALUE *DBC_NODE::findAttrValByName(QString name)
{
- if (attributes.length() == 0) return NULL;
+ if (attributes.length() == 0) return nullptr;
for (int i = 0; i < attributes.length(); i++)
{
if (attributes[i].attrName.compare(name, Qt::CaseInsensitive) == 0)
@@ -291,12 +292,12 @@ DBC_ATTRIBUTE_VALUE *DBC_NODE::findAttrValByName(QString name)
return &attributes[i];
}
}
- return NULL;
+ return nullptr;
}
DBC_ATTRIBUTE_VALUE *DBC_NODE::findAttrValByIdx(int idx)
{
- if (idx < 0) return NULL;
- if (idx >= attributes.count()) return NULL;
+ if (idx < 0) return nullptr;
+ if (idx >= attributes.count()) return nullptr;
return &attributes[idx];
}
diff --git a/dbc/dbchandler.cpp b/dbc/dbchandler.cpp
index d56d18b..b2bc9ef 100644
--- a/dbc/dbchandler.cpp
+++ b/dbc/dbchandler.cpp
@@ -90,7 +90,7 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
if (messages.count() == 0) return nullptr;
for (int i = 0; i < messages.count(); i++)
{
- if (isJ1939Handler)
+ if (matchingCriteria == J1939)
{
// include data page and extended data page in the pgn
uint32_t pgn = (id & 0x3FFFF00) >> 8;
@@ -112,6 +112,13 @@ DBC_MESSAGE* DBCMessageHandler::findMsgByID(uint32_t id)
}
}
}
+ else if (matchingCriteria == GMLAN)
+ {
+ // Match the bits 14-26 (Arbitration Id) of GMLAN 29bit header
+ uint32_t arbId = id &0x3FFE000;
+ if ( (arbId != 0) && (messages[i].ID & 0x3FFE000) == arbId )
+ return &messages[i];
+ }
else
{
if ( messages[i].ID == id )
@@ -206,29 +213,41 @@ int DBCMessageHandler::getCount()
return messages.count();
}
-bool DBCMessageHandler::isJ1939()
+bool DBCMessageHandler::filterLabeling()
{
- return isJ1939Handler;
+ return filterLabelingEnabled;
}
-void DBCMessageHandler::setJ1939(bool j1939)
+void DBCMessageHandler::setFilterLabeling(bool filterLabeling)
{
- isJ1939Handler = j1939;
+ filterLabelingEnabled = filterLabeling;
+}
+
+MatchingCriteria_t DBCMessageHandler::getMatchingCriteria()
+{
+ return matchingCriteria;
+}
+
+void DBCMessageHandler::setMatchingCriteria(MatchingCriteria_t _matchingCriteria)
+{
+ matchingCriteria = _matchingCriteria;
}
DBCFile::DBCFile()
{
messageHandler = new DBCMessageHandler;
- messageHandler->setJ1939(false);
+ messageHandler->setMatchingCriteria(EXACT);
+ messageHandler->setFilterLabeling(false);
}
-DBCFile::DBCFile(const DBCFile& cpy)
+DBCFile::DBCFile(const DBCFile& cpy) : QObject()
{
messageHandler = new DBCMessageHandler;
for (int i = 0 ; i < cpy.messageHandler->getCount() ; i++)
messageHandler->addMessage(*cpy.messageHandler->findMsgByIdx(i));
- messageHandler->setJ1939(cpy.messageHandler->isJ1939());
+ messageHandler->setMatchingCriteria(cpy.messageHandler->getMatchingCriteria());
+ messageHandler->setFilterLabeling(cpy.messageHandler->filterLabeling());
fileName = cpy.fileName;
filePath = cpy.filePath;
assocBuses = cpy.assocBuses;
@@ -296,9 +315,10 @@ int DBCFile::getAssocBus()
void DBCFile::setAssocBus(int bus)
{
- int numBuses = CANConManager::getInstance()->getNumBuses();
if (bus < -1) return;
- if (bus >= numBuses) return;
+ // To allow setting bus numbers even before connection is configured, do not enforce "valid" bus numbers
+ //int numBuses = CANConManager::getInstance()->getNumBuses();
+ //if (bus >= numBuses) return;
assocBuses = bus;
}
@@ -448,6 +468,14 @@ DBC_SIGNAL* DBCFile::parseSignalLine(QString line, DBC_MESSAGE *msg)
case 4:
sig.valType = STRING;
break;
+ case 5: //single point float in little endian
+ sig.valType = SP_FLOAT;
+ sig.intelByteOrder = true;
+ break;
+ case 6: //double point float in little endian
+ sig.valType = DP_FLOAT;
+ sig.intelByteOrder = true;
+ break;
}
sig.factor = match.captured(6 + offset).toDouble();
sig.bias = match.captured(7 + offset).toDouble();
@@ -693,7 +721,8 @@ void DBCFile::loadFile(QString fileName)
qDebug() << "Starting DBC load";
dbc_nodes.clear();
messageHandler->removeAllMessages();
- messageHandler->setJ1939(false);
+ messageHandler->setMatchingCriteria(EXACT);
+ messageHandler->setFilterLabeling(false);
DBC_NODE falseNode;
falseNode.name = "Vector__XXX";
@@ -887,14 +916,24 @@ void DBCFile::loadFile(QString fileName)
fgAttr = findAttributeByName("GenMsgForegroundColor");
}
- DBC_ATTRIBUTE *j1939attr = findAttributeByName("isj1939dbc");
- if (j1939attr)
+ DBC_ATTRIBUTE *mc_attr = findAttributeByName("matchingcriteria");
+ if (mc_attr)
{
- messageHandler->setJ1939(j1939attr->defaultValue > 0);
+ messageHandler->setMatchingCriteria((MatchingCriteria_t)mc_attr->defaultValue.toInt());
}
else
{
- messageHandler->setJ1939(false);
+ messageHandler->setMatchingCriteria(EXACT);
+ }
+
+ DBC_ATTRIBUTE *fl_attr = findAttributeByName("filterlabeling");
+ if (fl_attr)
+ {
+ messageHandler->setFilterLabeling(fl_attr->defaultValue.toInt());
+ }
+ else
+ {
+ messageHandler->setFilterLabeling(false);
}
QColor DefaultBG = QColor(bgAttr->defaultValue.toString());
@@ -1202,10 +1241,12 @@ void DBCFile::saveFile(QString fileName)
else msgOutput.append("0-");
break;
case SP_FLOAT:
- msgOutput.append("2-");
+ if (sig->intelByteOrder) msgOutput.append("5-");
+ else msgOutput.append("2-");
break;
case DP_FLOAT:
- msgOutput.append("3-");
+ if (sig->intelByteOrder) msgOutput.append("6-");
+ else msgOutput.append("3-");
break;
case STRING:
msgOutput.append("4-");
@@ -1402,7 +1443,16 @@ int DBCHandler::createBlankFile()
attr.enumVals.clear();
attr.lower = 0;
attr.upper = 0;
- attr.name = "isj1939dbc";
+ attr.name = "matchingcriteria";
+ attr.valType = QINT;
+ newFile.dbc_attributes.append(attr);
+
+ attr.attrType = MESSAGE;
+ attr.defaultValue = 0;
+ attr.enumVals.clear();
+ attr.lower = 0;
+ attr.upper = 0;
+ attr.name = "filterlabeling";
attr.valType = QINT;
newFile.dbc_attributes.append(attr);
@@ -1415,6 +1465,14 @@ int DBCHandler::createBlankFile()
return loadedFiles.count();
}
+DBCFile* DBCHandler::loadDBCFile(QString filename)
+{
+ DBCFile newFile;
+ newFile.loadFile(filename);
+ loadedFiles.append(newFile);
+ return &loadedFiles.last();
+}
+
//the only reason to even bother sending the index is to see if
//the user wants to replace an already loaded DBC.
//Otherwise add a new one. Well, always add a new one.
@@ -1440,11 +1498,8 @@ DBCFile* DBCHandler::loadDBCFile(int idx)
{
filename = dialog.selectedFiles()[0];
//right now there is only one file type that can be loaded here so just do it.
- DBCFile newFile;
- newFile.loadFile(filename);
- loadedFiles.append(newFile);
settings.setValue("DBC/LoadSaveDirectory", dialog.directory().path());
- return &loadedFiles.last();
+ return loadDBCFile(filename);
}
return nullptr;
@@ -1650,7 +1705,7 @@ void DBCHandler::swapFiles(int pos1, int pos2)
* Convenience function that encapsulates a whole lot of the details.
* You give it a canbus frame and it'll tell you whether there is a loaded DBC file that can
* interpret that frame for you.
- * Returns NULL if there is no message definition that matches.
+ * Returns nullptr if there is no message definition that matches.
*/
DBC_MESSAGE* DBCHandler::findMessage(const CANFrame &frame)
{
@@ -1658,13 +1713,36 @@ DBC_MESSAGE* DBCHandler::findMessage(const CANFrame &frame)
{
if (loadedFiles[i].getAssocBus() == -1 || frame.bus == (unsigned int)loadedFiles[i].getAssocBus())
{
- DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(frame.ID);
+ DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(frame.frameId());
if (msg != nullptr) return msg;
}
}
return nullptr;
}
+
+// This function won't care which bus the DBC file is associated, but will return any message as long as ID matches and the file
+// has filter labeling enabled.
+// Returns the found message as well as the matching criteria (exact/J1939/GMLAN)
+// Used for quickly populating the Frame Filtering section with interpreted values
+DBC_MESSAGE* DBCHandler::findMessageForFilter(uint32_t id, MatchingCriteria_t * matchingCriteria)
+{
+ for(int i = 0; i < loadedFiles.count(); i++)
+ {
+ if (loadedFiles[i].messageHandler->filterLabeling())
+ {
+ DBC_MESSAGE* msg = loadedFiles[i].messageHandler->findMsgByID(id);
+ if (msg != nullptr)
+ {
+ *matchingCriteria = loadedFiles[i].messageHandler->getMatchingCriteria();
+ return msg;
+ }
+ }
+ }
+ return nullptr;
+}
+
+
/*
* As above, a real shortcut function that searches all files in order to try to find a message with the given name
*/
@@ -1708,7 +1786,44 @@ DBCFile* DBCHandler::getFileByName(QString name)
DBCHandler::DBCHandler()
{
+ // Load previously saved DBC file settings
+ QSettings settings;
+ int filecount = settings.value("DBC/FileCount", 0).toInt();
+ for (int i=0; isetAssocBus(bus);
+ MatchingCriteria_t matchingCriteria = (MatchingCriteria_t)settings.value("DBC/MatchingCriteria_" + QString(i),0).toInt();
+
+ DBC_ATTRIBUTE attr;
+
+ attr.attrType = MESSAGE;
+ attr.defaultValue = matchingCriteria;
+ attr.enumVals.clear();
+ attr.lower = 0;
+ attr.upper = 0;
+ attr.name = "matchingcriteria";
+ attr.valType = QINT;
+ file->dbc_attributes.append(attr);
+ file->messageHandler->setMatchingCriteria(matchingCriteria);
+
+ bool filterLabeling = settings.value("DBC/FilterLabeling_" + QString(i),0).toBool();
+ attr.attrType = MESSAGE;
+ attr.defaultValue = filterLabeling;
+ attr.enumVals.clear();
+ attr.lower = 0;
+ attr.upper = 0;
+ attr.name = "filterlabeling";
+ attr.valType = QINT;
+ file->dbc_attributes.append(attr);
+ file->messageHandler->setFilterLabeling(filterLabeling);
+
+ qInfo() << "Loaded DBC file" << filename << " (bus:" << bus
+ << ", Matching Criteria:" << (int)matchingCriteria << "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
+ }
}
DBCHandler* DBCHandler::getReference()
diff --git a/dbc/dbchandler.h b/dbc/dbchandler.h
index c767a7d..0dfd3fe 100644
--- a/dbc/dbchandler.h
+++ b/dbc/dbchandler.h
@@ -5,6 +5,13 @@
#include "dbc_classes.h"
#include "can_structs.h"
+ typedef enum
+ {
+ EXACT,
+ J1939,
+ GMLAN
+ } MatchingCriteria_t;
+
/*
* TODO:
* Finish coding up the decoupled design
@@ -40,11 +47,14 @@ public:
bool removeMessage(QString name);
void removeAllMessages();
int getCount();
- bool isJ1939();
- void setJ1939(bool j1939);
+ MatchingCriteria_t getMatchingCriteria();
+ void setMatchingCriteria(MatchingCriteria_t mc);
+ void setFilterLabeling( bool labelFiltering );
+ bool filterLabeling();
private:
QList messages;
- bool isJ1939Handler;
+ MatchingCriteria_t matchingCriteria;
+ bool filterLabelingEnabled;
};
//technically there should be a node handler too but I'm sort of treating nodes as second class
@@ -90,6 +100,7 @@ class DBCHandler: public QObject
{
Q_OBJECT
public:
+ DBCFile* loadDBCFile(QString filename);
DBCFile* loadDBCFile(int);
void saveDBCFile(int);
void removeDBCFile(int);
@@ -97,6 +108,7 @@ public:
void swapFiles(int pos1, int pos2);
DBC_MESSAGE* findMessage(const CANFrame &frame);
DBC_MESSAGE* findMessage(const QString msgName);
+ DBC_MESSAGE* findMessageForFilter(uint32_t id, MatchingCriteria_t * matchingCriteria);
int getFileCount();
DBCFile* getFileByIdx(int idx);
DBCFile* getFileByName(QString name);
diff --git a/dbc/dbcloadsavewindow.cpp b/dbc/dbcloadsavewindow.cpp
index 91bee2f..0c9b400 100644
--- a/dbc/dbcloadsavewindow.cpp
+++ b/dbc/dbcloadsavewindow.cpp
@@ -1,6 +1,8 @@
#include "dbcloadsavewindow.h"
#include "ui_dbcloadsavewindow.h"
-#include
+#include
+#include
+#include
#include "helpwindow.h"
#include "connections/canconmanager.h"
@@ -15,17 +17,47 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector *frames, QWidget *p
ui->setupUi(this);
- inhibitCellProcessing = false;
+ inhibitCellProcessing = true;
QStringList header;
- header << "Filename" << "Associated Bus" << "J1939";
- ui->tableFiles->setColumnCount(3);
+ header << "Filename" << "Associated Bus" << "Matching criteria" << "Label filters";
+ ui->tableFiles->setColumnCount(4);
ui->tableFiles->setHorizontalHeaderLabels(header);
ui->tableFiles->setColumnWidth(0, 265);
ui->tableFiles->setColumnWidth(1, 125);
- ui->tableFiles->setColumnWidth(2, 80);
+ ui->tableFiles->setColumnWidth(2, 120);
+ ui->tableFiles->setColumnWidth(3, 90);
ui->tableFiles->horizontalHeader()->setStretchLastSection(true);
+ // Populate table
+ for (int idx=0; idxgetFileCount(); idx++)
+ {
+ DBCFile * file = dbcHandler->getFileByIdx(idx);
+ ui->tableFiles->insertRow(ui->tableFiles->rowCount());
+ ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
+ QString bus = QString::number(file->getAssocBus() );
+ ui->tableFiles->setItem(idx, 1, new QTableWidgetItem(bus));
+
+ QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
+ int mc = (int)file->messageHandler->getMatchingCriteria();
+ mc_item->setCurrentIndex(mc);
+
+ QTableWidgetItem *item = new QTableWidgetItem("");
+ ui->tableFiles->setItem(idx, 3, item);
+ bool filterLabeling = file->messageHandler->filterLabeling();
+ if (filterLabeling)
+ {
+ item->setCheckState(Qt::Checked);
+ }
+ else
+ {
+ item->setCheckState(Qt::Unchecked);
+ }
+
+ qDebug() << "Populate DBC table:" << file->getFullFilename() << " (bus:" << bus << " - Matching Criteria:" << mc
+ << "Filter labeling: " << (filterLabeling?"enabled":"disabled") << ")";
+ }
+
connect(ui->btnEdit, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::editFile);
connect(ui->btnLoad, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::loadFile);
connect(ui->btnMoveDown, &QAbstractButton::clicked, this, &DBCLoadSaveWindow::moveDown);
@@ -40,15 +72,51 @@ DBCLoadSaveWindow::DBCLoadSaveWindow(const QVector *frames, QWidget *p
editorWindow = new DBCMainEditor(frames, this);
currentlyEditingFile = nullptr;
+ inhibitCellProcessing = false;
+
installEventFilter(this);
}
+QComboBox * DBCLoadSaveWindow::addMatchingCriteriaCombobox(int row)
+{
+ QComboBox *item = new QComboBox();
+ item->addItem("Exact");
+ item->addItem("J1939");
+ item->addItem("GMLAN");
+ ui->tableFiles->setCellWidget(row, 2, item);
+ connect(item, static_cast(&QComboBox::currentIndexChanged),
+ [this](int box_idx) { matchingCriteriaChanged(box_idx); } );
+ return item;
+}
+
DBCLoadSaveWindow::~DBCLoadSaveWindow()
{
removeEventFilter(this);
delete ui;
}
+void DBCLoadSaveWindow::updateSettings()
+{
+ QSettings settings;
+ int filecount = ui->tableFiles->rowCount();
+ settings.setValue("DBC/FileCount", filecount);
+ for (int i=0; igetFileByIdx(i);
+ if (file)
+ {
+ qDebug() << "Save DBC settings #" << i << " File: " << file->getFullFilename()
+ << "Bus: " << file->getAssocBus() << "MC: " << file->messageHandler->getMatchingCriteria()
+ << "Filter Labeling: " << (file->messageHandler->filterLabeling() ? "enabled" : "disabled");
+ settings.setValue("DBC/Filename_" + QString(i), file->getFullFilename());
+ settings.setValue("DBC/AssocBus_" + QString(i), file->getAssocBus());
+ settings.setValue("DBC/MatchingCriteria_" + QString(i), file->messageHandler->getMatchingCriteria());
+ settings.setValue("DBC/FilterLabeling_" + QString(i), file->messageHandler->filterLabeling());
+ }
+ }
+ emit updatedDBCSettings();
+}
+
bool DBCLoadSaveWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::KeyRelease) {
@@ -75,22 +143,34 @@ void DBCLoadSaveWindow::newFile()
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem("UNNAMEDFILE"));
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
+ QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
+ mc_item->setCurrentIndex(EXACT);
+
QTableWidgetItem *item = new QTableWidgetItem("");
- item->setCheckState(Qt::Unchecked);
- ui->tableFiles->setItem(idx, 2, item);
+ item->setCheckState(Qt::Checked);
+ ui->tableFiles->setItem(idx, 3, item);
}
void DBCLoadSaveWindow::loadFile()
{
DBCFile *file = dbcHandler->loadDBCFile(-1);
if(file) {
+ inhibitCellProcessing=true;
int idx = ui->tableFiles->rowCount();
ui->tableFiles->insertRow(ui->tableFiles->rowCount());
ui->tableFiles->setItem(idx, 0, new QTableWidgetItem(file->getFullFilename()));
ui->tableFiles->setItem(idx, 1, new QTableWidgetItem("-1"));
- DBC_ATTRIBUTE *attr = file->findAttributeByName("isj1939dbc");
+
+ DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
+ QComboBox * mc_item = addMatchingCriteriaCombobox(idx);
+ if (attr && attr->defaultValue > 0)
+ {
+ mc_item->setCurrentIndex(attr->defaultValue.toInt());
+ }
+
+ attr = file->findAttributeByName("filterlabeling");
QTableWidgetItem *item = new QTableWidgetItem("");
- ui->tableFiles->setItem(idx, 2, item);
+ ui->tableFiles->setItem(idx, 3, item);
if (attr && attr->defaultValue > 0)
{
item->setCheckState(Qt::Checked);
@@ -99,6 +179,9 @@ void DBCLoadSaveWindow::loadFile()
{
item->setCheckState(Qt::Unchecked);
}
+ inhibitCellProcessing=false;
+
+ updateSettings();
}
}
@@ -154,6 +237,7 @@ void DBCLoadSaveWindow::removeFile()
dbcHandler->removeDBCFile(idx);
ui->tableFiles->removeRow(idx);
}
+ updateSettings();
}
void DBCLoadSaveWindow::moveUp()
@@ -162,6 +246,7 @@ void DBCLoadSaveWindow::moveUp()
if (idx < 1) return;
dbcHandler->swapFiles(idx - 1, idx);
swapTableRows(true);
+ updateSettings();
}
void DBCLoadSaveWindow::moveDown()
@@ -171,6 +256,7 @@ void DBCLoadSaveWindow::moveDown()
if (idx > (dbcHandler->getFileCount() - 2)) return;
dbcHandler->swapFiles(idx, idx + 1);
swapTableRows(false);
+ updateSettings();
}
void DBCLoadSaveWindow::editFile()
@@ -182,6 +268,43 @@ void DBCLoadSaveWindow::editFile()
editorWindow->show();
}
+void DBCLoadSaveWindow::matchingCriteriaChanged(int index)
+{
+ if (inhibitCellProcessing) return;
+ // We don't know which combobox changed, so we just update all of them
+ for (int row=0; rowtableFiles->rowCount(); row++)
+ {
+ DBCFile *file = dbcHandler->getFileByIdx(row);
+ if (file)
+ {
+ QComboBox *item = (QComboBox*)ui->tableFiles->cellWidget(row, 2);
+ MatchingCriteria_t matchingCriteria = (MatchingCriteria_t) item->currentIndex();
+ DBC_ATTRIBUTE *attr = file->findAttributeByName("matchingcriteria");
+ if (attr)
+ {
+ attr->defaultValue = matchingCriteria;
+ file->messageHandler->setMatchingCriteria(matchingCriteria);
+ }
+ else
+ {
+ DBC_ATTRIBUTE attr;
+
+ attr.attrType = MESSAGE;
+ attr.defaultValue = matchingCriteria;
+ attr.enumVals.clear();
+ attr.lower = 0;
+ attr.upper = 0;
+ attr.name = "matchingcriteria";
+ attr.valType = QINT;
+ file->dbc_attributes.append(attr);
+ file->messageHandler->setMatchingCriteria(matchingCriteria);
+ }
+ }
+ }
+ updateSettings();
+}
+
+
void DBCLoadSaveWindow::cellChanged(int row, int col)
{
if (inhibitCellProcessing) return;
@@ -190,39 +313,40 @@ void DBCLoadSaveWindow::cellChanged(int row, int col)
DBCFile *file = dbcHandler->getFileByIdx(row);
int bus = ui->tableFiles->item(row, col)->text().toInt();
int numBuses = CANConManager::getInstance()->getNumBuses();
- if (bus > -2 && bus < numBuses)
+ if (bus > -2)
{
file->setAssocBus(bus);
}
- }
- else if (col == 2)
+ updateSettings();
+ }
+ else if (col == 3) // labelfilters
{
DBCFile *file = dbcHandler->getFileByIdx(row);
if (file)
{
- //int isj1939dbc = ui->tableFiles->item(row, col)->text().toInt();
- bool isj1939dbc = ui->tableFiles->item(row, col)->checkState() == Qt::Checked;
- DBC_ATTRIBUTE *attr = file->findAttributeByName("isj1939dbc");
+ bool labelFilters = ui->tableFiles->item(row, col)->checkState() == Qt::Checked;
+ DBC_ATTRIBUTE *attr = file->findAttributeByName("filterlabeling");
if (attr)
{
- attr->defaultValue = isj1939dbc ? 1 : 0;
- file->messageHandler->setJ1939(isj1939dbc);
+ attr->defaultValue = labelFilters ? 1 : 0;
+ file->messageHandler->setFilterLabeling(labelFilters);
}
else
{
DBC_ATTRIBUTE attr;
attr.attrType = MESSAGE;
- attr.defaultValue = isj1939dbc ? 1 : 0;
+ attr.defaultValue = labelFilters ? 1 : 0;
attr.enumVals.clear();
attr.lower = 0;
attr.upper = 0;
- attr.name = "isj1939dbc";
+ attr.name = "labelfilters";
attr.valType = QINT;
file->dbc_attributes.append(attr);
- file->messageHandler->setJ1939(isj1939dbc);
+ file->messageHandler->setFilterLabeling(labelFilters);
}
- }
+ updateSettings();
+ }
}
}
@@ -245,10 +369,17 @@ void DBCLoadSaveWindow::swapTableRows(bool up)
QList sourceItems = takeRow(idx);
QList destItems = takeRow(destIdx);
+ // QCombobox needs separate handling
+ int sourceMC = ((QComboBox*)ui->tableFiles->cellWidget(idx,2))->currentIndex();
+ int destMC = ((QComboBox*)ui->tableFiles->cellWidget(destIdx,2))->currentIndex();
+
// set back in reverse order
setRow(idx, destItems);
setRow(destIdx, sourceItems);
+ ((QComboBox*)ui->tableFiles->cellWidget(idx,2))->setCurrentIndex(destMC);
+ ((QComboBox*)ui->tableFiles->cellWidget(destIdx,2))->setCurrentIndex(sourceMC);
+
inhibitCellProcessing = false;
}
diff --git a/dbc/dbcloadsavewindow.h b/dbc/dbcloadsavewindow.h
index 18625cc..34961a3 100644
--- a/dbc/dbcloadsavewindow.h
+++ b/dbc/dbcloadsavewindow.h
@@ -3,6 +3,7 @@
#include
#include
+#include
#include "dbchandler.h"
#include "dbcmaineditor.h"
@@ -28,8 +29,12 @@ private slots:
void editFile();
void cellChanged(int row, int col);
void cellDoubleClicked(int row, int col);
+ void matchingCriteriaChanged(int index);
void newFile();
+signals:
+ void updatedDBCSettings();
+
private:
Ui::DBCLoadSaveWindow *ui;
DBCHandler *dbcHandler;
@@ -42,6 +47,8 @@ private:
QList takeRow(int row);
void setRow(int row, const QList& rowItems);
bool eventFilter(QObject *obj, QEvent *event);
+ void updateSettings();
+ QComboBox * addMatchingCriteriaCombobox(int row);
};
#endif // DBCLOADSAVEWINDOW_H
diff --git a/dbc/dbcmaineditor.cpp b/dbc/dbcmaineditor.cpp
index ccf9a1b..8687ce6 100644
--- a/dbc/dbcmaineditor.cpp
+++ b/dbc/dbcmaineditor.cpp
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include "helpwindow.h"
DBCMainEditor::DBCMainEditor( const QVector *frames, QWidget *parent) :
@@ -193,7 +194,7 @@ void DBCMainEditor::onCellChangedNode(int row,int col)
QString newName = ui->NodesTable->item(row, col)->text().simplified().replace(' ', '_');
qDebug() << "new name: " << newName;
if (newName.length() == 0) return;
- if (dbcFile->findNodeByName(newName) != NULL) //duplicates an existing node!
+ if (dbcFile->findNodeByName(newName) != nullptr) //duplicates an existing node!
{
QMessageBox msg;
msg.setParent(0);
@@ -217,7 +218,7 @@ void DBCMainEditor::onCellChangedNode(int row,int col)
{
DBC_NODE *oldNode = dbcFile->findNodeByIdx(row);
QString nodeName = ui->NodesTable->item(row, col)->text().simplified().replace(' ', '_');
- if (oldNode == NULL) return;
+ if (oldNode == nullptr) return;
if (row != 0) oldNode->name = nodeName;
else nodeName = oldNode->name;
inhibitCellChanged = true;
@@ -230,7 +231,7 @@ void DBCMainEditor::onCellChangedNode(int row,int col)
QString nodeName = ui->NodesTable->item(row, 0)->text().simplified().replace(' ', '_');
qDebug() << "searching for node " << nodeName;
DBC_NODE *thisNode = dbcFile->findNodeByName(nodeName);
- if (thisNode == NULL) return;
+ if (thisNode == nullptr) return;
thisNode->comment = ui->NodesTable->item(row, col)->text().simplified();
qDebug() << "New comment: " << thisNode->comment;
}
@@ -240,15 +241,15 @@ void DBCMainEditor::onCellChangedNode(int row,int col)
void DBCMainEditor::onCellChangedMessage(int row,int col)
{
- QTableWidgetItem* item = NULL;
+ QTableWidgetItem* item = nullptr;
bool ret = false;
- DBC_MESSAGE *msg = NULL;
+ DBC_MESSAGE *msg = nullptr;
uint msgID;
if (inhibitCellChanged) return;
DBC_NODE *node = dbcFile->findNodeByIdx(ui->NodesTable->currentRow());
- if (node == NULL)
+ if (node == nullptr)
{
qDebug() << "No node set?!? This is bad!";
return;
@@ -271,7 +272,7 @@ void DBCMainEditor::onCellChangedMessage(int row,int col)
ui->MessagesTable->item(row, 0)->setText("");
return;
}
- if (msg != NULL)
+ if (msg != nullptr)
{
QMessageBox msg;
msg.setParent(0);
@@ -293,9 +294,9 @@ void DBCMainEditor::onCellChangedMessage(int row,int col)
for (int i = 0; i < referenceFrames->length(); i++)
{
- if ((uint) referenceFrames->at(i).ID == msgID)
+ if ((uint) referenceFrames->at(i).frameId() == msgID)
{
- newMsg.len = referenceFrames->at(i).len;
+ newMsg.len = referenceFrames->at(i).payload().length();
break;
}
}
@@ -328,7 +329,7 @@ void DBCMainEditor::onCellChangedMessage(int row,int col)
{
QString msgName = ui->MessagesTable->item(row, 1)->text().simplified().replace(' ', '_');
if (msgName.length() == 0) return;
- if( ret && (msg!=NULL) )
+ if( ret && (msg!=nullptr) )
msg->name = msgName;
break;
}
@@ -349,7 +350,7 @@ void DBCMainEditor::onCellChangedMessage(int row,int col)
ui->MessagesTable->item(row, col)->setText(QString::number(msgLen));
}
- if( ret && (msg!=NULL) )
+ if( ret && (msg!=nullptr) )
msg->len = msgLen;
break;
}
@@ -358,7 +359,7 @@ void DBCMainEditor::onCellChangedMessage(int row,int col)
case 6: //comment
{
QString msgComment = ui->MessagesTable->item(row, col)->text().simplified();
- if( ret && (msgComment!=NULL) )
+ if( ret && (msgComment!=nullptr) )
msg->comment = msgComment;
break;
}
@@ -376,7 +377,7 @@ void DBCMainEditor::onCellClickedNode(int row, int col)
currRow = row;
QTableWidgetItem *item = ui->NodesTable->item(currRow, 0);
QString nodeName;
- if (item == NULL) return;
+ if (item == nullptr) return;
nodeName = item->text();
qDebug() << "Trying to find node with name " << nodeName;
@@ -476,7 +477,7 @@ void DBCMainEditor::refreshNodesTable()
int rowIdx;
- if (dbcFile->findNodeByName("Vector__XXX") == NULL)
+ if (dbcFile->findNodeByName("Vector__XXX") == nullptr)
{
DBC_NODE newNode;
newNode.name = "Vector__XXX";
@@ -509,7 +510,7 @@ void DBCMainEditor::refreshMessagesTable(const DBC_NODE *node)
int rowIdx;
- if (node != NULL)
+ if (node != nullptr)
{
for (int x = 0; x < dbcFile->messageHandler->getCount(); x++)
{
diff --git a/dbc/dbcsignaleditor.cpp b/dbc/dbcsignaleditor.cpp
index d86353d..6c579ec 100644
--- a/dbc/dbcsignaleditor.cpp
+++ b/dbc/dbcsignaleditor.cpp
@@ -4,6 +4,7 @@
#include
#include
#include
+#include
#include "helpwindow.h"
DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
@@ -17,8 +18,8 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
qsrand(QDateTime::currentMSecsSinceEpoch());
dbcHandler = DBCHandler::getReference();
- dbcMessage = NULL;
- currentSignal = NULL;
+ dbcMessage = nullptr;
+ currentSignal = nullptr;
QStringList headers2;
headers2 << "Value" << "Text";
@@ -46,23 +47,21 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->cbIntelFormat, &QCheckBox::toggled,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
currentSignal->intelByteOrder = ui->cbIntelFormat->isChecked();
- if (currentSignal->valType == SP_FLOAT || currentSignal->valType == DP_FLOAT)
- currentSignal->intelByteOrder = false;
fillSignalForm(currentSignal);
});
connect(ui->comboReceiver, &QComboBox::currentTextChanged,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
currentSignal->receiver = dbcFile->findNodeByName(ui->comboReceiver->currentText());
});
connect(ui->comboType, &QComboBox::currentTextChanged,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
switch (ui->comboType->currentIndex())
{
case 0:
@@ -73,13 +72,11 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
break;
case 2:
currentSignal->valType = SP_FLOAT;
- currentSignal->intelByteOrder = false;
if (currentSignal->startBit > 39) currentSignal->startBit = 39;
currentSignal->signalSize = 32;
break;
case 3:
currentSignal->valType = DP_FLOAT;
- currentSignal->intelByteOrder = false;
currentSignal->startBit = 7; //has to be!
currentSignal->signalSize = 64;
break;
@@ -92,7 +89,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtBias, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
double temp;
bool result;
temp = ui->txtBias->text().toDouble(&result);
@@ -102,7 +99,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtMaxVal, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
double temp;
bool result;
temp = ui->txtMaxVal->text().toDouble(&result);
@@ -112,7 +109,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtMinVal, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
double temp;
bool result;
temp = ui->txtMinVal->text().toDouble(&result);
@@ -121,7 +118,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtScale, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
double temp;
bool result;
temp = ui->txtScale->text().toDouble(&result);
@@ -130,24 +127,24 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtComment, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
currentSignal->comment = ui->txtComment->text().simplified().replace(' ', '_');
});
connect(ui->txtUnitName, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
currentSignal->unitName = ui->txtUnitName->text().simplified().replace(' ', '_');
});
connect(ui->txtBitLength, &QLineEdit::textChanged,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtBitLength->text());
- if (temp < 0) return;
- if (temp > 63) return;
+ if (temp < 1) return;
+ if (temp > 64) return;
if (currentSignal->valType != SP_FLOAT && currentSignal->valType != DP_FLOAT)
currentSignal->signalSize = temp;
fillSignalForm(currentSignal);
@@ -155,7 +152,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtName, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
QString tempNameStr = ui->txtName->text().simplified().replace(' ', '_');
if (tempNameStr.length() > 0) currentSignal->name = tempNameStr;
//need to update the list too.
@@ -165,7 +162,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
connect(ui->txtMultiplexValue, &QLineEdit::editingFinished,
[=]()
{
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
int temp;
temp = Utility::ParseStringToNum(ui->txtMultiplexValue->text());
//TODO: could look up the multiplexor and ensure that the value is within a range that the multiplexor could return
@@ -179,7 +176,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
currentSignal->isMultiplexed = true;
currentSignal->isMultiplexor = false;
//if the set multiplexor for the message was this signal then clear it
- if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = NULL;
+ if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
}
});
@@ -189,7 +186,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
if (state && currentSignal) //signal is now set as a multiplexed signal
{
//don't allow this signal to be a multiplexor if there is already one for this message.
- //if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != NULL) return; //I spoke too soon above...
+ //if (dbcMessage->multiplexorSignal != currentSignal && dbcMessage->multiplexorSignal != nullptr) return; //I spoke too soon above...
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = true;
//we just set that this is the multiplexor so update the message to show that as well.
@@ -204,7 +201,7 @@ DBCSignalEditor::DBCSignalEditor(QWidget *parent) :
{
currentSignal->isMultiplexed = false;
currentSignal->isMultiplexor = false;
- if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = NULL;
+ if (dbcMessage->multiplexorSignal == currentSignal) dbcMessage->multiplexorSignal = nullptr;
}
});
@@ -286,7 +283,7 @@ void DBCSignalEditor::showEvent(QShowEvent* event)
{
QDialog::showEvent(event);
- currentSignal = NULL;
+ currentSignal = nullptr;
refreshSignalsList();
}
@@ -422,7 +419,7 @@ void DBCSignalEditor::deleteCurrentSignal()
{
delete(ui->signalsList->item(currIdx));
dbcMessage->sigHandler->removeSignal(currIdx);
- currentSignal = NULL;
+ currentSignal = nullptr;
}
}
@@ -461,7 +458,7 @@ void DBCSignalEditor::fillSignalForm(DBC_SIGNAL *sig)
{
unsigned char bitpattern[8];
- if (sig == NULL) {
+ if (sig == nullptr) {
ui->groupBox->setEnabled(false);
ui->txtName->setText("");
ui->txtBias->setText("");
@@ -578,7 +575,7 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
ui->valuesTable->clearContents();
ui->valuesTable->setRowCount(0);
- if (sig == NULL) {
+ if (sig == nullptr) {
ui->valuesTable->setEnabled(false);
inhibitCellChanged = false;
return;
@@ -588,7 +585,7 @@ void DBCSignalEditor::fillValueTable(DBC_SIGNAL *sig)
for (int i = 0; i < sig->valList.count(); i++)
{
- QTableWidgetItem *val = new QTableWidgetItem(Utility::formatNumber(sig->valList[i].value));
+ QTableWidgetItem *val = new QTableWidgetItem(Utility::formatNumber((uint64_t)sig->valList[i].value));
QTableWidgetItem *desc = new QTableWidgetItem(sig->valList[i].descript);
rowIdx = ui->valuesTable->rowCount();
ui->valuesTable->insertRow(rowIdx);
@@ -606,7 +603,7 @@ void DBCSignalEditor::clickSignalList(int row)
{
//qDebug() << ui->signalsList->item(row)->text();
- DBC_SIGNAL *thisSig = (row<0) ? NULL : dbcMessage->sigHandler->findSignalByName(ui->signalsList->item(row)->text());
+ DBC_SIGNAL *thisSig = (row<0) ? nullptr : dbcMessage->sigHandler->findSignalByName(ui->signalsList->item(row)->text());
currentSignal = thisSig;
fillSignalForm(thisSig);
fillValueTable(thisSig);
@@ -615,7 +612,7 @@ void DBCSignalEditor::clickSignalList(int row)
void DBCSignalEditor::bitfieldClicked(int x, int y)
{
int bit = (7 - x) + (y * 8);
- if (currentSignal == NULL) return;
+ if (currentSignal == nullptr) return;
currentSignal->startBit = bit;
if (currentSignal->valType == SP_FLOAT)
{
diff --git a/docs/build.sh b/docs/build.sh
index db03507..195b50e 100755
--- a/docs/build.sh
+++ b/docs/build.sh
@@ -1,4 +1,4 @@
make qthelp
-~/Qt/5.12.1/gcc_64/bin/qcollectiongenerator build/qthelp/SavvyCAN.qhcp
-~/Qt/5.12.1/gcc_64/bin/assistant -collectionFile build/qthelp/SavvyCAN.qhc
+cp -R build/qthelp/* ../help
+rm ../help/SavvyCAN.q*
diff --git a/filterutility.cpp b/filterutility.cpp
new file mode 100644
index 0000000..b577c3d
--- /dev/null
+++ b/filterutility.cpp
@@ -0,0 +1,80 @@
+#include "utility.h"
+#include "filterutility.h"
+#include "dbc/dbchandler.h"
+#include
+
+uint32_t FilterUtility::getIdAsInt( QListWidgetItem * item )
+{
+ return Utility::ParseStringToNum(getId(item));
+}
+
+QString FilterUtility::getId( QString itemText )
+{
+ if (itemText.contains(" "))
+ // Strip away the filter label
+ return itemText.left(itemText.indexOf(" "));
+ else
+ return itemText;
+}
+
+QString FilterUtility::getId( QListWidgetItem * item )
+{
+ return getId(item->text());
+}
+
+uint32_t FilterUtility::getGMLanArbitrationId(int32_t id)
+{
+ return (id >> 13) & 0x1FFF;
+}
+
+uint32_t FilterUtility::getGMLanPriorityBits(int32_t id)
+{
+ return (id >> 26) & 0x7;
+}
+
+uint32_t FilterUtility::getGMLanSenderId(int32_t id)
+{
+ return id & 0x1FFF;
+}
+
+QListWidgetItem * FilterUtility::createCheckableFilterItem(int32_t id, bool checked, QListWidget* parent)
+{
+ QListWidgetItem * thisItem = createFilterItem(id,parent);
+ thisItem->setFlags(thisItem->flags() | Qt::ItemIsUserCheckable);
+ if (checked)
+ thisItem->setCheckState(Qt::Checked);
+ else
+ thisItem->setCheckState(Qt::Unchecked);
+ return thisItem;
+}
+
+QListWidgetItem * FilterUtility::createFilterItem(int32_t id, QListWidget* parent)
+{
+ QSettings settings;
+ DBCHandler * dbcHandler = DBCHandler::getReference();
+ QListWidgetItem *thisItem = new QListWidgetItem(parent);
+ QString filterItemName = Utility::formatCANID(id);
+
+ if (settings.value("Main/FilterLabeling", false).toBool())
+ {
+ // Filter labeling (show interpreted frame names next to the CAN addr ID)
+ MatchingCriteria_t matchingCriteria;
+ DBC_MESSAGE *msg = dbcHandler->findMessageForFilter(id,&matchingCriteria);
+ if (msg != NULL)
+ {
+ filterItemName.append(" ");
+ filterItemName.append(msg->name);
+
+ // Create tooltip to show the whole name just in case it's too long to fit in the filter window.
+ // Also if the matching criteria is set to GMLAN, show the Arbitration ID as well
+ QString tooltip;
+ if (matchingCriteria == GMLAN)
+ tooltip.append("0x" + QString::number(FilterUtility::getGMLanArbitrationId(id), 16).toUpper().rightJustified(4,'0') + ": ");
+ tooltip.append(msg->name);
+ thisItem->setToolTip(tooltip);
+ }
+ }
+
+ thisItem->setText(filterItemName);
+ return thisItem;
+}
diff --git a/filterutility.h b/filterutility.h
new file mode 100644
index 0000000..e346c31
--- /dev/null
+++ b/filterutility.h
@@ -0,0 +1,23 @@
+#ifndef FILTERUTILITY_H
+#define FILTERUTILITY_H
+
+#include
+
+
+class FilterUtility
+{
+
+public:
+ static QListWidgetItem * createFilterItem(int32_t id, QListWidget* parent=NULL); // if parent is given, add item automatically to listwidget
+ static QListWidgetItem * createCheckableFilterItem(int32_t id, bool checked, QListWidget* parent=NULL);
+
+ static uint32_t getIdAsInt( QListWidgetItem * item );
+ static QString getId( QListWidgetItem * item );
+ static QString getId( QString itemText );
+
+ static uint32_t getGMLanArbitrationId(int32_t id);
+ static uint32_t getGMLanSenderId(int32_t id);
+ static uint32_t getGMLanPriorityBits(int32_t id);
+};
+
+#endif // DBCLOADSAVEWINDOW_H
diff --git a/firmwareuploaderwindow.cpp b/firmwareuploaderwindow.cpp
index 2b13746..6480e25 100644
--- a/firmwareuploaderwindow.cpp
+++ b/firmwareuploaderwindow.cpp
@@ -4,6 +4,13 @@
#include
+//You might wonder: Collin, what in the hell is this for? Firmware uploader? For what? I'm interested! Well, it's a custom
+//firmware uploader for a motor controller I built. Why would that be in this project. Cuz. It's not really relevant
+//to anyone else but might serve as a decent reference for a few things: How to make an uploader interface that runs over CAN,
+//how to lay out a screen like this, how to make a comm protocol for firmware updating over CAN. But, most things use UDS
+//for firmware updates and wouldn't need this specific code. But, it might be able to be turned into a UDS firmware uploader or downloader.
+//Note that this screen is specifically hidden by default because of it's oddball status. You have to re-enable it in mainwindow.cpp to see it.
+
FirmwareUploaderWindow::FirmwareUploaderWindow(const QVector *frames, QWidget *parent) :
QDialog(parent),
ui(new Ui::FirmwareUploaderWindow)
@@ -70,17 +77,20 @@ void FirmwareUploaderWindow::updatedFrames(int numFrames)
void FirmwareUploaderWindow::gotTargettedFrame(CANFrame frame)
{
- qDebug() << "FUW: Got targetted frame with id " << frame.ID;
- if (frame.ID == (uint32_t)(baseAddress + 0x10)) {
+ unsigned char *data = reinterpret_cast(frame.payload().data());
+ int dataLen = frame.payload().count();
+
+ qDebug() << "FUW: Got targetted frame with id " << frame.frameId();
+ if (frame.frameId() == (uint32_t)(baseAddress + 0x10) && (dataLen == 8) ) {
qDebug() << "Start firmware reply";
- if ((frame.data[0] == 0xAD) && (frame.data[1] == 0xDE))
+ if ((data[0] == 0xAD) && (data[1] == 0xDE))
{
- if ((frame.data[2] == 0xAF) && (frame.data[3] == 0xDE))
+ if ((data[2] == 0xAF) && (data[3] == 0xDE))
{
- qDebug() << "THere's dead beef here";
- if ((frame.data[4] == (token & 0xFF)) && (frame.data[5] == ((token >> 8) & 0xFF)))
+ qDebug() << "There's dead beef here";
+ if ( (data[4] == (token & 0xFF)) && (data[5] == ((token >> 8) & 0xFF) ) )
{
- if ((frame.data[6] == ((token >> 16) & 0xFF)) && (frame.data[7] == ((token >> 24) & 0xFF)))
+ if ((data[6] == ((token >> 16) & 0xFF)) && (data[7] == ((token >> 24) & 0xFF)))
{
qDebug() << "starting firmware process";
//MainWindow::getReference()->setTargettedID(baseAddress + 0x20);
@@ -92,9 +102,9 @@ void FirmwareUploaderWindow::gotTargettedFrame(CANFrame frame)
}
}
- if (frame.ID == (uint32_t)(baseAddress + 0x20)) {
+ if (frame.frameId() == (uint32_t)(baseAddress + 0x20)) {
qDebug() << "Firmware reception success reply";
- int seq = frame.data[0] + (256 * frame.data[1]);
+ int seq = data[0] + (256 * data[1]);
if (seq == currentSendingPosition)
{
currentSendingPosition++;
@@ -126,18 +136,19 @@ void FirmwareUploaderWindow::sendFirmwareChunk()
CANFrame *output = new CANFrame;
int firmwareLocation = currentSendingPosition * 4;
int xorByte = 0;
- output->extended = false;
- output->len = 7;
+ output->setExtendedFrameFormat(false);
+ QByteArray bytes(7,0);
output->bus = bus;
- output->ID = baseAddress + 0x16;
- output->data[0] = currentSendingPosition & 0xFF;
- output->data[1] = (currentSendingPosition >> 8) & 0xFF;
- output->data[2] = firmwareData[firmwareLocation++];
- output->data[3] = firmwareData[firmwareLocation++];
- output->data[4] = firmwareData[firmwareLocation++];
- output->data[5] = firmwareData[firmwareLocation++];
- for (int i = 0; i < 6; i++) xorByte = xorByte ^ output->data[i];
- output->data[6] = xorByte;
+ output->setFrameId(baseAddress + 0x16);
+ output->payload()[0] = currentSendingPosition & 0xFF;
+ output->payload()[1] = (currentSendingPosition >> 8) & 0xFF;
+ output->payload()[2] = firmwareData[firmwareLocation++];
+ output->payload()[3] = firmwareData[firmwareLocation++];
+ output->payload()[4] = firmwareData[firmwareLocation++];
+ output->payload()[5] = firmwareData[firmwareLocation++];
+ for (int i = 0; i < 6; i++) xorByte = xorByte ^ static_cast(output->payload()[i]);
+ output->payload()[6] = xorByte;
+ output->setPayload(bytes);
sendCANFrame(output);
timer->start();
}
@@ -145,14 +156,15 @@ void FirmwareUploaderWindow::sendFirmwareChunk()
void FirmwareUploaderWindow::sendFirmwareEnding()
{
CANFrame *output = new CANFrame;
- output->extended = false;
+ output->setExtendedFrameFormat(false);
output->bus = bus;
- output->len = 4;
- output->ID = baseAddress + 0x30;
- output->data[3] = 0xC0;
- output->data[2] = 0xDE;
- output->data[1] = 0xFA;
- output->data[0] = 0xDE;
+ QByteArray bytes(4,0);
+ output->setFrameId(baseAddress + 0x30);
+ output->payload()[3] = 0xC0;
+ output->payload()[2] = 0xDE;
+ output->payload()[1] = 0xFA;
+ output->payload()[0] = 0xDE;
+ output->setPayload(bytes);
//sendCANFrame(output, bus);
}
@@ -171,19 +183,19 @@ void FirmwareUploaderWindow::handleStartStopTransfer()
CANConManager::getInstance()->addTargettedFrame(bus, baseAddress + 0x10, 0x7FF, this);
CANConManager::getInstance()->addTargettedFrame(bus, baseAddress + 0x20, 0x7FF, this);
CANFrame *output = new CANFrame;
- output->extended = false;
- output->len = 8;
+ output->setExtendedFrameFormat(false);
+ QByteArray bytes(8,0);
output->bus = bus;
- output->ID = baseAddress;
+ output->setFrameId(baseAddress);
- output->data[0] = 0xEF;
- output->data[1] = 0xBE;
- output->data[2] = 0xAD;
- output->data[3] = 0xDE;
- output->data[4] = token & 0xFF;
- output->data[5] = (token >> 8) & 0xFF;
- output->data[6] = (token >> 16) & 0xFF;
- output->data[7] = (token >> 24) & 0xFF;
+ output->payload()[0] = 0xEF;
+ output->payload()[1] = 0xBE;
+ output->payload()[2] = 0xAD;
+ output->payload()[3] = 0xDE;
+ output->payload()[4] = token & 0xFF;
+ output->payload()[5] = (token >> 8) & 0xFF;
+ output->payload()[6] = (token >> 16) & 0xFF;
+ output->payload()[7] = (token >> 24) & 0xFF;
sendCANFrame(output);
}
else //stop anything in process
diff --git a/framefileio.cpp b/framefileio.cpp
index 71e21c4..741d8b1 100644
--- a/framefileio.cpp
+++ b/framefileio.cpp
@@ -50,7 +50,7 @@ bool FrameFileIO::saveFrameFile(QString &fileName, const QVector* fram
QProgressDialog progress(qApp->activeWindow());
progress.setWindowModality(Qt::WindowModal);
progress.setLabelText("Saving file...");
- progress.setCancelButton(0);
+ progress.setCancelButton(nullptr);
progress.setRange(0,0);
progress.setMinimumDuration(0);
progress.show();
@@ -155,6 +155,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache
filters.append(QString(tr("CAN-DO Log (*.avc *.can *.evc *.qcc *.AVC *.CAN *.EVC *.QCC)")));
filters.append(QString(tr("Vehicle Spy (*.csv *.CSV)")));
filters.append(QString(tr("Candump/Kayak (*.log *.LOG)")));
+ filters.append(QString(tr("CANDump Lawicel (*.txt *.TXT *.LOG *.log)")));
filters.append(QString(tr("PCAN Viewer (*.trc *.TRC)")));
filters.append(QString(tr("Kvaser Log Decimal (*.txt *.TXT)")));
filters.append(QString(tr("Kvaser Log Hex (*.txt *.TXT)")));
@@ -176,7 +177,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache
QProgressDialog progress(qApp->activeWindow());
progress.setWindowModality(Qt::WindowModal);
progress.setLabelText("Loading file...");
- progress.setCancelButton(0);
+ progress.setCancelButton(nullptr);
progress.setRange(0,0);
progress.setMinimumDuration(0);
progress.show();
@@ -194,14 +195,15 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache
if (dialog.selectedNameFilter() == filters[8]) result = loadCANDOFile(filename, frameCache);
if (dialog.selectedNameFilter() == filters[9]) result = loadVehicleSpyFile(filename, frameCache);
if (dialog.selectedNameFilter() == filters[10]) result = loadCanDumpFile(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[11]) result = loadPCANFile(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[12]) result = loadKvaserFile(filename, frameCache, false);
- if (dialog.selectedNameFilter() == filters[13]) result = loadKvaserFile(filename, frameCache, true);
- if (dialog.selectedNameFilter() == filters[14]) result = loadCanalyzerASC(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[15]) result = loadCanalyzerBLF(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[16]) result = loadCANHackerFile(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[17]) result = loadCabanaFile(filename, frameCache);
- if (dialog.selectedNameFilter() == filters[18]) result = loadCANOpenFile(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[11]) result = loadLawicelFile(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[12]) result = loadPCANFile(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[13]) result = loadKvaserFile(filename, frameCache, false);
+ if (dialog.selectedNameFilter() == filters[14]) result = loadKvaserFile(filename, frameCache, true);
+ if (dialog.selectedNameFilter() == filters[15]) result = loadCanalyzerASC(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[16]) result = loadCanalyzerBLF(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[17]) result = loadCANHackerFile(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[18]) result = loadCabanaFile(filename, frameCache);
+ if (dialog.selectedNameFilter() == filters[19]) result = loadCANOpenFile(filename, frameCache);
progress.cancel();
@@ -229,6 +231,7 @@ bool FrameFileIO::loadFrameFile(QString &fileName, QVector* frameCache
//whether a file could be loaded or not by a given loader. The loader return is still used in case the guess was wrong.
bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames)
{
+ qDebug() << "Attempting Canalyzer BLF";
if (isCanalyzerBLF(filename))
{
if (loadCanalyzerBLF(filename, frames))
@@ -238,6 +241,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting native CSV";
if (isNativeCSVFile(filename))
{
if (loadNativeCSVFile(filename, frames))
@@ -247,6 +251,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting canalyzer ASC";
if (isCanalyzerASC(filename))
{
if (loadCanalyzerASC(filename, frames))
@@ -256,6 +261,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting CRTD";
if (isCRTDFile(filename))
{
if (loadCRTDFile(filename, frames))
@@ -266,6 +272,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
+ qDebug() << "Attempting trace file";
if (isTraceFile(filename))
{
if (loadTraceFile(filename, frames))
@@ -275,6 +282,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting vehicle spy";
if (isVehicleSpyFile(filename))
{
if (loadVehicleSpyFile(filename, frames))
@@ -284,6 +292,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting candump";
if (isCanDumpFile(filename))
{
if (loadCanDumpFile(filename, frames))
@@ -293,6 +302,17 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting lawicel";
+ if (isLawicelFile(filename))
+ {
+ if (loadLawicelFile(filename, frames))
+ {
+ qDebug() << "Loaded as lawicel successfully!";
+ return true;
+ }
+ }
+
+ qDebug() << "Attempting canhacker";
if (isCANHackerFile(filename))
{
if (loadCANHackerFile(filename, frames))
@@ -302,6 +322,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting cabana";
if (isCabanaFile(filename))
{
if (loadCabanaFile(filename, frames))
@@ -311,6 +332,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting canopen";
if (isCANOpenFile(filename))
{
if (loadCANOpenFile(filename, frames))
@@ -320,6 +342,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting busmaster log";
if (isLogFile(filename))
{
if (loadLogFile(filename, frames))
@@ -329,6 +352,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting pcan";
if (isPCANFile(filename))
{
if (loadPCANFile(filename, frames))
@@ -338,6 +362,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting ixxat";
if (isIXXATFile(filename))
{
if (loadIXXATFile(filename, frames))
@@ -347,6 +372,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting microchip";
if (isMicrochipFile(filename))
{
if (loadMicrochipFile(filename, frames))
@@ -356,6 +382,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting CANDo";
if (isCANDOFile(filename))
{
if (loadCANDOFile(filename, frames))
@@ -365,6 +392,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting kvaser";
if (isKvaserFile(filename))
{
if (loadKvaserFile(filename, frames,true))
@@ -379,6 +407,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Attempting generic CSV";
if (isGenericCSVFile(filename))
{
if (loadGenericCSVFile(filename, frames))
@@ -388,6 +417,7 @@ bool FrameFileIO::autoDetectLoadFile(QString filename, QVector* frames
}
}
+ qDebug() << "Nothing worked... sorry...";
return false;
}
@@ -424,7 +454,7 @@ bool FrameFileIO::isVehicleSpyFile(QString filename)
QList tokens = line.split(',');
if (tokens.length() > 20)
{
- if (tokens[9].toInt(NULL, 16) > 0) isMatch = true;
+ if (tokens[9].toInt(nullptr, 16) > 0) isMatch = true;
}
}
}
@@ -481,26 +511,25 @@ bool FrameFileIO::loadVehicleSpyFile(QString filename, QVector *frames
if (tokens.length() > 20)
{
thisFrame.bus = 0;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
tempTime = now;
- tempTime.addMSecs(tokens[1].toDouble() * 1000.0);
- thisFrame.timestamp = tempTime.toMSecsSinceEpoch() * 1000ul;
+ tempTime = tempTime.addMSecs(static_cast(tokens[1].toDouble() * 1000.0));
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(tempTime.toMSecsSinceEpoch() * 1000)));
if (tokens[5].startsWith("T")) thisFrame.isReceived = false;
else thisFrame.isReceived = true;
- thisFrame.ID = tokens[9].toInt(NULL, 16);
- if (tokens[11].startsWith("T")) thisFrame.extended = true;
- else thisFrame.extended = false;
-
- thisFrame.len = 0;
+ thisFrame.setFrameId(static_cast(tokens[9].toInt(nullptr, 16)));
+ if (tokens[11].startsWith("T")) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
+ QByteArray bytes;
for (int i = 0; i < 8; i++)
{
if (tokens[12 + i].length() > 0)
{
- thisFrame.data[i] = tokens[12 + i].toInt(NULL, 16);
- thisFrame.len++;
+ bytes.append(static_cast(tokens[12 + i].toInt(nullptr, 16)));
}
else break;
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -637,7 +666,7 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector* frames)
multiplier = 1; //special case. Assume no decimal means microseconds
}
//qDebug() << "decimal places " << decimalPlaces;
- thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * multiplier);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast((tokens[0].toDouble() * multiplier))));
thisFrame.bus = 0;
char firstChar = tokens[1].left(1)[0];
if (firstChar >= '1' && firstChar <= '9')
@@ -648,21 +677,22 @@ bool FrameFileIO::loadCRTDFile(QString filename, QVector* frames)
}
if (firstChar == 'R' || firstChar == 'T')
{
- thisFrame.ID = tokens[2].toInt(NULL, 16);
- if (tokens[1] == "R29" || tokens[1] == "T29") thisFrame.extended = true;
- else thisFrame.extended = false;
+ thisFrame.setFrameId(static_cast(tokens[2].toInt(nullptr, 16)));
+ if (tokens[1] == "R29" || tokens[1] == "T29") thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
if (firstChar == 'T') thisFrame.isReceived = false;
else thisFrame.isReceived = true;
- thisFrame.len = tokens.length() - 3;
- thisFrame.remote = false;
- for (unsigned int d = 0; d < thisFrame.len; d++)
+ QByteArray bytes(tokens.length() - 3, 0);
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ for (int d = 0; d < bytes.length(); d++)
{
if (tokens[d + 3] != "")
{
- thisFrame.data[d] = tokens[d + 3].toInt(NULL, 16);
+ bytes[d] = static_cast(tokens[d + 3].toInt(nullptr, 16));
}
- else thisFrame.data[d] = 0;
+ else bytes[d] = 0;
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
}
@@ -700,7 +730,7 @@ bool FrameFileIO::isCANHackerFile(QString filename)
QList tokens = line.split(' ');
if (tokens.length() > 3)
{
- if (tokens[1].toInt(NULL, 16) > 0)
+ if (tokens[1].toInt(nullptr, 16) > 0)
{
int len = tokens[2].toInt();
if (len > -1 && len < 9)
@@ -768,21 +798,22 @@ bool FrameFileIO::loadCANHackerFile(QString filename, QVector* frames)
multiplier = 1; //special case. Assume no decimal means microseconds
}
//qDebug() << "decimal places " << decimalPlaces;
- thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * multiplier);
- thisFrame.ID = tokens[1].toInt(NULL, 16);
- thisFrame.extended = (thisFrame.ID > 0x7FF);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(tokens[0].toDouble() * multiplier)));
+ thisFrame.setFrameId( static_cast(tokens[1].toInt(nullptr, 16)) );
+ thisFrame.setExtendedFrameFormat((thisFrame.frameId() > 0x7FF));
thisFrame.isReceived = true;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
thisFrame.bus = 0;
- thisFrame.len = tokens[2].toInt(NULL, 16);
- for (unsigned int d = 0; d < thisFrame.len; d++)
+ QByteArray bytes( tokens[2].toInt(nullptr, 16), 0);
+ for (int d = 0; d < thisFrame.payload().length(); d++)
{
if (tokens[d + 3] != "")
{
- thisFrame.data[d] = tokens[d + 3].toInt(NULL, 16);
+ bytes[d] = static_cast(tokens[d + 3].toInt(nullptr, 16));
}
- else thisFrame.data[d] = 0;
+ else bytes[d] = 0;
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -884,22 +915,23 @@ bool FrameFileIO::loadCANOpenFile(QString filename, QVector* frames)
QList tokens = line.split(',');
if (tokens.length() > 11)
{
- thisFrame.timestamp = (int64_t)(tokens[1].simplified().toDouble() * 1000.0);
- thisFrame.ID = Utility::ParseStringToNum(tokens[5].simplified());
- thisFrame.extended = (thisFrame.ID > 0x7FF);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(tokens[1].simplified().toDouble() * 1000.0)));
+ thisFrame.setFrameId(static_cast(Utility::ParseStringToNum(tokens[5].simplified())));
+ thisFrame.setExtendedFrameFormat( (thisFrame.frameId() > 0x7FF) );
thisFrame.isReceived = true;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
thisFrame.bus = 0;
QList dataTok = tokens[11].simplified().split(' ');
- thisFrame.len = dataTok.length();
- for (unsigned int d = 0; d < thisFrame.len; d++)
+ QByteArray bytes(dataTok.length(), 0);
+ for (int d = 0; d < thisFrame.payload().length(); d++)
{
if (dataTok[d] != "")
{
- thisFrame.data[d] = dataTok[d].simplified().toInt(NULL, 16);
+ bytes[d] = static_cast(dataTok[d].simplified().toInt(nullptr, 16));
}
- else thisFrame.data[d] = 0;
+ else bytes[d] = 0;
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -915,6 +947,10 @@ bool FrameFileIO::saveCRTDFile(QString filename, const QVector* frames
QFile *outFile = new QFile(filename);
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
{
delete outFile;
@@ -922,7 +958,7 @@ bool FrameFileIO::saveCRTDFile(QString filename, const QVector* frames
}
//write in float format with 6 digits after the decimal point
- outFile->write(QString::number(frames->at(0).timestamp / 1000000.0, 'f', 6).toUtf8() + tr(" CXX GVRET-PC Reverse Engineering Tool Output V").toUtf8() + QString::number(VERSION).toUtf8());
+ outFile->write(QString::number(frames->at(0).timeStamp().microSeconds() / 1000000.0, 'f', 6).toUtf8() + tr(" CXX GVRET-PC Reverse Engineering Tool Output V").toUtf8() + QString::number(VERSION).toUtf8());
outFile->write("\n");
for (int c = 0; c < frames->count(); c++)
@@ -934,24 +970,28 @@ bool FrameFileIO::saveCRTDFile(QString filename, const QVector* frames
lineCounter = 0;
}
- outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8());
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ outFile->write(QString::number(frame->timeStamp().microSeconds() / 1000000.0, 'f', 6).toUtf8());
outFile->putChar(' ');
- outFile->write(QString::number(frames->at(c).bus + 1).toUtf8());
- if (frames->at(c).isReceived) outFile->putChar('R');
+ outFile->write(QString::number(frame->bus + 1).toUtf8());
+ if (frame->isReceived) outFile->putChar('R');
else outFile->putChar('T');
- if (frames->at(c).extended)
+ if (frame->hasExtendedFrameFormat())
{
outFile->write("29 ");
}
else outFile->write("11 ");
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(' ');
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
@@ -993,7 +1033,7 @@ bool FrameFileIO::isPCANFile(QString filename)
{
if (fileVersion == 1)
{
- int id = line.mid(28, 8).simplified().toUInt(NULL, 16);
+ uint32_t id = line.mid(28, 8).simplified().toUInt(nullptr, 16);
if (id > 0 && id < 0x1FFFFFFF)
{
int len = line.mid(38,1).toInt();
@@ -1004,7 +1044,7 @@ bool FrameFileIO::isPCANFile(QString filename)
else if (fileVersion == 2)
{
- int id = line.mid(25, 8).simplified().toUInt(NULL, 16);
+ uint32_t id = line.mid(25, 8).simplified().toUInt(nullptr, 16);
if (id > 0 && id < 0x1FFFFFFF)
{
int len = line.mid(37,2).trimmed().toInt();
@@ -1082,65 +1122,67 @@ bool FrameFileIO::loadPCANFile(QString filename, QVector* frames)
{
if (fileVersion == 1)
{
- thisFrame.timestamp = (uint64_t)(line.mid(10, 8).simplified().toDouble() * 1000.0);
- thisFrame.ID = line.mid(28, 8).simplified().toUInt(NULL, 16);
- if (thisFrame.ID < 0x1FFFFFFF)
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, (uint64_t)(line.mid(10, 8).simplified().toDouble() * 1000.0)));
+ thisFrame.setFrameId(line.mid(28, 8).simplified().toUInt(nullptr, 16));
+ if (thisFrame.frameId() < 0x1FFFFFFF)
{
- thisFrame.len = line.mid(38,1).toInt();
+ QByteArray bytes(line.mid(38,1).toInt(), 0);
thisFrame.isReceived = true;
thisFrame.bus = 0;
if (line.at(28) == ' ') {
- thisFrame.extended = false;
+ thisFrame.setExtendedFrameFormat(false);
} else {
- thisFrame.extended = true;
+ thisFrame.setExtendedFrameFormat(true);
}
if (line.at(41) == 'R') {
- thisFrame.remote = true;
+ thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else {
- QList tokens = line.mid(41, thisFrame.len * 3).split(' ');
- thisFrame.remote = false;
- for (unsigned int d = 0; d < thisFrame.len; d++)
+ QList tokens = line.mid(41, thisFrame.payload().length() * 3).split(' ');
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ for (int d = 0; d < thisFrame.payload().length(); d++)
{
if (tokens[d] != "")
{
- thisFrame.data[d] = tokens[d].toInt(NULL, 16);
+ bytes[d] = static_cast(tokens[d].toInt(nullptr, 16));
}
- else thisFrame.data[d] = 0;
+ else bytes[d] = 0;
}
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
}
else if (fileVersion == 2)
{
- thisFrame.timestamp = (uint64_t)(line.mid(8, 13).simplified().toDouble() * 1000.0);
- thisFrame.ID = line.mid(25, 8).simplified().toUInt(NULL, 16);
- if (thisFrame.ID < 0x1FFFFFFF)
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(line.mid(8, 13).simplified().toDouble() * 1000.0)));
+ thisFrame.setFrameId(line.mid(25, 8).simplified().toUInt(nullptr, 16));
+ if (thisFrame.frameId() < 0x1FFFFFFF)
{
- thisFrame.len = line.mid(37,2).trimmed().toInt();
- qDebug() << thisFrame.len;
+ QByteArray bytes(line.mid(37,2).trimmed().toInt(), 0);
+ qDebug() << thisFrame.payload().length();
thisFrame.isReceived = true;
thisFrame.bus = 0;
if (line.at(25) == ' ') {
- thisFrame.extended = false;
+ thisFrame.setExtendedFrameFormat(false);
} else {
- thisFrame.extended = true;
+ thisFrame.setExtendedFrameFormat(true);
}
if (line.at(40) == 'R') {
- thisFrame.remote = true;
+ thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else {
- QList tokens = line.mid(40, thisFrame.len * 3).split(' ');
- thisFrame.remote = false;
- for (unsigned int d = 0; d < thisFrame.len; d++)
+ QList tokens = line.mid(40, thisFrame.payload().length() * 3).split(' ');
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ for (int d = 0; d < thisFrame.payload().length(); d++)
{
if (tokens[d] != "")
{
- thisFrame.data[d] = tokens[d].toInt(NULL, 16);
+ bytes[d] = static_cast(tokens[d].toInt(nullptr, 16));
}
- else thisFrame.data[d] = 0;
+ else bytes[d] = 0;
}
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
}
@@ -1157,7 +1199,7 @@ bool FrameFileIO::isCanalyzerASC(QString filename)
QFile *inFile = new QFile(filename);
QByteArray line;
int lineCounter = 0;
- bool isMatch = true;
+ bool isMatch = false;
bool inHeader = true;
QList tokens;
@@ -1190,17 +1232,15 @@ bool FrameFileIO::isCanalyzerASC(QString filename)
tokens = line.simplified().split(' ');
if (tokens.length() > 5)
{
- uint64_t time = (uint64_t)(tokens[0].toDouble() * (double)1000000.0);
- if (time <= 0) isMatch = false;
- int id = tokens[2].toUInt(NULL, 16);
- if (id < 1 || id > 0x1FFFFFFF) isMatch = false;
- int len = tokens[5].toUInt();
- if (len < 0 || len > 8) isMatch = false;
- if (tokens.count() < (len + 6)) isMatch = false;
+ uint64_t time = static_cast(tokens[0].toDouble() * 1000000.0);
+ if (time > 0) isMatch = true;
+ uint32_t id = static_cast(tokens[2].toUInt(nullptr, 16));
+ if (id > 0 && id < 0x20000000) isMatch = true;
+ int len = tokens[5].toInt();
+ if (len > 0 && len < 9) isMatch = true;
+ if (tokens.count() >= (len + 6)) isMatch = true;
}
- else isMatch = false;
}
- else isMatch = false;
}
}
catch (...)
@@ -1227,7 +1267,7 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames)
int lineCounter = 0;
bool foundErrors = false;
bool inHeader = true;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
QList tokens;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
@@ -1258,26 +1298,38 @@ bool FrameFileIO::loadCanalyzerASC(QString filename, QVector* frames)
tokens = line.simplified().split(' ');
if (tokens.length() > 5)
{
- thisFrame.timestamp = (uint64_t)(tokens[0].toDouble() * (double)1000000.0);
- thisFrame.ID = tokens[2].toUInt(NULL, 16);
- thisFrame.len = tokens[5].toUInt();
- if (thisFrame.len > 8) return false;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(tokens[0].toDouble() * 1000000.0)));
+ if (tokens[2].endsWith('x'))
+ {
+ QByteArray copied_id = tokens[2];
+ copied_id.chop(1);
+ thisFrame.setFrameId(copied_id.toUInt(nullptr, 16));
+ thisFrame.setExtendedFrameFormat(true);
+ }
+ else
+ {
+ thisFrame.setFrameId(tokens[2].toUInt(nullptr, 16));
+ thisFrame.setExtendedFrameFormat(false);
+ }
+ QByteArray bytes(tokens[5].toInt(), 0);
+ if (thisFrame.payload().length() > 8) return false;
+ if (thisFrame.payload().length() < 0) return false;
thisFrame.isReceived = tokens[3].toUpper().contains("RX");
- thisFrame.bus = tokens[1].toUInt();
- thisFrame.extended = (thisFrame.ID > 0x7FF);
- thisFrame.remote = false;
- for (unsigned int d = 6; d < (6 + thisFrame.len); d++)
+ thisFrame.bus = tokens[1].toInt();
+ if (tokens[4] == "r") thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
+ for (int d = 6; d < (6 + static_cast(thisFrame.payload().length())); d++)
{
if (tokens.count() > d)
{
- thisFrame.data[d - 6] = tokens[d].toInt(NULL, 16);
+ bytes[d - 6] = static_cast(tokens[d].toInt(nullptr, 16));
}
else //expected byte wasn't there to read. Set it zero and set error flag
{
- thisFrame.data[d - 6] = 0;
+ bytes[d - 6] = 0;
foundErrors = true;
}
}
+ thisFrame.setPayload(bytes);
}
frames->append(thisFrame);
}
@@ -1292,10 +1344,15 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr
{
QFile *outFile = new QFile(filename);
int lineCounter = 0;
- uint64_t offsetTime = frames->at(0).timestamp;
+ int64_t offsetTime = frames->at(0).timeStamp().microSeconds();
+
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
for (int c = 0; c < frames->count(); c++)
{
- if (frames->at(c).timestamp < offsetTime) offsetTime = frames->at(c).timestamp;
+ if (frames->at(c).timeStamp().microSeconds() < offsetTime) offsetTime = frames->at(c).timeStamp().microSeconds();
}
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -1325,34 +1382,44 @@ bool FrameFileIO::saveCanalyzerASC(QString filename, const QVector* fr
lineCounter = 0;
}
- uint64_t timeStamp = (frames->at(c).timestamp - offsetTime) / 1000000ull;
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ uint64_t timeStamp = (frame->timeStamp().microSeconds() - offsetTime) / 1000000ull;
int tsLen = QString::number(timeStamp).length();
int precision = 6;
//vector seems to keep 10 bytes at the start of the line for the timestamp. It should never exceed this
//and there should never be a precision over 6 digits after the decimal
if (tsLen > 3) precision = 9 - tsLen;
- outFile->write(QString::number((frames->at(c).timestamp - offsetTime) / 1000000.0, 'f', precision).rightJustified(10, ' ').toUtf8());
+ outFile->write(QString::number((frame->timeStamp().microSeconds() - offsetTime) / 1000000.0, 'f', precision).rightJustified(10, ' ').toUtf8());
outFile->putChar(' ');
- outFile->write(QString::number(frames->at(c).bus + 1).toUtf8());
+ outFile->write(QString::number(frame->bus + 1).toUtf8());
outFile->write(" ");
- if (frames->at(c).extended)
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ if (frames->at(c).hasExtendedFrameFormat())
+ {
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
+ outFile->write("x");
+ }
else
{
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(3, '0').toUtf8());
- outFile->write(" ");
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(3, '0').toUtf8());
+ outFile->write(" ");
}
outFile->write(" ");
- if (frames->at(c).isReceived) outFile->write("Rx D ");
- else outFile->write("Tx D ");
+ if (frames->at(c).isReceived) outFile->write("Rx ");
+ else outFile->write("Tx ");
- outFile->write(QString::number(frames->at(c).len).toUtf8());
+ if (frames->at(c).frameType() == QCanBusFrame::RemoteRequestFrame) outFile->write("r ");
+ else outFile->write("d ");
+
+ outFile->write(QString::number(dataLen).toUtf8());
outFile->write(" ");
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->write(" ");
}
@@ -1376,7 +1443,7 @@ bool FrameFileIO::isCanalyzerBLF(QString filename)
delete inFile;
return false;
}
- inFile->read((char *)&header, sizeof(header));
+ inFile->read(reinterpret_cast(&header), sizeof(header));
if (qFromLittleEndian(header.sig) == 0x47474F4C)
{
qDebug() << "Proper BLF file header token";
@@ -1458,10 +1525,10 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector* frames)
CANFrame thisFrame;
QByteArray line;
int fileVersion = 1;
- long long timeStamp = Utility::GetTimeMS();
+ uint64_t timeStamp = Utility::GetTimeMS();
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -1488,43 +1555,48 @@ bool FrameFileIO::loadNativeCSVFile(QString filename, QVector* frames)
{
if (tokens[0].length() > 3)
{
- long long temp = tokens[0].toLongLong();
- thisFrame.timestamp = temp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, tokens[0].toULongLong()));
}
else
{
timeStamp += 5;
- thisFrame.timestamp = timeStamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
}
- thisFrame.ID = tokens[1].toInt(NULL, 16);
- if (tokens[2].toUpper().contains("TRUE")) thisFrame.extended = 1;
- else thisFrame.extended = 0;
+ thisFrame.setFrameId(tokens[1].toUInt(nullptr, 16));
+ if (tokens[2].toUpper().contains("TRUE")) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (fileVersion == 1)
{
thisFrame.isReceived = true;
thisFrame.bus = tokens[3].toInt();
- thisFrame.len = tokens[4].toUInt();
- if (thisFrame.len > 8) thisFrame.len = 8;
- for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
- if (thisFrame.len + 5 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 5;
- for (unsigned int d = 0; d < thisFrame.len; d++)
- thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
+ int lng = tokens[4].toInt();
+ if (lng > 8) lng = 8;
+ if (lng < 0) lng = 0;
+ if (lng + 5 > tokens.length()) lng = tokens.length() - 5;
+ QByteArray bytes(lng, 0);
+ for (int c = 0; c < 8; c++) bytes[c] = 0;
+ for (int d = 0; d < thisFrame.payload().length(); d++)
+ bytes[d] = static_cast(tokens[5 + d].toInt(nullptr, 16));
+ thisFrame.setPayload(bytes);
}
else if (fileVersion == 2)
{
if (tokens[3].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
- thisFrame.bus = tokens[4].toInt();
- thisFrame.len = tokens[5].toUInt();
- if (thisFrame.len > 8) thisFrame.len = 8;
- if (thisFrame.len + 6 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 6;
- for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
- for (unsigned int d = 0; d < thisFrame.len; d++)
- thisFrame.data[d] = tokens[6 + d].toInt(NULL, 16);
+ thisFrame.bus = tokens[4].toInt();
+ int lng = tokens[5].toInt();
+ if (lng > 8) lng = 8;
+ if (lng < 0) lng = 0;
+ if (lng + 6 > tokens.length()) lng = tokens.length() - 6;
+ QByteArray bytes(lng, 0);
+ for (int c = 0; c < 8; c++) bytes[c] = 0;
+ for (int d = 0; d < thisFrame.payload().length(); d++)
+ bytes[d] = static_cast(tokens[6 + d].toInt(nullptr, 16));
+ thisFrame.setPayload(bytes);
}
frames->append(thisFrame);
@@ -1542,6 +1614,10 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector* f
QFile *outFile = new QFile(filename);
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
{
delete outFile;
@@ -1560,28 +1636,32 @@ bool FrameFileIO::saveNativeCSVFile(QString filename, const QVector* f
lineCounter = 0;
}
- outFile->write(QString::number(frames->at(c).timestamp).toUtf8());
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ outFile->write(QString::number(frame->timeStamp().microSeconds()).toUtf8());
outFile->putChar(44);
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(44);
- if (frames->at(c).extended) outFile->write("true,");
+ if (frame->hasExtendedFrameFormat()) outFile->write("true,");
else outFile->write("false,");
- if (frames->at(c).isReceived) outFile->write("Rx,");
+ if (frame->isReceived) outFile->write("Rx,");
else outFile->write("Tx,");
- outFile->write(QString::number(frames->at(c).bus).toUtf8());
+ outFile->write(QString::number(frame->bus).toUtf8());
outFile->putChar(44);
- outFile->write(QString::number(frames->at(c).len).toUtf8());
+ outFile->write(QString::number(dataLen).toUtf8());
outFile->putChar(44);
- for (unsigned int temp = 0; temp < 8; temp++)
+ for (int temp = 0; temp < 8; temp++)
{
- if (temp < frames->at(c).len)
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ if (temp < dataLen)
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
else
outFile->write("00");
outFile->putChar(44);
@@ -1639,32 +1719,41 @@ bool FrameFileIO::closeContinuousNative()
bool FrameFileIO::writeContinuousNative(const QVector* frames, int beginningFrame)
{
+
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
if (!continuousFile.isOpen()) return false;
qDebug() << "Bgn: " << beginningFrame << " Count: " << frames->count();
for (int c = beginningFrame; c < frames->count(); c++)
{
- continuousFile.write(QString::number(frames->at(c).timestamp).toUtf8());
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ continuousFile.write(QString::number(frame->timeStamp().microSeconds()).toUtf8());
continuousFile.putChar(44);
- continuousFile.write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ continuousFile.write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
continuousFile.putChar(44);
- if (frames->at(c).extended) continuousFile.write("true,");
+ if (frame->hasExtendedFrameFormat()) continuousFile.write("true,");
else continuousFile.write("false,");
- if (frames->at(c).isReceived) continuousFile.write("Rx,");
+ if (frame->isReceived) continuousFile.write("Rx,");
else continuousFile.write("Tx,");
- continuousFile.write(QString::number(frames->at(c).bus).toUtf8());
+ continuousFile.write(QString::number(frame->bus).toUtf8());
continuousFile.putChar(44);
- continuousFile.write(QString::number(frames->at(c).len).toUtf8());
+ continuousFile.write(QString::number(dataLen).toUtf8());
continuousFile.putChar(44);
- for (unsigned int temp = 0; temp < 8; temp++)
+ for (int temp = 0; temp < 8; temp++)
{
- if (temp < frames->at(c).len)
- continuousFile.write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ if (temp < dataLen)
+ continuousFile.write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
else
continuousFile.write("00");
continuousFile.putChar(44);
@@ -1706,7 +1795,7 @@ bool FrameFileIO::isGenericCSVFile(QString filename)
{
QList tokens = line.split(',');
- int ID = tokens[0].toInt(NULL, 16);
+ int ID = tokens[0].toInt(nullptr, 16);
if (ID < 1 || ID > 0x1FFFFFFF) isMatch = false;
if (tokens.count() < 2)
@@ -1739,10 +1828,10 @@ bool FrameFileIO::loadGenericCSVFile(QString filename, QVector* frames
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
- long long timeStamp = Utility::GetTimeMS();
+ uint64_t timeStamp = Utility::GetTimeMS();
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -1766,17 +1855,16 @@ bool FrameFileIO::loadGenericCSVFile(QString filename, QVector* frames
QList tokens = line.split(',');
timeStamp += 5000;
- thisFrame.timestamp = timeStamp;
- thisFrame.ID = tokens[0].toInt(NULL, 16);
- if (thisFrame.ID > 0x7FF) thisFrame.extended = true;
- else thisFrame.extended = false;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
+ thisFrame.setFrameId(tokens[0].toUInt(nullptr, 16));
+ if (thisFrame.frameId() > 0x7FF) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
thisFrame.bus = 0;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
QList dataTok = tokens[1].split(' ');
- thisFrame.len = dataTok.length();
- if (thisFrame.len > 8) thisFrame.len = 8;
- for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataTok[d].toInt(NULL, 16);
-
+ QByteArray bytes(dataTok.length(), 0);
+ for (int d = 0; d < thisFrame.payload().length(); d++) bytes[d] = static_cast(dataTok[d].toInt(nullptr, 16));
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -1792,6 +1880,10 @@ bool FrameFileIO::saveGenericCSVFile(QString filename, const QVector*
QFile *outFile = new QFile(filename);
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
{
delete outFile;
@@ -1810,12 +1902,16 @@ bool FrameFileIO::saveGenericCSVFile(QString filename, const QVector*
lineCounter = 0;
}
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(44);
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
@@ -1859,10 +1955,10 @@ bool FrameFileIO::isLogFile(QString filename)
QList timeToks = tokens[0].split(':');
if (timeToks.count() != 4) isMatch = false;
- int ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
+ int ID = tokens[3].right(tokens[3].length() - 2).toInt(nullptr, 16);
if (ID < 1 || ID > 0x1FFFFFFF) isMatch = false;
if (tokens[4] != "S" && tokens[4] != "X" && tokens[4] != "SR" && tokens[4] != "XR") isMatch = false;
- int len = tokens[5].toUInt();
+ int len = tokens[5].toInt();
if (len > 8) isMatch = false;
}
else isMatch = false;
@@ -1944,32 +2040,36 @@ bool FrameFileIO::loadLogFile(QString filename, QVector* frames)
if (tokens.length() >= 6)
{
QList timeToks = tokens[0].split(':');
- timeStamp = (timeToks[0].toInt() * (1000ul * 1000ul * 60ul * 60ul)) + (timeToks[1].toInt() * (1000ul * 1000ul * 60ul))
- + (timeToks[2].toInt() * (1000ul * 1000ul)) + (timeToks[3].toInt() * 100ul);
- thisFrame.timestamp = timeStamp;
+ timeStamp = (timeToks[0].toUInt() * (1000ul * 1000ul * 60ul * 60ul)) + (timeToks[1].toUInt() * (1000ul * 1000ul * 60ul))
+ + (timeToks[2].toUInt() * (1000ul * 1000ul)) + (timeToks[3].toUInt() * 100ul);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
if (tokens[1].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
- thisFrame.ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
+ thisFrame.setFrameId(tokens[3].right(tokens[3].length() - 2).toUInt(nullptr, 16));
if (tokens[4] == "S") {
- thisFrame.extended = false;
- thisFrame.remote = false;
+ thisFrame.setExtendedFrameFormat(false);
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
} else if (tokens[4] == "X") {
- thisFrame.extended = true;
- thisFrame.remote = false;
+ thisFrame.setExtendedFrameFormat(true);
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
} else if (tokens[4] == "SR") {
- thisFrame.extended = false;
- thisFrame.remote = true;
+ thisFrame.setExtendedFrameFormat(false);
+ thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else { // XR
- thisFrame.extended = true;
- thisFrame.remote = true;
+ thisFrame.setExtendedFrameFormat(true);
+ thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
}
thisFrame.bus = tokens[2].toInt() - 1;
- thisFrame.len = tokens[5].toUInt();
- if (thisFrame.len > 8) thisFrame.len = 8;
- if (!thisFrame.remote) {
- for (unsigned int d = 0; d < thisFrame.len; d++)
- thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
+
+ int lng = tokens[5].toInt();
+ if (lng > 8) lng = 8;
+ if (lng < 0) lng = 0;
+ QByteArray bytes(lng, 0);
+ if (thisFrame.frameType() != QCanBusFrame::RemoteRequestFrame) {
+ for (int d = 0; d < thisFrame.payload().length(); d++)
+ bytes[d] = static_cast(tokens[d + 6].toInt(nullptr, 16));
}
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -1986,6 +2086,10 @@ bool FrameFileIO::saveLogFile(QString filename, const QVector* frames)
QDateTime timestamp, tempStamp;
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
//timestamp = QDateTime::currentDateTime();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -2019,28 +2123,32 @@ bool FrameFileIO::saveLogFile(QString filename, const QVector* frames)
lineCounter = 0;
}
- tempStamp = QDateTime::fromMSecsSinceEpoch(frames->at(c).timestamp / 1000);
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ tempStamp = QDateTime::fromMSecsSinceEpoch(frame->timeStamp().microSeconds() / 1000);
outFile->write(tempStamp.toString("hh:mm:ss:zzz").toUtf8());
- if (frames->at(c).isReceived) outFile->write(" Rx ");
+ if (frame->isReceived) outFile->write(" Rx ");
else outFile->write(" Tx ");
// busmaster channel start at 1
- outFile->write(QString::number(frames->at(c).bus+1).toUtf8() + " ");
+ outFile->write(QString::number(frame->bus + 1).toUtf8() + " ");
outFile->write("0x");
- if (frames->at(c).extended && frames->at(c).ID > 0x7FF) {
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
+ if (frame->hasExtendedFrameFormat() && frame->frameId() > 0x7FF) {
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8());
} else {
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(3, '0').toUtf8());
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(3, '0').toUtf8());
}
- if (frames->at(c).extended) outFile->write(" x");
+ if (frame->hasExtendedFrameFormat()) outFile->write(" x");
else outFile->write(" s");
- if (frames->at(c).remote) outFile->write("r ");
+ if (frame->frameType() == QCanBusFrame::RemoteRequestFrame) outFile->write("r ");
else outFile->write(" ");
- outFile->write(QString::number(frames->at(c).len).toUtf8() + " ");
+ outFile->write(QString::number(dataLen).toUtf8() + " ");
- if (!frames->at(c).remote) {
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ if (frame->frameType() != QCanBusFrame::RemoteRequestFrame) {
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
}
@@ -2097,7 +2205,7 @@ bool FrameFileIO::loadIXXATFile(QString filename, QVector* frames)
uint64_t timeStamp = Utility::GetTimeMS();
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -2125,8 +2233,8 @@ bool FrameFileIO::loadIXXATFile(QString filename, QVector* frames)
QStringList timeToks = timePortion.split(':');
if (timeToks.length() >= 3)
{
- timeStamp = (timeToks[0].toInt() * (1000ul * 1000ul * 60ul * 60ul)) + (timeToks[1].toInt() * (1000ul * 1000ul * 60ul))
- + (timeToks[2].toDouble() * (1000.0 * 1000.0));
+ timeStamp = (timeToks[0].toUInt() * (1000ul * 1000ul * 60ul * 60ul)) + (timeToks[1].toUInt() * (1000ul * 1000ul * 60ul))
+ + static_cast(timeToks[2].toDouble() * (1000.0 * 1000.0));
}
else
{
@@ -2134,29 +2242,30 @@ bool FrameFileIO::loadIXXATFile(QString filename, QVector* frames)
foundErrors = true;
return false;
}
- thisFrame.timestamp = timeStamp;
- thisFrame.ID = Utility::unQuote(tokens[1]).toInt(NULL, 16);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
+ thisFrame.setFrameId(Utility::unQuote(tokens[1]).toUInt(nullptr, 16));
QString tempStr = Utility::unQuote(tokens[2]).toUpper();
if (tempStr.length() > 0)
{
- if (tempStr.at(0) == 'S') thisFrame.extended = false;
- else thisFrame.extended = true;
+ if (tempStr.at(0) == 'S') thisFrame.setExtendedFrameFormat(false);
+ else thisFrame.setExtendedFrameFormat(true);
}
else
{
- thisFrame.extended = false;
+ thisFrame.setExtendedFrameFormat(false);
foundErrors = true;
return false;
}
thisFrame.isReceived = true;
thisFrame.bus = 0;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
QStringList dataToks = Utility::unQuote(tokens[4]).simplified().split(' ');
- thisFrame.len = dataToks.length();
- if (thisFrame.len > 8) return false;
- for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataToks[d].toInt(NULL, 16);
+ QByteArray bytes(dataToks.length(), 0);
+ if (thisFrame.payload().length() > 8) return false;
+ for (int d = 0; d < thisFrame.payload().length(); d++) bytes[d] = static_cast(dataToks[d].toInt(nullptr, 16));
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else return false;
@@ -2173,6 +2282,10 @@ bool FrameFileIO::saveIXXATFile(QString filename, const QVector* frame
QDateTime timestamp, tempStamp;
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
timestamp = QDateTime::currentDateTime();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -2184,7 +2297,7 @@ bool FrameFileIO::saveIXXATFile(QString filename, const QVector* frame
outFile->write("ASCII Trace IXXAT SavvyCAN V" + QString::number(VERSION).toUtf8() + "\n");
outFile->write("Date: " + timestamp.toString("d:M:yyyy").toUtf8() + "\n");
outFile->write("Start time: " + timestamp.toString("h:m:s").toUtf8() + "\n");
- timestamp.addMSecs((frames->last().timestamp - frames->first().timestamp) / 1000);
+ timestamp = timestamp.addMSecs((frames->last().timeStamp().microSeconds() - frames->first().timeStamp().microSeconds()) / 1000);
outFile->write("Stop time: " + timestamp.toString("h:m:s").toUtf8() + "\n");
outFile->write("Overruns: 0\n");
outFile->write("Baudrate: 500 kbit/s\n"); //could be a lie... this code has no way to know the baud rate (at the moment)
@@ -2198,17 +2311,22 @@ bool FrameFileIO::saveIXXATFile(QString filename, const QVector* frame
qApp->processEvents();
lineCounter = 0;
}
- tempStamp = QDateTime::fromMSecsSinceEpoch(frames->at(c).timestamp / 1000);
+
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ tempStamp = QDateTime::fromMSecsSinceEpoch(frame->timeStamp().microSeconds() / 1000);
outFile->write("\"" + tempStamp.toString("h:m:s.").toUtf8() + tempStamp.toString("z").rightJustified(3, '0').toUtf8() + "\"");
- outFile->write(",\"" + QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + "\"");
- if (frames->at(c).extended) outFile->write(",\"Ext\"");
+ outFile->write(",\"" + QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8() + "\"");
+ if (frame->hasExtendedFrameFormat()) outFile->write(",\"Ext\"");
else outFile->write(",\"Std\"");
outFile->write(",\"\",\"");
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
@@ -2245,14 +2363,14 @@ bool FrameFileIO::isCANDOFile(QString filename)
data = inFile->read(12);
- int ID = (((unsigned int)data[3] & 0x0F) * 256 + (unsigned int)data[2]);
- int len = (unsigned char)data[3] >> 4;
+ int ID = ((data[3] & 0x0F) * 256 + data[2]);
+ int len = data[3] >> 4;
if (len <= 8 && ID <= 0x7FF)
{
if (len < 8)
{
- if (data[4 + len] != (char)0xFF) isMatch = false;
+ if (data[4 + len] != static_cast(0xFF)) isMatch = false;
}
}
else isMatch = false;
@@ -2275,9 +2393,9 @@ bool FrameFileIO::loadCANDOFile(QString filename, QVector* frames)
int lineCounter = 0;
QByteArray data;
int timeOffset = 0;
- uint64_t lastTimeStamp = 0;
+ int64_t lastTimeStamp = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly))
{
@@ -2300,26 +2418,29 @@ bool FrameFileIO::loadCANDOFile(QString filename, QVector* frames)
}
data = inFile->read(12);
+ unsigned char *uData = reinterpret_cast(data.data());
thisFrame.bus = 0;
thisFrame.isReceived = true;
- thisFrame.extended = false; //format is incapable of extended frames
- thisFrame.remote = false;
-
- thisFrame.timestamp = 1000000ul * ((unsigned char)data[0] >> 2);
- thisFrame.timestamp += (((data[0] & 3) << 8) + (unsigned char)data[1]) * 1000;
- thisFrame.timestamp += timeOffset;
- if (thisFrame.timestamp < lastTimeStamp)
+ thisFrame.setExtendedFrameFormat(false); //format is incapable of extended frames
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ qint64 tempStamp;
+ tempStamp = 1000000ul * (uData[0] >> 2);
+ tempStamp += (((uData[0] & 3) << 8) + uData[1]) * 1000;
+ tempStamp += timeOffset;
+ if (tempStamp < lastTimeStamp)
{
timeOffset += 60000000ul;
}
- lastTimeStamp = thisFrame.timestamp;
- thisFrame.ID = (((unsigned char)data[3] & 0x0F) * 256 + (unsigned char)data[2]) & 0x7FF;
- thisFrame.len = (unsigned char)data[3] >> 4;
+ lastTimeStamp = tempStamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, tempStamp));
+ thisFrame.setFrameId(((uData[3] & 0x0F) * 256 + uData[2]) & 0x7FF);
+ QByteArray bytes(uData[3] >> 4, 0);
- if (thisFrame.len <= 8 && thisFrame.ID <= 0x7FF)
+ if (thisFrame.payload().length() <= 8 && thisFrame.frameId() <= 0x7FF)
{
- for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)data[4 + d];
+ for (int d = 0; d < thisFrame.payload().length(); d++) bytes[d] = data[4 + d];
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -2336,7 +2457,12 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector* frame
int lineCounter = 0;
QByteArray data;
CANFrame thisFrame;
- int ms, id;
+ int id;
+ qint64 ms;
+
+ unsigned char *inData;
+ int inDataLen;
+ const CANFrame *frame;
if (!outFile->open(QIODevice::WriteOnly))
{
@@ -2348,7 +2474,7 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector* frame
//The initial frame in official files sets the global time but I don't care so it is set all zeros here.
thisFrame = frames->at(0);
- ms = (thisFrame.timestamp / 1000);
+ ms = (thisFrame.timeStamp().microSeconds() / 1000);
data[0] = (((ms / 1000) % 60) << 2) + ((ms % 1000) >> 8);
data[1] = (char)(ms & 0xFF);
data[2] = (char)0xFF;
@@ -2364,18 +2490,22 @@ bool FrameFileIO::saveCANDOFile(QString filename, const QVector* frame
qApp->processEvents();
lineCounter = 0;
}
+
+ frame = &frames->at(c);
+ inData = reinterpret_cast(frame->payload().data());
+ inDataLen = frame->payload().count();
+
for (int j = 0; j < 8; j++) data[4 + j] = (char)0xFF;
- thisFrame = frames->at(c);
- if (!thisFrame.extended)
+ if (!frame->hasExtendedFrameFormat())
{
- ms = (thisFrame.timestamp / 1000);
- id = thisFrame.ID & 0x7FF;
+ ms = (frame->timeStamp().microSeconds() / 1000);
+ id = frame->frameId() & 0x7FF;
data[0] = (((ms / 1000) % 60) << 2) + ((ms % 1000) >> 8);
data[1] = (char)(ms & 0xFF);
data[2] = (char)(id & 0xFF);
- data[3] = (char)((id >> 8) + (thisFrame.len << 4));
- for (unsigned int d = 0; d < thisFrame.len; d++) data[4 + d] = (char)thisFrame.data[d];
+ data[3] = (char)((id >> 8) + (inDataLen << 4));
+ for (int d = 0; d < inDataLen; d++) data[4 + d] = (char)inData[d];
outFile->write(data);
}
}
@@ -2455,7 +2585,7 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector* frames)
long long timeStamp;
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -2488,18 +2618,19 @@ bool FrameFileIO::loadMicrochipFile(QString filename, QVector* frames)
if (tokens.length() >= 4)
{
timeStamp = tokens[0].toInt() * 1000;
- thisFrame.timestamp = timeStamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp));
if (tokens[1].at(0) == 'R') thisFrame.isReceived = true;
else thisFrame.isReceived = false;
- thisFrame.remote = false;
- thisFrame.ID = Utility::ParseStringToNum(tokens[2]);
- if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
- else thisFrame.extended = true;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ thisFrame.setFrameId(static_cast( Utility::ParseStringToNum(tokens[2])) );
+ if (thisFrame.frameId() <= 0x7FF) thisFrame.setExtendedFrameFormat(false);
+ else thisFrame.setExtendedFrameFormat(true);
thisFrame.bus = 0;
- thisFrame.len = tokens[3].toUInt();
- if (thisFrame.len > 8) thisFrame.len = 8;
- if (thisFrame.len + 4 > (unsigned int) tokens.length()) thisFrame.len = tokens.length() - 4;
- for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
+ QByteArray bytes(tokens[3].toInt(), 0);
+ if (thisFrame.payload().length() > 8) thisFrame.payload().resize(8);
+ if (thisFrame.payload().length() + 4 > tokens.length()) thisFrame.payload().resize( tokens.length() - 4 );
+ for (int d = 0; d < thisFrame.payload().length(); d++) bytes[d] = static_cast( Utility::ParseStringToNum(tokens[4 + d]) );
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -2529,6 +2660,10 @@ bool FrameFileIO::saveMicrochipFile(QString filename, const QVector* f
QDateTime timestamp, tempStamp;
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
timestamp = QDateTime::currentDateTime();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -2555,15 +2690,19 @@ bool FrameFileIO::saveMicrochipFile(QString filename, const QVector* f
lineCounter = 0;
}
- outFile->write(QString::number((int)(frames->at(c).timestamp / 1000)).toUtf8());
- if (frames->at(c).isReceived) outFile->write(";RX;");
- else outFile->write(";TX;");
- outFile->write("0x" + QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + ";");
- outFile->write(QString::number(frames->at(c).len).toUtf8() + ";");
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ outFile->write(QString::number((frame->timeStamp().microSeconds() / 1000)).toUtf8());
+ if (frame->isReceived) outFile->write(";RX;");
+ else outFile->write(";TX;");
+ outFile->write("0x" + QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8() + ";");
+ outFile->write(QString::number(dataLen).toUtf8() + ";");
+
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write("0x" + QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write("0x" + QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(';');
}
@@ -2609,12 +2748,12 @@ bool FrameFileIO::isTraceFile(QString filename)
QList timestampToks = tokens[1].split(':');
if (timestampToks.count() != 4) isMatch = false;
- int ID = tokens[2].toLong(NULL, 16);
+ long ID = tokens[2].toLong(nullptr, 16);
if (ID < 1 || ID > 0x1FFFFFFF) isMatch = false;
int len = tokens[3].toInt();
if (len > 8 || len < 0) isMatch = false;
QList dataToks = tokens[4].split(' ');
- if (len > (unsigned int) dataToks.length()) isMatch = false;
+ if (len > dataToks.length()) isMatch = false;
}
else isMatch = false;
}
@@ -2668,7 +2807,7 @@ bool FrameFileIO::loadTraceFile(QString filename, QVector* frames)
long long timeStamp = 0;
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -2699,23 +2838,24 @@ bool FrameFileIO::loadTraceFile(QString filename, QVector* frames)
{
QList timestampToks = tokens[1].split(':');
- timeStamp = timestampToks[0].toInt() * 1000000ul * 60 * 60;
- timeStamp += timestampToks[1].toInt() * 1000000ul * 60;
- timeStamp += timestampToks[2].toInt() * 1000000ul;
+ timeStamp = timestampToks[0].toInt() * 1000000l * 60 * 60;
+ timeStamp += timestampToks[1].toInt() * 1000000l * 60;
+ timeStamp += timestampToks[2].toInt() * 1000000l;
timeStamp += timestampToks[3].toInt() * 100;
- thisFrame.timestamp = timeStamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, static_cast(timeStamp)));
- thisFrame.ID = tokens[2].toLong(NULL, 16);
- if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
- else thisFrame.extended = true;
+ thisFrame.setFrameId(static_cast(tokens[2].toLong(nullptr, 16)));
+ if (thisFrame.frameId() <= 0x7FF) thisFrame.setExtendedFrameFormat(false);
+ else thisFrame.setExtendedFrameFormat(true);
thisFrame.bus = 0;
- thisFrame.remote = false;
- thisFrame.len = tokens[3].toUInt();
- if (thisFrame.len > 8) thisFrame.len = 8;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ QByteArray bytes(tokens[3].toInt(), 0);
+ if (thisFrame.payload().length() > 8) thisFrame.payload().resize(8);
QList dataToks = tokens[4].split(' ');
- if (thisFrame.len > (unsigned int) dataToks.length()) thisFrame.len = (unsigned int) dataToks.length();
- for (unsigned int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)dataToks[d].toInt(NULL, 16);
+ if (thisFrame.payload().length() > dataToks.length()) thisFrame.payload().resize(dataToks.length());
+ for (int d = 0; d < thisFrame.payload().length(); d++) bytes[d] = static_cast(dataToks[d].toInt(nullptr, 16));
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -2732,9 +2872,13 @@ bool FrameFileIO::saveTraceFile(QString filename, const QVector * fram
QFile *outFile = new QFile(filename);
QDateTime timestamp;
int lineCounter = 0;
- uint64_t tempTime;
+ int64_t tempTime;
int tempTimePiece;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
timestamp = QDateTime::currentDateTime();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -2773,38 +2917,41 @@ bool FrameFileIO::saveTraceFile(QString filename, const QVector * fram
//lineCounter = 0;
}
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
//1F D3 3F FF 08 FF E0 CB
outFile->write(QString::number(lineCounter).rightJustified(10, ' ').toUtf8());
outFile->write("\t");
- tempTime = frames->at(c).timestamp;
- tempTimePiece = tempTime / 1000000ul / 60 / 60;
- tempTime -= tempTimePiece * 1000000ul * 60 * 60;
+ tempTime = frame->timeStamp().microSeconds();
+ tempTimePiece = static_cast(tempTime / 1000000l / 60 / 60);
+ tempTime -= tempTimePiece * 1000000l * 60 * 60;
outFile->write(QString::number(tempTimePiece).rightJustified(2, '0').toUtf8());
outFile->write(":");
- tempTimePiece = tempTime / 1000000ul / 60;
- tempTime -= tempTimePiece * 1000000ul * 60;
+ tempTimePiece = static_cast(tempTime / 1000000l / 60);
+ tempTime -= tempTimePiece * 1000000l * 60;
outFile->write(QString::number(tempTimePiece).rightJustified(2, '0').toUtf8());
outFile->write(":");
- tempTimePiece = tempTime / 1000000ul;
- tempTime -= tempTimePiece * 1000000ul;
+ tempTimePiece = static_cast(tempTime / 1000000l);
+ tempTime -= tempTimePiece * 1000000l;
outFile->write(QString::number(tempTimePiece).rightJustified(2, '0').toUtf8());
outFile->write(":");
- tempTimePiece = tempTime / 100;
+ tempTimePiece = static_cast(tempTime / 100);
outFile->write(QString::number(tempTimePiece).rightJustified(4, '0').toUtf8());
outFile->write("\t");
- outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8() + "\t");
+ outFile->write(QString::number(frame->frameId(), 16).toUpper().rightJustified(8, '0').toUtf8() + "\t");
- outFile->write(QString::number(frames->at(c).len).toUtf8() + "\t");
+ outFile->write(QString::number(dataLen).toUtf8() + "\t");
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
@@ -2823,6 +2970,10 @@ bool FrameFileIO::saveCanDumpFile(QString filename, const QVector * fr
int lineCounter = 0;
double tempTime;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
timestamp = QDateTime::currentDateTime();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
@@ -2839,27 +2990,31 @@ bool FrameFileIO::saveCanDumpFile(QString filename, const QVector * fr
qApp->processEvents();
}
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
outFile->write("(");
- tempTime = frames->at(c).timestamp / 1000000.0;
+ tempTime = frame->timeStamp().microSeconds() / 1000000.0;
outFile->write(QString::number(tempTime,'f', 6).rightJustified(17, '0').toUtf8());
outFile->write(") vcan0 ");
- if (frames->at(c).extended) {
- outFile->write(QString::number(frames->at(c).ID, 16).rightJustified(8,'0').toUpper().toUtf8());
+ if (frame->hasExtendedFrameFormat()) {
+ outFile->write(QString::number(frame->frameId(), 16).rightJustified(8,'0').toUpper().toUtf8());
} else {
- outFile->write(QString::number(frames->at(c).ID, 16).rightJustified(3,'0').toUpper().toUtf8());
+ outFile->write(QString::number(frame->frameId(), 16).rightJustified(3,'0').toUpper().toUtf8());
}
outFile->write("#");
- if (frames->at(c).remote) {
+ if (frame->frameType() == QCanBusFrame::RemoteRequestFrame) {
outFile->write("R");
- outFile->write(QString::number(frames->at(c).len).toUtf8());
+ outFile->write(QString::number(dataLen).toUtf8());
} else {
- for (unsigned int temp = 0; temp < frames->at(c).len; temp++)
+ for (int temp = 0; temp < dataLen; temp++)
{
- outFile->write(QString::number(frames->at(c).data[temp], 16).rightJustified(2,'0').toUpper().toUtf8());
+ outFile->write(QString::number(data[temp], 16).rightJustified(2,'0').toUpper().toUtf8());
}
}
@@ -2907,7 +3062,7 @@ bool FrameFileIO::isCanDumpFile(QString filename)
ret = timeExp.exactMatch(tokens[0]);
if(!ret) isMatch = false;
- uint64_t timestamp = (uint64_t)(timeExp.cap(1).toDouble(&ret) * (double)1000000.0);
+ /*uint64_t timestamp = (uint64_t)*/(timeExp.cap(1).toDouble(&ret) /** (double)1000000.0*/);
if(!ret) isMatch = false;
if (line.contains('[')) //the expanded format
@@ -2941,7 +3096,7 @@ bool FrameFileIO::isCanDumpFile(QString filename)
}
/* ID */
- int ID = IdValExp.cap(1).toInt(&ret, 16);
+ /*int ID = */IdValExp.cap(1).toInt(&ret, 16);
QString val= IdValExp.cap(2);
@@ -2965,7 +3120,7 @@ bool FrameFileIO::isCanDumpFile(QString filename)
isMatch = false;
break;
}
- int data = valExp.cap(1).toInt(&ret, 16);
+ /*int data = */valExp.cap(1).toInt(&ret, 16);
if(!ret)
{
isMatch = false;
@@ -3032,22 +3187,23 @@ bool FrameFileIO::loadCanDumpFile(QString filename, QVector* frames)
ret = timeExp.exactMatch(tokens[0]);
if(!ret) continue;
- thisFrame.timestamp = (uint64_t)(timeExp.cap(1).toDouble(&ret) * (double)1000000.0);
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, (uint64_t)(timeExp.cap(1).toDouble(&ret) * (double)1000000.0)));
if(!ret) continue;
if (line.contains('[')) //the expanded format (second one from the above list)
{
//(1551774790.942758) can1 7A8 [8] F4 DC D1 83 0E 02 00 00
// 0 1 2 3 4 5 6 7 8 9 10 11
- thisFrame.ID = tokens[2].toULong(nullptr, 16);
- if (thisFrame.ID > 0x7FF) thisFrame.extended = true;
- else thisFrame.extended = false;
- thisFrame.remote = false;
- thisFrame.len = tokens[3].at(1) - '0';
- for (int c = 0; c < thisFrame.len; c++)
+ thisFrame.setFrameId(tokens[2].toLong(nullptr, 16));
+ if (thisFrame.frameId() > 0x7FF) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ QByteArray bytes(tokens[3].at(1) - '0', 0);
+ for (int c = 0; c < thisFrame.payload().length(); c++)
{
- thisFrame.data[c] = tokens[4 + c].toInt(nullptr, 16);
+ bytes[c] = static_cast(tokens[4 + c].toInt(nullptr, 16));
}
+ thisFrame.setPayload(bytes);
}
else //the more concise format (first one from list above)
{
@@ -3061,32 +3217,32 @@ bool FrameFileIO::loadCanDumpFile(QString filename, QVector* frames)
}
/* ID */
- thisFrame.ID = IdValExp.cap(1).toInt(&ret, 16);
+ thisFrame.setFrameId(static_cast(IdValExp.cap(1).toInt(&ret, 16)));
if (IdValExp.cap(1).length() > 3) {
- thisFrame.extended = true;
+ thisFrame.setExtendedFrameFormat(true);
} else {
- thisFrame.extended = false;
+ thisFrame.setExtendedFrameFormat(false);
}
QString val= IdValExp.cap(2);
pos = 0;
- thisFrame.len = 0;
+ QByteArray bytes;
if (val.startsWith("R") && val.at(1).isDigit()) {
- thisFrame.len = val.at(1).toLatin1() - '0';
- thisFrame.remote = true;
+ thisFrame.payload().resize( val.at(1).toLatin1() - '0' );
+ thisFrame.setFrameType(QCanBusFrame::RemoteRequestFrame);
} else {
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
/* val byte per byte */
while ((pos = valExp.indexIn(val, pos)) != -1)
{
- thisFrame.data[thisFrame.len] = valExp.cap(1).toInt(&ret, 16);
+ bytes.append((char)valExp.cap(1).toInt(&ret, 16));
if(!ret) continue;
- thisFrame.len++;
pos += valExp.matchedLength();
}
}
+ thisFrame.setPayload(bytes);
}
/*NB: should we make sure len <= 8? */
@@ -3100,6 +3256,96 @@ bool FrameFileIO::loadCanDumpFile(QString filename, QVector* frames)
return true;
}
+bool FrameFileIO::isLawicelFile(QString filename)
+{
+ QFile *inFile = new QFile(filename);
+ QByteArray line;
+ int lineCounter = 0;
+ bool isMatch = false;
+
+ if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ delete inFile;
+ return false;
+ }
+
+ try
+ {
+ while (!inFile->atEnd() && lineCounter < 100) {
+ lineCounter++;
+
+ line = inFile->readLine().toUpper();
+ if (line.length() > 4 && !line.startsWith("S"))
+ {
+ int ID = line.mid(0, 3).toInt(nullptr, 16);
+ if (ID > 0 && ID < 0x800)
+ {
+ line.remove(0, 3);
+ int len = line.length() / 2;
+ if (len > -1 && len < 9) isMatch = true;
+ }
+ }
+ }
+ }
+ catch (...)
+ {
+ isMatch = false;
+ }
+ inFile->close();
+ delete inFile;
+ return isMatch;
+}
+
+/*Example line:
+1D5210000000000E0D7
+The first three digits are the ID, all bytes are then two hex digits after that. So, the length is determined by line length
+Skip all lines that start with an S
+*/
+bool FrameFileIO::loadLawicelFile(QString filename, QVector* frames)
+{
+ QFile *inFile = new QFile(filename);
+ CANFrame thisFrame;
+ QByteArray line;
+ int lineCounter = 0;
+ bool foundErrors = false;
+ quint64 timeStamp = 0;
+
+ if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
+ {
+ delete inFile;
+ return false;
+ }
+
+ while (!inFile->atEnd()) {
+ lineCounter++;
+ if (lineCounter > 100)
+ {
+ qApp->processEvents();
+ lineCounter = 0;
+ }
+ line = inFile->readLine().simplified();
+ if (line.length() > 4 && !line.startsWith("S"))
+ {
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, timeStamp += 100));
+ thisFrame.setFrameId( line.mid(0, 3).toInt(nullptr, 16) );
+ thisFrame.setExtendedFrameFormat(false);
+ thisFrame.isReceived = true;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ thisFrame.bus = 0;
+ line.remove(0, 3);
+ QByteArray bytes(line.length() / 2, 0);
+ for (int d = 0; d < bytes.length(); d++)
+ {
+ bytes[d] = static_cast(line.mid(d * 2, 2).toInt(nullptr, 16));
+ }
+ thisFrame.setPayload(bytes);
+ frames->append(thisFrame);
+ }
+ }
+ inFile->close();
+ delete inFile;
+ return !foundErrors;
+}
bool FrameFileIO::isKvaserFile(QString filename)
{
@@ -3155,7 +3401,7 @@ bool FrameFileIO::loadKvaserFile(QString filename, QVector *frames, bo
int lineCounter = 0;
int base = 10;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (useHex) base = 16;
@@ -3185,18 +3431,18 @@ bool FrameFileIO::loadKvaserFile(QString filename, QVector *frames, bo
//Chn Identifier Flg DLC D0...1...2...3...4...5...6..D7 Time Dir
// 0 000000AD 8 FF FF 00 00 00 00 00 00 154.266550 R
thisFrame.bus = line.mid(0,3).simplified().toInt();
- thisFrame.ID = line.mid(4,10).simplified().toInt(NULL, base);
- if (thisFrame.ID > 0x7FF) thisFrame.extended = true;
- else thisFrame.extended = false;
- thisFrame.remote = false;
- thisFrame.len = line.mid(21, 3).simplified().toInt();
+ thisFrame.setFrameId(line.mid(4,10).simplified().toInt(nullptr, base));
+ if (thisFrame.frameId() > 0x7FF) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
+ QByteArray bytes(line.mid(21, 3).simplified().toInt(), 0);
for (int i = 0; i < 8; i++) {
- thisFrame.data[i] = line.mid(25 + i * 4, 3).simplified().toInt(NULL, base);
+ bytes[i] = line.mid(25 + i * 4, 3).simplified().toInt(nullptr, base);
}
- thisFrame.timestamp = line.mid(57, 14).simplified().toDouble() * 1000000;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, line.mid(57, 14).simplified().toDouble() * 1000000));
if (line.mid(72, 1).toUpper() == "R") thisFrame.isReceived = true;
else thisFrame.isReceived = false;
-
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
//else foundErrors = true;
@@ -3267,7 +3513,7 @@ bool FrameFileIO::loadCabanaFile(QString filename, QVector* frames)
uint64_t lastTimeStamp = 0;
int lineCounter = 0;
bool foundErrors = false;
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
{
@@ -3303,42 +3549,41 @@ bool FrameFileIO::loadCabanaFile(QString filename, QVector* frames)
}
if(timeStampBaseSet) {
- thisFrame.timestamp = ((uint64_t)(temp) - timeStampBase);
- lastTimeStamp = thisFrame.timestamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, ((uint64_t)(temp) - timeStampBase)));
+ lastTimeStamp = thisFrame.timeStamp().microSeconds();
} else {
- thisFrame.timestamp = (lastTimeStamp + 1);
- lastTimeStamp = thisFrame.timestamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, (lastTimeStamp + 1)));
+ lastTimeStamp = thisFrame.timeStamp().microSeconds();
}
}
else
{
- thisFrame.timestamp = (lastTimeStamp + 1);
- lastTimeStamp = thisFrame.timestamp;
+ thisFrame.setTimeStamp(QCanBusFrame::TimeStamp(0, (lastTimeStamp + 1)));
+ lastTimeStamp = thisFrame.timeStamp().microSeconds();
}
- thisFrame.ID = tokens[1].toInt();
- if (thisFrame.ID > 0x7ff) thisFrame.extended = 1;
- else thisFrame.extended = 0;
+ thisFrame.setFrameId(tokens[1].toInt());
+ if (thisFrame.frameId() > 0x7ff) thisFrame.setExtendedFrameFormat(true);
+ else thisFrame.setExtendedFrameFormat(false);
- thisFrame.remote = false;
+ thisFrame.setFrameType(QCanBusFrame::DataFrame);
thisFrame.isReceived = true;
thisFrame.bus = tokens[2].toInt();
- thisFrame.len = 8;
-
+ QByteArray bytes(8,0);
{
- unsigned long long int tempData = tokens[3].toULongLong(NULL, 16);
- thisFrame.data[0] = ((tempData >> 56) & 0xFF);
- thisFrame.data[1] = ((tempData >> 48) & 0xFF);
- thisFrame.data[2] = ((tempData >> 40) & 0xFF);
- thisFrame.data[3] = ((tempData >> 32) & 0xFF);
- thisFrame.data[4] = ((tempData >> 24) & 0xFF);
- thisFrame.data[5] = ((tempData >> 16) & 0xFF);
- thisFrame.data[6] = ((tempData >> 8) & 0xFF);
- thisFrame.data[7] = (tempData & 0xFF);
+ unsigned long long int tempData = tokens[3].toULongLong(nullptr, 16);
+ bytes[0] = ((tempData >> 56) & 0xFF);
+ bytes[1] = ((tempData >> 48) & 0xFF);
+ bytes[2] = ((tempData >> 40) & 0xFF);
+ bytes[3] = ((tempData >> 32) & 0xFF);
+ bytes[4] = ((tempData >> 24) & 0xFF);
+ bytes[5] = ((tempData >> 16) & 0xFF);
+ bytes[6] = ((tempData >> 8) & 0xFF);
+ bytes[7] = (tempData & 0xFF);
}
-
+ thisFrame.setPayload(bytes);
frames->append(thisFrame);
}
else foundErrors = true;
@@ -3354,6 +3599,10 @@ bool FrameFileIO::saveCabanaFile(QString filename, const QVector* fram
QFile *outFile = new QFile(filename);
int lineCounter = 0;
+ unsigned char *data;
+ int dataLen;
+ const CANFrame *frame;
+
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
{
delete outFile;
@@ -3372,23 +3621,27 @@ bool FrameFileIO::saveCabanaFile(QString filename, const QVector* fram
lineCounter = 0;
}
- double tempTimeStamp = frames->at(c).timestamp;
+ frame = &frames->at(c);
+ data = reinterpret_cast(frame->payload().data());
+ dataLen = frame->payload().count();
+
+ double tempTimeStamp = frame->timeStamp().microSeconds();
tempTimeStamp /= 1000000;
outFile->write(QString::number(tempTimeStamp, 'f').toUtf8());
outFile->write(".0");
outFile->putChar(44);
- outFile->write(QString::number(frames->at(c).ID, 10).toUpper().toUtf8());
+ outFile->write(QString::number(frame->frameId(), 10).toUpper().toUtf8());
outFile->putChar(44);
- outFile->write(QString::number(frames->at(c).bus).toUtf8());
+ outFile->write(QString::number(frame->bus).toUtf8());
outFile->putChar(44);
- for (unsigned int temp = 0; temp < 8; temp++)
+ for (int temp = 0; temp < 8; temp++)
{
- if (temp < frames->at(c).len)
- outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
+ if (temp < dataLen)
+ outFile->write(QString::number(data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
else
outFile->write("00");
}
diff --git a/framefileio.h b/framefileio.h
index 8839e76..06da738 100644
--- a/framefileio.h
+++ b/framefileio.h
@@ -41,6 +41,7 @@ public:
static bool loadCANDOFile(QString, QVector*);
static bool loadVehicleSpyFile(QString, QVector*);
static bool loadCanDumpFile(QString, QVector*);
+ static bool loadLawicelFile(QString, QVector*);
static bool loadPCANFile(QString, QVector*);
static bool loadKvaserFile(QString, QVector*, bool);
static bool loadCanalyzerASC(QString, QVector*);
@@ -61,6 +62,7 @@ public:
static bool isCANDOFile(QString);
static bool isVehicleSpyFile(QString);
static bool isCanDumpFile(QString);
+ static bool isLawicelFile(QString);
static bool isPCANFile(QString);
static bool isKvaserFile(QString);
static bool isCanalyzerASC(QString);
diff --git a/frameplaybackobject.cpp b/frameplaybackobject.cpp
index e990efe..b918b07 100644
--- a/frameplaybackobject.cpp
+++ b/frameplaybackobject.cpp
@@ -68,7 +68,7 @@ quint64 FramePlaybackObject::updatePosition(bool forward)
//only send frame out if its ID is checked in the list. Otherwise discard it.
CANFrame *thisFrame = ¤tSeqItem->data[currentPosition];
uint32_t originalBus = thisFrame->bus;
- if (currentSeqItem->idFilters.find(thisFrame->ID).value())
+ if (currentSeqItem->idFilters.find(thisFrame->frameId()).value())
{
if (whichBusSend > -1)
{
@@ -90,7 +90,7 @@ quint64 FramePlaybackObject::updatePosition(bool forward)
thisFrame->bus = originalBus;
}
- return thisFrame->timestamp;
+ return thisFrame->timeStamp().microSeconds();
}
quint64 FramePlaybackObject::peekPosition(bool forward)
@@ -113,7 +113,7 @@ quint64 FramePlaybackObject::peekPosition(bool forward)
}
}
CANFrame *thisFrame = ¤tSeqItem->data[peekCurrentPosition];
- return thisFrame->timestamp;
+ return thisFrame->timeStamp().microSeconds();
}
void FramePlaybackObject::piStart()
@@ -197,8 +197,8 @@ void FramePlaybackObject::startPlaybackForward()
{
playbackTimer->setInterval(1);
playbackElapsed.start();
- if (currentSeqItem->data[currentPosition].timestamp > 2000)
- playbackLastTimeStamp = currentSeqItem->data[currentPosition].timestamp - 2000;
+ if (currentSeqItem->data[currentPosition].timeStamp().microSeconds() > 2000)
+ playbackLastTimeStamp = currentSeqItem->data[currentPosition].timeStamp().microSeconds() - 2000;
else playbackLastTimeStamp = 0;
}
playbackTimer->start();
@@ -219,7 +219,7 @@ void FramePlaybackObject::startPlaybackBackward()
{
playbackElapsed.start();
playbackTimer->setInterval(1);
- playbackLastTimeStamp = currentSeqItem->data[currentPosition].timestamp + 2000;
+ playbackLastTimeStamp = currentSeqItem->data[currentPosition].timeStamp().microSeconds() + 2000;
}
playbackTimer->start();
}
@@ -350,8 +350,8 @@ void FramePlaybackObject::timerTriggered()
if (peekPosition(true) == 0xFFFFFFFFFFFFFFFFull)
{
updatePosition(true); //this'll go to the next log (if there is one)
- if (currentSeqItem->data[currentPosition].timestamp > 1000)
- playbackLastTimeStamp = currentSeqItem->data[currentPosition].timestamp - 1000;
+ if (currentSeqItem->data[currentPosition].timeStamp().microSeconds() > 1000)
+ playbackLastTimeStamp = currentSeqItem->data[currentPosition].timeStamp().microSeconds() - 1000;
else playbackLastTimeStamp = 0;
}
}
@@ -367,7 +367,7 @@ void FramePlaybackObject::timerTriggered()
if (peekPosition(false) == 0xFFFFFFFFFFFFFFFFull)
{
updatePosition(false); //this'll go to the next log (if there is one)
- playbackLastTimeStamp = currentSeqItem->data[currentPosition].timestamp + 1000;
+ playbackLastTimeStamp = currentSeqItem->data[currentPosition].timeStamp().microSeconds() + 1000;
}
}
statusCounter++;
diff --git a/frameplaybackwindow.cpp b/frameplaybackwindow.cpp
index 7da98ef..85fd517 100644
--- a/frameplaybackwindow.cpp
+++ b/frameplaybackwindow.cpp
@@ -4,8 +4,11 @@
#include
#include