Fixes to ISO-TP decoding
This commit is contained in:
@@ -9,7 +9,6 @@ ISOTP_HANDLER::ISOTP_HANDLER()
|
|||||||
processAll = false;
|
processAll = false;
|
||||||
lastSenderBus = 0;
|
lastSenderBus = 0;
|
||||||
lastSenderID = 0;
|
lastSenderID = 0;
|
||||||
issuedMultiFrame = false;
|
|
||||||
|
|
||||||
modelFrames = MainWindow::getReference()->getCANFrameModel()->getListReference();
|
modelFrames = MainWindow::getReference()->getCANFrameModel()->getListReference();
|
||||||
|
|
||||||
@@ -62,7 +61,6 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector<unsigned char> data)
|
|||||||
|
|
||||||
if (data.length() < 8)
|
if (data.length() < 8)
|
||||||
{
|
{
|
||||||
issuedMultiFrame = false;
|
|
||||||
frame.bus = bus;
|
frame.bus = bus;
|
||||||
frame.ID = ID;
|
frame.ID = ID;
|
||||||
if (ID > 0x7FF) frame.extended = true;
|
if (ID > 0x7FF) frame.extended = true;
|
||||||
@@ -75,7 +73,6 @@ void ISOTP_HANDLER::sendISOTPFrame(int bus, int ID, QVector<unsigned char> data)
|
|||||||
}
|
}
|
||||||
else //need to send a multi-part ISO_TP message - Respects timing and frame number based flow control
|
else //need to send a multi-part ISO_TP message - Respects timing and frame number based flow control
|
||||||
{
|
{
|
||||||
issuedMultiFrame = true;
|
|
||||||
frame.bus = bus;
|
frame.bus = bus;
|
||||||
frame.ID = ID;
|
frame.ID = ID;
|
||||||
if (ID > 0x7FF) frame.extended = true;
|
if (ID > 0x7FF) frame.extended = true;
|
||||||
@@ -194,6 +191,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
msg.len = frameLen;
|
msg.len = frameLen;
|
||||||
msg.data.reserve(frameLen);
|
msg.data.reserve(frameLen);
|
||||||
msg.timestamp = frame.timestamp;
|
msg.timestamp = frame.timestamp;
|
||||||
|
msg.isMultiframe = false;
|
||||||
if (useExtendedAddressing) for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+2]);
|
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]);
|
else for (int j = 0; j < frameLen; j++) msg.data.append(frame.data[j+1]);
|
||||||
//qDebug() << "Emitting single frame ISOTP message";
|
//qDebug() << "Emitting single frame ISOTP message";
|
||||||
@@ -206,7 +204,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
msg.ID = ID;
|
msg.ID = ID;
|
||||||
msg.timestamp = frame.timestamp;
|
msg.timestamp = frame.timestamp;
|
||||||
msg.isReceived = frame.isReceived;
|
msg.isReceived = frame.isReceived;
|
||||||
issuedMultiFrame = true;
|
msg.isMultiframe = true;
|
||||||
frameLen = frameLen << 8;
|
frameLen = frameLen << 8;
|
||||||
if (useExtendedAddressing)
|
if (useExtendedAddressing)
|
||||||
{
|
{
|
||||||
@@ -224,10 +222,11 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
msg.data.reserve(frameLen);
|
msg.data.reserve(frameLen);
|
||||||
for (int j = 0; j < 6; j++) msg.data.append(frame.data[2 + j]);
|
for (int j = 0; j < 6; j++) msg.data.append(frame.data[2 + j]);
|
||||||
}
|
}
|
||||||
|
msg.lastSequence = -1;
|
||||||
messageBuffer.append(msg);
|
messageBuffer.append(msg);
|
||||||
//The sending ID is set to the last ID we used to send from this class which is
|
//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.
|
//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;
|
CANFrame outFrame;
|
||||||
outFrame.bus = lastSenderBus;
|
outFrame.bus = lastSenderBus;
|
||||||
@@ -252,6 +251,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pMsg) return;
|
if (!pMsg) return;
|
||||||
|
if (!pMsg->isMultiframe) return; //if we didn't get a frame type 1 (start of multiframe) first then ignore this frame.
|
||||||
ln = pMsg->len - pMsg->data.count();
|
ln = pMsg->len - pMsg->data.count();
|
||||||
//offset = pMsg->data.count();
|
//offset = pMsg->data.count();
|
||||||
if (useExtendedAddressing)
|
if (useExtendedAddressing)
|
||||||
@@ -267,8 +267,7 @@ void ISOTP_HANDLER::processFrame(const CANFrame &frame)
|
|||||||
if (pMsg->len <= pMsg->data.count())
|
if (pMsg->len <= pMsg->data.count())
|
||||||
{
|
{
|
||||||
//qDebug() << "Emitting multiframe ISOTP message";
|
//qDebug() << "Emitting multiframe ISOTP message";
|
||||||
issuedMultiFrame = false;
|
checkNeedFlush(pMsg->ID);
|
||||||
emit newISOMessage(*pMsg);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3: //flow control messages
|
case 3: //flow control messages
|
||||||
@@ -306,9 +305,18 @@ void ISOTP_HANDLER::checkNeedFlush(uint64_t ID)
|
|||||||
if (messageBuffer[i].ID == ID)
|
if (messageBuffer[i].ID == ID)
|
||||||
{
|
{
|
||||||
//used to pass by reference but now newISOMessage should pass by value which makes it easier to use cross thread
|
//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].ID > 0x600 && messageBuffer[i].ID < 0x630)
|
||||||
|
{
|
||||||
|
if (messageBuffer[i].len <= messageBuffer[i].data.count())
|
||||||
|
{
|
||||||
|
qDebug() << "Flushing full frame" << QString::number(messageBuffer[i].ID, 16) << " " << messageBuffer[i].len << " " << messageBuffer[i].data.count();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Flushing a partial frame " << QString::number(messageBuffer[i].ID, 16) << " " << messageBuffer[i].len << " " << messageBuffer[i].data.count();
|
||||||
|
}
|
||||||
|
}
|
||||||
emit newISOMessage(messageBuffer[i]);
|
emit newISOMessage(messageBuffer[i]);
|
||||||
issuedMultiFrame = false;
|
|
||||||
messageBuffer.removeAt(i);
|
messageBuffer.removeAt(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ private:
|
|||||||
int framesUntilFlow;
|
int framesUntilFlow;
|
||||||
bool processAll;
|
bool processAll;
|
||||||
bool issueFlowMsgs;
|
bool issueFlowMsgs;
|
||||||
bool issuedMultiFrame;
|
|
||||||
QTimer frameTimer;
|
QTimer frameTimer;
|
||||||
uint32_t lastSenderID;
|
uint32_t lastSenderID;
|
||||||
uint32_t lastSenderBus;
|
uint32_t lastSenderBus;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ public:
|
|||||||
bool isReceived;
|
bool isReceived;
|
||||||
int len; //# of bytes this message should have (as reported)
|
int len; //# of bytes this message should have (as reported)
|
||||||
int actualSize; //# we actually got
|
int actualSize; //# we actually got
|
||||||
|
int lastSequence;
|
||||||
|
bool isMultiframe;
|
||||||
QVector<unsigned char> data;
|
QVector<unsigned char> data;
|
||||||
uint64_t timestamp;
|
uint64_t timestamp;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ static QVector<CODE_STRUCT> UDS_SERVICE_DESC = {
|
|||||||
{0x19, "READ_DTC", "Read diagnostic trouble codes"},
|
{0x19, "READ_DTC", "Read diagnostic trouble codes"},
|
||||||
{0x1A, "GMLAN_READ_DIAGNOSTIC_ID", "GMLAN - Read diagnostics ID"},
|
{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"},
|
{0x22, "READ_BY_ID", "Read data by ID"},
|
||||||
{0x23, "READ_BY_ADDR", "Read data by address"},
|
{0x23, "READ_BY_ADDR", "Read data by address"},
|
||||||
{0x24, "READ_SCALING_ID", "Read scaling data by ID"},
|
{0x24, "READ_SCALING_ID", "Read scaling data by ID"},
|
||||||
@@ -184,6 +185,10 @@ void UDS_HANDLER::gotISOTPFrame(ISOTP_MESSAGE msg)
|
|||||||
udsMsg.isReceived = msg.isReceived;
|
udsMsg.isReceived = msg.isReceived;
|
||||||
udsMsg.timestamp = msg.timestamp;
|
udsMsg.timestamp = msg.timestamp;
|
||||||
udsMsg.actualSize = msg.actualSize;
|
udsMsg.actualSize = msg.actualSize;
|
||||||
|
udsMsg.service = 0;
|
||||||
|
udsMsg.subFunc = 0;
|
||||||
|
udsMsg.subFuncLen = 0;
|
||||||
|
udsMsg.isErrorReply = false;
|
||||||
udsMsg.len = msg.len;
|
udsMsg.len = msg.len;
|
||||||
if (msg.data.length() > 0) {
|
if (msg.data.length() > 0) {
|
||||||
udsMsg.service = msg.data.at(0);
|
udsMsg.service = msg.data.at(0);
|
||||||
|
|||||||
@@ -61,7 +61,21 @@ void ISOTP_InterpreterWindow::showEvent(QShowEvent* event)
|
|||||||
{
|
{
|
||||||
QDialog::showEvent(event);
|
QDialog::showEvent(event);
|
||||||
readSettings();
|
readSettings();
|
||||||
|
|
||||||
|
QProgressDialog progress(qApp->activeWindow());
|
||||||
|
progress.setWindowModality(Qt::WindowModal);
|
||||||
|
progress.setLabelText("Analyzing Frames...");
|
||||||
|
progress.setCancelButton(nullptr);
|
||||||
|
progress.setRange(0,0);
|
||||||
|
progress.setMinimumDuration(0);
|
||||||
|
progress.show();
|
||||||
|
|
||||||
|
qApp->processEvents();
|
||||||
|
|
||||||
decoder->updatedFrames(-2);
|
decoder->updatedFrames(-2);
|
||||||
|
|
||||||
|
progress.cancel();
|
||||||
|
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,7 +148,7 @@ void ISOTP_InterpreterWindow::filterAll()
|
|||||||
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
||||||
{
|
{
|
||||||
ui->listFilter->item(i)->setCheckState(Qt::Checked);
|
ui->listFilter->item(i)->setCheckState(Qt::Checked);
|
||||||
idFilters[ui->listFilter->item(1)->text().toInt(nullptr, 16)] = true;
|
//idFilters[ui->listFilter->item(i)->text().toInt(nullptr, 16)] = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,7 +157,7 @@ void ISOTP_InterpreterWindow::filterNone()
|
|||||||
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
for (int i = 0 ; i < ui->listFilter->count(); i++)
|
||||||
{
|
{
|
||||||
ui->listFilter->item(i)->setCheckState(Qt::Unchecked);
|
ui->listFilter->item(i)->setCheckState(Qt::Unchecked);
|
||||||
idFilters[ui->listFilter->item(1)->text().toInt(nullptr, 16)] = false;
|
//idFilters[ui->listFilter->item(i)->text().toInt(nullptr, 16)] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -362,13 +362,13 @@ void UDSScanWindow::gotUDSReply(UDS_MESSAGE msg)
|
|||||||
|
|
||||||
id = msg.ID;
|
id = msg.ID;
|
||||||
|
|
||||||
qDebug() << "UDS message ID " << msg.ID << " service: " << msg.service << " subfunc: " << msg.subFunc;
|
qDebug() << "UDS message ID " << QString::number(msg.ID,16) << " service: " << QString::number(msg.service, 16) << " subfunc: " << QString::number(msg.subFunc, 16);
|
||||||
|
|
||||||
if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked())
|
if ((id == (uint32_t)(sentFrame.ID + offset)) || ui->cbAllowAdaptiveOffset->isChecked())
|
||||||
{
|
{
|
||||||
serviceShortName = udsHandler->getServiceShortDesc(sentFrame.service);
|
serviceShortName = udsHandler->getServiceShortDesc(sentFrame.service);
|
||||||
if (serviceShortName.length() < 3) serviceShortName = QString::number(sentFrame.service, 16);
|
if (serviceShortName.length() < 3) serviceShortName = QString::number(sentFrame.service, 16);
|
||||||
if (msg.service == 0x40 + sendingFrames[currIdx].service)
|
if (msg.service == (0x40 + sendingFrames[currIdx].service) )
|
||||||
{
|
{
|
||||||
setupNodes(id);
|
setupNodes(id);
|
||||||
|
|
||||||
@@ -385,7 +385,7 @@ void UDSScanWindow::gotUDSReply(UDS_MESSAGE msg)
|
|||||||
nodeSubFunc->setForeground(0, QBrush(Qt::darkGreen));
|
nodeSubFunc->setForeground(0, QBrush(Qt::darkGreen));
|
||||||
gotReply = true;
|
gotReply = true;
|
||||||
}
|
}
|
||||||
else if ( msg.isErrorReply && msg.service == sendingFrames[currIdx].service)
|
else if ( msg.isErrorReply && (msg.service == sendingFrames[currIdx].service) )
|
||||||
{
|
{
|
||||||
if (msg.data.length())
|
if (msg.data.length())
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user