#include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); app.setApplicationName("CANDUmpPlayer"); app.setApplicationVersion("1.0"); QCommandLineParser parser; parser.addHelpOption(); parser.addVersionOption(); parser.addPositionalArgument("can_interface", "CAN device"); parser.addPositionalArgument("candump_file", "Input CAN dump file"); parser.process(app); const QStringList args = parser.positionalArguments(); if (args.length() != 2) { qCritical().noquote() << Qt::endl << QString("ERROR: incorrect number of arguments (expected 2, but received %1)").arg(args.length()) << Qt::endl; parser.showHelp(1); return 1; } QString error; QSharedPointer can_device(QCanBus::instance()->createDevice(QStringLiteral("socketcan"), args.at(0), &error)); if (can_device == nullptr) { qCritical().noquote() << QString("ERROR: could not open CAN device %1 (error=%2)").arg(args.at(0)).arg(error); return 1; } can_device->setConfigurationParameter(QCanBusDevice::CanFdKey, false); can_device->setConfigurationParameter(QCanBusDevice::BitRateKey, 250000); can_device->connectDevice(); QFile can_file(args.at(1)); if (can_file.open(QIODevice::ReadOnly | QIODevice::Text) == false) { qCritical().noquote() << QString("ERROR: could not open input CAN dump file %1").arg(args.at(1)); return 1; } QTextStream stream(&can_file); QString line; const QRegularExpression regexEntry("^\\s*\\((?.+)\\)\\s+(?\\S+)\\s+(?\\S+)\\s+\\[(?\\S+)\\]\\s+(?.*)$"); const QRegularExpression regexPayload("(?:\\s*)(\\S+)"); unsigned int lineCount = 1; while (stream.readLineInto(&line)) { auto match = regexEntry.match(line); if (match.hasMatch()) { // qDebug().noquote() << " timestamp=" << match.captured(QStringLiteral("timestamp")); // qDebug().noquote() << " device=" << match.captured(QStringLiteral("device")); // qDebug().noquote() << " can_id=" << match.captured(QStringLiteral("can_id")); // qDebug().noquote() << " size=" << match.captured(QStringLiteral("size")); // qDebug().noquote() << " payload=" << match.captured(QStringLiteral("payload")); QByteArray payload; auto it = regexPayload.globalMatch(match.captured(QStringLiteral("payload"))); while (it.hasNext()) { auto payloadMatch = it.next(); payload.append(payloadMatch.captured(1).toUInt(nullptr, 16)); } const unsigned int can_id = match.captured(QStringLiteral("can_id")).toUInt(nullptr, 16); QCanBusFrame frame(can_id, payload); can_device->writeFrame(frame); } else { qWarning().noquote() << QString("WARNING: \"%1\" (line %2) did not match expected format").arg(line).arg(lineCount); } lineCount++; } can_file.close(); can_device->disconnectDevice(); // Set up code that uses the Qt event loop here. // Call a.quit() or a.exit() to quit the application. // A not very useful example would be including // #include // near the top of the file and calling // QTimer::singleShot(5000, &a, &QCoreApplication::quit); // which quits the application after 5 seconds. // If you do not need a running Qt event loop, remove the call // to a.exec() or use the Non-Qt Plain C++ Application template. return 0; }