diff -Nru dlt-viewer-2.25.0+dfsg/debian/changelog dlt-viewer-2.25.0+dfsg/debian/changelog --- dlt-viewer-2.25.0+dfsg/debian/changelog 2023-11-10 13:39:51.000000000 +0000 +++ dlt-viewer-2.25.0+dfsg/debian/changelog 2024-01-18 21:27:00.000000000 +0000 @@ -1,8 +1,14 @@ -dlt-viewer (2.25.0+dfsg-1~bpo22.04.1~ppa1) jammy; urgency=medium +dlt-viewer (2.25.0+dfsg-2~bpo22.04.1~ppa1) jammy; urgency=medium * No-change backport to jammy. - -- Gianfranco Costamagna Fri, 10 Nov 2023 14:39:51 +0100 + -- Gianfranco Costamagna Thu, 18 Jan 2024 22:27:00 +0100 + +dlt-viewer (2.25.0+dfsg-2) unstable; urgency=medium + + * Package real 2.25.0 tag as Debian specific patch + + -- Gianfranco Costamagna Thu, 18 Jan 2024 12:08:30 +0100 dlt-viewer (2.25.0+dfsg-1) unstable; urgency=medium diff -Nru dlt-viewer-2.25.0+dfsg/debian/patches/2.25.0-real.patch dlt-viewer-2.25.0+dfsg/debian/patches/2.25.0-real.patch --- dlt-viewer-2.25.0+dfsg/debian/patches/2.25.0-real.patch 1970-01-01 00:00:00.000000000 +0000 +++ dlt-viewer-2.25.0+dfsg/debian/patches/2.25.0-real.patch 2024-01-18 11:08:02.000000000 +0000 @@ -0,0 +1,1663 @@ +Description: For some reasons a wrong 2.25.0 tag was pushed on github. + This is the real version 2.25.0 dated 2023/12/14 a1778c6d5cd09ac1a1ed86576710dc1e6e38216f +Author: Gianfranco Costamagna +Origin: upstream +Forwarded: not-needed +Last-Update: 2024-01-18 + +--- /dev/null ++++ dlt-viewer-2.25.0+dfsg/.github/release.yml +@@ -0,0 +1,16 @@ ++changelog: ++ exclude: ++ labels: ++ - ignore-for-release ++ authors: ++ - someuser ++ categories: ++ - title: Breaking Changes 🛠 ++ labels: ++ - breaking-change ++ - title: Exciting New Features 🎉 ++ labels: ++ - enhancement ++ - title: Other Changes ++ labels: ++ - "*" +\ No newline at end of file +--- dlt-viewer-2.25.0+dfsg.orig/.github/workflows/BuildPR.yml ++++ dlt-viewer-2.25.0+dfsg/.github/workflows/BuildPR.yml +@@ -18,7 +18,7 @@ jobs: + xcode: [ Xcode_14.1.0 ] + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -47,7 +47,7 @@ jobs: + runs-on: ${{ matrix.ubuntu }} + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -72,7 +72,7 @@ jobs: + runs-on: windows-2019 + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +--- dlt-viewer-2.25.0+dfsg.orig/.github/workflows/Release.yml ++++ dlt-viewer-2.25.0+dfsg/.github/workflows/Release.yml +@@ -15,7 +15,7 @@ jobs: + xcode: [ Xcode_14.1.0 ] + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -45,7 +45,7 @@ jobs: + runs-on: ${{ matrix.ubuntu }} + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -71,7 +71,7 @@ jobs: + runs-on: windows-2019 + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -100,7 +100,7 @@ jobs: + needs: [ buildMac, buildLinux, buildWindows ] + steps: + - name: Checkout +- uses: actions/checkout@v3 ++ uses: actions/checkout@v4 + with: + fetch-depth: 0 + submodules: true +@@ -120,11 +120,33 @@ jobs: + uses: actions/download-artifact@v3 + with: + name: DLT-Windows-sdk +- - run: | +- assetsZip=$(find . -name 'DLT*.zip' | xargs -I asset echo "-a asset" | xargs) +- VERSION=$(echo $VERSION | cut -d'/' -f3) +- tag_name="${GITHUB_REF##*/}" +- hub release create ${assetsZip} -m "$tag_name" "$tag_name" ++ ++ - name: Find Tag ++ id: tagger ++ uses: jimschubert/query-tag-action@v2 ++ with: ++ skip-unshallow: 'true' ++ abbrev: false ++ commit-ish: HEAD ++ - name: Check pre-release ++ run: | ++ echo "tag=${{steps.tagger.outputs.tag}}" ++ if [[ ${{ steps.tagger.outputs.tag }} == *alpha* || ${{ steps.tagger.outputs.tag }} == *beta* ]] ++ then ++ prerelease=true ++ else ++ prerelease=false ++ fi ++ echo "PRE_RELEASE=$prerelease" >> $GITHUB_ENV ++ echo "prerelease=$prerelease" ++ - name: Create Release ++ uses: softprops/action-gh-release@v1 ++ with: ++ tag_name: ${{steps.tagger.outputs.tag}} ++ generate_release_notes: true ++ prerelease: ${{ env.PRE_RELEASE }} ++ name: ${{steps.tagger.outputs.tag}} ++ files: | ++ DLT-* + env: +- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +- VERSION: ${{ github.ref }} ++ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +\ No newline at end of file +--- dlt-viewer-2.25.0+dfsg.orig/INSTALL.md ++++ dlt-viewer-2.25.0+dfsg/INSTALL.md +@@ -5,7 +5,7 @@ Alexander Wenzel + + Version + ------- +-Version 2.24.0 RELEASE ++Version 2.25.0 RELEASE + + + Known issues +@@ -16,6 +16,37 @@ Known issues + + Changes + ------- ++2.25.0 ++ ++ * Experimental IPC import from PCAP file ++ * filetransferplugin: Present save popup once (#392) ++ * Fixes a bug where doFLDA was erroneously called on messages ending ++ * Adds FiletransferPlugin::doFLFI which emits a new signal ++ * Allow passing multiple dlt files on commandline (#390) ++ * More search history (#388) ++ * Add more keyboard shortcuts (#387) ++ * Add shortcut to focus search input ++ * Add shortcut to apply config ++ * Add filter shortcut ++ * Improve speed of non verbose plugin Fibex loader (#386) ++ * Fix non-monotonic timestamps under Windows ++ * Remove Linefeeds and Cariage Returns in CSV Export of ECUId, AppId and CtxId. ++ * Fix also Timezone export for CSV and Jira ++ * Fix to use configured timezone during export ++ * Import from PCAP file ++ * Disable Completer in Injection Dialog ++ * Update INSTALL.md ++ * Release with auto. generated changelog ++ * Merge pull request #373 from SangTruongTan/build-on-apple-silicon ++ * No viable conversion from 'QDltDataView' to 'QByteArray' ++ * Revert "Build on Apple Silicon" ++ * Build on Apple Silicon ++ * Show cmake version ++ * Fix release on CI ++ * Code format ++ * Improved speed when loading DLT files, when plugins and filters are disabled ++ * bugfix: install qt5 dev packages manually since qt5-default is not available ++ + 2.24.0 + + * Close ECU connections before loading new project to prevent crash of DLT Viewer. +--- dlt-viewer-2.25.0+dfsg.orig/plugin/filetransferplugin/file.cpp ++++ dlt-viewer-2.25.0+dfsg/plugin/filetransferplugin/file.cpp +@@ -41,7 +41,6 @@ File::File(QDltFile *qfile,QTreeWidgetIt + receivedPackages = 0; + fileSerialNumber = 0; + packages = 0; +- receivedPackages = 0; + sizeInBytes = 0; + buffer = 0; + dltFileIndex = NULL; +@@ -76,7 +75,7 @@ QString File::getFileSerialNumber(){ + + return str; + } +-unsigned int File:: getPackages(){ ++unsigned int File::getPackages(){ + return packages; + } + unsigned int File::getReceivedPackages(){ +@@ -90,7 +89,6 @@ unsigned int File::getBufferSize(){ + } + + +- + void File::setFilename(QString f){ + filenameWithPath = f; + this->setText(COLUMN_FILENAME, filenameWithPath); +@@ -161,7 +159,7 @@ bool File::isComplete(){ + + void File::setQFileIndexForPackage(QString packageNumber, int index){ + int i = packageNumber.toInt(); +- dltFileIndex->insert(i-1,index); ++ dltFileIndex->insert(i-1, index); + increaseReceivedPackages(); + } + +--- dlt-viewer-2.25.0+dfsg.orig/plugin/filetransferplugin/filetransferplugin.cpp ++++ dlt-viewer-2.25.0+dfsg/plugin/filetransferplugin/filetransferplugin.cpp +@@ -295,7 +295,7 @@ void FiletransferPlugin::updateFiletrans + msg.getArgument(PROTOCOL_FLFI_ENDFLAG,msgLastArgument); + if(msgLastArgument.toString().compare(config.getFlfiTag()) == 0) + { +- doFLDA(index,&msg); ++ doFLFI(&msg); + } + return; + } +@@ -363,16 +363,19 @@ void FiletransferPlugin::doFLDA(int inde + msg->getArgument(PROTOCOL_FLDA_FILEID,argument); + msg->getArgument(PROTOCOL_FLDA_PACKAGENR,packageNumber); + +- emit(form->handleupdate_signal(argument.toString(),packageNumber.toString(), index )); ++ emit(form->handleupdate_signal(argument.toString(), packageNumber.toString(), index )); + return; + } +- +-void FiletransferPlugin::doFLIF(QDltMsg *msg) +-{ ++void FiletransferPlugin::doFLIF(QDltMsg *msg) { + Q_UNUSED(msg); ++ //not implemented yet. Would handle extended file information: file serialnumber, name ,size, creation date ++} + +-//empty. +-//not implemented yet. Would handle extended file information: file serialnumber, name ,size, creation date, number of packages ++void FiletransferPlugin::doFLFI(QDltMsg *msg) ++{ ++ QDltArgument id; ++ msg->getArgument(PROTOCOL_FLFI_FILEID, id); ++ emit(form->handlefinish_signal(id.toString())); + } + + void FiletransferPlugin::doFLER(QDltMsg *msg) +--- dlt-viewer-2.25.0+dfsg.orig/plugin/filetransferplugin/filetransferplugin.h ++++ dlt-viewer-2.25.0+dfsg/plugin/filetransferplugin/filetransferplugin.h +@@ -96,6 +96,7 @@ private: + void doFLST(QDltMsg *msg); // file transfer start + void doFLDA(int index, QDltMsg *msg); // file transfer update + void doFLIF(QDltMsg *msg); ++ void doFLFI(QDltMsg *msg); + void doFLER(QDltMsg *msg); // file transfer error handling + + Configuration config; +--- dlt-viewer-2.25.0+dfsg.orig/plugin/filetransferplugin/form.cpp ++++ dlt-viewer-2.25.0+dfsg/plugin/filetransferplugin/form.cpp +@@ -53,6 +53,7 @@ Form::Form(QWidget *parent) : + + connect(this, SIGNAL( additem_signal(File *)), this, SLOT(additem_slot(File *) ) ); + connect(this, SIGNAL( handleupdate_signal(QString, QString, int)), this, SLOT(updatefile_slot(QString,QString,int) ) ); ++ connect(this, SIGNAL( handlefinish_signal(QString)), this, SLOT(finishfile_slot(QString) ) ); + connect(this, SIGNAL( export_signal(QDir, QString *, bool * )), this, SLOT(export_slot(QDir, QString *, bool * ) ) ); + connect(this, SIGNAL( handle_errorsignal(QString,QString,QString,QString)), this, SLOT(error_slot(QString,QString,QString,QString) ) ); + } +@@ -175,99 +176,89 @@ void Form::on_saveButton_clicked() + + void Form::savetofile() + { +- QString path = QFileDialog::getExistingDirectory(this, tr("Save file to directory"), QDir::currentPath(), QFileDialog::DontResolveSymlinks); +- if(path != nullptr) ++ QString path = QFileDialog::getExistingDirectory(this, tr("Save file to directory"), ++ QDir::currentPath(), ++ QFileDialog::DontResolveSymlinks); ++ if(path == nullptr) + { +- QDir::setCurrent(path); // because we want to keep the last selected path to offer next time again +- QTreeWidgetItemIterator it(ui->treeWidget,QTreeWidgetItemIterator::NoChildren ); +- QString text; +- QString infoText; +- QString detailedText; +- QMessageBox msgBox; +- QString absolutePath; +- QString FiletoSave; +- File *tmpfile; +- unsigned int number_of_saved_files=0; +- msgBox.setWindowTitle("Filetransfer Plugin"); +- bool errorOccured = true; ++ qDebug()<< "File save cancelled because of invalid path parameter passed to savetofile()"; ++ return; ++ } ++ QDir::setCurrent(path); // because we want to keep the last selected path to offer next time again ++ unsigned int number_of_saved_files = 0; ++ unsigned int number_of_files_not_saved = 0; ++ unsigned int number_of_invalid_handles = 0; ++ QString pathnamesSavedText; ++ QString pathnamesNotSavedText; ++ QString invalidHandles; ++ QString incompleteFiles; ++ bool triedToSaveIncomplete = false; + +- while (*it) ++ for (QTreeWidgetItemIterator it(ui->treeWidget,QTreeWidgetItemIterator::NoChildren); *it ; ++it) ++ { ++ File * tmpfile = dynamic_cast(*it); ++ if (tmpfile == NULL) + { +- tmpfile = dynamic_cast(*it); +- if (tmpfile == NULL) +- { +- qDebug()<< "File handle is NULL"; +- msgBox.setIcon(QMessageBox::Critical); +- text += ("Not vaild file selected"); +- msgBox.setText(text); +- msgBox.setStandardButtons(QMessageBox::Ok); +- msgBox.setDefaultButton(QMessageBox::Ok); +- msgBox.exec(); +- } +- else if ( !tmpfile->isComplete() && (tmpfile->checkState(COLUMN_CHECK) == Qt::Checked)) ++ ++number_of_invalid_handles; ++ invalidHandles += tmpfile->getFilename() + "\n"; ++ } ++ else if ( !tmpfile->isComplete() && tmpfile->checkState(COLUMN_CHECK) == Qt::Checked) ++ { ++ triedToSaveIncomplete = true; ++ incompleteFiles += tmpfile->getFilename() + "\n"; ++ } ++ else if (tmpfile->checkState(COLUMN_CHECK) == Qt::Checked) ++ { ++ QString absolutePath = path + "//" + tmpfile->getFilename(); ++ if(!tmpfile->saveFile(absolutePath) ) + { +- // if it is not selected we do not care ... +- FiletoSave = tmpfile->getFilename(); +- qDebug()<< "File is not complete" << FiletoSave; +- msgBox.setIcon(QMessageBox::Critical); +- text += ("File is not complete: "); +- text += FiletoSave; +- msgBox.setText(text); +- msgBox.setStandardButtons(QMessageBox::Ok); +- msgBox.setDefaultButton(QMessageBox::Ok); +- msgBox.exec(); ++ ++number_of_files_not_saved; ++ pathnamesNotSavedText += tmpfile->getFilename() + "\n"; + } +- else if (tmpfile->checkState(COLUMN_CHECK) == Qt::Checked) +- { +- FiletoSave = tmpfile->getFilename(); +- absolutePath = path+"//"+FiletoSave; +- if(!tmpfile->saveFile(absolutePath) ) +- { +- qDebug()<< "File save incomplete: " << FiletoSave; +- text = ("File save incomplete"); +- infoText ="The selected file "+FiletoSave+ " was not saved to "+path+".\n"; +- detailedText = tmpfile->getFilenameOnTarget() + "\n"; +- msgBox.setIcon(QMessageBox::Critical); +- msgBox.setText(text); +- msgBox.setInformativeText(infoText); +- msgBox.setDetailedText(detailedText); +- msgBox.setStandardButtons(QMessageBox::Ok); +- msgBox.setDefaultButton(QMessageBox::Ok); +- msgBox.exec(); +- } +- else +- { +- qDebug()<< "Successfully saved " << FiletoSave; +- number_of_saved_files++; +- errorOccured = false; // we indicate that at least one file save was successful +- } +- } +- else // file is not marked ++ else + { +- FiletoSave = tmpfile->getFilename(); +- qDebug()<< "File " << FiletoSave << " not marked for save"; ++ ++number_of_saved_files; ++ pathnamesSavedText += tmpfile->getFilename() + "\n"; + } +- ++it; +- } // while +- +- if(false == errorOccured ) // no error ++ } ++ else // file is not marked + { +- msgBox.setIcon(QMessageBox::Information); +- text = ("Save successful"); +- infoText = QString("%1 selected files were saved to %2\n").arg(number_of_saved_files).arg(path); +- msgBox.setText(text); +- msgBox.setInformativeText(infoText); +- msgBox.setDetailedText(""); +- msgBox.setStandardButtons(QMessageBox::Ok); +- msgBox.setDefaultButton(QMessageBox::Ok); +- msgBox.exec(); ++ qDebug()<< "File " << tmpfile->getFilename() << " not marked for save"; + } +- }// if path +- else +- { +- qDebug()<< "Filesave canceled"; + } +- return; // void, but anyway ... ++ ++ /* Done or not, present popup here only once: */ ++ QString text; ++ QString infoText; ++ QString detailedText; ++ QMessageBox msgBox; ++ msgBox.setWindowTitle("Filetransfer Plugin"); ++ msgBox.setIcon(QMessageBox::Information); ++ msgBox.setText("Save successful"); ++ infoText += "Destination path: " + path + "\n"; ++ if (number_of_files_not_saved || triedToSaveIncomplete || number_of_invalid_handles) { ++ msgBox.setIcon(QMessageBox::Critical); ++ msgBox.setText("Errors were encountered"); ++ if (number_of_files_not_saved) { ++ detailedText += "These files were not saved to " + path + ":\n" + incompleteFiles + "\n"; ++ } ++ if (triedToSaveIncomplete) { ++ detailedText += "These files were incomplete and were not saved:\n" + pathnamesNotSavedText + "\n"; ++ } ++ if (number_of_invalid_handles) { ++ detailedText += "These files had invalid handles and were not saved:\n" + invalidHandles + "\n"; ++ } ++ } ++ if (number_of_saved_files) { ++ infoText += QString("%1 selected files were saved to %2\n").arg(number_of_saved_files).arg(path); ++ } ++ ++ msgBox.setInformativeText(infoText); ++ msgBox.setDetailedText(detailedText); ++ msgBox.setStandardButtons(QMessageBox::Ok); ++ msgBox.setDefaultButton(QMessageBox::Ok); ++ msgBox.exec(); ++ return; + } + + +@@ -408,26 +399,30 @@ void Form::updatefile_slot(QString files + else + { + File *file = (File*)result.at(0); +- if(false == file->isComplete()) ++ if (false == file->isComplete()) + { +- file->setQFileIndexForPackage(packetnumber,index); ++ file->setQFileIndexForPackage(packetnumber, index); + } +- else +- { +- qDebug() << "Received file" << file->getFilename(); +- file->setComplete(); +- if ( true == autosave ) +- { +- QString path = savepath +"//"+ file->getFilename(); +- if ( false == file->saveFile(path) ) +- { +- qDebug() << "ERROR saving" << path << __LINE__ << __FILE__; +- } +- else +- { +- qDebug() << "Auto - saved" << path; +- } +- } ++ } ++} ++ ++void Form::finishfile_slot (QString fileid) { ++ QList result = getTreeWidget()->findItems(fileid, Qt::MatchExactly | Qt::MatchRecursive, COLUMN_FILEID); ++ if (result.isEmpty()) { ++ return; ++ } ++ File *file = (File *) result.at(0); ++ if (!file->isComplete()) { ++ return; ++ } ++ ++ file->setComplete(); ++ if (autosave) { ++ QString path = savepath + "//" + file->getFilename(); ++ if ( false == file->saveFile(path) ) { ++ qDebug() << "Unable to save file with ID " << fileid << " at " << path << " " << __LINE__ << __FILE__; ++ } else { ++ qDebug() << fileid << " auto-saved at " << path; + } + } + } +@@ -435,7 +430,6 @@ void Form::updatefile_slot(QString files + + void Form::additem_slot(File *f) + { +- + QList result = getTreeWidget()->findItems(f->getFileSerialNumber(),Qt::MatchExactly | Qt::MatchRecursive,COLUMN_FILEID); + if(true == result.isEmpty()) + { +--- dlt-viewer-2.25.0+dfsg.orig/plugin/filetransferplugin/form.h ++++ dlt-viewer-2.25.0+dfsg/plugin/filetransferplugin/form.h +@@ -45,6 +45,7 @@ signals: + void additem_signal(File *f); + void export_signal(QDir dir, QString *errorText, bool *success); + void handleupdate_signal(QString filestring, QString packetnumber, int index); ++ void handlefinish_signal (QString fileid); + void err_signal(QDltMsg *msg); + void handle_errorsignal(QString filesname, QString errorCode1, QString errorCode2, QString time); + +@@ -70,6 +71,7 @@ private slots: + void on_saveRightButtonClicked(); + void additem_slot(File *f); + void updatefile_slot(QString filestring, QString packetnumber, int index); ++ void finishfile_slot (QString fileid); + void export_slot(QDir dir, QString *errorText, bool *success); + void error_slot(QString filesname, QString errorCode1, QString errorCode2, QString time); + }; +--- dlt-viewer-2.25.0+dfsg.orig/plugin/nonverboseplugin/nonverboseplugin.cpp ++++ dlt-viewer-2.25.0+dfsg/plugin/nonverboseplugin/nonverboseplugin.cpp +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + + #include "nonverboseplugin.h" + #include "dlt_protocol.h" +@@ -122,6 +123,8 @@ bool NonverbosePlugin::parseFile(QString + DltFibexPdu *pdu = 0; + DltFibexFrame *frame = 0; + ++ qDebug() << "Start loading Fibex XML " << filename; ++ + QXmlStreamReader xml(&file); + while (!xml.atEnd()) { + xml.readNext(); +@@ -430,12 +433,15 @@ bool NonverbosePlugin::parseFile(QString + + file.close(); + ++ qDebug() << "Finish loading Fibex XML."; ++ + if (warning_text.length()){ + warning_text.chop(2); // remove last ", " + m_error_string.append("Duplicated FRAMES ignored: \n").append(warning_text); + ret = true;//it is not breaking the plugin functionality, but could cause wrong decoding. + } + ++ qDebug() << "Start Creating Links"; + /* create PDU Ref links */ + foreach(DltFibexFrame *frame, framemapwithkey) + { +@@ -443,17 +449,15 @@ bool NonverbosePlugin::parseFile(QString + { + foreach(DltFibexPduRef *ref, frame->pdureflist) + { +- foreach(DltFibexPdu *pdu, pdumap) +- { +- if((pdu->id == ref->id)) +- { +- ref->ref = pdu; +- break; +- } ++ QHash::iterator i = pdumap.find(ref->id); ++ while (i != pdumap.end() && i.key() == ref->id) { ++ ref->ref = i.value(); ++ ++i; + } + } + } + } ++ qDebug() << "Finish Creating Links"; + + pdumap.clear(); + +--- dlt-viewer-2.25.0+dfsg.orig/qdlt/qdltconnection.cpp ++++ dlt-viewer-2.25.0+dfsg/qdlt/qdltconnection.cpp +@@ -75,7 +75,8 @@ void QDltConnection::add(const QByteArra + { + bytesReceived += bytes.size(); + +- data = dataView + bytes; ++ QByteArray dataViewArray = dataView; ++ data = dataViewArray + bytes; + + dataView.align(data); + } +--- dlt-viewer-2.25.0+dfsg.orig/qdlt/qdltoptmanager.cpp ++++ dlt-viewer-2.25.0+dfsg/qdlt/qdltoptmanager.cpp +@@ -92,6 +92,7 @@ void QDltOptManager::printUsage() + qDebug()<<" dlt-viewer.exe -s -csv -c c:\\trace\\trace.dlt .\\trace.csv"; + qDebug()<<" dlt-viewer.exe -s -d -f c:\\filter\\filter.dlf -c c:\\trace\\trace.dlt .\\filteredtrace.dlt"; + qDebug()<<" dlt-viewer.exe -p c:\\proj\\export.dlp -l c:\\trace\\trace.dlt -e \"Filetransfer Plugin|export|ftransferdir\""; ++ qDebug()<<" dlt-viewer.exe trace_1.dlt trace_2.dlt"; + #else + qDebug()<<" dlt-viewer -c ./traces/trace.dlt ./trace.txt"; + qDebug()<<" dlt-viewer -s -c -u ./trace/trace.dlt ./trace.txt"; +@@ -100,6 +101,7 @@ void QDltOptManager::printUsage() + qDebug()<<" dlt-viewer -s -csv -c ./trace/trace.dlt ./trace.csv"; + qDebug()<<" dlt-viewer -s -d -f ./filter/filter.dlf -c ./trace/trace.dlt ./filteredtrace.dlt"; + qDebug()<<" dlt-viewer -p ./proj/export.dlp -l ./trace/trace.dlt -e \"Filetransfer Plugin|export|./ftransferdir\""; ++ qDebug()<<" dlt-viewer trace_1.dlt trace_2.dlt"; + #endif + } + +@@ -134,7 +136,8 @@ void QDltOptManager::parse(QStringList * + } + if(opt->at(1).endsWith(".dlt") || opt->at(1).endsWith(".DLT")) + { +- logFile = QString("%1").arg(opt->at(1)); ++ const QString logFile = QString("%1").arg(opt->at(1)); ++ logFiles += logFile; + log = true; + qDebug()<< "Loading logfile " << logFile; + return; +@@ -151,7 +154,7 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(0); + } +- if(str.compare("-s") == 0 || str.compare("--silent") == 0) ++ else if(str.compare("-s") == 0 || str.compare("--silent") == 0) + { + if ( silent_mode == false) + { +@@ -159,12 +162,12 @@ void QDltOptManager::parse(QStringList * + qDebug() << "Enable silent mode"; + } + } +- if(str.compare("-v") == 0 || str.compare("--version") == 0) ++ else if(str.compare("-v") == 0 || str.compare("--version") == 0) + { + printVersion(opt->at(0)); + exit(0); + } +- if(str.compare("-p")==0) ++ else if(str.compare("-p")==0) + { + QString p1 = opt->value(i+1); + +@@ -187,8 +190,9 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(-1); + } ++ i += 1; + } +- if(str.compare("-l")==0) ++ else if(str.compare("-l")==0) + { + if (convert == true) + { +@@ -201,7 +205,8 @@ void QDltOptManager::parse(QStringList * + + if(l1!=nullptr && (l1.endsWith(".dlt")||l1.endsWith(".DLT"))) + { +- logFile = QString("%1").arg(l1); ++ const QString logFile = QString("%1").arg(l1); ++ logFiles += logFile; + QFile Fout(logFile); + if(false == Fout.exists()) + { +@@ -220,8 +225,9 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(-1); + } ++ i += 1; + } +- if(str.compare("-f")==0) ++ else if(str.compare("-f")==0) + { + QString f1 = opt->value(i+1); + +@@ -244,9 +250,9 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(-1); + } +- ++ i += 1; + } +- if(str.compare("-c")==0) ++ else if(str.compare("-c")==0) + { + if (log == true) + { +@@ -281,24 +287,25 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(-1); + } ++ i += 2; + } +- if(str.compare("-u")==0) ++ else if(str.compare("-u")==0) + { + convertionmode = e_UTF8; + } +- if(str.compare("-csv")==0) ++ else if(str.compare("-csv")==0) + { + convertionmode = e_CSV; + } +- if(str.compare("-d")==0) ++ else if(str.compare("-d")==0) + { + convertionmode = e_DLT; + } +- if(str.compare("-dd")==0) ++ else if(str.compare("-dd")==0) + { + convertionmode = e_DDLT; + } +- if(str.compare("-e")==0) ++ else if(str.compare("-e")==0) + { + QString c = opt->value(i+1); + QStringList args = c.split("|"); +@@ -319,7 +326,22 @@ void QDltOptManager::parse(QStringList * + printUsage(); + exit(-1); + } ++ ++i; + } ++ else if(opt->at(i).endsWith(".dlt") || opt->at(i).endsWith(".DLT")) ++ { ++ if (convert == true) ++ { ++ qDebug() << "\nError: Can't use -c and multiple logfiles once\n"; ++ printUsage(); ++ exit(-1); ++ } ++ ++ const QString logFile = QString("%1").arg(opt->at(i)); ++ logFiles += logFile; ++ log = true; ++ qDebug()<< "Loading logfile " << logFile; ++ } + + } // end of for loop + printVersion(opt->at(0)); +@@ -339,7 +361,7 @@ e_convertionmode QDltOptManager::get_con + } + + QString QDltOptManager::getProjectFile(){return projectFile;} +-QString QDltOptManager::getLogFile(){return logFile;} ++QStringList QDltOptManager::getLogFiles(){return logFiles;} + QString QDltOptManager::getFilterFile(){return filterFile;} + QString QDltOptManager::getConvertSourceFile(){return convertSourceFile;} + QString QDltOptManager::getConvertDestFile(){return convertDestFile;} +--- dlt-viewer-2.25.0+dfsg.orig/qdlt/qdltoptmanager.h ++++ dlt-viewer-2.25.0+dfsg/qdlt/qdltoptmanager.h +@@ -55,7 +55,7 @@ public: + e_convertionmode get_convertionmode(); + + QString getProjectFile(); +- QString getLogFile(); ++ QStringList getLogFiles(); + QString getFilterFile(); + QString getConvertSourceFile(); + QString getConvertDestFile(); +@@ -78,7 +78,7 @@ private: + e_convertionmode convertionmode; + + QString projectFile; +- QString logFile; ++ QStringList logFiles; + QString filterFile; + QString convertSourceFile; + QString convertDestFile; +--- dlt-viewer-2.25.0+dfsg.orig/src/dltexporter.cpp ++++ dlt-viewer-2.25.0+dfsg/src/dltexporter.cpp +@@ -9,7 +9,7 @@ + #include "fieldnames.h" + #include "qdltoptmanager.h" + +-DltExporter::DltExporter(QObject *parent) : ++DltExporter::DltExporter(Project *_project,QObject *parent) : + QObject(parent) + { + size = 0; +@@ -21,6 +21,7 @@ DltExporter::DltExporter(QObject *parent + exportSelection = SelectionAll; + starting_index=0; + stoping_index=0; ++ project = _project; + } + + QString DltExporter::escapeCSVValue(QString arg) +@@ -54,12 +55,15 @@ void DltExporter::writeCSVLine(int index + QString text(""); + + text += escapeCSVValue(QString("%1").arg(index)).append(","); +- text += escapeCSVValue(QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0'))).append(","); ++ if( project->settings->automaticTimeSettings == 0 ) ++ text += escapeCSVValue(QString("%1.%2").arg(msg.getGmTimeWithOffsetString(project->settings->utcOffset,project->settings->dst)).arg(msg.getMicroseconds(),6,10,QLatin1Char('0'))).append(","); ++ else ++ text += escapeCSVValue(QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0'))).append(","); + text += escapeCSVValue(QString("%1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0'))).append(","); + text += escapeCSVValue(QString("%1").arg(msg.getMessageCounter())).append(","); +- text += escapeCSVValue(QString("%1").arg(msg.getEcuid())).append(","); +- text += escapeCSVValue(QString("%1").arg(msg.getApid())).append(","); +- text += escapeCSVValue(QString("%1").arg(msg.getCtid())).append(","); ++ text += escapeCSVValue(QString("%1").arg(msg.getEcuid().simplified())).append(","); ++ text += escapeCSVValue(QString("%1").arg(msg.getApid().simplified())).append(","); ++ text += escapeCSVValue(QString("%1").arg(msg.getCtid().simplified())).append(","); + text += escapeCSVValue(QString("%1").arg(msg.getSessionid())).append(","); + text += escapeCSVValue(QString("%1").arg(msg.getTypeString())).append(","); + text += escapeCSVValue(QString("%1").arg(msg.getSubtypeString())).append(","); +@@ -260,7 +264,21 @@ bool DltExporter::exportMsg(unsigned lon + text += QString("%1 ").arg(from->getMsgFilterPos(selectedRows[num])); + else + return false; +- text += msg.toStringHeader(); ++ if( project->settings->automaticTimeSettings == 0 ) ++ text += QString("%1.%2").arg(msg.getGmTimeWithOffsetString(project->settings->utcOffset,project->settings->dst)).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); ++ else ++ text += QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); ++ text += QString(" %1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0')); ++ text += QString(" %1").arg(msg.getMessageCounter()); ++ text += QString(" %1").arg(msg.getEcuid()); ++ text += QString(" %1").arg(msg.getApid()); ++ text += QString(" %1").arg(msg.getCtid()); ++ text += QString(" %1").arg(msg.getSessionid()); ++ text += QString(" %2").arg(msg.getTypeString()); ++ text += QString(" %2").arg(msg.getSubtypeString()); ++ text += QString(" %2").arg(msg.getModeString()); ++ text += QString(" %1").arg(msg.getNumberOfArguments()); ++ + text += " "; + } + text += msg.toStringPayload().trimmed(); +@@ -305,8 +323,11 @@ bool DltExporter::exportMsg(unsigned lon + else + return false; + +- text += "|" + QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),4,10,QLatin1Char('0')) + +- "|" + QString("%1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0')) + ++ if( project->settings->automaticTimeSettings == 0 ) ++ text += "|" + QString("%1.%2").arg(msg.getGmTimeWithOffsetString(project->settings->utcOffset,project->settings->dst)).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); ++ else ++ text += "|" + QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); ++ text += "|" + QString("%1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0')) + + "|" + msg.getEcuid() + + "|" + msg.getApid() + + "|" + msg.getCtid() + +--- dlt-viewer-2.25.0+dfsg.orig/src/dltexporter.h ++++ dlt-viewer-2.25.0+dfsg/src/dltexporter.h +@@ -9,6 +9,7 @@ + #include "qdltfile.h" + #include "qdltmsg.h" + #include "qdltpluginmanager.h" ++#include "project.h" + + class DltExporter : public QObject + { +@@ -53,7 +54,7 @@ public: + /* Default QT constructor. + * Please pass a window as a parameter to parent dialogs correctly. + */ +- explicit DltExporter(QObject *parent = 0); ++ explicit DltExporter(Project *_project,QObject *parent = 0); + + /* Export some messages from QDltFile to a CSV file. + * \param from QDltFile to pull messages from +@@ -85,6 +86,7 @@ private: + QList selectedRows; + DltExporter::DltExportFormat exportFormat; + DltExporter::DltExportSelection exportSelection; ++ Project *project; + }; + + #endif // DLTEXPORTER_H +--- dlt-viewer-2.25.0+dfsg.orig/src/injectiondialog.cpp ++++ dlt-viewer-2.25.0+dfsg/src/injectiondialog.cpp +@@ -21,6 +21,7 @@ + #include "ui_injectiondialog.h" + + #include "qdltsettingsmanager.h" ++#include + + InjectionDialog::InjectionDialog(QString appid,QString conid,QWidget *parent) : + QDialog(parent), +@@ -29,6 +30,12 @@ InjectionDialog::InjectionDialog(QString + ui->setupUi(this); + ui->applicationidComboBox->setEditText(appid); + ui->contextidComboBox->setEditText(conid); ++ ++ ui->applicationidComboBox->setCompleter(NULL); ++ ui->contextidComboBox->setCompleter(NULL); ++ ui->serviceidComboBox->setCompleter(NULL); ++ ui->dataComboBox->setCompleter(NULL); ++ + } + + InjectionDialog::~InjectionDialog() +--- dlt-viewer-2.25.0+dfsg.orig/src/injectiondialog.ui ++++ dlt-viewer-2.25.0+dfsg/src/injectiondialog.ui +@@ -7,14 +7,14 @@ + 0 + 0 + 441 +- 168 ++ 180 + + + + Injection Configuration + + +- ++ + :/icons/png/org.genivi.DLTViewer.png:/icons/png/org.genivi.DLTViewer.png + + +@@ -75,6 +75,9 @@ + + true + ++ ++ false ++ + + + +@@ -89,6 +92,9 @@ + + true + ++ ++ true ++ + + + +@@ -109,7 +115,7 @@ + dataComboBox + + +- ++ + + + +--- dlt-viewer-2.25.0+dfsg.orig/src/mainwindow.cpp ++++ dlt-viewer-2.25.0+dfsg/src/mainwindow.cpp +@@ -469,6 +469,11 @@ void MainWindow::initView() + connect(settingsDlg, SIGNAL(FilterPathChanged()), this, SLOT(on_actionDefault_Filter_Reload_triggered())); + connect(settingsDlg, SIGNAL(PluginsAutoloadChanged()), this, SLOT(triggerPluginsAutoload())); + ++ QAction *focusSearchTextbox = new QAction(this); ++ focusSearchTextbox->setShortcut(Qt::Key_L | Qt::CTRL); ++ connect(focusSearchTextbox, SIGNAL(triggered()), searchTextbox, SLOT(setFocus())); ++ addAction(focusSearchTextbox); ++ + searchComboBox = new QComboBox(); + searchComboBox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + searchComboBox->setLineEdit(searchTextbox); +@@ -484,6 +489,18 @@ void MainWindow::initView() + + /* Update the scrollbutton status */ + updateScrollButton(); ++ ++ /* Add shortcut to apply config */ ++ QAction *applyConfig = new QAction(this); ++ applyConfig->setShortcut(Qt::Key_C | Qt::SHIFT | Qt::CTRL); ++ connect(applyConfig, SIGNAL(triggered()), this, SLOT(on_applyConfig_clicked())); ++ addAction(applyConfig); ++ ++ /* Add shortcut to add filter */ ++ QAction *addFilter = new QAction(this); ++ addFilter->setShortcut(Qt::Key_A | Qt::SHIFT | Qt::CTRL); ++ connect(addFilter, SIGNAL(triggered()), this, SLOT(on_action_menuFilter_Add_triggered())); ++ addAction(addFilter); + } + + void MainWindow::initSignalConnections() +@@ -644,7 +661,9 @@ void MainWindow::initFileHandling() + outputfileIsTemporary = false; + if(QDltOptManager::getInstance()->isLogFile()) + { +- openDltFile(QStringList(QDltOptManager::getInstance()->getLogFile())); ++ QStringList logFiles = QDltOptManager::getInstance()->getLogFiles(); ++ logFiles.sort(); ++ openDltFile(logFiles); + /* Command line file is treated as temp file */ + outputfileIsTemporary = true; + outputfileIsFromCLI = true; +@@ -752,7 +771,7 @@ void MainWindow::commandLineConvertToDLT + QFile dltFile(QDltOptManager::getInstance()->getConvertDestFile()); + + /* start exporter */ +- DltExporter exporter; ++ DltExporter exporter(&project); + qDebug() << "Commandline DLT convert to " << dltFile.fileName(); + //exporter.exportMessages(&qfile,&asciiFile,&pluginManager,DltExporter::FormatAscii,DltExporter::SelectionFiltered); + exporter.exportMessages(&qfile,&dltFile,&pluginManager,DltExporter::FormatDlt,DltExporter::SelectionFiltered); +@@ -771,7 +790,7 @@ void MainWindow::commandLineConvertToASC + QFile asciiFile(QDltOptManager::getInstance()->getConvertDestFile()); + + /* start exporter */ +- DltExporter exporter; ++ DltExporter exporter(&project); + qDebug() << "Commandline ASCII convert to " << asciiFile.fileName(); + exporter.exportMessages(&qfile,&asciiFile,&pluginManager,DltExporter::FormatAscii,DltExporter::SelectionFiltered); + qDebug() << "DLT export ASCII done"; +@@ -788,7 +807,7 @@ void MainWindow::commandLineConvertToCSV + QFile asciiFile(QDltOptManager::getInstance()->getConvertDestFile()); + + /* start exporter */ +- DltExporter exporter; ++ DltExporter exporter(&project); + qDebug() << "Commandline ASCII convert to " << asciiFile.fileName(); + exporter.exportMessages(&qfile,&asciiFile,&pluginManager,DltExporter::FormatCsv,DltExporter::SelectionFiltered); + qDebug() << "DLT export CSV done"; +@@ -805,7 +824,7 @@ void MainWindow::commandLineConvertToUTF + QFile asciiFile(QDltOptManager::getInstance()->getConvertDestFile()); + + /* start exporter */ +- DltExporter exporter; ++ DltExporter exporter(&project); + qDebug() << "Commandline UTF8 convert to " << asciiFile.fileName(); + exporter.exportMessages(&qfile,&asciiFile,&pluginManager,DltExporter::FormatUTF8,DltExporter::SelectionFiltered); + qDebug() << "DLT export UTF8 done"; +@@ -821,7 +840,7 @@ void MainWindow::commandLineConvertToDLT + QFile dltFile(QDltOptManager::getInstance()->getConvertDestFile()); + + /* start exporter */ +- DltExporter exporter; ++ DltExporter exporter(&project); + qDebug() << "Commandline decoding to dlt formated file" << dltFile.fileName(); + exporter.exportMessages(&qfile,&dltFile,&pluginManager,DltExporter::FormatDltDecoded,DltExporter::SelectionFiltered); + qDebug() << "DLT export DLT decoded done"; +@@ -1275,6 +1294,411 @@ void MainWindow::on_action_menuFile_Impo + + } + ++typedef struct pcap_hdr_s { ++ quint32 magic_number; /* magic number */ ++ quint16 version_major; /* major version number */ ++ quint16 version_minor; /* minor version number */ ++ qint32 thiszone; /* GMT to local correction */ ++ quint32 sigfigs; /* accuracy of timestamps */ ++ quint32 snaplen; /* max length of captured packets, in octets */ ++ quint32 network; /* data link type */ ++} PACKED pcap_hdr_t; ++ ++typedef struct pcaprec_hdr_s { ++ quint32 ts_sec; /* timestamp seconds */ ++ quint32 ts_usec; /* timestamp microseconds */ ++ quint32 incl_len; /* number of octets of packet saved in file */ ++ quint32 orig_len; /* actual length of packet */ ++} PACKED pcaprec_hdr_t; ++ ++void MainWindow::on_actionImport_DLT_from_PCAP_triggered() ++{ ++ quint32 counterRecords = 0, counterRecordsDLT = 0, counterDLTMessages = 0; ++ QString fileName = QFileDialog::getOpenFileName(this, ++ tr("Import DLT from PCAP file"), workingDirectory.getDltDirectory(), tr("PCAP file (*.pcap)")); ++ ++ if(fileName.isEmpty()) ++ return; ++ ++ /* change DLT file working directory */ ++ workingDirectory.setDltDirectory(QFileInfo(fileName).absolutePath()); ++ ++ if(!outputfile.isOpen()) ++ return; ++ ++ QFile inputfile(fileName); ++ ++ if(!inputfile.open(QFile::ReadOnly)) ++ return; ++ ++ QProgressDialog progress("Import DLT from PCAP...", "Abort Import", 0, inputfile.size()/1000, this); ++ progress.setWindowModality(Qt::WindowModal); ++ ++ pcap_hdr_t globalHeader; ++ pcaprec_hdr_t recordHeader; ++ ++ qDebug() << "Import DLt from PCAp file:" << fileName; ++ ++ if(inputfile.read((char*)&globalHeader,sizeof(pcap_hdr_t))!=sizeof(pcap_hdr_t)) ++ { ++ inputfile.close(); ++ return; ++ } ++ while(inputfile.read((char*)&recordHeader,sizeof(pcaprec_hdr_t))==sizeof(pcaprec_hdr_t)) ++ { ++ progress.setValue(inputfile.pos()/1000); ++ ++ if (progress.wasCanceled()) ++ { ++ inputfile.close(); ++ ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records DLT:" << counterRecordsDLT; ++ qDebug() << "Counter DLT Mesages:" << counterDLTMessages; ++ ++ reloadLogFile(); ++ return; ++ } ++ ++ QByteArray record = inputfile.read(recordHeader.incl_len); ++ if(record.length() != recordHeader.incl_len) ++ { ++ inputfile.close(); ++ qDebug() << "PCAP file not complete!"; ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records DLT:" << counterRecordsDLT; ++ qDebug() << "Counter DLT Mesages:" << counterDLTMessages; ++ return; ++ } ++ counterRecords ++; ++ // Check if Record is IP/UDP Packet with Dest Port 3490 ++ quint64 pos = 12; ++ //Read EtherType ++ if(record.size()<(pos+2)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ return; ++ } ++ quint16 etherType = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); ++ if(etherType==0x8100) ++ { ++ // VLAN tagging used ++ pos+=4; ++ if(record.size()<(pos+2)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ return; ++ } ++ etherType = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); ++ } ++ if(etherType==0x0800) // IP packet found ++ { ++ pos+=2; ++ pos+=9; ++ if(record.size()<(pos+1)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ return; ++ } ++ quint8 protocol = record.at(pos); ++ if(protocol==0x11) // UDP packet found ++ { ++ pos+=11; ++ pos+=2; ++ if(record.size()<(pos+2)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ return; ++ } ++ quint16 destPort = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); ++ if(destPort==3490) ++ { ++ pos+=6; ++ counterRecordsDLT++; ++ // Now read the DLT Messages ++ quint64 dataSize; ++ if(recordHeader.orig_len0) ++ { ++ quint64 sizeMsg = qmsg.checkMsgSize(dataPtr,dataSize); ++ if(sizeMsg>0) ++ { ++ // DLT message found, write it with storage header ++ QByteArray empty; ++ writeDLTMessageToFile(empty,dataPtr,sizeMsg,0,recordHeader.ts_sec,recordHeader.ts_usec); ++ counterDLTMessages++; ++ ++ //totalBytesRcvd+=sizeMsg; ++ if(sizeMsg<=dataSize) ++ { ++ dataSize -= sizeMsg; ++ dataPtr += sizeMsg; ++ } ++ else ++ { ++ dataSize = 0; ++ } ++ } ++ else ++ { ++ dataSize = 0; ++ } ++ } ++ } ++ } ++ } ++ } ++ inputfile.close(); ++ ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records DLT:" << counterRecordsDLT; ++ qDebug() << "Counter DLT Mesages:" << counterDLTMessages; ++ ++ reloadLogFile(); ++} ++ ++typedef struct plp_header { ++ quint16 probeId; ++ quint16 counter; ++ quint8 version; ++ quint8 plpType; ++ quint16 msgType; ++ quint16 reserved; ++ quint16 probeFlags; ++} PACKED plp_header_t; ++ ++typedef struct plp_header_data { ++ quint32 busSpecId; ++ quint32 timeStampHigh; ++ quint32 timeStampLow; ++ quint16 length; ++ quint16 dataFlags; ++} PACKED plp_header_data_t; ++ ++void MainWindow::on_actionImport_IPC_from_PCAP_triggered() ++{ ++ quint32 counterRecords = 0, counterRecordsIPC = 0, counterIPCMessages = 0; ++ QString fileName = QFileDialog::getOpenFileName(this, ++ tr("Import IPC from PCAP file"), workingDirectory.getDltDirectory(), tr("PCAP file (*.pcap)")); ++ ++ if(fileName.isEmpty()) ++ return; ++ ++ /* change DLT file working directory */ ++ workingDirectory.setDltDirectory(QFileInfo(fileName).absolutePath()); ++ ++ if(!outputfile.isOpen()) ++ return; ++ ++ QFile inputfile(fileName); ++ ++ if(!inputfile.open(QFile::ReadOnly)) ++ return; ++ ++ QProgressDialog progress("Import IPC from PCAP...", "Abort Import", 0, inputfile.size()/1000, this); ++ progress.setWindowModality(Qt::WindowModal); ++ ++ pcap_hdr_t globalHeader; ++ pcaprec_hdr_t recordHeader; ++ ++ qDebug() << "Import DLt from PCAp file:" << fileName; ++ ++ if(inputfile.read((char*)&globalHeader,sizeof(pcap_hdr_t))!=sizeof(pcap_hdr_t)) ++ { ++ inputfile.close(); ++ return; ++ } ++ ++ bool inSegment = false; ++ QByteArray segmentBuffer; ++ while(inputfile.read((char*)&recordHeader,sizeof(pcaprec_hdr_t))==sizeof(pcaprec_hdr_t)) ++ { ++ progress.setValue(inputfile.pos()/1000); ++ ++ if (progress.wasCanceled()) ++ { ++ inputfile.close(); ++ ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records IPC:" << counterRecordsIPC; ++ qDebug() << "Counter IPC Mesages:" << counterIPCMessages; ++ ++ reloadLogFile(); ++ return; ++ } ++ ++ QByteArray record = inputfile.read(recordHeader.incl_len); ++ if(record.length() != recordHeader.incl_len) ++ { ++ inputfile.close(); ++ qDebug() << "PCAP file not complete!"; ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records IPC:" << counterRecordsIPC; ++ qDebug() << "Counter IPC Mesages:" << counterIPCMessages; ++ return; ++ } ++ counterRecords ++; ++ // Check if Record is PLP packet ++ quint64 pos = 12; ++ //Read EtherType ++ if(record.size()<(pos+2)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ qDebug() << "PCAP file not complete!"; ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records IPC:" << counterRecordsIPC; ++ qDebug() << "Counter IPC Mesages:" << counterIPCMessages; ++ return; ++ } ++ quint16 etherType = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); ++ if(etherType==0x8100) ++ { ++ // VLAN tagging used ++ pos+=4; ++ if(record.size()<(pos+2)) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ qDebug() << "PCAP file not complete!"; ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records IPC:" << counterRecordsIPC; ++ qDebug() << "Counter IPC Mesages:" << counterIPCMessages; ++ return; ++ } ++ etherType = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); ++ } ++ if(etherType==0x2090) // PLP packet found ++ { ++ pos += 2; ++ ++ if(record.size()<(pos+sizeof(plp_header_t))) ++ { ++ qDebug() << "Size issue!"; ++ inputfile.close(); ++ return; ++ } ++ plp_header_t *plpHeader = (plp_header_t *) (record.data()+pos); ++ ++ pos += sizeof(plp_header_t); ++ ++ bool startOfSegment = qFromBigEndian(plpHeader->probeFlags) & 0x2; ++ if(startOfSegment) ++ { ++ inSegment = true; ++ segmentBuffer.clear(); ++ } ++ bool endOfSegment = qFromBigEndian(plpHeader->probeFlags) & 0x1; ++ if(endOfSegment) ++ { ++ inSegment = false; ++ } ++ bool multiFrame = qFromBigEndian(plpHeader->probeFlags) & 0x8; ++ if(qFromBigEndian(plpHeader->probeId) == 0xd0 && qFromBigEndian(plpHeader->msgType) == 0x500) ++ { ++ counterRecordsIPC++; ++ while(record.size()>=(pos+sizeof(plp_header_data_t))) ++ { ++ plp_header_data_t *plpHeaderData = (plp_header_data_t *) (record.data()+pos); ++ ++ pos += sizeof(plp_header_data_t); ++ ++ if(record.size()<(pos+qFromBigEndian(plpHeaderData->length))) ++ { ++ qDebug() << "Size issue!"; ++ break; ++ } ++ counterIPCMessages++; ++ ++ if(inSegment || endOfSegment) ++ { ++ segmentBuffer += record.mid(pos,qFromBigEndian(plpHeaderData->length)); ++ } ++ if(!inSegment || endOfSegment) ++ { ++ /* now write DLT message here */ ++ QByteArray empty,payload; ++ QDltMsg msg; ++ ++ // set parameters of DLT message to be generated ++ msg.clear(); ++ msg.setEcuid("IPNP"); ++ msg.setApid("IPC"); ++ msg.setCtid("IPC"); ++ msg.setMode(QDltMsg::DltModeVerbose); ++ msg.setType(QDltMsg::DltTypeLog); ++ msg.setSubtype(QDltMsg::DltLogInfo); ++ msg.setMessageCounter(0); ++ msg.setNumberOfArguments(3); ++ ++ // add PLP Header Data ++ QDltArgument arg1; ++ arg1.setTypeInfo(QDltArgument::DltTypeInfoRawd); ++ arg1.setEndianness(QDltArgument::DltEndiannessLittleEndian); ++ arg1.setOffsetPayload(0); ++ arg1.setData(record.mid(pos-sizeof(plp_header_data_t),sizeof(plp_header_data_t))); ++ msg.addArgument(arg1); ++ ++ // add IPC Header ++ QDltArgument arg2; ++ arg2.setTypeInfo(QDltArgument::DltTypeInfoRawd); ++ arg2.setEndianness(QDltArgument::DltEndiannessLittleEndian); ++ arg2.setOffsetPayload(0); ++ if(endOfSegment) ++ { ++ arg2.setData(segmentBuffer.mid(0,35)); ++ } ++ else ++ { ++ arg2.setData(record.mid(pos,35)); ++ } ++ msg.addArgument(arg2); ++ ++ // add IPC Data ++ QDltArgument arg3; ++ arg3.setTypeInfo(QDltArgument::DltTypeInfoRawd); ++ arg3.setEndianness(QDltArgument::DltEndiannessLittleEndian); ++ arg3.setOffsetPayload(0); ++ if(endOfSegment) ++ { ++ arg3.setData(segmentBuffer.mid(35)); ++ segmentBuffer.clear(); ++ } ++ else ++ { ++ arg3.setData(record.mid(pos+35,qFromBigEndian(plpHeaderData->length)-35)); ++ } ++ msg.addArgument(arg3); ++ ++ // write DLT message ++ msg.getMsg(payload,false); ++ writeDLTMessageToFile(payload,0,0,0,recordHeader.ts_sec,recordHeader.ts_usec); ++ } ++ ++ pos += qFromBigEndian(plpHeaderData->length); ++ } ++ } ++ } ++ } ++ inputfile.close(); ++ ++ qDebug() << "Counter Records:" << counterRecords; ++ qDebug() << "Counter Records IPC:" << counterRecordsIPC; ++ qDebug() << "Counter IPC Mesages:" << counterIPCMessages; ++ ++ reloadLogFile(); ++ ++} ++ + void MainWindow::on_action_menuFile_Import_DLT_Stream_with_Serial_Header_triggered() + { + QString fileName = QFileDialog::getOpenFileName(this, +@@ -1377,7 +1801,7 @@ void MainWindow::exportSelection(bool as + QModelIndexList list = ui->tableView->selectionModel()->selection().indexes(); + + +- DltExporter exporter; ++ DltExporter exporter(&project); + exporter.exportMessages(&qfile,0,&pluginManager,format,DltExporter::SelectionSelected,&list); + } + +@@ -1411,7 +1835,7 @@ void MainWindow::exportSelection_searchT + + QModelIndexList finallist = ui->tableView->selectionModel()->selection().indexes(); + +- DltExporter exporter; ++ DltExporter exporter(&project); + exporter.exportMessages(&qfile,0,&pluginManager,format,DltExporter::SelectionSelected,&finallist); + } + +@@ -1509,7 +1933,7 @@ void MainWindow::on_actionExport_trigger + + /* change last export directory */ + workingDirectory.setExportDirectory(QFileInfo(fileName).absolutePath()); +- DltExporter exporter(this); ++ DltExporter exporter(&project,this); + QFile outfile(fileName); + + unsigned long int startix, stopix; +@@ -3693,11 +4117,10 @@ void MainWindow::readyRead() + + } + +-void MainWindow::writeDLTMessageToFile(QByteArray &bufferHeader,char* bufferPayload,quint32 bufferPayloadSize,EcuItem* ecuitem) ++void MainWindow::writeDLTMessageToFile(QByteArray &bufferHeader,char* bufferPayload,quint32 bufferPayloadSize,EcuItem* ecuitem,quint32 sec,quint32 usec) + { + DltStorageHeader str; + +- //DltStorageHeader str; + str.pattern[0]='D'; + str.pattern[1]='L'; + str.pattern[2]='T'; +@@ -3707,22 +4130,27 @@ void MainWindow::writeDLTMessageToFile(Q + str.ecu[2]=0; + str.ecu[3]=0; + +- /* get time of day */ +- #if defined(_MSC_VER) +- SYSTEMTIME systemtime; +- GetSystemTime(&systemtime); +- time_t timestamp_sec; +- time(×tamp_sec); +- str.seconds = (time_t)timestamp_sec; +- str.microseconds = (int32_t)systemtime.wMilliseconds * 1000; // for some reasons we do not have microseconds in Windows ! +- #else ++ if (sec || usec) ++ { // todo should better use ptrs and not != 0 ++ str.seconds = (time_t)sec; ++ str.microseconds = (int32_t)usec; ++ } ++ else ++ { ++#if defined(_MSC_VER) ++ struct timespec ts; ++ (void)timespec_get(&ts, TIME_UTC); ++ str.seconds = (time_t)ts.tv_sec; ++ str.microseconds = (int32_t)(ts.tv_nsec / 1000); ++#else + struct timeval tv; + gettimeofday(&tv, NULL); +- str.seconds = (time_t)tv.tv_sec; /* value is long */ ++ str.seconds = (time_t)tv.tv_sec; /* value is long */ + str.microseconds = (int32_t)tv.tv_usec; /* value is long */ +- #endif +- +- dlt_set_id(str.ecu,ecuitem->id.toLatin1()); ++#endif ++ } ++ if (ecuitem) ++ dlt_set_id(str.ecu, ecuitem->id.toLatin1()); + + /* check if message is matching the filter */ + if (outputfile.isOpen()) +@@ -3745,7 +4173,7 @@ void MainWindow::writeDLTMessageToFile(Q + } + + // write data into file +- if(!ecuitem->getWriteDLTv2StorageHeader()) ++ if(!ecuitem || !ecuitem->getWriteDLTv2StorageHeader()) + { + // write version 1 storage header + outputfile.write((char*)&str,sizeof(DltStorageHeader)); +@@ -8134,3 +8562,4 @@ void MainWindow::on_lineEditFilterEnd_te + { + applyConfigEnabled(true); + } ++ +--- dlt-viewer-2.25.0+dfsg.orig/src/mainwindow.h ++++ dlt-viewer-2.25.0+dfsg/src/mainwindow.h +@@ -177,7 +177,7 @@ private: + QStringList autoloadPluginsVersionStrings; + + /* String List Containing Search History */ +- enum { MaxSearchHistory = 20 }; ++ enum { MaxSearchHistory = 50 }; + QAction *searchHistoryActs[MaxSearchHistory]; + QStringList searchHistory; + +@@ -379,7 +379,7 @@ private: + /* Get path from explorerView model index */ + QString getPathFromExplorerViewIndexModel(const QModelIndex &proxyIndex); + +- void writeDLTMessageToFile(QByteArray &bufferHeader,char*bufferPayload,quint32 bufferPayloadSize,EcuItem* ecuitem); ++ void writeDLTMessageToFile(QByteArray &bufferHeader,char*bufferPayload,quint32 bufferPayloadSize,EcuItem* ecuitem,quint32 sec=0,quint32 use=0); + + protected: + void keyPressEvent ( QKeyEvent * event ); +@@ -587,6 +587,10 @@ private slots: + + void on_lineEditFilterEnd_textChanged(const QString &arg1); + ++ void on_actionImport_DLT_from_PCAP_triggered(); ++ ++ void on_actionImport_IPC_from_PCAP_triggered(); ++ + public slots: + + void sendInjection(int index,QString applicationId,QString contextId,int serviceId,QByteArray data); +--- dlt-viewer-2.25.0+dfsg.orig/src/mainwindow.ui ++++ dlt-viewer-2.25.0+dfsg/src/mainwindow.ui +@@ -114,6 +114,8 @@ + + + ++ ++ + + + +@@ -312,7 +314,7 @@ + Qt::NoFocus + + +- QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable ++ QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable + + + Project +@@ -1670,6 +1672,16 @@ + Sort By Timestamp + + ++ ++ ++ Import DLT from PCAP... ++ ++ ++ ++ ++ Import IPC from PCAP... ++ ++ + + + +--- dlt-viewer-2.25.0+dfsg.orig/src/version.h ++++ dlt-viewer-2.25.0+dfsg/src/version.h +@@ -25,10 +25,10 @@ + /* for other bugfixes and not major feature enhancement just use patch level */ + #define PACKAGE_VERSION_STATE "" + #define PACKAGE_MAJOR_VERSION 2 +-#define PACKAGE_MINOR_VERSION 24 ++#define PACKAGE_MINOR_VERSION 25 + #define PACKAGE_PATCH_LEVEL 0 +-#define PACKAGE_VERSION "2.24.0" +-#define PACKAGE_REVISION "" ++#define PACKAGE_VERSION "2.25.0" ++#define PACKAGE_REVISION "stable" + #define PACKAGE_DESCRIPTION "DLT Viewer" + #define DLT_SUPPORT_MAIL_ADDRESS "" + #define DLT_SUPPORT_NAME "COVESA" diff -Nru dlt-viewer-2.25.0+dfsg/debian/patches/series dlt-viewer-2.25.0+dfsg/debian/patches/series --- dlt-viewer-2.25.0+dfsg/debian/patches/series 1970-01-01 00:00:00.000000000 +0000 +++ dlt-viewer-2.25.0+dfsg/debian/patches/series 2024-01-18 11:06:06.000000000 +0000 @@ -0,0 +1 @@ +2.25.0-real.patch