diff --git a/.github/workflows/BuildPR.yml b/.github/workflows/BuildPR.yml index c5b1e0de..f0ff44f9 100644 --- a/.github/workflows/BuildPR.yml +++ b/.github/workflows/BuildPR.yml @@ -38,7 +38,7 @@ jobs: - name: Show cmake version run: cmake --version - name: Build project - run: scripts/darwin/build.sh + run: scripts/darwin/build_cmake.sh - name: Codesign app bundle if: "! github.event.pull_request.head.repo.fork " # not running on a fork # Extract the secrets we defined earlier as environment variables @@ -124,6 +124,8 @@ jobs: run: scripts/linux/install.sh - name: Build project run: scripts/linux/build.sh + - name: Run tests + run: ctest --test-dir build/qdlt - name: Make artifact executable run: chmod -R +x build/dist - name: Archive artifact diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml index 58383274..36cde841 100644 --- a/.github/workflows/Release.yml +++ b/.github/workflows/Release.yml @@ -12,9 +12,9 @@ jobs: runs-on: ${{ matrix.macos }} strategy: matrix: - xcode: [ Xcode_15.2 ] - abi: [ x86 ] macos: [ macos-13 ] + abi: [ x86 ] + xcode: [ Xcode_15.2 ] include: - macos: macos-14 abi: arm64 @@ -34,14 +34,76 @@ jobs: - name: install build environment run: scripts/darwin/install.sh - name: Build project - run: scripts/darwin/build.sh + run: scripts/darwin/build_cmake.sh + - name: Codesign app bundle + if: "! github.event.pull_request.head.repo.fork " # not running on a fork + # Extract the secrets we defined earlier as environment variables + env: + MACOS_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.P12_PASSWORD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.APPLE_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.KEYCHAIN_PASSWORD }} + run: | + # Turn our base64-encoded certificate back to a regular .p12 file + + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + # We need to create a new keychain, otherwise using the certificate will prompt + # with a UI dialog asking for the certificate password, which we can't + # use in a headless CI environment + + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" build.keychain + security import certificate.p12 -k build.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" build.keychain + + # We finally codesign our app bundle, specifying the Hardened runtime option + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/Frameworks/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/Resources/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/bearer/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents//PlugIns/iconengines/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/imageformats/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/platforminputcontexts/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/platforms/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/printsupport/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/styles/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/PlugIns/virtualkeyboard/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/MacOS/plugins/* + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/MacOS/dlt-commander + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app/Contents/MacOS/dlt-viewer + /usr/bin/codesign --timestamp --options=runtime -s "$MACOS_CERTIFICATE_NAME" -f -v /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app + - name: Notarize app bundle + if: "! github.event.pull_request.head.repo.fork " # not running on a fork + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.APP_PASSWORD }} + run: | + echo "Create keychain profile" + xcrun notarytool store-credentials "notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + echo "Creating temp notarization archive" + ditto -c -k --keepParent "/Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app" "/Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.zip" + + echo "Notarize app" + xcrun notarytool submit "/Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.zip" --keychain-profile "notarytool-profile" --wait + + echo "Attach staple" + xcrun stapler staple "/Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.app" + rm -r /Users/runner/work/dlt-viewer/dlt-viewer/build/install/DLTViewer.zip + - name: Artifact Creation + run: | + cd /Users/runner/work/dlt-viewer/dlt-viewer/build + mkdir -p dist + cp ../scripts/darwin/install.md dist + tar -czvf "dist/DLTViewer.tgz" -C /Users/runner/work/dlt-viewer/dlt-viewer/build/install . - name: Archive artifact run: zip DLT-macOS-${{ matrix.abi }}.zip -r build/dist - - name: Upload DLT artifact + - name: Archive artifact uses: actions/upload-artifact@v4 + if: ${{ success() }} with: name: DLT-Mac-${{ matrix.abi }} - path: DLT-macOS-${{ matrix.abi }}.zip + path: DLT-macOS*.zip buildLinux: name: Build ${{ matrix.ubuntu }} diff --git a/build_parser_windows_qt5_MSVC.bat b/build_parser_windows_qt5_MSVC_qmake.bat similarity index 100% rename from build_parser_windows_qt5_MSVC.bat rename to build_parser_windows_qt5_MSVC_qmake.bat diff --git a/build_sdk_windows_qt5_MSVC_interactive.bat b/build_sdk_windows_qt5_MSVC_interactive_qmake.bat similarity index 60% rename from build_sdk_windows_qt5_MSVC_interactive.bat rename to build_sdk_windows_qt5_MSVC_interactive_qmake.bat index ce3f7cf1..7955d535 100644 --- a/build_sdk_windows_qt5_MSVC_interactive.bat +++ b/build_sdk_windows_qt5_MSVC_interactive_qmake.bat @@ -1,4 +1,4 @@ -call build_sdk_windows_qt5_MSVC.bat +call build_sdk_windows_qt5_MSVC_qmake.bat SET RETCODE=%ERRORLEVEL% set /p name= Continue exit /b %RETCODE% \ No newline at end of file diff --git a/build_sdk_windows_qt5_MSVC.bat b/build_sdk_windows_qt5_MSVC_qmake.bat similarity index 100% rename from build_sdk_windows_qt5_MSVC.bat rename to build_sdk_windows_qt5_MSVC_qmake.bat diff --git a/qdlt/CMakeLists.txt b/qdlt/CMakeLists.txt index 4ee1e017..80fa297d 100644 --- a/qdlt/CMakeLists.txt +++ b/qdlt/CMakeLists.txt @@ -123,6 +123,7 @@ endforeach() find_package(GTest) # configure unit tests only if gtest found on the system if (GTest_FOUND) + message(STATUS "Tests enabled") enable_testing() add_subdirectory(tests) endif() diff --git a/qdlt/qdlt.pro b/qdlt/qdlt.pro index e51f5f40..978c5d6f 100644 --- a/qdlt/qdlt.pro +++ b/qdlt/qdlt.pro @@ -32,6 +32,8 @@ CONFIG += warn_on qt QT += network QT += serialport +win32:LIBS += User32.lib + # Put intermediate files in the build directory MOC_DIR = build/moc OBJECTS_DIR = build/obj diff --git a/qdlt/qdltexporter.cpp b/qdlt/qdltexporter.cpp index 26547ad1..8fc52382 100644 --- a/qdlt/qdltexporter.cpp +++ b/qdlt/qdltexporter.cpp @@ -69,7 +69,9 @@ void QDltExporter::writeCSVLine(int index, QFile *to, QDltMsg msg) text += escapeCSVValue(QString("%1").arg(msg.getSubtypeString())).append(delimiter); text += escapeCSVValue(QString("%1").arg(msg.getModeString())).append(delimiter); text += escapeCSVValue(QString("%1").arg(msg.getNumberOfArguments())).append(delimiter); - text += escapeCSVValue(msg.toStringPayload().simplified().remove(QChar::Null)); + QString payload = msg.toStringPayload().simplified().remove(QChar::Null); + if(from) from->applyRegExString(msg,payload); + text += escapeCSVValue(payload); text += "\n"; to->write(text.toLatin1().constData()); @@ -97,12 +99,12 @@ bool QDltExporter::start() { if(!to->open(QIODevice::WriteOnly | QIODevice::Text)) { - if ( true == QDltOptManager::getInstance()->issilentMode() ) - { - qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); - } - else - ;//QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), + if (QDltOptManager::getInstance()->issilentMode()) + { + qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); + } + //else + //QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), // QString("Cannot open the export file %1").arg(to->fileName())); return false; } @@ -111,12 +113,12 @@ bool QDltExporter::start() { if(!to->open(QIODevice::WriteOnly)) { - if ( true == QDltOptManager::getInstance()->issilentMode() ) - { - qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); - } - else - ;//QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), + if (QDltOptManager::getInstance()->issilentMode() ) + { + qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); + } + //else + //QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), // QString("Cannot open the export file %1").arg(to->fileName())); return false; } @@ -128,12 +130,12 @@ bool QDltExporter::start() /* Write the first line of CSV file */ if(!writeCSVHeader(to)) { - if ( true == QDltOptManager::getInstance()->issilentMode() ) - { - qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); - } - else - ;//QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), + if(QDltOptManager::getInstance()->issilentMode()) + { + qDebug() << QString("ERROR - cannot open the export file %1").arg(to->fileName()); + } + //else + //QMessageBox::critical(qobject_cast(parent()), QString("DLT Viewer"), // QString("Cannot open the export file %1").arg(to->fileName())); return false; } @@ -280,7 +282,9 @@ bool QDltExporter::exportMsg(unsigned long int num, QDltMsg &msg, QByteArray &bu text += " "; } - text += msg.toStringPayload().simplified().remove(QChar::Null); + QString payload = msg.toStringPayload().simplified().remove(QChar::Null); + if(from) from->applyRegExString(msg,payload); + text += payload; text += "\n"; try { @@ -326,11 +330,13 @@ bool QDltExporter::exportMsg(unsigned long int num, QDltMsg &msg, QByteArray &bu text += "|" + QString("%1.%2").arg(msg.getGmTimeWithOffsetString(utcOffset,dst)).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); else text += "|" + QString("%1.%2").arg(msg.getTimeString()).arg(msg.getMicroseconds(),6,10,QLatin1Char('0')); + QString payload = msg.toStringPayload().simplified().remove(QChar::Null); + if(from) from->applyRegExString(msg,payload); text += "|" + QString("%1.%2").arg(msg.getTimestamp()/10000).arg(msg.getTimestamp()%10000,4,10,QLatin1Char('0')) + "|" + msg.getEcuid() + "|" + msg.getApid() + "|" + msg.getCtid() + - "|" + msg.toStringPayload().simplified().remove(QChar::Null).replace('|', "\\|").replace('#', "\\#").replace('*', "\\*") + + "|" + payload.replace('|', "\\|").replace('#', "\\#").replace('*', "\\*") + "| |\n"; clipboardString += text; } @@ -374,7 +380,6 @@ void QDltExporter::exportMessages(QDltFile *from, QFile *to, QDltPluginManager * return; } - bool silentMode = !QDltOptManager::getInstance()->issilentMode(); if ( this->stoping_index == 0 || this->stoping_index > this->size || this->stoping_index < this->starting_index ) @@ -420,6 +425,7 @@ void QDltExporter::exportMessages(QDltFile *from, QFile *to, QDltPluginManager * // decode message if needed if(exportFormat != QDltExporter::FormatDlt) { + //FIXME: The following does not work for non verbose messages, must be fixed if(pluginManager) pluginManager->decodeMsg(msg,silentMode); if (exportFormat == QDltExporter::FormatDltDecoded) @@ -429,6 +435,16 @@ void QDltExporter::exportMessages(QDltFile *from, QFile *to, QDltPluginManager * } } + // apply Regex if needed + if(exportFormat == QDltExporter::FormatDlt || exportFormat == QDltExporter::FormatDltDecoded) + { + //FIXME: The following does not work for non verbose messages, must be fixed to enable RegEx for DLT Export again + //msg.setNumberOfArguments(msg.sizeArguments()); + bool isApplied = false; + if(from) isApplied = from->applyRegExStringMsg(msg); + if(isApplied) msg.getMsg(buf,true); + } + // export message if(!exportMsg(starting,msg,buf)) { diff --git a/qdlt/qdltfile.cpp b/qdlt/qdltfile.cpp index d2ef5b53..1b97144e 100644 --- a/qdlt/qdltfile.cpp +++ b/qdlt/qdltfile.cpp @@ -754,3 +754,14 @@ void QDltFile::setIndexFilter(QVector _indexFilter) { indexFilter = _indexFilter; } + +bool QDltFile::applyRegExString(QDltMsg &msg,QString &text) +{ + + return filterList.applyRegExString(msg,text); +} + +bool QDltFile::applyRegExStringMsg(QDltMsg &msg) +{ + return filterList.applyRegExStringMsg(msg); +} diff --git a/qdlt/qdltfile.h b/qdlt/qdltfile.h index 92a2cd15..c07963d8 100644 --- a/qdlt/qdltfile.h +++ b/qdlt/qdltfile.h @@ -299,6 +299,16 @@ class QDLT_EXPORT QDltFile : public QDlt **/ bool getDLTv2Support() const; + //! Apply RegEx Replace to the string, if any active in the filters + /*! + */ + bool applyRegExString(QDltMsg &msg,QString &text); + + //! Apply RegEx Replace to the arguments of a message, if any active in the filters + /*! + */ + bool applyRegExStringMsg(QDltMsg &msg); + protected: private: diff --git a/qdlt/qdltfilterlist.cpp b/qdlt/qdltfilterlist.cpp index abe2f747..0152585c 100644 --- a/qdlt/qdltfilterlist.cpp +++ b/qdlt/qdltfilterlist.cpp @@ -19,6 +19,9 @@ * @licence end@ */ +#include +#include + #include #include @@ -121,6 +124,55 @@ QString QDltFilterList::checkMarker(QDltMsg &msg) #endif +bool QDltFilterList::applyRegExString(QDltMsg &msg,QString &text) +{ + QDltFilter *filter; + bool result = false; + + for(int numfilter=0;numfilterenableFilter && filter->enableRegexSearchReplace && filter->match(msg)) + { + text.replace(QRegularExpression(filter->regex_search), filter->regex_replace); + result = true; + } + } + return result; +} + +bool QDltFilterList::applyRegExStringMsg(QDltMsg &msg) +{ + QDltFilter *filter; + bool result = false; + + for(int numfilter=0;numfilterenableFilter && filter->enableRegexSearchReplace && filter->match(msg)) + { + for(int num=0;numregex_search), filter->regex_replace); + arg.setValue(text); + msg.removeArgument(num); + msg.addArgument(arg,num); + } + } + + result = true; + } + } + return result; +} + bool QDltFilterList::checkFilter(QDltMsg &msg) { QDltFilter *filter; diff --git a/qdlt/qdltfilterlist.h b/qdlt/qdltfilterlist.h index b2f6a2a7..8d250b53 100644 --- a/qdlt/qdltfilterlist.h +++ b/qdlt/qdltfilterlist.h @@ -122,6 +122,16 @@ class QDLT_EXPORT QDltFilterList */ void updateSortedFilter(); + //! Apply RegEx Replace to the string, if any active in the filters. + /*! + */ + bool applyRegExString(QDltMsg &msg,QString &text); + + //! Apply RegEx Replace to the argumnets of a message, if any active in the filters. + /*! + */ + bool applyRegExStringMsg(QDltMsg &msg); + protected: private: diff --git a/qdlt/qdltimporter.cpp b/qdlt/qdltimporter.cpp index a8a3656d..3838f0fc 100644 --- a/qdlt/qdltimporter.cpp +++ b/qdlt/qdltimporter.cpp @@ -52,6 +52,12 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa if(!inputfile.open(QFile::ReadOnly)) return; + /* open output file */ + if(!outputfile.open(QIODevice::WriteOnly|QIODevice::Append)) + { + qDebug() << "Failed opening WriteOnly" << outputfile.fileName(); + } + int progressCounter = 1; emit progress("PCAP",1,0); @@ -63,6 +69,7 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa if(inputfile.read((char*)&globalHeader,sizeof(pcap_hdr_t))!=sizeof(pcap_hdr_t)) { inputfile.close(); + outputfile.close(); qDebug() << "fromPCAP:" << "Cannot open file" << fileName; return; } @@ -83,6 +90,7 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa if(record.length() != recordHeader.incl_len) { inputfile.close(); + outputfile.close(); qDebug() << "fromPCAP: PCAP file not complete!"; qDebug() << "fromPCAP:" << "Size Error: Cannot read Record"; return; @@ -93,6 +101,7 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa if(record.size()<(qsizetype)(pos+2)) { inputfile.close(); + outputfile.close(); qDebug() << "dltFromPCAP:" << "Size Error: Cannot read Record"; return; } @@ -101,17 +110,20 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa if(!dltFromEthernetFrame(outputfile,record,pos,etherType,recordHeader.ts_sec,recordHeader.ts_usec)) { inputfile.close(); + outputfile.close(); qDebug() << "fromPCAP:" << "Size Error: Cannot read Ethernet Frame"; return; } if(!ipcFromEthernetFrame(outputfile,record,pos,etherType,recordHeader.ts_sec,recordHeader.ts_usec)) { inputfile.close(); + outputfile.close(); qDebug() << "fromPCAP:" << "Size Error: Cannot read Ethernet Frame"; return; } } inputfile.close(); + outputfile.close(); emit progress("",3,100); @@ -122,7 +134,6 @@ void QDltImporter::dltIpcFromPCAP(QFile &outputfile,QString fileName,QWidget *pa qDebug() << "fromPCAP: Counter IPC Mesages:" << counterIPCMessages; qDebug() << "fromPCAP: Import finished"; - } void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *parent,bool silent) @@ -146,6 +157,12 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par return; } + /* open output file */ + if(!outputfile.open(QIODevice::WriteOnly|QIODevice::Append)) + { + qDebug() << "Failed opening WriteOnly" << outputfile.fileName(); + } + int progressCounter = 1; emit progress("MF4",1,0); @@ -154,140 +171,182 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)&mdfIdblock,sizeof(mdf_idblock_t))!=sizeof(mdf_idblock_t)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot reard Id Block"; return; } mdf_hdr_t mdfHeader,mdfDgHeader,mdfCgHeader,mdfCnHeader,mdfTxHeader; + mdf_dgblocklinks_t mdfDgBlockLinks; memset((char*)&mdfHeader,0,sizeof(mdf_hdr_t)); quint64 pos=0,hd_pos=0,dt_pos=0; - - while(inputfile.read((char*)&mdfHeader,sizeof(mdf_hdr_t))==sizeof(mdf_hdr_t)) + if(inputfile.read((char*)&mdfHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + { + inputfile.close(); + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot read mdf header"; + return; + } + if(!hd_pos && mdfHeader.id[0]=='#' && mdfHeader.id[1]=='#' && mdfHeader.id[2]=='H' && mdfHeader.id[3]=='D') { - //qDebug() << "pos" << pos; - if(!hd_pos && mdfHeader.id[0]=='#' && mdfHeader.id[1]=='#' && mdfHeader.id[2]=='H' && mdfHeader.id[3]=='D') + pos = inputfile.pos() - sizeof(mdf_hdr_t); + //qDebug() << "HD:"; + hd_pos=pos; + if(inputfile.read((char*)&hdBlockLinks,sizeof(mdf_hdblocklinks_t))!=sizeof(mdf_hdblocklinks_t)) { - pos = inputfile.pos() - sizeof(mdf_hdr_t); - //qDebug() << "HD:"; - hd_pos=pos; - if(inputfile.read((char*)&hdBlockLinks,sizeof(mdf_hdblocklinks_t))!=sizeof(mdf_hdblocklinks_t)) + inputfile.close(); + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot read HD Block"; + return; + } + // Iterate through all data groups + quint64 ptrDg = hdBlockLinks.hd_dg_first; + while(ptrDg) + { + inputfile.seek(ptrDg); + if(inputfile.read((char*)&mdfDgHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) { inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot reard HD Block"; + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot reard DG Block"; return; } - // Iterate through all data groups - quint64 ptrDg = hdBlockLinks.hd_dg_first; - while(ptrDg) + if(mdfDgHeader.id[0]=='#' && mdfDgHeader.id[1]=='#' && mdfDgHeader.id[2]=='D' && mdfDgHeader.id[3]=='G') { - inputfile.seek(ptrDg); - if(inputfile.read((char*)&mdfDgHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + //qDebug() << "\tDG:"; + if(inputfile.read((char*)&mdfDgBlockLinks,sizeof(mdf_dgblocklinks_t))!=sizeof(mdf_dgblocklinks_t)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot reard DG Block"; return; } - if(mdfDgHeader.id[0]=='#' && mdfDgHeader.id[1]=='#' && mdfDgHeader.id[2]=='D' && mdfDgHeader.id[3]=='G') + ptrDg=mdfDgBlockLinks.dg_dg_next; + // Iterate through all channel groups + quint64 ptrCg = mdfDgBlockLinks.dg_cg_first; + while(ptrCg) { - //qDebug() << "\tDG:"; - mdf_dgblocklinks_t mdfDgBlockLinks; - if(inputfile.read((char*)&mdfDgBlockLinks,sizeof(mdf_dgblocklinks_t))!=sizeof(mdf_dgblocklinks_t)) + inputfile.seek(ptrCg); + if(inputfile.read((char*)&mdfCgHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) { inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot reard DG Block"; + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot reard CG Block"; return; } - ptrDg=mdfDgBlockLinks.dg_dg_next; - // Iterate through all channel groups - quint64 ptrCg = mdfDgBlockLinks.dg_cg_first; - while(ptrCg) + if(mdfCgHeader.id[0]=='#' && mdfCgHeader.id[1]=='#' && mdfCgHeader.id[2]=='C' && mdfCgHeader.id[3]=='G') { - inputfile.seek(ptrCg); - if(inputfile.read((char*)&mdfCgHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + //qDebug() << "\t\tCG:"; + mdf_cgblocklinks_t mdfCgBlockLinks; + if(inputfile.read((char*)&mdfCgBlockLinks,sizeof(mdf_cgblocklinks_t))!=sizeof(mdf_cgblocklinks_t)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot reard CG Block"; return; } - if(mdfCgHeader.id[0]=='#' && mdfCgHeader.id[1]=='#' && mdfCgHeader.id[2]=='C' && mdfCgHeader.id[3]=='G') + //qDebug() << "\t\cg_record_id =" << mdfCgBlockLinks.cg_record_id; + //qDebug() << "\t\cg_data_bytes =" << mdfCgBlockLinks.cg_data_bytes; + ptrCg=mdfCgBlockLinks.cg_cg_next; + if(mdfCgBlockLinks.cg_flags&1) // VLSD + channelGroupLength[mdfCgBlockLinks.cg_record_id]=-1; + else + channelGroupLength[mdfCgBlockLinks.cg_record_id]=mdfCgBlockLinks.cg_data_bytes; + // Iterate through all channels + quint64 ptrCh = mdfCgBlockLinks.cg_cn_first; + while(ptrCh) { - //qDebug() << "\t\tCG:"; - mdf_cgblocklinks_t mdfCgBlockLinks; - if(inputfile.read((char*)&mdfCgBlockLinks,sizeof(mdf_cgblocklinks_t))!=sizeof(mdf_cgblocklinks_t)) + inputfile.seek(ptrCh); + if(inputfile.read((char*)&mdfCnHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) { + qDebug() << "fromMF4:" << "Size Error: Cannot reard CN Block"; inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot reard CG Block"; + outputfile.close(); return; } - //qDebug() << "\t\cg_record_id =" << mdfCgBlockLinks.cg_record_id; - //qDebug() << "\t\cg_data_bytes =" << mdfCgBlockLinks.cg_data_bytes; - ptrCg=mdfCgBlockLinks.cg_cg_next; - if(mdfCgBlockLinks.cg_flags&1) // VLSD - channelGroupLength[mdfCgBlockLinks.cg_record_id]=-1; - else - channelGroupLength[mdfCgBlockLinks.cg_record_id]=mdfCgBlockLinks.cg_data_bytes; - // Iterate through all channels - quint64 ptrCh = mdfCgBlockLinks.cg_cn_first; - while(ptrCh) + if(mdfCnHeader.id[0]=='#' && mdfCnHeader.id[1]=='#' && mdfCnHeader.id[2]=='C' && mdfCnHeader.id[3]=='N') { - inputfile.seek(ptrCh); - if(inputfile.read((char*)&mdfCnHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + //qDebug() << "\t\t\tCN:"; + mdf_cnblocklinks_t mdfChBlockLinks; + if(inputfile.read((char*)&mdfChBlockLinks,sizeof(mdf_cnblocklinks_t))!=sizeof(mdf_cnblocklinks_t)) { - qDebug() << "fromMF4:" << "Size Error: Cannot reard CN Block"; inputfile.close(); + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot reard CN Block"; return; } - if(mdfCnHeader.id[0]=='#' && mdfCnHeader.id[1]=='#' && mdfCnHeader.id[2]=='C' && mdfCnHeader.id[3]=='N') + ptrCh=mdfChBlockLinks.cn_cn_next; + // Read channel name + inputfile.seek(mdfChBlockLinks.cn_tx_name); + if(inputfile.read((char*)&mdfTxHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) { - //qDebug() << "\t\t\tCN:"; - mdf_cnblocklinks_t mdfChBlockLinks; - if(inputfile.read((char*)&mdfChBlockLinks,sizeof(mdf_cnblocklinks_t))!=sizeof(mdf_cnblocklinks_t)) - { - inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot reard CN Block"; - return; - } - ptrCh=mdfChBlockLinks.cn_cn_next; - // Read channel name - inputfile.seek(mdfChBlockLinks.cn_tx_name); - if(inputfile.read((char*)&mdfTxHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + inputfile.close(); + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot reard Tx Block"; + return; + } + char cnName[256]; + memset(cnName,0,256); + + const auto cnNameLength = mdfTxHeader.length-sizeof(mdf_hdr_t); + if(cnNameLength < 256) { + const quint64 cnNameReadLength = inputfile.read((char*)cnName, cnNameLength); + if(cnNameReadLength != cnNameLength ) { inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot reard Tx Block"; + outputfile.close(); + qDebug() << "fromMF4:" << "Size Error: Cannot read cn name"; return; } - char cnName[256]; - memset(cnName,0,256); - - const auto cnNameLength = mdfTxHeader.length-sizeof(mdf_hdr_t); - if(cnNameLength < 256) { - const quint64 cnNameReadLength = inputfile.read((char*)cnName, cnNameLength); - if(cnNameReadLength != cnNameLength ) - { - inputfile.close(); - qDebug() << "fromMF4:" << "Size Error: Cannot read cn name"; - return; - } - } - // FIXME: this is probably a bug if this line is reached because cnNameLength >= 256, since cnName is 0-initialized 256-bytes array - channelGroupName[mdfCgBlockLinks.cg_record_id] = QString(cnName); - //qDebug() << "fromMF4: cnName=" << cnName; - } - else - ptrCh=0; + // FIXME: this is probably a bug if this line is reached because cnNameLength >= 256, since cnName is 0-initialized 256-bytes array + channelGroupName[mdfCgBlockLinks.cg_record_id] = QString(cnName); + //qDebug() << "fromMF4: cnName=" << cnName; + } + else + ptrCh=0; } - else - ptrCg=0; } + else + ptrCg=0; } - else - ptrDg=0; } + else + ptrDg=0; + } + } + // seek to and read data list header + inputfile.seek(mdfDgBlockLinks.dg_data); + if(inputfile.read((char*)&mdfHeader,sizeof(mdf_hdr_t))!=sizeof(mdf_hdr_t)) + { + inputfile.close(); + outputfile.close(); + qDebug() << "fromMF4: Cannot read datalist header"; + return; + } + int numberOfLinks = mdfHeader.link_count; + for(int num=1;num0) && ((percent%10)==0)) + { qDebug() << "Import MF4:" << percent << "%"; // every 10% + } } + //qDebug() << "Record:" << counterRecords << pos << posDt; // TODO: Handle cancel operation @@ -318,6 +380,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)&recordId,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -332,6 +395,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)&lengthVLSD,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -346,54 +410,63 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)ðFrame.timeStamp,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.asynchronous,sizeof(quint8))!=sizeof(quint8)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.source,6)!=6) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.destination,6)!=6) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.etherType,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.crc,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.receivedDataByteCount,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.dataLength,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.dataBytes,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -404,6 +477,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!dltFromEthernetFrame(outputfile,recordData,pos,ethFrame.etherType,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read Ethernet Frame"; return; } @@ -411,6 +485,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!ipcFromEthernetFrame(outputfile,recordData,pos,ethFrame.etherType,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read Ethernet Frame"; return; } @@ -424,60 +499,70 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)ðFrame.timeStamp,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.asynchronous,sizeof(quint8))!=sizeof(quint8)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.source,6)!=6) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.destination,6)!=6) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.etherType,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.crc,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.receivedDataByteCount,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.beaconTimeStamp,sizeof(quint64))!=sizeof(quint64)) // TODO: Beacon Time Stamp { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.dataLength,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)ðFrame.dataBytes,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -488,6 +573,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!dltFromEthernetFrame(outputfile,recordData,pos,ethFrame.etherType,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read Ethernet Frame"; return; } @@ -495,6 +581,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!ipcFromEthernetFrame(outputfile,recordData,pos,ethFrame.etherType,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read Ethernet Frame"; return; } @@ -508,42 +595,49 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)&dltFrameBlock.timeStamp,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.asynchronous,sizeof(quint8))!=sizeof(quint8)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.currentFragmentNumber,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.lastFragmentNumber,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.ecuId,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.dataLength,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&dltFrameBlock.dataBytes,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -554,6 +648,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!dltFrame(outputfile,recordData,pos,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read DLTFrame"; return; } @@ -567,54 +662,63 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(inputfile.read((char*)&plpRaw.timeStamp,sizeof(quint64))!=sizeof(quint64)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.asynchronous,sizeof(quint8))!=sizeof(quint8)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.probeId,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.msgType,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.probeFlags,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.dataFlags,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.dataCounter,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.dataLength,sizeof(quint16))!=sizeof(quint16)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } if(inputfile.read((char*)&plpRaw.dataBytes,sizeof(quint32))!=sizeof(quint32)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4:" << "Size Error: Cannot read Record"; return; } @@ -624,6 +728,7 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par if(!ipcFromPlpRaw(&plpRaw,outputfile,recordData,time/1000000000,time%1000000000/1000)) { inputfile.close(); + outputfile.close(); qDebug() << "fromMF4: ERROR:" << "Size Error: Cannot read Ethernet Frame"; return; } @@ -644,28 +749,11 @@ void QDltImporter::dltIpcFromMF4(QFile &outputfile,QString fileName,QWidget *par break; } } - - } - else if(mdfHeader.id[0]==0 && mdfHeader.id[1]==0 && mdfHeader.id[2]==0 && mdfHeader.id[3]==0) - { - // end reached - break; - } - if(dt_pos && hd_pos) - { - // all blocks found end reading - break; - } - //qDebug() << "pos+mdfHeader.length" << pos+mdfHeader.length; - if(inputfile.size()< (pos+mdfHeader.length)) - { - qDebug() << "fromMF4: ERROR: Header length size error."; - break; } - inputfile.seek(pos+mdfHeader.length); } inputfile.close(); + outputfile.close(); emit progress("",3,100); @@ -1052,7 +1140,7 @@ bool QDltImporter::dltFromEthernetFrame(QFile &outputfile,QByteArray &record,int return false; } quint16 destPort = (((quint16)record.at(pos))<<8)|((quint16)(record.at(pos+1)&0xff)); - if(destPort==3490) + if(destPort==3490||destPort==3489) { pos+=6; dltFrame(outputfile,record,pos,sec,usec); @@ -1073,7 +1161,7 @@ bool QDltImporter::dltFromEthernetFrame(QFile &outputfile,QByteArray &record,int return false; } quint16 destPort = (((quint16)segmentBufferUDP.at(pos))<<8)|((quint16)(segmentBufferUDP.at(pos+1)&0xff)); - if(destPort==3490) + if(destPort==3490||destPort==3489) { pos+=6; dltFrame(outputfile,segmentBufferUDP,pos,sec,usec); @@ -1125,12 +1213,6 @@ void QDltImporter::writeDLTMessageToFile(QFile &outputfile,QByteArray &bufferHea } dlt_set_id(str.ecu, ecuId.toLatin1()); - /* check if message is matching the filter */ - if(!outputfile.open(QIODevice::WriteOnly|QIODevice::Append)) - { - qDebug() << "Failed opening WriteOnly" << outputfile.fileName(); - } - // write data into file //if(!ecuitem || !ecuitem->getWriteDLTv2StorageHeader()) { @@ -1154,8 +1236,6 @@ void QDltImporter::writeDLTMessageToFile(QFile &outputfile,QByteArray &bufferHea }*/ outputfile.write(bufferHeader); outputfile.write(bufferPayload,bufferPayloadSize); - outputfile.flush(); - outputfile.close(); } diff --git a/qdlt/qdltimporter.h b/qdlt/qdltimporter.h index b6fff3cc..d21d5117 100644 --- a/qdlt/qdltimporter.h +++ b/qdlt/qdltimporter.h @@ -75,6 +75,12 @@ typedef struct mdf_dgblocklinks { quint64 dg_md_comment; } PACKED mdf_dgblocklinks_t; +typedef struct mdf_dlblocklinks { + quint8 dl_flags; + quint8 reserved[3]; + quint32 dl_count; +} PACKED mdf_dlblocklinks_t; + typedef struct mdf_cgblocklinks { quint64 cg_cg_next; quint64 cg_cn_first; diff --git a/qdlt/qdltoptmanager.cpp b/qdlt/qdltoptmanager.cpp index c422b762..3c9eb874 100644 --- a/qdlt/qdltoptmanager.cpp +++ b/qdlt/qdltoptmanager.cpp @@ -26,30 +26,11 @@ #include #include -// Global static pointer used to ensure a single instance of the class. -QDltOptManager* QDltOptManager::instance; - -QDltOptManager::QDltOptManager() -{ - project = false; - silent_mode = false; - terminate=false; - convertionmode = e_ASCI; - commandline_mode = false; - delimiter=','; -} - QDltOptManager* QDltOptManager::getInstance() { - if (!instance) - instance = new QDltOptManager; - - return instance; -} - -QDltOptManager::QDltOptManager(QDltOptManager const&) -{ + static QDltOptManager instance; + return &instance; } const QStringList &QDltOptManager::getMf4Files() const @@ -81,32 +62,8 @@ void QDltOptManager::printVersion(QString appname) void QDltOptManager::printUsage() { -#if (WIN32) - qDebug()<<"Usage: dlt-viewer.exe [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]"; -#else - qDebug()<<"Usage: dlt-viewer [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]"; -#endif + qDebug().noquote() << getHelpText(); - qDebug()<<"\nOptions:"; - qDebug()<<" [logfile]\tLoading one or more logfiles on startup (must end with .dlt)"; - qDebug()<<" [projectfile]\tLoading project file on startup (must end with .dlp)"; - qDebug()<<" [filterfile]\tLoading filterfile on startup (must end with .dlf)"; - qDebug()<<" [pcapfile]\tImporting DLT/IPC from pcap file on startup (must end with .pcap)"; - qDebug()<<" [mf4file]\tImporting DLT/IPC from mf4 file on startup (must end with .mf4)"; - qDebug()<<" -h or --help\tPrint usage"; - qDebug()<<" -c textfile\tConvert logfile file to textfile"; - qDebug()<<" -u\tConversion will be done in UTF8 instead of ASCII"; - qDebug()<<" -csv\tConversion will be done in CSV format"; - qDebug()<<" -d\tConversion will NOT be done, save in dlt file format again instead"; - qDebug()<<" -dd\tConversion will NOT be done, save as decoded messages in dlt format"; - qDebug()<<" -b \"plugin|command|param1|..|param\"\tExecute a plugin command with parameters before loading log file."; - qDebug()<<" -e \"plugin|command|param1|..|param\"\tExecute a plugin command with parameters after loading log file."; - qDebug()<<" -s or --silent\tEnable silent mode without any GUI. Ideal for commandline usage."; - qDebug()<<" -stream\tTreat the input logfiles as DLT stream instead of DLT files."; - qDebug()<<" -t or --terminate\tTerminate DLT Viewer after command line execution."; - qDebug()<<" -v or --version\tOnly show version and buildtime information"; - qDebug()<<" -w workingdirectory\tSet the working directory"; - qDebug()<<" -delimiter \tThe used delimiter for CSV export (Default: ,)."; qDebug()<<"\nExamples:"; qDebug()<<" dlt-viewer.exe -t -c output.txt input.dlt"; qDebug()<<" dlt-viewer.exe -t -s -u -c output.txt input.dlt"; @@ -120,42 +77,37 @@ void QDltOptManager::printUsage() qDebug()<<" dlt-viewer.exe -t -c output.txt input1.mf4 input2.mf4"; } -void QDltOptManager::parse(QStringList *opt) +void QDltOptManager::parse(QStringList&& opt) { - QString str; - qDebug() << "### Starting DLT Viewer"; - printVersion(opt->at(0)); + printVersion(opt.at(0)); qDebug() << "### Parsing Options"; /* the default parameter - exactly one parameter - should either be * a dlt or a dlp file, so this enables the "doubleclick" feature */ - //str = opt->at(0); && ( str.compare("-h)") != 0 || str.compare("-v") !=0 ) - if(opt->size()==2 ) - { - if(opt->at(1).endsWith(".dlp") || opt->at(1).endsWith(".DLP")) - { - projectFile = QString("%1").arg(opt->at(1)); - project = true; - qDebug()<< "Project filename:" << projectFile; - return; - } - if(opt->at(1).endsWith(".dlt") || opt->at(1).endsWith(".DLT")) - { - const QString logFile = QString("%1").arg(opt->at(1)); - logFiles += logFile; - qDebug()<< "DLT filename:" << logFile; - return; - } - } + //str = opt.at(0); && ( str.compare("-h)") != 0 || str.compare("-v") !=0 ) + if (opt.size() == 2) { + if (opt.at(1).endsWith(".dlp") || opt.at(1).endsWith(".DLP")) { + projectFile = QString("%1").arg(opt.at(1)); + project = true; + qDebug() << "Project filename:" << projectFile; + return; + } + if (opt.at(1).endsWith(".dlt") || opt.at(1).endsWith(".DLT")) { + const QString logFile = QString("%1").arg(opt.at(1)); + logFiles += logFile; + qDebug() << "DLT filename:" << logFile; + return; + } + } // 0==Binary 1==First Argument - for (int i = 0; i < opt->size(); ++i) + for (int i = 0; i < opt.size(); ++i) { - str = opt->at(i); + QString str = opt.at(i); if(str.compare("-h") == 0 || str.compare("--help") == 0) { @@ -172,7 +124,7 @@ void QDltOptManager::parse(QStringList *opt) } else if(str.compare("-v") == 0 || str.compare("--version") == 0) { - printVersion(opt->at(0)); + // version has already been printed above, just exit exit(0); } else if(str.compare("-t") == 0 || str.compare("--terminate") == 0) @@ -182,7 +134,7 @@ void QDltOptManager::parse(QStringList *opt) } else if(str.compare("-c")==0) { - QString c1 = opt->value(i+1); + QString c1 = opt.value(i+1); convertDestFile = QString("%1").arg(c1); // check here already if the selected file exists @@ -194,7 +146,7 @@ void QDltOptManager::parse(QStringList *opt) } else if(str.compare("-delimiter")==0) { - QString c1 = opt->value(i+1); + QString c1 = opt.value(i+1); delimiter = QString("%1").arg(c1).front().toLatin1(); @@ -224,30 +176,30 @@ void QDltOptManager::parse(QStringList *opt) } else if(str.compare("-e")==0) { - QString c = opt->value(i+1); + QString c = opt.value(i+1); postPluginCommands += c; commandline_mode = true; ++i; } else if(str.compare("-b")==0) { - QString c = opt->value(i+1); + QString c = opt.value(i+1); prePluginCommands += c; commandline_mode = true; ++i; } else if (str.compare("-w") == 0) { - workingDirectory = opt->value(i+1); + workingDirectory = opt.value(i+1); ++i; } - else if(opt->at(i).endsWith(".dlt") || opt->at(i).endsWith(".DLT")) + else if(opt.at(i).endsWith(".dlt") || opt.at(i).endsWith(".DLT")) { - const QString logFile = QString("%1").arg(opt->at(i)); + const QString logFile = QString("%1").arg(opt.at(i)); logFiles += logFile; qDebug()<< "DLT filename:" << logFile; } - else if(opt->at(i).endsWith(".dlp") || opt->at(i).endsWith(".DLP")) + else if(opt.at(i).endsWith(".dlp") || opt.at(i).endsWith(".DLP")) { if (project == true) { @@ -256,24 +208,24 @@ void QDltOptManager::parse(QStringList *opt) exit(-1); } - projectFile = QString("%1").arg(opt->at(i)); + projectFile = QString("%1").arg(opt.at(i)); project = true; qDebug()<< "Project filename:" << projectFile; } - else if(opt->at(i).endsWith(".dlf") || opt->at(i).endsWith(".DLF")) + else if(opt.at(i).endsWith(".dlf") || opt.at(i).endsWith(".DLF")) { - filterFiles += QString("%1").arg(opt->at(i)); - qDebug()<< "Filter filename:" << QString("%1").arg(opt->at(i)); + filterFiles += QString("%1").arg(opt.at(i)); + qDebug()<< "Filter filename:" << QString("%1").arg(opt.at(i)); } - else if(opt->at(i).endsWith(".pcap") || opt->at(i).endsWith(".PCAP")) + else if(opt.at(i).endsWith(".pcap") || opt.at(i).endsWith(".PCAP")) { - const QString pcapFile = QString("%1").arg(opt->at(i)); + const QString pcapFile = QString("%1").arg(opt.at(i)); pcapFiles += pcapFile; qDebug()<< "Pcap filename:" << pcapFile; } - else if(opt->at(i).endsWith(".mf4") || opt->at(i).endsWith(".MF4")) + else if(opt.at(i).endsWith(".mf4") || opt.at(i).endsWith(".MF4")) { - const QString mf4File = QString("%1").arg(opt->at(i)); + const QString mf4File = QString("%1").arg(opt.at(i)); mf4Files += mf4File; qDebug()<< "MF4 filename:" << mf4File; } @@ -315,3 +267,57 @@ QString QDltOptManager::getCommandName(){return commandName;} QStringList QDltOptManager::getCommandParams(){return commandParams;} QString QDltOptManager::getWorkingDirectory() const { return workingDirectory; } char QDltOptManager::getDelimiter(){return delimiter;} + +QString QDltOptManager::getHelpText() const { + QStringList helpText; +#if (WIN32) + helpText << "Usage: dlt-viewer.exe [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]"; +#else + helpText << "Usage: dlt-viewer [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]"; +#endif + + helpText << "\nOptions:"; + helpText << " [logfile]\tLoading one or more logfiles on startup (must end with .dlt)"; + helpText << " [projectfile]\tLoading project file on startup (must end with .dlp)"; + helpText << " [filterfile]\tLoading filterfile on startup (must end with .dlf)"; + helpText << " [pcapfile]\tImporting DLT/IPC from pcap file on startup (must end with .pcap)"; + helpText << " [mf4file]\tImporting DLT/IPC from mf4 file on startup (must end with .mf4)"; + helpText << " -h or --help\tPrint usage"; + helpText << " -c textfile\tConvert logfile file to textfile"; + helpText << " -u\tConversion will be done in UTF8 instead of ASCII"; + helpText << " -csv\tConversion will be done in CSV format"; + helpText << " -d\tConversion will NOT be done, save in dlt file format again instead"; + helpText << " -dd\tConversion will NOT be done, save as decoded messages in dlt format"; + helpText << " -b \"plugin|command|param1|..|param\"\tExecute a plugin command with parameters before loading log file."; + helpText << " -e \"plugin|command|param1|..|param\"\tExecute a plugin command with parameters after loading log file."; + helpText << " -s or --silent\tEnable silent mode without any GUI. Ideal for commandline usage."; + helpText << " -stream\tTreat the input logfiles as DLT stream instead of DLT files."; + helpText << " -t or --terminate\tTerminate DLT Viewer after command line execution."; + helpText << " -v or --version\tOnly show version and buildtime information"; + helpText << " -w workingdirectory\tSet the working directory"; + helpText << " -delimiter \tThe used delimiter for CSV export (Default: ,)."; + + return helpText.join('\n'); +} + +void QDltOptManager::reset() { + project = false; + terminate = false; + silent_mode = false; + commandline_mode = false; + convertionmode = e_ASCI; + inputmode = e_inputmode::DLT; + projectFile.clear(); + logFiles.clear(); + filterFiles.clear(); + convertDestFile.clear(); + pluginName.clear(); + commandName.clear(); + commandParams.clear(); + prePluginCommands.clear(); + postPluginCommands.clear(); + workingDirectory.clear(); + delimiter = ','; + pcapFiles.clear(); + mf4Files.clear(); +} diff --git a/qdlt/qdltoptmanager.h b/qdlt/qdltoptmanager.h index 6cdda7e1..f1fccd71 100644 --- a/qdlt/qdltoptmanager.h +++ b/qdlt/qdltoptmanager.h @@ -46,7 +46,7 @@ class QDLT_EXPORT QDltOptManager static QDltOptManager* getInstance(); void printUsage(); void printVersion(QString appname); - void parse(QStringList *opt); + void parse(QStringList&& opt); bool isProjectFile(); bool isTerminate(); @@ -71,16 +71,17 @@ class QDLT_EXPORT QDltOptManager const QStringList &getMf4Files() const; char getDelimiter(); + QString getHelpText() const; + + // only testing relevant + void reset(); + private: - QDltOptManager(); - QDltOptManager(QDltOptManager const&); - static QDltOptManager *instance; - - bool project; - bool terminate; - bool silent_mode; - bool commandline_mode; - e_convertionmode convertionmode; + bool project{false}; + bool terminate{false}; + bool silent_mode{false}; + bool commandline_mode{false}; + e_convertionmode convertionmode{e_ASCI}; e_inputmode inputmode{e_inputmode::DLT}; QString projectFile; @@ -97,7 +98,7 @@ class QDLT_EXPORT QDltOptManager QStringList postPluginCommands; // command after loading log file QString workingDirectory; - char delimiter; + char delimiter{','}; }; #endif //QDLTOPTMANAGER_H diff --git a/qdlt/tests/CMakeLists.txt b/qdlt/tests/CMakeLists.txt index 13b400a4..7b65fda1 100644 --- a/qdlt/tests/CMakeLists.txt +++ b/qdlt/tests/CMakeLists.txt @@ -1,10 +1,31 @@ -add_executable(test_tools +add_executable(test_dltmessagematcher test_dltmessagematcher.cpp ) target_link_libraries( - test_tools + test_dltmessagematcher PRIVATE GTest::gtest_main qdlt ) +add_test( + NAME test_dltmessagematcher + COMMAND $ +) + + +add_executable(test_dltoptmanager + test_dltoptmanager.cpp +) + +target_link_libraries( + test_dltoptmanager + PRIVATE + GTest::gtest_main + qdlt +) + +add_test( + NAME test_dltoptmanager + COMMAND $ +) diff --git a/qdlt/tests/test_dltoptmanager.cpp b/qdlt/tests/test_dltoptmanager.cpp new file mode 100644 index 00000000..116d19c9 --- /dev/null +++ b/qdlt/tests/test_dltoptmanager.cpp @@ -0,0 +1,191 @@ +#include + +#include + +#include + + +QString logMessageSink; + +void messageHandler(QtMsgType type, const QMessageLogContext &, + const QString &msg) { + if (type == QtDebugMsg) { + logMessageSink.append(msg); + } +} + +class OptManagerTest : public ::testing::Test { +protected: + static void SetUpTestSuite() { + m_manager = QDltOptManager::getInstance(); + + qInstallMessageHandler(messageHandler); + } + + void SetUp() override { + m_manager->reset(); + } + + void TearDown() override { + logMessageSink.clear(); + } + + static QDltOptManager* m_manager; +}; + +QDltOptManager* OptManagerTest::m_manager = nullptr; + +TEST_F(OptManagerTest, txtConversion) { + auto args = QStringList() << "executable" << "-t" << "-c" << "output.txt" << "input.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.txt"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, txtConversionSilentUtf8Mode) { + auto args = QStringList() << "executable" << "-t" << "-s" << "-u" << "-c" << "output.txt" << "input.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_TRUE(m_manager->issilentMode()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.txt"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_EQ(m_manager->get_convertionmode(), e_UTF8); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, txtConversionSilentAsciiMode) { + auto args = QStringList() << "executable" << "-t" << "-s" << "-d" << "-c" << "output.txt" << "input.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_TRUE(m_manager->issilentMode()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.txt"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_EQ(m_manager->get_convertionmode(), e_DLT); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, csvConversionSilentMode) { + auto args = QStringList() << "executable" << "-t" << "-s" << "-csv" << "-c" << "output.csv" << "input.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_TRUE(m_manager->issilentMode()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.csv"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_EQ(m_manager->get_convertionmode(), e_CSV); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, txtConversionSilentDdlMode) { + auto args = QStringList() << "executable" << "-t" << "-s" << "decoded.dlp" << "-dd" << "-c" << "output.dlt" << "input.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_TRUE(m_manager->issilentMode()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.dlt"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_EQ(m_manager->get_convertionmode(), e_DDLT); + EXPECT_TRUE(m_manager->isCommandlineMode()); + EXPECT_EQ(m_manager->getProjectFile(), "decoded.dlp"); +} + +TEST_F(OptManagerTest, pluginPostCommands) { + auto args = QStringList() << "executable" + << "-p" + << "export.dlp" + << "-e" + << "\"Filetransfer Plugin|export|ftransferdir\"" + << "input.dlt"; + m_manager->parse(std::move(args)); + + EXPECT_EQ(m_manager->getProjectFile(), "export.dlp"); + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_TRUE(m_manager->getPostPluginCommands().contains("\"Filetransfer Plugin|export|ftransferdir\"")); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, pluginPreCommands) { + auto args = QStringList() << "executable" + << "-b" + << "\"Filetransfer Plugin|export|ftransferdir\"" + << "input.dlt"; + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_TRUE(m_manager->getPrePluginCommands().contains("\"Filetransfer Plugin|export|ftransferdir\"")); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, multipleLogFiles) { + auto args = QStringList() << "executable" << "input1.dlt" << "input2.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->getLogFiles().contains("input1.dlt")); + EXPECT_TRUE(m_manager->getLogFiles().contains("input2.dlt")); +} + +TEST_F(OptManagerTest, pcapFile) { + auto args = QStringList() << "executable" << "-t" << "-c" << "output.txt" << "input.pcap"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.txt"); + EXPECT_TRUE(m_manager->getPcapFiles().contains("input.pcap")); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, mf4Files) { + auto args = QStringList() << "executable" << "-t" << "-c" << "output.txt" << "input1.mf4" << "input2.mf4"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_EQ(m_manager->getConvertDestFile(), "output.txt"); + EXPECT_TRUE(m_manager->getMf4Files().contains("input1.mf4")); + EXPECT_TRUE(m_manager->getMf4Files().contains("input2.mf4")); + EXPECT_TRUE(m_manager->isCommandlineMode()); +} + +TEST_F(OptManagerTest, filterFile) { + auto args = QStringList() << "executable" + << "input.dlt" + << "filter.dlf" + << "-c" + << "out.dlt" + << "-d" + << "-s" + << "-t"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(m_manager->getLogFiles().contains("input.dlt")); + EXPECT_TRUE(m_manager->getFilterFiles().contains("filter.dlf")); + EXPECT_EQ(m_manager->getConvertDestFile(), "out.dlt"); + EXPECT_TRUE(m_manager->isCommandlineMode()); + EXPECT_TRUE(m_manager->isTerminate()); + EXPECT_TRUE(m_manager->issilentMode()); +} + +TEST_F(OptManagerTest, version) { + // impossible to check just version because there is a call to exit(0) in the qdltoptmanager + // but any output will be enough to check the version call because it is always printed + auto args = QStringList() << "executable" << "some.dlt"; + + m_manager->parse(std::move(args)); + + EXPECT_TRUE(logMessageSink.contains("Executable Name:")); + EXPECT_TRUE(logMessageSink.contains("Build time:")); + EXPECT_TRUE(logMessageSink.contains("Version:")); +} diff --git a/scripts/darwin/build.sh b/scripts/darwin/build_cmake.sh similarity index 100% rename from scripts/darwin/build.sh rename to scripts/darwin/build_cmake.sh diff --git a/scripts/linux/build.sh b/scripts/linux/build.sh index 42ce0dca..f625c5a2 100755 --- a/scripts/linux/build.sh +++ b/scripts/linux/build.sh @@ -9,14 +9,17 @@ BUILD_DIR="${SRC_DIR}/build" INSTALL_DIR="${BUILD_DIR}/install" APP_DIR_NAME="DLTViewer" +NPROC=$(nproc) +echo Nb of cpus: ${NPROC} + rm -rf "${APP_DIR_NAME}" rm -rf "${SRC_DIR}/build" mkdir -p "${BUILD_DIR}" cd "${BUILD_DIR}" -echo Build with QMake -qmake ../BuildDltViewer.pro -make +#echo Build with QMake +#qmake ../BuildDltViewer.pro +#make -j ${NPROC} echo Cleanup rm -rf "${INSTALL_DIR}" @@ -37,7 +40,7 @@ cmake -G Ninja \ -DDLT_RESOURCE_INSTALLATION_PATH="${APP_DIR_NAME}/usr/share" \ -DDLT_PLUGIN_INSTALLATION_PATH="${APP_DIR_NAME}/usr/bin/plugins" \ "${SRC_DIR}" -cmake --build "${BUILD_DIR}" -v +cmake --build "${BUILD_DIR}" -j ${NPROC} -v # External CPack generator calls "cmake --install" and "linuxdeploy" # diff --git a/scripts/linux/install.sh b/scripts/linux/install.sh index dc6c2e1d..6bff11ea 100755 --- a/scripts/linux/install.sh +++ b/scripts/linux/install.sh @@ -23,7 +23,7 @@ sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt update sudo apt install -y git cmake build-essential ninja-build \ qt515declarative qt515serialport qt515charts-no-lgpl qt515svg \ - libgtk2.0-dev libgl-dev gcc-11 g++-11 + libgtk2.0-dev libgl-dev gcc-11 g++-11 libgtest-dev sudo update-alternatives --remove-all cpp sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 110 --slave /usr/bin/g++ g++ /usr/bin/g++-11 --slave /usr/bin/gcov gcov /usr/bin/gcov-11 --slave /usr/bin/gcc-ar gcc-ar /usr/bin/gcc-ar-11 --slave /usr/bin/gcc-ranlib gcc-ranlib /usr/bin/gcc-ranlib-11 --slave /usr/bin/cpp cpp /usr/bin/cpp-11 diff --git a/src/main.cpp b/src/main.cpp index dc8b8db5..e3ac3cac 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -45,10 +45,7 @@ int main(int argc, char *argv[]) } QApplication a(argc, argv); - - QStringList arguments = a.arguments(); - QDltOptManager *opt = QDltOptManager::getInstance(); - opt->parse(&arguments); + QDltOptManager::getInstance()->parse(a.arguments()); MainWindow w; w.show(); diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 169ede80..83702fcf 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -17,7 +17,6 @@ * @licence end@ */ -#include #include #include #include @@ -143,6 +142,8 @@ MainWindow::MainWindow(QWidget *parent) : } + filterUpdate(); // update filters of qfile before starting Exporting for RegEx operation + if(!QDltOptManager::getInstance()->getConvertDestFile().isEmpty()) { switch ( QDltOptManager::getInstance()->get_convertionmode() ) @@ -1552,6 +1553,7 @@ void MainWindow::exportSelection(bool ascii = true,bool file = false,QDltExporte QModelIndexList list = ui->tableView->selectionModel()->selection().indexes(); + filterUpdate(); // update filters of qfile before starting Exporting for RegEx operation QDltExporter exporter(project.settings->automaticTimeSettings,project.settings->utcOffset,project.settings->dst,QDltOptManager::getInstance()->getDelimiter()); connect(&exporter,SIGNAL(clipboard(QString)),this,SLOT(clipboard(QString))); @@ -1589,6 +1591,8 @@ void MainWindow::exportSelection_searchTable(QDltExporter::DltExportFormat forma QModelIndexList finallist = ui->tableView->selectionModel()->selection().indexes(); + filterUpdate(); // update filters of qfile before starting Exporting for RegEx operation + QDltExporter exporter(project.settings->automaticTimeSettings,project.settings->utcOffset,project.settings->dst,QDltOptManager::getInstance()->getDelimiter()); connect(&exporter,SIGNAL(clipboard(QString)),this,SLOT(clipboard(QString))); exporter.exportMessages(&qfile,0,&pluginManager,format,QDltExporter::SelectionSelected,&finallist); @@ -1695,6 +1699,8 @@ void MainWindow::on_actionExport_triggered() unsigned long int startix, stopix; exporterDialog.getRange(&startix,&stopix); + filterUpdate(); // update filters of qfile before starting Exporting for RegEx operation + connect(&exporter,SIGNAL(progress(QString,int,int)),this,SLOT(progress(QString,int,int))); if(exportSelection == QDltExporter::SelectionSelected) // marked messages { @@ -5714,39 +5720,10 @@ void MainWindow::on_action_menuHelp_Info_triggered() } -void MainWindow::on_action_menuHelp_Command_Line_triggered() -{ - // Please copy changes to QDltOptManager::getInstance().cpp - printUsage() - - QMessageBox::information(0, QString("DLT Viewer - Command line usage\t\t\t\t\t"), // tabs used to expand mesage box ! - #ifdef WIN32 - QString("Usage: dlt-viewer.exe [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]\n\n")+ - QString("Options:\n")+ - #else - QString("Usage: dlt-viewer [OPTIONS] [logfile] [projectfile] [filterfile] [mf4file] [pcapfile]\n\n")+ - QString("Options:\n")+ - #endif - QString(" [logfile]\t\t\tLoading one or more logfiles on startup (must end with .dlt)\n")+ - QString(" [projectfile]\t\tLoading project file on startup (must end with .dlp)\n")+ - QString(" [filterfile]\t\tLoading filterfile on startup (must end with .dlf)\n")+ - QString(" [pcapfile]\tImporting DLT/IPC from pcap file on startup (must end with .pcap)\n")+ - QString(" [mf4file]\tImporting DLT/IPC from mf4 file on startup (must end with .mf4)\n")+ - QString(" -h\t\t\tPrint usage\n")+ - QString(" -s\t\t\tEnable silent mode without any GUI. Ideal for commandline usage.\n")+ - QString(" -stream\tTreat the input logfiles as DLT stream instead of DLT files.\n")+ - QString(" -v\t\t\tShow version and buildtime information\n")+ - QString(" -c \tConvert logfile to ASCII textfile\n")+ - QString(" -u\t\t\tExport logfile to UTF8 instead\n")+ - QString(" -csv\t\t\tExport logfile to csv ( Excel ) instead\n")+ - QString(" -d\t\t\tExport logfile to DLT format\n")+ - QString(" -dd\t\t\tExport logfile to decoded DLT format\n")+ - QString(" -b |command|param1|..|param\n\t\t\tExecute a command plugin with parameters before loading log file\n")+ - QString(" -e |command|param1|..|param\n\t\t\tExecute a command plugin with parameters after loading log file\n")+ - QString(" -t\t\t\tTerminate DLT Viewer after command line execution\n")+ - QString(" -v\t\t\tShow version and buildtime information\n")+ - QString(" -w workingdirectory\tSet the working directory\n")+ - QString(" -delimiter \tThe used delimiter for CSV export (Default: ,)\n") - ); +void MainWindow::on_action_menuHelp_Command_Line_triggered() { + QMessageBox::information( + 0, "DLT Viewer - Command line usage\t\t\t\t\t", // tabs used to expand message box ! + QDltOptManager::getInstance()->getHelpText()); } void MainWindow::on_pluginWidget_itemSelectionChanged() @@ -6686,7 +6663,8 @@ void MainWindow::filterIndexStart() } } - ui->lineEditFilterStart->setText(QString("%1").arg(index.row())); + quint64 pos = qfile.getMsgFilterPos(index.row()); + ui->lineEditFilterStart->setText(QString("%1").arg(pos)); } void MainWindow::filterIndexEnd() @@ -6710,8 +6688,8 @@ void MainWindow::filterIndexEnd() } } - ui->lineEditFilterEnd->setText(QString("%1").arg(index.row())); - + quint64 pos = qfile.getMsgFilterPos(index.row()); + ui->lineEditFilterEnd->setText(QString("%1").arg(pos)); } void MainWindow::filterAddTable() { diff --git a/src/regex_search_replace.h b/src/regex_search_replace.h deleted file mode 100644 index 05c01224..00000000 --- a/src/regex_search_replace.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef REGEX_SEARCH_REPLACE_H -#define REGEX_SEARCH_REPLACE_H - -#include -#include -#include - - -static void apply_regex_string(QString &data, const QString& regex_search, const QString& regex_replace) -{ - std::regex regex(regex_search.toStdString()); - - std::string payload_str = std::regex_replace(data.toStdString(), regex, regex_replace.toStdString()); - - data = QString::fromStdString(payload_str); -} - -#endif // REGEX_SEARCH_REPLACE_H diff --git a/src/searchtablemodel.cpp b/src/searchtablemodel.cpp index cfd5b99b..443872db 100644 --- a/src/searchtablemodel.cpp +++ b/src/searchtablemodel.cpp @@ -21,7 +21,6 @@ #include "fieldnames.h" #include "dltuiutils.h" #include "dlt_protocol.h" -#include "regex_search_replace.h" #include "qdltoptmanager.h" @@ -164,15 +163,16 @@ QVariant SearchTableModel::data(const QModelIndex &index, int role) const case FieldNames::Payload: /* display payload */ visu_data = msg.toStringPayload().simplified().remove(QChar::Null); - if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) + if(qfile) qfile->applyRegExString(msg,visu_data); + /*if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) { for(int num = 0; num < project->filter->topLevelItemCount (); num++) { FilterItem *item = (FilterItem*)project->filter->topLevelItem(num); if(item->checkState(0) == Qt::Checked && item->filter.enableRegexSearchReplace) { - apply_regex_string(visu_data, item->filter.regex_search, item->filter.regex_replace); + visu_data.replace(QRegularExpression(item->filter.regex_search), item->filter.regex_replace); } } - } + }*/ return visu_data; case FieldNames::MessageId: return QString::asprintf(project->settings->msgIdFormat.toUtf8(),msg.getMessageId()); diff --git a/src/src.pro b/src/src.pro index 423afb2b..ee4bfd03 100644 --- a/src/src.pro +++ b/src/src.pro @@ -181,8 +181,7 @@ HEADERS += mainwindow.h \ dltmsgqueue.h \ dltfileindexerthread.h \ dltfileindexerdefaultfilterthread.h \ - mcudpsocket.h \ - regex_search_replace.h + mcudpsocket.h # Compile these UI files FORMS += mainwindow.ui \ diff --git a/src/tablemodel.cpp b/src/tablemodel.cpp index 0378ea61..c4cf1a0d 100644 --- a/src/tablemodel.cpp +++ b/src/tablemodel.cpp @@ -26,7 +26,6 @@ #include "dltuiutils.h" #include "dlt_protocol.h" #include "qdltoptmanager.h" -#include "regex_search_replace.h" static long int lastrow = -1; // necessary because object tablemodel can not be changed, so no member variable can be used char buffer[DLT_VIEWER_LIST_BUFFER_SIZE]; @@ -249,16 +248,16 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) } /* display payload */ visu_data = msg.toStringPayload().simplified().remove(QChar::Null); - - if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) + if(qfile) qfile->applyRegExString(msg,visu_data); + /*if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) { for(int num = 0; num < project->filter->topLevelItemCount (); num++) { FilterItem *item = (FilterItem*)project->filter->topLevelItem(num); if(item->checkState(0) == Qt::Checked && item->filter.enableRegexSearchReplace) { - apply_regex_string(visu_data, item->filter.regex_search, item->filter.regex_replace); + visu_data.replace(QRegularExpression(item->filter.regex_search), item->filter.regex_replace); } } - } + }*/ /* limit size of string to 1000 characters to speed up scrolling */ if(visu_data.size()>1000) @@ -369,7 +368,19 @@ TableModel::TableModel(const QString & /*data*/, QObject *parent) msg = last_decoded_msg; } } - return msg.toStringPayload().simplified().remove(QChar::Null); + + QString visu_data = msg.toStringPayload().simplified().remove(QChar::Null); + if((QDltSettingsManager::getInstance()->value("startup/filtersEnabled", true).toBool())) + { + for(int num = 0; num < project->filter->topLevelItemCount (); num++) { + FilterItem *item = (FilterItem*)project->filter->topLevelItem(num); + if(item->checkState(0) == Qt::Checked && item->filter.enableRegexSearchReplace) { + visu_data.replace(QRegularExpression(item->filter.regex_search), item->filter.regex_replace); + } + } + } + + return visu_data; } return QVariant();