Moved the frame file saving/loading routines to their own class in preparation for new cool stuff.

This commit is contained in:
Collin Kidder
2015-06-16 20:15:37 -04:00
parent b2819e3b55
commit f1cedbd880
6 changed files with 454 additions and 443 deletions
+5 -2
View File
@@ -27,7 +27,8 @@ SOURCES += main.cpp\
framesenderwindow.cpp \
dbchandler.cpp \
dbcmaineditor.cpp \
dbcsignaleditor.cpp
dbcsignaleditor.cpp \
framefileio.cpp
HEADERS += mainwindow.h \
can_structs.h \
@@ -46,7 +47,9 @@ HEADERS += mainwindow.h \
dbc_classes.h \
dbchandler.h \
dbcmaineditor.h \
dbcsignaleditor.h
dbcsignaleditor.h \
framefileio.h \
config.h
FORMS += mainwindow.ui \
graphingwindow.ui \
+7
View File
@@ -0,0 +1,7 @@
#ifndef CONFIG
#define CONFIG
#define VERSION 111
#endif // CONFIG
+372
View File
@@ -0,0 +1,372 @@
#include "framefileio.h"
FrameFileIO::FrameFileIO()
{
}
//CRTD format from Mark Webb-Johnson / OVMS project
/*
Sample data in CRTD format
1320745424.000 CXX OVMS Tesla Roadster cando2crtd converted log
1320745424.000 CXX OVMS Tesla roadster log: charge.20111108.csv
1320745424.002 R11 402 FA 01 C3 A0 96 00 07 01
1320745424.015 R11 400 02 9E 01 80 AB 80 55 00
1320745424.066 R11 400 01 01 00 00 00 00 4C 1D
1320745424.105 R11 100 A4 53 46 5A 52 45 38 42
1320745424.106 R11 100 A5 31 35 42 33 30 30 30
1320745424.106 R11 100 A6 35 36 39
1320745424.106 CEV Open charge port door
1320745424.106 R11 100 9B 97 A6 31 03 15 05 06
1320745424.107 R11 100 07 64
tokens:
0 = timestamp
1 = line type
2 = ID
3-x = The data bytes
*/
bool FrameFileIO::loadCRTDFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return false;
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine().simplified();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(' ');
int multiplier;
int idxOfDecimal = tokens[0].indexOf('.');
if (idxOfDecimal > -1) {
int decimalPlaces = tokens[0].length() - tokens[0].indexOf('.') - 1;
//the result of the above is the # of digits after the decimal.
//This program deals in microsecond so turn the value into microseconds
multiplier = 1000000; //turn the decimal into full microseconds
}
else
{
multiplier = 1; //special case. Assume no decimal means microseconds
}
//qDebug() << "decimal places " << decimalPlaces;
thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * multiplier);
if (tokens[1] == "R11" || tokens[1] == "R29")
{
thisFrame.ID = tokens[2].toInt(NULL, 16);
if (tokens[1] == "R29") thisFrame.extended = true;
else thisFrame.extended = false;
thisFrame.bus = 0;
thisFrame.len = tokens.length() - 3;
for (int d = 0; d < thisFrame.len; d++)
{
if (tokens[d + 3] != "")
{
thisFrame.data[d] = tokens[d + 3].toInt(NULL, 16);
}
else thisFrame.data[d] = 0;
}
frames->append(thisFrame);
}
}
}
inFile->close();
return true;
}
bool FrameFileIO::saveCRTDFile(QString filename, QVector<CANFrame>* frames)
{
QFile *outFile = new QFile(filename);
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
return false;
//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("\n");
for (int c = 0; c < frames->count(); c++)
{
outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8());
outFile->putChar(' ');
if (frames->at(c).extended)
{
outFile->write("R29 ");
}
else outFile->write("R11 ");
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(' ');
for (int temp = 0; temp < frames->at(c).len; temp++)
{
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
outFile->write("\n");
}
outFile->close();
return true;
}
//The "native" file format for this program
bool FrameFileIO::loadNativeCSVFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return false;
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(',');
if (tokens[0].length() > 3)
{
long long temp = tokens[0].right(10).toLongLong();
thisFrame.timestamp = temp;
}
else
{
timeStamp += 5;
thisFrame.timestamp = timeStamp;
}
thisFrame.ID = tokens[1].toInt(NULL, 16);
if (tokens[2].toUpper().contains("TRUE")) thisFrame.extended = 1;
else thisFrame.extended = 0;
thisFrame.bus = tokens[3].toInt();
thisFrame.len = tokens[4].toInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
frames->append(thisFrame);
}
}
inFile->close();
return true;
}
bool FrameFileIO::saveNativeCSVFile(QString filename, QVector<CANFrame>* frames)
{
QFile *outFile = new QFile(filename);
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
return false;
outFile->write("Time Stamp,ID,Extended,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8");
outFile->write("\n");
for (int c = 0; c < frames->count(); c++)
{
outFile->write(QString::number(frames->at(c).timestamp).toUtf8());
outFile->putChar(44);
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(44);
if (frames->at(c).extended) outFile->write("true,");
else outFile->write("false,");
outFile->write(QString::number(frames->at(c).bus).toUtf8());
outFile->putChar(44);
outFile->write(QString::number(frames->at(c).len).toUtf8());
outFile->putChar(44);
for (int temp = 0; temp < 8; temp++)
{
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(44);
}
outFile->write("\n");
}
outFile->close();
return true;
}
bool FrameFileIO::loadGenericCSVFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return false;
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(',');
timeStamp += 5;
thisFrame.timestamp = timeStamp;
thisFrame.ID = tokens[0].toInt(NULL, 16);
if (thisFrame.ID > 0x7FF) thisFrame.extended = true;
else thisFrame.extended = false;
thisFrame.bus = 0;
QList<QByteArray> dataTok = tokens[1].split(' ');
thisFrame.len = dataTok.length();
if (thisFrame.len > 8) thisFrame.len = 8;
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataTok[d].toInt(NULL, 16);
frames->append(thisFrame);
}
}
inFile->close();
return true;
}
bool FrameFileIO::saveGenericCSVFile(QString filename, QVector<CANFrame>* frames)
{
return false;
}
//busmaster log file
/*
tokens:
0 = timestamp
1 = Transmission direction
2 = Channel
3 = ID
4 = Type (s = standard, I believe x = extended)
5 = Data byte length
6-x = The data bytes
Sample chunk of a busmaster log:
***BUSMASTER Ver 2.4.0***
***PROTOCOL CAN***
***NOTE: PLEASE DO NOT EDIT THIS DOCUMENT***
***[START LOGGING SESSION]***
***START DATE AND TIME 8:8:2014 11:49:7:965***
***HEX***
***SYSTEM MODE***
***START CHANNEL BAUD RATE***
***CHANNEL 1 - Kvaser - Kvaser Leaf Light HS #0 (Channel 0), Serial Number- 0, Firmware- 0x00000037 0x00020000 - 500000 bps***
***END CHANNEL BAUD RATE***
***START DATABASE FILES (DBF/DBC)***
***END OF DATABASE FILES (DBF/DBC)***
***<Time><Tx/Rx><Channel><CAN ID><Type><DLC><DataBytes>***
11:49:12:9420 Rx 1 0x023 s 1 40
11:49:12:9440 Rx 1 0x460 s 8 03 E0 00 00 C0 00 00 00
11:49:12:9530 Rx 1 0x023 s 1 40
11:49:12:9680 Rx 1 0x408 s 8 0F 02 00 30 00 00 7F 00
11:49:12:9680 Rx 1 0x40B s 8 00 00 00 00 00 10 60 00
11:49:12:9690 Rx 1 0x045 s 8 40 00 00 00 00 00 00 00
*/
bool FrameFileIO::loadLogFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
uint64_t timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return false;
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.startsWith("***")) continue;
if (line.length() > 1)
{
QList<QByteArray> tokens = line.split(' ');
QList<QByteArray> 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;
thisFrame.ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
if (tokens[4] == "s") thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = tokens[2].toInt() - 1;
thisFrame.len = tokens[5].toInt();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
}
frames->append(thisFrame);
}
inFile->close();
return true;
}
bool FrameFileIO::saveLogFile(QString filename, QVector<CANFrame>* frames)
{
return false;
}
//log file from microchip tool
/*
tokens:
0 = timestamp
1 = Transmission direction
2 = ID
3 = Data byte length
4-x = The data bytes
*/
bool FrameFileIO::loadMicrochipFile(QString filename, QVector<CANFrame>* frames)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
bool inComment = false;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return false;
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
if (line.startsWith("//"))
{
inComment = !inComment;
}
else
{
if (!inComment)
{
QList<QByteArray> tokens = line.split(';');
timeStamp += 5;
thisFrame.timestamp = timeStamp;
thisFrame.ID = Utility::ParseStringToNum(tokens[2]);
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
frames->append(thisFrame);
}
}
}
}
inFile->close();
return true;
}
bool FrameFileIO::saveMicrochipFile(QString filename, QVector<CANFrame>* frames)
{
return false;
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef FRAMEFILEIO_H
#define FRAMEFILEIO_H
//Class full of static methods that load and save canbus frames to/from various file formats
#include "config.h"
#include <Qt>
#include <QObject>
#include <QVector>
#include <QFile>
#include <QString>
#include <QStringList>
#include "can_structs.h"
#include "utility.h"
class FrameFileIO: public QObject
{
Q_OBJECT
public:
FrameFileIO();
static bool loadCRTDFile(QString, QVector<CANFrame>*);
static bool loadNativeCSVFile(QString, QVector<CANFrame>*);
static bool loadGenericCSVFile(QString, QVector<CANFrame>*);
static bool loadLogFile(QString, QVector<CANFrame>*);
static bool loadMicrochipFile(QString, QVector<CANFrame>*);
static bool saveCRTDFile(QString, QVector<CANFrame>*);
static bool saveNativeCSVFile(QString, QVector<CANFrame>*);
static bool saveGenericCSVFile(QString, QVector<CANFrame>*);
static bool saveLogFile(QString, QVector<CANFrame>*);
static bool saveMicrochipFile(QString, QVector<CANFrame>*);
};
#endif // FRAMEFILEIO_H
+33 -429
View File
@@ -247,10 +247,10 @@ void MainWindow::gotFrames(int FPS, int framesSinceLastUpdate)
void MainWindow::addFrameToDisplay(CANFrame &frame, bool autoRefresh = false)
{
model->addFrame(frame, autoRefresh);
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
model->addFrame(frame, autoRefresh);
if (autoRefresh)
{
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
}
}
@@ -276,427 +276,11 @@ void MainWindow::changeBaudRates()
emit updateBaudRates(Speed1, Speed2);
}
//CRTD format from Mark Webb-Johnson / OVMS project
/*
Sample data in CRTD format
1320745424.000 CXX OVMS Tesla Roadster cando2crtd converted log
1320745424.000 CXX OVMS Tesla roadster log: charge.20111108.csv
1320745424.002 R11 402 FA 01 C3 A0 96 00 07 01
1320745424.015 R11 400 02 9E 01 80 AB 80 55 00
1320745424.066 R11 400 01 01 00 00 00 00 4C 1D
1320745424.105 R11 100 A4 53 46 5A 52 45 38 42
1320745424.106 R11 100 A5 31 35 42 33 30 30 30
1320745424.106 R11 100 A6 35 36 39
1320745424.106 CEV Open charge port door
1320745424.106 R11 100 9B 97 A6 31 03 15 05 06
1320745424.107 R11 100 07 64
tokens:
0 = timestamp
1 = line type
2 = ID
3-x = The data bytes
*/
void MainWindow::loadCRTDFile(QString filename)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine().simplified();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(' ');
int multiplier;
int idxOfDecimal = tokens[0].indexOf('.');
if (idxOfDecimal > -1) {
int decimalPlaces = tokens[0].length() - tokens[0].indexOf('.') - 1;
//the result of the above is the # of digits after the decimal.
//This program deals in microsecond so turn the value into microseconds
multiplier = 1000000; //turn the decimal into full microseconds
}
else
{
multiplier = 1; //special case. Assume no decimal means microseconds
}
//qDebug() << "decimal places " << decimalPlaces;
thisFrame.timestamp = (int64_t)(tokens[0].toDouble() * multiplier);
if (tokens[1] == "R11" || tokens[1] == "R29")
{
thisFrame.ID = tokens[2].toInt(NULL, 16);
if (tokens[1] == "R29") thisFrame.extended = true;
else thisFrame.extended = false;
thisFrame.bus = 0;
thisFrame.len = tokens.length() - 3;
for (int d = 0; d < thisFrame.len; d++)
{
if (tokens[d + 3] != "")
{
thisFrame.data[d] = tokens[d + 3].toInt(NULL, 16);
}
else thisFrame.data[d] = 0;
}
addFrameToDisplay(thisFrame);
}
}
}
inFile->close();
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
void MainWindow::saveCRTDFile(QString filename)
{
QFile *outFile = new QFile(filename);
QVector<CANFrame> *frames = model->getListReference();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
//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("\n");
for (int c = 0; c < frames->count(); c++)
{
outFile->write(QString::number(frames->at(c).timestamp / 1000000.0, 'f', 6).toUtf8());
outFile->putChar(' ');
if (frames->at(c).extended)
{
outFile->write("R29 ");
}
else outFile->write("R11 ");
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(' ');
for (int temp = 0; temp < frames->at(c).len; temp++)
{
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(' ');
}
outFile->write("\n");
}
outFile->close();
updateFileStatus();
}
//The "native" file format for this program
void MainWindow::loadNativeCSVFile(QString filename)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(',');
if (tokens[0].length() > 3)
{
long long temp = tokens[0].right(10).toLongLong();
thisFrame.timestamp = temp;
}
else
{
timeStamp += 5;
thisFrame.timestamp = timeStamp;
}
thisFrame.ID = tokens[1].toInt(NULL, 16);
if (tokens[2].toUpper().contains("TRUE")) thisFrame.extended = 1;
else thisFrame.extended = 0;
thisFrame.bus = tokens[3].toInt();
thisFrame.len = tokens[4].toInt();
for (int c = 0; c < 8; c++) thisFrame.data[c] = 0;
for (int d = 0; d < thisFrame.len; d++)
thisFrame.data[d] = tokens[5 + d].toInt(NULL, 16);
addFrameToDisplay(thisFrame);
}
}
inFile->close();
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
void MainWindow::saveNativeCSVFile(QString filename)
{
QFile *outFile = new QFile(filename);
QVector<CANFrame> *frames = model->getListReference();
if (!outFile->open(QIODevice::WriteOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
outFile->write("Time Stamp,ID,Extended,Bus,LEN,D1,D2,D3,D4,D5,D6,D7,D8");
outFile->write("\n");
for (int c = 0; c < frames->count(); c++)
{
outFile->write(QString::number(frames->at(c).timestamp).toUtf8());
outFile->putChar(44);
outFile->write(QString::number(frames->at(c).ID, 16).toUpper().rightJustified(8, '0').toUtf8());
outFile->putChar(44);
if (frames->at(c).extended) outFile->write("true,");
else outFile->write("false,");
outFile->write(QString::number(frames->at(c).bus).toUtf8());
outFile->putChar(44);
outFile->write(QString::number(frames->at(c).len).toUtf8());
outFile->putChar(44);
for (int temp = 0; temp < 8; temp++)
{
outFile->write(QString::number(frames->at(c).data[temp], 16).toUpper().rightJustified(2, '0').toUtf8());
outFile->putChar(44);
}
outFile->write("\n");
}
outFile->close();
updateFileStatus();
}
void MainWindow::loadGenericCSVFile(QString filename)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
QList<QByteArray> tokens = line.split(',');
timeStamp += 5;
thisFrame.timestamp = timeStamp;
thisFrame.ID = tokens[0].toInt(NULL, 16);
if (thisFrame.ID > 0x7FF) thisFrame.extended = true;
else thisFrame.extended = false;
thisFrame.bus = 0;
QList<QByteArray> dataTok = tokens[1].split(' ');
thisFrame.len = dataTok.length();
if (thisFrame.len > 8) thisFrame.len = 8;
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = dataTok[d].toInt(NULL, 16);
addFrameToDisplay(thisFrame);
}
}
inFile->close();
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
void MainWindow::saveGenericCSVFile(QString filename)
{
}
//busmaster log file
/*
tokens:
0 = timestamp
1 = Transmission direction
2 = Channel
3 = ID
4 = Type (s = standard, I believe x = extended)
5 = Data byte length
6-x = The data bytes
Sample chunk of a busmaster log:
***BUSMASTER Ver 2.4.0***
***PROTOCOL CAN***
***NOTE: PLEASE DO NOT EDIT THIS DOCUMENT***
***[START LOGGING SESSION]***
***START DATE AND TIME 8:8:2014 11:49:7:965***
***HEX***
***SYSTEM MODE***
***START CHANNEL BAUD RATE***
***CHANNEL 1 - Kvaser - Kvaser Leaf Light HS #0 (Channel 0), Serial Number- 0, Firmware- 0x00000037 0x00020000 - 500000 bps***
***END CHANNEL BAUD RATE***
***START DATABASE FILES (DBF/DBC)***
***END OF DATABASE FILES (DBF/DBC)***
***<Time><Tx/Rx><Channel><CAN ID><Type><DLC><DataBytes>***
11:49:12:9420 Rx 1 0x023 s 1 40
11:49:12:9440 Rx 1 0x460 s 8 03 E0 00 00 C0 00 00 00
11:49:12:9530 Rx 1 0x023 s 1 40
11:49:12:9680 Rx 1 0x408 s 8 0F 02 00 30 00 00 7F 00
11:49:12:9680 Rx 1 0x40B s 8 00 00 00 00 00 10 60 00
11:49:12:9690 Rx 1 0x045 s 8 40 00 00 00 00 00 00 00
*/
void MainWindow::loadLogFile(QString filename)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
uint64_t timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.startsWith("***")) continue;
if (line.length() > 1)
{
QList<QByteArray> tokens = line.split(' ');
QList<QByteArray> 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;
thisFrame.ID = tokens[3].right(tokens[3].length() - 2).toInt(NULL, 16);
if (tokens[4] == "s") thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = tokens[2].toInt() - 1;
thisFrame.len = tokens[5].toInt();
for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = tokens[d + 6].toInt(NULL, 16);
}
addFrameToDisplay(thisFrame);
}
inFile->close();
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
void MainWindow::saveLogFile(QString filename)
{
}
//log file from microchip tool
/*
tokens:
0 = timestamp
1 = Transmission direction
2 = ID
3 = Data byte length
4-x = The data bytes
*/
void MainWindow::loadMicrochipFile(QString filename)
{
QFile *inFile = new QFile(filename);
CANFrame thisFrame;
QByteArray line;
bool inComment = false;
long long timeStamp = Utility::GetTimeMS();
if (!inFile->open(QIODevice::ReadOnly | QIODevice::Text))
return;
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
line = inFile->readLine(); //read out the header first and discard it.
while (!inFile->atEnd()) {
line = inFile->readLine();
if (line.length() > 2)
{
if (line.startsWith("//"))
{
inComment = !inComment;
}
else
{
if (!inComment)
{
QList<QByteArray> tokens = line.split(';');
timeStamp += 5;
thisFrame.timestamp = timeStamp;
//thisFrame.ID = Utility::ParseStringToNum(tokens[2]);
if (thisFrame.ID <= 0x7FF) thisFrame.extended = false;
else thisFrame.extended = true;
thisFrame.bus = 0;
thisFrame.len = tokens[3].toInt();
//for (int d = 0; d < thisFrame.len; d++) thisFrame.data[d] = (unsigned char)Utility::ParseStringToNum(tokens[4 + d]);
addFrameToDisplay(thisFrame);
}
}
}
}
inFile->close();
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
void MainWindow::saveMicrochipFile(QString filename)
{
}
void MainWindow::handleLoadFile()
{
QString filename;
QFileDialog dialog(this);
bool result = false;
QStringList filters;
filters.append(QString(tr("CRTD Logs (*.txt)")));
@@ -715,11 +299,23 @@ void MainWindow::handleLoadFile()
ui->canFramesView->scrollToTop();
model->clearFrames();
if (dialog.selectedNameFilter() == filters[0]) loadCRTDFile(filename);
if (dialog.selectedNameFilter() == filters[1]) loadNativeCSVFile(filename);
if (dialog.selectedNameFilter() == filters[2]) loadGenericCSVFile(filename);
if (dialog.selectedNameFilter() == filters[3]) loadLogFile(filename);
if (dialog.selectedNameFilter() == filters[4]) loadMicrochipFile(filename);
if (dialog.selectedNameFilter() == filters[0]) result = FrameFileIO::loadCRTDFile(filename, model->getListReference());
if (dialog.selectedNameFilter() == filters[1]) result = FrameFileIO::loadNativeCSVFile(filename, model->getListReference());
if (dialog.selectedNameFilter() == filters[2]) result = FrameFileIO::loadGenericCSVFile(filename, model->getListReference());
if (dialog.selectedNameFilter() == filters[3]) result = FrameFileIO::loadLogFile(filename, model->getListReference());
if (dialog.selectedNameFilter() == filters[4]) result = FrameFileIO::loadMicrochipFile(filename, model->getListReference());
if (result)
{
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
model->sendRefresh();
ui->lbNumFrames->setText(QString::number(model->rowCount()));
if (ui->cbAutoScroll->isChecked()) ui->canFramesView->scrollToBottom();
updateFileStatus();
emit framesUpdated(-2);
}
}
}
@@ -727,6 +323,7 @@ void MainWindow::handleSaveFile()
{
QString filename;
QFileDialog dialog(this);
bool result = false;
QStringList filters;
filters.append(QString(tr("CRTD Logs (*.txt)")));
@@ -742,12 +339,19 @@ void MainWindow::handleSaveFile()
if (dialog.exec() == QDialog::Accepted)
{
QVector<CANFrame> *frames = model->getListReference();
filename = dialog.selectedFiles()[0];
if (dialog.selectedNameFilter() == filters[0]) saveCRTDFile(filename);
if (dialog.selectedNameFilter() == filters[1]) saveNativeCSVFile(filename);
if (dialog.selectedNameFilter() == filters[2]) saveGenericCSVFile(filename);
if (dialog.selectedNameFilter() == filters[3]) saveLogFile(filename);
if (dialog.selectedNameFilter() == filters[4]) saveMicrochipFile(filename);
if (dialog.selectedNameFilter() == filters[0]) result = FrameFileIO::saveCRTDFile(filename, frames);
if (dialog.selectedNameFilter() == filters[1]) result = FrameFileIO::saveNativeCSVFile(filename, frames);
if (dialog.selectedNameFilter() == filters[2]) result = FrameFileIO::saveGenericCSVFile(filename, frames);
if (dialog.selectedNameFilter() == filters[3]) result = FrameFileIO::saveLogFile(filename, frames);
if (dialog.selectedNameFilter() == filters[4]) result = FrameFileIO::saveMicrochipFile(filename, frames);
if (result)
{
QStringList fileList = filename.split('/');
loadedFileName = fileList[fileList.length() - 1];
updateFileStatus();
}
}
}
+2 -12
View File
@@ -1,11 +1,13 @@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "config.h"
#include <QMainWindow>
#include <QSerialPort>
#include <QSerialPortInfo>
#include "canframemodel.h"
#include "can_structs.h"
#include "framefileio.h"
#include "graphingwindow.h"
#include "frameinfowindow.h"
#include "frameplaybackwindow.h"
@@ -14,8 +16,6 @@
#include "dbchandler.h"
#include "dbcmaineditor.h"
#define VERSION 111
namespace Ui {
class MainWindow;
}
@@ -102,16 +102,6 @@ private:
bool isConnected;
//private methods
void loadCRTDFile(QString);
void loadNativeCSVFile(QString);
void loadGenericCSVFile(QString);
void loadLogFile(QString);
void loadMicrochipFile(QString);
void saveCRTDFile(QString);
void saveNativeCSVFile(QString);
void saveGenericCSVFile(QString);
void saveLogFile(QString);
void saveMicrochipFile(QString);
void saveDecodedTextFile(QString);
void addFrameToDisplay(CANFrame &, bool);
void updateFileStatus();